summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2020-05-28 03:31:59 -0700
committerYe Li <ye.li@nxp.com>2020-05-28 19:14:46 -0700
commitf229793a05f1039d9eba4286d9039403924cd1da (patch)
treef8d66a170a7917516d1b46d050b9117d68a52378 /drivers
parent11ea97fb3c67f71ba7d9cb05bf10a9035f1d3cc4 (diff)
MLK-24192-3 pci: pcie_imx: Enable some LPCG clocks for iMX8
Align the kernel's clocks enablement to enable the phy_per, misc_per clocks for all iMX8, and enable pciex2_per and pcie_phy_pclk for pcieb controller of iMX8QM. Signed-off-by: Ye Li <ye.li@nxp.com> Signed-off-by: Peng Fan <peng.fan@nxp.com> (cherry picked from commit 97b8d1c613f56b539328e421ba205f2221fc658e)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pcie_imx.c144
1 files changed, 105 insertions, 39 deletions
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index 10eff284e4..87305eb82d 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -252,8 +252,10 @@ struct imx_pcie_priv {
#if CONFIG_IS_ENABLED(CLK)
struct clk pcie_bus;
struct clk pcie_phy;
+ struct clk pcie_phy_pclk;
struct clk pcie_inbound_axi;
struct clk pcie_per;
+ struct clk pciex2_per;
struct clk phy_per;
struct clk misc_per;
struct clk pcie;
@@ -962,62 +964,100 @@ static int imx8_pcie_deassert_core_reset(struct imx_pcie_priv *priv)
printf("unable to enable pcie_phy clock\n");
goto err_pcie;
}
-#endif
- if (priv->variant == IMX8QM
- || priv->variant == IMX8QXP) {
+ ret = clk_enable(&priv->pcie_bus);
+ if (ret) {
+ printf("unable to enable pcie_bus clock\n");
+ goto err_pcie_phy;
+ }
-#if CONFIG_IS_ENABLED(CLK)
- ret = clk_enable(&priv->pcie_inbound_axi);
+ ret = clk_enable(&priv->pcie_inbound_axi);
+ if (ret) {
+ printf("unable to enable pcie_axi clock\n");
+ goto err_pcie_bus;
+ }
+ ret = clk_enable(&priv->pcie_per);
+ if (ret) {
+ printf("unable to enable pcie_per clock\n");
+ goto err_pcie_inbound_axi;
+ }
+
+ ret = clk_enable(&priv->phy_per);
+ if (ret) {
+ printf("unable to enable phy_per clock\n");
+ goto err_pcie_per;
+ }
+
+ ret = clk_enable(&priv->misc_per);
+ if (ret) {
+ printf("unable to enable misc_per clock\n");
+ goto err_phy_per;
+ }
+
+ if (priv->variant == IMX8QM && priv->ctrl_id == 1) {
+ ret = clk_enable(&priv->pcie_phy_pclk);
if (ret) {
- printf("unable to enable pcie_axi clock\n");
- goto err_pcie_phy;
+ printf("unable to enable pcie_phy_pclk clock\n");
+ goto err_misc_per;
}
- ret = clk_enable(&priv->pcie_per);
+
+ ret = clk_enable(&priv->pciex2_per);
if (ret) {
- printf("unable to enable pcie_per clock\n");
- clk_disable(&priv->pcie_inbound_axi);
- goto err_pcie_phy;
+ printf("unable to enable pciex2_per clock\n");
+ clk_disable(&priv->pcie_phy_pclk);
+ goto err_misc_per;
}
+ }
#endif
- /* allow the clocks to stabilize */
- udelay(200);
-
- /* bit19 PM_REQ_CORE_RST of pciex#_stts0 should be cleared. */
- for (i = 0; i < 100; i++) {
- val = IMX8QM_CSR_PCIEA_OFFSET
- + priv->ctrl_id * SZ_64K;
- imx_pcie_gpr_read(priv,
- val + IMX8QM_CSR_PCIE_STTS0_OFFSET,
- &tmp);
- if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) == 0)
- break;
- udelay(10);
- }
+ /* allow the clocks to stabilize */
+ udelay(200);
- if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) != 0)
- printf("ERROR PM_REQ_CORE_RST is still set.\n");
+ /* bit19 PM_REQ_CORE_RST of pciex#_stts0 should be cleared. */
+ for (i = 0; i < 100; i++) {
+ val = IMX8QM_CSR_PCIEA_OFFSET
+ + priv->ctrl_id * SZ_64K;
+ imx_pcie_gpr_read(priv,
+ val + IMX8QM_CSR_PCIE_STTS0_OFFSET,
+ &tmp);
+ if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) == 0)
+ break;
+ udelay(10);
+ }
- /* wait for phy pll lock firstly. */
- if (imx8_pcie_wait_for_phy_pll_lock(priv)) {
- ret = -ENODEV;
- goto err_ref_clk;;
- }
+ if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) != 0)
+ printf("ERROR PM_REQ_CORE_RST is still set.\n");
- if (dm_gpio_is_valid(&priv->reset_gpio)) {
- dm_gpio_set_value(&priv->reset_gpio, 1);
- mdelay(20);
- dm_gpio_set_value(&priv->reset_gpio, 0);
- mdelay(20);
- }
+ /* wait for phy pll lock firstly. */
+ if (imx8_pcie_wait_for_phy_pll_lock(priv)) {
+ ret = -ENODEV;
+ goto err_ref_clk;;
+ }
- return 0;
+ if (dm_gpio_is_valid(&priv->reset_gpio)) {
+ dm_gpio_set_value(&priv->reset_gpio, 1);
+ mdelay(20);
+ dm_gpio_set_value(&priv->reset_gpio, 0);
+ mdelay(20);
}
+ return 0;
+
err_ref_clk:
#if CONFIG_IS_ENABLED(CLK)
+ if (priv->variant == IMX8QM && priv->ctrl_id == 1) {
+ clk_disable(&priv->pciex2_per);
+ clk_disable(&priv->pcie_phy_pclk);
+ }
+err_misc_per:
+ clk_disable(&priv->misc_per);
+err_phy_per:
+ clk_disable(&priv->phy_per);
+err_pcie_per:
clk_disable(&priv->pcie_per);
+err_pcie_inbound_axi:
clk_disable(&priv->pcie_inbound_axi);
+err_pcie_bus:
+ clk_disable(&priv->pcie_bus);
err_pcie_phy:
clk_disable(&priv->pcie_phy);
err_pcie:
@@ -1621,6 +1661,32 @@ static int imx_pcie_dm_probe(struct udevice *dev)
printf("Failed to get pcie_inbound_axi clk\n");
return ret;
}
+
+ ret = clk_get_by_name(dev, "phy_per", &priv->phy_per);
+ if (ret) {
+ printf("Failed to get phy_per clk\n");
+ return ret;
+ }
+
+ ret = clk_get_by_name(dev, "misc_per", &priv->misc_per);
+ if (ret) {
+ printf("Failed to get misc_per clk\n");
+ return ret;
+ }
+
+ if (priv->variant == IMX8QM && priv->ctrl_id == 1) {
+ ret = clk_get_by_name(dev, "pcie_phy_pclk", &priv->pcie_phy_pclk);
+ if (ret) {
+ printf("Failed to get pcie_phy_pclk clk\n");
+ return ret;
+ }
+
+ ret = clk_get_by_name(dev, "pciex2_per", &priv->pciex2_per);
+ if (ret) {
+ printf("Failed to get pciex2_per clk\n");
+ return ret;
+ }
+ }
#endif
priv->iomuxc_gpr =
syscon_regmap_lookup_by_phandle(dev, "hsio");