diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-02 16:45:22 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-06 12:55:32 -0400 |
commit | cf89c4262bd5fa70e67953126001c08ecea4f346 (patch) | |
tree | b968b7a7a2a9fb2140779948911e5c71b29585b1 | |
parent | a3c4f2fb26974b5134861af8f7593040ae61a1f4 (diff) |
tile PCI RC: support I/O space access
To enable this functionality, configure CONFIG_TILE_PCI_IO. Without
this flag, the kernel still assigns I/O address ranges to the
devices, but no TRIO resource and mapping support is provided.
We assign disjoint I/O address ranges to separate PCIe domains.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
-rw-r--r-- | arch/tile/Kconfig | 10 | ||||
-rw-r--r-- | arch/tile/include/asm/io.h | 126 | ||||
-rw-r--r-- | arch/tile/include/asm/pci.h | 11 | ||||
-rw-r--r-- | arch/tile/kernel/pci_gx.c | 128 |
4 files changed, 257 insertions, 18 deletions
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 24565a7ffe6d..bfff76947f83 100644 --- a/arch/tile/Kconfig +++ b/arch/tile/Kconfig | |||
@@ -396,6 +396,16 @@ config NO_IOMEM | |||
396 | config NO_IOPORT | 396 | config NO_IOPORT |
397 | def_bool !PCI | 397 | def_bool !PCI |
398 | 398 | ||
399 | config TILE_PCI_IO | ||
400 | bool "PCI I/O space support" | ||
401 | default n | ||
402 | depends on PCI | ||
403 | depends on TILEGX | ||
404 | ---help--- | ||
405 | Enable PCI I/O space support on TILEGx. Since the PCI I/O space | ||
406 | is used by few modern PCIe endpoint devices, its support is disabled | ||
407 | by default to save the TRIO PIO Region resource for other purposes. | ||
408 | |||
399 | source "drivers/pci/Kconfig" | 409 | source "drivers/pci/Kconfig" |
400 | 410 | ||
401 | config TILE_USB | 411 | config TILE_USB |
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h index 31672918064c..73b319e39a3b 100644 --- a/arch/tile/include/asm/io.h +++ b/arch/tile/include/asm/io.h | |||
@@ -19,7 +19,8 @@ | |||
19 | #include <linux/bug.h> | 19 | #include <linux/bug.h> |
20 | #include <asm/page.h> | 20 | #include <asm/page.h> |
21 | 21 | ||
22 | #define IO_SPACE_LIMIT 0xfffffffful | 22 | /* Maximum PCI I/O space address supported. */ |
23 | #define IO_SPACE_LIMIT 0xffffffff | ||
23 | 24 | ||
24 | /* | 25 | /* |
25 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | 26 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem |
@@ -281,8 +282,108 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
281 | 282 | ||
282 | #endif | 283 | #endif |
283 | 284 | ||
285 | #if CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) | ||
286 | |||
287 | static inline u8 inb(unsigned long addr) | ||
288 | { | ||
289 | return readb((volatile void __iomem *) addr); | ||
290 | } | ||
291 | |||
292 | static inline u16 inw(unsigned long addr) | ||
293 | { | ||
294 | return readw((volatile void __iomem *) addr); | ||
295 | } | ||
296 | |||
297 | static inline u32 inl(unsigned long addr) | ||
298 | { | ||
299 | return readl((volatile void __iomem *) addr); | ||
300 | } | ||
301 | |||
302 | static inline void outb(u8 b, unsigned long addr) | ||
303 | { | ||
304 | writeb(b, (volatile void __iomem *) addr); | ||
305 | } | ||
306 | |||
307 | static inline void outw(u16 b, unsigned long addr) | ||
308 | { | ||
309 | writew(b, (volatile void __iomem *) addr); | ||
310 | } | ||
311 | |||
312 | static inline void outl(u32 b, unsigned long addr) | ||
313 | { | ||
314 | writel(b, (volatile void __iomem *) addr); | ||
315 | } | ||
316 | |||
317 | static inline void insb(unsigned long addr, void *buffer, int count) | ||
318 | { | ||
319 | if (count) { | ||
320 | u8 *buf = buffer; | ||
321 | do { | ||
322 | u8 x = inb(addr); | ||
323 | *buf++ = x; | ||
324 | } while (--count); | ||
325 | } | ||
326 | } | ||
327 | |||
328 | static inline void insw(unsigned long addr, void *buffer, int count) | ||
329 | { | ||
330 | if (count) { | ||
331 | u16 *buf = buffer; | ||
332 | do { | ||
333 | u16 x = inw(addr); | ||
334 | *buf++ = x; | ||
335 | } while (--count); | ||
336 | } | ||
337 | } | ||
338 | |||
339 | static inline void insl(unsigned long addr, void *buffer, int count) | ||
340 | { | ||
341 | if (count) { | ||
342 | u32 *buf = buffer; | ||
343 | do { | ||
344 | u32 x = inl(addr); | ||
345 | *buf++ = x; | ||
346 | } while (--count); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | static inline void outsb(unsigned long addr, const void *buffer, int count) | ||
351 | { | ||
352 | if (count) { | ||
353 | const u8 *buf = buffer; | ||
354 | do { | ||
355 | outb(*buf++, addr); | ||
356 | } while (--count); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static inline void outsw(unsigned long addr, const void *buffer, int count) | ||
361 | { | ||
362 | if (count) { | ||
363 | const u16 *buf = buffer; | ||
364 | do { | ||
365 | outw(*buf++, addr); | ||
366 | } while (--count); | ||
367 | } | ||
368 | } | ||
369 | |||
370 | static inline void outsl(unsigned long addr, const void *buffer, int count) | ||
371 | { | ||
372 | if (count) { | ||
373 | const u32 *buf = buffer; | ||
374 | do { | ||
375 | outl(*buf++, addr); | ||
376 | } while (--count); | ||
377 | } | ||
378 | } | ||
379 | |||
380 | extern void __iomem *ioport_map(unsigned long port, unsigned int len); | ||
381 | extern void ioport_unmap(void __iomem *addr); | ||
382 | |||
383 | #else | ||
384 | |||
284 | /* | 385 | /* |
285 | * The Tile architecture does not support IOPORT, even with PCI. | 386 | * The TilePro architecture does not support IOPORT, even with PCI. |
286 | * Unfortunately we can't yet simply not declare these methods, | 387 | * Unfortunately we can't yet simply not declare these methods, |
287 | * since some generic code that compiles into the kernel, but | 388 | * since some generic code that compiles into the kernel, but |
288 | * we never run, uses them unconditionally. | 389 | * we never run, uses them unconditionally. |
@@ -290,7 +391,12 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, | |||
290 | 391 | ||
291 | static inline long ioport_panic(void) | 392 | static inline long ioport_panic(void) |
292 | { | 393 | { |
394 | #ifdef __tilegx__ | ||
395 | panic("PCI IO space support is disabled. Configure the kernel with" | ||
396 | " CONFIG_TILE_PCI_IO to enable it"); | ||
397 | #else | ||
293 | panic("inb/outb and friends do not exist on tile"); | 398 | panic("inb/outb and friends do not exist on tile"); |
399 | #endif | ||
294 | return 0; | 400 | return 0; |
295 | } | 401 | } |
296 | 402 | ||
@@ -335,13 +441,6 @@ static inline void outl(u32 b, unsigned long addr) | |||
335 | ioport_panic(); | 441 | ioport_panic(); |
336 | } | 442 | } |
337 | 443 | ||
338 | #define inb_p(addr) inb(addr) | ||
339 | #define inw_p(addr) inw(addr) | ||
340 | #define inl_p(addr) inl(addr) | ||
341 | #define outb_p(x, addr) outb((x), (addr)) | ||
342 | #define outw_p(x, addr) outw((x), (addr)) | ||
343 | #define outl_p(x, addr) outl((x), (addr)) | ||
344 | |||
345 | static inline void insb(unsigned long addr, void *buffer, int count) | 444 | static inline void insb(unsigned long addr, void *buffer, int count) |
346 | { | 445 | { |
347 | ioport_panic(); | 446 | ioport_panic(); |
@@ -372,6 +471,15 @@ static inline void outsl(unsigned long addr, const void *buffer, int count) | |||
372 | ioport_panic(); | 471 | ioport_panic(); |
373 | } | 472 | } |
374 | 473 | ||
474 | #endif /* CHIP_HAS_MMIO() && defined(CONFIG_TILE_PCI_IO) */ | ||
475 | |||
476 | #define inb_p(addr) inb(addr) | ||
477 | #define inw_p(addr) inw(addr) | ||
478 | #define inl_p(addr) inl(addr) | ||
479 | #define outb_p(x, addr) outb((x), (addr)) | ||
480 | #define outw_p(x, addr) outw((x), (addr)) | ||
481 | #define outl_p(x, addr) outl((x), (addr)) | ||
482 | |||
375 | #define ioread16be(addr) be16_to_cpu(ioread16(addr)) | 483 | #define ioread16be(addr) be16_to_cpu(ioread16(addr)) |
376 | #define ioread32be(addr) be32_to_cpu(ioread32(addr)) | 484 | #define ioread32be(addr) be32_to_cpu(ioread32(addr)) |
377 | #define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr)) | 485 | #define iowrite16be(v, addr) iowrite16(be16_to_cpu(v), (addr)) |
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h index cd10e654916e..9cf5308b1657 100644 --- a/arch/tile/include/asm/pci.h +++ b/arch/tile/include/asm/pci.h | |||
@@ -144,6 +144,10 @@ struct pci_controller { | |||
144 | 144 | ||
145 | int pio_mem_index; /* PIO region index for memory access */ | 145 | int pio_mem_index; /* PIO region index for memory access */ |
146 | 146 | ||
147 | #ifdef CONFIG_TILE_PCI_IO | ||
148 | int pio_io_index; /* PIO region index for I/O space access */ | ||
149 | #endif | ||
150 | |||
147 | /* | 151 | /* |
148 | * Mem-Map regions for all the memory controllers so that Linux can | 152 | * Mem-Map regions for all the memory controllers so that Linux can |
149 | * map all of its physical memory space to the PCI bus. | 153 | * map all of its physical memory space to the PCI bus. |
@@ -153,6 +157,10 @@ struct pci_controller { | |||
153 | int index; /* PCI domain number */ | 157 | int index; /* PCI domain number */ |
154 | struct pci_bus *root_bus; | 158 | struct pci_bus *root_bus; |
155 | 159 | ||
160 | /* PCI I/O space resource for this controller. */ | ||
161 | struct resource io_space; | ||
162 | char io_space_name[32]; | ||
163 | |||
156 | /* PCI memory space resource for this controller. */ | 164 | /* PCI memory space resource for this controller. */ |
157 | struct resource mem_space; | 165 | struct resource mem_space; |
158 | char mem_space_name[32]; | 166 | char mem_space_name[32]; |
@@ -210,7 +218,8 @@ static inline int pcibios_assign_all_busses(void) | |||
210 | } | 218 | } |
211 | 219 | ||
212 | #define PCIBIOS_MIN_MEM 0 | 220 | #define PCIBIOS_MIN_MEM 0 |
213 | #define PCIBIOS_MIN_IO 0 | 221 | /* Minimum PCI I/O address, starting at the page boundary. */ |
222 | #define PCIBIOS_MIN_IO PAGE_SIZE | ||
214 | 223 | ||
215 | /* Use any cpu for PCI. */ | 224 | /* Use any cpu for PCI. */ |
216 | #define cpumask_of_pcibus(bus) cpu_online_mask | 225 | #define cpumask_of_pcibus(bus) cpu_online_mask |
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c index bf8c69de2792..fde35891e9a7 100644 --- a/arch/tile/kernel/pci_gx.c +++ b/arch/tile/kernel/pci_gx.c | |||
@@ -77,6 +77,9 @@ static int rc_delay[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; | |||
77 | /* Default number of seconds that the PCIe RC port probe can be delayed. */ | 77 | /* Default number of seconds that the PCIe RC port probe can be delayed. */ |
78 | #define DEFAULT_RC_DELAY 10 | 78 | #define DEFAULT_RC_DELAY 10 |
79 | 79 | ||
80 | /* The PCI I/O space size in each PCI domain. */ | ||
81 | #define IO_SPACE_SIZE 0x10000 | ||
82 | |||
80 | /* Array of the PCIe ports configuration info obtained from the BIB. */ | 83 | /* Array of the PCIe ports configuration info obtained from the BIB. */ |
81 | struct pcie_port_property pcie_ports[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; | 84 | struct pcie_port_property pcie_ports[TILEGX_NUM_TRIO][TILEGX_TRIO_PCIES]; |
82 | 85 | ||
@@ -421,6 +424,17 @@ out: | |||
421 | controller->index = i; | 424 | controller->index = i; |
422 | controller->ops = &tile_cfg_ops; | 425 | controller->ops = &tile_cfg_ops; |
423 | 426 | ||
427 | controller->io_space.start = PCIBIOS_MIN_IO + | ||
428 | (i * IO_SPACE_SIZE); | ||
429 | controller->io_space.end = controller->io_space.start + | ||
430 | IO_SPACE_SIZE - 1; | ||
431 | BUG_ON(controller->io_space.end > IO_SPACE_LIMIT); | ||
432 | controller->io_space.flags = IORESOURCE_IO; | ||
433 | snprintf(controller->io_space_name, | ||
434 | sizeof(controller->io_space_name), | ||
435 | "PCI I/O domain %d", i); | ||
436 | controller->io_space.name = controller->io_space_name; | ||
437 | |||
424 | /* | 438 | /* |
425 | * The PCI memory resource is located above the PA space. | 439 | * The PCI memory resource is located above the PA space. |
426 | * For every host bridge, the BAR window or the MMIO aperture | 440 | * For every host bridge, the BAR window or the MMIO aperture |
@@ -861,17 +875,16 @@ int __init pcibios_init(void) | |||
861 | /* | 875 | /* |
862 | * The PCI memory resource is located above the PA space. | 876 | * The PCI memory resource is located above the PA space. |
863 | * The memory range for the PCI root bus should not overlap | 877 | * The memory range for the PCI root bus should not overlap |
864 | * with the physical RAM | 878 | * with the physical RAM. |
865 | */ | 879 | */ |
866 | pci_add_resource_offset(&resources, &controller->mem_space, | 880 | pci_add_resource_offset(&resources, &controller->mem_space, |
867 | controller->mem_offset); | 881 | controller->mem_offset); |
868 | 882 | pci_add_resource(&resources, &controller->io_space); | |
869 | controller->first_busno = next_busno; | 883 | controller->first_busno = next_busno; |
870 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, | 884 | bus = pci_scan_root_bus(NULL, next_busno, controller->ops, |
871 | controller, &resources); | 885 | controller, &resources); |
872 | controller->root_bus = bus; | 886 | controller->root_bus = bus; |
873 | next_busno = bus->busn_res.end + 1; | 887 | next_busno = bus->busn_res.end + 1; |
874 | |||
875 | } | 888 | } |
876 | 889 | ||
877 | /* Do machine dependent PCI interrupt routing */ | 890 | /* Do machine dependent PCI interrupt routing */ |
@@ -915,9 +928,9 @@ int __init pcibios_init(void) | |||
915 | pci_controllers[i].mem_resources[0] = | 928 | pci_controllers[i].mem_resources[0] = |
916 | *next_bus->resource[0]; | 929 | *next_bus->resource[0]; |
917 | pci_controllers[i].mem_resources[1] = | 930 | pci_controllers[i].mem_resources[1] = |
918 | *next_bus->resource[1]; | 931 | *next_bus->resource[1]; |
919 | pci_controllers[i].mem_resources[2] = | 932 | pci_controllers[i].mem_resources[2] = |
920 | *next_bus->resource[2]; | 933 | *next_bus->resource[2]; |
921 | 934 | ||
922 | break; | 935 | break; |
923 | } | 936 | } |
@@ -967,6 +980,39 @@ int __init pcibios_init(void) | |||
967 | continue; | 980 | continue; |
968 | } | 981 | } |
969 | 982 | ||
983 | #ifdef CONFIG_TILE_PCI_IO | ||
984 | /* | ||
985 | * Alloc a PIO region for PCI I/O space access for each RC port. | ||
986 | */ | ||
987 | ret = gxio_trio_alloc_pio_regions(trio_context, 1, 0, 0); | ||
988 | if (ret < 0) { | ||
989 | pr_err("PCI: I/O PIO alloc failure on TRIO %d mac %d, " | ||
990 | "give up\n", controller->trio_index, | ||
991 | controller->mac); | ||
992 | |||
993 | continue; | ||
994 | } | ||
995 | |||
996 | controller->pio_io_index = ret; | ||
997 | |||
998 | /* | ||
999 | * For PIO IO, the bus_address_hi parameter is hard-coded 0 | ||
1000 | * because PCI I/O address space is 32-bit. | ||
1001 | */ | ||
1002 | ret = gxio_trio_init_pio_region_aux(trio_context, | ||
1003 | controller->pio_io_index, | ||
1004 | controller->mac, | ||
1005 | 0, | ||
1006 | HV_TRIO_PIO_FLAG_IO_SPACE); | ||
1007 | if (ret < 0) { | ||
1008 | pr_err("PCI: I/O PIO init failure on TRIO %d mac %d, " | ||
1009 | "give up\n", controller->trio_index, | ||
1010 | controller->mac); | ||
1011 | |||
1012 | continue; | ||
1013 | } | ||
1014 | #endif | ||
1015 | |||
970 | /* | 1016 | /* |
971 | * Configure a Mem-Map region for each memory controller so | 1017 | * Configure a Mem-Map region for each memory controller so |
972 | * that Linux can map all of its PA space to the PCI bus. | 1018 | * that Linux can map all of its PA space to the PCI bus. |
@@ -1052,8 +1098,7 @@ char *pcibios_setup(char *str) | |||
1052 | 1098 | ||
1053 | /* | 1099 | /* |
1054 | * Enable memory address decoding, as appropriate, for the | 1100 | * Enable memory address decoding, as appropriate, for the |
1055 | * device described by the 'dev' struct. The I/O decoding | 1101 | * device described by the 'dev' struct. |
1056 | * is disabled, though the TILE-Gx supports I/O addressing. | ||
1057 | * | 1102 | * |
1058 | * This is called from the generic PCI layer, and can be called | 1103 | * This is called from the generic PCI layer, and can be called |
1059 | * for bridges or endpoints. | 1104 | * for bridges or endpoints. |
@@ -1134,10 +1179,77 @@ got_it: | |||
1134 | * We need to keep the PCI bus address's in-page offset in the VA. | 1179 | * We need to keep the PCI bus address's in-page offset in the VA. |
1135 | */ | 1180 | */ |
1136 | return iorpc_ioremap(trio_fd, offset, size) + | 1181 | return iorpc_ioremap(trio_fd, offset, size) + |
1137 | (phys_addr & (PAGE_SIZE - 1)); | 1182 | (start & (PAGE_SIZE - 1)); |
1138 | } | 1183 | } |
1139 | EXPORT_SYMBOL(ioremap); | 1184 | EXPORT_SYMBOL(ioremap); |
1140 | 1185 | ||
1186 | #ifdef CONFIG_TILE_PCI_IO | ||
1187 | /* Map a PCI I/O address into VA space. */ | ||
1188 | void __iomem *ioport_map(unsigned long port, unsigned int size) | ||
1189 | { | ||
1190 | struct pci_controller *controller = NULL; | ||
1191 | resource_size_t bar_start; | ||
1192 | resource_size_t bar_end; | ||
1193 | resource_size_t offset; | ||
1194 | resource_size_t start; | ||
1195 | resource_size_t end; | ||
1196 | int trio_fd; | ||
1197 | int i; | ||
1198 | |||
1199 | start = port; | ||
1200 | end = port + size - 1; | ||
1201 | |||
1202 | /* | ||
1203 | * In the following, each PCI controller's mem_resources[0] | ||
1204 | * represents its PCI I/O resource. By searching port in each | ||
1205 | * controller's mem_resources[0], we can determine the controller | ||
1206 | * that should accept the PCI I/O access. | ||
1207 | */ | ||
1208 | |||
1209 | for (i = 0; i < num_rc_controllers; i++) { | ||
1210 | /* | ||
1211 | * Skip controllers that are not properly initialized or | ||
1212 | * have down links. | ||
1213 | */ | ||
1214 | if (pci_controllers[i].root_bus == NULL) | ||
1215 | continue; | ||
1216 | |||
1217 | bar_start = pci_controllers[i].mem_resources[0].start; | ||
1218 | bar_end = pci_controllers[i].mem_resources[0].end; | ||
1219 | |||
1220 | if ((start >= bar_start) && (end <= bar_end)) { | ||
1221 | |||
1222 | controller = &pci_controllers[i]; | ||
1223 | |||
1224 | goto got_it; | ||
1225 | } | ||
1226 | } | ||
1227 | |||
1228 | if (controller == NULL) | ||
1229 | return NULL; | ||
1230 | |||
1231 | got_it: | ||
1232 | trio_fd = controller->trio->fd; | ||
1233 | |||
1234 | /* Convert the resource start to the bus address offset. */ | ||
1235 | port -= controller->io_space.start; | ||
1236 | |||
1237 | offset = HV_TRIO_PIO_OFFSET(controller->pio_io_index) + port; | ||
1238 | |||
1239 | /* | ||
1240 | * We need to keep the PCI bus address's in-page offset in the VA. | ||
1241 | */ | ||
1242 | return iorpc_ioremap(trio_fd, offset, size) + (port & (PAGE_SIZE - 1)); | ||
1243 | } | ||
1244 | EXPORT_SYMBOL(ioport_map); | ||
1245 | |||
1246 | void ioport_unmap(void __iomem *addr) | ||
1247 | { | ||
1248 | iounmap(addr); | ||
1249 | } | ||
1250 | EXPORT_SYMBOL(ioport_unmap); | ||
1251 | #endif | ||
1252 | |||
1141 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | 1253 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) |
1142 | { | 1254 | { |
1143 | iounmap(addr); | 1255 | iounmap(addr); |