imx6: update PCIe driver
[openwrt/svn-archive/archive.git] / target / linux / imx6 / patches-3.10 / 0012-PCI-imx6-Add-support-for-i.MX6-PCIe-controller.patch
1 Subject: [v6,3/3] PCI: imx6: Add support for i.MX6 PCIe controller
2 From: Sean Cross <xobs@kosagi.com>
3
4 Add support for the PCIe port present on the i.MX6 family of controllers.
5 These use the Synopsis Designware core tied to their own PHY.
6
7 Signed-off-by: Sean Cross <xobs@kosagi.com>
8 Acked-by: Bjorn Helgaas <bhelgaas@google.com>
9 Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
10 ---
11 arch/arm/boot/dts/imx6qdl.dtsi | 16 +
12 arch/arm/mach-imx/Kconfig | 2 +
13 arch/arm/mach-imx/clk-imx6q.c | 4 +
14 drivers/pci/host/Kconfig | 6 +
15 drivers/pci/host/Makefile | 1 +
16 drivers/pci/host/pci-imx6.c | 576 ++++++++++++++++++++
17 7 files changed, 611 insertions(+), 1 deletion(-)
18 create mode 100644 drivers/pci/host/pci-imx6.c
19
20 diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
21 index ccd55c2..125202e 100644
22 --- a/arch/arm/boot/dts/imx6qdl.dtsi
23 +++ b/arch/arm/boot/dts/imx6qdl.dtsi
24 @@ -116,6 +116,22 @@
25 arm,data-latency = <4 2 3>;
26 };
27
28 + pcie: pcie@0x01000000 {
29 + compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
30 + reg = <0x01ffc000 0x4000>; /* DBI */
31 + #address-cells = <3>;
32 + #size-cells = <2>;
33 + device_type = "pci";
34 + ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000 /* configuration space */
35 + 0x81000000 0 0 0x01f80000 0 0x00010000 /* downstream I/O */
36 + 0x82000000 0 0x01000000 0x01000000 0 0x00f00000>; /* non-prefetchable memory */
37 + num-lanes = <1>;
38 + interrupts = <0 123 0x04>;
39 + clocks = <&clks 189>, <&clks 187>, <&clks 205>, <&clks 144>;
40 + clock-names = "pcie_ref_125m", "sata_ref_100m", "lvds_gate", "pcie_axi";
41 + status = "disabled";
42 + };
43 +
44 pmu {
45 compatible = "arm,cortex-a9-pmu";
46 interrupts = <0 94 0x04>;
47 diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
48 index 29a8af6..e6ac281 100644
49 --- a/arch/arm/mach-imx/Kconfig
50 +++ b/arch/arm/mach-imx/Kconfig
51 @@ -801,6 +801,8 @@ config SOC_IMX6Q
52 select HAVE_IMX_SRC
53 select HAVE_SMP
54 select MFD_SYSCON
55 + select MIGHT_HAVE_PCI
56 + select PCI_DOMAINS if PCI
57 select PINCTRL
58 select PINCTRL_IMX6Q
59 select PL310_ERRATA_588369 if CACHE_PL310
60 diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
61 index d94be84..6956995 100644
62 --- a/arch/arm/mach-imx/clk-imx6q.c
63 +++ b/arch/arm/mach-imx/clk-imx6q.c
64 @@ -621,6 +621,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
65 if (ret)
66 pr_warn("failed to set up CLKO: %d\n", ret);
67
68 + /* All existing boards with PCIe use LVDS1 */
69 + if (IS_ENABLED(CONFIG_PCI_IMX6))
70 + clk_set_parent(clk[lvds1_sel], clk[sata_ref]);
71 +
72 /* Set initial power mode */
73 imx6q_set_lpm(WAIT_CLOCKED);
74
75 --- /dev/null
76 +++ b/drivers/pci/host/Kconfig
77 @@ -0,0 +1,13 @@
78 +menu "PCI host controller drivers"
79 + depends on PCI
80 +
81 +config PCIE_DW
82 + bool
83 +
84 +config PCI_IMX6
85 + bool "Freescale i.MX6 PCIe controller"
86 + depends on SOC_IMX6Q
87 + select PCIEPORTBUS
88 + select PCIE_DW
89 +
90 +endmenu
91 --- /dev/null
92 +++ b/drivers/pci/host/Makefile
93 @@ -0,0 +1,2 @@
94 +obj-$(CONFIG_PCIE_DW) += pcie-designware.o
95 +obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
96 --- /dev/null
97 +++ b/drivers/pci/host/pci-imx6.c
98 @@ -0,0 +1,576 @@
99 +/*
100 + * PCIe host controller driver for Freescale i.MX6 SoCs
101 + *
102 + * Copyright (C) 2013 Kosagi
103 + * http://www.kosagi.com
104 + *
105 + * Author: Sean Cross <xobs@kosagi.com>
106 + *
107 + * This program is free software; you can redistribute it and/or modify
108 + * it under the terms of the GNU General Public License version 2 as
109 + * published by the Free Software Foundation.
110 + */
111 +
112 +#include <linux/clk.h>
113 +#include <linux/delay.h>
114 +#include <linux/gpio.h>
115 +#include <linux/kernel.h>
116 +#include <linux/mfd/syscon.h>
117 +#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
118 +#include <linux/module.h>
119 +#include <linux/of_gpio.h>
120 +#include <linux/pci.h>
121 +#include <linux/platform_device.h>
122 +#include <linux/regmap.h>
123 +#include <linux/resource.h>
124 +#include <linux/signal.h>
125 +#include <linux/types.h>
126 +
127 +#include "pcie-designware.h"
128 +
129 +#define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
130 +
131 +struct imx6_pcie {
132 + int reset_gpio;
133 + int power_on_gpio;
134 + int wake_up_gpio;
135 + int disable_gpio;
136 + struct clk *lvds_gate;
137 + struct clk *sata_ref_100m;
138 + struct clk *pcie_ref_125m;
139 + struct clk *pcie_axi;
140 + struct pcie_port pp;
141 + struct regmap *iomuxc_gpr;
142 + void __iomem *mem_base;
143 +};
144 +
145 +/* PCIe Port Logic registers (memory-mapped) */
146 +#define PL_OFFSET 0x700
147 +#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
148 +#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
149 +
150 +#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
151 +#define PCIE_PHY_CTRL_DATA_LOC 0
152 +#define PCIE_PHY_CTRL_CAP_ADR_LOC 16
153 +#define PCIE_PHY_CTRL_CAP_DAT_LOC 17
154 +#define PCIE_PHY_CTRL_WR_LOC 18
155 +#define PCIE_PHY_CTRL_RD_LOC 19
156 +
157 +#define PCIE_PHY_STAT (PL_OFFSET + 0x110)
158 +#define PCIE_PHY_STAT_ACK_LOC 16
159 +
160 +/* PHY registers (not memory-mapped) */
161 +#define PCIE_PHY_RX_ASIC_OUT 0x100D
162 +
163 +#define PHY_RX_OVRD_IN_LO 0x1005
164 +#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
165 +#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
166 +
167 +static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
168 +{
169 + u32 val;
170 + u32 max_iterations = 10;
171 + u32 wait_counter = 0;
172 +
173 + do {
174 + val = readl(dbi_base + PCIE_PHY_STAT);
175 + val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
176 + wait_counter++;
177 +
178 + if (val == exp_val)
179 + return 0;
180 +
181 + udelay(1);
182 + } while ((wait_counter < max_iterations) && (val != exp_val));
183 +
184 + return -ETIMEDOUT;
185 +}
186 +
187 +static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
188 +{
189 + u32 val;
190 + int ret;
191 +
192 + val = addr << PCIE_PHY_CTRL_DATA_LOC;
193 + writel(val, dbi_base + PCIE_PHY_CTRL);
194 +
195 + val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
196 + writel(val, dbi_base + PCIE_PHY_CTRL);
197 +
198 + ret = pcie_phy_poll_ack(dbi_base, 1);
199 + if (ret)
200 + return ret;
201 +
202 + val = addr << PCIE_PHY_CTRL_DATA_LOC;
203 + writel(val, dbi_base + PCIE_PHY_CTRL);
204 +
205 + ret = pcie_phy_poll_ack(dbi_base, 0);
206 + if (ret)
207 + return ret;
208 +
209 + return 0;
210 +}
211 +
212 +/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
213 +static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
214 +{
215 + u32 val, phy_ctl;
216 + int ret;
217 +
218 + ret = pcie_phy_wait_ack(dbi_base, addr);
219 + if (ret)
220 + return ret;
221 +
222 + /* assert Read signal */
223 + phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
224 + writel(phy_ctl, dbi_base + PCIE_PHY_CTRL);
225 +
226 + ret = pcie_phy_poll_ack(dbi_base, 1);
227 + if (ret)
228 + return ret;
229 +
230 + val = readl(dbi_base + PCIE_PHY_STAT);
231 + *data = val & 0xffff;
232 +
233 + /* deassert Read signal */
234 + writel(0x00, dbi_base + PCIE_PHY_CTRL);
235 +
236 + ret = pcie_phy_poll_ack(dbi_base, 0);
237 + if (ret)
238 + return ret;
239 +
240 + return 0;
241 +}
242 +
243 +static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
244 +{
245 + u32 var;
246 + int ret;
247 +
248 + /* write addr */
249 + /* cap addr */
250 + ret = pcie_phy_wait_ack(dbi_base, addr);
251 + if (ret)
252 + return ret;
253 +
254 + var = data << PCIE_PHY_CTRL_DATA_LOC;
255 + writel(var, dbi_base + PCIE_PHY_CTRL);
256 +
257 + /* capture data */
258 + var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
259 + writel(var, dbi_base + PCIE_PHY_CTRL);
260 +
261 + ret = pcie_phy_poll_ack(dbi_base, 1);
262 + if (ret)
263 + return ret;
264 +
265 + /* deassert cap data */
266 + var = data << PCIE_PHY_CTRL_DATA_LOC;
267 + writel(var, dbi_base + PCIE_PHY_CTRL);
268 +
269 + /* wait for ack de-assetion */
270 + ret = pcie_phy_poll_ack(dbi_base, 0);
271 + if (ret)
272 + return ret;
273 +
274 + /* assert wr signal */
275 + var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
276 + writel(var, dbi_base + PCIE_PHY_CTRL);
277 +
278 + /* wait for ack */
279 + ret = pcie_phy_poll_ack(dbi_base, 1);
280 + if (ret)
281 + return ret;
282 +
283 + /* deassert wr signal */
284 + var = data << PCIE_PHY_CTRL_DATA_LOC;
285 + writel(var, dbi_base + PCIE_PHY_CTRL);
286 +
287 + /* wait for ack de-assetion */
288 + ret = pcie_phy_poll_ack(dbi_base, 0);
289 + if (ret)
290 + return ret;
291 +
292 + writel(0x0, dbi_base + PCIE_PHY_CTRL);
293 +
294 + return 0;
295 +}
296 +
297 +/* Added for PCI abort handling */
298 +static int imx6q_pcie_abort_handler(unsigned long addr,
299 + unsigned int fsr, struct pt_regs *regs)
300 +{
301 + /*
302 + * If it was an imprecise abort, then we need to correct the
303 + * return address to be _after_ the instruction.
304 + */
305 + if (fsr & (1 << 10))
306 + regs->ARM_pc += 4;
307 + return 0;
308 +}
309 +
310 +static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
311 +{
312 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
313 +
314 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
315 + IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
316 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
317 + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
318 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
319 + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
320 +
321 + gpio_set_value(imx6_pcie->reset_gpio, 0);
322 + msleep(100);
323 + gpio_set_value(imx6_pcie->reset_gpio, 1);
324 +
325 + return 0;
326 +}
327 +
328 +static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
329 +{
330 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
331 + int ret;
332 +
333 + if (gpio_is_valid(imx6_pcie->power_on_gpio))
334 + gpio_set_value(imx6_pcie->power_on_gpio, 1);
335 +
336 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
337 + IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
338 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
339 + IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
340 +
341 + ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
342 + if (ret) {
343 + dev_err(pp->dev, "unable to enable sata_ref_100m\n");
344 + goto err_sata_ref;
345 + }
346 +
347 + ret = clk_prepare_enable(imx6_pcie->pcie_ref_125m);
348 + if (ret) {
349 + dev_err(pp->dev, "unable to enable pcie_ref_125m\n");
350 + goto err_pcie_ref;
351 + }
352 +
353 + ret = clk_prepare_enable(imx6_pcie->lvds_gate);
354 + if (ret) {
355 + dev_err(pp->dev, "unable to enable lvds_gate\n");
356 + goto err_lvds_gate;
357 + }
358 +
359 + ret = clk_prepare_enable(imx6_pcie->pcie_axi);
360 + if (ret) {
361 + dev_err(pp->dev, "unable to enable pcie_axi\n");
362 + goto err_pcie_axi;
363 + }
364 +
365 + /* allow the clocks to stabilize */
366 + usleep_range(200, 500);
367 +
368 + return 0;
369 +
370 +err_pcie_axi:
371 + clk_disable_unprepare(imx6_pcie->lvds_gate);
372 +err_lvds_gate:
373 + clk_disable_unprepare(imx6_pcie->pcie_ref_125m);
374 +err_pcie_ref:
375 + clk_disable_unprepare(imx6_pcie->sata_ref_100m);
376 +err_sata_ref:
377 + return ret;
378 +
379 +}
380 +
381 +static void imx6_pcie_init_phy(struct pcie_port *pp)
382 +{
383 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
384 +
385 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
386 + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
387 +
388 + /* configure constant input signal to the pcie ctrl and phy */
389 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
390 + IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
391 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
392 + IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
393 +
394 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
395 + IMX6Q_GPR8_TX_DEEMPH_GEN1, 0 << 0);
396 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
397 + IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB, 0 << 6);
398 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
399 + IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB, 20 << 12);
400 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
401 + IMX6Q_GPR8_TX_SWING_FULL, 127 << 18);
402 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
403 + IMX6Q_GPR8_TX_SWING_LOW, 127 << 25);
404 +}
405 +
406 +static void imx6_pcie_host_init(struct pcie_port *pp)
407 +{
408 + int count = 0;
409 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
410 +
411 + imx6_pcie_assert_core_reset(pp);
412 +
413 + imx6_pcie_init_phy(pp);
414 +
415 + imx6_pcie_deassert_core_reset(pp);
416 +
417 + dw_pcie_setup_rc(pp);
418 +
419 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
420 + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
421 +
422 + while (!dw_pcie_link_up(pp)) {
423 + usleep_range(100, 1000);
424 + count++;
425 + if (count >= 10) {
426 + dev_err(pp->dev, "phy link never came up\n");
427 + dev_dbg(pp->dev,
428 + "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
429 + readl(pp->dbi_base + PCIE_PHY_DEBUG_R0),
430 + readl(pp->dbi_base + PCIE_PHY_DEBUG_R1));
431 + break;
432 + }
433 + }
434 +
435 + return;
436 +}
437 +
438 +static int imx6_pcie_link_up(struct pcie_port *pp)
439 +{
440 + u32 rc, ltssm, rx_valid, temp;
441 +
442 + /* link is debug bit 36, debug register 1 starts at bit 32 */
443 + rc = readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & (0x1 << (36 - 32));
444 + if (rc)
445 + return -EAGAIN;
446 +
447 + /*
448 + * From L0, initiate MAC entry to gen2 if EP/RC supports gen2.
449 + * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2).
450 + * If (MAC/LTSSM.state == Recovery.RcvrLock)
451 + * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition
452 + * to gen2 is stuck
453 + */
454 + pcie_phy_read(pp->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid);
455 + ltssm = readl(pp->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F;
456 +
457 + if (rx_valid & 0x01)
458 + return 0;
459 +
460 + if (ltssm != 0x0d)
461 + return 0;
462 +
463 + dev_err(pp->dev,
464 + "transition to gen2 is stuck, reset PHY!\n");
465 +
466 + pcie_phy_read(pp->dbi_base,
467 + PHY_RX_OVRD_IN_LO, &temp);
468 + temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN
469 + | PHY_RX_OVRD_IN_LO_RX_PLL_EN);
470 + pcie_phy_write(pp->dbi_base,
471 + PHY_RX_OVRD_IN_LO, temp);
472 +
473 + usleep_range(2000, 3000);
474 +
475 + pcie_phy_read(pp->dbi_base,
476 + PHY_RX_OVRD_IN_LO, &temp);
477 + temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN
478 + | PHY_RX_OVRD_IN_LO_RX_PLL_EN);
479 + pcie_phy_write(pp->dbi_base,
480 + PHY_RX_OVRD_IN_LO, temp);
481 +
482 + return 0;
483 +}
484 +
485 +static struct pcie_host_ops imx6_pcie_host_ops = {
486 + .link_up = imx6_pcie_link_up,
487 + .host_init = imx6_pcie_host_init,
488 +};
489 +
490 +static int imx6_add_pcie_port(struct pcie_port *pp,
491 + struct platform_device *pdev)
492 +{
493 + int ret;
494 +
495 + pp->irq = platform_get_irq(pdev, 0);
496 + if (!pp->irq) {
497 + dev_err(&pdev->dev, "failed to get irq\n");
498 + return -ENODEV;
499 + }
500 +
501 + pp->root_bus_nr = -1;
502 + pp->ops = &imx6_pcie_host_ops;
503 +
504 + spin_lock_init(&pp->conf_lock);
505 + ret = dw_pcie_host_init(pp);
506 + if (ret) {
507 + dev_err(&pdev->dev, "failed to initialize host\n");
508 + return ret;
509 + }
510 +
511 + return 0;
512 +}
513 +
514 +static int __init imx6_pcie_probe(struct platform_device *pdev)
515 +{
516 + struct imx6_pcie *imx6_pcie;
517 + struct pcie_port *pp;
518 + struct device_node *np = pdev->dev.of_node;
519 + struct resource *dbi_base;
520 + int ret;
521 +
522 + imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL);
523 + if (!imx6_pcie)
524 + return -ENOMEM;
525 +
526 + pp = &imx6_pcie->pp;
527 + pp->dev = &pdev->dev;
528 +
529 + /* Added for PCI abort handling */
530 + hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
531 + "imprecise external abort");
532 +
533 + dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
534 + if (!dbi_base) {
535 + dev_err(&pdev->dev, "dbi_base memory resource not found\n");
536 + return -ENODEV;
537 + }
538 +
539 + pp->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base);
540 + if (IS_ERR(pp->dbi_base)) {
541 + dev_err(&pdev->dev, "unable to remap dbi_base\n");
542 + ret = PTR_ERR(pp->dbi_base);
543 + goto err;
544 + }
545 +
546 + /* Fetch GPIOs */
547 + imx6_pcie->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
548 + if (!gpio_is_valid(imx6_pcie->reset_gpio)) {
549 + dev_err(&pdev->dev, "no reset-gpio defined\n");
550 + ret = -ENODEV;
551 + }
552 + ret = devm_gpio_request_one(&pdev->dev,
553 + imx6_pcie->reset_gpio,
554 + GPIOF_OUT_INIT_LOW,
555 + "PCIe reset");
556 + if (ret) {
557 + dev_err(&pdev->dev, "unable to get reset gpio\n");
558 + goto err;
559 + }
560 +
561 + imx6_pcie->power_on_gpio = of_get_named_gpio(np, "power-on-gpio", 0);
562 + if (gpio_is_valid(imx6_pcie->power_on_gpio)) {
563 + ret = devm_gpio_request_one(&pdev->dev,
564 + imx6_pcie->power_on_gpio,
565 + GPIOF_OUT_INIT_LOW,
566 + "PCIe power enable");
567 + if (ret) {
568 + dev_err(&pdev->dev, "unable to get power-on gpio\n");
569 + goto err;
570 + }
571 + }
572 +
573 + imx6_pcie->wake_up_gpio = of_get_named_gpio(np, "wake-up-gpio", 0);
574 + if (gpio_is_valid(imx6_pcie->wake_up_gpio)) {
575 + ret = devm_gpio_request_one(&pdev->dev,
576 + imx6_pcie->wake_up_gpio,
577 + GPIOF_IN,
578 + "PCIe wake up");
579 + if (ret) {
580 + dev_err(&pdev->dev, "unable to get wake-up gpio\n");
581 + goto err;
582 + }
583 + }
584 +
585 + imx6_pcie->disable_gpio = of_get_named_gpio(np, "disable-gpio", 0);
586 + if (gpio_is_valid(imx6_pcie->disable_gpio)) {
587 + ret = devm_gpio_request_one(&pdev->dev,
588 + imx6_pcie->disable_gpio,
589 + GPIOF_OUT_INIT_HIGH,
590 + "PCIe disable endpoint");
591 + if (ret) {
592 + dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
593 + goto err;
594 + }
595 + }
596 +
597 + /* Fetch clocks */
598 + imx6_pcie->lvds_gate = clk_get(&pdev->dev, "lvds_gate");
599 + if (IS_ERR(imx6_pcie->lvds_gate)) {
600 + dev_err(&pdev->dev,
601 + "lvds_gate clock select missing or invalid\n");
602 + ret = PTR_ERR(imx6_pcie->lvds_gate);
603 + goto err;
604 + }
605 +
606 + imx6_pcie->sata_ref_100m = clk_get(&pdev->dev, "sata_ref_100m");
607 + if (IS_ERR(imx6_pcie->sata_ref_100m)) {
608 + dev_err(&pdev->dev,
609 + "sata_ref_100m clock source missing or invalid\n");
610 + ret = PTR_ERR(imx6_pcie->sata_ref_100m);
611 + goto err;
612 + }
613 +
614 + imx6_pcie->pcie_ref_125m = clk_get(&pdev->dev, "pcie_ref_125m");
615 + if (IS_ERR(imx6_pcie->pcie_ref_125m)) {
616 + dev_err(&pdev->dev,
617 + "pcie_ref_125m clock source missing or invalid\n");
618 + ret = PTR_ERR(imx6_pcie->pcie_ref_125m);
619 + goto err;
620 + }
621 +
622 + imx6_pcie->pcie_axi = clk_get(&pdev->dev, "pcie_axi");
623 + if (IS_ERR(imx6_pcie->pcie_axi)) {
624 + dev_err(&pdev->dev,
625 + "pcie_axi clock source missing or invalid\n");
626 + ret = PTR_ERR(imx6_pcie->pcie_axi);
627 + goto err;
628 + }
629 +
630 + /* Grab GPR config register range */
631 + imx6_pcie->iomuxc_gpr =
632 + syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
633 + if (IS_ERR(imx6_pcie->iomuxc_gpr)) {
634 + dev_err(&pdev->dev, "unable to find iomuxc registers\n");
635 + ret = PTR_ERR(imx6_pcie->iomuxc_gpr);
636 + goto err;
637 + }
638 +
639 + ret = imx6_add_pcie_port(pp, pdev);
640 + if (ret < 0)
641 + goto err;
642 +
643 + platform_set_drvdata(pdev, imx6_pcie);
644 + return 0;
645 +
646 +err:
647 + return ret;
648 +}
649 +
650 +static const struct of_device_id imx6_pcie_of_match[] = {
651 + { .compatible = "fsl,imx6q-pcie", },
652 + {},
653 +};
654 +MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
655 +
656 +static struct platform_driver imx6_pcie_driver = {
657 + .driver = {
658 + .name = "imx6q-pcie",
659 + .owner = THIS_MODULE,
660 + .of_match_table = of_match_ptr(imx6_pcie_of_match),
661 + },
662 +};
663 +
664 +/* Freescale PCIe driver does not allow module unload */
665 +
666 +static int __init imx6_init(void)
667 +{
668 + return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe);
669 +}
670 +module_init(imx6_init);
671 +
672 +MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");
673 +MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver");
674 +MODULE_LICENSE("GPL v2");