/* Copyright (c) 2013-2014, The Linux Foundation. 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 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 *
 */
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>

#include "adreno.h"
#include "adreno_profile.h"
#include "kgsl_sharedmem.h"
#include "kgsl_cffdump.h"

#define ASSIGNS_STR_FORMAT "%.8s:%u "

/*
 * Raw Data for processing later:
 *        : 3 - timestamp, count, context id
 * [per counter] - data for each counter
 *        : 1 - Register offset
 *        : 2 - Pre IB register hi/lo value
 *        : 2 - Post IB register hi/lo value
 * [per counter end]
 */
#define SIZE_DATA(cnt) (6 + (cnt) * 5)

/*
 * Pre-IB command size (in dwords):
 *        : 2 - NOP start identifier
 *        : 3 - timestamp
 *        : 3 - count
 *        : 3 - context id
 *        : 3 - pid
 *        : 3 - tid
 *        : 3 - type
 * [loop count start] - for each counter to watch
 *        : 3 - Register offset
 *        : 3 - Register read lo
 *        : 3 - Register read high
 * [loop end]
 *        : 2 - NOP end identifier
 */
#define SIZE_PREIB(cnt) (22 + (cnt) * 9)

/*
 * Post-IB command size (in dwords):
 *        : 2 - NOP start identifier
 * [loop count start] - for each counter to watch
 *        : 3 - Register read lo
 *        : 3 - Register read high
 * [loop end]
 *        : 2 - NOP end identifier
 */
#define SIZE_POSTIB(cnt) (4 + (cnt) * 6)

/* Counter data + Pre size + post size = total size */
#define SIZE_SHARED_ENTRY(cnt) (SIZE_DATA(cnt) + SIZE_PREIB(cnt) \
		+ SIZE_POSTIB(cnt))

/*
 * Space for following string :"%u %u %u %.5s %u "
 * [count iterations]: "%.8s:%u %llu %llu%c"
 */
#define SIZE_PIPE_ENTRY(cnt) (50 + (cnt) * 62)
#define SIZE_LOG_ENTRY(cnt) (6 + (cnt) * 5)

static struct adreno_context_type ctxt_type_table[] = {KGSL_CONTEXT_TYPES};

static const char *get_api_type_str(unsigned int type)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(ctxt_type_table) - 1; i++) {
		if (ctxt_type_table[i].type == type)
			return ctxt_type_table[i].str;
	}
	return "UNKNOWN";
}

static inline void _create_ib_ref(struct kgsl_memdesc *memdesc,
		unsigned int *cmd, unsigned int cnt, unsigned int off)
{
	cmd[0] = CP_HDR_INDIRECT_BUFFER_PFE;
	cmd[1] = memdesc->gpuaddr + off;
	cmd[2] = cnt;
}

#define IB_START(cmd) do { \
		*cmd++ = cp_nop_packet(1); \
		*cmd++ = KGSL_START_OF_PROFILE_IDENTIFIER; \
	} while (0);

#define IB_END(cmd) do { \
		*cmd++ = cp_nop_packet(1); \
		*cmd++ = KGSL_END_OF_PROFILE_IDENTIFIER; \
	} while (0);

#define IB_CMD(cmd, type, val1, val2, off) do { \
		*cmd++ = cp_type3_packet(type, 2); \
		*cmd++ = val1; \
		*cmd++ = val2; \
		off += sizeof(unsigned int); \
	} while (0);

static void _build_pre_ib_cmds(struct adreno_profile *profile,
		unsigned int *rbcmds, unsigned int head,
		unsigned int timestamp, struct adreno_context *drawctxt)
{
	struct adreno_profile_assigns_list *entry;
	unsigned int *start, *ibcmds;
	unsigned int count = profile->assignment_count;
	unsigned int gpuaddr = profile->shared_buffer.gpuaddr;
	unsigned int ib_offset = head + SIZE_DATA(count);
	unsigned int data_offset = head * sizeof(unsigned int);

	ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr);
	start = ibcmds;

	/* start of profile identifier */
	IB_START(ibcmds);

	/*
	 * Write ringbuffer commands to save the following to memory:
	 * timestamp, count, context_id, pid, tid, context type
	 */
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			timestamp, data_offset);
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			profile->assignment_count, data_offset);
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			drawctxt->base.id, data_offset);
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			drawctxt->base.proc_priv->pid, data_offset);
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			drawctxt->base.tid, data_offset);
	IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
			drawctxt->type, data_offset);

	/* loop for each countable assigned */
	list_for_each_entry(entry, &profile->assignments_list, list) {
		IB_CMD(ibcmds, CP_MEM_WRITE, gpuaddr + data_offset,
				entry->offset, data_offset);
		IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset,
				gpuaddr + data_offset, data_offset);
		IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset_hi,
				gpuaddr + data_offset, data_offset);

		/* skip over post_ib counter data */
		data_offset += sizeof(unsigned int) * 2;
	}

	/* end of profile identifier */
	IB_END(ibcmds);

	_create_ib_ref(&profile->shared_buffer, rbcmds,
			ibcmds - start, ib_offset * sizeof(unsigned int));
}

