mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user