summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/powernv
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-17 16:07:43 +1000
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-17 16:07:43 +1000
commiteda485f06d17f98bd58559fb5dd331951ffd1608 (patch)
treec76f119e68734932c6751cd14fdd420544da92c3 /arch/powerpc/platforms/powernv
parent6b5e7229bbd59f0cfce7015fd46736fc93d8c8c3 (diff)
parent9a5d5bd8480068c5829e3d997ee21dab9b3ed05f (diff)
Merge remote-tracking branch 'pci/pci/gavin-window-alignment' into next
Merge Gavin patches from the PCI tree as subsequent powerpc patches are going to depend on them Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/platforms/powernv')
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5e75dcfe51b..cae7281e4e6 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -854,7 +854,7 @@ static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus)
if (pe == NULL)
continue;
/* Leaving the PCIe domain ... single PE# */
- if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE)
+ if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
pnv_ioda_setup_bus_PE(dev, pe);
else if (dev->subordinate)
pnv_ioda_setup_PEs(dev->subordinate);
@@ -1138,6 +1138,44 @@ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)
}
}
+/*
+ * Returns the alignment for I/O or memory windows for P2P
+ * bridges. That actually depends on how PEs are segmented.
+ * For now, we return I/O or M32 segment size for PE sensitive
+ * P2P bridges. Otherwise, the default values (4KiB for I/O,
+ * 1MiB for memory) will be returned.
+ *
+ * The current PCI bus might be put into one PE, which was
+ * create against the parent PCI bridge. For that case, we
+ * needn't enlarge the alignment so that we can save some
+ * resources.
+ */
+static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
+ unsigned long type)
+{
+ struct pci_dev *bridge;
+ struct pci_controller *hose = pci_bus_to_host(bus);
+ struct pnv_phb *phb = hose->private_data;
+ int num_pci_bridges = 0;
+
+ bridge = bus->self;
+ while (bridge) {
+ if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) {
+ num_pci_bridges++;
+ if (num_pci_bridges >= 2)
+ return 1;
+ }
+
+ bridge = bridge->bus->self;
+ }
+
+ /* We need support prefetchable memory window later */
+ if (type & IORESOURCE_MEM)
+ return phb->ioda.m32_segsize;
+
+ return phb->ioda.io_segsize;
+}
+
/* Prevent enabling devices for which we couldn't properly
* assign a PE
*/
@@ -1305,6 +1343,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
*/
ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
+ ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
/* Reset IODA tables to a clean state */