.. | .. |
---|
60 | 60 | #define APB_ERR_EN_SHIFT 0 |
---|
61 | 61 | #define APB_ERR_EN BIT(APB_ERR_EN_SHIFT) |
---|
62 | 62 | |
---|
| 63 | +#define CFG_RD_SUCCESS 0 |
---|
| 64 | +#define CFG_RD_UR 1 |
---|
| 65 | +#define CFG_RD_CRS 2 |
---|
| 66 | +#define CFG_RD_CA 3 |
---|
63 | 67 | #define CFG_RETRY_STATUS 0xffff0001 |
---|
64 | 68 | #define CFG_RETRY_STATUS_TIMEOUT_US 500000 /* 500 milliseconds */ |
---|
65 | 69 | |
---|
.. | .. |
---|
159 | 163 | * @size_unit: inbound mapping region size unit, could be SZ_1K, SZ_1M, or |
---|
160 | 164 | * SZ_1G |
---|
161 | 165 | * @region_sizes: list of supported inbound mapping region sizes in KB, MB, or |
---|
162 | | - * GB, depedning on the size unit |
---|
| 166 | + * GB, depending on the size unit |
---|
163 | 167 | * @nr_sizes: number of supported inbound mapping region sizes |
---|
164 | 168 | * @nr_windows: number of supported inbound mapping windows for the region |
---|
165 | 169 | * @imap_addr_offset: register offset between the upper and lower 32-bit |
---|
.. | .. |
---|
188 | 192 | .imap_window_offset = 0x4, |
---|
189 | 193 | }, |
---|
190 | 194 | { |
---|
191 | | - /* IARR1/IMAP1 (currently unused) */ |
---|
192 | | - .type = IPROC_PCIE_IB_MAP_INVALID, |
---|
| 195 | + /* IARR1/IMAP1 */ |
---|
| 196 | + .type = IPROC_PCIE_IB_MAP_MEM, |
---|
| 197 | + .size_unit = SZ_1M, |
---|
| 198 | + .region_sizes = { 8 }, |
---|
| 199 | + .nr_sizes = 1, |
---|
| 200 | + .nr_windows = 8, |
---|
| 201 | + .imap_addr_offset = 0x4, |
---|
| 202 | + .imap_window_offset = 0x8, |
---|
| 203 | + |
---|
193 | 204 | }, |
---|
194 | 205 | { |
---|
195 | 206 | /* IARR2/IMAP2 */ |
---|
.. | .. |
---|
289 | 300 | IPROC_PCIE_IARR4, |
---|
290 | 301 | IPROC_PCIE_IMAP4, |
---|
291 | 302 | |
---|
| 303 | + /* config read status */ |
---|
| 304 | + IPROC_PCIE_CFG_RD_STATUS, |
---|
| 305 | + |
---|
292 | 306 | /* link status */ |
---|
293 | 307 | IPROC_PCIE_LINK_STATUS, |
---|
294 | 308 | |
---|
.. | .. |
---|
344 | 358 | [IPROC_PCIE_OMAP3] = 0xdf8, |
---|
345 | 359 | [IPROC_PCIE_IARR0] = 0xd00, |
---|
346 | 360 | [IPROC_PCIE_IMAP0] = 0xc00, |
---|
| 361 | + [IPROC_PCIE_IARR1] = 0xd08, |
---|
| 362 | + [IPROC_PCIE_IMAP1] = 0xd70, |
---|
347 | 363 | [IPROC_PCIE_IARR2] = 0xd10, |
---|
348 | 364 | [IPROC_PCIE_IMAP2] = 0xcc0, |
---|
349 | 365 | [IPROC_PCIE_IARR3] = 0xe00, |
---|
350 | 366 | [IPROC_PCIE_IMAP3] = 0xe08, |
---|
351 | 367 | [IPROC_PCIE_IARR4] = 0xe68, |
---|
352 | 368 | [IPROC_PCIE_IMAP4] = 0xe70, |
---|
| 369 | + [IPROC_PCIE_CFG_RD_STATUS] = 0xee0, |
---|
353 | 370 | [IPROC_PCIE_LINK_STATUS] = 0xf0c, |
---|
354 | 371 | [IPROC_PCIE_APB_ERR_EN] = 0xf40, |
---|
355 | 372 | }; |
---|
.. | .. |
---|
474 | 491 | return (pcie->base + offset); |
---|
475 | 492 | } |
---|
476 | 493 | |
---|
477 | | -static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) |
---|
| 494 | +static unsigned int iproc_pcie_cfg_retry(struct iproc_pcie *pcie, |
---|
| 495 | + void __iomem *cfg_data_p) |
---|
478 | 496 | { |
---|
479 | 497 | int timeout = CFG_RETRY_STATUS_TIMEOUT_US; |
---|
480 | 498 | unsigned int data; |
---|
| 499 | + u32 status; |
---|
481 | 500 | |
---|
482 | 501 | /* |
---|
483 | 502 | * As per PCIe spec r3.1, sec 2.3.2, CRS Software Visibility only |
---|
.. | .. |
---|
498 | 517 | */ |
---|
499 | 518 | data = readl(cfg_data_p); |
---|
500 | 519 | while (data == CFG_RETRY_STATUS && timeout--) { |
---|
| 520 | + /* |
---|
| 521 | + * CRS state is set in CFG_RD status register |
---|
| 522 | + * This will handle the case where CFG_RETRY_STATUS is |
---|
| 523 | + * valid config data. |
---|
| 524 | + */ |
---|
| 525 | + status = iproc_pcie_read_reg(pcie, IPROC_PCIE_CFG_RD_STATUS); |
---|
| 526 | + if (status != CFG_RD_CRS) |
---|
| 527 | + return data; |
---|
| 528 | + |
---|
501 | 529 | udelay(1); |
---|
502 | 530 | data = readl(cfg_data_p); |
---|
503 | 531 | } |
---|
.. | .. |
---|
576 | 604 | if (!cfg_data_p) |
---|
577 | 605 | return PCIBIOS_DEVICE_NOT_FOUND; |
---|
578 | 606 | |
---|
579 | | - data = iproc_pcie_cfg_retry(cfg_data_p); |
---|
| 607 | + data = iproc_pcie_cfg_retry(pcie, cfg_data_p); |
---|
580 | 608 | |
---|
581 | 609 | *val = data; |
---|
582 | 610 | if (size <= 2) |
---|
.. | .. |
---|
936 | 964 | resource_size_t window_size = |
---|
937 | 965 | ob_map->window_sizes[size_idx] * SZ_1M; |
---|
938 | 966 | |
---|
939 | | - if (size < window_size) |
---|
940 | | - continue; |
---|
| 967 | + /* |
---|
| 968 | + * Keep iterating until we reach the last window and |
---|
| 969 | + * with the minimal window size at index zero. In this |
---|
| 970 | + * case, we take a compromise by mapping it using the |
---|
| 971 | + * minimum window size that can be supported |
---|
| 972 | + */ |
---|
| 973 | + if (size < window_size) { |
---|
| 974 | + if (size_idx > 0 || window_idx > 0) |
---|
| 975 | + continue; |
---|
| 976 | + |
---|
| 977 | + /* |
---|
| 978 | + * For the corner case of reaching the minimal |
---|
| 979 | + * window size that can be supported on the |
---|
| 980 | + * last window |
---|
| 981 | + */ |
---|
| 982 | + axi_addr = ALIGN_DOWN(axi_addr, window_size); |
---|
| 983 | + pci_addr = ALIGN_DOWN(pci_addr, window_size); |
---|
| 984 | + size = window_size; |
---|
| 985 | + } |
---|
941 | 986 | |
---|
942 | 987 | if (!IS_ALIGNED(axi_addr, window_size) || |
---|
943 | 988 | !IS_ALIGNED(pci_addr, window_size)) { |
---|
.. | .. |
---|
1086 | 1131 | } |
---|
1087 | 1132 | |
---|
1088 | 1133 | static int iproc_pcie_setup_ib(struct iproc_pcie *pcie, |
---|
1089 | | - struct of_pci_range *range, |
---|
| 1134 | + struct resource_entry *entry, |
---|
1090 | 1135 | enum iproc_pcie_ib_map_type type) |
---|
1091 | 1136 | { |
---|
1092 | 1137 | struct device *dev = pcie->dev; |
---|
1093 | 1138 | struct iproc_pcie_ib *ib = &pcie->ib; |
---|
1094 | 1139 | int ret; |
---|
1095 | 1140 | unsigned int region_idx, size_idx; |
---|
1096 | | - u64 axi_addr = range->cpu_addr, pci_addr = range->pci_addr; |
---|
1097 | | - resource_size_t size = range->size; |
---|
| 1141 | + u64 axi_addr = entry->res->start; |
---|
| 1142 | + u64 pci_addr = entry->res->start - entry->offset; |
---|
| 1143 | + resource_size_t size = resource_size(entry->res); |
---|
1098 | 1144 | |
---|
1099 | 1145 | /* iterate through all IARR mapping regions */ |
---|
1100 | 1146 | for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) { |
---|
.. | .. |
---|
1148 | 1194 | |
---|
1149 | 1195 | static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie) |
---|
1150 | 1196 | { |
---|
1151 | | - struct of_pci_range range; |
---|
1152 | | - struct of_pci_range_parser parser; |
---|
1153 | | - int ret; |
---|
| 1197 | + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); |
---|
| 1198 | + struct resource_entry *entry; |
---|
| 1199 | + int ret = 0; |
---|
1154 | 1200 | |
---|
1155 | | - /* Get the dma-ranges from DT */ |
---|
1156 | | - ret = of_pci_dma_range_parser_init(&parser, pcie->dev->of_node); |
---|
1157 | | - if (ret) |
---|
1158 | | - return ret; |
---|
1159 | | - |
---|
1160 | | - for_each_of_pci_range(&parser, &range) { |
---|
| 1201 | + resource_list_for_each_entry(entry, &host->dma_ranges) { |
---|
1161 | 1202 | /* Each range entry corresponds to an inbound mapping region */ |
---|
1162 | | - ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_MEM); |
---|
| 1203 | + ret = iproc_pcie_setup_ib(pcie, entry, IPROC_PCIE_IB_MAP_MEM); |
---|
1163 | 1204 | if (ret) |
---|
1164 | | - return ret; |
---|
| 1205 | + break; |
---|
1165 | 1206 | } |
---|
1166 | 1207 | |
---|
1167 | | - return 0; |
---|
| 1208 | + return ret; |
---|
| 1209 | +} |
---|
| 1210 | + |
---|
| 1211 | +static void iproc_pcie_invalidate_mapping(struct iproc_pcie *pcie) |
---|
| 1212 | +{ |
---|
| 1213 | + struct iproc_pcie_ib *ib = &pcie->ib; |
---|
| 1214 | + struct iproc_pcie_ob *ob = &pcie->ob; |
---|
| 1215 | + int idx; |
---|
| 1216 | + |
---|
| 1217 | + if (pcie->ep_is_internal) |
---|
| 1218 | + return; |
---|
| 1219 | + |
---|
| 1220 | + if (pcie->need_ob_cfg) { |
---|
| 1221 | + /* iterate through all OARR mapping regions */ |
---|
| 1222 | + for (idx = ob->nr_windows - 1; idx >= 0; idx--) { |
---|
| 1223 | + iproc_pcie_write_reg(pcie, |
---|
| 1224 | + MAP_REG(IPROC_PCIE_OARR0, idx), 0); |
---|
| 1225 | + } |
---|
| 1226 | + } |
---|
| 1227 | + |
---|
| 1228 | + if (pcie->need_ib_cfg) { |
---|
| 1229 | + /* iterate through all IARR mapping regions */ |
---|
| 1230 | + for (idx = 0; idx < ib->nr_regions; idx++) { |
---|
| 1231 | + iproc_pcie_write_reg(pcie, |
---|
| 1232 | + MAP_REG(IPROC_PCIE_IARR0, idx), 0); |
---|
| 1233 | + } |
---|
| 1234 | + } |
---|
1168 | 1235 | } |
---|
1169 | 1236 | |
---|
1170 | 1237 | static int iproce_pcie_get_msi(struct iproc_pcie *pcie, |
---|
.. | .. |
---|
1198 | 1265 | static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) |
---|
1199 | 1266 | { |
---|
1200 | 1267 | int ret; |
---|
1201 | | - struct of_pci_range range; |
---|
| 1268 | + struct resource_entry entry; |
---|
1202 | 1269 | |
---|
1203 | | - memset(&range, 0, sizeof(range)); |
---|
1204 | | - range.size = SZ_32K; |
---|
1205 | | - range.pci_addr = range.cpu_addr = msi_addr & ~(range.size - 1); |
---|
| 1270 | + memset(&entry, 0, sizeof(entry)); |
---|
| 1271 | + entry.res = &entry.__res; |
---|
1206 | 1272 | |
---|
1207 | | - ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_IO); |
---|
| 1273 | + msi_addr &= ~(SZ_32K - 1); |
---|
| 1274 | + entry.res->start = msi_addr; |
---|
| 1275 | + entry.res->end = msi_addr + SZ_32K - 1; |
---|
| 1276 | + |
---|
| 1277 | + ret = iproc_pcie_setup_ib(pcie, &entry, IPROC_PCIE_IB_MAP_IO); |
---|
1208 | 1278 | return ret; |
---|
1209 | 1279 | } |
---|
1210 | 1280 | |
---|
.. | .. |
---|
1320 | 1390 | if (pcie->need_msi_steer) { |
---|
1321 | 1391 | ret = iproc_pcie_msi_steer(pcie, msi_node); |
---|
1322 | 1392 | if (ret) |
---|
1323 | | - return ret; |
---|
| 1393 | + goto out_put_node; |
---|
1324 | 1394 | } |
---|
1325 | 1395 | |
---|
1326 | 1396 | /* |
---|
1327 | 1397 | * If another MSI controller is being used, the call below should fail |
---|
1328 | 1398 | * but that is okay |
---|
1329 | 1399 | */ |
---|
1330 | | - return iproc_msi_init(pcie, msi_node); |
---|
| 1400 | + ret = iproc_msi_init(pcie, msi_node); |
---|
| 1401 | + |
---|
| 1402 | +out_put_node: |
---|
| 1403 | + of_node_put(msi_node); |
---|
| 1404 | + return ret; |
---|
1331 | 1405 | } |
---|
1332 | 1406 | |
---|
1333 | 1407 | static void iproc_pcie_msi_disable(struct iproc_pcie *pcie) |
---|
.. | .. |
---|
1405 | 1479 | { |
---|
1406 | 1480 | struct device *dev; |
---|
1407 | 1481 | int ret; |
---|
1408 | | - struct pci_bus *child; |
---|
1409 | 1482 | struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); |
---|
1410 | 1483 | |
---|
1411 | 1484 | dev = pcie->dev; |
---|
.. | .. |
---|
1415 | 1488 | dev_err(dev, "unable to initialize controller parameters\n"); |
---|
1416 | 1489 | return ret; |
---|
1417 | 1490 | } |
---|
1418 | | - |
---|
1419 | | - ret = devm_request_pci_bus_resources(dev, res); |
---|
1420 | | - if (ret) |
---|
1421 | | - return ret; |
---|
1422 | 1491 | |
---|
1423 | 1492 | ret = phy_init(pcie->phy); |
---|
1424 | 1493 | if (ret) { |
---|
.. | .. |
---|
1434 | 1503 | |
---|
1435 | 1504 | iproc_pcie_perst_ctrl(pcie, true); |
---|
1436 | 1505 | iproc_pcie_perst_ctrl(pcie, false); |
---|
| 1506 | + |
---|
| 1507 | + iproc_pcie_invalidate_mapping(pcie); |
---|
1437 | 1508 | |
---|
1438 | 1509 | if (pcie->need_ob_cfg) { |
---|
1439 | 1510 | ret = iproc_pcie_map_ranges(pcie, res); |
---|
.. | .. |
---|
1461 | 1532 | if (iproc_pcie_msi_enable(pcie)) |
---|
1462 | 1533 | dev_info(dev, "not using iProc MSI\n"); |
---|
1463 | 1534 | |
---|
1464 | | - list_splice_init(res, &host->windows); |
---|
1465 | | - host->busnr = 0; |
---|
1466 | | - host->dev.parent = dev; |
---|
1467 | 1535 | host->ops = &iproc_pcie_ops; |
---|
1468 | 1536 | host->sysdata = pcie; |
---|
1469 | 1537 | host->map_irq = pcie->map_irq; |
---|
1470 | | - host->swizzle_irq = pci_common_swizzle; |
---|
1471 | 1538 | |
---|
1472 | | - ret = pci_scan_root_bus_bridge(host); |
---|
| 1539 | + ret = pci_host_probe(host); |
---|
1473 | 1540 | if (ret < 0) { |
---|
1474 | 1541 | dev_err(dev, "failed to scan host: %d\n", ret); |
---|
1475 | 1542 | goto err_power_off_phy; |
---|
1476 | 1543 | } |
---|
1477 | | - |
---|
1478 | | - pci_assign_unassigned_bus_resources(host->bus); |
---|
1479 | | - |
---|
1480 | | - pcie->root_bus = host->bus; |
---|
1481 | | - |
---|
1482 | | - list_for_each_entry(child, &host->bus->children, node) |
---|
1483 | | - pcie_bus_configure_settings(child); |
---|
1484 | | - |
---|
1485 | | - pci_bus_add_devices(host->bus); |
---|
1486 | 1544 | |
---|
1487 | 1545 | return 0; |
---|
1488 | 1546 | |
---|
.. | .. |
---|
1496 | 1554 | |
---|
1497 | 1555 | int iproc_pcie_remove(struct iproc_pcie *pcie) |
---|
1498 | 1556 | { |
---|
1499 | | - pci_stop_root_bus(pcie->root_bus); |
---|
1500 | | - pci_remove_root_bus(pcie->root_bus); |
---|
| 1557 | + struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); |
---|
| 1558 | + |
---|
| 1559 | + pci_stop_root_bus(host->bus); |
---|
| 1560 | + pci_remove_root_bus(host->bus); |
---|
1501 | 1561 | |
---|
1502 | 1562 | iproc_pcie_msi_disable(pcie); |
---|
1503 | 1563 | |
---|