static void _build_post_ib_cmds(struct adreno_profile *profile,
		unsigned int *rbcmds, unsigned int head)
{
	struct adreno_profile_assigns_list *entry;
	unsigned int *start, *ibcmds;
	unsigned int count = profile->assignment_count;
	unsigned int gpuaddr =  profile->shared_buffer.gpuaddr;
	unsigned int ib_offset = head + SIZE_DATA(count) + SIZE_PREIB(count);
	unsigned int data_offset = head * sizeof(unsigned int);

	ibcmds = ib_offset + ((unsigned int *) profile->shared_buffer.hostptr);
	start = ibcmds;
	/* start of profile identifier */
	IB_START(ibcmds);

	/* skip over pre_ib preamble */
	data_offset += sizeof(unsigned int) * 6;

	/* loop for each countable assigned */
	list_for_each_entry(entry, &profile->assignments_list, list) {
		/* skip over pre_ib counter data */
		data_offset += sizeof(unsigned int) * 3;

		IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset,
				gpuaddr + data_offset, data_offset);
		IB_CMD(ibcmds, CP_REG_TO_MEM, entry->offset_hi,
				gpuaddr + data_offset, data_offset);
	}

	/* end of profile identifier */
	IB_END(ibcmds);

	_create_ib_ref(&profile->shared_buffer, rbcmds,
			ibcmds - start, ib_offset * sizeof(unsigned int));
}

static bool shared_buf_empty(struct adreno_profile *profile)
{
	if (profile->shared_buffer.hostptr == NULL ||
			profile->shared_buffer.size == 0)
		return true;

	if (profile->shared_head == profile->shared_tail)
		return true;

	return false;
}

static inline void shared_buf_inc(unsigned int max_size,
		unsigned int *offset, size_t inc)
{
	*offset = (*offset + inc) % max_size;
}

static inline void log_buf_wrapcnt(unsigned int cnt, uintptr_t *off)
{
	*off = (*off + cnt) % ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
}

static inline void log_buf_wrapinc_len(unsigned int *profile_log_buffer,
		unsigned int **ptr, unsigned int len)
{
	*ptr += len;
	if (*ptr >= (profile_log_buffer +
				ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS))
		*ptr -= ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS;
}

static inline void log_buf_wrapinc(unsigned int *profile_log_buffer,
		unsigned int **ptr)
{
	log_buf_wrapinc_len(profile_log_buffer, ptr, 1);
}

static inline unsigned int log_buf_available(struct adreno_profile *profile,
		unsigned int *head_ptr)
{
	uintptr_t tail, head;

	tail = (uintptr_t) profile->log_tail -
		(uintptr_t) profile->log_buffer;
	head = (uintptr_t)head_ptr - (uintptr_t) profile->log_buffer;
	if (tail > head)
		return (tail - head) / sizeof(uintptr_t);
	else
		return ADRENO_PROFILE_LOG_BUF_SIZE_DWORDS - ((head - tail) /
				sizeof(uintptr_t));
}

static inline unsigned int shared_buf_available(struct adreno_profile *profile)
{
	if (profile->shared_tail > profile->shared_head)
		return profile->shared_tail - profile->shared_head;
	else
		return profile->shared_size -
			(profile->shared_head - profile->shared_tail);
}

static struct adreno_profile_assigns_list *_find_assignment_by_offset(
		struct adreno_profile *profile, unsigned int offset)
{
	struct adreno_profile_assigns_list *entry;

	list_for_each_entry(entry, &profile->assignments_list, list) {
		if (entry->offset == offset)
			return entry;
	}

	return NULL;
}

static bool _in_assignments_list(struct adreno_profile *profile,
		unsigned int groupid, unsigned int countable)
{
	struct adreno_profile_assigns_list *entry;

	list_for_each_entry(entry, &profile->assignments_list, list) {
		if (entry->groupid == groupid && entry->countable ==
				countable)
			return true;
	}

	return false;
}

