summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorManikanta Maddireddy <mmaddireddy@nvidia.com>2019-06-18 20:01:55 +0200
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2019-06-20 18:22:27 +0200
commitc23ae2aec5bc40cfc8e9ad0058aff2edacb0fbcb (patch)
tree9986ad0214f11c050b4d03b547114c62298d18b8 /drivers/pci
parentPCI: tegra: Update flow control timer frequency in Tegra210 (diff)
downloadlinux-c23ae2aec5bc40cfc8e9ad0058aff2edacb0fbcb.tar.xz
linux-c23ae2aec5bc40cfc8e9ad0058aff2edacb0fbcb.zip
PCI: tegra: Set target speed as Gen1 before starting LTSSM
PCIe link up fails with few legacy endpoints if root port advertises both Gen-1 and Gen-2 speeds in Tegra. This is because link number negotiation fails if both Gen1 & Gen2 are advertised. Tegra doesn't retry link up by advertising only Gen1. Hence, the strategy followed here is to initially advertise only Gen-1 and after link is up, retrain link to Gen-2 speed. Tegra doesn't support HW autonomous speed change. Link comes up in Gen1 even if Gen2 is advertised, so there is no downside of this change. This behavior is observed with following two PCIe devices on Tegra: - Fusion HDTV 5 Express card - IOGear SIL - PCIE - SATA card Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/pci-tegra.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index cf2398a10d8c..ffe3ad5d0509 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -676,6 +676,17 @@ static void tegra_pcie_apply_sw_fixup(struct tegra_pcie_port *port)
value |= soc->update_fc_threshold;
writel(value, port->base + RP_VEND_XP);
}
+
+ /*
+ * PCIe link doesn't come up with few legacy PCIe endpoints if
+ * root port advertises both Gen-1 and Gen-2 speeds in Tegra.
+ * Hence, the strategy followed here is to initially advertise
+ * only Gen-1 and after link is up, retrain link to Gen-2 speed
+ */
+ value = readl(port->base + RP_LINK_CONTROL_STATUS_2);
+ value &= ~PCI_EXP_LNKSTA_CLS;
+ value |= PCI_EXP_LNKSTA_CLS_2_5GB;
+ writel(value, port->base + RP_LINK_CONTROL_STATUS_2);
}
static void tegra_pcie_port_enable(struct tegra_pcie_port *port)