/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * arch/sh64/kernel/irq_intc.c
 *
 * Copyright (C) 2000, 2001  Paolo Alberelli
 * Copyright (C) 2003  Paul Mundt
 *
 * Interrupt Controller support for SH5 INTC.
 * Per-interrupt selective. IRLM=0 (Fixed priority) is not
 * supported being useless without a cascaded interrupt
 * controller.
 *
 */

#include <linux/init.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/bitops.h>       /* this includes also <asm/registers.h */
                                /* which is required to remap register */
                                /* names used into __asm__ blocks...   */

#include <asm/hardware.h>
#include <asm/platform.h>
#include <asm/page.h>
#include <asm/io.h>
#include <asm/irq.h>

/*
 * Maybe the generic Peripheral block could move to a more
 * generic include file. INTC Block will be defined here
 * and only here to make INTC self-contained in a single
 * file.
 */
#define	INTC_BLOCK_OFFSET	0x01000000

/* Base */
#define INTC_BASE		PHYS_PERIPHERAL_BLOCK + \
				INTC_BLOCK_OFFSET

/* Address */
#define INTC_ICR_SET		(intc_virt + 0x0)
#define INTC_ICR_CLEAR		(intc_virt + 0x8)
#define INTC_INTPRI_0		(intc_virt + 0x10)
#define INTC_INTSRC_0		(intc_virt + 0x50)
#define INTC_INTSRC_1		(intc_virt + 0x58)
#define INTC_INTREQ_0		(intc_virt + 0x60)
#define INTC_INTREQ_1		(intc_virt + 0x68)
#define INTC_INTENB_0		(intc_virt + 0x70)
#define INTC_INTENB_1		(intc_virt + 0x78)
#define INTC_INTDSB_0		(intc_virt + 0x80)
#define INTC_INTDSB_1		(intc_virt + 0x88)

#define INTC_ICR_IRLM		0x1
#define	INTC_INTPRI_PREGS	8		/* 8 Priority Registers */
#define	INTC_INTPRI_PPREG	8		/* 8 Priorities per Register */


/*
 * Mapper between the vector ordinal and the IRQ number
 * passed to kernel/device drivers.
 */
int intc_evt_to_irq[(0xE20/0x20)+1] = {
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x000 - 0x0E0 */
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x100 - 0x1E0 */
	 0,  0,  0,  0,  0,  1,  0,  0,	/* 0x200 - 0x2E0 */
	 2,  0,  0,  3,  0,  0,  0, -1,	/* 0x300 - 0x3E0 */
	32, 33, 34, 35, 36, 37, 38, -1,	/* 0x400 - 0x4E0 */
	-1, -1, -1, 63, -1, -1, -1, -1,	/* 0x500 - 0x5E0 */
	-1, -1, 18, 19, 20, 21, 22, -1,	/* 0x600 - 0x6E0 */
	39, 40, 41, 42, -1, -1, -1, -1,	/* 0x700 - 0x7E0 */
	 4,  5,  6,  7, -1, -1, -1, -1,	/* 0x800 - 0x8E0 */
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0x900 - 0x9E0 */
	12, 13, 14, 15, 16, 17, -1, -1,	/* 0xA00 - 0xAE0 */
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xB00 - 0xBE0 */
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xC00 - 0xCE0 */
	-1, -1, -1, -1, -1, -1, -1, -1,	/* 0xD00 - 0xDE0 */
	-1, -1				/* 0xE00 - 0xE20 */
};

/*
 * Opposite mapper.
 */
static int IRQ_to_vectorN[NR_INTC_IRQS] = {
	0x12, 0x15, 0x18, 0x1B, 0x40, 0x41, 0x42, 0x43, /*  0- 7 */
	  -1,   -1,   -1,   -1, 0x50, 0x51, 0x52, 0x53,	/*  8-15 */
	0x54, 0x55, 0x32, 0x33, 0x34, 0x35, 0x36,   -1, /* 16-23 */
	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 24-31 */
	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x38,	/* 32-39 */
        0x39, 0x3A, 0x3B,   -1,   -1,   -1,   -1,   -1, /* 40-47 */
	  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1, /* 48-55 */
	  -1,   -1,   -1,   -1,   -1,   -1,   -1, 0x2B, /* 56-63 */

};

static unsigned long intc_virt;

static unsigned int startup_intc_irq(unsigned int irq);
static void shutdown_intc_irq(unsigned int irq);
static void enable_intc_irq(unsigned int irq);
static void disable_intc_irq(unsigned int irq);
static void mask_and_ack_intc(unsigned int);
static void end_intc_irq(unsigned int irq);

static struct hw_interrupt_type intc_irq_type = {
	.typename = "INTC",
	.startup = startup_intc_irq,
	.shutdown = shutdown_intc_irq,
	.enable = enable_intc_irq,
	.disable = disable_intc_irq,
	.ack = mask_and_ack_intc,
	.end = end_intc_irq
};

