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 <jian.hu@amlogic.com>
This commit is contained in:
Jian Hu
2019-09-06 19:47:02 +08:00
committed by Tao Zeng
parent 4a0dc752bd
commit cd6e01682d

View File

@@ -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);