diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-18 12:06:19 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-07-18 16:54:16 -0400 |
commit | f6d2ce00da145ae31ec22d21daca6ca5e22b3c84 (patch) | |
tree | bb030290bc253b37bfad91de618c6f080f0b0af9 /arch | |
parent | f1006257893917dfb1e0d74cb47b18c0e2908693 (diff) |
tile: updates to pci root complex from community feedback
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/tile/include/asm/pci.h | 27 | ||||
-rw-r--r-- | arch/tile/kernel/pci_gx.c | 80 | ||||
-rw-r--r-- | arch/tile/kernel/setup.c | 4 |
3 files changed, 47 insertions, 64 deletions
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index 553b7ff018c4..302cdf71ceed 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h | |||
@@ -128,15 +128,10 @@ static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {} | |||
128 | #define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH()) | 128 | #define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH()) |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * End of the PCI memory resource. | 131 | * Start of the PCI memory resource, which starts at the end of the |
132 | * maximum system physical RAM address. | ||
132 | */ | 133 | */ |
133 | #define TILE_PCI_MEM_END \ | 134 | #define TILE_PCI_MEM_START (1ULL << CHIP_PA_WIDTH()) |
134 | ((1ULL << CHIP_PA_WIDTH()) + TILE_PCI_BAR_WINDOW_TOP) | ||
135 | |||
136 | /* | ||
137 | * Start of the PCI memory resource. | ||
138 | */ | ||
139 | #define TILE_PCI_MEM_START (TILE_PCI_MEM_END - TILE_PCI_BAR_WINDOW_SIZE) | ||
140 | 135 | ||
141 | /* | 136 | /* |
142 | * Structure of a PCI controller (host bridge) on Gx. | 137 | * Structure of a PCI controller (host bridge) on Gx. |
@@ -159,17 +154,19 @@ struct pci_controller { | |||
159 | int index; /* PCI domain number */ | 154 | int index; /* PCI domain number */ |
160 | struct pci_bus *root_bus; | 155 | struct pci_bus *root_bus; |
161 | 156 | ||
157 | /* PCI memory space resource for this controller. */ | ||
158 | struct resource mem_space; | ||
159 | char mem_space_name[32]; | ||
160 | |||
162 | uint64_t mem_offset; /* cpu->bus memory mapping offset. */ | 161 | uint64_t mem_offset; /* cpu->bus memory mapping offset. */ |
163 | 162 | ||
164 | int last_busno; | 163 | int first_busno; |
165 | 164 | ||
166 | struct pci_ops *ops; | 165 | struct pci_ops *ops; |
167 | 166 | ||
168 | /* Table that maps the INTx numbers to Linux irq numbers. */ | 167 | /* Table that maps the INTx numbers to Linux irq numbers. */ |
169 | int irq_intx_table[4]; | 168 | int irq_intx_table[4]; |
170 | 169 | ||
171 | struct resource mem_space; | ||
172 | |||
173 | /* Address ranges that are routed to this controller/bridge. */ | 170 | /* Address ranges that are routed to this controller/bridge. */ |
174 | struct resource mem_resources[3]; | 171 | struct resource mem_resources[3]; |
175 | }; | 172 | }; |
@@ -179,14 +176,6 @@ extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO]; | |||
179 | 176 | ||
180 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); | 177 | extern void pci_iounmap(struct pci_dev *dev, void __iomem *); |
181 | 178 | ||
182 | extern void | ||
183 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
184 | struct resource *res); | ||
185 | |||
186 | extern void | ||
187 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
188 | struct pci_bus_region *region); | ||
189 | |||
190 | /* | 179 | /* |
191 | * The PCI address space does not equal the physical memory address | 180 | * The PCI address space does not equal the physical memory address |
192 | * space (we have an IOMMU). The IDE and SCSI device layers use this | 181 | * space (we have an IOMMU). The IDE and SCSI device layers use this |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index 27f7ab021137..fa75264a82ae 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -96,21 +96,6 @@ static struct pci_ops tile_cfg_ops; | |||
96 | /* Mask of CPUs that should receive PCIe interrupts. */ | 96 | /* Mask of CPUs that should receive PCIe interrupts. */ |
97 | static struct cpumask intr_cpus_map; | 97 | static struct cpumask intr_cpus_map; |
98 | 98 | ||
99 | /* PCI I/O space support is not implemented. */ | ||
100 | static struct resource pci_ioport_resource = { | ||
101 | .name = "PCI IO", | ||
102 | .start = 0, | ||
103 | .end = 0, | ||
104 | .flags = IORESOURCE_IO, | ||
105 | }; | ||
106 | |||
107 | static struct resource pci_iomem_resource = { | ||
108 | .name = "PCI mem", | ||
109 | .start = TILE_PCI_MEM_START, | ||
110 | .end = TILE_PCI_MEM_END, | ||
111 | .flags = IORESOURCE_MEM, | ||
112 | }; | ||
113 | |||
114 | /* | 99 | /* |
115 | * We don't need to worry about the alignment of resources. | 100 | * We don't need to worry about the alignment of resources. |
116 | */ | 101 | */ |
@@ -437,9 +422,26 @@ out: | |||
437 | struct pci_controller *controller = &pci_controllers[i]; | 422 | struct pci_controller *controller = &pci_controllers[i]; |
438 | 423 | ||
439 | controller->index = i; | 424 | controller->index = i; |
440 | controller->last_busno = 0xff; | ||
441 | controller->ops = &tile_cfg_ops; | 425 | controller->ops = &tile_cfg_ops; |
442 | 426 | ||
427 | /* | ||
428 | * The PCI memory resource is located above the PA space. | ||
429 | * For every host bridge, the BAR window or the MMIO aperture | ||
430 | * is in range [3GB, 4GB - 1] of a 4GB space beyond the | ||
431 | * PA space. | ||
432 | */ | ||
433 | |||
434 | controller->mem_offset = TILE_PCI_MEM_START + | ||
435 | (i * TILE_PCI_BAR_WINDOW_TOP); | ||
436 | controller->mem_space.start = controller->mem_offset + | ||
437 | TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE; | ||
438 | controller->mem_space.end = controller->mem_offset + | ||
439 | TILE_PCI_BAR_WINDOW_TOP - 1; | ||
440 | controller->mem_space.flags = IORESOURCE_MEM; | ||
441 | snprintf(controller->mem_space_name, | ||
442 | sizeof(controller->mem_space_name), | ||
443 | "PCI mem domain %d", i); | ||
444 | controller->mem_space.name = controller->mem_space_name; | ||
443 | } | 445 | } |
444 | 446 | ||
445 | return num_rc_controllers; | 447 | return num_rc_controllers; |
@@ -588,6 +590,7 @@ int __init pcibios_init(void) | |||
588 | { | 590 | { |
589 | resource_size_t offset; | 591 | resource_size_t offset; |
590 | LIST_HEAD(resources); | 592 | LIST_HEAD(resources); |
593 | int next_busno; | ||
591 | int i; | 594 | int i; |
592 | 595 | ||
593 | tile_pci_init(); | 596 | tile_pci_init(); |
@@ -628,7 +631,7 @@ int __init pcibios_init(void) | |||
628 | msleep(250); | 631 | msleep(250); |
629 | 632 | ||
630 | /* Scan all of the recorded PCI controllers. */ | 633 | /* Scan all of the recorded PCI controllers. */ |
631 | for (i = 0; i < num_rc_controllers; i++) { | 634 | for (next_busno = 0, i = 0; i < num_rc_controllers; i++) { |
632 | struct pci_controller *controller = &pci_controllers[i]; | 635 | struct pci_controller *controller = &pci_controllers[i]; |
633 | gxio_trio_context_t *trio_context = controller->trio; | 636 | gxio_trio_context_t *trio_context = controller->trio; |
634 | TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; | 637 | TRIO_PCIE_INTFC_PORT_CONFIG_t port_config; |
@@ -843,13 +846,14 @@ int __init pcibios_init(void) | |||
843 | * The memory range for the PCI root bus should not overlap | 846 | * The memory range for the PCI root bus should not overlap |
844 | * with the physical RAM | 847 | * with the physical RAM |
845 | */ | 848 | */ |
846 | pci_add_resource_offset(&resources, &iomem_resource, | 849 | pci_add_resource_offset(&resources, &controller->mem_space, |
847 | 1ULL << CHIP_PA_WIDTH()); | 850 | controller->mem_offset); |
848 | 851 | ||
849 | bus = pci_scan_root_bus(NULL, 0, controller->ops, | 852 | controller->first_busno = next_busno; |
853 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, | ||
850 | controller, &resources); | 854 | controller, &resources); |
851 | controller->root_bus = bus; | 855 | controller->root_bus = bus; |
852 | controller->last_busno = bus->subordinate; | 856 | next_busno = bus->subordinate + 1; |
853 | 857 | ||
854 | } | 858 | } |
855 | 859 | ||
@@ -1011,20 +1015,9 @@ alloc_mem_map_failed: | |||
1011 | } | 1015 | } |
1012 | subsys_initcall(pcibios_init); | 1016 | subsys_initcall(pcibios_init); |
1013 | 1017 | ||
1014 | /* | 1018 | /* Note: to be deleted after Linux 3.6 merge. */ |
1015 | * PCI scan code calls the arch specific pcibios_fixup_bus() each time it scans | ||
1016 | * a new bridge. Called after each bus is probed, but before its children are | ||
1017 | * examined. | ||
1018 | */ | ||
1019 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 1019 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
1020 | { | 1020 | { |
1021 | struct pci_dev *dev = bus->self; | ||
1022 | |||
1023 | if (!dev) { | ||
1024 | /* This is the root bus. */ | ||
1025 | bus->resource[0] = &pci_ioport_resource; | ||
1026 | bus->resource[1] = &pci_iomem_resource; | ||
1027 | } | ||
1028 | } | 1021 | } |
1029 | 1022 | ||
1030 | /* | 1023 | /* |
@@ -1124,7 +1117,10 @@ void __iomem *ioremap(resource_size_t phys_addr, unsigned long size) | |||
1124 | got_it: | 1117 | got_it: |
1125 | trio_fd = controller->trio->fd; | 1118 | trio_fd = controller->trio->fd; |
1126 | 1119 | ||
1127 | offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + phys_addr; | 1120 | /* Convert the resource start to the bus address offset. */ |
1121 | start = phys_addr - controller->mem_offset; | ||
1122 | |||
1123 | offset = HV_TRIO_PIO_OFFSET(controller->pio_mem_index) + start; | ||
1128 | 1124 | ||
1129 | /* | 1125 | /* |
1130 | * We need to keep the PCI bus address's in-page offset in the VA. | 1126 | * We need to keep the PCI bus address's in-page offset in the VA. |
@@ -1172,11 +1168,11 @@ static int __devinit tile_cfg_read(struct pci_bus *bus, | |||
1172 | void *mmio_addr; | 1168 | void *mmio_addr; |
1173 | 1169 | ||
1174 | /* | 1170 | /* |
1175 | * Map all accesses to the local device (bus == 0) into the | 1171 | * Map all accesses to the local device on root bus into the |
1176 | * MMIO space of the MAC. Accesses to the downstream devices | 1172 | * MMIO space of the MAC. Accesses to the downstream devices |
1177 | * go to the PIO space. | 1173 | * go to the PIO space. |
1178 | */ | 1174 | */ |
1179 | if (busnum == 0) { | 1175 | if (pci_is_root_bus(bus)) { |
1180 | if (device == 0) { | 1176 | if (device == 0) { |
1181 | /* | 1177 | /* |
1182 | * This is the internal downstream P2P bridge, | 1178 | * This is the internal downstream P2P bridge, |
@@ -1205,11 +1201,11 @@ static int __devinit tile_cfg_read(struct pci_bus *bus, | |||
1205 | } | 1201 | } |
1206 | 1202 | ||
1207 | /* | 1203 | /* |
1208 | * Accesses to the directly attached device (bus == 1) have to be | 1204 | * Accesses to the directly attached device have to be |
1209 | * sent as type-0 configs. | 1205 | * sent as type-0 configs. |
1210 | */ | 1206 | */ |
1211 | 1207 | ||
1212 | if (busnum == 1) { | 1208 | if (busnum == (controller->first_busno + 1)) { |
1213 | /* | 1209 | /* |
1214 | * There is only one device off of our built-in P2P bridge. | 1210 | * There is only one device off of our built-in P2P bridge. |
1215 | */ | 1211 | */ |
@@ -1303,11 +1299,11 @@ static int __devinit tile_cfg_write(struct pci_bus *bus, | |||
1303 | u8 val_8 = (u8)val; | 1299 | u8 val_8 = (u8)val; |
1304 | 1300 | ||
1305 | /* | 1301 | /* |
1306 | * Map all accesses to the local device (bus == 0) into the | 1302 | * Map all accesses to the local device on root bus into the |
1307 | * MMIO space of the MAC. Accesses to the downstream devices | 1303 | * MMIO space of the MAC. Accesses to the downstream devices |
1308 | * go to the PIO space. | 1304 | * go to the PIO space. |
1309 | */ | 1305 | */ |
1310 | if (busnum == 0) { | 1306 | if (pci_is_root_bus(bus)) { |
1311 | if (device == 0) { | 1307 | if (device == 0) { |
1312 | /* | 1308 | /* |
1313 | * This is the internal downstream P2P bridge, | 1309 | * This is the internal downstream P2P bridge, |
@@ -1336,11 +1332,11 @@ static int __devinit tile_cfg_write(struct pci_bus *bus, | |||
1336 | } | 1332 | } |
1337 | 1333 | ||
1338 | /* | 1334 | /* |
1339 | * Accesses to the directly attached device (bus == 1) have to be | 1335 | * Accesses to the directly attached device have to be |
1340 | * sent as type-0 configs. | 1336 | * sent as type-0 configs. |
1341 | */ | 1337 | */ |
1342 | 1338 | ||
1343 | if (busnum == 1) { | 1339 | if (busnum == (controller->first_busno + 1)) { |
1344 | /* | 1340 | /* |
1345 | * There is only one device off of our built-in P2P bridge. | 1341 | * There is only one device off of our built-in P2P bridge. |
1346 | */ | 1342 | */ |
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index 2b8b689e596d..6a649a4462d3 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c | |||
@@ -1536,8 +1536,7 @@ static struct resource code_resource = { | |||
1536 | 1536 | ||
1537 | /* | 1537 | /* |
1538 | * On Pro, we reserve all resources above 4GB so that PCI won't try to put | 1538 | * On Pro, we reserve all resources above 4GB so that PCI won't try to put |
1539 | * mappings above 4GB; the standard allows that for some devices but | 1539 | * mappings above 4GB. |
1540 | * the probing code trunates values to 32 bits. | ||
1541 | */ | 1540 | */ |
1542 | #if defined(CONFIG_PCI) && !defined(__tilegx__) | 1541 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1543 | static struct resource* __init | 1542 | static struct resource* __init |
@@ -1584,7 +1583,6 @@ static int __init request_standard_resources(void) | |||
1584 | int i; | 1583 | int i; |
1585 | enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; | 1584 | enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET }; |
1586 | 1585 | ||
1587 | iomem_resource.end = -1LL; | ||
1588 | #if defined(CONFIG_PCI) && !defined(__tilegx__) | 1586 | #if defined(CONFIG_PCI) && !defined(__tilegx__) |
1589 | insert_non_bus_resource(); | 1587 | insert_non_bus_resource(); |
1590 | #endif | 1588 | #endif |