summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2017-11-14 10:22:16 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit80781537383e8873ab93d18c338ea0331525bdd0 (patch)
treec8e55ee9e985079b53e91d16134bd5cb3b64706f /drivers/pci
parent2c532b744315142f11bb9dad995d71caf7b49d35 (diff)
MLK-16777 PCI: imx: enable pcie pm on mscale
Enable the PCIE PM on mScale. - Refine the codes. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-imx6.c419
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);
}