/*
 * Copyright (C) 1999, 2000, 2006  MIPS Technologies, Inc.
 *	All rights reserved.
 *	Authors: Carsten Langgaard <carstenl@mips.com>
 *		 Maciej W. Rozycki <macro@mips.com>
 *
 * ########################################################################
 *
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope 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.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * ########################################################################
 *
 * Routines for generic manipulation of the interrupts found on the MIPS
 * Atlas board.
 *
 */
#include <linux/compiler.h>
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/kernel.h>

#include <asm/gdb-stub.h>
#include <asm/io.h>
#include <asm/irq_cpu.h>
#include <asm/msc01_ic.h>

#include <asm/mips-boards/atlas.h>
#include <asm/mips-boards/atlasint.h>
#include <asm/mips-boards/generic.h>

static struct atlas_ictrl_regs *atlas_hw0_icregs;

#if 0
#define DEBUG_INT(x...) printk(x)
#else
#define DEBUG_INT(x...)
#endif

void disable_atlas_irq(unsigned int irq_nr)
{
	atlas_hw0_icregs->intrsten = 1 << (irq_nr - ATLAS_INT_BASE);
	iob();
}

void enable_atlas_irq(unsigned int irq_nr)
{
	atlas_hw0_icregs->intseten = 1 << (irq_nr - ATLAS_INT_BASE);
	iob();
}

static void end_atlas_irq(unsigned int irq)
{
	if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
		enable_atlas_irq(irq);
}

static struct irq_chip atlas_irq_type = {
	.name = "Atlas",
	.ack = disable_atlas_irq,
	.mask = disable_atlas_irq,
	.mask_ack = disable_atlas_irq,
	.unmask = enable_atlas_irq,
	.eoi = enable_atlas_irq,
	.end = end_atlas_irq,
};

static inline int ls1bit32(unsigned int x)
{
	int b = 31, s;

	s = 16; if (x << 16 == 0) s = 0; b -= s; x <<= s;
	s =  8; if (x <<  8 == 0) s = 0; b -= s; x <<= s;
	s =  4; if (x <<  4 == 0) s = 0; b -= s; x <<= s;
	s =  2; if (x <<  2 == 0) s = 0; b -= s; x <<= s;
	s =  1; if (x <<  1 == 0) s = 0; b -= s;

	return b;
}

static inline void atlas_hw0_irqdispatch(void)
{
	unsigned long int_status;
	int irq;

	int_status = atlas_hw0_icregs->intstatus;

	/* if int_status == 0, then the interrupt has already been cleared */
	if (unlikely(int_status == 0))
		return;

	irq = ATLAS_INT_BASE + ls1bit32(int_status);

	DEBUG_INT("atlas_hw0_irqdispatch: irq=%d\n", irq);

	do_IRQ(irq);
}

static inline int clz(unsigned long x)
{
	__asm__ (
	"	.set	push					\n"
	"	.set	mips32					\n"
	"	clz	%0, %1					\n"
	"	.set	pop					\n"
	: "=r" (x)
	: "r" (x));

	return x;
}

/*
 * Version of ffs that only looks at bits 12..15.
 */
static inline unsigned int irq_ffs(unsigned int pending)
{
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
	return -clz(pending) + 31 - CAUSEB_IP;
#else
	unsigned int a0 = 7;
	unsigned int t0;

	t0 = s0 & 0xf000;
	t0 = t0 < 1;
	t0 = t0 << 2;
	a0 = a0 - t0;
	s0 = s0 << t0;

	t0 = s0 & 0xc000;
	t0 = t0 < 1;
	t0 = t0 << 1;
	a0 = a0 - t0;
	s0 = s0 << t0;

	t0 = s0 & 0x8000;
	t0 = t0 < 1;
	//t0 = t0 << 2;
	a0 = a0 - t0;
	//s0 = s0 << t0;

	return a0;
#endif
}

/*
 * IRQs on the Atlas board look basically like (all external interrupt
 * sources are combined together on hardware interrupt 0 (MIPS IRQ 2)):
 *
 *      MIPS IRQ        Source
 *      --------        ------
 *             0        Software 0 (reschedule IPI on MT)
 *             1        Software 1 (remote call IPI on MT)
 *             2        Combined Atlas hardware interrupt (hw0)
 *             3        Hardware (ignored)
 *             4        Hardware (ignored)
 *             5        Hardware (ignored)
 *             6        Hardware (ignored)
 *             7        R4k timer (what we use)
 *
 * We handle the IRQ according to _our_ priority which is:
 *
 * Highest ----     R4k Timer
 * Lowest  ----     Software 0
 *
 * then we just return, if multiple IRQs are pending then we will just take
 * another exception, big deal.
 */
