diff options
author | Andrey Smirnov <andrew.smirnov@gmail.com> | 2016-05-02 14:09:10 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-05-02 14:33:17 -0500 |
commit | 4d31c6109a24892df461b6a98842935e80159a5e (patch) | |
tree | df1343bf8354c06ff5a5e96d27ec0093a2959c68 /drivers/pci | |
parent | e6f1fef04c253955004efea35aea2e4bc59f49b6 (diff) |
PCI: imx6: Implement reset sequence for i.MX6+
I.MX6+ has a dedicated bit for resetting 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
Tested-by: Gary Bisson <gary.bisson@boundarydevices.com>
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 6b5d8c2fe2f2..b741a36a67f3 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -34,7 +34,8 @@ enum imx6_pcie_variants { IMX6Q, - IMX6SX + IMX6SX, + IMX6QP, }; struct imx6_pcie { @@ -256,6 +257,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 @@ -310,6 +316,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, @@ -370,9 +377,20 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp) !imx6_pcie->gpio_active_high); } - 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; + } return 0; @@ -718,6 +736,7 @@ static void imx6_pcie_shutdown(struct platform_device *pdev) static const struct of_device_id imx6_pcie_of_match[] = { { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, }, { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, }, + { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, }, {}, }; MODULE_DEVICE_TABLE(of, imx6_pcie_of_match); |