@@ -181,10 +181,59 @@ static int fu740_pcie_start_link(struct dw_pcie *pci)
181181{
182182 struct device * dev = pci -> dev ;
183183 struct fu740_pcie * afp = dev_get_drvdata (dev );
184+ u8 cap_exp = dw_pcie_find_capability (pci , PCI_CAP_ID_EXP );
185+ int ret ;
186+ u32 orig , tmp ;
187+
188+ /*
189+ * Force 2.5GT/s when starting the link, due to some devices not
190+ * probing at higher speeds. This happens with the PCIe switch
191+ * on the Unmatched board when U-Boot has not initialised the PCIe.
192+ * The fix in U-Boot is to force 2.5GT/s, which then gets cleared
193+ * by the soft reset done by this driver.
194+ */
195+ dev_dbg (dev , "cap_exp at %x\n" , cap_exp );
196+ dw_pcie_dbi_ro_wr_en (pci );
197+
198+ tmp = dw_pcie_readl_dbi (pci , cap_exp + PCI_EXP_LNKCAP );
199+ orig = tmp & PCI_EXP_LNKCAP_SLS ;
200+ tmp &= ~PCI_EXP_LNKCAP_SLS ;
201+ tmp |= PCI_EXP_LNKCAP_SLS_2_5GB ;
202+ dw_pcie_writel_dbi (pci , cap_exp + PCI_EXP_LNKCAP , tmp );
184203
185204 /* Enable LTSSM */
186205 writel_relaxed (0x1 , afp -> mgmt_base + PCIEX8MGMT_APP_LTSSM_ENABLE );
187- return 0 ;
206+
207+ ret = dw_pcie_wait_for_link (pci );
208+ if (ret ) {
209+ dev_err (dev , "error: link did not start\n" );
210+ goto err ;
211+ }
212+
213+ tmp = dw_pcie_readl_dbi (pci , cap_exp + PCI_EXP_LNKCAP );
214+ if ((tmp & PCI_EXP_LNKCAP_SLS ) != orig ) {
215+ dev_dbg (dev , "changing speed back to original\n" );
216+
217+ tmp &= ~PCI_EXP_LNKCAP_SLS ;
218+ tmp |= orig ;
219+ dw_pcie_writel_dbi (pci , cap_exp + PCI_EXP_LNKCAP , tmp );
220+
221+ tmp = dw_pcie_readl_dbi (pci , PCIE_LINK_WIDTH_SPEED_CONTROL );
222+ tmp |= PORT_LOGIC_SPEED_CHANGE ;
223+ dw_pcie_writel_dbi (pci , PCIE_LINK_WIDTH_SPEED_CONTROL , tmp );
224+
225+ ret = dw_pcie_wait_for_link (pci );
226+ if (ret ) {
227+ dev_err (dev , "error: link did not start at new speed\n" );
228+ goto err ;
229+ }
230+ }
231+
232+ ret = 0 ;
233+ err :
234+ WARN_ON (ret ); /* we assume that errors will be very rare */
235+ dw_pcie_dbi_ro_wr_dis (pci );
236+ return ret ;
188237}
189238
190239static int fu740_pcie_host_init (struct pcie_port * pp )
@@ -259,11 +308,11 @@ static int fu740_pcie_probe(struct platform_device *pdev)
259308 return PTR_ERR (afp -> mgmt_base );
260309
261310 /* Fetch GPIOs */
262- afp -> reset = devm_gpiod_get_optional (dev , "reset-gpios " , GPIOD_OUT_LOW );
311+ afp -> reset = devm_gpiod_get_optional (dev , "reset" , GPIOD_OUT_LOW );
263312 if (IS_ERR (afp -> reset ))
264313 return dev_err_probe (dev , PTR_ERR (afp -> reset ), "unable to get reset-gpios\n" );
265314
266- afp -> pwren = devm_gpiod_get_optional (dev , "pwren-gpios " , GPIOD_OUT_LOW );
315+ afp -> pwren = devm_gpiod_get_optional (dev , "pwren" , GPIOD_OUT_LOW );
267316 if (IS_ERR (afp -> pwren ))
268317 return dev_err_probe (dev , PTR_ERR (afp -> pwren ), "unable to get pwren-gpios\n" );
269318
0 commit comments