| .. | .. |
|---|
| 12 | 12 | |
|---|
| 13 | 13 | #include "pcie-cadence.h" |
|---|
| 14 | 14 | |
|---|
| 15 | +#define LINK_RETRAIN_TIMEOUT HZ |
|---|
| 16 | + |
|---|
| 15 | 17 | static u64 bar_max_size[] = { |
|---|
| 16 | 18 | [RP_BAR0] = _ULL(128 * SZ_2G), |
|---|
| 17 | 19 | [RP_BAR1] = SZ_2G, |
|---|
| .. | .. |
|---|
| 77 | 79 | .write = pci_generic_config_write, |
|---|
| 78 | 80 | }; |
|---|
| 79 | 81 | |
|---|
| 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 | + |
|---|
| 80 | 103 | static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) |
|---|
| 81 | 104 | { |
|---|
| 82 | 105 | struct device *dev = pcie->dev; |
|---|
| .. | .. |
|---|
| 118 | 141 | cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL, |
|---|
| 119 | 142 | lnk_ctl); |
|---|
| 120 | 143 | |
|---|
| 144 | + ret = cdns_pcie_host_training_complete(pcie); |
|---|
| 145 | + if (ret) |
|---|
| 146 | + return ret; |
|---|
| 147 | + |
|---|
| 121 | 148 | ret = cdns_pcie_host_wait_for_link(pcie); |
|---|
| 122 | 149 | } |
|---|
| 123 | 150 | return ret; |
|---|