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
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.
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>
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
20 --- a/drivers/pci/host/Kconfig
21 +++ b/drivers/pci/host/Kconfig
22 @@ -15,6 +15,12 @@ config PCI_EXYNOS
27 + bool "Freescale i.MX6 PCIe controller"
28 + depends on SOC_IMX6Q
33 bool "NVIDIA Tegra PCIe controller"
35 --- a/drivers/pci/host/Makefile
36 +++ b/drivers/pci/host/Makefile
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
44 +++ b/drivers/pci/host/pci-imx6.c
47 + * PCIe host controller driver for Freescale i.MX6 SoCs
49 + * Copyright (C) 2013 Kosagi
50 + * http://www.kosagi.com
52 + * Author: Sean Cross <xobs@kosagi.com>
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.
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>
74 +#include "pcie-designware.h"
76 +#define to_imx6_pcie(x) container_of(x, struct imx6_pcie, pp)
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;
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)
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
104 +#define PCIE_PHY_STAT (PL_OFFSET + 0x110)
105 +#define PCIE_PHY_STAT_ACK_LOC 16
107 +/* PHY registers (not memory-mapped) */
108 +#define PCIE_PHY_RX_ASIC_OUT 0x100D
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)
114 +static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
117 + u32 max_iterations = 10;
118 + u32 wait_counter = 0;
121 + val = readl(dbi_base + PCIE_PHY_STAT);
122 + val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
125 + if (val == exp_val)
129 + } while (wait_counter < max_iterations);
134 +static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
139 + val = addr << PCIE_PHY_CTRL_DATA_LOC;
140 + writel(val, dbi_base + PCIE_PHY_CTRL);
142 + val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
143 + writel(val, dbi_base + PCIE_PHY_CTRL);
145 + ret = pcie_phy_poll_ack(dbi_base, 1);
149 + val = addr << PCIE_PHY_CTRL_DATA_LOC;
150 + writel(val, dbi_base + PCIE_PHY_CTRL);
152 + ret = pcie_phy_poll_ack(dbi_base, 0);
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)
165 + ret = pcie_phy_wait_ack(dbi_base, addr);
169 + /* assert Read signal */
170 + phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
171 + writel(phy_ctl, dbi_base + PCIE_PHY_CTRL);
173 + ret = pcie_phy_poll_ack(dbi_base, 1);
177 + val = readl(dbi_base + PCIE_PHY_STAT);
178 + *data = val & 0xffff;
180 + /* deassert Read signal */
181 + writel(0x00, dbi_base + PCIE_PHY_CTRL);
183 + ret = pcie_phy_poll_ack(dbi_base, 0);
190 +static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
197 + ret = pcie_phy_wait_ack(dbi_base, addr);
201 + var = data << PCIE_PHY_CTRL_DATA_LOC;
202 + writel(var, dbi_base + PCIE_PHY_CTRL);
205 + var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
206 + writel(var, dbi_base + PCIE_PHY_CTRL);
208 + ret = pcie_phy_poll_ack(dbi_base, 1);
212 + /* deassert cap data */
213 + var = data << PCIE_PHY_CTRL_DATA_LOC;
214 + writel(var, dbi_base + PCIE_PHY_CTRL);
216 + /* wait for ack de-assertion */
217 + ret = pcie_phy_poll_ack(dbi_base, 0);
221 + /* assert wr signal */
222 + var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
223 + writel(var, dbi_base + PCIE_PHY_CTRL);
226 + ret = pcie_phy_poll_ack(dbi_base, 1);
230 + /* deassert wr signal */
231 + var = data << PCIE_PHY_CTRL_DATA_LOC;
232 + writel(var, dbi_base + PCIE_PHY_CTRL);
234 + /* wait for ack de-assertion */
235 + ret = pcie_phy_poll_ack(dbi_base, 0);
239 + writel(0x0, dbi_base + PCIE_PHY_CTRL);
244 +/* Added for PCI abort handling */
245 +static int imx6q_pcie_abort_handler(unsigned long addr,
246 + unsigned int fsr, struct pt_regs *regs)
249 + * If it was an imprecise abort, then we need to correct the
250 + * return address to be _after_ the instruction.
252 + if (fsr & (1 << 10))
257 +static int imx6_pcie_assert_core_reset(struct pcie_port *pp)
259 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
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);
268 + gpio_set_value(imx6_pcie->reset_gpio, 0);
270 + gpio_set_value(imx6_pcie->reset_gpio, 1);
275 +static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
277 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
280 + if (gpio_is_valid(imx6_pcie->power_on_gpio))
281 + gpio_set_value(imx6_pcie->power_on_gpio, 1);
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);
288 + ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
290 + dev_err(pp->dev, "unable to enable sata_ref_100m\n");
294 + ret = clk_prepare_enable(imx6_pcie->pcie_ref_125m);
296 + dev_err(pp->dev, "unable to enable pcie_ref_125m\n");
300 + ret = clk_prepare_enable(imx6_pcie->lvds_gate);
302 + dev_err(pp->dev, "unable to enable lvds_gate\n");
303 + goto err_lvds_gate;
306 + ret = clk_prepare_enable(imx6_pcie->pcie_axi);
308 + dev_err(pp->dev, "unable to enable pcie_axi\n");
312 + /* allow the clocks to stabilize */
313 + usleep_range(200, 500);
318 + clk_disable_unprepare(imx6_pcie->lvds_gate);
320 + clk_disable_unprepare(imx6_pcie->pcie_ref_125m);
322 + clk_disable_unprepare(imx6_pcie->sata_ref_100m);
328 +static void imx6_pcie_init_phy(struct pcie_port *pp)
330 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
332 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
333 + IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
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);
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);
353 +static void imx6_pcie_host_init(struct pcie_port *pp)
356 + struct imx6_pcie *imx6_pcie = to_imx6_pcie(pp);
358 + imx6_pcie_assert_core_reset(pp);
360 + imx6_pcie_init_phy(pp);
362 + imx6_pcie_deassert_core_reset(pp);
364 + dw_pcie_setup_rc(pp);
366 + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
367 + IMX6Q_GPR12_PCIE_CTL_2, 1 << 10);
369 + while (!dw_pcie_link_up(pp)) {
370 + usleep_range(100, 1000);
373 + dev_err(pp->dev, "phy link never came up\n");
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));
385 +static int imx6_pcie_link_up(struct pcie_port *pp)
387 + u32 rc, ltssm, rx_valid, temp;
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));
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
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;
404 + if (rx_valid & 0x01)
410 + dev_err(pp->dev, "transition to gen2 is stuck, reset PHY!\n");
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);
419 + usleep_range(2000, 3000);
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);
431 +static struct pcie_host_ops imx6_pcie_host_ops = {
432 + .link_up = imx6_pcie_link_up,
433 + .host_init = imx6_pcie_host_init,
436 +static int imx6_add_pcie_port(struct pcie_port *pp,
437 + struct platform_device *pdev)
441 + pp->irq = platform_get_irq(pdev, 0);
443 + dev_err(&pdev->dev, "failed to get irq\n");
447 + pp->root_bus_nr = -1;
448 + pp->ops = &imx6_pcie_host_ops;
450 + spin_lock_init(&pp->conf_lock);
451 + ret = dw_pcie_host_init(pp);
453 + dev_err(&pdev->dev, "failed to initialize host\n");
460 +static int __init imx6_pcie_probe(struct platform_device *pdev)
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;
468 + imx6_pcie = devm_kzalloc(&pdev->dev, sizeof(*imx6_pcie), GFP_KERNEL);
472 + pp = &imx6_pcie->pp;
473 + pp->dev = &pdev->dev;
475 + /* Added for PCI abort handling */
476 + hook_fault_code(16 + 6, imx6q_pcie_abort_handler, SIGBUS, 0,
477 + "imprecise external abort");
479 + dbi_base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
481 + dev_err(&pdev->dev, "dbi_base memory resource not found\n");
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);
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");
498 + ret = devm_gpio_request_one(&pdev->dev,
499 + imx6_pcie->reset_gpio,
500 + GPIOF_OUT_INIT_LOW,
503 + dev_err(&pdev->dev, "unable to get reset gpio\n");
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");
514 + dev_err(&pdev->dev, "unable to get power-on gpio\n");
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,
526 + dev_err(&pdev->dev, "unable to get wake-up gpio\n");
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");
538 + dev_err(&pdev->dev, "unable to get disable-ep gpio\n");
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);
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);
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);
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);
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);
585 + ret = imx6_add_pcie_port(pp, pdev);
589 + platform_set_drvdata(pdev, imx6_pcie);
596 +static const struct of_device_id imx6_pcie_of_match[] = {
597 + { .compatible = "fsl,imx6q-pcie", },
600 +MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
602 +static struct platform_driver imx6_pcie_driver = {
604 + .name = "imx6q-pcie",
605 + .owner = THIS_MODULE,
606 + .of_match_table = of_match_ptr(imx6_pcie_of_match),
610 +/* Freescale PCIe driver does not allow module unload */
612 +static int __init imx6_pcie_init(void)
614 + return platform_driver_probe(&imx6_pcie_driver, imx6_pcie_probe);
616 +module_init(imx6_pcie_init);
618 +MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");
619 +MODULE_DESCRIPTION("Freescale i.MX6 PCIe host controller driver");
620 +MODULE_LICENSE("GPL v2");