/*
 * Cell Broadband Engine Performance Monitor
 *
 * (C) Copyright IBM Corporation 2001,2006
 *
 * Author:
 *    David Erb (djerb@us.ibm.com)
 *    Kevin Corry (kevcorry@us.ibm.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/interrupt.h>
#include <linux/types.h>
#include <asm/io.h>
#include <asm/irq_regs.h>
#include <asm/machdep.h>
#include <asm/pmc.h>
#include <asm/reg.h>
#include <asm/spu.h>
#include <asm/cell-regs.h>

#include "interrupt.h"

/*
 * When writing to write-only mmio addresses, save a shadow copy. All of the
 * registers are 32-bit, but stored in the upper-half of a 64-bit field in
 * pmd_regs.
 */

#define WRITE_WO_MMIO(reg, x)					\
	do {							\
		u32 _x = (x);					\
		struct cbe_pmd_regs __iomem *pmd_regs;		\
		struct cbe_pmd_shadow_regs *shadow_regs;	\
		pmd_regs = cbe_get_cpu_pmd_regs(cpu);		\
		shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);	\
		out_be64(&(pmd_regs->reg), (((u64)_x) << 32));	\
		shadow_regs->reg = _x;				\
	} while (0)

#define READ_SHADOW_REG(val, reg)				\
	do {							\
		struct cbe_pmd_shadow_regs *shadow_regs;	\
		shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);	\
		(val) = shadow_regs->reg;			\
	} while (0)

#define READ_MMIO_UPPER32(val, reg)				\
	do {							\
		struct cbe_pmd_regs __iomem *pmd_regs;		\
		pmd_regs = cbe_get_cpu_pmd_regs(cpu);		\
		(val) = (u32)(in_be64(&pmd_regs->reg) >> 32);	\
	} while (0)

/*
 * Physical counter registers.
 * Each physical counter can act as one 32-bit counter or two 16-bit counters.
 */

u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr)
{
	u32 val_in_latch, val = 0;

	if (phys_ctr < NR_PHYS_CTRS) {
		READ_SHADOW_REG(val_in_latch, counter_value_in_latch);

		/* Read the latch or the actual counter, whichever is newer. */
		if (val_in_latch & (1 << phys_ctr)) {
			READ_SHADOW_REG(val, pm_ctr[phys_ctr]);
		} else {
			READ_MMIO_UPPER32(val, pm_ctr[phys_ctr]);
		}
	}

	return val;
}
EXPORT_SYMBOL_GPL(cbe_read_phys_ctr);

void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
{
	struct cbe_pmd_shadow_regs *shadow_regs;
	u32 pm_ctrl;

	if (phys_ctr < NR_PHYS_CTRS) {
		/* Writing to a counter only writes to a hardware latch.
		 * The new value is not propagated to the actual counter
		 * until the performance monitor is enabled.
		 */
		WRITE_WO_MMIO(pm_ctr[phys_ctr], val);

		pm_ctrl = cbe_read_pm(cpu, pm_control);
		if (pm_ctrl & CBE_PM_ENABLE_PERF_MON) {
			/* The counters are already active, so we need to
			 * rewrite the pm_control register to "re-enable"
			 * the PMU.
			 */
			cbe_write_pm(cpu, pm_control, pm_ctrl);
		} else {
			shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
			shadow_regs->counter_value_in_latch |= (1 << phys_ctr);
		}
	}
}
EXPORT_SYMBOL_GPL(cbe_write_phys_ctr);

/*
 * "Logical" counter registers.
 * These will read/write 16-bits or 32-bits depending on the
 * current size of the counter. Counters 4 - 7 are always 16-bit.
 */

u32 cbe_read_ctr(u32 cpu, u32 ctr)
{
	u32 val;
	u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);

	val = cbe_read_phys_ctr(cpu, phys_ctr);

	if (cbe_get_ctr_size(cpu, phys_ctr) == 16)
		val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);

	return val;
}
EXPORT_SYMBOL_GPL(cbe_read_ctr);

