From b66510cb9992d204f216049e9c01d432c7635f6c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 16 Aug 2007 23:55:55 -0500 Subject: [POWERPC] Fix interrupt routing and setup of ULI M1575 on FSL boards The interrupt routing in the device trees for the ULI M1575 was inproperly using the interrupt line field as pci function. Fixed up the device tree's to actual conform for to specification and changed the interrupt mapping code so it just uses a static mapping setup as follows: PIRQA - IRQ9 PIRQB - IRQ10 PIRQC - IRQ11 PIRQD - IRQ12 USB 1.1 OCHI (1c.0) - IRQ12 USB 1.1 OCHI (1c.1) - IRQ9 USB 1.1 OCHI (1c.2) - IRQ10 USB 1.1 ECHI (1c.3) - IRQ11 LAN (1b.0) - IRQ6 AC97 (1d.0) - IRQ6 Modem (1d.1) - IRQ6 HD Audio (1d.2) - IRQ6 SATA (1f.1) - IRQ5 SMB (1e.1) - IRQ7 PMU (1e.2) - IRQ7 PATA (1f.0) - IRQ14/15 Took the oppurtunity to refactor the code into a single file so we don't have to duplicate these fixes on the two current boards in the tree and several forth coming boards that will also need the code. Fixed RTC support that requires a dummy memory read on the P2P bridge to unlock the RTC and setup the default of the RTC alarm registers to match with a basic x86 style CMOS RTC. Moved code that poked ISA registers to a FIXUP_FINAL quirk to ensure the PCI IO space has been setup properly before we start poking ISA registers at random locations. Signed-off-by: Kumar Gala --- arch/powerpc/platforms/85xx/Kconfig | 1 + arch/powerpc/platforms/85xx/mpc8544_ds.c | 214 +++---------------------------- 2 files changed, 16 insertions(+), 199 deletions(-) (limited to 'arch/powerpc/platforms/85xx') diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index f58184086c8c..f620171ad6b1 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -33,6 +33,7 @@ config MPC8544_DS bool "Freescale MPC8544 DS" select PPC_I8259 select DEFAULT_UIMAGE + select FSL_ULI1575 help This option enables support for the MPC8544 DS board diff --git a/arch/powerpc/platforms/85xx/mpc8544_ds.c b/arch/powerpc/platforms/85xx/mpc8544_ds.c index 4905f6f8903b..0f834d8be444 100644 --- a/arch/powerpc/platforms/85xx/mpc8544_ds.c +++ b/arch/powerpc/platforms/85xx/mpc8544_ds.c @@ -114,211 +114,25 @@ void __init mpc8544_ds_pic_init(void) } #ifdef CONFIG_PCI -enum pirq { PIRQA = 8, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH }; +extern int uses_fsl_uli_m1575; +extern int uli_exclude_device(struct pci_controller *hose, + u_char bus, u_char devfn); -/* - * Value in table -- IRQ number - */ -const unsigned char uli1575_irq_route_table[16] = { - 0, /* 0: Reserved */ - 0x8, - 0, /* 2: Reserved */ - 0x2, - 0x4, - 0x5, - 0x7, - 0x6, - 0, /* 8: Reserved */ - 0x1, - 0x3, - 0x9, - 0xb, - 0, /* 13: Reserved */ - 0xd, - 0xf, -}; - -static int __devinit -get_pci_irq_from_of(struct pci_controller *hose, int slot, int pin) -{ - struct of_irq oirq; - u32 laddr[3]; - struct device_node *hosenode = hose ? hose->arch_data : NULL; - - if (!hosenode) - return -EINVAL; - - laddr[0] = (hose->first_busno << 16) | (PCI_DEVFN(slot, 0) << 8); - laddr[1] = laddr[2] = 0; - of_irq_map_raw(hosenode, &pin, 1, laddr, &oirq); - DBG("mpc8544_ds: pci irq addr %x, slot %d, pin %d, irq %d\n", - laddr[0], slot, pin, oirq.specifier[0]); - return oirq.specifier[0]; -} - -/*8259*/ -static void __devinit quirk_uli1575(struct pci_dev *dev) -{ - unsigned short temp; - struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned char irq2pin[16]; - unsigned long pirq_map_word = 0; - u32 irq; - int i; - - /* - * ULI1575 interrupts route setup - */ - memset(irq2pin, 0, 16); /* Initialize default value 0 */ - - irq2pin[6]=PIRQA+3; /* enabled mapping for IRQ6 to PIRQD, used by SATA */ - - /* - * PIRQE -> PIRQF mapping set manually - * - * IRQ pin IRQ# - * PIRQE ---- 9 - * PIRQF ---- 10 - * PIRQG ---- 11 - * PIRQH ---- 12 - */ - for (i = 0; i < 4; i++) - irq2pin[i + 9] = PIRQE + i; - - /* Set IRQ-PIRQ Mapping to ULI1575 */ - for (i = 0; i < 16; i++) - if (irq2pin[i]) - pirq_map_word |= (uli1575_irq_route_table[i] & 0xf) - << ((irq2pin[i] - PIRQA) * 4); - - pirq_map_word |= 1<<26; /* disable INTx in EP mode*/ - - /* ULI1575 IRQ mapping conf register default value is 0xb9317542 */ - DBG("Setup ULI1575 IRQ mapping configuration register value = 0x%x\n", - (int)pirq_map_word); - pci_write_config_dword(dev, 0x48, pirq_map_word); - -#define ULI1575_SET_DEV_IRQ(slot, pin, reg) \ - do { \ - int irq; \ - irq = get_pci_irq_from_of(hose, slot, pin); \ - if (irq > 0 && irq < 16) \ - pci_write_config_byte(dev, reg, irq2pin[irq]); \ - else \ - printk(KERN_WARNING "ULI1575 device" \ - "(slot %d, pin %d) irq %d is invalid.\n", \ - slot, pin, irq); \ - } while(0) - - /* USB 1.1 OHCI controller 1, slot 28, pin 1 */ - ULI1575_SET_DEV_IRQ(28, 1, 0x86); - - /* USB 1.1 OHCI controller 2, slot 28, pin 2 */ - ULI1575_SET_DEV_IRQ(28, 2, 0x87); - - /* USB 1.1 OHCI controller 3, slot 28, pin 3 */ - ULI1575_SET_DEV_IRQ(28, 3, 0x88); - - /* USB 2.0 controller, slot 28, pin 4 */ - irq = get_pci_irq_from_of(hose, 28, 4); - if (irq >= 0 && irq <= 15) - pci_write_config_dword(dev, 0x74, uli1575_irq_route_table[irq]); - - /* Audio controller, slot 29, pin 1 */ - ULI1575_SET_DEV_IRQ(29, 1, 0x8a); - - /* Modem controller, slot 29, pin 2 */ - ULI1575_SET_DEV_IRQ(29, 2, 0x8b); - - /* HD audio controller, slot 29, pin 3 */ - ULI1575_SET_DEV_IRQ(29, 3, 0x8c); - - /* SMB interrupt: slot 30, pin 1 */ - ULI1575_SET_DEV_IRQ(30, 1, 0x8e); - - /* PMU ACPI SCI interrupt: slot 30, pin 2 */ - ULI1575_SET_DEV_IRQ(30, 2, 0x8f); - - /* Serial ATA interrupt: slot 31, pin 1 */ - ULI1575_SET_DEV_IRQ(31, 1, 0x8d); - - /* Primary PATA IDE IRQ: 14 - * Secondary PATA IDE IRQ: 15 - */ - pci_write_config_byte(dev, 0x44, 0x30 | uli1575_irq_route_table[14]); - pci_write_config_byte(dev, 0x75, uli1575_irq_route_table[15]); - - /* Set IRQ14 and IRQ15 to legacy IRQs */ - pci_read_config_word(dev, 0x46, &temp); - temp |= 0xc000; - pci_write_config_word(dev, 0x46, temp); - - /* Set i8259 interrupt trigger - * IRQ 3: Level - * IRQ 4: Level - * IRQ 5: Level - * IRQ 6: Level - * IRQ 7: Level - * IRQ 9: Level - * IRQ 10: Level - * IRQ 11: Level - * IRQ 12: Level - * IRQ 14: Edge - * IRQ 15: Edge - */ - outb(0xfa, 0x4d0); - outb(0x1e, 0x4d1); - -#undef ULI1575_SET_DEV_IRQ -} - -/* SATA */ -static void __devinit quirk_uli5288(struct pci_dev *dev) +static int mpc85xx_exclude_device(struct pci_controller *hose, + u_char bus, u_char devfn) { - unsigned char c; - - pci_read_config_byte(dev, 0x83, &c); - c |= 0x80; /* read/write lock */ - pci_write_config_byte(dev, 0x83, c); - - pci_write_config_byte(dev, 0x09, 0x01); /* Base class code: storage */ - pci_write_config_byte(dev, 0x0a, 0x06); /* IDE disk */ + struct device_node* node; + struct resource rsrc; - pci_read_config_byte(dev, 0x83, &c); - c &= 0x7f; - pci_write_config_byte(dev, 0x83, c); - - pci_read_config_byte(dev, 0x84, &c); - c |= 0x01; /* emulated PATA mode enabled */ - pci_write_config_byte(dev, 0x84, c); -} + node = (struct device_node *)hose->arch_data; + of_address_to_resource(node, 0, &rsrc); -/* PATA */ -static void __devinit quirk_uli5229(struct pci_dev *dev) -{ - unsigned short temp; - pci_write_config_word(dev, 0x04, 0x0405); /* MEM IO MSI */ - pci_read_config_word(dev, 0x4a, &temp); - temp |= 0x1000; /* Enable Native IRQ 14/15 */ - pci_write_config_word(dev, 0x4a, temp); -} + if ((rsrc.start & 0xfffff) == 0xb000) { + return uli_exclude_device(hose, bus, devfn); + } -/*Bridge*/ -static void __devinit early_uli5249(struct pci_dev *dev) -{ - unsigned char temp; - pci_write_config_word(dev, 0x04, 0x0007); /* mem access */ - pci_read_config_byte(dev, 0x7c, &temp); - pci_write_config_byte(dev, 0x7c, 0x80); /* R/W lock control */ - pci_write_config_byte(dev, 0x09, 0x01); /* set as pci-pci bridge */ - pci_write_config_byte(dev, 0x7c, temp); /* restore pci bus debug control */ - dev->class |= 0x1; + return PCIBIOS_SUCCESSFUL; } - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_uli1575); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); #endif /* CONFIG_PCI */ /* @@ -342,6 +156,8 @@ static void __init mpc8544_ds_setup_arch(void) else fsl_add_bridge(np, 0); } + uses_fsl_uli_m1575 = 1; + ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif printk("MPC8544 DS board from Freescale Semiconductor\n"); -- cgit v1.2.3