static bool _add_to_assignments_list(struct adreno_profile *profile,
		const char *str, unsigned int groupid, unsigned int countable,
		unsigned int offset, unsigned int offset_hi)
{
	struct adreno_profile_assigns_list *entry;

	/* first make sure we can alloc memory */
	entry = kmalloc(sizeof(struct adreno_profile_assigns_list), GFP_KERNEL);
	if (!entry)
		return false;

	list_add_tail(&entry->list, &profile->assignments_list);

	entry->countable = countable;
	entry->groupid = groupid;
	entry->offset = offset;
	entry->offset_hi = offset_hi;

	strlcpy(entry->name, str, sizeof(entry->name));

	profile->assignment_count++;

	return true;
}

static bool results_available(struct adreno_device *adreno_dev,
		struct adreno_profile *profile, unsigned int *shared_buf_tail)
{
	struct kgsl_device *device = &adreno_dev->dev;
	unsigned int global_eop;
	unsigned int off = profile->shared_tail;
	unsigned int *shared_ptr = (unsigned int *)
		profile->shared_buffer.hostptr;
	unsigned int ts, cnt;
	int ts_cmp;

	/*
	 * If shared_buffer empty or Memstore EOP timestamp is less than
	 * outstanding counter buffer timestamps then no results available
	 */
	if (shared_buf_empty(profile))
		return false;

	if (adreno_rb_readtimestamp(device,
			adreno_dev->cur_rb,
			KGSL_TIMESTAMP_RETIRED, &global_eop))
		return false;
	do {
		cnt = *(shared_ptr + off + 1);
		if (cnt == 0)
			return false;

		ts = *(shared_ptr + off);
		ts_cmp = timestamp_cmp(ts, global_eop);
		if (ts_cmp >= 0) {
			*shared_buf_tail = off;
			if (off == profile->shared_tail)
				return false;
			else
				return true;
		}
		shared_buf_inc(profile->shared_size, &off,
				SIZE_SHARED_ENTRY(cnt));
	} while (off != profile->shared_head);

	*shared_buf_tail = profile->shared_head;

	return true;
}

static void transfer_results(struct adreno_profile *profile,
		unsigned int shared_buf_tail)
{
	unsigned int buf_off;
	unsigned int ts, cnt, ctxt_id, pid, tid, client_type;
	unsigned int *ptr = (unsigned int *) profile->shared_buffer.hostptr;
	unsigned int *log_ptr, *log_base;
	struct adreno_profile_assigns_list *assigns_list;
	int i, tmp_tail;

	log_ptr = profile->log_head;
	log_base = profile->log_buffer;
	if (log_ptr == NULL)
		return;

	/*
	 * go through counter buffers and format for write into log_buffer
	 * if log buffer doesn't have space just overwrite it circularly
	 * shared_buf is guaranteed to not wrap within an entry so can use
	 * ptr increment
	 */
	while (profile->shared_tail != shared_buf_tail) {
		buf_off = profile->shared_tail;
		/*
		 * format: timestamp, count, context_id
		 * count entries: pc_off, pc_start, pc_end
		 */
		ts = *(ptr + buf_off++);
		cnt = *(ptr + buf_off++);
		ctxt_id = *(ptr + buf_off++);
		pid = *(ptr + buf_off++);
		tid = *(ptr + buf_off++);
		client_type = *(ptr + buf_off++);

		/*
		 * if entry overwrites the tail of log_buffer then adjust tail
		 * ptr to make room for the new entry, discarding old entry
		 */
		while (log_buf_available(profile, log_ptr) <=
				SIZE_LOG_ENTRY(cnt)) {
			unsigned int size_tail;
			uintptr_t boff;
			size_tail = SIZE_LOG_ENTRY(0xffff &
					*(profile->log_tail));
			boff = ((uintptr_t) profile->log_tail -
				(uintptr_t) log_base) / sizeof(uintptr_t);
			log_buf_wrapcnt(size_tail, &boff);
			profile->log_tail = log_base + boff;
		}

		*log_ptr = cnt;
		log_buf_wrapinc(log_base, &log_ptr);
		*log_ptr = client_type;
		log_buf_wrapinc(log_base, &log_ptr);
		*log_ptr = pid;
		log_buf_wrapinc(log_base, &log_ptr);
		*log_ptr = tid;
		log_buf_wrapinc(log_base, &log_ptr);
		*log_ptr = ctxt_id;
		log_buf_wrapinc(log_base, &log_ptr);
		*log_ptr = ts;
		log_buf_wrapinc(log_base, &log_ptr);

		for (i = 0; i < cnt; i++) {
			assigns_list = _find_assignment_by_offset(
					profile, *(ptr + buf_off++));
			if (assigns_list == NULL) {
				*log_ptr = (unsigned int) -1;

				shared_buf_inc(profile->shared_size,
					&profile->shared_tail,
					SIZE_SHARED_ENTRY(cnt));
				goto err;
			} else {
				*log_ptr = assigns_list->groupid << 16 |
					(assigns_list->countable & 0xffff);
			}
			log_buf_wrapinc(log_base, &log_ptr);
			*log_ptr  = *(ptr + buf_off++); /* perf cntr start hi */
			log_buf_wrapinc(log_base, &log_ptr);
			*log_ptr = *(ptr + buf_off++);  /* perf cntr start lo */
			log_buf_wrapinc(log_base, &log_ptr);
			*log_ptr = *(ptr + buf_off++);  /* perf cntr end hi */
			log_buf_wrapinc(log_base, &log_ptr);
			*log_ptr = *(ptr + buf_off++);  /* perf cntr end lo */
			log_buf_wrapinc(log_base, &log_ptr);

		}

		tmp_tail = profile->shared_tail;
		shared_buf_inc(profile->shared_size,
				&profile->shared_tail,
				SIZE_SHARED_ENTRY(cnt));
		/*
		 * Possibly lost some room as we cycled around, so it's safe to
		 * reset the max size
		 */
		if (profile->shared_tail < tmp_tail)
			profile->shared_size =
				ADRENO_PROFILE_SHARED_BUF_SIZE_DWORDS;

	}
	profile->log_head = log_ptr;
	return;
err:
	/* reset head/tail to same on error in hopes we work correctly later */
	profile->log_head = profile->log_tail;
}

