/*
 * Example events provider
 *
 * 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.
 *
 * Similar entries to those below must be present in the events.xml file.
 * To add them to the events.xml, create an events-mmap.xml with the 
 * following contents and rebuild gatord:
 *
 * <counter_set name="mmaped_cnt" count="3"/>
 * <category name="mmaped" counter_set="mmaped_cnt" per_cpu="no">
 *   <event event="0x0" title="Simulated1" name="Sine" display="maximum" average_selection="yes" description="Sort-of-sine"/>
 *   <event event="0x1" title="Simulated2" name="Triangle" display="maximum" average_selection="yes" description="Triangular wave"/>
 *   <event event="0x2" title="Simulated3" name="PWM" display="maximum" average_selection="yes" description="PWM Signal"/>
 * </category>
 */

#include <linux/init.h>
#include <linux/io.h>
#include <linux/ratelimit.h>

#include "gator.h"

#define MMAPED_COUNTERS_NUM 3

static struct {
	unsigned long enabled;
	unsigned long event;
	unsigned long key;
} mmaped_counters[MMAPED_COUNTERS_NUM];

static int mmaped_buffer[MMAPED_COUNTERS_NUM * 2];

#ifdef TODO
static void __iomem *mmaped_base;
#endif

#ifndef TODO
static s64 prev_time;
#endif

/* Adds mmaped_cntX directories and enabled, event, and key files to /dev/gator/events */
static int gator_events_mmaped_create_files(struct super_block *sb,
					    struct dentry *root)
{
	int i;

	for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
		char buf[16];
		struct dentry *dir;

		snprintf(buf, sizeof(buf), "mmaped_cnt%d", i);
		dir = gatorfs_mkdir(sb, root, buf);
		if (WARN_ON(!dir))
			return -1;
		gatorfs_create_ulong(sb, dir, "enabled",
				     &mmaped_counters[i].enabled);
		gatorfs_create_ulong(sb, dir, "event",
				     &mmaped_counters[i].event);
		gatorfs_create_ro_ulong(sb, dir, "key",
					&mmaped_counters[i].key);
	}

	return 0;
}

static int gator_events_mmaped_start(void)
{
#ifdef TODO
	for (i = 0; i < MMAPED_COUNTERS_NUM; i++)
		writel(mmaped_counters[i].event,
		       mmaped_base + COUNTERS_CONFIG_OFFSET[i]);

	writel(ENABLED, COUNTERS_CONTROL_OFFSET);
#endif

#ifndef TODO
	struct timespec ts;
	getnstimeofday(&ts);
	prev_time = timespec_to_ns(&ts);
#endif

	return 0;
}

static void gator_events_mmaped_stop(void)
{
#ifdef TODO
	writel(DISABLED, COUNTERS_CONTROL_OFFSET);
#endif
}

#ifndef TODO
/* This function "simulates" counters, generating values of fancy
 * functions like sine or triangle... */
static int mmaped_simulate(int counter, int delta_in_us)
{
	int result = 0;

	switch (counter) {
	case 0:		/* sort-of-sine */
		{
			static int t = 0;
			int x;

			t += delta_in_us;
			if (t > 2048000)
				t = 0;

			if (t % 1024000 < 512000)
				x = 512000 - (t % 512000);
			else
				x = t % 512000;

			result = 32 * x / 512000;
			result = result * result;

			if (t < 1024000)
				result = 1922 - result;
		}
		break;
	case 1:		/* triangle */
		{
			static int v, d = 1;

			v = v + d * delta_in_us;
			if (v < 0) {
				v = 0;
				d = 1;
			} else if (v > 1000000) {
				v = 1000000;
				d = -1;
			}

			result = v;
		}
		break;
	case 2:		/* PWM signal */
		{
			static int dc, x, t = 0;

			t += delta_in_us;
			if (t > 1000000)
				t = 0;
			if (x / 1000000 != (x + delta_in_us) / 1000000)
				dc = (dc + 100000) % 1000000;
			x += delta_in_us;

			result = t < dc ? 0 : 10;
		}
		break;
	}

	return result;
}
#endif

static int gator_events_mmaped_read(int **buffer)
{
	int i;
	int len = 0;
#ifndef TODO
	int delta_in_us;
	struct timespec ts;
	s64 time;
#endif

	/* System wide counters - read from one core only */
	if (!on_primary_core())
		return 0;

#ifndef TODO
	getnstimeofday(&ts);
	time = timespec_to_ns(&ts);
	delta_in_us = (int)(time - prev_time) / 1000;
	prev_time = time;
#endif

	for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
		if (mmaped_counters[i].enabled) {
			mmaped_buffer[len++] = mmaped_counters[i].key;
#ifdef TODO
			mmaped_buffer[len++] =
			    readl(mmaped_base + COUNTERS_VALUE_OFFSET[i]);
#else
			mmaped_buffer[len++] =
			    mmaped_simulate(mmaped_counters[i].event,
					    delta_in_us);
#endif
		}
	}

	if (buffer)
		*buffer = mmaped_buffer;

	return len;
}

static struct gator_interface gator_events_mmaped_interface = {
	.create_files = gator_events_mmaped_create_files,
	.start = gator_events_mmaped_start,
	.stop = gator_events_mmaped_stop,
	.read = gator_events_mmaped_read,
};

/* Must not be static! */
int __init gator_events_mmaped_init(void)
{
	int i;

#ifdef TODO
	mmaped_base = ioremap(COUNTERS_PHYS_ADDR, SZ_4K);
	if (!mmaped_base)
		return -ENOMEM;
#endif

	for (i = 0; i < MMAPED_COUNTERS_NUM; i++) {
		mmaped_counters[i].enabled = 0;
		mmaped_counters[i].key = gator_events_get_key();
	}

	return gator_events_install(&gator_events_mmaped_interface);
}

gator_events_init(gator_events_mmaped_init);
