[RFC 3/7] Unite all PCI-e on 85xx and 86xx under one codebase
From: Andy Fleming <hidden>
Date: 2007-02-16 02:45:22
Subsystem:
linux for powerpc (32-bit and 64-bit), linux for powerpc embedded ppc85xx, the rest · Maintainers:
Madhavan Srinivasan, Scott Wood, Linus Torvalds
Add 8548 CDS PCI express host bridge support Signed-off-by: Roy Zang <redacted> Acked-by: Andy Fleming <redacted> --- arch/powerpc/platforms/85xx/mpc85xx_cds.c | 11 +-- arch/powerpc/platforms/85xx/pci.c | 108 ++++++++++++++++++++++++++++- 2 files changed, 110 insertions(+), 9 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index abc0aca..2027855 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c@@ -79,9 +79,9 @@ static int mpc85xx_exclude_device(u_char return PCIBIOS_SUCCESSFUL; } -static void __init mpc85xx_cds_pcibios_fixup(void) +void __init +mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev) { - struct pci_dev *dev; u_char c; if ((dev = pci_get_device(PCI_VENDOR_ID_VIA,
@@ -120,11 +120,6 @@ static void __init mpc85xx_cds_pcibios_f pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); pci_dev_put(dev); } - - /* Now map all the PCI irqs */ - dev = NULL; - for_each_pci_dev(dev) - pci_read_irq_line(dev); } #ifdef CONFIG_PPC_I8259
@@ -260,7 +255,7 @@ static void __init mpc85xx_cds_setup_arc for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) add_bridge(np); - ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; + ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif
diff --git a/arch/powerpc/platforms/85xx/pci.c b/arch/powerpc/platforms/85xx/pci.c
index 05930ee..5c70797 100644
--- a/arch/powerpc/platforms/85xx/pci.c
+++ b/arch/powerpc/platforms/85xx/pci.c@@ -24,6 +24,7 @@ #include <asm/pci-bridge.h> #include <asm/prom.h> #include <sysdev/fsl_soc.h> +#include <asm/immap_85xx.h> #undef DEBUG
@@ -35,13 +36,108 @@ int mpc85xx_pci2_busno = 0; +extern void +setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data); + #ifdef CONFIG_PCI +struct pcie_outbound_window_regs { + uint pexotar; /* 0x.0 - PCI Express outbound translation address register */ + uint pexotear; /* 0x.4 - PCI Express outbound translation extended address register */ + uint pexowbar; /* 0x.8 - PCI Express outbound window base address register */ + char res1[4]; + uint pexowar; /* 0x.10 - PCI Express outbound window attributes register */ + char res2[12]; +}; + +struct pcie_inbound_window_regs { + uint pexitar; /* 0x.0 - PCI Express inbound translation address register */ + char res1[4]; + uint pexiwbar; /* 0x.8 - PCI Express inbound window base address register */ + uint pexiwbear; /* 0x.c - PCI Express inbound window base extended address register */ + uint pexiwar; /* 0x.10 - PCI Express inbound window attributes register */ + char res2[12]; +}; + +static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource *rsrc) +{ + volatile struct ccsr_pex *pcie; + volatile struct pcie_outbound_window_regs *pcieow; + volatile struct pcie_inbound_window_regs *pcieiw; + int i = 0; + + DBG("PCIE memory map start 0x%x, size 0x%x\n", rsrc->start, + rsrc->end - rsrc->start + 1); + pcie = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); + + /* Disable all windows (except pexowar0 since its ignored) */ + pcie->pexowar1 = 0; + pcie->pexowar2 = 0; + pcie->pexowar3 = 0; + pcie->pexowar4 = 0; + pcie->pexiwar1 = 0; + pcie->pexiwar2 = 0; + pcie->pexiwar3 = 0; + + pcieow = (struct pcie_outbound_window_regs *)&pcie->pexotar1; + pcieiw = (struct pcie_inbound_window_regs *)&pcie->pexitar1; + + /* Setup outbound MEM window */ + for(i = 0; i < 3; i++) + if (hose->mem_resources[i].flags & IORESOURCE_MEM){ + DBG("PCIE MEM resource start 0x%08x, size 0x%08x.\n", + hose->mem_resources[i].start, + hose->mem_resources[i].end + - hose->mem_resources[i].start + 1); + pcieow->pexotar = (hose->mem_resources[i].start) >> 12 + & 0x000fffff; + pcieow->pexotear = 0; + pcieow->pexowbar = (hose->mem_resources[i].start) >> 12 + & 0x000fffff; + /* Enable, Mem R/W */ + pcieow->pexowar = 0x80044000 | + (__ilog2(hose->mem_resources[i].end + - hose->mem_resources[i].start + 1) + - 1); + pcieow++; + } + + /* Setup outbound IO window */ + if (hose->io_resource.flags & IORESOURCE_IO){ + DBG("PCIE IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n", + hose->io_resource.start, + hose->io_resource.end - hose->io_resource.start + 1, + hose->io_base_phys); + pcieow->pexotar = (hose->io_resource.start) >> 12 & 0x000fffff; + pcieow->pexotear = 0; + pcieow->pexowbar = (hose->io_base_phys) >> 12 & 0x000fffff; + /* Enable, IO R/W */ + pcieow->pexowar = 0x80088000 | (__ilog2(hose->io_resource.end + - hose->io_resource.start + 1) - 1); + } + + /* Setup 2G inbound Memory Window @ 0 */ + pcieiw->pexitar = 0x00000000; + pcieiw->pexiwbar = 0x00000000; + /* Enable, Prefetch, Local Mem, Snoop R/W, 2G */ + pcieiw->pexiwar = 0xa0f5501e; +} +static void __init +mpc85xx_setup_pcie(struct pci_controller *hose) +{ + u16 temps; + early_read_config_word(hose, 0, 0, PCI_COMMAND, &temps); + temps |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + early_write_config_word(hose, 0, 0, PCI_COMMAND, temps); + early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); +} + int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; + unsigned int temp; int primary = 1, has_address = 0; phys_addr_t immr = get_immrbase();
@@ -77,6 +173,17 @@ int __init add_bridge(struct device_node hose->bus_offset = hose->first_busno; mpc85xx_pci2_busno = hose->first_busno; } + /* PEX */ + if ((rsrc.start & 0xfffff) == 0xa000) { + setup_indirect_pcie(hose, immr + 0xa000, immr + 0xa004); + mpc85xx_setup_pcie(hose); + primary = 1; + hose->bus_offset = hose->first_busno; + /* Setup PEX window registers */ + setup_pcie_atmu(hose, &rsrc); + early_read_config_dword(hose, 0, 0, 0x404, &temp); + printk("Reg 0x404 is 0x%x\n",temp); + } printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n",
@@ -92,5 +199,4 @@ int __init add_bridge(struct device_node return 0; } - #endif
--
1.4.4