/*
 *	linux/arch/alpha/kernel/sys_eiger.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996, 1999 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *	Copyright (C) 1999 Iain Grant
 *
 * Code supporting the EIGER (EV6+TSUNAMI).
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/pgtable.h>
#include <asm/core_tsunami.h>
#include <asm/hwrpb.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"


/* Note that this interrupt code is identical to TAKARA.  */

/* Note mask bit is true for DISABLED irqs.  */
static unsigned long cached_irq_mask[2] = { -1, -1 };

static inline void
eiger_update_irq_hw(unsigned long irq, unsigned long mask)
{
	int regaddr;

	mask = (irq >= 64 ? mask << 16 : mask >> ((irq - 16) & 0x30));
	regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
	outl(mask & 0xffff0000UL, regaddr);
}

static inline void
eiger_enable_irq(unsigned int irq)
{
	unsigned long mask;
	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
	eiger_update_irq_hw(irq, mask);
}

static void
eiger_disable_irq(unsigned int irq)
{
	unsigned long mask;
	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
	eiger_update_irq_hw(irq, mask);
}

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

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

static struct hw_interrupt_type eiger_irq_type = {
	.typename	= "EIGER",
	.startup	= eiger_startup_irq,
	.shutdown	= eiger_disable_irq,
	.enable		= eiger_enable_irq,
	.disable	= eiger_disable_irq,
	.ack		= eiger_disable_irq,
	.end		= eiger_end_irq,
};

static void
eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
	unsigned intstatus;

	/*
	 * The PALcode will have passed us vectors 0x800 or 0x810,
	 * which are fairly arbitrary values and serve only to tell
	 * us whether an interrupt has come in on IRQ0 or IRQ1. If
	 * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
	 * probably ISA, but PCI interrupts can come through IRQ0
	 * as well if the interrupt controller isn't in accelerated
	 * mode.
	 *
	 * OTOH, the accelerator thing doesn't seem to be working
	 * overly well, so what we'll do instead is try directly
	 * examining the Master Interrupt Register to see if it's a
	 * PCI interrupt, and if _not_ then we'll pass it on to the
	 * ISA handler.
	 */

	intstatus = inw(0x500) & 15;
	if (intstatus) {
		/*
		 * This is a PCI interrupt. Check each bit and
		 * despatch an interrupt if it's set.
		 */

		if (intstatus & 8) handle_irq(16+3, regs);
		if (intstatus & 4) handle_irq(16+2, regs);
		if (intstatus & 2) handle_irq(16+1, regs);
		if (intstatus & 1) handle_irq(16+0, regs);
	} else {
		isa_device_interrupt(vector, regs);
	}
}

static void
eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
	int irq = (vector - 0x800) >> 4;
	handle_irq(irq, regs);
}

static void __init
eiger_init_irq(void)
{
	long i;

	outb(0, DMA1_RESET_REG);
	outb(0, DMA2_RESET_REG);
	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
	outb(0, DMA2_MASK_REG);

	if (alpha_using_srm)
		alpha_mv.device_interrupt = eiger_srm_device_interrupt;

	for (i = 16; i < 128; i += 16)
		eiger_update_irq_hw(i, -1);

	init_i8259a_irqs();

	for (i = 16; i < 128; ++i) {
		irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL;
		irq_desc[i].handler = &eiger_irq_type;
	}
}

static int __init
eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
	u8 irq_orig;

	/* The SRM console has already calculated out the IRQ value's for
	   option cards. As this works lets just read in the value already
	   set and change it to a useable value by Linux.

	   All the IRQ values generated by the console are greater than 90,
	   so we subtract 80 because it is (90 - allocated ISA IRQ's).  */

	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_orig);

	return irq_orig - 0x80;
}

static u8 __init
eiger_swizzle(struct pci_dev *dev, u8 *pinp)
{
	struct pci_controller *hose = dev->sysdata;
	int slot, pin = *pinp;
	int bridge_count = 0;

	/* Find the number of backplane bridges.  */
	int backplane = inw(0x502) & 0x0f;

	switch (backplane)
	{
	   case 0x00: bridge_count = 0; break; /* No bridges */
	   case 0x01: bridge_count = 1; break; /* 1 */
	   case 0x03: bridge_count = 2; break; /* 2 */
	   case 0x07: bridge_count = 3; break; /* 3 */
	   case 0x0f: bridge_count = 4; break; /* 4 */
	};

	slot = PCI_SLOT(dev->devfn);
	while (dev->bus->self) {
		/* Check for built-in bridges on hose 0. */
		if (hose->index == 0
		    && (PCI_SLOT(dev->bus->self->devfn)
			> 20 - bridge_count)) {
			slot = PCI_SLOT(dev->devfn);
			break;
		}
		/* Must be a card-based bridge.  */
		pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));

		/* Move up the chain of bridges.  */
		dev = dev->bus->self;
	}
	*pinp = pin;
	return slot;
}

/*
 * The System Vectors
 */

struct alpha_machine_vector eiger_mv __initmv = {
	.vector_name		= "Eiger",
	DO_EV6_MMU,
	DO_DEFAULT_RTC,
	DO_TSUNAMI_IO,
	.machine_check		= tsunami_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,
	.pci_dac_offset		= TSUNAMI_DAC_OFFSET,

	.nr_irqs		= 128,
	.device_interrupt	= eiger_device_interrupt,

	.init_arch		= tsunami_init_arch,
	.init_irq		= eiger_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= common_init_pci,
	.kill_arch		= tsunami_kill_arch,
	.pci_map_irq		= eiger_map_irq,
	.pci_swizzle		= eiger_swizzle,
};
ALIAS_MV(eiger)
