aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2014-06-19 21:51:38 -0400
committerRichard Zhu <r65037@freescale.com>2014-06-23 21:49:01 -0400
commitddd7803a15dd195dbc5030dc9acdc6b7a9e95fea (patch)
tree480b5cd458375039da8fb04f696af96bbd2b7e4b
parent8c99f4a76eae6314fe5b5a732b79f053ad70344c (diff)
ENGR00319416 pcie: random link down issue after warm-rst
There are about 0.02% percentage on some imx6q/dl/solo hw boards, random pcie link down when warm-reset is used. Make sure to clear the ref_ssp_en bit16 of gpr1 before warm-rst, and set ref_ssp_en after the pcie clks are stable to workaround it. rootcause: * gpr regisers wouldn't be reset by warm-rst, while the ref_ssp_en is required to be reset by pcie. (work-around in u-boot) * ref_ssp_en should be set after pcie clks are stable. (work-around in kernel) Signed-off-by: Richard Zhu <r65037@freescale.com>
-rw-r--r--drivers/pci/host/pci-imx6.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 6645220911f1..9a378b33fefa 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -261,8 +261,6 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
261 /* Those bits are not used anymore on imx6sx */ 261 /* Those bits are not used anymore on imx6sx */
262 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, 262 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
263 IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18); 263 IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
264 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
265 IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
266 264
267 /* sata_ref is not used by pcie on imx6sx */ 265 /* sata_ref is not used by pcie on imx6sx */
268 ret = clk_prepare_enable(imx6_pcie->sata_ref_100m); 266 ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
@@ -293,6 +291,17 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
293 goto err_pcie_axi; 291 goto err_pcie_axi;
294 } 292 }
295 293
294 if (!is_imx6sx_pcie(imx6_pcie)) {
295 /*
296 * This bit is not used anymore on imx6sx.
297 * wailt for the pcie clks are stable.
298 * ~4us is requried, let it to be 10us here.
299 */
300 udelay(10);
301 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
302 IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
303 }
304
296 if (gpio_is_valid(imx6_pcie->reset_gpio)) { 305 if (gpio_is_valid(imx6_pcie->reset_gpio)) {
297 gpio_set_value(imx6_pcie->reset_gpio, 0); 306 gpio_set_value(imx6_pcie->reset_gpio, 0);
298 mdelay(1); 307 mdelay(1);