summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorRichard Zhu <r65037@freescale.com>2014-06-20 09:51:38 +0800
committerRichard Zhu <r65037@freescale.com>2014-06-24 09:49:01 +0800
commitddd7803a15dd195dbc5030dc9acdc6b7a9e95fea (patch)
tree480b5cd458375039da8fb04f696af96bbd2b7e4b /drivers/pci
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>
Diffstat (limited to 'drivers/pci')
-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)
/* Those bits are not used anymore on imx6sx */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
IMX6Q_GPR1_PCIE_TEST_PD, 0 << 18);
- regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
- IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
/* sata_ref is not used by pcie on imx6sx */
ret = clk_prepare_enable(imx6_pcie->sata_ref_100m);
@@ -293,6 +291,17 @@ static int imx6_pcie_deassert_core_reset(struct pcie_port *pp)
goto err_pcie_axi;
}
+ if (!is_imx6sx_pcie(imx6_pcie)) {
+ /*
+ * This bit is not used anymore on imx6sx.
+ * wailt for the pcie clks are stable.
+ * ~4us is requried, let it to be 10us here.
+ */
+ udelay(10);
+ regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1,
+ IMX6Q_GPR1_PCIE_REF_CLK_EN, 1 << 16);
+ }
+
if (gpio_is_valid(imx6_pcie->reset_gpio)) {
gpio_set_value(imx6_pcie->reset_gpio, 0);
mdelay(1);