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 /arch/tile/kernel | |
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>
Diffstat (limited to 'arch/tile/kernel')
-rw-r--r-- | arch/tile/kernel/pci_gx.c | 128 |
1 files changed, 120 insertions, 8 deletions
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); |