static int profile_enable_get(void *data, u64 *val)
{
	struct kgsl_device *device = data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);

	mutex_lock(&device->mutex);
	*val = adreno_profile_enabled(&adreno_dev->profile);
	mutex_unlock(&device->mutex);

	return 0;
}

static int profile_enable_set(void *data, u64 val)
{
	struct kgsl_device *device = data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_profile *profile = &adreno_dev->profile;

	mutex_lock(&device->mutex);

	if (val && profile->log_buffer == NULL) {
		/* allocate profile_log_buffer the first time enabled */
		profile->log_buffer = vmalloc(ADRENO_PROFILE_LOG_BUF_SIZE);
		if (profile->log_buffer == NULL)
			return -ENOMEM;
		profile->log_tail = profile->log_buffer;
		profile->log_head = profile->log_buffer;
	}

	profile->enabled = val;

	mutex_unlock(&device->mutex);

	return 0;
}

static ssize_t profile_assignments_read(struct file *filep,
		char __user *ubuf, size_t max, loff_t *ppos)
{
	struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_profile *profile = &adreno_dev->profile;
	struct adreno_profile_assigns_list *entry;
	int len = 0, max_size = PAGE_SIZE;
	char *buf, *pos;
	ssize_t size = 0;

	mutex_lock(&device->mutex);

	buf = kmalloc(max_size, GFP_KERNEL);
	if (!buf) {
		mutex_unlock(&device->mutex);
		return -ENOMEM;
	}

	pos = buf;

	/* copy all assingments from list to str */
	list_for_each_entry(entry, &profile->assignments_list, list) {
		len = snprintf(pos, max_size, ASSIGNS_STR_FORMAT,
				entry->name, entry->countable);

		max_size -= len;
		pos += len;
	}

	size = simple_read_from_buffer(ubuf, max, ppos, buf,
			strlen(buf));

	kfree(buf);

	mutex_unlock(&device->mutex);
	return size;
}

static void _remove_assignment(struct adreno_device *adreno_dev,
		unsigned int groupid, unsigned int countable)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	struct adreno_profile_assigns_list *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &profile->assignments_list, list) {
		if (entry->groupid == groupid &&
				entry->countable == countable) {
			list_del(&entry->list);

			profile->assignment_count--;

			kfree(entry);

			/* remove from perf counter allocation */
			adreno_perfcounter_put(adreno_dev, groupid, countable,
					PERFCOUNTER_FLAG_KERNEL);
		}
	}
}

