layerscape: add 64b/32b target for ls1043ardb device
[openwrt/openwrt.git] / target / linux / layerscape / patches-4.4 / 0056-PCI-designware-Add-generic-dw_pcie_wait_for_link.patch
1 From f0c3f31a8bd81b8e7354a187c49200f3ce52740d Mon Sep 17 00:00:00 2001
2 From: Joao Pinto <Joao.Pinto@synopsys.com>
3 Date: Thu, 10 Mar 2016 14:44:35 -0600
4 Subject: [PATCH 56/70] PCI: designware: Add generic dw_pcie_wait_for_link()
5
6 commit 886bc5ceb5cc3ad4b219502d72b277e3c3255a32 upstream
7 [context adjustment]
8 [remove drivers/pci/host/pcie-qcom.c related changes]
9
10 Several DesignWare-based drivers (dra7xx, exynos, imx6, keystone, qcom, and
11 spear13xx) had similar loops waiting for the link to come up.
12
13 Add a generic dw_pcie_wait_for_link() for use by all these drivers so the
14 waiting is done consistently, e.g., always using usleep_range() rather than
15 mdelay() and using similar timeouts and retry counts.
16
17 Note that this changes the Keystone link training/wait for link strategy,
18 so we initiate link training, then wait longer for the link to come up
19 before re-initiating link training.
20
21 [bhelgaas: changelog, split into its own patch, update pci-keystone.c, pcie-qcom.c]
22 Signed-off-by: Joao Pinto <jpinto@synopsys.com>
23 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
24 Acked-by: Pratyush Anand <pratyush.anand@gmail.com>
25 Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
26 ---
27 drivers/pci/host/pci-dra7xx.c | 11 +----------
28 drivers/pci/host/pci-exynos.c | 13 +++----------
29 drivers/pci/host/pci-imx6.c | 13 ++++---------
30 drivers/pci/host/pci-keystone.c | 10 ++++------
31 drivers/pci/host/pcie-designware.c | 19 +++++++++++++++++++
32 drivers/pci/host/pcie-designware.h | 6 ++++++
33 drivers/pci/host/pcie-spear13xx.c | 14 +-------------
34 7 files changed, 38 insertions(+), 48 deletions(-)
35
36 --- a/drivers/pci/host/pci-dra7xx.c
37 +++ b/drivers/pci/host/pci-dra7xx.c
38 @@ -10,7 +10,6 @@
39 * published by the Free Software Foundation.
40 */
41
42 -#include <linux/delay.h>
43 #include <linux/err.h>
44 #include <linux/interrupt.h>
45 #include <linux/irq.h>
46 @@ -108,7 +107,6 @@ static int dra7xx_pcie_establish_link(st
47 {
48 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pp);
49 u32 reg;
50 - unsigned int retries;
51
52 if (dw_pcie_link_up(pp)) {
53 dev_err(pp->dev, "link is already up\n");
54 @@ -119,14 +117,7 @@ static int dra7xx_pcie_establish_link(st
55 reg |= LTSSM_EN;
56 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
57
58 - for (retries = 0; retries < 1000; retries++) {
59 - if (dw_pcie_link_up(pp))
60 - return 0;
61 - usleep_range(10, 20);
62 - }
63 -
64 - dev_err(pp->dev, "link is not up\n");
65 - return -EINVAL;
66 + return dw_pcie_wait_for_link(pp);
67 }
68
69 static void dra7xx_pcie_enable_interrupts(struct pcie_port *pp)
70 --- a/drivers/pci/host/pci-exynos.c
71 +++ b/drivers/pci/host/pci-exynos.c
72 @@ -318,7 +318,6 @@ static int exynos_pcie_establish_link(st
73 {
74 struct exynos_pcie *exynos_pcie = to_exynos_pcie(pp);
75 u32 val;
76 - unsigned int retries;
77
78 if (dw_pcie_link_up(pp)) {
79 dev_err(pp->dev, "Link already up\n");
80 @@ -357,13 +356,8 @@ static int exynos_pcie_establish_link(st
81 PCIE_APP_LTSSM_ENABLE);
82
83 /* check if the link is up or not */
84 - for (retries = 0; retries < 10; retries++) {
85 - if (dw_pcie_link_up(pp)) {
86 - dev_info(pp->dev, "Link up\n");
87 - return 0;
88 - }
89 - mdelay(100);
90 - }
91 + if (!dw_pcie_wait_for_link(pp))
92 + return 0;
93
94 while (exynos_phy_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED) == 0) {
95 val = exynos_blk_readl(exynos_pcie, PCIE_PHY_PLL_LOCKED);
96 @@ -372,8 +366,7 @@ static int exynos_pcie_establish_link(st
97 /* power off phy */
98 exynos_pcie_power_off_phy(pp);
99
100 - dev_err(pp->dev, "PCIe Link Fail\n");
101 - return -EINVAL;
102 + return -ETIMEDOUT;
103 }
104
105 static void exynos_pcie_clear_irq_pulse(struct pcie_port *pp)
106 --- a/drivers/pci/host/pci-imx6.c
107 +++ b/drivers/pci/host/pci-imx6.c
108 @@ -330,19 +330,14 @@ static void imx6_pcie_init_phy(struct pc
109
110 static int imx6_pcie_wait_for_link(struct pcie_port *pp)
111 {
112 - unsigned int retries;
113 + /* check if the link is up or not */
114 + if (!dw_pcie_wait_for_link(pp))
115 + return 0;
116
117 - for (retries = 0; retries < 200; retries++) {
118 - if (dw_pcie_link_up(pp))
119 - return 0;
120 - usleep_range(100, 1000);
121 - }
122 -
123 - dev_err(pp->dev, "phy link never came up\n");
124 dev_dbg(pp->dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
125 readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
126 readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
127 - return -EINVAL;
128 + return -ETIMEDOUT;
129 }
130
131 static int imx6_pcie_wait_for_speed_change(struct pcie_port *pp)
132 --- a/drivers/pci/host/pci-keystone.c
133 +++ b/drivers/pci/host/pci-keystone.c
134 @@ -97,17 +97,15 @@ static int ks_pcie_establish_link(struct
135 return 0;
136 }
137
138 - ks_dw_pcie_initiate_link_train(ks_pcie);
139 /* check if the link is up or not */
140 - for (retries = 0; retries < 200; retries++) {
141 - if (dw_pcie_link_up(pp))
142 - return 0;
143 - usleep_range(100, 1000);
144 + for (retries = 0; retries < 5; retries++) {
145 ks_dw_pcie_initiate_link_train(ks_pcie);
146 + if (!dw_pcie_wait_for_link(pp))
147 + return 0;
148 }
149
150 dev_err(pp->dev, "phy link never came up\n");
151 - return -EINVAL;
152 + return -ETIMEDOUT;
153 }
154
155 static void ks_pcie_msi_irq_handler(struct irq_desc *desc)
156 --- a/drivers/pci/host/pcie-designware.c
157 +++ b/drivers/pci/host/pcie-designware.c
158 @@ -22,6 +22,7 @@
159 #include <linux/pci_regs.h>
160 #include <linux/platform_device.h>
161 #include <linux/types.h>
162 +#include <linux/delay.h>
163
164 #include "pcie-designware.h"
165
166 @@ -380,6 +381,24 @@ static struct msi_controller dw_pcie_msi
167 .teardown_irq = dw_msi_teardown_irq,
168 };
169
170 +int dw_pcie_wait_for_link(struct pcie_port *pp)
171 +{
172 + int retries;
173 +
174 + /* check if the link is up or not */
175 + for (retries = 0; retries < LINK_WAIT_MAX_RETRIES; retries++) {
176 + if (dw_pcie_link_up(pp)) {
177 + dev_info(pp->dev, "link up\n");
178 + return 0;
179 + }
180 + usleep_range(LINK_WAIT_USLEEP_MIN, LINK_WAIT_USLEEP_MAX);
181 + }
182 +
183 + dev_err(pp->dev, "phy link never came up\n");
184 +
185 + return -ETIMEDOUT;
186 +}
187 +
188 int dw_pcie_link_up(struct pcie_port *pp)
189 {
190 if (pp->ops->link_up)
191 --- a/drivers/pci/host/pcie-designware.h
192 +++ b/drivers/pci/host/pcie-designware.h
193 @@ -22,6 +22,11 @@
194 #define MAX_MSI_IRQS 32
195 #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32)
196
197 +/* Parameters for the waiting for link up routine */
198 +#define LINK_WAIT_MAX_RETRIES 10
199 +#define LINK_WAIT_USLEEP_MIN 90000
200 +#define LINK_WAIT_USLEEP_MAX 100000
201 +
202 struct pcie_port {
203 struct device *dev;
204 u8 root_bus_nr;
205 @@ -76,6 +81,7 @@ int dw_pcie_cfg_read(void __iomem *addr,
206 int dw_pcie_cfg_write(void __iomem *addr, int size, u32 val);
207 irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
208 void dw_pcie_msi_init(struct pcie_port *pp);
209 +int dw_pcie_wait_for_link(struct pcie_port *pp);
210 int dw_pcie_link_up(struct pcie_port *pp);
211 void dw_pcie_setup_rc(struct pcie_port *pp);
212 int dw_pcie_host_init(struct pcie_port *pp);
213 --- a/drivers/pci/host/pcie-spear13xx.c
214 +++ b/drivers/pci/host/pcie-spear13xx.c
215 @@ -13,7 +13,6 @@
216 */
217
218 #include <linux/clk.h>
219 -#include <linux/delay.h>
220 #include <linux/interrupt.h>
221 #include <linux/kernel.h>
222 #include <linux/module.h>
223 @@ -149,7 +148,6 @@ static int spear13xx_pcie_establish_link
224 struct spear13xx_pcie *spear13xx_pcie = to_spear13xx_pcie(pp);
225 struct pcie_app_reg *app_reg = spear13xx_pcie->app_base;
226 u32 exp_cap_off = EXP_CAP_ID_OFFSET;
227 - unsigned int retries;
228
229 if (dw_pcie_link_up(pp)) {
230 dev_err(pp->dev, "link already up\n");
231 @@ -200,17 +198,7 @@ static int spear13xx_pcie_establish_link
232 | ((u32)1 << REG_TRANSLATION_ENABLE),
233 &app_reg->app_ctrl_0);
234
235 - /* check if the link is up or not */
236 - for (retries = 0; retries < 10; retries++) {
237 - if (dw_pcie_link_up(pp)) {
238 - dev_info(pp->dev, "link up\n");
239 - return 0;
240 - }
241 - mdelay(100);
242 - }
243 -
244 - dev_err(pp->dev, "link Fail\n");
245 - return -EINVAL;
246 + return dw_pcie_wait_for_link(pp);
247 }
248
249 static irqreturn_t spear13xx_pcie_irq_handler(int irq, void *arg)