/*
 * arch/mips/vr41xx/nec-cmbvr4133/pci_fixup.c
 *
 * The NEC CMB-VR4133 Board specific PCI fixups.
 *
 * Author: Yoichi Yuasa <yyuasa@mvista.com, or source@mvista.com> and
 *         Alex Sapkov <asapkov@ru.mvista.com>
 *
 * 2003-2004 (c) MontaVista, Software, Inc. This file is licensed under
 * the terms of the GNU General Public License version 2. This program
 * is licensed "as is" without any warranty of any kind, whether express
 * or implied.
 *
 * Modified for support in 2.6
 * Author: Manish Lachwani (mlachwani@mvista.com)
 *
 */
#include <linux/init.h>
#include <linux/pci.h>

#include <asm/io.h>
#include <asm/vr41xx/cmbvr4133.h>

extern int vr4133_rockhopper;
extern void ali_m1535plus_init(struct pci_dev *dev);
extern void ali_m5229_init(struct pci_dev *dev);

/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
	/*
	 * We have to reset AMD PCnet adapter on Rockhopper since
	 * PMON leaves it enabled and generating interrupts. This leads
	 * to a lock if some PCI device driver later enables the IRQ line
	 * shared with PCnet and there is no AMD PCnet driver to catch its
	 * interrupts.
	 */
#ifdef CONFIG_ROCKHOPPER
	if (dev->vendor == PCI_VENDOR_ID_AMD &&
		dev->device == PCI_DEVICE_ID_AMD_LANCE) {
		inl(pci_resource_start(dev, 0) + 0x18);
	}
#endif

	/*
	 * we have to open the bridges' windows down to 0 because otherwise
	 * we cannot access ISA south bridge I/O registers that get mapped from
	 * 0. for example, 8259 PIC would be unaccessible without that
	 */
	if(dev->vendor == PCI_VENDOR_ID_INTEL && dev->device == PCI_DEVICE_ID_INTEL_S21152BB) {
		pci_write_config_byte(dev, PCI_IO_BASE, 0);
		if(dev->bus->number == 0) {
			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0);
		} else {
			pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 1);
		}
	}

	return 0;
}

/*
 * M1535 IRQ mapping
 * Feel free to change this, although it shouldn't be needed
 */
#define M1535_IRQ_INTA  7
#define M1535_IRQ_INTB  9
#define M1535_IRQ_INTC  10
#define M1535_IRQ_INTD  11

#define M1535_IRQ_USB   9
#define M1535_IRQ_IDE   14
#define M1535_IRQ_IDE2  15
#define M1535_IRQ_PS2   12
#define M1535_IRQ_RTC   8
#define M1535_IRQ_FDC   6
#define M1535_IRQ_AUDIO 5
#define M1535_IRQ_COM1  4
#define M1535_IRQ_COM2  4
#define M1535_IRQ_IRDA  3
#define M1535_IRQ_KBD   1
#define M1535_IRQ_TMR   0

/* Rockhopper "slots" assignment; this is hard-coded ... */
#define ROCKHOPPER_M5451_SLOT  1
#define ROCKHOPPER_M1535_SLOT  2
#define ROCKHOPPER_M5229_SLOT  11
#define ROCKHOPPER_M5237_SLOT  15
#define ROCKHOPPER_PMU_SLOT    12
/* ... and hard-wired. */
#define ROCKHOPPER_PCI1_SLOT   3
#define ROCKHOPPER_PCI2_SLOT   4
#define ROCKHOPPER_PCI3_SLOT   5
#define ROCKHOPPER_PCI4_SLOT   6
#define ROCKHOPPER_PCNET_SLOT  1

#define M1535_IRQ_MASK(n) (1 << (n))

#define M1535_IRQ_EDGE  (M1535_IRQ_MASK(M1535_IRQ_TMR)  | \
                         M1535_IRQ_MASK(M1535_IRQ_KBD)  | \
                         M1535_IRQ_MASK(M1535_IRQ_COM1) | \
                         M1535_IRQ_MASK(M1535_IRQ_COM2) | \
                         M1535_IRQ_MASK(M1535_IRQ_IRDA) | \
                         M1535_IRQ_MASK(M1535_IRQ_RTC)  | \
                         M1535_IRQ_MASK(M1535_IRQ_FDC)  | \
                         M1535_IRQ_MASK(M1535_IRQ_PS2))