static void _add_assignment(struct adreno_device *adreno_dev,
		unsigned int groupid, unsigned int countable)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	unsigned int offset, offset_hi;
	const char *name = NULL;

	name = adreno_perfcounter_get_name(adreno_dev, groupid);
	if (!name)
		return;

	/* if already in assigned list skip it */
	if (_in_assignments_list(profile, groupid, countable))
		return;

	/* add to perf counter allocation, if fail skip it */
	if (adreno_perfcounter_get(adreno_dev, groupid, countable,
				&offset, &offset_hi, PERFCOUNTER_FLAG_NONE))
		return;

	/* add to assignments list, put counter back if error */
	if (!_add_to_assignments_list(profile, name, groupid,
				countable, offset, offset_hi))
		adreno_perfcounter_put(adreno_dev, groupid,
				countable, PERFCOUNTER_FLAG_KERNEL);
}

static char *_parse_next_assignment(struct adreno_device *adreno_dev,
		char *str, int *groupid, int *countable, bool *remove)
{
	char *groupid_str, *countable_str, *next_str = NULL;
	int ret;

	*groupid = -EINVAL;
	*countable = -EINVAL;
	*remove = false;

	/* remove spaces */
	while (*str == ' ')
		str++;

	/* check if it's a remove assignment */
	if (*str == '-') {
		*remove = true;
		str++;
	}

	/* get the groupid string */
	groupid_str = str;
	while (*str != ':') {
		if (*str == '\0')
			return NULL;
		*str = tolower(*str);
		str++;
	}
	if (groupid_str == str)
		return NULL;

	*str = '\0';
	str++;

	/* get the countable string */
	countable_str = str;
	while (*str != ' ' && *str != '\0')
		str++;
	if (countable_str == str)
		return NULL;

	/*
	 * If we have reached the end of the original string then make sure we
	 * return NULL from this function or we could accidently overrun
	 */

	if (*str != '\0') {
		*str = '\0';
		next_str = str + 1;
	}

	/* set results */
	*groupid = adreno_perfcounter_get_groupid(adreno_dev,
			groupid_str);
	if (*groupid < 0)
		return NULL;
	ret = kstrtou32(countable_str, 10, countable);
	if (ret)
		return NULL;

	return next_str;
}

