Skip to content

Commit 375328f

Browse files
committed
Merge branch 'pci/controller/cadence'
- Wait for link retrain to complete when working around the J721E i2085 erratum with Gen2 mode (Siddharth Vadapalli) * pci/controller/cadence: PCI: cadence: Fix Gen2 Link Retraining process
2 parents 4137055 + 0e12f83 commit 375328f

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

drivers/pci/controller/cadence/pcie-cadence-host.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
#include "pcie-cadence.h"
1414

15+
#define LINK_RETRAIN_TIMEOUT HZ
16+
1517
static u64 bar_max_size[] = {
1618
[RP_BAR0] = _ULL(128 * SZ_2G),
1719
[RP_BAR1] = SZ_2G,
@@ -77,6 +79,27 @@ static struct pci_ops cdns_pcie_host_ops = {
7779
.write = pci_generic_config_write,
7880
};
7981

82+
static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
83+
{
84+
u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
85+
unsigned long end_jiffies;
86+
u16 lnk_stat;
87+
88+
/* Wait for link training to complete. Exit after timeout. */
89+
end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
90+
do {
91+
lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
92+
if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
93+
break;
94+
usleep_range(0, 1000);
95+
} while (time_before(jiffies, end_jiffies));
96+
97+
if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
98+
return 0;
99+
100+
return -ETIMEDOUT;
101+
}
102+
80103
static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
81104
{
82105
struct device *dev = pcie->dev;
@@ -118,6 +141,10 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
118141
cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
119142
lnk_ctl);
120143

144+
ret = cdns_pcie_host_training_complete(pcie);
145+
if (ret)
146+
return ret;
147+
121148
ret = cdns_pcie_host_wait_for_link(pcie);
122149
}
123150
return ret;

0 commit comments

Comments
 (0)