Skip to content

Commit

Permalink
Merge branch 'pci/controller/cadence'
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
Bjorn Helgaas committed Jun 26, 2023
2 parents 4137055 + 0e12f83 commit 375328f
Showing 1 changed file with 27 additions and 0 deletions.
27 changes: 27 additions & 0 deletions drivers/pci/controller/cadence/pcie-cadence-host.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 375328f

Please sign in to comment.