static ssize_t profile_assignments_write(struct file *filep,
		const char __user *user_buf, size_t len, loff_t *off)
{
	struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_profile *profile = &adreno_dev->profile;
	size_t size = 0;
	char *buf, *pbuf;
	bool remove_assignment = false;
	int groupid, countable, ret;

	if (len >= PAGE_SIZE || len == 0)
		return -EINVAL;

	buf = kmalloc(len + 1, GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

	if (copy_from_user(buf, user_buf, len)) {
		size = -EFAULT;
		goto error_free;
	}

	mutex_lock(&device->mutex);

	if (adreno_profile_enabled(profile)) {
		size = -EINVAL;
		goto error_unlock;
	}

	ret = kgsl_active_count_get(device);
	if (ret) {
		size = ret;
		goto error_unlock;
	}

	/*
	 * When adding/removing assignments, ensure that the GPU is done with
	 * all it's work.  This helps to syncronize the work flow to the
	 * GPU and avoid racey conditions.
	 */
	if (adreno_idle(device)) {
		size = -ETIMEDOUT;
		goto error_put;
	}

	/* clear all shared buffer results */
	adreno_profile_process_results(adreno_dev);

	pbuf = buf;

	/* clear the log buffer */
	if (profile->log_buffer != NULL) {
		profile->log_head = profile->log_buffer;
		profile->log_tail = profile->log_buffer;
	}


	/* for sanity and parsing, ensure it is null terminated */
	buf[len] = '\0';

	/* parse file buf and add(remove) to(from) appropriate lists */
	while (pbuf) {
		pbuf = _parse_next_assignment(adreno_dev, pbuf, &groupid,
				&countable, &remove_assignment);
		if (groupid < 0 || countable < 0)
			break;

		if (remove_assignment)
			_remove_assignment(adreno_dev, groupid, countable);
		else
			_add_assignment(adreno_dev, groupid, countable);
	}

	size = len;

error_put:
	kgsl_active_count_put(device);
error_unlock:
	mutex_unlock(&device->mutex);
error_free:
	kfree(buf);
	return size;
}

static int _pipe_print_pending(char *ubuf, size_t max)
{
	loff_t unused = 0;
	char str[] = "Operation Would Block!";

	return simple_read_from_buffer(ubuf, max,
			&unused, str, strlen(str));
}

static int _pipe_print_results(struct adreno_device *adreno_dev,
		char *ubuf, size_t max)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	const char *grp_name;
	char *usr_buf = ubuf;
	unsigned int *log_ptr = NULL, *tmp_log_ptr = NULL;
	int len, i;
	int status = 0;
	ssize_t size, total_size = 0;
	unsigned int cnt, api_type, ctxt_id, pid, tid, ts, cnt_reg;
	unsigned long long pc_start, pc_end;
	const char *api_str;
	char format_space;
	loff_t unused = 0;
	char pipe_hdr_buf[51];   /* 4 uint32 + 5 space + 5 API type + '\0' */
	char pipe_cntr_buf[63];  /* 2 uint64 + 1 uint32 + 4 spaces + 8 group */

	/* convert unread entries to ASCII, copy to user-space */
	log_ptr = profile->log_tail;

	do {
		/* store the tmp var for error cases so we can skip */
		tmp_log_ptr = log_ptr;

		/* Too many to output to pipe, so skip this data */
		cnt = *log_ptr;
		log_buf_wrapinc(profile->log_buffer, &log_ptr);

		if (SIZE_PIPE_ENTRY(cnt) > max) {
			log_buf_wrapinc_len(profile->log_buffer,
				&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
			log_ptr = tmp_log_ptr;
			goto done;
		}

		/*
		 * Not enough space left in pipe, return without doing
		 * anything
		 */
		if ((max - (usr_buf - ubuf)) < SIZE_PIPE_ENTRY(cnt)) {
			log_ptr = tmp_log_ptr;
			goto done;
		}

		api_type = *log_ptr;
		api_str = get_api_type_str(api_type);
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		pid = *log_ptr;
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		tid = *log_ptr;
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		ctxt_id =  *log_ptr;
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		ts = *log_ptr;
		log_buf_wrapinc(profile->log_buffer, &log_ptr);
		len = snprintf(pipe_hdr_buf, sizeof(pipe_hdr_buf) - 1,
				"%u %u %u %.5s %u ",
				pid, tid, ctxt_id, api_str, ts);
		size = simple_read_from_buffer(usr_buf,
				max - (usr_buf - ubuf),
				&unused, pipe_hdr_buf, len);

		/* non-fatal error, so skip rest of entry and return */
		if (size < 0) {
			log_buf_wrapinc_len(profile->log_buffer,
				&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
			log_ptr = tmp_log_ptr;
			goto done;
		}

		unused = 0;
		usr_buf += size;
		total_size += size;

		for (i = 0; i < cnt; i++) {
			unsigned int start_lo, start_hi;
			unsigned int end_lo, end_hi;

			grp_name = adreno_perfcounter_get_name(
					adreno_dev, (*log_ptr >> 16) & 0xffff);

			/* non-fatal error, so skip rest of entry and return */
			if (grp_name == NULL) {
				log_buf_wrapinc_len(profile->log_buffer,
					&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
				log_ptr = tmp_log_ptr;
				goto done;
			}

			if (i == cnt - 1)
				format_space = '\n';
			else
				format_space = ' ';

			cnt_reg = *log_ptr & 0xffff;
			log_buf_wrapinc(profile->log_buffer, &log_ptr);
			start_lo = *log_ptr;
			log_buf_wrapinc(profile->log_buffer, &log_ptr);
			start_hi = *log_ptr;
			log_buf_wrapinc(profile->log_buffer, &log_ptr);
			end_lo = *log_ptr;
			log_buf_wrapinc(profile->log_buffer, &log_ptr);
			end_hi = *log_ptr;
			log_buf_wrapinc(profile->log_buffer, &log_ptr);

			pc_start = (((uint64_t) start_hi) << 32) | start_lo;
			pc_end = (((uint64_t) end_hi) << 32) | end_lo;

			len = snprintf(pipe_cntr_buf,
					sizeof(pipe_cntr_buf) - 1,
					"%.8s:%u %llu %llu%c",
					grp_name, cnt_reg, pc_start,
					pc_end, format_space);

			size = simple_read_from_buffer(usr_buf,
					max - (usr_buf - ubuf),
					&unused, pipe_cntr_buf, len);

			/* non-fatal error, so skip rest of entry and return */
			if (size < 0) {
				log_buf_wrapinc_len(profile->log_buffer,
					&tmp_log_ptr, SIZE_PIPE_ENTRY(cnt));
				log_ptr = tmp_log_ptr;
				goto done;
			}
			unused = 0;
			usr_buf += size;
			total_size += size;
		}
	} while (log_ptr != profile->log_head);

done:
	status = total_size;
	profile->log_tail = log_ptr;

	return status;
}

static ssize_t profile_pipe_print(struct file *filep, char __user *ubuf,
		size_t max, loff_t *ppos)
{
	struct kgsl_device *device = (struct kgsl_device *) filep->private_data;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_profile *profile = &adreno_dev->profile;
	char *usr_buf = ubuf;
	int status = 0;

	/*
	 * this file not seekable since it only supports streaming, ignore
	 * ppos <> 0
	 */
	/*
	 * format <pid>  <tid> <context id> <cnt<<16 | client type> <timestamp>
	 * for each perf counter <cntr_reg_off> <start hi & lo> <end hi & low>
	 */

	mutex_lock(&device->mutex);

	while (1) {
		/* process any results that are available into the log_buffer */
		status = adreno_profile_process_results(adreno_dev);
		if (status > 0) {
			/* if we have results, print them and exit */
			status = _pipe_print_results(adreno_dev, usr_buf, max);
			break;
		}

		/* there are no unread results, act accordingly */
		if (filep->f_flags & O_NONBLOCK) {
			if (profile->shared_tail != profile->shared_head) {
				status = _pipe_print_pending(usr_buf, max);
				break;
			} else {
				status = 0;
				break;
			}
		}

		mutex_unlock(&device->mutex);
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(msecs_to_jiffies(100));
		mutex_lock(&device->mutex);

		if (signal_pending(current)) {
			status = 0;
			break;
		}
	}

	mutex_unlock(&device->mutex);

	return status;
}

static int profile_groups_print(struct seq_file *s, void *unused)
{
	struct kgsl_device *device = (struct kgsl_device *) s->private;
	struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
	struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
	struct adreno_perfcounters *counters = gpudev->perfcounters;
	struct adreno_perfcount_group *group;
	int i, j, used;

	mutex_lock(&device->mutex);

	for (i = 0; i < counters->group_count; ++i) {
		group = &(counters->groups[i]);
		/* get number of counters used for this group */
		used = 0;
		for (j = 0; j < group->reg_count; j++) {
			if (group->regs[j].countable !=
					KGSL_PERFCOUNTER_NOT_USED)
				used++;
		}

		seq_printf(s, "%s %d %d\n", group->name,
			group->reg_count, used);
	}

	mutex_unlock(&device->mutex);

	return 0;
}

static int profile_groups_open(struct inode *inode, struct file *file)
{
	return single_open(file, profile_groups_print, inode->i_private);
}

static const struct file_operations profile_groups_fops = {
	.owner = THIS_MODULE,
	.open = profile_groups_open,
	.read = seq_read,
	.llseek = noop_llseek,
	.release = single_release,
};

static const struct file_operations profile_pipe_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = profile_pipe_print,
	.llseek = noop_llseek,
};

static const struct file_operations profile_assignments_fops = {
	.owner = THIS_MODULE,
	.open = simple_open,
	.read = profile_assignments_read,
	.write = profile_assignments_write,
	.llseek = noop_llseek,
};

DEFINE_SIMPLE_ATTRIBUTE(profile_enable_fops,
			profile_enable_get,
			profile_enable_set, "%llu\n");

void adreno_profile_init(struct adreno_device *adreno_dev)
{
	struct kgsl_device *device = &adreno_dev->dev;
	struct adreno_profile *profile = &adreno_dev->profile;
	struct dentry *profile_dir;
	int ret;

	profile->enabled = false;

	/* allocate shared_buffer, which includes pre_ib and post_ib */
	profile->shared_size = ADRENO_PROFILE_SHARED_BUF_SIZE_DWORDS;
	ret = kgsl_allocate_global(device, &profile->shared_buffer,
			profile->shared_size * sizeof(unsigned int), 0, 0);

	if (ret) {
		profile->shared_size = 0;
		return;
	}

	INIT_LIST_HEAD(&profile->assignments_list);

	/* Create perf counter debugfs */
	profile_dir = debugfs_create_dir("profiling", device->d_debugfs);
	if (IS_ERR(profile_dir))
		return;

	debugfs_create_file("enable",  0644, profile_dir, device,
			&profile_enable_fops);
	debugfs_create_file("blocks", 0444, profile_dir, device,
			&profile_groups_fops);
	debugfs_create_file("pipe", 0444, profile_dir, device,
			&profile_pipe_fops);
	debugfs_create_file("assignments", 0644, profile_dir, device,
			&profile_assignments_fops);
}

void adreno_profile_close(struct adreno_device *adreno_dev)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	struct adreno_profile_assigns_list *entry, *tmp;

	profile->enabled = false;
	vfree(profile->log_buffer);
	profile->log_buffer = NULL;
	profile->log_head = NULL;
	profile->log_tail = NULL;
	profile->shared_head = 0;
	profile->shared_tail = 0;
	kgsl_free_global(&profile->shared_buffer);
	profile->shared_size = 0;

	profile->assignment_count = 0;

	list_for_each_entry_safe(entry, tmp, &profile->assignments_list, list) {
		list_del(&entry->list);
		kfree(entry);
	}
}

int adreno_profile_process_results(struct adreno_device *adreno_dev)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	unsigned int shared_buf_tail = profile->shared_tail;

	if (!results_available(adreno_dev, profile, &shared_buf_tail))
		return 0;

	/*
	 * transfer retired results to log_buffer
	 * update shared_buffer tail ptr
	 */
	transfer_results(profile, shared_buf_tail);

	return 1;
}

