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.smirnov@xxxxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html