diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2015-12-31 21:58:37 -0800 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-01-08 08:51:47 +0100 |
commit | cb3643d425f3d83748a67a0fec973512a5ea5956 (patch) | |
tree | 8964deda283ea037408aab6d5f770476bf94573f | |
parent | cd5f6a99ded8e1b6b9109a2fb953b30faabfd60f (diff) | |
download | barebox-cb3643d425f3d83748a67a0fec973512a5ea5956.tar.gz barebox-cb3643d425f3d83748a67a0fec973512a5ea5956.tar.xz |
i.MX6: pci: Reconcile imx6_pcie_start_link with the kernel code
Reconcile imx6_pcie_start_link with almost identical
imx6_pcie_establish_link from analogous Linux kernel driver. This
change is purely cosmetical, but refactoring the code this way
simplifies implementation comparison.
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | drivers/pci/pci-imx6.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/drivers/pci/pci-imx6.c b/drivers/pci/pci-imx6.c index 84a937ffbb..713007b27a 100644 --- a/drivers/pci/pci-imx6.c +++ b/drivers/pci/pci-imx6.c @@ -362,13 +362,29 @@ static int imx6_pcie_wait_for_link(struct pcie_port *pp) } } +static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp) +{ + uint32_t tmp; + uint64_t start = get_time_ns(); + + while (!is_timeout(start, SECOND)) { + tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); + /* Test if the speed change finished. */ + if (!(tmp & PORT_LOGIC_SPEED_CHANGE)) + return 0; + } + + dev_err(pp->dev, "Speed change timeout\n"); + return -EINVAL; +} + + static int imx6_pcie_start_link(struct pcie_port *pp) { struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp); uint32_t tmp; int ret; u32 gpr12; - u64 start; /* * Force Gen1 operation when starting the link. In case the link is @@ -403,28 +419,22 @@ static int imx6_pcie_start_link(struct pcie_port *pp) tmp |= PORT_LOGIC_SPEED_CHANGE; writel(tmp, pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - start = get_time_ns(); - while (!is_timeout(start, SECOND)) { - tmp = readl(pp->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL); - /* Test if the speed change finished. */ - if (!(tmp & PORT_LOGIC_SPEED_CHANGE)) - break; + ret = imx6_pcie_wait_for_speed_change(pp); + if (ret) { + dev_err(pp->dev, "Failed to bring link up!\n"); + return ret; } /* Make sure link training is finished as well! */ - if (tmp & PORT_LOGIC_SPEED_CHANGE) - ret = -EINVAL; - else - ret = imx6_pcie_wait_for_link(pp); - + ret = imx6_pcie_wait_for_link(pp); if (ret) { dev_err(pp->dev, "Failed to bring link up!\n"); - } else { - tmp = readl(pp->dbi_base + PCIE_RC_LCSR); - dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf); + return ret; } - return ret; + tmp = readl(pp->dbi_base + PCIE_RC_LCSR); + dev_dbg(pp->dev, "Link up, Gen=%i\n", (tmp >> 16) & 0xf); + return 0; } static void imx6_pcie_host_init(struct pcie_port *pp) |