summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/cadence/pcie-cadence-host.c
diff options
context:
space:
mode:
authorKishon Vijay Abraham I <kishon@ti.com>2020-07-22 16:33:07 +0530
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2020-07-27 15:46:16 +0100
commit40d957e6f9eb3a8a585007b8b730340c829afbdb (patch)
tree0c300dee226fbf471a99baff2db53f81c1731da2 /drivers/pci/controller/cadence/pcie-cadence-host.c
parenta8b661eb50abaac97401625d3ff28761bcf1822d (diff)
PCI: cadence: Add support to start link and verify link status
Add cdns_pcie_ops to start link and verify link status. The registers to start link and to check link status is in Platform specific PCIe wrapper. Add support for platform specific drivers to add callback functions for the PCIe Cadence core to start link and verify link status. Link: https://lore.kernel.org/r/20200722110317.4744-6-kishon@ti.com Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'drivers/pci/controller/cadence/pcie-cadence-host.c')
-rw-r--r--drivers/pci/controller/cadence/pcie-cadence-host.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
index 61161d2de96f..4e650c7a0032 100644
--- a/drivers/pci/controller/cadence/pcie-cadence-host.c
+++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
@@ -3,6 +3,7 @@
// Cadence PCIe host controller driver.
// Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
+#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/list_sort.h>
#include <linux/of_address.h>
@@ -420,6 +421,23 @@ static int cdns_pcie_host_init(struct device *dev,
return err;
}
+static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
+{
+ struct device *dev = pcie->dev;
+ int retries;
+
+ /* Check if the link is up or not */
+ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
+ if (cdns_pcie_link_up(pcie)) {
+ dev_info(dev, "Link up\n");
+ return 0;
+ }
+ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
+ }
+
+ return -ETIMEDOUT;
+}
+
int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
{
struct device *dev = rc->pcie.dev;
@@ -468,6 +486,16 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
pcie->mem_res = res;
+ ret = cdns_pcie_start_link(pcie);
+ if (ret) {
+ dev_err(dev, "Failed to start link\n");
+ return ret;
+ }
+
+ ret = cdns_pcie_host_wait_for_link(pcie);
+ if (ret)
+ dev_dbg(dev, "PCIe link never came up\n");
+
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
rc->avail_ib_bar[bar] = true;