static int irlm;		/* IRL mode */

static unsigned int startup_intc_irq(unsigned int irq)
{
	enable_intc_irq(irq);
	return 0; /* never anything pending */
}

static void shutdown_intc_irq(unsigned int irq)
{
	disable_intc_irq(irq);
}

static void enable_intc_irq(unsigned int irq)
{
	unsigned long reg;
	unsigned long bitmask;

	if ((irq <= IRQ_IRL3) && (irlm == NO_PRIORITY))
		printk("Trying to use straight IRL0-3 with an encoding platform.\n");

	if (irq < 32) {
		reg = INTC_INTENB_0;
		bitmask = 1 << irq;
	} else {
		reg = INTC_INTENB_1;
		bitmask = 1 << (irq - 32);
	}

	ctrl_outl(bitmask, reg);
}

static void disable_intc_irq(unsigned int irq)
{
	unsigned long reg;
	unsigned long bitmask;

	if (irq < 32) {
		reg = INTC_INTDSB_0;
		bitmask = 1 << irq;
	} else {
		reg = INTC_INTDSB_1;
		bitmask = 1 << (irq - 32);
	}

	ctrl_outl(bitmask, reg);
}

static void mask_and_ack_intc(unsigned int irq)
{
	disable_intc_irq(irq);
}

static void end_intc_irq(unsigned int irq)
{
	enable_intc_irq(irq);
}

/* For future use, if we ever support IRLM=0) */
void make_intc_irq(unsigned int irq)
{
	disable_irq_nosync(irq);
	irq_desc[irq].chip = &intc_irq_type;
	disable_intc_irq(irq);
}

#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
int intc_irq_describe(char* p, int irq)
{
	if (irq < NR_INTC_IRQS)
		return sprintf(p, "(0x%3x)", IRQ_to_vectorN[irq]*0x20);
	else
		return 0;
}
#endif

void __init init_IRQ(void)
{
        unsigned long long __dummy0, __dummy1=~0x00000000100000f0;
	unsigned long reg;
	unsigned long data;
	int i;

	intc_virt = onchip_remap(INTC_BASE, 1024, "INTC");
	if (!intc_virt) {
		panic("Unable to remap INTC\n");
	}


	/* Set default: per-line enable/disable, priority driven ack/eoi */
	for (i = 0; i < NR_INTC_IRQS; i++) {
		if (platform_int_priority[i] != NO_PRIORITY) {
			irq_desc[i].chip = &intc_irq_type;
		}
	}


	/* Disable all interrupts and set all priorities to 0 to avoid trouble */
	ctrl_outl(-1, INTC_INTDSB_0);
	ctrl_outl(-1, INTC_INTDSB_1);

	for (reg = INTC_INTPRI_0, i = 0; i < INTC_INTPRI_PREGS; i++, reg += 8)
		ctrl_outl( NO_PRIORITY, reg);


	/* Set IRLM */
	/* If all the priorities are set to 'no priority', then
	 * assume we are using encoded mode.
	 */
	irlm = platform_int_priority[IRQ_IRL0] + platform_int_priority[IRQ_IRL1] + \
		platform_int_priority[IRQ_IRL2] + platform_int_priority[IRQ_IRL3];

	if (irlm == NO_PRIORITY) {
		/* IRLM = 0 */
		reg = INTC_ICR_CLEAR;
		i = IRQ_INTA;
		printk("Trying to use encoded IRL0-3. IRLs unsupported.\n");
	} else {
		/* IRLM = 1 */
		reg = INTC_ICR_SET;
		i = IRQ_IRL0;
	}
	ctrl_outl(INTC_ICR_IRLM, reg);

	/* Set interrupt priorities according to platform description */
	for (data = 0, reg = INTC_INTPRI_0; i < NR_INTC_IRQS; i++) {
		data |= platform_int_priority[i] << ((i % INTC_INTPRI_PPREG) * 4);
		if ((i % INTC_INTPRI_PPREG) == (INTC_INTPRI_PPREG - 1)) {
			/* Upon the 7th, set Priority Register */
			ctrl_outl(data, reg);
			data = 0;
			reg += 8;
		}
	}

#ifdef CONFIG_SH_CAYMAN
	{
		extern void init_cayman_irq(void);

		init_cayman_irq();
	}
#endif

	/*
	 * And now let interrupts come in.
	 * sti() is not enough, we need to
	 * lower priority, too.
	 */
        __asm__ __volatile__("getcon    " __SR ", %0\n\t"
                             "and       %0, %1, %0\n\t"
                             "putcon    %0, " __SR "\n\t"
                             : "=&r" (__dummy0)
                             : "r" (__dummy1));
}
