ENGR00319415 pcie: random link down issue after warm-rst
authorRichard Zhu <r65037@freescale.com>
Tue, 24 Jun 2014 01:59:47 +0000 (09:59 +0800)
committerYe Li <ye.li@nxp.com>
Wed, 28 Apr 2021 20:49:34 +0000 (13:49 -0700)
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.

imx6sl doesn't have the pcie module, mask the pcie
related codes from imx6sl.

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>
(cherry picked from commit 5cc825b12c6b86a22f1a6a0535b52cf3ee142e77)
Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
(cherry picked from commit 6193cf4e3384a59e29546d13a67657f7faeafc9e)
(cherry picked from commit 7b4aabeddffabca46d7d6e7ef2611de468a6b4f7)
(cherry picked from commit a117fc7b2b8d930fd7a47b168c4638365cb3a475)
(cherry picked from commit d94a5b283afd2786428f514b0db4a6eaa5bcccff)
(cherry picked from commit 9ee86b956916432e0a27afc31d29933705d4a675)

arch/arm/mach-imx/mx6/soc.c

index 1533792..ce4f4a3 100644 (file)
@@ -447,6 +447,29 @@ int arch_cpu_init(void)
 {
        struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 
+       if (!is_mx6sl() && !is_mx6sx()
+               && !is_mx6ul() && !is_mx6ull()
+               && !is_mx6sll()) {
+               /*
+                * imx6sl doesn't have pcie at all.
+                * this bit is not used by imx6sx anymore
+                */
+               u32 val;
+
+               /*
+                * There are about 0.02% percentage, random pcie link down
+                * when warm-reset is used.
+                * clear the ref_ssp_en bit16 of gpr1 to workaround it.
+                * then warm-reset imx6q/dl/solo again.
+                */
+               val = readl(IOMUXC_BASE_ADDR + 0x4);
+               if (val & (0x1 << 16)) {
+                       val &= ~(0x1 << 16);
+                       writel(val, IOMUXC_BASE_ADDR + 0x4);
+                       reset_cpu(0);
+               }
+       }
+
        init_aips();
 
        /* Need to clear MMDC_CHx_MASK to make warm reset work. */