/**
 * Copyright (C) ARM Limited 2010-2013. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "gator.h"

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/math64.h>

#ifdef MALI_SUPPORT
#include "linux/mali_linux_trace.h"
#endif
#include "gator_trace_gpu.h"

/*
 * Taken from MALI_PROFILING_EVENT_TYPE_* items in Mali DDK.
 */
#define EVENT_TYPE_SINGLE  0
#define EVENT_TYPE_START   1
#define EVENT_TYPE_STOP    2
#define EVENT_TYPE_SUSPEND 3
#define EVENT_TYPE_RESUME  4

/* Note whether tracepoints have been registered */
static int mali_timeline_trace_registered;
static int mali_job_slots_trace_registered;
static int gpu_trace_registered;

enum {
	GPU_UNIT_NONE = 0,
	GPU_UNIT_VP,
	GPU_UNIT_FP,
	GPU_UNIT_CL,
	NUMBER_OF_GPU_UNITS
};

#define MALI_4xx     (0x0b07)
#define MALI_T6xx    (0x0056)

struct mali_gpu_job {
	int count;
	int last_tgid;
	int last_pid;
	int last_job_id;
};

#define NUMBER_OF_GPU_CORES 16
static struct mali_gpu_job mali_gpu_jobs[NUMBER_OF_GPU_UNITS][NUMBER_OF_GPU_CORES];
static DEFINE_SPINLOCK(mali_gpu_jobs_lock);

/* Only one event should be running on a unit and core at a time (ie, a start
 * event can only be followed by a stop and vice versa), but because the kernel
 * only knows when a job is enqueued and not started, it is possible for a
 * start1, start2, stop1, stop2. Change it back into start1, stop1, start2,
 * stop2 by queueing up start2 and releasing it when stop1 is received.
 */
static void mali_gpu_enqueue(int unit, int core, int tgid, int pid, int job_id)
{
	int count;

	spin_lock(&mali_gpu_jobs_lock);
	count = mali_gpu_jobs[unit][core].count;
	BUG_ON(count < 0);
	++mali_gpu_jobs[unit][core].count;
	if (count) {
		mali_gpu_jobs[unit][core].last_tgid = tgid;
		mali_gpu_jobs[unit][core].last_pid = pid;
		mali_gpu_jobs[unit][core].last_job_id = job_id;
	}
	spin_unlock(&mali_gpu_jobs_lock);

	if (!count) {
		marshal_sched_gpu_start(unit, core, tgid, pid/*, job_id*/);
	}
}

static void mali_gpu_stop(int unit, int core)
{
	int count;
	int last_tgid = 0;
	int last_pid = 0;
	int last_job_id = 0;

	spin_lock(&mali_gpu_jobs_lock);
	if (mali_gpu_jobs[unit][core].count == 0) {
		spin_unlock(&mali_gpu_jobs_lock);
		return;
	}
	--mali_gpu_jobs[unit][core].count;
	count = mali_gpu_jobs[unit][core].count;
	if (count) {
		last_tgid = mali_gpu_jobs[unit][core].last_tgid;
		last_pid = mali_gpu_jobs[unit][core].last_pid;
		last_job_id = mali_gpu_jobs[unit][core].last_job_id;
	}
	spin_unlock(&mali_gpu_jobs_lock);

	marshal_sched_gpu_stop(unit, core);
	if (count) {
		marshal_sched_gpu_start(unit, core, last_tgid, last_pid/*, last_job_id*/);
	}
}

#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
#include "gator_events_mali_4xx.h"

/*
 * Taken from MALI_PROFILING_EVENT_CHANNEL_* in Mali DDK.
 */
enum {
	EVENT_CHANNEL_SOFTWARE = 0,
	EVENT_CHANNEL_VP0 = 1,
	EVENT_CHANNEL_FP0 = 5,
	EVENT_CHANNEL_FP1,
	EVENT_CHANNEL_FP2,
	EVENT_CHANNEL_FP3,
	EVENT_CHANNEL_FP4,
	EVENT_CHANNEL_FP5,
	EVENT_CHANNEL_FP6,
	EVENT_CHANNEL_FP7,
	EVENT_CHANNEL_GPU = 21
};

/**
 * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
 */
enum {
	EVENT_REASON_SINGLE_GPU_NONE = 0,
	EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
};

