/**
 * @file op_model_mpcore.c
 * MPCORE Event Monitor Driver
 * @remark Copyright 2004 ARM SMP Development Team
 * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
 * @remark Copyright 2000-2004 MontaVista Software Inc
 * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
 * @remark Copyright 2004 Intel Corporation
 * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
 * @remark Copyright 2004 Oprofile Authors
 *
 * @remark Read the file COPYING
 *
 * @author Zwane Mwaikambo
 *
 *  Counters:
 *    0: PMN0 on CPU0, per-cpu configurable event counter
 *    1: PMN1 on CPU0, per-cpu configurable event counter
 *    2: CCNT on CPU0
 *    3: PMN0 on CPU1
 *    4: PMN1 on CPU1
 *    5: CCNT on CPU1
 *    6: PMN0 on CPU1
 *    7: PMN1 on CPU1
 *    8: CCNT on CPU1
 *    9: PMN0 on CPU1
 *   10: PMN1 on CPU1
 *   11: CCNT on CPU1
 *   12-19: configurable SCU event counters
 */

/* #define DEBUG */
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/oprofile.h>
#include <linux/interrupt.h>
#include <linux/smp.h>

#include <asm/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <asm/hardware.h>
#include <asm/system.h>

#include "op_counter.h"
#include "op_arm_model.h"
#include "op_model_arm11_core.h"
#include "op_model_mpcore.h"

/*
 * MPCore SCU event monitor support
 */
#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_MPCORE_SCU_BASE + 0x10)

/*
 * Bitmask of used SCU counters
 */
static unsigned int scu_em_used;

/*
 * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
 */
static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n)
{
	writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]);
}

static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event)
{
	event &= 0xff;
	writeb(event, &emc->MCEB[n]);
}

/*
 * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU)
 */
static irqreturn_t scu_em_interrupt(int irq, void *arg)
{
	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
	unsigned int cnt;

	cnt = irq - IRQ_PMU_SCU0;
	oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt));
	scu_reset_counter(emc, cnt);

	/* Clear overflow flag for this counter */
	writel(1 << (cnt + 16), &emc->PMCR);

	return IRQ_HANDLED;
}

/* Configure just the SCU counters that the user has requested */
static void scu_setup(void)
{
	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
	unsigned int i;

	scu_em_used = 0;

	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
		if (counter_config[SCU_COUNTER(i)].enabled &&
		    counter_config[SCU_COUNTER(i)].event) {
			scu_set_event(emc, i, 0); /* disable counter for now */
			scu_em_used |= 1 << i;
		}
	}
}

static int scu_start(void)
{
	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
	unsigned int temp, i;
	unsigned long event;
	int ret = 0;

	/*
	 * request the SCU counter interrupts that we need
	 */
	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
		if (scu_em_used & (1 << i)) {
			ret = request_irq(IRQ_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL);
			if (ret) {
				printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n",
				       IRQ_PMU_SCU0 + i);
				goto err_free_scu;
			}
		}
	}

	/*
	 * clear overflow and enable interrupt for all used counters
	 */
	temp = readl(&emc->PMCR);
	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
		if (scu_em_used & (1 << i)) {
			scu_reset_counter(emc, i);
			event = counter_config[SCU_COUNTER(i)].event;
			scu_set_event(emc, i, event);

			/* clear overflow/interrupt */
			temp |= 1 << (i + 16);
			/* enable interrupt*/
			temp |= 1 << (i + 8);
		}
	}

	/* Enable all 8 counters */
	temp |= PMCR_E;
	writel(temp, &emc->PMCR);

	return 0;

 err_free_scu:
	while (i--)
		free_irq(IRQ_PMU_SCU0 + i, NULL);
	return ret;
}

static void scu_stop(void)
{
	struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
	unsigned int temp, i;

	/* Disable counter interrupts */
	/* Don't disable all 8 counters (with the E bit) as they may be in use */
	temp = readl(&emc->PMCR);
	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
		if (scu_em_used & (1 << i))
			temp &= ~(1 << (i + 8));
	}
	writel(temp, &emc->PMCR);

	/* Free counter interrupts and reset counters */
	for (i = 0; i < NUM_SCU_COUNTERS; i++) {
		if (scu_em_used & (1 << i)) {
			scu_reset_counter(emc, i);
			free_irq(IRQ_PMU_SCU0 + i, NULL);
		}
	}
}

struct em_function_data {
	int (*fn)(void);
	int ret;
};

static void em_func(void *data)
{
	struct em_function_data *d = data;
	int ret = d->fn();
	if (ret)
		d->ret = ret;
}

static int em_call_function(int (*fn)(void))
{
	struct em_function_data data;

	data.fn = fn;
	data.ret = 0;

	preempt_disable();
	smp_call_function(em_func, &data, 1, 1);
	em_func(&data);
	preempt_enable();

	return data.ret;
}

/*
 * Glue to stick the individual ARM11 PMUs and the SCU
 * into the oprofile framework.
 */
static int em_setup_ctrs(void)
{
	int ret;

	/* Configure CPU counters by cross-calling to the other CPUs */
	ret = em_call_function(arm11_setup_pmu);
	if (ret == 0)
		scu_setup();

	return 0;
}

static int arm11_irqs[] = {
	[0]	= IRQ_PMU_CPU0,
	[1]	= IRQ_PMU_CPU1,
	[2]	= IRQ_PMU_CPU2,
	[3]	= IRQ_PMU_CPU3
};

static int em_start(void)
{
	int ret;

	ret = arm11_request_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
	if (ret == 0) {
		em_call_function(arm11_start_pmu);

		ret = scu_start();
		if (ret)
			arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
	}
	return ret;
}

static void em_stop(void)
{
	em_call_function(arm11_stop_pmu);
	arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
	scu_stop();
}

/*
 * Why isn't there a function to route an IRQ to a specific CPU in
 * genirq?
 */
static void em_route_irq(int irq, unsigned int cpu)
{
	struct irq_desc *desc = irq_desc + irq;
	cpumask_t mask = cpumask_of_cpu(cpu);

	spin_lock_irq(&desc->lock);
	desc->affinity = mask;
	desc->chip->set_affinity(irq, mask);
	spin_unlock_irq(&desc->lock);
}

static int em_setup(void)
{
	/*
	 * Send SCU PMU interrupts to the "owner" CPU.
	 */
	em_route_irq(IRQ_PMU_SCU0, 0);
	em_route_irq(IRQ_PMU_SCU1, 0);
	em_route_irq(IRQ_PMU_SCU2, 1);
	em_route_irq(IRQ_PMU_SCU3, 1);
	em_route_irq(IRQ_PMU_SCU4, 2);
	em_route_irq(IRQ_PMU_SCU5, 2);
	em_route_irq(IRQ_PMU_SCU6, 3);
	em_route_irq(IRQ_PMU_SCU7, 3);

	/*
	 * Send CP15 PMU interrupts to the owner CPU.
	 */
	em_route_irq(IRQ_PMU_CPU0, 0);
	em_route_irq(IRQ_PMU_CPU1, 1);
	em_route_irq(IRQ_PMU_CPU2, 2);
	em_route_irq(IRQ_PMU_CPU3, 3);

	return 0;
}

struct op_arm_model_spec op_mpcore_spec = {
	.init		= em_setup,
	.num_counters	= MPCORE_NUM_COUNTERS,
	.setup_ctrs	= em_setup_ctrs,
	.start		= em_start,
	.stop		= em_stop,
	.name		= "arm/mpcore",
};
