diff options
author | Richard Zhu <r65037@freescale.com> | 2014-06-19 21:51:38 -0400 |
---|---|---|
committer | Richard Zhu <r65037@freescale.com> | 2014-06-23 21:49:01 -0400 |
commit | ddd7803a15dd195dbc5030dc9acdc6b7a9e95fea (patch) | |
tree | 480b5cd458375039da8fb04f696af96bbd2b7e4b | |
parent | 8c99f4a76eae6314fe5b5a732b79f053ad70344c (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.c | 13 |
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); |