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