/*
 * arch/mips/pci/fixup-vr4133.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 <linux/kernel.h>

#include <asm/io.h>
#include <asm/i8259.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 < ARRAY_SIZE(int_map); 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)
{
	init_i8259_irqs();

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

int __init pcibios_map_irq(const 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);