void adreno_profile_preib_processing(struct adreno_device *adreno_dev,
		struct adreno_context *drawctxt, unsigned int *cmd_flags,
		unsigned int **rbptr)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	int count = profile->assignment_count;
	unsigned int entry_head = profile->shared_head;
	unsigned int *shared_ptr;
	struct adreno_ringbuffer *rb = ADRENO_CURRENT_RINGBUFFER(adreno_dev);
	unsigned int rbcmds[3] = { cp_nop_packet(2),
		KGSL_NOP_IB_IDENTIFIER, KGSL_NOP_IB_IDENTIFIER };
	unsigned int *ptr = *rbptr;

	*cmd_flags &= ~KGSL_CMD_FLAGS_PROFILE;

	if (!adreno_profile_assignments_ready(profile))
		goto done;

	/*
	 * check if space available, include the post_ib in space available
	 * check so don't have to handle trying to undo the pre_ib insertion in
	 * ringbuffer in the case where only the post_ib fails enough space
	 */
	if (SIZE_SHARED_ENTRY(count) >= shared_buf_available(profile))
		goto done;

	if (entry_head + SIZE_SHARED_ENTRY(count) >= profile->shared_size) {
		/* entry_head would wrap, start entry_head at 0 in buffer */
		entry_head = 0;
		profile->shared_size = profile->shared_head;
		profile->shared_head = 0;

		/* recheck space available */
		if (SIZE_SHARED_ENTRY(count) >= shared_buf_available(profile))
			goto done;
	}

	/* zero out the counter area of shared_buffer entry_head */
	shared_ptr = entry_head + ((unsigned int *)
			profile->shared_buffer.hostptr);
	memset(shared_ptr, 0, SIZE_SHARED_ENTRY(count) * sizeof(unsigned int));

	/* reserve space for the pre ib shared buffer */
	shared_buf_inc(profile->shared_size, &profile->shared_head,
			SIZE_SHARED_ENTRY(count));

	/* create the shared ibdesc */
	_build_pre_ib_cmds(profile, rbcmds, entry_head,
			rb->timestamp + 1, drawctxt);

	/* set flag to sync with post ib commands */
	*cmd_flags |= KGSL_CMD_FLAGS_PROFILE;

