[RFC 3/7] Unite all PCI-e on 85xx and 86xx under one codebase
Andy Fleming
afleming at freescale.com
Fri Feb 16 13:44:45 EST 2007
Add 8548 CDS PCI express host bridge support
Signed-off-by: Roy Zang <tie-fei.zang at freescale.com>
Acked-by: Andy Fleming <afleming at freescale.com>
---
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
More information about the Linuxppc-dev
mailing list