summaryrefslogtreecommitdiff
path: root/drivers/pci/host/pci-imx6.c
diff options
context:
space:
mode:
authorRichard Zhu <hongxing.zhu@nxp.com>2017-03-07 09:11:12 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit38ed2b805c2b787bcf4fb6f1e454a375643a8b61 (patch)
tree076bcb661a31e74d0754444bb7c1b5644635350d /drivers/pci/host/pci-imx6.c
parentff5a5725e758ad8987433704c5134108ef4b65a2 (diff)
MLK-14325-2 PCI: imx: enable pcie on 4.9 kernel
- Do not return error when the GEN2 link negatiation is failed. Because that the limitation maybe caused by the remote GEN1 EP device. - Move the power saving codes to the proper place after the link is down. Otherwise, system would hang when link is down. Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Diffstat (limited to 'drivers/pci/host/pci-imx6.c')
-rw-r--r--drivers/pci/host/pci-imx6.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 8bb8bc24503e..57d880a0c2b2 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -463,9 +463,10 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value_cansleep(imx6_pcie->reset_gpio,
imx6_pcie->gpio_active_high);
- msleep(100);
+ mdelay(20);
gpio_set_value_cansleep(imx6_pcie->reset_gpio,
!imx6_pcie->gpio_active_high);
+ mdelay(20);
}
switch (imx6_pcie->variant) {
@@ -477,28 +478,28 @@ static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie)
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_SW_RST, 0);
- usleep_range(200, 500);
+ udelay(200);
/* Configure the PHY when 100Mhz external OSC is used as input clock */
if (!imx6_pcie->ext_osc)
break;
mdelay(4);
- pcie_phy_read(pp->dbi_base, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, &val);
+ pcie_phy_read(imx6_pcie, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, &val);
/* MPLL_MULTIPLIER [8:2] */
val &= ~(0x7F << 2);
val |= (0x19 << 2);
/* MPLL_MULTIPLIER_OVRD [9:9] */
val |= (0x1 << 9);
- pcie_phy_write(pp->dbi_base, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, val);
+ pcie_phy_write(imx6_pcie, SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO, val);
mdelay(4);
- pcie_phy_read(pp->dbi_base, SSP_CR_SUP_DIG_ATEOVRD, &val);
+ pcie_phy_read(imx6_pcie, SSP_CR_SUP_DIG_ATEOVRD, &val);
/* ref_clkdiv2 [0:0] */
val &= ~0x1;
/* ateovrd_en [2:2] */
val |= 0x4;
- pcie_phy_write(pp->dbi_base, SSP_CR_SUP_DIG_ATEOVRD, val);
+ pcie_phy_write(imx6_pcie, SSP_CR_SUP_DIG_ATEOVRD, val);
mdelay(4);
break;
@@ -642,21 +643,6 @@ static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
dev_dbg(dev, "DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
-
- if (!IS_ENABLED(CONFIG_PCI_IMX6_COMPLIANCE_TEST)) {
- clk_disable_unprepare(imx6_pcie->pcie);
- if (!imx6_pcie->ext_osc)
- clk_disable_unprepare(imx6_pcie->pcie_bus);
- clk_disable_unprepare(imx6_pcie->pcie_phy);
- if (imx6_pcie->variant == IMX6SX)
- clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
- release_bus_freq(BUS_FREQ_HIGH);
- 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 -ETIMEDOUT;
}
@@ -672,7 +658,7 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
/* Test if the speed change finished. */
if (!(tmp & PORT_LOGIC_SPEED_CHANGE))
return 0;
- usleep_range(100, 1000);
+ udelay(100);
}
dev_err(dev, "Speed change timeout\n");
@@ -727,6 +713,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
dw_pcie_writel_rc(pp, PCIE_RC_LCR, tmp);
} else {
dev_info(dev, "Link: Gen2 disabled\n");
+ goto out;
}
/*
@@ -739,8 +726,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
ret = imx6_pcie_wait_for_speed_change(imx6_pcie);
if (ret) {
- dev_err(dev, "Failed to bring link up!\n");
- goto err_reset_phy;
+ dev_info(dev, "Roll back to GEN1 link!\n");
}
/* Make sure link training is finished as well! */
@@ -750,6 +736,7 @@ static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
goto err_reset_phy;
}
+out:
tmp = dw_pcie_readl_rc(pp, PCIE_RC_LCSR);
dev_info(dev, "Link up, Gen%i\n", (tmp >> 16) & 0xf);
return 0;
@@ -759,6 +746,21 @@ err_reset_phy:
dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R0),
dw_pcie_readl_rc(pp, PCIE_PHY_DEBUG_R1));
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)
+ clk_disable_unprepare(imx6_pcie->pcie_bus);
+ clk_disable_unprepare(imx6_pcie->pcie_phy);
+ if (imx6_pcie->variant == IMX6SX)
+ clk_disable_unprepare(imx6_pcie->pcie_inbound_axi);
+ release_bus_freq(BUS_FREQ_HIGH);
+ 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 ret;
}