done:
	/* write the ibdesc to the ringbuffer */
	*ptr++ = rbcmds[0];
	*ptr++ = rbcmds[1];
	*ptr++ = rbcmds[2];

	*rbptr = ptr;
}

void adreno_profile_postib_processing(struct adreno_device *adreno_dev,
		unsigned int *cmd_flags, unsigned int **rbptr)
{
	struct adreno_profile *profile = &adreno_dev->profile;
	int count = profile->assignment_count;
	unsigned int entry_head = profile->shared_head -
		SIZE_SHARED_ENTRY(count);
	unsigned int rbcmds[3] = { cp_nop_packet(2),
		KGSL_NOP_IB_IDENTIFIER, KGSL_NOP_IB_IDENTIFIER };
	unsigned int *ptr = *rbptr;

	if (!adreno_profile_assignments_ready(profile))
		goto done;

	if (!(*cmd_flags & KGSL_CMD_FLAGS_PROFILE))
		goto done;

	/* create the shared ibdesc */
	_build_post_ib_cmds(profile, rbcmds, entry_head);

done:
	/* write the ibdesc to the ringbuffer */
	*ptr++ = rbcmds[0];
	*ptr++ = rbcmds[1];
	*ptr++ = rbcmds[2];

	*rbptr = ptr;

	/* reset the sync flag */
	*cmd_flags &= ~KGSL_CMD_FLAGS_PROFILE;
}

