From 72b122cc301858dcf283fe6731e61322c9772cf4 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 14 Jan 2008 17:02:19 -0600 Subject: [PATCH] [POWERPC] FSL: Rework PCI/PCIe support for 85xx/86xx The current PCI code for Freescale 85xx/86xx was treating the virtual P2P PCIe bridge as a transparent bridge. Rather than doing that fixup the virtual P2P bridge by copying the resources from the PHB. Also, fixup a bit of the code for dealing with resource_size_t being 64-bits and how we set ATMU registers for >4G. Signed-off-by: Kumar Gala --- arch/powerpc/sysdev/fsl_pci.c | 150 ++++++++++++++-------------------- 1 file changed, 62 insertions(+), 88 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4b1d5120c122..bf13c2174a4e 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -33,8 +33,8 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) struct ccsr_pci __iomem *pci; int i; - pr_debug("PCI memory map start 0x%x, size 0x%x\n", rsrc->start, - rsrc->end - rsrc->start + 1); + pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", + (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1); pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); /* Disable all windows (except powar0 since its ignored) */ @@ -46,17 +46,17 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) /* Setup outbound MEM window */ for(i = 0; i < 3; i++) if (hose->mem_resources[i].flags & IORESOURCE_MEM){ - pr_debug("PCI 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); - out_be32(&pci->pow[i+1].potar, - (hose->mem_resources[i].start >> 12) - & 0x000fffff); + resource_size_t pci_addr_start = + hose->mem_resources[i].start - + hose->pci_mem_offset; + pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n", + (u64)hose->mem_resources[i].start, + (u64)hose->mem_resources[i].end + - (u64)hose->mem_resources[i].start + 1); + out_be32(&pci->pow[i+1].potar, (pci_addr_start >> 12)); out_be32(&pci->pow[i+1].potear, 0); out_be32(&pci->pow[i+1].powbar, - (hose->mem_resources[i].start >> 12) - & 0x000fffff); + (hose->mem_resources[i].start >> 12)); /* Enable, Mem R/W */ out_be32(&pci->pow[i+1].powar, 0x80044000 | (__ilog2(hose->mem_resources[i].end @@ -65,15 +65,14 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc) /* Setup outbound IO window */ if (hose->io_resource.flags & IORESOURCE_IO){ - pr_debug("PCI 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); - out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12) - & 0x000fffff); + pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, " + "phy base 0x%016llx.\n", + (u64)hose->io_resource.start, + (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1, + (u64)hose->io_base_phys); + out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12)); out_be32(&pci->pow[i+1].potear, 0); - out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12) - & 0x000fffff); + out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12)); /* Enable, IO R/W */ out_be32(&pci->pow[i+1].powar, 0x80088000 | (__ilog2(hose->io_resource.end @@ -107,55 +106,17 @@ void __init setup_pci_cmd(struct pci_controller *hose) } } -static void __init quirk_fsl_pcie_transparent(struct pci_dev *dev) -{ - struct resource *res; - int i, res_idx = PCI_BRIDGE_RESOURCES; - struct pci_controller *hose; +static int fsl_pcie_bus_fixup; +static void __init quirk_fsl_pcie_header(struct pci_dev *dev) +{ /* if we aren't a PCIe don't bother */ if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) return ; - /* - * Make the bridge be transparent. - */ - dev->transparent = 1; - - hose = pci_bus_to_host(dev->bus); - if (!hose) { - printk(KERN_ERR "Can't find hose for bus %d\n", - dev->bus->number); - return; - } - - /* Clear out any of the virtual P2P bridge registers */ - pci_write_config_word(dev, PCI_IO_BASE_UPPER16, 0); - pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16, 0); - pci_write_config_byte(dev, PCI_IO_BASE, 0x10); - pci_write_config_byte(dev, PCI_IO_LIMIT, 0); - pci_write_config_word(dev, PCI_MEMORY_BASE, 0x10); - pci_write_config_word(dev, PCI_MEMORY_LIMIT, 0); - pci_write_config_word(dev, PCI_PREF_BASE_UPPER32, 0x0); - pci_write_config_word(dev, PCI_PREF_LIMIT_UPPER32, 0x0); - pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10); - pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0); - - if (hose->io_resource.flags) { - res = &dev->resource[res_idx++]; - res->start = hose->io_resource.start; - res->end = hose->io_resource.end; - res->flags = hose->io_resource.flags; - update_bridge_resource(dev, res); - } - - for (i = 0; i < 3; i++) { - res = &dev->resource[res_idx + i]; - res->start = hose->mem_resources[i].start; - res->end = hose->mem_resources[i].end; - res->flags = hose->mem_resources[i].flags; - update_bridge_resource(dev, res); - } + dev->class = PCI_CLASS_BRIDGE_PCI << 8; + fsl_pcie_bus_fixup = 1; + return ; } int __init fsl_pcie_check_link(struct pci_controller *hose) @@ -172,11 +133,24 @@ void fsl_pcibios_fixup_bus(struct pci_bus *bus) struct pci_controller *hose = (struct pci_controller *) bus->sysdata; int i; - /* deal with bogus pci_bus when we don't have anything connected on PCIe */ - if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) { - if (bus->parent) { - for (i = 0; i < 4; ++i) - bus->resource[i] = bus->parent->resource[i]; + if ((bus->parent == hose->bus) && + ((fsl_pcie_bus_fixup && + early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) || + (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK))) + { + for (i = 0; i < 4; ++i) { + struct resource *res = bus->resource[i]; + struct resource *par = bus->parent->resource[i]; + if (res) { + res->start = 0; + res->end = 0; + res->flags = 0; + } + if (res && par) { + res->start = par->start; + res->end = par->end; + res->flags = par->flags; + } } } } @@ -240,23 +214,23 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary) return 0; } -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent); -DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_transparent); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header); +DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);