#define M1535_IRQ_LEVEL (M1535_IRQ_MASK(M1535_IRQ_IDE)  | \
                         M1535_IRQ_MASK(M1535_IRQ_USB)  | \
                         M1535_IRQ_MASK(M1535_IRQ_INTA) | \
                         M1535_IRQ_MASK(M1535_IRQ_INTB) | \
                         M1535_IRQ_MASK(M1535_IRQ_INTC) | \
                         M1535_IRQ_MASK(M1535_IRQ_INTD))

struct irq_map_entry {
	u16 bus;
	u8 slot;
	u8 irq;
};
static struct irq_map_entry int_map[] = {
	{1, ROCKHOPPER_M5451_SLOT, M1535_IRQ_AUDIO},	/* Audio controller */
	{1, ROCKHOPPER_PCI1_SLOT, M1535_IRQ_INTD},	/* PCI slot #1 */
	{1, ROCKHOPPER_PCI2_SLOT, M1535_IRQ_INTC},	/* PCI slot #2 */
	{1, ROCKHOPPER_M5237_SLOT, M1535_IRQ_USB},	/* USB host controller */
	{1, ROCKHOPPER_M5229_SLOT, IDE_PRIMARY_IRQ},	/* IDE controller */
	{2, ROCKHOPPER_PCNET_SLOT, M1535_IRQ_INTD},	/* AMD Am79c973 on-board
							   ethernet */
	{2, ROCKHOPPER_PCI3_SLOT, M1535_IRQ_INTB},	/* PCI slot #3 */
	{2, ROCKHOPPER_PCI4_SLOT, M1535_IRQ_INTC}	/* PCI slot #4 */
};

static int pci_intlines[] =
    { M1535_IRQ_INTA, M1535_IRQ_INTB, M1535_IRQ_INTC, M1535_IRQ_INTD };

/* Determine the Rockhopper IRQ line number for the PCI device */
int rockhopper_get_irq(struct pci_dev *dev, u8 pin, u8 slot)
{
	struct pci_bus *bus;
	int i;

	bus = dev->bus;
	if (bus == NULL)
		return -1;

	for (i = 0; i < sizeof (int_map) / sizeof (int_map[0]); i++) {
		if (int_map[i].bus == bus->number && int_map[i].slot == slot) {
			int line;
			for (line = 0; line < 4; line++)
				if (pci_intlines[line] == int_map[i].irq)
					break;
			if (line < 4)
				return pci_intlines[(line + (pin - 1)) % 4];
			else
				return int_map[i].irq;
		}
	}
	return -1;
}

#ifdef CONFIG_ROCKHOPPER
void i8259_init(void)
{
	outb(0x11, 0x20);		/* Master ICW1 */
	outb(I8259_IRQ_BASE, 0x21);	/* Master ICW2 */
	outb(0x04, 0x21);		/* Master ICW3 */
	outb(0x01, 0x21);		/* Master ICW4 */
	outb(0xff, 0x21);		/* Master IMW */

	outb(0x11, 0xa0);		/* Slave ICW1 */
	outb(I8259_IRQ_BASE + 8, 0xa1);	/* Slave ICW2 */
	outb(0x02, 0xa1);		/* Slave ICW3 */
	outb(0x01, 0xa1);		/* Slave ICW4 */
	outb(0xff, 0xa1);		/* Slave IMW */

	outb(0x00, 0x4d0);
	outb(0x02, 0x4d1);	/* USB IRQ9 is level */
}
#endif

int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
	extern int pci_probe_only;
	pci_probe_only = 1;

#ifdef CONFIG_ROCKHOPPER
	if( dev->bus->number == 1 && vr4133_rockhopper )  {
		if(slot == ROCKHOPPER_PCI1_SLOT || slot == ROCKHOPPER_PCI2_SLOT)
			dev->irq = CMBVR41XX_INTA_IRQ;
		else
			dev->irq = rockhopper_get_irq(dev, pin, slot);
	} else
		dev->irq = CMBVR41XX_INTA_IRQ;
#else
	dev->irq = CMBVR41XX_INTA_IRQ;
#endif

	return dev->irq;
}

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, ali_m1535plus_init);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, ali_m5229_init);


