diff options
author | Yutang Jiang <yutang.jiang@nxp.com> | 2016-10-29 00:14:32 +0800 |
---|---|---|
committer | John Crispin <john@phrozen.org> | 2016-10-31 17:00:10 +0100 |
commit | c6c731fe311f7da42777ffd31804a4f6aa3f8e19 (patch) | |
tree | d92c7296f82d46d1b2da30933a97595f6cb8ad66 /target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch | |
parent | a34f96d6cf80c7c3c425076714d9c4caa67e3670 (diff) | |
download | upstream-c6c731fe311f7da42777ffd31804a4f6aa3f8e19.tar.gz upstream-c6c731fe311f7da42777ffd31804a4f6aa3f8e19.tar.bz2 upstream-c6c731fe311f7da42777ffd31804a4f6aa3f8e19.zip |
layerscape: add 64b/32b target for ls1043ardb device
Add support for NXP layerscape ls1043ardb 64b/32b Dev board.
LS1043a is an SoC with 4x64-bit up to 1.6 GHz ARMv8 A53 cores.
ls1043ardb support features as: 2GB DDR4, 128MB NOR/512MB NAND, USB3.0, eSDHC,
I2C, GPIO, PCIe/Mini-PCIe, 6x1G/1x10G network port, etc.
64b/32b ls1043ardb target is using 4.4 kernel, and rcw/u-boot/fman images from
NXP QorIQ SDK release.
All of 4.4 kernel patches porting from SDK release or upstream.
QorIQ SDK ISOs can be downloaded from this location:
http://www.nxp.com/products/software-and-tools/run-time-software/linux-sdk/linux-sdk-for-qoriq-processors:SDKLINUX
Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
Diffstat (limited to 'target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch')
-rw-r--r-- | target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch b/target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch new file mode 100644 index 0000000000..b13aba33df --- /dev/null +++ b/target/linux/layerscape/patches-4.4/0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch @@ -0,0 +1,249 @@ +From f0c3f31a8bd81b8e7354a187c49200f3ce52740d Mon Sep 17 00:00:00 2001 +From: Joao Pinto <Joao.Pinto@synopsys.com> +Date: Thu, 10 Mar 2016 14:44:35 -0600 +Subject: [PATCH 56/70] PCI: designware: Add generic dw_pcie_wait_for_link() + +commit 886bc5ceb5cc3ad4b219502d72b277e3c3255a32 upstream +[context adjustment] +[remove drivers/pci/host/pcie-qcom.c related changes] + +Several DesignWare-based drivers (dra7xx, exynos, imx6, keystone, qcom, and +spear13xx) had similar loops waiting for the link to come up. + +Add a generic dw_pcie_wait_for_link() for use by all these drivers so the +waiting is done consistently, e.g., always using usleep_range() rather than +mdelay() and using similar timeouts and retry counts. + +Note that this changes the Keystone link training/wait for link strategy, +so we initiate link training, then wait longer for the link to come up +before re-initiating link training. + +[bhelgaas: changelog, split into its own patch, update pci-keystone.c, pcie-qcom.c] +Signed-off-by: Joao Pinto <jpinto@synopsys.com> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Pratyush Anand <pratyush.anand@gmail.com> +Integrated-by: Jiang Yutang <yutang.jiang@nxp.com> +--- + drivers/pci/host/pci-dra7xx.c | 11 +---------- + drivers/pci/host/pci-exynos.c | 13 +++---------- + drivers/pci/host/pci-imx6.c | 13 ++++--------- + drivers/pci/host/pci-keystone.c | 10 ++++------ + drivers/pci/host/pcie-designware.c | 19 +++++++++++++++++++ + drivers/pci/host/pcie-designware.h | 6 ++++++ + drivers/pci/host/pcie-spear13xx.c | 14 +------------- + 7 files changed, 38 insertions(+), 48 deletions(-) + +--- a/drivers/pci/host/pci-dra7xx.c ++++ b/drivers/pci/host/pci-dra7xx.c +@@ -10,7 +10,6 @@ + * published by the Free Software Foundation. + */ + +-#include <linux/delay.h> + #include <linux/err.h> + #include <linux/interrupt.h> + #include <linux/irq.h> +@@ -108,7 +107,6 @@ static int dra7xx_pcie_establish_link(st + { + struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp); + u32 reg; +- unsigned int retries; + + if (dw_pcie_link_up(pp)) { + dev_err(pp->dev, "link is already up\n"); +@@ -119,14 +117,7 @@ static int dra7xx_pcie_establish_link(st + reg |= LTSSM_EN; + dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); + +- for (retries = 0; retries < 1000; retries++) { +- if (dw_pcie_link_up(pp)) +- return 0; +- usleep_range(10, 20); +- } +- +- dev_err(pp->dev, "link is not up\n"); +- return -EINVAL; ++ return dw_pcie_wait_for_link(pp); + } + + static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp) +--- a/drivers/pci/host/pci-exynos.c ++++ b/drivers/pci/host/pci-exynos.c +@@ -318,7 +318,6 @@ static int exynos_pcie_establish_link(st + { + struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp); + u32 val; +- unsigned int retries; + + if (dw_pcie_link_up(pp)) { + dev_err(pp->dev, "Link already up\n"); +@@ -357,13 +356,8 @@ static int exynos_pcie_establish_link(st + PCIE_APP_LTSSM_ENABLE); + + /* check if the link is up or not */ +- for (retries = 0; retries < 10; retries++) { +- if (dw_pcie_link_up(pp)) { +- dev_info(pp->dev, "Link up\n"); +- return 0; +- } +- mdelay(100); +- } ++ if (!dw_pcie_wait_for_link(pp)) ++ return 0; + + while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) { + val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED); +@@ -372,8 +366,7 @@ static int exynos_pcie_establish_link(st + /* power off phy */ + exynos_pcie_power_off_phy(pp); + +- dev_err(pp->dev, "PCIe Link Fail\n"); +- return -EINVAL; ++ return -ETIMEDOUT; + } + + static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp) +--- a/drivers/pci/host/pci-imx6.c ++++ b/drivers/pci/host/pci-imx6.c +@@ -330,19 +330,14 @@ static void imx6_pcie_init_phy(struct pc + + static int imx6_pcie_wait_for_link(struct pcie_port *pp) + { +- unsigned int retries; ++ /* check if the link is up or not */ ++ if (!dw_pcie_wait_for_link(pp)) ++ return 0; + +- for (retries = 0; retries < 200; retries++) { +- if (dw_pcie_link_up(pp)) +- return 0; +- usleep_range(100, 1000); +- } +- +- dev_err(pp->dev, "phy link never came up\n"); + dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n", + readl(pp->dbi_base + PCIE_PHY_DEBUG_R0), + readl(pp->dbi_base + PCIE_PHY_DEBUG_R1)); +- return -EINVAL; ++ return -ETIMEDOUT; + } + + static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp) +--- a/drivers/pci/host/pci-keystone.c ++++ b/drivers/pci/host/pci-keystone.c +@@ -97,17 +97,15 @@ static int ks_pcie_establish_link(struct + return 0; + } + +- ks_dw_pcie_initiate_link_train(ks_pcie); + /* check if the link is up or not */ +- for (retries = 0; retries < 200; retries++) { +- if (dw_pcie_link_up(pp)) +- return 0; +- usleep_range(100, 1000); ++ for (retries = 0; retries < 5; retries++) { + ks_dw_pcie_initiate_link_train(ks_pcie); ++ if (!dw_pcie_wait_for_link(pp)) ++ return 0; + } + + dev_err(pp->dev, "phy link never came up\n"); +- return -EINVAL; ++ return -ETIMEDOUT; + } + + static void ks_pcie_msi_irq_handler(struct irq_desc *desc) +--- a/drivers/pci/host/pcie-designware.c ++++ b/drivers/pci/host/pcie-designware.c +@@ -22,6 +22,7 @@ + #include <linux/pci_regs.h> + #include <linux/platform_device.h> + #include <linux/types.h> ++#include <linux/delay.h> + + #include "pcie-designware.h" + +@@ -380,6 +381,24 @@ static struct msi_controller dw_pcie_msi + .teardown_irq = dw_msi_teardown_irq, + }; + ++int dw_pcie_wait_for_link(struct pcie_port *pp) ++{ ++ int retries; ++ ++ /* check if the link is up or not */ ++ for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) { ++ if (dw_pcie_link_up(pp)) { ++ dev_info(pp->dev, "link up\n"); ++ return 0; ++ } ++ usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX); ++ } ++ ++ dev_err(pp->dev, "phy link never came up\n"); ++ ++ return -ETIMEDOUT; ++} ++ + int dw_pcie_link_up(struct pcie_port *pp) + { + if (pp->ops->link_up) +--- a/drivers/pci/host/pcie-designware.h ++++ b/drivers/pci/host/pcie-designware.h +@@ -22,6 +22,11 @@ + #define MAX_MSI_IRQS 32 + #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) + ++/* Parameters for the waiting for link up routine */ ++#define LINK_WAIT_MAX_RETRIES 10 ++#define LINK_WAIT_USLEEP_MIN 90000 ++#define LINK_WAIT_USLEEP_MAX 100000 ++ + struct pcie_port { + struct device *dev; + u8 root_bus_nr; +@@ -76,6 +81,7 @@ int dw_pcie_cfg_read(void __iomem *addr, + int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val); + irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); + void dw_pcie_msi_init(struct pcie_port *pp); ++int dw_pcie_wait_for_link(struct pcie_port *pp); + int dw_pcie_link_up(struct pcie_port *pp); + void dw_pcie_setup_rc(struct pcie_port *pp); + int dw_pcie_host_init(struct pcie_port *pp); +--- a/drivers/pci/host/pcie-spear13xx.c ++++ b/drivers/pci/host/pcie-spear13xx.c +@@ -13,7 +13,6 @@ + */ + + #include <linux/clk.h> +-#include <linux/delay.h> + #include <linux/interrupt.h> + #include <linux/kernel.h> + #include <linux/module.h> +@@ -149,7 +148,6 @@ static int spear13xx_pcie_establish_link + struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp); + struct pcie_app_reg *app_reg = spear13xx_pcie->app_base; + u32 exp_cap_off = EXP_CAP_ID_OFFSET; +- unsigned int retries; + + if (dw_pcie_link_up(pp)) { + dev_err(pp->dev, "link already up\n"); +@@ -200,17 +198,7 @@ static int spear13xx_pcie_establish_link + | ((u32)1 << REG_TRANSLATION_ENABLE), + &app_reg->app_ctrl_0); + +- /* check if the link is up or not */ +- for (retries = 0; retries < 10; retries++) { +- if (dw_pcie_link_up(pp)) { +- dev_info(pp->dev, "link up\n"); +- return 0; +- } +- mdelay(100); +- } +- +- dev_err(pp->dev, "link Fail\n"); +- return -EINVAL; ++ return dw_pcie_wait_for_link(pp); + } + + static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg) |