void cbe_write_ctr(u32 cpu, u32 ctr, u32 val)
{
	u32 phys_ctr;
	u32 phys_val;

	phys_ctr = ctr & (NR_PHYS_CTRS - 1);

	if (cbe_get_ctr_size(cpu, phys_ctr) == 16) {
		phys_val = cbe_read_phys_ctr(cpu, phys_ctr);

		if (ctr < NR_PHYS_CTRS)
			val = (val << 16) | (phys_val & 0xffff);
		else
			val = (val & 0xffff) | (phys_val & 0xffff0000);
	}

	cbe_write_phys_ctr(cpu, phys_ctr, val);
}
EXPORT_SYMBOL_GPL(cbe_write_ctr);

/*
 * Counter-control registers.
 * Each "logical" counter has a corresponding control register.
 */

u32 cbe_read_pm07_control(u32 cpu, u32 ctr)
{
	u32 pm07_control = 0;

	if (ctr < NR_CTRS)
		READ_SHADOW_REG(pm07_control, pm07_control[ctr]);

	return pm07_control;
}
EXPORT_SYMBOL_GPL(cbe_read_pm07_control);

void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val)
{
	if (ctr < NR_CTRS)
		WRITE_WO_MMIO(pm07_control[ctr], val);
}
EXPORT_SYMBOL_GPL(cbe_write_pm07_control);

/*
 * Other PMU control registers. Most of these are write-only.
 */

u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg)
{
	u32 val = 0;

	switch (reg) {
	case group_control:
		READ_SHADOW_REG(val, group_control);
		break;

	case debug_bus_control:
		READ_SHADOW_REG(val, debug_bus_control);
		break;

	case trace_address:
		READ_MMIO_UPPER32(val, trace_address);
		break;

	case ext_tr_timer:
		READ_SHADOW_REG(val, ext_tr_timer);
		break;

	case pm_status:
		READ_MMIO_UPPER32(val, pm_status);
		break;

	case pm_control:
		READ_SHADOW_REG(val, pm_control);
		break;

	case pm_interval:
		READ_MMIO_UPPER32(val, pm_interval);
		break;

	case pm_start_stop:
		READ_SHADOW_REG(val, pm_start_stop);
		break;
	}

	return val;
}
EXPORT_SYMBOL_GPL(cbe_read_pm);

void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
{
	switch (reg) {
	case group_control:
		WRITE_WO_MMIO(group_control, val);
		break;

	case debug_bus_control:
		WRITE_WO_MMIO(debug_bus_control, val);
		break;

	case trace_address:
		WRITE_WO_MMIO(trace_address, val);
		break;

	case ext_tr_timer:
		WRITE_WO_MMIO(ext_tr_timer, val);
		break;

	case pm_status:
		WRITE_WO_MMIO(pm_status, val);
		break;

	case pm_control:
		WRITE_WO_MMIO(pm_control, val);
		break;

	case pm_interval:
		WRITE_WO_MMIO(pm_interval, val);
		break;

	case pm_start_stop:
		WRITE_WO_MMIO(pm_start_stop, val);
		break;
	}
}
EXPORT_SYMBOL_GPL(cbe_write_pm);

/*
 * Get/set the size of a physical counter to either 16 or 32 bits.
 */

