/*
 * Copyright 2001 MontaVista Software Inc.
 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
 *
 *  arch/mips/ddb5xxx/ddb5477/irq.c
 *     The irq setup and misc routines for DDB5476.
 *
 * 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 of the  License, or (at your
 * option) any later version.
 */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/types.h>
#include <linux/ptrace.h>

#include <asm/i8259.h>
#include <asm/system.h>
#include <asm/mipsregs.h>
#include <asm/debug.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>

#include <asm/ddb5xxx/ddb5xxx.h>


/*
 * IRQ mapping
 *
 *  0-7: 8 CPU interrupts
 *	0 -	software interrupt 0
 *	1 - 	software interrupt 1
 *	2 - 	most Vrc5477 interrupts are routed to this pin
 *	3 - 	(optional) some other interrupts routed to this pin for debugg
 *	4 - 	not used
 *	5 - 	not used
 *	6 - 	not used
 *	7 - 	cpu timer (used by default)
 *
 *  8-39: 32 Vrc5477 interrupt sources
 *	(refer to the Vrc5477 manual)
 */

#define	PCI0			DDB_INTPPES0
#define	PCI1			DDB_INTPPES1

#define	ACTIVE_LOW		1
#define	ACTIVE_HIGH		0

#define	LEVEL_SENSE		2
#define	EDGE_TRIGGER		0

#define	INTA			0
#define	INTB			1
#define	INTC			2
#define	INTD			3
#define	INTE			4

static inline void
set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger)
{
	u32 reg_value;
	u32 reg_bitmask;

	reg_value = ddb_in32(pci);
	reg_bitmask = 0x3 << (intn * 2);

	reg_value &= ~reg_bitmask;
	reg_value |= (active | trigger) << (intn * 2);
	ddb_out32(pci, reg_value);
}

extern void vrc5477_irq_init(u32 base);
extern void mips_cpu_irq_init(u32 base);
extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL };

void __init arch_init_irq(void)
{
	/* by default, we disable all interrupts and route all vrc5477
	 * interrupts to pin 0 (irq 2) */
	ddb_out32(DDB_INTCTRL0, 0);
	ddb_out32(DDB_INTCTRL1, 0);
	ddb_out32(DDB_INTCTRL2, 0);
	ddb_out32(DDB_INTCTRL3, 0);

	clear_c0_status(0xff00);
	set_c0_status(0x0400);

	/* setup PCI interrupt attributes */
	set_pci_int_attr(PCI0, INTA, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI0, INTB, ACTIVE_LOW, LEVEL_SENSE);
	if (mips_machtype == MACH_NEC_ROCKHOPPERII)
		set_pci_int_attr(PCI0, INTC, ACTIVE_HIGH, LEVEL_SENSE);
	else
		set_pci_int_attr(PCI0, INTC, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI0, INTD, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI0, INTE, ACTIVE_LOW, LEVEL_SENSE);

	set_pci_int_attr(PCI1, INTA, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI1, INTB, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI1, INTC, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI1, INTD, ACTIVE_LOW, LEVEL_SENSE);
	set_pci_int_attr(PCI1, INTE, ACTIVE_LOW, LEVEL_SENSE);

	/*
	 * for debugging purpose, we enable several error interrupts
	 * and route them to pin 1. (IP3)
	 */
	/* cpu parity check - 0 */
	ll_vrc5477_irq_route(0, 1); ll_vrc5477_irq_enable(0);
	/* cpu no-target decode - 1 */
	ll_vrc5477_irq_route(1, 1); ll_vrc5477_irq_enable(1);
	/* local bus read time-out - 7 */
	ll_vrc5477_irq_route(7, 1); ll_vrc5477_irq_enable(7);
	/* PCI SERR# - 14 */
	ll_vrc5477_irq_route(14, 1); ll_vrc5477_irq_enable(14);
	/* PCI internal error - 15 */
	ll_vrc5477_irq_route(15, 1); ll_vrc5477_irq_enable(15);
	/* IOPCI SERR# - 30 */
	ll_vrc5477_irq_route(30, 1); ll_vrc5477_irq_enable(30);
	/* IOPCI internal error - 31 */
	ll_vrc5477_irq_route(31, 1); ll_vrc5477_irq_enable(31);

	/* init all controllers */
	init_i8259_irqs();
	mips_cpu_irq_init(CPU_IRQ_BASE);
	vrc5477_irq_init(VRC5477_IRQ_BASE);


	/* setup cascade interrupts */
	setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade);
	setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade);
}

u8 i8259_interrupt_ack(void)
{
	u8 irq;
	u32 reg;

	/* Set window 0 for interrupt acknowledge */
	reg = ddb_in32(DDB_PCIINIT10);

	ddb_set_pmr(DDB_PCIINIT10, DDB_PCICMD_IACK, 0, DDB_PCI_ACCESS_32);
	irq = *(volatile u8 *) KSEG1ADDR(DDB_PCI_IACK_BASE);
	ddb_out32(DDB_PCIINIT10, reg);

	/* i8259.c set the base vector to be 0x0 */
	return irq + I8259_IRQ_BASE;
}
/*
 * the first level int-handler will jump here if it is a vrc5477 irq
 */
#define	NUM_5477_IRQS	32
static void
vrc5477_irq_dispatch(struct pt_regs *regs)
{
	u32 intStatus;
	u32 bitmask;
	u32 i;

	db_assert(ddb_in32(DDB_INT2STAT) == 0);
	db_assert(ddb_in32(DDB_INT3STAT) == 0);
	db_assert(ddb_in32(DDB_INT4STAT) == 0);
	db_assert(ddb_in32(DDB_NMISTAT) == 0);

	if (ddb_in32(DDB_INT1STAT) != 0) {
#if defined(CONFIG_RUNTIME_DEBUG)
		vrc5477_show_int_regs();
#endif
		panic("error interrupt has happened.");
	}

	intStatus = ddb_in32(DDB_INT0STAT);

	if (mips_machtype == MACH_NEC_ROCKHOPPERII) {
		/* check for i8259 interrupts */
		if (intStatus & (1 << VRC5477_I8259_CASCADE)) {
			int i8259_irq = i8259_interrupt_ack();
			do_IRQ(I8259_IRQ_BASE + i8259_irq, regs);
			return;
		}
	}

	for (i=0, bitmask=1; i<= NUM_5477_IRQS; bitmask <<=1, i++) {
		/* do we need to "and" with the int mask? */
		if (intStatus & bitmask) {
			do_IRQ(VRC5477_IRQ_BASE + i, regs);
			return;
		}
	}
}

#define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6)

asmlinkage void plat_irq_dispatch(struct pt_regs *regs)
{
	unsigned int pending = read_c0_cause() & read_c0_status();

	if (pending & STATUSF_IP7)
		do_IRQ(CPU_IRQ_BASE + 7, regs);
	else if (pending & VR5477INTS)
		vrc5477_irq_dispatch(regs);
	else if (pending & STATUSF_IP0)
		do_IRQ(CPU_IRQ_BASE, regs);
	else if (pending & STATUSF_IP1)
		do_IRQ(CPU_IRQ_BASE + 1, regs);
	else
		spurious_interrupt(regs);
}
