/*
 *
 * (C) COPYRIGHT 2012-2016 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */





#include <mali_kbase.h>
#include <mali_kbase_jm.h>
#include <mali_kbase_hwaccess_jm.h>

#define CREATE_TRACE_POINTS

#ifdef CONFIG_MALI_TRACE_TIMELINE
#include "mali_timeline.h"

#include <linux/debugfs.h>
#include <linux/seq_file.h>

EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_atoms_in_flight);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_atom);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_gpu_slot_active);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_gpu_slot_action);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_gpu_power_active);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_l2_power_active);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_pm_event);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_slot_atom);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_pm_checktrans);
EXPORT_TRACEPOINT_SYMBOL_GPL(mali_timeline_context_active);

struct kbase_trace_timeline_desc {
	char *enum_str;
	char *desc;
	char *format;
	char *format_desc;
};

static struct kbase_trace_timeline_desc kbase_trace_timeline_desc_table[] = {
	#define KBASE_TIMELINE_TRACE_CODE(enum_val, desc, format, format_desc) { #enum_val, desc, format, format_desc }
	#include "mali_kbase_trace_timeline_defs.h"
	#undef KBASE_TIMELINE_TRACE_CODE
};

#define KBASE_NR_TRACE_CODES ARRAY_SIZE(kbase_trace_timeline_desc_table)

static void *kbasep_trace_timeline_seq_start(struct seq_file *s, loff_t *pos)
{
	if (*pos >= KBASE_NR_TRACE_CODES)
		return NULL;

	return &kbase_trace_timeline_desc_table[*pos];
}

static void kbasep_trace_timeline_seq_stop(struct seq_file *s, void *data)
{
}

static void *kbasep_trace_timeline_seq_next(struct seq_file *s, void *data, loff_t *pos)
{
	(*pos)++;

	if (*pos == KBASE_NR_TRACE_CODES)
		return NULL;

	return &kbase_trace_timeline_desc_table[*pos];
}

static int kbasep_trace_timeline_seq_show(struct seq_file *s, void *data)
{
	struct kbase_trace_timeline_desc *trace_desc = data;

	seq_printf(s, "%s#%s#%s#%s\n", trace_desc->enum_str, trace_desc->desc, trace_desc->format, trace_desc->format_desc);
	return 0;
}


static const struct seq_operations kbasep_trace_timeline_seq_ops = {
	.start = kbasep_trace_timeline_seq_start,
	.next = kbasep_trace_timeline_seq_next,
	.stop = kbasep_trace_timeline_seq_stop,
	.show = kbasep_trace_timeline_seq_show,
};

static int kbasep_trace_timeline_debugfs_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &kbasep_trace_timeline_seq_ops);
}

static const struct file_operations kbasep_trace_timeline_debugfs_fops = {
	.open = kbasep_trace_timeline_debugfs_open,
	.read = seq_read,
	.llseek = seq_lseek,
	.release = seq_release,
};

#ifdef CONFIG_DEBUG_FS

void kbasep_trace_timeline_debugfs_init(struct kbase_device *kbdev)
{
	debugfs_create_file("mali_timeline_defs",
			S_IRUGO, kbdev->mali_debugfs_directory, NULL,
			&kbasep_trace_timeline_debugfs_fops);
}

#endif /* CONFIG_DEBUG_FS */

void kbase_timeline_job_slot_submit(struct kbase_device *kbdev, struct kbase_context *kctx,
		struct kbase_jd_atom *katom, int js)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);

	if (kbdev->timeline.slot_atoms_submitted[js] > 0) {
		KBASE_TIMELINE_JOB_START_NEXT(kctx, js, 1);
	} else {
		base_atom_id atom_number = kbase_jd_atom_id(kctx, katom);

		KBASE_TIMELINE_JOB_START_HEAD(kctx, js, 1);
		KBASE_TIMELINE_JOB_START(kctx, js, atom_number);
	}
	++kbdev->timeline.slot_atoms_submitted[js];

	KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, kbdev->timeline.slot_atoms_submitted[js]);
}

