From cd6e01682d0a22a7b33028b3fbb6fe42b5620507 Mon Sep 17 00:00:00 2001 From: Jian Hu Date: Fri, 6 Sep 2019 19:47:02 +0800 Subject: [PATCH] clk: tm2: fix pcie pll lock failed [1/1] PD#SWPL-11934 Problem: pcie pll lock failed some times Solution: 1.add retry mechanism when pcie lock failed 2.add protection mechanism for all plls Verify: test passed on tm2 ab311 Change-Id: Id34e87d84e2bc2368c074556f500f8af1f2a4088 Signed-off-by: Jian Hu --- drivers/amlogic/clk/tl1/tl1_clk-pll.c | 216 ++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 104 deletions(-) diff --git a/drivers/amlogic/clk/tl1/tl1_clk-pll.c b/drivers/amlogic/clk/tl1/tl1_clk-pll.c index 473e644..b08c29f 100644 --- a/drivers/amlogic/clk/tl1/tl1_clk-pll.c +++ b/drivers/amlogic/clk/tl1/tl1_clk-pll.c @@ -231,6 +231,7 @@ static int meson_tl1_pll_set_rate(struct clk_hw *hw, unsigned long rate, u32 reg; unsigned long flags = 0; void *cntlbase; + int j = 10; if (parent_rate == 0 || rate == 0) return -EINVAL; @@ -263,110 +264,117 @@ static int meson_tl1_pll_set_rate(struct clk_hw *hw, unsigned long rate, cntlbase = pll->base + p->reg_off; - - if (!strcmp(clk_hw_get_name(hw), "sys_pll")) { - writel((readl(cntlbase) | MESON_PLL_RESET) - & (~MESON_PLL_ENABLE), cntlbase); - writel(TL1_SYS_PLL_CNTL1, - cntlbase + (unsigned long)(1*4)); - writel(TL1_SYS_PLL_CNTL2, - cntlbase + (unsigned long)(2*4)); - writel(TL1_SYS_PLL_CNTL3, - cntlbase + (unsigned long)(3*4)); - writel(TL1_SYS_PLL_CNTL4, - cntlbase + (unsigned long)(4*4)); - writel(TL1_SYS_PLL_CNTL5, - cntlbase + (unsigned long)(5*4)); - writel(TL1_PLL_CNTL6, - cntlbase + (unsigned long)(6*4)); - udelay(10); - } else if (!strcmp(clk_hw_get_name(hw), "gp0_pll") || - !strcmp(clk_hw_get_name(hw), "gp1_pll")) { - writel((readl(cntlbase) | MESON_PLL_RESET) - & (~MESON_PLL_ENABLE), cntlbase); - writel(TL1_GP0_PLL_CNTL1, - cntlbase + (unsigned long)(1*4)); - writel(TL1_GP0_PLL_CNTL2, - cntlbase + (unsigned long)(2*4)); - writel(TL1_GP0_PLL_CNTL3, - cntlbase + (unsigned long)(3*4)); - writel(TL1_GP0_PLL_CNTL4, - cntlbase + (unsigned long)(4*4)); - writel(TL1_GP0_PLL_CNTL5, - cntlbase + (unsigned long)(5*4)); - writel(TL1_PLL_CNTL6, - cntlbase + (unsigned long)(6*4)); - udelay(10); - } else if (!strcmp(clk_hw_get_name(hw), "hifi_pll")) { - writel((readl(cntlbase) | MESON_PLL_RESET) - & (~MESON_PLL_ENABLE), cntlbase); - writel(TL1_HIFI_PLL_CNTL1, - cntlbase + (unsigned long)(1*4)); - writel(TL1_HIFI_PLL_CNTL2, - cntlbase + (unsigned long)(2*4)); - writel(TL1_HIFI_PLL_CNTL3, - cntlbase + (unsigned long)(3*4)); - writel(TL1_HIFI_PLL_CNTL4, - cntlbase + (unsigned long)(4*4)); - writel(TL1_HIFI_PLL_CNTL5, - cntlbase + (unsigned long)(5*4)); - writel(TL1_PLL_CNTL6, - cntlbase + (unsigned long)(6*4)); - udelay(10); - } else if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { - writel(TM2_PCIE_PLL_CNTL0_0, - cntlbase + (unsigned long)(0*4)); - writel(TM2_PCIE_PLL_CNTL0_1, - cntlbase + (unsigned long)(0*4)); - writel(TM2_PCIE_PLL_CNTL1, - cntlbase + (unsigned long)(1*4)); - writel(TM2_PCIE_PLL_CNTL2, - cntlbase + (unsigned long)(7*4)); - writel(TM2_PCIE_PLL_CNTL3, - cntlbase + (unsigned long)(8*4)); - writel(TM2_PCIE_PLL_CNTL4, - cntlbase + (unsigned long)(53*4)); - writel(TM2_PCIE_PLL_CNTL5, - cntlbase + (unsigned long)(54*4)); - writel(TM2_PCIE_PLL_CNTL5_, - cntlbase + (unsigned long)(54*4)); - udelay(20); - writel(TM2_PCIE_PLL_CNTL4_, - cntlbase + (unsigned long)(53*4)); - udelay(10); - /*set pcie_apll_afc_start bit*/ - writel(TM2_PCIE_PLL_CNTL0_2, - cntlbase + (unsigned long)(0*4)); - writel(TM2_PCIE_PLL_CNTL0_3, - cntlbase + (unsigned long)(0*4)); - udelay(20); - writel(TM2_PCIE_PLL_CNTL0_4, - cntlbase + (unsigned long)(0*4)); - writel(TM2_PCIE_PLL_CNTL2_, - cntlbase + (unsigned long)(7*4)); - } else if (!strcmp(clk_hw_get_name(hw), "fixed_pll")) { - writel((readl(cntlbase) | MESON_PLL_RESET) - & (~MESON_PLL_ENABLE), cntlbase); - - udelay(100); - writel(TL1_FIXED_PLL_CNTL1, - cntlbase + (unsigned long)(1*4)); - writel(TL1_FIXED_PLL_CNTL2, - cntlbase + (unsigned long)(2*4)); - writel(TL1_FIXED_PLL_CNTL3, - cntlbase + (unsigned long)(3*4)); - writel(TL1_FIXED_PLL_CNTL4, - cntlbase + (unsigned long)(4*4)); - writel(TL1_FIXED_PLL_CNTL5, - cntlbase + (unsigned long)(5*4)); - writel(TL1_FIXED_PLL_CNTL6, - cntlbase + (unsigned long)(6*4)); - udelay(10); - } else { - pr_err("%s: %s pll not found!!!\n", - __func__, clk_hw_get_name(hw)); - return -EINVAL; - } + do { + if (!strcmp(clk_hw_get_name(hw), "sys_pll")) { + writel((readl(cntlbase) | MESON_PLL_RESET) + & (~MESON_PLL_ENABLE), cntlbase); + writel(TL1_SYS_PLL_CNTL1, + cntlbase + (unsigned long)(1 * 4)); + writel(TL1_SYS_PLL_CNTL2, + cntlbase + (unsigned long)(2 * 4)); + writel(TL1_SYS_PLL_CNTL3, + cntlbase + (unsigned long)(3 * 4)); + writel(TL1_SYS_PLL_CNTL4, + cntlbase + (unsigned long)(4 * 4)); + writel(TL1_SYS_PLL_CNTL5, + cntlbase + (unsigned long)(5 * 4)); + writel(TL1_PLL_CNTL6, + cntlbase + (unsigned long)(6 * 4)); + udelay(10); + } else if (!strcmp(clk_hw_get_name(hw), "gp0_pll") || + !strcmp(clk_hw_get_name(hw), "gp1_pll")) { + writel((readl(cntlbase) | MESON_PLL_RESET) + & (~MESON_PLL_ENABLE), cntlbase); + writel(TL1_GP0_PLL_CNTL1, + cntlbase + (unsigned long)(1 * 4)); + writel(TL1_GP0_PLL_CNTL2, + cntlbase + (unsigned long)(2 * 4)); + writel(TL1_GP0_PLL_CNTL3, + cntlbase + (unsigned long)(3 * 4)); + writel(TL1_GP0_PLL_CNTL4, + cntlbase + (unsigned long)(4 * 4)); + writel(TL1_GP0_PLL_CNTL5, + cntlbase + (unsigned long)(5 * 4)); + writel(TL1_PLL_CNTL6, + cntlbase + (unsigned long)(6 * 4)); + udelay(10); + } else if (!strcmp(clk_hw_get_name(hw), "hifi_pll")) { + writel((readl(cntlbase) | MESON_PLL_RESET) + & (~MESON_PLL_ENABLE), cntlbase); + writel(TL1_HIFI_PLL_CNTL1, + cntlbase + (unsigned long)(1 * 4)); + writel(TL1_HIFI_PLL_CNTL2, + cntlbase + (unsigned long)(2 * 4)); + writel(TL1_HIFI_PLL_CNTL3, + cntlbase + (unsigned long)(3 * 4)); + writel(TL1_HIFI_PLL_CNTL4, + cntlbase + (unsigned long)(4 * 4)); + writel(TL1_HIFI_PLL_CNTL5, + cntlbase + (unsigned long)(5 * 4)); + writel(TL1_PLL_CNTL6, + cntlbase + (unsigned long)(6 * 4)); + udelay(10); + } else if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) { + writel(TM2_PCIE_PLL_CNTL0_0, + cntlbase + (unsigned long)(0 * 4)); + writel(TM2_PCIE_PLL_CNTL0_1, + cntlbase + (unsigned long)(0 * 4)); + writel(TM2_PCIE_PLL_CNTL1, + cntlbase + (unsigned long)(1 * 4)); + writel(TM2_PCIE_PLL_CNTL2, + cntlbase + (unsigned long)(7 * 4)); + writel(TM2_PCIE_PLL_CNTL3, + cntlbase + (unsigned long)(8 * 4)); + writel(TM2_PCIE_PLL_CNTL4, + cntlbase + (unsigned long)(53 * 4)); + writel(TM2_PCIE_PLL_CNTL5, + cntlbase + (unsigned long)(54 * 4)); + writel(TM2_PCIE_PLL_CNTL5_, + cntlbase + (unsigned long)(54 * 4)); + udelay(20); + writel(TM2_PCIE_PLL_CNTL4_, + cntlbase + (unsigned long)(53 * 4)); + udelay(10); + /*set pcie_apll_afc_start bit*/ + writel(TM2_PCIE_PLL_CNTL0_2, + cntlbase + (unsigned long)(0 * 4)); + writel(TM2_PCIE_PLL_CNTL0_3, + cntlbase + (unsigned long)(0 * 4)); + udelay(20); + writel(TM2_PCIE_PLL_CNTL0_4, + cntlbase + (unsigned long)(0 * 4)); + writel(TM2_PCIE_PLL_CNTL2_, + cntlbase + (unsigned long)(7 * 4)); + } else if (!strcmp(clk_hw_get_name(hw), "fixed_pll")) { + writel((readl(cntlbase) | MESON_PLL_RESET) + & (~MESON_PLL_ENABLE), cntlbase); + udelay(100); + writel(TL1_FIXED_PLL_CNTL1, + cntlbase + (unsigned long)(1 * 4)); + writel(TL1_FIXED_PLL_CNTL2, + cntlbase + (unsigned long)(2 * 4)); + writel(TL1_FIXED_PLL_CNTL3, + cntlbase + (unsigned long)(3 * 4)); + writel(TL1_FIXED_PLL_CNTL4, + cntlbase + (unsigned long)(4 * 4)); + writel(TL1_FIXED_PLL_CNTL5, + cntlbase + (unsigned long)(5 * 4)); + writel(TL1_FIXED_PLL_CNTL6, + cntlbase + (unsigned long)(6 * 4)); + udelay(10); + } else { + pr_err("%s: %s pll not found!!!\n", + __func__, clk_hw_get_name(hw)); + return -EINVAL; + } + /* waiting for 50us to check is locked or not */ + udelay(50); + /* lock bit is in the cntlbase */ + if (readl(cntlbase + (unsigned long)(0 * 4)) + & MESON_PLL_LOCK) + break; + j--; + } while (j); reg = readl(pll->base + p->reg_off); -- 2.7.4