GATOR_DEFINE_PROBE(mali_timeline_event, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned int d2, unsigned int d3, unsigned int d4))
{
	unsigned int component, state;

	// do as much work as possible before disabling interrupts
	component = (event_id >> 16) & 0xFF;	// component is an 8-bit field
	state = (event_id >> 24) & 0xF;	// state is a 4-bit field

	switch (state) {
	case EVENT_TYPE_START:
		if (component == EVENT_CHANNEL_VP0) {
			/* tgid = d0; pid = d1; */
			mali_gpu_enqueue(GPU_UNIT_VP, 0, d0, d1, 0);
		} else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) {
			/* tgid = d0; pid = d1; */
			mali_gpu_enqueue(GPU_UNIT_FP, component - EVENT_CHANNEL_FP0, d0, d1, 0);
		}
		break;

	case EVENT_TYPE_STOP:
		if (component == EVENT_CHANNEL_VP0) {
			mali_gpu_stop(GPU_UNIT_VP, 0);
		} else if (component >= EVENT_CHANNEL_FP0 && component <= EVENT_CHANNEL_FP7) {
			mali_gpu_stop(GPU_UNIT_FP, component - EVENT_CHANNEL_FP0);
		}
		break;

	case EVENT_TYPE_SINGLE:
		if (component == EVENT_CHANNEL_GPU) {
			unsigned int reason = (event_id & 0xffff);

			if (reason == EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE) {
				gator_events_mali_log_dvfs_event(d0, d1);
			}
		}
		break;

	default:
		break;
	}
}
#endif

#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
#if defined(MALI_JOB_SLOTS_EVENT_CHANGED)
GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigned int tgid, unsigned int pid, unsigned char job_id))
#else
GATOR_DEFINE_PROBE(mali_job_slots_event, TP_PROTO(unsigned int event_id, unsigned int tgid, unsigned int pid))
#endif
{
	unsigned int component, state, unit;
#if !defined(MALI_JOB_SLOTS_EVENT_CHANGED)
	unsigned char job_id = 0;
#endif

	component = (event_id >> 16) & 0xFF;	// component is an 8-bit field
	state = (event_id >> 24) & 0xF;	// state is a 4-bit field

	switch (component) {
	case 0:
		unit = GPU_UNIT_FP;
		break;
	case 1:
		unit = GPU_UNIT_VP;
		break;
	case 2:
		unit = GPU_UNIT_CL;
		break;
	default:
		unit = GPU_UNIT_NONE;
	}

	if (unit != GPU_UNIT_NONE) {
		switch (state) {
		case EVENT_TYPE_START:
			mali_gpu_enqueue(unit, 0, tgid, (pid != 0 ? pid : tgid), job_id);
			break;
		case EVENT_TYPE_STOP:
			mali_gpu_stop(unit, 0);
			break;
		default:
			/*
			 * Some jobs can be soft-stopped, so ensure that this terminates the activity trace.
			 */
			mali_gpu_stop(unit, 0);
		}
	}
}
#endif

GATOR_DEFINE_PROBE(gpu_activity_start, TP_PROTO(int gpu_unit, int gpu_core, struct task_struct *p))
{
	mali_gpu_enqueue(gpu_unit, gpu_core, (int)p->tgid, (int)p->pid, 0);
}

GATOR_DEFINE_PROBE(gpu_activity_stop, TP_PROTO(int gpu_unit, int gpu_core))
{
	mali_gpu_stop(gpu_unit, gpu_core);
}

int gator_trace_gpu_start(void)
{
	/*
	 * Returns nonzero for installation failed
	 * Absence of gpu trace points is not an error
	 */

	memset(&mali_gpu_jobs, sizeof(mali_gpu_jobs), 0);
	gpu_trace_registered = mali_timeline_trace_registered = mali_job_slots_trace_registered = 0;

#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
	if (!GATOR_REGISTER_TRACE(mali_timeline_event)) {
		mali_timeline_trace_registered = 1;
	}
#endif

#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
	if (!GATOR_REGISTER_TRACE(mali_job_slots_event)) {
		mali_job_slots_trace_registered = 1;
	}
#endif

	if (!mali_timeline_trace_registered) {
		if (GATOR_REGISTER_TRACE(gpu_activity_start)) {
			return 0;
		}
		if (GATOR_REGISTER_TRACE(gpu_activity_stop)) {
			GATOR_UNREGISTER_TRACE(gpu_activity_start);
			return 0;
		}
		gpu_trace_registered = 1;
	}

	return 0;
}

void gator_trace_gpu_stop(void)
{
#if defined(MALI_SUPPORT) && (MALI_SUPPORT != MALI_T6xx)
	if (mali_timeline_trace_registered) {
		GATOR_UNREGISTER_TRACE(mali_timeline_event);
	}
#endif

#if defined(MALI_SUPPORT) && (MALI_SUPPORT == MALI_T6xx)
	if (mali_job_slots_trace_registered) {
		GATOR_UNREGISTER_TRACE(mali_job_slots_event);
	}
#endif

	if (gpu_trace_registered) {
		GATOR_UNREGISTER_TRACE(gpu_activity_stop);
		GATOR_UNREGISTER_TRACE(gpu_activity_start);
	}

	gpu_trace_registered = mali_timeline_trace_registered = mali_job_slots_trace_registered = 0;
}
