diff options
author | Richard Zhu <r65037@freescale.com> | 2014-06-20 09:51:38 +0800 |
---|---|---|
committer | Richard Zhu <r65037@freescale.com> | 2014-06-24 09:49:01 +0800 |
commit | ddd7803a15dd195dbc5030dc9acdc6b7a9e95fea (patch) | |
tree | 480b5cd458375039da8fb04f696af96bbd2b7e4b /drivers/pci | |
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>
Diffstat (limited to 'drivers/pci')
-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) /* 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); |