diff options
-rw-r--r-- | drivers/pci/controller/pcie-iproc.c | 159 | ||||
-rw-r--r-- | drivers/pci/controller/pcie-iproc.h | 8 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 3 |
3 files changed, 144 insertions, 26 deletions
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c index 3c76c5fa4f32..3160e9342a2f 100644 --- a/drivers/pci/controller/pcie-iproc.c +++ b/drivers/pci/controller/pcie-iproc.c | |||
@@ -85,6 +85,8 @@ | |||
85 | #define IMAP_VALID_SHIFT 0 | 85 | #define IMAP_VALID_SHIFT 0 |
86 | #define IMAP_VALID BIT(IMAP_VALID_SHIFT) | 86 | #define IMAP_VALID BIT(IMAP_VALID_SHIFT) |
87 | 87 | ||
88 | #define IPROC_PCI_PM_CAP 0x48 | ||
89 | #define IPROC_PCI_PM_CAP_MASK 0xffff | ||
88 | #define IPROC_PCI_EXP_CAP 0xac | 90 | #define IPROC_PCI_EXP_CAP 0xac |
89 | 91 | ||
90 | #define IPROC_PCIE_REG_INVALID 0xffff | 92 | #define IPROC_PCIE_REG_INVALID 0xffff |
@@ -375,6 +377,17 @@ static const u16 iproc_pcie_reg_paxc_v2[] = { | |||
375 | [IPROC_PCIE_CFG_DATA] = 0x1fc, | 377 | [IPROC_PCIE_CFG_DATA] = 0x1fc, |
376 | }; | 378 | }; |
377 | 379 | ||
380 | /* | ||
381 | * List of device IDs of controllers that have corrupted capability list that | ||
382 | * require SW fixup | ||
383 | */ | ||
384 | static const u16 iproc_pcie_corrupt_cap_did[] = { | ||
385 | 0x16cd, | ||
386 | 0x16f0, | ||
387 | 0xd802, | ||
388 | 0xd804 | ||
389 | }; | ||
390 | |||
378 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) | 391 | static inline struct iproc_pcie *iproc_data(struct pci_bus *bus) |
379 | { | 392 | { |
380 | struct iproc_pcie *pcie = bus->sysdata; | 393 | struct iproc_pcie *pcie = bus->sysdata; |
@@ -495,6 +508,49 @@ static unsigned int iproc_pcie_cfg_retry(void __iomem *cfg_data_p) | |||
495 | return data; | 508 | return data; |
496 | } | 509 | } |
497 | 510 | ||
511 | static void iproc_pcie_fix_cap(struct iproc_pcie *pcie, int where, u32 *val) | ||
512 | { | ||
513 | u32 i, dev_id; | ||
514 | |||
515 | switch (where & ~0x3) { | ||
516 | case PCI_VENDOR_ID: | ||
517 | dev_id = *val >> 16; | ||
518 | |||
519 | /* | ||
520 | * Activate fixup for those controllers that have corrupted | ||
521 | * capability list registers | ||
522 | */ | ||
523 | for (i = 0; i < ARRAY_SIZE(iproc_pcie_corrupt_cap_did); i++) | ||
524 | if (dev_id == iproc_pcie_corrupt_cap_did[i]) | ||
525 | pcie->fix_paxc_cap = true; | ||
526 | break; | ||
527 | |||
528 | case IPROC_PCI_PM_CAP: | ||
529 | if (pcie->fix_paxc_cap) { | ||
530 | /* advertise PM, force next capability to PCIe */ | ||
531 | *val &= ~IPROC_PCI_PM_CAP_MASK; | ||
532 | *val |= IPROC_PCI_EXP_CAP << 8 | PCI_CAP_ID_PM; | ||
533 | } | ||
534 | break; | ||
535 | |||
536 | case IPROC_PCI_EXP_CAP: | ||
537 | if (pcie->fix_paxc_cap) { | ||
538 | /* advertise root port, version 2, terminate here */ | ||
539 | *val = (PCI_EXP_TYPE_ROOT_PORT << 4 | 2) << 16 | | ||
540 | PCI_CAP_ID_EXP; | ||
541 | } | ||
542 | break; | ||
543 | |||
544 | case IPROC_PCI_EXP_CAP + PCI_EXP_RTCTL: | ||
545 | /* Don't advertise CRS SV support */ | ||
546 | *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16); | ||
547 | break; | ||
548 | |||
549 | default: | ||
550 | break; | ||
551 | } | ||
552 | } | ||
553 | |||
498 | static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | 554 | static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, |
499 | int where, int size, u32 *val) | 555 | int where, int size, u32 *val) |
500 | { | 556 | { |
@@ -509,13 +565,10 @@ static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | |||
509 | /* root complex access */ | 565 | /* root complex access */ |
510 | if (busno == 0) { | 566 | if (busno == 0) { |
511 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | 567 | ret = pci_generic_config_read32(bus, devfn, where, size, val); |
512 | if (ret != PCIBIOS_SUCCESSFUL) | 568 | if (ret == PCIBIOS_SUCCESSFUL) |
513 | return ret; | 569 | iproc_pcie_fix_cap(pcie, where, val); |
514 | 570 | ||
515 | /* Don't advertise CRS SV support */ | 571 | return ret; |
516 | if ((where & ~0x3) == IPROC_PCI_EXP_CAP + PCI_EXP_RTCTL) | ||
517 | *val &= ~(PCI_EXP_RTCAP_CRSVIS << 16); | ||
518 | return PCIBIOS_SUCCESSFUL; | ||
519 | } | 572 | } |
520 | 573 | ||
521 | cfg_data_p = iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where); | 574 | cfg_data_p = iproc_pcie_map_ep_cfg_reg(pcie, busno, slot, fn, where); |
@@ -529,6 +582,25 @@ static int iproc_pcie_config_read(struct pci_bus *bus, unsigned int devfn, | |||
529 | if (size <= 2) | 582 | if (size <= 2) |
530 | *val = (data >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); | 583 | *val = (data >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); |
531 | 584 | ||
585 | /* | ||
586 | * For PAXC and PAXCv2, the total number of PFs that one can enumerate | ||
587 | * depends on the firmware configuration. Unfortunately, due to an ASIC | ||
588 | * bug, unconfigured PFs cannot be properly hidden from the root | ||
589 | * complex. As a result, write access to these PFs will cause bus lock | ||
590 | * up on the embedded processor | ||
591 | * | ||
592 | * Since all unconfigured PFs are left with an incorrect, staled device | ||
593 | * ID of 0x168e (PCI_DEVICE_ID_NX2_57810), we try to catch those access | ||
594 | * early here and reject them all | ||
595 | */ | ||
596 | #define DEVICE_ID_MASK 0xffff0000 | ||
597 | #define DEVICE_ID_SHIFT 16 | ||
598 | if (pcie->rej_unconfig_pf && | ||
599 | (where & CFG_ADDR_REG_NUM_MASK) == PCI_VENDOR_ID) | ||
600 | if ((*val & DEVICE_ID_MASK) == | ||
601 | (PCI_DEVICE_ID_NX2_57810 << DEVICE_ID_SHIFT)) | ||
602 | return PCIBIOS_FUNC_NOT_SUPPORTED; | ||
603 | |||
532 | return PCIBIOS_SUCCESSFUL; | 604 | return PCIBIOS_SUCCESSFUL; |
533 | } | 605 | } |
534 | 606 | ||
@@ -628,7 +700,7 @@ static int iproc_pcie_config_read32(struct pci_bus *bus, unsigned int devfn, | |||
628 | struct iproc_pcie *pcie = iproc_data(bus); | 700 | struct iproc_pcie *pcie = iproc_data(bus); |
629 | 701 | ||
630 | iproc_pcie_apb_err_disable(bus, true); | 702 | iproc_pcie_apb_err_disable(bus, true); |
631 | if (pcie->type == IPROC_PCIE_PAXB_V2) | 703 | if (pcie->iproc_cfg_read) |
632 | ret = iproc_pcie_config_read(bus, devfn, where, size, val); | 704 | ret = iproc_pcie_config_read(bus, devfn, where, size, val); |
633 | else | 705 | else |
634 | ret = pci_generic_config_read32(bus, devfn, where, size, val); | 706 | ret = pci_generic_config_read32(bus, devfn, where, size, val); |
@@ -808,14 +880,14 @@ static inline int iproc_pcie_ob_write(struct iproc_pcie *pcie, int window_idx, | |||
808 | writel(lower_32_bits(pci_addr), pcie->base + omap_offset); | 880 | writel(lower_32_bits(pci_addr), pcie->base + omap_offset); |
809 | writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4); | 881 | writel(upper_32_bits(pci_addr), pcie->base + omap_offset + 4); |
810 | 882 | ||
811 | dev_info(dev, "ob window [%d]: offset 0x%x axi %pap pci %pap\n", | 883 | dev_dbg(dev, "ob window [%d]: offset 0x%x axi %pap pci %pap\n", |
812 | window_idx, oarr_offset, &axi_addr, &pci_addr); | 884 | window_idx, oarr_offset, &axi_addr, &pci_addr); |
813 | dev_info(dev, "oarr lo 0x%x oarr hi 0x%x\n", | 885 | dev_dbg(dev, "oarr lo 0x%x oarr hi 0x%x\n", |
814 | readl(pcie->base + oarr_offset), | 886 | readl(pcie->base + oarr_offset), |
815 | readl(pcie->base + oarr_offset + 4)); | 887 | readl(pcie->base + oarr_offset + 4)); |
816 | dev_info(dev, "omap lo 0x%x omap hi 0x%x\n", | 888 | dev_dbg(dev, "omap lo 0x%x omap hi 0x%x\n", |
817 | readl(pcie->base + omap_offset), | 889 | readl(pcie->base + omap_offset), |
818 | readl(pcie->base + omap_offset + 4)); | 890 | readl(pcie->base + omap_offset + 4)); |
819 | 891 | ||
820 | return 0; | 892 | return 0; |
821 | } | 893 | } |
@@ -982,8 +1054,8 @@ static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx, | |||
982 | iproc_pcie_reg_is_invalid(imap_offset)) | 1054 | iproc_pcie_reg_is_invalid(imap_offset)) |
983 | return -EINVAL; | 1055 | return -EINVAL; |
984 | 1056 | ||
985 | dev_info(dev, "ib region [%d]: offset 0x%x axi %pap pci %pap\n", | 1057 | dev_dbg(dev, "ib region [%d]: offset 0x%x axi %pap pci %pap\n", |
986 | region_idx, iarr_offset, &axi_addr, &pci_addr); | 1058 | region_idx, iarr_offset, &axi_addr, &pci_addr); |
987 | 1059 | ||
988 | /* | 1060 | /* |
989 | * Program the IARR registers. The upper 32-bit IARR register is | 1061 | * Program the IARR registers. The upper 32-bit IARR register is |
@@ -993,9 +1065,9 @@ static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx, | |||
993 | pcie->base + iarr_offset); | 1065 | pcie->base + iarr_offset); |
994 | writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4); | 1066 | writel(upper_32_bits(pci_addr), pcie->base + iarr_offset + 4); |
995 | 1067 | ||
996 | dev_info(dev, "iarr lo 0x%x iarr hi 0x%x\n", | 1068 | dev_dbg(dev, "iarr lo 0x%x iarr hi 0x%x\n", |
997 | readl(pcie->base + iarr_offset), | 1069 | readl(pcie->base + iarr_offset), |
998 | readl(pcie->base + iarr_offset + 4)); | 1070 | readl(pcie->base + iarr_offset + 4)); |
999 | 1071 | ||
1000 | /* | 1072 | /* |
1001 | * Now program the IMAP registers. Each IARR region may have one or | 1073 | * Now program the IMAP registers. Each IARR region may have one or |
@@ -1009,10 +1081,10 @@ static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx, | |||
1009 | writel(upper_32_bits(axi_addr), | 1081 | writel(upper_32_bits(axi_addr), |
1010 | pcie->base + imap_offset + ib_map->imap_addr_offset); | 1082 | pcie->base + imap_offset + ib_map->imap_addr_offset); |
1011 | 1083 | ||
1012 | dev_info(dev, "imap window [%d] lo 0x%x hi 0x%x\n", | 1084 | dev_dbg(dev, "imap window [%d] lo 0x%x hi 0x%x\n", |
1013 | window_idx, readl(pcie->base + imap_offset), | 1085 | window_idx, readl(pcie->base + imap_offset), |
1014 | readl(pcie->base + imap_offset + | 1086 | readl(pcie->base + imap_offset + |
1015 | ib_map->imap_addr_offset)); | 1087 | ib_map->imap_addr_offset)); |
1016 | 1088 | ||
1017 | imap_offset += ib_map->imap_window_offset; | 1089 | imap_offset += ib_map->imap_window_offset; |
1018 | axi_addr += size; | 1090 | axi_addr += size; |
@@ -1144,10 +1216,22 @@ static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) | |||
1144 | return ret; | 1216 | return ret; |
1145 | } | 1217 | } |
1146 | 1218 | ||
1147 | static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr) | 1219 | static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr, |
1220 | bool enable) | ||
1148 | { | 1221 | { |
1149 | u32 val; | 1222 | u32 val; |
1150 | 1223 | ||
1224 | if (!enable) { | ||
1225 | /* | ||
1226 | * Disable PAXC MSI steering. All write transfers will be | ||
1227 | * treated as non-MSI transfers | ||
1228 | */ | ||
1229 | val = iproc_pcie_read_reg(pcie, IPROC_PCIE_MSI_EN_CFG); | ||
1230 | val &= ~MSI_ENABLE_CFG; | ||
1231 | iproc_pcie_write_reg(pcie, IPROC_PCIE_MSI_EN_CFG, val); | ||
1232 | return; | ||
1233 | } | ||
1234 | |||
1151 | /* | 1235 | /* |
1152 | * Program bits [43:13] of address of GITS_TRANSLATER register into | 1236 | * Program bits [43:13] of address of GITS_TRANSLATER register into |
1153 | * bits [30:0] of the MSI base address register. In fact, in all iProc | 1237 | * bits [30:0] of the MSI base address register. In fact, in all iProc |
@@ -1201,7 +1285,7 @@ static int iproc_pcie_msi_steer(struct iproc_pcie *pcie, | |||
1201 | return ret; | 1285 | return ret; |
1202 | break; | 1286 | break; |
1203 | case IPROC_PCIE_PAXC_V2: | 1287 | case IPROC_PCIE_PAXC_V2: |
1204 | iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr); | 1288 | iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr, true); |
1205 | break; | 1289 | break; |
1206 | default: | 1290 | default: |
1207 | return -EINVAL; | 1291 | return -EINVAL; |
@@ -1271,6 +1355,7 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | |||
1271 | break; | 1355 | break; |
1272 | case IPROC_PCIE_PAXB: | 1356 | case IPROC_PCIE_PAXB: |
1273 | regs = iproc_pcie_reg_paxb; | 1357 | regs = iproc_pcie_reg_paxb; |
1358 | pcie->iproc_cfg_read = true; | ||
1274 | pcie->has_apb_err_disable = true; | 1359 | pcie->has_apb_err_disable = true; |
1275 | if (pcie->need_ob_cfg) { | 1360 | if (pcie->need_ob_cfg) { |
1276 | pcie->ob_map = paxb_ob_map; | 1361 | pcie->ob_map = paxb_ob_map; |
@@ -1293,10 +1378,14 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie) | |||
1293 | case IPROC_PCIE_PAXC: | 1378 | case IPROC_PCIE_PAXC: |
1294 | regs = iproc_pcie_reg_paxc; | 1379 | regs = iproc_pcie_reg_paxc; |
1295 | pcie->ep_is_internal = true; | 1380 | pcie->ep_is_internal = true; |
1381 | pcie->iproc_cfg_read = true; | ||
1382 | pcie->rej_unconfig_pf = true; | ||
1296 | break; | 1383 | break; |
1297 | case IPROC_PCIE_PAXC_V2: | 1384 | case IPROC_PCIE_PAXC_V2: |
1298 | regs = iproc_pcie_reg_paxc_v2; | 1385 | regs = iproc_pcie_reg_paxc_v2; |
1299 | pcie->ep_is_internal = true; | 1386 | pcie->ep_is_internal = true; |
1387 | pcie->iproc_cfg_read = true; | ||
1388 | pcie->rej_unconfig_pf = true; | ||
1300 | pcie->need_msi_steer = true; | 1389 | pcie->need_msi_steer = true; |
1301 | break; | 1390 | break; |
1302 | default: | 1391 | default: |
@@ -1427,6 +1516,24 @@ int iproc_pcie_remove(struct iproc_pcie *pcie) | |||
1427 | } | 1516 | } |
1428 | EXPORT_SYMBOL(iproc_pcie_remove); | 1517 | EXPORT_SYMBOL(iproc_pcie_remove); |
1429 | 1518 | ||
1519 | /* | ||
1520 | * The MSI parsing logic in certain revisions of Broadcom PAXC based root | ||
1521 | * complex does not work and needs to be disabled | ||
1522 | */ | ||
1523 | static void quirk_paxc_disable_msi_parsing(struct pci_dev *pdev) | ||
1524 | { | ||
1525 | struct iproc_pcie *pcie = iproc_data(pdev->bus); | ||
1526 | |||
1527 | if (pdev->hdr_type == PCI_HEADER_TYPE_BRIDGE) | ||
1528 | iproc_pcie_paxc_v2_msi_steer(pcie, 0, false); | ||
1529 | } | ||
1530 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, | ||
1531 | quirk_paxc_disable_msi_parsing); | ||
1532 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, | ||
1533 | quirk_paxc_disable_msi_parsing); | ||
1534 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, | ||
1535 | quirk_paxc_disable_msi_parsing); | ||
1536 | |||
1430 | MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>"); | 1537 | MODULE_AUTHOR("Ray Jui <rjui@broadcom.com>"); |
1431 | MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver"); | 1538 | MODULE_DESCRIPTION("Broadcom iPROC PCIe common driver"); |
1432 | MODULE_LICENSE("GPL v2"); | 1539 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/pci/controller/pcie-iproc.h b/drivers/pci/controller/pcie-iproc.h index 814b600b383a..4f03ea539805 100644 --- a/drivers/pci/controller/pcie-iproc.h +++ b/drivers/pci/controller/pcie-iproc.h | |||
@@ -58,8 +58,13 @@ struct iproc_msi; | |||
58 | * @phy: optional PHY device that controls the Serdes | 58 | * @phy: optional PHY device that controls the Serdes |
59 | * @map_irq: function callback to map interrupts | 59 | * @map_irq: function callback to map interrupts |
60 | * @ep_is_internal: indicates an internal emulated endpoint device is connected | 60 | * @ep_is_internal: indicates an internal emulated endpoint device is connected |
61 | * @iproc_cfg_read: indicates the iProc config read function should be used | ||
62 | * @rej_unconfig_pf: indicates the root complex needs to detect and reject | ||
63 | * enumeration against unconfigured physical functions emulated in the ASIC | ||
61 | * @has_apb_err_disable: indicates the controller can be configured to prevent | 64 | * @has_apb_err_disable: indicates the controller can be configured to prevent |
62 | * unsupported request from being forwarded as an APB bus error | 65 | * unsupported request from being forwarded as an APB bus error |
66 | * @fix_paxc_cap: indicates the controller has corrupted capability list in its | ||
67 | * config space registers and requires SW based fixup | ||
63 | * | 68 | * |
64 | * @need_ob_cfg: indicates SW needs to configure the outbound mapping window | 69 | * @need_ob_cfg: indicates SW needs to configure the outbound mapping window |
65 | * @ob: outbound mapping related parameters | 70 | * @ob: outbound mapping related parameters |
@@ -84,7 +89,10 @@ struct iproc_pcie { | |||
84 | struct phy *phy; | 89 | struct phy *phy; |
85 | int (*map_irq)(const struct pci_dev *, u8, u8); | 90 | int (*map_irq)(const struct pci_dev *, u8, u8); |
86 | bool ep_is_internal; | 91 | bool ep_is_internal; |
92 | bool iproc_cfg_read; | ||
93 | bool rej_unconfig_pf; | ||
87 | bool has_apb_err_disable; | 94 | bool has_apb_err_disable; |
95 | bool fix_paxc_cap; | ||
88 | 96 | ||
89 | bool need_ob_cfg; | 97 | bool need_ob_cfg; |
90 | struct iproc_pcie_ob ob; | 98 | struct iproc_pcie_ob ob; |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b2e6c02385e5..46f58a9771d7 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2356,6 +2356,9 @@ static void quirk_paxc_bridge(struct pci_dev *pdev) | |||
2356 | } | 2356 | } |
2357 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); | 2357 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16cd, quirk_paxc_bridge); |
2358 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); | 2358 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0x16f0, quirk_paxc_bridge); |
2359 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd750, quirk_paxc_bridge); | ||
2360 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd802, quirk_paxc_bridge); | ||
2361 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_BROADCOM, 0xd804, quirk_paxc_bridge); | ||
2359 | #endif | 2362 | #endif |
2360 | 2363 | ||
2361 | /* | 2364 | /* |