diff options
-rw-r--r-- | drivers/pci/host/pci-imx6.c | 419 |
1 files changed, 218 insertions, 201 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 8a099fbcb08d..5893f613fb6d 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -73,7 +73,6 @@ struct imx6_pcie { struct clk *pcie_inbound_axi; struct clk *pcie_phy; struct clk *pcie; - struct clk *pcie_ext; struct clk *pcie_ext_src; struct regmap *iomuxc_gpr; enum imx6_pcie_variants variant; @@ -537,6 +536,8 @@ static int pci_imx_phy_pll_locked(struct imx6_pcie *imx6_pcie) { u32 val, tmp, orig; int i = 0; + struct pcie_port *pp = &imx6_pcie->pp; + struct device *dev = pp->dev; if (imx6_pcie->variant == IMX7D) { for (i = 0; i < 100; i++) { @@ -610,7 +611,7 @@ static int pci_imx_phy_pll_locked(struct imx6_pcie *imx6_pcie) } if (i >= 100) { - pr_info("pcie phy pll can't be locked.\n"); + dev_info(dev, "pcie phy pll can't be locked.\n"); return -ENODEV; } else { return 0; @@ -634,20 +635,13 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) return -ENODEV; } - if (imx6_pcie->ext_osc && (imx6_pcie->variant == IMX6QP)) { - clk_set_parent(imx6_pcie->pcie_ext, + if (imx6_pcie->ext_osc && (imx6_pcie->variant == IMX6QP)) + clk_set_parent(imx6_pcie->pcie_bus, imx6_pcie->pcie_ext_src); - ret = clk_prepare_enable(imx6_pcie->pcie_ext); - if (ret) { - dev_err(pp->dev, "unable to enable pcie_ext clock\n"); - goto err_pcie_bus; - } - } else { - ret = clk_prepare_enable(imx6_pcie->pcie_bus); - if (ret) { - dev_err(pp->dev, "unable to enable pcie_bus clock\n"); - goto err_pcie_bus; - } + ret = clk_prepare_enable(imx6_pcie->pcie_bus); + if (ret) { + dev_err(pp->dev, "unable to enable pcie_bus clock\n"); + goto err_pcie_bus; } ret = clk_prepare_enable(imx6_pcie->pcie_phy); @@ -716,7 +710,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) /* Add the workaround for ERR010728 */ if (unlikely(imx6_pcie->phy_base == NULL)) { - pr_err("phy base shouldn't be null.\n"); + dev_err(dev, "phy base shouldn't be null.\n"); } else { /* De-assert DCC_FB_EN by writing data "0x29". */ writel(PCIE_PHY_CMN_REG4_DCC_FB_EN, @@ -751,11 +745,22 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) } if ((tmp & IMX8QM_CTRL_STTS0_PM_REQ_CORE_RST) != 0) - pr_err("ERROR PM_REQ_CORE_RST is still set.\n"); + dev_err(dev, "ERROR PM_REQ_CORE_RST is still set.\n"); /* wait for phy pll lock firstly. */ if (pci_imx_phy_pll_locked(imx6_pcie)) ret = -ENODEV; + + /* set up the cpu address offset */ + if (imx6_pcie->cpu_base) + pp->cpu_addr_offset = imx6_pcie->cpu_base + - pp->mem_base; + else + pp->cpu_addr_offset = 0; + + if (dw_pcie_readl_rc(pp, PCIE_MISC_CTRL) == 0) + dw_pcie_writel_rc(pp, PCIE_MISC_CTRL, + PCIE_MISC_DBI_RO_WR_EN); break; case IMX8MQ: /* wait for more than 10us to release phy g_rst and btnrst */ @@ -789,9 +794,7 @@ static int imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) err_ref_clk: clk_disable_unprepare(imx6_pcie->pcie_phy); err_pcie_phy: - if (!imx6_pcie->ext_osc || (imx6_pcie->variant == IMX8QM) - || (imx6_pcie->variant == IMX8QXP)) - clk_disable_unprepare(imx6_pcie->pcie_bus); + clk_disable_unprepare(imx6_pcie->pcie_bus); err_pcie_bus: clk_disable_unprepare(imx6_pcie->pcie); return ret; @@ -801,6 +804,8 @@ static void imx6_pcie_phy_pwr_up(struct imx6_pcie *imx6_pcie) { u32 val, offset; unsigned long timeout = jiffies + msecs_to_jiffies(500); + struct pcie_port *pp = &imx6_pcie->pp; + struct device *dev = pp->dev; if (imx6_pcie->variant != IMX8MQ) return; @@ -832,7 +837,7 @@ static void imx6_pcie_phy_pwr_up(struct imx6_pcie *imx6_pcie) IMX8MQ_GPC_PU_PGC_SW_PUP_REQ_OFFSET, &val); if (time_after(jiffies, timeout)) { - pr_err("CAN NOT PWR UP PCIE%d PHY!\n", + dev_err(dev, "CAN NOT PWR UP PCIE%d PHY!\n", imx6_pcie->ctrl_id); break; } @@ -844,6 +849,8 @@ static void imx6_pcie_phy_pwr_dn(struct imx6_pcie *imx6_pcie) { u32 val, offset; unsigned long timeout = jiffies + msecs_to_jiffies(500); + struct pcie_port *pp = &imx6_pcie->pp; + struct device *dev = pp->dev; if (imx6_pcie->variant != IMX8MQ) return; @@ -884,7 +891,7 @@ static void imx6_pcie_phy_pwr_dn(struct imx6_pcie *imx6_pcie) IMX8MQ_GPC_PU_PGC_SW_PDN_REQ_OFFSET, &val); if (time_after(jiffies, timeout)) { - pr_err("CAN NOT PWR DN PCIE%d PHY!\n", + dev_err(dev, "CAN NOT PWR DN PCIE%d PHY!\n", imx6_pcie->ctrl_id); break; } @@ -1163,6 +1170,87 @@ static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg) return dw_handle_msi_irq(pp); } +static void pci_imx_clk_disable(struct device *dev) +{ + u32 val; + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); + + clk_disable_unprepare(imx6_pcie->pcie); + clk_disable_unprepare(imx6_pcie->pcie_phy); + clk_disable_unprepare(imx6_pcie->pcie_bus); + switch (imx6_pcie->variant) { + case IMX6Q: + break; + case IMX6SX: + clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); + break; + case IMX6QP: + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_REF_CLK_EN, 0); + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, + IMX6Q_GPR1_PCIE_TEST_PD); + break; + case IMX7D: + /* turn off external osc input */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + BIT(5), BIT(5)); + break; + case IMX8MQ: + if (imx6_pcie->ctrl_id == 0) + val = IOMUXC_GPR14; + else + val = IOMUXC_GPR16; + + regmap_update_bits(imx6_pcie->iomuxc_gpr, val, + IMX8MQ_GPR_PCIE_REF_USE_PAD, 0); + break; + case IMX8QXP: + case IMX8QM: + clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); + break; + } + + release_bus_freq(BUS_FREQ_HIGH); +} + +static void pci_imx_ltssm_enable(struct device *dev) +{ + u32 val; + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); + + switch (imx6_pcie->variant) { + case IMX6Q: + case IMX6SX: + case IMX6QP: + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, + IMX6Q_GPR12_PCIE_CTL_2); + break; + case IMX7D: + case IMX8MQ: + if (imx6_pcie->ctrl_id == 0) + val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET; + else + val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET; + regmap_update_bits(imx6_pcie->reg_src, val, + IMX8MQ_PCIE_CTRL_APPS_EN, + IMX8MQ_PCIE_CTRL_APPS_EN); + break; + case IMX8QXP: + case IMX8QM: + /* Bit4 of the CTRL2 */ + val = IMX8QM_CSR_PCIEA_OFFSET + + imx6_pcie->ctrl_id * SZ_64K; + regmap_update_bits(imx6_pcie->iomuxc_gpr, + val + IMX8QM_CSR_PCIE_CTRL2_OFFSET, + IMX8QM_CTRL_LTSSM_ENABLE, + IMX8QM_CTRL_LTSSM_ENABLE); + break; + } + +} + static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) { struct pcie_port *pp = &imx6_pcie->pp; @@ -1183,27 +1271,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie) } /* Start LTSSM. */ - if (imx6_pcie->variant == IMX8QM || imx6_pcie->variant == IMX8QXP) { - /* Bit4 of the CTRL2 */ - tmp = IMX8QM_CSR_PCIEA_OFFSET - + imx6_pcie->ctrl_id * SZ_64K; - regmap_update_bits(imx6_pcie->iomuxc_gpr, - tmp + IMX8QM_CSR_PCIE_CTRL2_OFFSET, - IMX8QM_CTRL_LTSSM_ENABLE, - IMX8QM_CTRL_LTSSM_ENABLE); - } else if ((imx6_pcie->variant == IMX7D) - || (imx6_pcie->variant == IMX8MQ)) { - if (imx6_pcie->ctrl_id == 0) - tmp = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET; - else - tmp = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET; - regmap_update_bits(imx6_pcie->reg_src, tmp, - IMX8MQ_PCIE_CTRL_APPS_EN, - IMX8MQ_PCIE_CTRL_APPS_EN); - } else { - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); - } + pci_imx_ltssm_enable(dev); ret = imx6_pcie_wait_for_link(imx6_pcie); if (ret) { @@ -1254,17 +1322,7 @@ err_reset_phy: imx6_pcie_reset_phy(imx6_pcie); if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) { - clk_disable_unprepare(imx6_pcie->pcie); - if (!imx6_pcie->ext_osc - || (imx6_pcie->variant == IMX8QXP) - || (imx6_pcie->variant == IMX8QM)) - clk_disable_unprepare(imx6_pcie->pcie_bus); - clk_disable_unprepare(imx6_pcie->pcie_phy); - if (imx6_pcie->variant == IMX6SX - || imx6_pcie->variant == IMX8QXP - || imx6_pcie->variant == IMX8QM) - clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); - release_bus_freq(BUS_FREQ_HIGH); + pci_imx_clk_disable(dev); if ((imx6_pcie->variant == IMX7D) || (imx6_pcie->variant == IMX8MQ) || (imx6_pcie->variant == IMX8QM) @@ -1299,18 +1357,6 @@ static int imx6_pcie_host_init(struct pcie_port *pp) if (ret < 0) return ret; - /* set up the cpu address offset */ - if (imx6_pcie->cpu_base) - pp->cpu_addr_offset = imx6_pcie->cpu_base - pp->mem_base; - else - pp->cpu_addr_offset = 0; - - if (imx6_pcie->variant == IMX8QM || imx6_pcie->variant == IMX8QXP) { - if (dw_pcie_readl_rc(pp, PCIE_MISC_CTRL) == 0) - dw_pcie_writel_rc(pp, PCIE_MISC_CTRL, - PCIE_MISC_DBI_RO_WR_EN); - } - dw_pcie_setup_rc(pp); ret = imx6_pcie_establish_link(imx6_pcie); if (ret < 0) @@ -1559,27 +1605,44 @@ static void imx6_pcie_setup_ep(struct pcie_port *pp) /* PM_TURN_OFF */ static void pci_imx_pm_turn_off(struct imx6_pcie *imx6_pcie) { + u32 val; + struct pcie_port *pp = &imx6_pcie->pp; + struct device *dev = pp->dev; + /* PM_TURN_OFF */ - if (imx6_pcie->variant == IMX7D) { - regmap_update_bits(imx6_pcie->reg_src, 0x2c, - BIT(11), BIT(11)); - regmap_update_bits(imx6_pcie->reg_src, 0x2c, - BIT(11), 0); - } else if (imx6_pcie->variant == IMX6SX) { + switch (imx6_pcie->variant) { + case IMX6SX: regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6SX_GPR12_PCIE_PM_TURN_OFF, IMX6SX_GPR12_PCIE_PM_TURN_OFF); regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6SX_GPR12_PCIE_PM_TURN_OFF, 0); - } else if (imx6_pcie->variant == IMX6QP) { + break; + case IMX6QP: regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_PCIE_PM_TURN_OFF, IMX6Q_GPR12_PCIE_PM_TURN_OFF); regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX6Q_GPR12_PCIE_PM_TURN_OFF, 0); - } else { - pr_info("Info: don't support pm_turn_off yet.\n"); - return; + break; + case IMX7D: + case IMX8MQ: + if (imx6_pcie->ctrl_id == 0) + val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET; + else + val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET; + regmap_update_bits(imx6_pcie->reg_src, val, + IMX8MQ_PCIE_CTRL_APPS_TURNOFF, + IMX8MQ_PCIE_CTRL_APPS_TURNOFF); + regmap_update_bits(imx6_pcie->reg_src, val, + IMX8MQ_PCIE_CTRL_APPS_TURNOFF, + 0); + break; + case IMX6Q: + case IMX8QXP: + case IMX8QM: + dev_info(dev, "Info: don't support pm_turn_off yet.\n"); + break; } udelay(1000); @@ -1597,41 +1660,7 @@ static int pci_imx_suspend_noirq(struct device *dev) pci_imx_pm_turn_off(imx6_pcie); - if (imx6_pcie->variant == IMX7D || imx6_pcie->variant == IMX6SX || - imx6_pcie->variant == IMX6QP || imx6_pcie->variant == IMX8QM - || imx6_pcie->variant == IMX8QXP) { - /* Disable clks */ - clk_disable_unprepare(imx6_pcie->pcie); - clk_disable_unprepare(imx6_pcie->pcie_phy); - if (!imx6_pcie->ext_osc - || (imx6_pcie->variant == IMX8QXP) - || (imx6_pcie->variant == IMX8QM)) - clk_disable_unprepare(imx6_pcie->pcie_bus); - if (imx6_pcie->variant == IMX6SX - || imx6_pcie->variant == IMX8QXP - || imx6_pcie->variant == IMX8QM) - clk_disable_unprepare(imx6_pcie->pcie_inbound_axi); - else if (imx6_pcie->variant == IMX7D) - /* turn off external osc input */ - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - BIT(5), BIT(5)); - else if (imx6_pcie->variant == IMX6QP) { - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_REF_CLK_EN, 0); - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, - IMX6Q_GPR1_PCIE_TEST_PD); - } - release_bus_freq(BUS_FREQ_HIGH); - - /* Power down PCIe PHY. */ - if (imx6_pcie->pcie_phy_regulator != NULL) - regulator_disable(imx6_pcie->pcie_phy_regulator); - if (imx6_pcie->pcie_bus_regulator != NULL) - regulator_disable(imx6_pcie->pcie_bus_regulator); - if (gpio_is_valid(imx6_pcie->power_on_gpio)) - gpio_set_value_cansleep(imx6_pcie->power_on_gpio, 0); - } else { + if (unlikely(imx6_pcie->variant == IMX6Q)) { /* * L2 can exit by 'reset' or Inband beacon (from remote EP) * toggling phy_powerdown has same effect as 'inband beacon' @@ -1641,41 +1670,77 @@ static int pci_imx_suspend_noirq(struct device *dev) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD, IMX6Q_GPR1_PCIE_TEST_PD); + } else { + pci_imx_clk_disable(dev); + + if (imx6_pcie->variant == IMX8MQ) + imx6_pcie_phy_pwr_dn(imx6_pcie); + /* Power down PCIe PHY. */ + if (imx6_pcie->pcie_phy_regulator != NULL) + regulator_disable(imx6_pcie->pcie_phy_regulator); + if (imx6_pcie->pcie_bus_regulator != NULL) + regulator_disable(imx6_pcie->pcie_bus_regulator); } return 0; } -static int pci_imx_resume_noirq(struct device *dev) +static void pci_imx_ltssm_disable(struct device *dev) { u32 val; + struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); + + switch (imx6_pcie->variant) { + case IMX6Q: + case IMX6SX: + case IMX6QP: + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, + IMX6Q_GPR12_PCIE_CTL_2, 0); + break; + case IMX7D: + case IMX8MQ: + if (imx6_pcie->ctrl_id == 0) + val = IMX8MQ_SRC_PCIEPHY_RCR_OFFSET; + else + val = IMX8MQ_SRC_PCIE2PHY_RCR_OFFSET; + regmap_update_bits(imx6_pcie->reg_src, val, + IMX8MQ_PCIE_CTRL_APPS_EN, + 0); + break; + case IMX8QXP: + case IMX8QM: + /* Bit4 of the CTRL2 */ + val = IMX8QM_CSR_PCIEA_OFFSET + + imx6_pcie->ctrl_id * SZ_64K; + regmap_update_bits(imx6_pcie->iomuxc_gpr, + val + IMX8QM_CSR_PCIE_CTRL2_OFFSET, + IMX8QM_CTRL_LTSSM_ENABLE, 0); + break; + } +} + +static int pci_imx_resume_noirq(struct device *dev) +{ int ret = 0; struct imx6_pcie *imx6_pcie = dev_get_drvdata(dev); struct pcie_port *pp = &imx6_pcie->pp; - if (imx6_pcie->variant == IMX7D || imx6_pcie->variant == IMX6SX || - imx6_pcie->variant == IMX6QP || imx6_pcie->variant == IMX8QXP - || imx6_pcie->variant == IMX8QM) { - if (imx6_pcie->variant == IMX8QM - || imx6_pcie->variant == IMX8QXP) { - /* Bit4 of the CTRL2 */ - val = IMX8QM_CSR_PCIEA_OFFSET - + imx6_pcie->ctrl_id * SZ_64K; - regmap_update_bits(imx6_pcie->iomuxc_gpr, - val + IMX8QM_CSR_PCIE_CTRL2_OFFSET, - IMX8QM_CTRL_LTSSM_ENABLE, 0); - } else if (imx6_pcie->variant == IMX7D) { - regmap_update_bits(imx6_pcie->reg_src, 0x2c, BIT(6), 0); - } else { - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 0); - } - + if (unlikely(imx6_pcie->variant == IMX6Q)) { + /* + * L2 can exit by 'reset' or Inband beacon (from remote EP) + * toggling phy_powerdown has same effect as 'inband beacon' + * So, toggle bit18 of GPR1, used as a workaround of errata + * "PCIe PCIe does not support L2 Power Down" + */ + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, + IMX6Q_GPR1_PCIE_TEST_PD, 0); + } else { + pci_imx_ltssm_disable(dev); imx6_pcie_assert_core_reset(imx6_pcie); - imx6_pcie_init_phy(imx6_pcie); - - imx6_pcie_deassert_core_reset(imx6_pcie); + ret = imx6_pcie_deassert_core_reset(imx6_pcie); + if (ret < 0) + return ret; /* * controller maybe turn off, re-configure again @@ -1684,45 +1749,14 @@ static int pci_imx_resume_noirq(struct device *dev) if (IS_ENABLED(CONFIG_PCI_MSI)) dw_pcie_msi_cfg_restore(pp); - - if (imx6_pcie->variant == IMX8QM - || imx6_pcie->variant == IMX8QXP) { - /* wait for phy pll lock firstly. */ - pci_imx_phy_pll_locked(imx6_pcie); - - /* Bit4 of the CTRL2 */ - val = IMX8QM_CSR_PCIEA_OFFSET - + imx6_pcie->ctrl_id * SZ_64K; - regmap_update_bits(imx6_pcie->iomuxc_gpr, - val + IMX8QM_CSR_PCIE_CTRL2_OFFSET, - IMX8QM_CTRL_LTSSM_ENABLE, - IMX8QM_CTRL_LTSSM_ENABLE); - } else if (imx6_pcie->variant == IMX7D) { - /* wait for phy pll lock firstly. */ - pci_imx_phy_pll_locked(imx6_pcie); - regmap_update_bits(imx6_pcie->reg_src, 0x2c, - BIT(6), BIT(6)); - } else { - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, - IMX6Q_GPR12_PCIE_CTL_2); - } + pci_imx_ltssm_enable(dev); ret = imx6_pcie_wait_for_link(imx6_pcie); if (ret < 0) - pr_info("pcie link is down after resume.\n"); - } else { - /* - * L2 can exit by 'reset' or Inband beacon (from remote EP) - * toggling phy_powerdown has same effect as 'inband beacon' - * So, toggle bit18 of GPR1, used as a workaround of errata - * "PCIe PCIe does not support L2 Power Down" - */ - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, - IMX6Q_GPR1_PCIE_TEST_PD, 0); + dev_info(dev, "pcie link is down after resume.\n"); } - return 0; + return ret; } static const struct dev_pm_ops pci_imx_pm_ops = { @@ -1865,11 +1899,12 @@ static int imx6_pcie_probe(struct platform_device *pdev) imx6_pcie->ext_osc = 0; if (imx6_pcie->ext_osc && (imx6_pcie->variant == IMX6QP)) { - imx6_pcie->pcie_ext = devm_clk_get(&pdev->dev, "pcie_ext"); - if (IS_ERR(imx6_pcie->pcie_ext)) { + /* Change the pcie_bus clock to pcie external OSC */ + imx6_pcie->pcie_bus = devm_clk_get(&pdev->dev, "pcie_ext"); + if (IS_ERR(imx6_pcie->pcie_bus)) { dev_err(&pdev->dev, - "pcie_ext clock source missing or invalid\n"); - return PTR_ERR(imx6_pcie->pcie_ext); + "pcie_bus clock source missing or invalid\n"); + return PTR_ERR(imx6_pcie->pcie_bus); } imx6_pcie->pcie_ext_src = devm_clk_get(&pdev->dev, @@ -1993,12 +2028,14 @@ static int imx6_pcie_probe(struct platform_device *pdev) if (ret) imx6_pcie->link_gen = 1; + platform_set_drvdata(pdev, imx6_pcie); + if (IS_ENABLED(CONFIG_EP_MODE_IN_EP_RC_SYS)) { int i; void *test_reg1, *test_reg2; void __iomem *pcie_arb_base_addr; struct timeval tv1s, tv1e, tv2s, tv2e; - u32 val, tv_count1, tv_count2; + u32 tv_count1, tv_count2; struct device_node *np = pp->dev->of_node; LIST_HEAD(res); struct resource_entry *win, *tmp; @@ -2058,40 +2095,22 @@ static int imx6_pcie_probe(struct platform_device *pdev) BIT(19), 0 << 19); /* assert LTSSM enable */ - if (imx6_pcie->variant == IMX8QM - || imx6_pcie->variant == IMX8QXP) { - /* Bit4 of the CTRL2 */ - val = IMX8QM_CSR_PCIEA_OFFSET - + imx6_pcie->ctrl_id * SZ_64K; - regmap_update_bits(imx6_pcie->iomuxc_gpr, - val + IMX8QM_CSR_PCIE_CTRL2_OFFSET, - IMX8QM_CTRL_LTSSM_ENABLE, - IMX8QM_CTRL_LTSSM_ENABLE); - } else if (imx6_pcie->variant == IMX7D) { - regmap_update_bits(imx6_pcie->reg_src, 0x2c, - BIT(6), BIT(6)); - } else { - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, - IMX6Q_GPR12_PCIE_CTL_2, 1 << 10); - } + pci_imx_ltssm_enable(dev); dev_info(&pdev->dev, "PCIe EP: waiting for link up...\n"); - - platform_set_drvdata(pdev, imx6_pcie); /* link is indicated by the bit4 of DB_R1 register */ do { usleep_range(10, 20); } while ((readl(pp->dbi_base + PCIE_PHY_DEBUG_R1) & 0x10) == 0); imx6_pcie_setup_ep(pp); - imx_pcie_regions_setup(&pdev->dev); /* self io test */ test_reg1 = devm_kzalloc(&pdev->dev, test_region_size, GFP_KERNEL); if (!test_reg1) { - pr_err("pcie ep: can't alloc the test reg1.\n"); + dev_err(dev, "pcie ep: can't alloc the test reg1.\n"); ret = PTR_ERR(test_reg1); return ret; } @@ -2099,7 +2118,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) test_reg2 = devm_kzalloc(&pdev->dev, test_region_size, GFP_KERNEL); if (!test_reg2) { - pr_err("pcie ep: can't alloc the test reg2.\n"); + dev_err(dev, "pcie ep: can't alloc the test reg2.\n"); ret = PTR_ERR(test_reg1); return ret; } @@ -2114,7 +2133,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) test_region_size); if (!pcie_arb_base_addr) { - pr_err("error with ioremap in ep selftest\n"); + dev_err(dev, "error with ioremap in ep selftest\n"); ret = PTR_ERR(pcie_arb_base_addr); return ret; } @@ -2125,7 +2144,7 @@ static int imx6_pcie_probe(struct platform_device *pdev) } /* PCIe EP start the data transfer after link up */ - pr_info("pcie ep: Starting data transfer...\n"); + dev_info(dev, "pcie ep: Starting data transfer...\n"); do_gettimeofday(&tv1s); memcpy((unsigned int *)pcie_arb_base_addr, @@ -2149,28 +2168,26 @@ static int imx6_pcie_probe(struct platform_device *pdev) * USEC_PER_SEC + tv2e.tv_usec - tv2s.tv_usec; - pr_info("pcie ep: Data transfer is successful." + dev_info(dev, "pcie ep: Data transfer is successful." " tv_count1 %dus," " tv_count2 %dus.\n", tv_count1, tv_count2); - pr_info("pcie ep: Data write speed:%ldMB/s.\n", + dev_info(dev, "pcie ep: Data write speed:%ldMB/s.\n", ((test_region_size/1024) * MSEC_PER_SEC) /(tv_count1)); - pr_info("pcie ep: Data read speed:%ldMB/s.\n", + dev_info(dev, "pcie ep: Data read speed:%ldMB/s.\n", ((test_region_size/1024) * MSEC_PER_SEC) /(tv_count2)); } else { - pr_info("pcie ep: Data transfer is failed.\n"); + dev_info(dev, "pcie ep: Data transfer is failed.\n"); } /* end of self io test. */ } else { ret = imx6_add_pcie_port(imx6_pcie, pdev); if (ret < 0) return ret; - platform_set_drvdata(pdev, imx6_pcie); - if (IS_ENABLED(CONFIG_RC_MODE_IN_EP_RC_SYS)) imx_pcie_regions_setup(&pdev->dev); } |