.. | .. |
---|
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; |
---|