void kbase_timeline_job_slot_done(struct kbase_device *kbdev, struct kbase_context *kctx,
		struct kbase_jd_atom *katom, int js,
		kbasep_js_atom_done_code done_code)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);

	if (done_code & KBASE_JS_ATOM_DONE_EVICTED_FROM_NEXT) {
		KBASE_TIMELINE_JOB_START_NEXT(kctx, js, 0);
	} else {
		/* Job finished in JS_HEAD */
		base_atom_id atom_number = kbase_jd_atom_id(kctx, katom);

		KBASE_TIMELINE_JOB_START_HEAD(kctx, js, 0);
		KBASE_TIMELINE_JOB_STOP(kctx, js, atom_number);

		/* see if we need to trace the job in JS_NEXT moving to JS_HEAD */
		if (kbase_backend_nr_atoms_submitted(kbdev, js)) {
			struct kbase_jd_atom *next_katom;
			struct kbase_context *next_kctx;

			/* Peek the next atom - note that the atom in JS_HEAD will already
			 * have been dequeued */
			next_katom = kbase_backend_inspect_head(kbdev, js);
			WARN_ON(!next_katom);
			next_kctx = next_katom->kctx;
			KBASE_TIMELINE_JOB_START_NEXT(next_kctx, js, 0);
			KBASE_TIMELINE_JOB_START_HEAD(next_kctx, js, 1);
			KBASE_TIMELINE_JOB_START(next_kctx, js, kbase_jd_atom_id(next_kctx, next_katom));
		}
	}

	--kbdev->timeline.slot_atoms_submitted[js];

	KBASE_TIMELINE_ATOMS_SUBMITTED(kctx, js, kbdev->timeline.slot_atoms_submitted[js]);
}

void kbase_timeline_pm_send_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event_sent)
{
	int uid = 0;
	int old_uid;

	/* If a producer already exists for the event, try to use their UID (multiple-producers) */
	uid = atomic_read(&kbdev->timeline.pm_event_uid[event_sent]);
	old_uid = uid;

	/* Get a new non-zero UID if we don't have one yet */
	while (!uid)
		uid = atomic_inc_return(&kbdev->timeline.pm_event_uid_counter);

	/* Try to use this UID */
	if (old_uid != atomic_cmpxchg(&kbdev->timeline.pm_event_uid[event_sent], old_uid, uid))
		/* If it changed, raced with another producer: we've lost this UID */
		uid = 0;

	KBASE_TIMELINE_PM_SEND_EVENT(kbdev, event_sent, uid);
}

void kbase_timeline_pm_check_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event)
{
	int uid = atomic_read(&kbdev->timeline.pm_event_uid[event]);

	if (uid != 0) {
		if (uid != atomic_cmpxchg(&kbdev->timeline.pm_event_uid[event], uid, 0))
			/* If it changed, raced with another consumer: we've lost this UID */
			uid = 0;

		KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event, uid);
	}
}

void kbase_timeline_pm_handle_event(struct kbase_device *kbdev, enum kbase_timeline_pm_event event)
{
	int uid = atomic_read(&kbdev->timeline.pm_event_uid[event]);

	if (uid != atomic_cmpxchg(&kbdev->timeline.pm_event_uid[event], uid, 0))
		/* If it changed, raced with another consumer: we've lost this UID */
		uid = 0;

	KBASE_TIMELINE_PM_HANDLE_EVENT(kbdev, event, uid);
}

void kbase_timeline_pm_l2_transition_start(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);
	/* Simply log the start of the transition */
	kbdev->timeline.l2_transitioning = true;
	KBASE_TIMELINE_POWERING_L2(kbdev);
}

void kbase_timeline_pm_l2_transition_done(struct kbase_device *kbdev)
{
	lockdep_assert_held(&kbdev->hwaccess_lock);
	/* Simply log the end of the transition */
	if (kbdev->timeline.l2_transitioning) {
		kbdev->timeline.l2_transitioning = false;
		KBASE_TIMELINE_POWERED_L2(kbdev);
	}
}

#endif /* CONFIG_MALI_TRACE_TIMELINE */
