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
This commit is contained in:
Bjorn Helgaas 2023-06-26 12:59:58 -05:00
commit 375328faa2
1 changed files with 27 additions and 0 deletions

View File

@ -12,6 +12,8 @@
#include "pcie-cadence.h"
#define LINK_RETRAIN_TIMEOUT HZ
static u64 bar_max_size[] = {
[RP_BAR0] = _ULL(128 * SZ_2G),
[RP_BAR1] = SZ_2G,
@ -77,6 +79,27 @@ static struct pci_ops cdns_pcie_host_ops = {
.write = pci_generic_config_write,
};
static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
{
u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
unsigned long end_jiffies;
u16 lnk_stat;
/* Wait for link training to complete. Exit after timeout. */
end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
do {
lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
break;
usleep_range(0, 1000);
} while (time_before(jiffies, end_jiffies));
if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
return 0;
return -ETIMEDOUT;
}
static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
{
struct device *dev = pcie->dev;
@ -118,6 +141,10 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
lnk_ctl);
ret = cdns_pcie_host_training_complete(pcie);
if (ret)
return ret;
ret = cdns_pcie_host_wait_for_link(pcie);
}
return ret;