I.MX6+ has a dedicated bit for reseting PCIe core, which should be used
instead of a regular reset sequence since using the latter will hang the
SoC.

This commit is based on c34068d48273e24d392d9a49a38be807954420ed from
http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git

Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com>
---

Changes since v1:

        - Patchset is rebased against
          
https://git.kernel.org/cgit/linux/kernel/git/helgaas/pci.git/log/?h=pci/host-imx6

        - DTS files changes moved into a separate patch

 drivers/pci/host/pci-imx6.c                 | 28 ++++++++++++++++++++++++++--
 include/linux/mfd/syscon/imx6q-iomuxc-gpr.h |  1 +
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index c570bbb..834c5b8 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -33,7 +33,8 @@
 
 enum imx6_pcie_variants {
        IMX6Q,
-       IMX6SX
+       IMX6SX,
+       IMX6QP,
 };
 
 struct imx6_pcie {
@@ -253,6 +254,11 @@ static int imx6_pcie_assert_core_reset(struct pcie_port 
*pp)
                                   IMX6SX_GPR5_PCIE_BTNRST_RESET,
                                   IMX6SX_GPR5_PCIE_BTNRST_RESET);
                break;
+       case IMX6QP:
+               regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+                                  IMX6Q_GPR1_PCIE_SW_RST,
+                                  IMX6Q_GPR1_PCIE_SW_RST);
+               break;
        case IMX6Q:
                /*
                 * If the bootloader already enabled the link we need some 
special
@@ -307,6 +313,7 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie 
*imx6_pcie)
                regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
                                   IMX6SX_GPR12_PCIE_TEST_POWERDOWN, 0);
                break;
+       case IMX6QP:            /* FALLTHROUGH */
        case IMX6Q:
                /* power up core phy and enable ref clock */
                regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
@@ -367,9 +374,22 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port 
*pp)
                gpiod_set_value_cansleep(imx6_pcie->reset_gpio, 1);
        }
 
-       if (imx6_pcie->variant == IMX6SX)
+       switch (imx6_pcie->variant) {
+       case IMX6SX:
                regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5,
                                   IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
+               break;
+       case IMX6QP:
+               regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+                                  IMX6Q_GPR1_PCIE_SW_RST, 0);
+
+               usleep_range(200, 500);
+               break;
+       case IMX6Q:             /* Nothing to do */
+               break;
+       default:
+               BUG();
+       }
 
        return 0;
 
@@ -601,6 +621,9 @@ static int __init imx6_pcie_probe(struct platform_device 
*pdev)
        if (of_device_is_compatible(pp->dev->of_node,
                                    "fsl,imx6sx-pcie"))
                imx6_pcie->variant = IMX6SX;
+       else if (of_device_is_compatible(pp->dev->of_node,
+                                        "fsl,imx6qp-pcie"))
+               imx6_pcie->variant = IMX6QP;
        else
                imx6_pcie->variant = IMX6Q;
 
@@ -697,6 +720,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev)
 static const struct of_device_id imx6_pcie_of_match[] = {
        { .compatible = "fsl,imx6q-pcie", },
        { .compatible = "fsl,imx6sx-pcie", },
+       { .compatible = "fsl,imx6qp-pcie", },
        {},
 };
 MODULE_DEVICE_TABLE(of, imx6_pcie_of_match);
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h 
b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
index 238c8db..5b08e3c 100644
--- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -95,6 +95,7 @@
 #define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IOMUX       BIT(0)
 
 #define IMX6Q_GPR1_PCIE_REQ_MASK               (0x3 << 30)
+#define IMX6Q_GPR1_PCIE_SW_RST                 BIT(29)
 #define IMX6Q_GPR1_PCIE_EXIT_L1                        BIT(28)
 #define IMX6Q_GPR1_PCIE_RDY_L23                        BIT(27)
 #define IMX6Q_GPR1_PCIE_ENTER_L1               BIT(26)
-- 
2.5.5

Reply via email to