summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorAndrey Smirnov <andrew.smirnov@gmail.com>2019-01-16 18:16:56 -0800
committerSascha Hauer <s.hauer@pengutronix.de>2019-01-18 09:43:10 +0100
commita93654662b2640aaf4433d15051b0d1ef597ec9d (patch)
tree5300c8d5a398e493414750528e347a007163cad4 /drivers/pci
parent2d34376bc1a83fa118478675ca01a5d5bd03326b (diff)
downloadbarebox-a93654662b2640aaf4433d15051b0d1ef597ec9d.tar.gz
barebox-a93654662b2640aaf4433d15051b0d1ef597ec9d.tar.xz
PCI: imx6: Do not wait for speed change on i.MX7
Port of a Linux commit e6dcd87fff69a9d454104b65569074855cf95b1e As can be seen from [1]: "...the different behavior between iMX6Q PCIe and iMX7D PCIe maybe caused by the different controller version. Regarding to the DOC description, the DIRECT_SPEED_CHANGE should be cleared after the speed change from GEN1 to GEN2. Unfortunately, when GEN1 device is used, the behavior is not documented. So, IC design guys run the simulation and find out the following behaviors: 1. DIRECT_SPEED_CHANGE will be cleared in 7D after speed change from GEN1 to GEN2. This matches doc’s description 2. set MAX link speed(PCIE_CAP_TARGET_LINK_SPEED=0x01) as GEN1 and re-run the simulation, DIRECT_SPEED_CHANGE will not be cleared; remain as 1, this matches your result, but function test is passed, so this bit should not affect the normal PCIe function." imx6_pcie_wait_for_speed_change() will report false failures for Gen1 -> Gen1 speed transition, so avoid doing that check and just rely on imx6_pcie_wait_for_link() only. [1] https://community.nxp.com/message/867943 Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Lucas Stach <l.stach@pengutronix.de> Cc: yurovsky@gmail.com Cc: Fabio Estevam <fabio.estevam@nxp.com> Cc: Dong Aisheng <dongas86@gmail.com> Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/pci-imx6.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c
index ce68b007ab..d121a20ce1 100644
--- a/drivers/pci/pci-imx6.c
+++ b/drivers/pci/pci-imx6.c
@@ -508,10 +508,21 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
tmp |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_writel_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL, tmp);
- ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
- if (ret) {
- dev_err(dev, "Failed to bring link up!\n");
- goto err_reset_phy;
+ if (imx6_pcie->variant != IMX7D) {
+ /*
+ * On i.MX7, DIRECT_SPEED_CHANGE behaves differently
+ * from i.MX6 family when no link speed transition
+ * occurs and we go Gen1 -> yep, Gen1. The difference
+ * is that, in such case, it will not be cleared by HW
+ * which will cause the following code to report false
+ * failure.
+ */
+
+ ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
+ if (ret) {
+ dev_err(dev, "Failed to bring link up!\n");
+ goto err_reset_phy;
+ }
}
/* Make sure link training is finished as well! */