u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr)
{
	u32 pm_ctrl, size = 0;

	if (phys_ctr < NR_PHYS_CTRS) {
		pm_ctrl = cbe_read_pm(cpu, pm_control);
		size = (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
	}

	return size;
}
EXPORT_SYMBOL_GPL(cbe_get_ctr_size);

void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
{
	u32 pm_ctrl;

	if (phys_ctr < NR_PHYS_CTRS) {
		pm_ctrl = cbe_read_pm(cpu, pm_control);
		switch (ctr_size) {
		case 16:
			pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
			break;

		case 32:
			pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
			break;
		}
		cbe_write_pm(cpu, pm_control, pm_ctrl);
	}
}
EXPORT_SYMBOL_GPL(cbe_set_ctr_size);

/*
 * Enable/disable the entire performance monitoring unit.
 * When we enable the PMU, all pending writes to counters get committed.
 */

void cbe_enable_pm(u32 cpu)
{
	struct cbe_pmd_shadow_regs *shadow_regs;
	u32 pm_ctrl;

	shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
	shadow_regs->counter_value_in_latch = 0;

	pm_ctrl = cbe_read_pm(cpu, pm_control) | CBE_PM_ENABLE_PERF_MON;
	cbe_write_pm(cpu, pm_control, pm_ctrl);
}
EXPORT_SYMBOL_GPL(cbe_enable_pm);

void cbe_disable_pm(u32 cpu)
{
	u32 pm_ctrl;
	pm_ctrl = cbe_read_pm(cpu, pm_control) & ~CBE_PM_ENABLE_PERF_MON;
	cbe_write_pm(cpu, pm_control, pm_ctrl);
}
EXPORT_SYMBOL_GPL(cbe_disable_pm);

/*
 * Reading from the trace_buffer.
 * The trace buffer is two 64-bit registers. Reading from
 * the second half automatically increments the trace_address.
 */

void cbe_read_trace_buffer(u32 cpu, u64 *buf)
{
	struct cbe_pmd_regs __iomem *pmd_regs = cbe_get_cpu_pmd_regs(cpu);

	*buf++ = in_be64(&pmd_regs->trace_buffer_0_63);
	*buf++ = in_be64(&pmd_regs->trace_buffer_64_127);
}
EXPORT_SYMBOL_GPL(cbe_read_trace_buffer);

/*
 * Enabling/disabling interrupts for the entire performance monitoring unit.
 */

u32 cbe_get_and_clear_pm_interrupts(u32 cpu)
{
	/* Reading pm_status clears the interrupt bits. */
	return cbe_read_pm(cpu, pm_status);
}
EXPORT_SYMBOL_GPL(cbe_get_and_clear_pm_interrupts);

void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
{
	/* Set which node and thread will handle the next interrupt. */
	iic_set_interrupt_routing(cpu, thread, 0);

	/* Enable the interrupt bits in the pm_status register. */
	if (mask)
		cbe_write_pm(cpu, pm_status, mask);
}
EXPORT_SYMBOL_GPL(cbe_enable_pm_interrupts);

void cbe_disable_pm_interrupts(u32 cpu)
{
	cbe_get_and_clear_pm_interrupts(cpu);
	cbe_write_pm(cpu, pm_status, 0);
}
EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts);

static irqreturn_t cbe_pm_irq(int irq, void *dev_id)
{
	perf_irq(get_irq_regs());
	return IRQ_HANDLED;
}

static int __init cbe_init_pm_irq(void)
{
	unsigned int irq;
	int rc, node;

	for_each_node(node) {
		irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
					       (node << IIC_IRQ_NODE_SHIFT));
		if (irq == NO_IRQ) {
			printk("ERROR: Unable to allocate irq for node %d\n",
			       node);
			return -EINVAL;
		}

		rc = request_irq(irq, cbe_pm_irq,
				 IRQF_DISABLED, "cbe-pmu-0", NULL);
		if (rc) {
			printk("ERROR: Request for irq on node %d failed\n",
			       node);
			return rc;
		}
	}

	return 0;
}
machine_arch_initcall(cell, cbe_init_pm_irq);

void cbe_sync_irq(int node)
{
	unsigned int irq;

	irq = irq_find_mapping(NULL,
			       IIC_IRQ_IOEX_PMI
			       | (node << IIC_IRQ_NODE_SHIFT));

	if (irq == NO_IRQ) {
		printk(KERN_WARNING "ERROR, unable to get existing irq %d " \
		"for node %d\n", irq, node);
		return;
	}

	synchronize_irq(irq);
}
EXPORT_SYMBOL_GPL(cbe_sync_irq);

