[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 <galak@kernel.crashing.org>
This commit is contained in:
Kumar Gala 2008-01-14 17:02:19 -06:00
Родитель b188b2aefe
Коммит 72b122cc30
1 изменённых файлов: 62 добавлений и 88 удалений

Просмотреть файл

@ -33,8 +33,8 @@ void __init setup_pci_atmu(struct pci_controller *hose, struct resource *rsrc)
struct ccsr_pci __iomem *pci; struct ccsr_pci __iomem *pci;
int i; int i;
pr_debug("PCI memory map start 0x%x, size 0x%x\n", rsrc->start, pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
rsrc->end - rsrc->start + 1); (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); pci = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);
/* Disable all windows (except powar0 since its ignored) */ /* 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 */ /* Setup outbound MEM window */
for(i = 0; i < 3; i++) for(i = 0; i < 3; i++)
if (hose->mem_resources[i].flags & IORESOURCE_MEM){ if (hose->mem_resources[i].flags & IORESOURCE_MEM){
pr_debug("PCI MEM resource start 0x%08x, size 0x%08x.\n", resource_size_t pci_addr_start =
hose->mem_resources[i].start, hose->mem_resources[i].start -
hose->mem_resources[i].end hose->pci_mem_offset;
- hose->mem_resources[i].start + 1); pr_debug("PCI MEM resource start 0x%016llx, size 0x%016llx.\n",
out_be32(&pci->pow[i+1].potar, (u64)hose->mem_resources[i].start,
(hose->mem_resources[i].start >> 12) (u64)hose->mem_resources[i].end
& 0x000fffff); - (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].potear, 0);
out_be32(&pci->pow[i+1].powbar, out_be32(&pci->pow[i+1].powbar,
(hose->mem_resources[i].start >> 12) (hose->mem_resources[i].start >> 12));
& 0x000fffff);
/* Enable, Mem R/W */ /* Enable, Mem R/W */
out_be32(&pci->pow[i+1].powar, 0x80044000 out_be32(&pci->pow[i+1].powar, 0x80044000
| (__ilog2(hose->mem_resources[i].end | (__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 */ /* Setup outbound IO window */
if (hose->io_resource.flags & IORESOURCE_IO){ if (hose->io_resource.flags & IORESOURCE_IO){
pr_debug("PCI IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n", pr_debug("PCI IO resource start 0x%016llx, size 0x%016llx, "
hose->io_resource.start, "phy base 0x%016llx.\n",
hose->io_resource.end - hose->io_resource.start + 1, (u64)hose->io_resource.start,
hose->io_base_phys); (u64)hose->io_resource.end - (u64)hose->io_resource.start + 1,
out_be32(&pci->pow[i+1].potar, (hose->io_resource.start >> 12) (u64)hose->io_base_phys);
& 0x000fffff); 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].potear, 0);
out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12) out_be32(&pci->pow[i+1].powbar, (hose->io_base_phys >> 12));
& 0x000fffff);
/* Enable, IO R/W */ /* Enable, IO R/W */
out_be32(&pci->pow[i+1].powar, 0x80088000 out_be32(&pci->pow[i+1].powar, 0x80088000
| (__ilog2(hose->io_resource.end | (__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) static int fsl_pcie_bus_fixup;
{
struct resource *res;
int i, res_idx = PCI_BRIDGE_RESOURCES;
struct pci_controller *hose;
static void __init quirk_fsl_pcie_header(struct pci_dev *dev)
{
/* if we aren't a PCIe don't bother */ /* if we aren't a PCIe don't bother */
if (!pci_find_capability(dev, PCI_CAP_ID_EXP)) if (!pci_find_capability(dev, PCI_CAP_ID_EXP))
return ; return ;
/* dev->class = PCI_CLASS_BRIDGE_PCI << 8;
* Make the bridge be transparent. fsl_pcie_bus_fixup = 1;
*/ return ;
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);
}
} }
int __init fsl_pcie_check_link(struct pci_controller *hose) 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; struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
int i; int i;
/* deal with bogus pci_bus when we don't have anything connected on PCIe */ if ((bus->parent == hose->bus) &&
if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK) { ((fsl_pcie_bus_fixup &&
if (bus->parent) { early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) ||
for (i = 0; i < 4; ++i) (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)))
bus->resource[i] = bus->parent->resource[i]; {
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; return 0;
} }
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8548, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8533, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8544, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572E, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8572, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
DECLARE_PCI_FIXUP_EARLY(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_transparent); DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);