asmlinkage void plat_irq_dispatch(void)
{
	unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
	int irq;

	irq = irq_ffs(pending);

	if (irq == MIPSCPU_INT_ATLAS)
		atlas_hw0_irqdispatch();
	else if (irq >= 0)
		do_IRQ(MIPSCPU_INT_BASE + irq);
	else
		spurious_interrupt();
}

static inline void init_atlas_irqs (int base)
{
	int i;

	atlas_hw0_icregs = (struct atlas_ictrl_regs *)
			   ioremap(ATLAS_ICTRL_REGS_BASE,
				   sizeof(struct atlas_ictrl_regs *));

	/*
	 * Mask out all interrupt by writing "1" to all bit position in
	 * the interrupt reset reg.
	 */
	atlas_hw0_icregs->intrsten = 0xffffffff;

	for (i = ATLAS_INT_BASE; i <= ATLAS_INT_END; i++)
		set_irq_chip_and_handler(i, &atlas_irq_type, handle_level_irq);
}

static struct irqaction atlasirq = {
	.handler = no_action,
	.name = "Atlas cascade"
};

msc_irqmap_t __initdata msc_irqmap[] = {
	{MSC01C_INT_TMR,		MSC01_IRQ_EDGE, 0},
	{MSC01C_INT_PCI,		MSC01_IRQ_LEVEL, 0},
};
int __initdata msc_nr_irqs = ARRAY_SIZE(msc_irqmap);

msc_irqmap_t __initdata msc_eicirqmap[] = {
	{MSC01E_INT_SW0,		MSC01_IRQ_LEVEL, 0},
	{MSC01E_INT_SW1,		MSC01_IRQ_LEVEL, 0},
	{MSC01E_INT_ATLAS,		MSC01_IRQ_LEVEL, 0},
	{MSC01E_INT_TMR,		MSC01_IRQ_EDGE, 0},
	{MSC01E_INT_PCI,		MSC01_IRQ_LEVEL, 0},
	{MSC01E_INT_PERFCTR,		MSC01_IRQ_LEVEL, 0},
	{MSC01E_INT_CPUCTR,		MSC01_IRQ_LEVEL, 0}
};
int __initdata msc_nr_eicirqs = ARRAY_SIZE(msc_eicirqmap);

void __init arch_init_irq(void)
{
	init_atlas_irqs(ATLAS_INT_BASE);

	if (!cpu_has_veic)
		mips_cpu_irq_init();

	switch(mips_revision_corid) {
	case MIPS_REVISION_CORID_CORE_MSC:
	case MIPS_REVISION_CORID_CORE_FPGA2:
	case MIPS_REVISION_CORID_CORE_FPGA3:
	case MIPS_REVISION_CORID_CORE_24K:
	case MIPS_REVISION_CORID_CORE_EMUL_MSC:
		if (cpu_has_veic)
			init_msc_irqs (MSC01E_INT_BASE,
				       msc_eicirqmap, msc_nr_eicirqs);
		else
			init_msc_irqs (MSC01C_INT_BASE,
				       msc_irqmap, msc_nr_irqs);
	}


	if (cpu_has_veic) {
		set_vi_handler (MSC01E_INT_ATLAS, atlas_hw0_irqdispatch);
		setup_irq (MSC01E_INT_BASE + MSC01E_INT_ATLAS, &atlasirq);
	} else if (cpu_has_vint) {
		set_vi_handler (MIPSCPU_INT_ATLAS, atlas_hw0_irqdispatch);
#ifdef CONFIG_MIPS_MT_SMTC
		setup_irq_smtc (MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS,
				&atlasirq, (0x100 << MIPSCPU_INT_ATLAS));
#else /* Not SMTC */
		setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
#endif /* CONFIG_MIPS_MT_SMTC */
	} else
		setup_irq(MIPSCPU_INT_BASE + MIPSCPU_INT_ATLAS, &atlasirq);
}
