aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-17 02:07:43 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-09-17 02:07:43 -0400
commiteda485f06d17f98bd58559fb5dd331951ffd1608 (patch)
treec76f119e68734932c6751cd14fdd420544da92c3 /arch/powerpc
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')
-rw-r--r--arch/powerpc/include/asm/machdep.h3
-rw-r--r--arch/powerpc/kernel/pci-common.c20
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c41
3 files changed, 63 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 236b4779ec4f..8111e1b78f7f 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -215,6 +215,9 @@ struct machdep_calls {
215 /* Called after scan and before resource survey */ 215 /* Called after scan and before resource survey */
216 void (*pcibios_fixup_phb)(struct pci_controller *hose); 216 void (*pcibios_fixup_phb)(struct pci_controller *hose);
217 217
218 /* Called during PCI resource reassignment */
219 resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type);
220
218 /* Called to shutdown machine specific hardware not already controlled 221 /* Called to shutdown machine specific hardware not already controlled
219 * by other drivers. 222 * by other drivers.
220 */ 223 */
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 4cb714792bea..7f94f760dd0c 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -99,6 +99,26 @@ void pcibios_free_controller(struct pci_controller *phb)
99 kfree(phb); 99 kfree(phb);
100} 100}
101 101
102/*
103 * The function is used to return the minimal alignment
104 * for memory or I/O windows of the associated P2P bridge.
105 * By default, 4KiB alignment for I/O windows and 1MiB for
106 * memory windows.
107 */
108resource_size_t pcibios_window_alignment(struct pci_bus *bus,
109 unsigned long type)
110{
111 if (ppc_md.pcibios_window_alignment)
112 return ppc_md.pcibios_window_alignment(bus, type);
113
114 /*
115 * PCI core will figure out the default
116 * alignment: 4KiB for I/O and 1MiB for
117 * memory window.
118 */
119 return 1;
120}
121
102static resource_size_t pcibios_io_size(const struct pci_controller *hose) 122static resource_size_t pcibios_io_size(const struct pci_controller *hose)
103{ 123{
104#ifdef CONFIG_PPC64 124#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 5e75dcfe51b9..cae7281e4e66 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)
854 if (pe == NULL) 854 if (pe == NULL)
855 continue; 855 continue;
856 /* Leaving the PCIe domain ... single PE# */ 856 /* Leaving the PCIe domain ... single PE# */
857 if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) 857 if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE)
858 pnv_ioda_setup_bus_PE(dev, pe); 858 pnv_ioda_setup_bus_PE(dev, pe);
859 else if (dev->subordinate) 859 else if (dev->subordinate)
860 pnv_ioda_setup_PEs(dev->subordinate); 860 pnv_ioda_setup_PEs(dev->subordinate);
@@ -1138,6 +1138,44 @@ static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose)
1138 } 1138 }
1139} 1139}
1140 1140
1141/*
1142 * Returns the alignment for I/O or memory windows for P2P
1143 * bridges. That actually depends on how PEs are segmented.
1144 * For now, we return I/O or M32 segment size for PE sensitive
1145 * P2P bridges. Otherwise, the default values (4KiB for I/O,
1146 * 1MiB for memory) will be returned.
1147 *
1148 * The current PCI bus might be put into one PE, which was
1149 * create against the parent PCI bridge. For that case, we
1150 * needn't enlarge the alignment so that we can save some
1151 * resources.
1152 */
1153static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus,
1154 unsigned long type)
1155{
1156 struct pci_dev *bridge;
1157 struct pci_controller *hose = pci_bus_to_host(bus);
1158 struct pnv_phb *phb = hose->private_data;
1159 int num_pci_bridges = 0;
1160
1161 bridge = bus->self;
1162 while (bridge) {
1163 if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) {
1164 num_pci_bridges++;
1165 if (num_pci_bridges >= 2)
1166 return 1;
1167 }
1168
1169 bridge = bridge->bus->self;
1170 }
1171
1172 /* We need support prefetchable memory window later */
1173 if (type & IORESOURCE_MEM)
1174 return phb->ioda.m32_segsize;
1175
1176 return phb->ioda.io_segsize;
1177}
1178
1141/* Prevent enabling devices for which we couldn't properly 1179/* Prevent enabling devices for which we couldn't properly
1142 * assign a PE 1180 * assign a PE
1143 */ 1181 */
@@ -1305,6 +1343,7 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np)
1305 */ 1343 */
1306 ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; 1344 ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb;
1307 ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; 1345 ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook;
1346 ppc_md.pcibios_window_alignment = pnv_pci_window_alignment;
1308 pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC); 1347 pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC);
1309 1348
1310 /* Reset IODA tables to a clean state */ 1349 /* Reset IODA tables to a clean state */