Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: cadence: Retrain Link to work around Gen2 training defect

Cadence controller will not initiate autonomous speed change if strapped
as Gen2. The Retrain Link bit is set as quirk to enable this speed change.

Link: https://lore.kernel.org/r/20210209144622.26683-3-nadeem@cadence.com
Signed-off-by: Nadeem Athani <nadeem@cadence.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>

authored by

Nadeem Athani and committed by
Lorenzo Pieralisi
4740b969 7c53f6b6

+76 -19
+3
drivers/pci/controller/cadence/pci-j721e.c
··· 64 64 65 65 struct j721e_pcie_data { 66 66 enum j721e_pcie_mode mode; 67 + bool quirk_retrain_flag; 67 68 }; 68 69 69 70 static inline u32 j721e_pcie_user_readl(struct j721e_pcie *pcie, u32 offset) ··· 281 280 282 281 static const struct j721e_pcie_data j721e_pcie_rc_data = { 283 282 .mode = PCI_MODE_RC, 283 + .quirk_retrain_flag = true, 284 284 }; 285 285 286 286 static const struct j721e_pcie_data j721e_pcie_ep_data = { ··· 390 388 391 389 bridge->ops = &cdns_ti_pcie_host_ops; 392 390 rc = pci_host_bridge_priv(bridge); 391 + rc->quirk_retrain_flag = data->quirk_retrain_flag; 393 392 394 393 cdns_pcie = &rc->pcie; 395 394 cdns_pcie->dev = dev;
+63 -18
drivers/pci/controller/cadence/pcie-cadence-host.c
··· 77 77 .write = pci_generic_config_write, 78 78 }; 79 79 80 + static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) 81 + { 82 + struct device *dev = pcie->dev; 83 + int retries; 84 + 85 + /* Check if the link is up or not */ 86 + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { 87 + if (cdns_pcie_link_up(pcie)) { 88 + dev_info(dev, "Link up\n"); 89 + return 0; 90 + } 91 + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); 92 + } 93 + 94 + return -ETIMEDOUT; 95 + } 96 + 97 + static int cdns_pcie_retrain(struct cdns_pcie *pcie) 98 + { 99 + u32 lnk_cap_sls, pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET; 100 + u16 lnk_stat, lnk_ctl; 101 + int ret = 0; 102 + 103 + /* 104 + * Set retrain bit if current speed is 2.5 GB/s, 105 + * but the PCIe root port support is > 2.5 GB/s. 106 + */ 107 + 108 + lnk_cap_sls = cdns_pcie_readl(pcie, (CDNS_PCIE_RP_BASE + pcie_cap_off + 109 + PCI_EXP_LNKCAP)); 110 + if ((lnk_cap_sls & PCI_EXP_LNKCAP_SLS) <= PCI_EXP_LNKCAP_SLS_2_5GB) 111 + return ret; 112 + 113 + lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA); 114 + if ((lnk_stat & PCI_EXP_LNKSTA_CLS) == PCI_EXP_LNKSTA_CLS_2_5GB) { 115 + lnk_ctl = cdns_pcie_rp_readw(pcie, 116 + pcie_cap_off + PCI_EXP_LNKCTL); 117 + lnk_ctl |= PCI_EXP_LNKCTL_RL; 118 + cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, 119 + lnk_ctl); 120 + 121 + ret = cdns_pcie_host_wait_for_link(pcie); 122 + } 123 + return ret; 124 + } 125 + 126 + static int cdns_pcie_host_start_link(struct cdns_pcie_rc *rc) 127 + { 128 + struct cdns_pcie *pcie = &rc->pcie; 129 + int ret; 130 + 131 + ret = cdns_pcie_host_wait_for_link(pcie); 132 + 133 + /* 134 + * Retrain link for Gen2 training defect 135 + * if quirk flag is set. 136 + */ 137 + if (!ret && rc->quirk_retrain_flag) 138 + ret = cdns_pcie_retrain(pcie); 139 + 140 + return ret; 141 + } 80 142 81 143 static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc *rc) 82 144 { ··· 460 398 return cdns_pcie_host_init_address_translation(rc); 461 399 } 462 400 463 - static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) 464 - { 465 - struct device *dev = pcie->dev; 466 - int retries; 467 - 468 - /* Check if the link is up or not */ 469 - for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { 470 - if (cdns_pcie_link_up(pcie)) { 471 - dev_info(dev, "Link up\n"); 472 - return 0; 473 - } 474 - usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); 475 - } 476 - 477 - return -ETIMEDOUT; 478 - } 479 - 480 401 int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) 481 402 { 482 403 struct device *dev = rc->pcie.dev; ··· 502 457 return ret; 503 458 } 504 459 505 - ret = cdns_pcie_host_wait_for_link(pcie); 460 + ret = cdns_pcie_host_start_link(rc); 506 461 if (ret) 507 462 dev_dbg(dev, "PCIe link never came up\n"); 508 463
+10 -1
drivers/pci/controller/cadence/pcie-cadence.h
··· 119 119 * Root Port Registers (PCI configuration space for the root port function) 120 120 */ 121 121 #define CDNS_PCIE_RP_BASE 0x00200000 122 - 122 + #define CDNS_PCIE_RP_CAP_OFFSET 0xc0 123 123 124 124 /* 125 125 * Address Translation Registers ··· 291 291 * @device_id: PCI device ID 292 292 * @avail_ib_bar: Satus of RP_BAR0, RP_BAR1 and RP_NO_BAR if it's free or 293 293 * available 294 + * @quirk_retrain_flag: Retrain link as quirk for PCIe Gen2 294 295 */ 295 296 struct cdns_pcie_rc { 296 297 struct cdns_pcie pcie; ··· 300 299 u32 vendor_id; 301 300 u32 device_id; 302 301 bool avail_ib_bar[CDNS_PCIE_RP_MAX_IB]; 302 + bool quirk_retrain_flag; 303 303 }; 304 304 305 305 /** ··· 414 412 void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg; 415 413 416 414 cdns_pcie_write_sz(addr, 0x2, value); 415 + } 416 + 417 + static inline u16 cdns_pcie_rp_readw(struct cdns_pcie *pcie, u32 reg) 418 + { 419 + void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg; 420 + 421 + return cdns_pcie_read_sz(addr, 0x2); 417 422 } 418 423 419 424 /* Endpoint Function register access */