/*
 * ARC700 Simulation-only Extensions for SMP
 *
 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
 *
 * 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.
 *
 *  Vineet Gupta    - 2012 : split off arch common and plat specific SMP
 *  Rajeshwar Ranga - 2007 : Interrupt Distribution Unit API's
 */

#include <linux/smp.h>
#include <linux/irq.h>
#include <plat/smp.h>

#define IDU_INTERRUPT_0 16

static char smp_cpuinfo_buf[128];

/*
 *-------------------------------------------------------------------
 * Platform specific callbacks expected by arch SMP code
 *-------------------------------------------------------------------
 */

/*
 * Master kick starting another CPU
 */
static void iss_model_smp_wakeup_cpu(int cpu, unsigned long pc)
{
	/* setup the start PC */
	write_aux_reg(ARC_AUX_XTL_REG_PARAM, pc);

	/* Trigger WRITE_PC cmd for this cpu */
	write_aux_reg(ARC_AUX_XTL_REG_CMD,
			(ARC_XTL_CMD_WRITE_PC | (cpu << 8)));

	/* Take the cpu out of Halt */
	write_aux_reg(ARC_AUX_XTL_REG_CMD,
			(ARC_XTL_CMD_CLEAR_HALT | (cpu << 8)));

}

static inline int get_hw_config_num_irq(void)
{
	uint32_t val = read_aux_reg(ARC_REG_VECBASE_BCR);

	switch (val & 0x03) {
	case 0:
		return 16;
	case 1:
		return 32;
	case 2:
		return 8;
	default:
		return 0;
	}

	return 0;
}

/*
 * Any SMP specific init any CPU does when it comes up.
 * Here we setup the CPU to enable Inter-Processor-Interrupts
 * Called for each CPU
 * -Master      : init_IRQ()
 * -Other(s)    : start_kernel_secondary()
 */
void iss_model_init_smp(unsigned int cpu)
{
	/* Check if CPU is configured for more than 16 interrupts */
	if (NR_IRQS <= 16 || get_hw_config_num_irq() <= 16)
		panic("[arcfpga] IRQ system can't support IDU IPI\n");

	idu_disable();

	/****************************************************************
	 * IDU provides a set of Common IRQs, each of which can be dynamically
	 * attached to (1|many|all) CPUs.
	 * The Common IRQs [0-15] are mapped as CPU pvt [16-31]
	 *
	 * Here we use a simple 1:1 mapping:
	 * A CPU 'x' is wired to Common IRQ 'x'.
	 * So an IDU ASSERT on IRQ 'x' will trigger Interupt on CPU 'x', which
	 * makes up for our simple IPI plumbing.
	 *
	 * TBD: Have a dedicated multicast IRQ for sending IPIs to all CPUs
	 *      w/o having to do one-at-a-time
	 ******************************************************************/

	/*
	 * Claim an IRQ which would trigger IPI on this CPU.
	 * In IDU parlance it involves setting up a cpu bitmask for the IRQ
	 * The bitmap here contains only 1 CPU (self).
	 */
	idu_irq_set_tgtcpu(cpu, 0x1 << cpu);

	/* Set the IRQ destination to use the bitmask above */
	idu_irq_set_mode(cpu, 7, /* XXX: IDU_IRQ_MOD_TCPU_ALLRECP: ISS bug */
			 IDU_IRQ_MODE_PULSE_TRIG);

	idu_enable();

	/* Attach the arch-common IPI ISR to our IDU IRQ */
	smp_ipi_irq_setup(cpu, IDU_INTERRUPT_0 + cpu);
}

static void iss_model_ipi_send(int cpu)
{
	idu_irq_assert(cpu);
}

static void iss_model_ipi_clear(int irq)
{
	idu_irq_clear(IDU_INTERRUPT_0 + smp_processor_id());
}

void iss_model_init_early_smp(void)
{
#define IS_AVAIL1(var, str)    ((var) ? str : "")

	struct bcr_mp mp;

	READ_BCR(ARC_REG_MP_BCR, mp);

	sprintf(smp_cpuinfo_buf, "Extn [ISS-SMP]: v%d, arch(%d) %s %s %s\n",
		mp.ver, mp.mp_arch, IS_AVAIL1(mp.scu, "SCU"),
		IS_AVAIL1(mp.idu, "IDU"), IS_AVAIL1(mp.sdu, "SDU"));

	plat_smp_ops.info = smp_cpuinfo_buf;

	plat_smp_ops.cpu_kick = iss_model_smp_wakeup_cpu;
	plat_smp_ops.ipi_send = iss_model_ipi_send;
	plat_smp_ops.ipi_clear = iss_model_ipi_clear;
}

/*
 *-------------------------------------------------------------------
 * Low level Platform IPI Providers
 *-------------------------------------------------------------------
 */

/* Set the Mode for the Common IRQ */
void idu_irq_set_mode(uint8_t irq, uint8_t dest_mode, uint8_t trig_mode)
{
	uint32_t par = IDU_IRQ_MODE_PARAM(dest_mode, trig_mode);

	IDU_SET_PARAM(par);
	IDU_SET_COMMAND(irq, IDU_IRQ_WMODE);
}

/* Set the target cpu Bitmask for Common IRQ */
void idu_irq_set_tgtcpu(uint8_t irq, uint32_t mask)
{
	IDU_SET_PARAM(mask);
	IDU_SET_COMMAND(irq, IDU_IRQ_WBITMASK);
}

/* Get the Interrupt Acknowledged status for IRQ (as CPU Bitmask) */
bool idu_irq_get_ack(uint8_t irq)
{
	uint32_t val;

	IDU_SET_COMMAND(irq, IDU_IRQ_ACK);
	val = IDU_GET_PARAM();

	return val & (1 << irq);
}

/*
 * Get the Interrupt Pending status for IRQ (as CPU Bitmask)
 * -Pending means CPU has not yet noticed the IRQ (e.g. disabled)
 * -After Interrupt has been taken, the IPI expcitily needs to be
 *  cleared, to be acknowledged.
 */
bool idu_irq_get_pend(uint8_t irq)
{
	uint32_t val;

	IDU_SET_COMMAND(irq, IDU_IRQ_PEND);
	val = IDU_GET_PARAM();

	return val & (1 << irq);
}
