/*
 *
 * (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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0
 *
 */



#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 */
