diff options
author | Philipp Tomsich <philipp.tomsich@theobroma-systems.com> | 2015-01-06 15:44:00 +0100 |
---|---|---|
committer | Klaus Goger <klaus.goger@theobroma-systems.com> | 2015-07-30 18:44:04 +0200 |
commit | 49b7887bbef2bb243229b04c0422465a1ae7f8a8 (patch) | |
tree | 97fa34e1d0e19f3b54bb9a3c21cf34448b41f5d8 | |
parent | 33711bdd4a4dce942fb5ae85a68899a8357bdd94 (diff) |
ARM: sun6i: Wait for PLL lock bit on PLL update
This unifies the handling of PLL updates for sun6i (A31) by waiting
for the PLL lock bit of an updated PLL. This changes the previous
practice of either waiting for a "magic" duration using sdelay()
or not waiting at all.
Note, that we can't use a timer-based timeout, as the PLL update
may affect the timekeeping.
-rw-r--r-- | arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 14 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 2 |
2 files changed, 14 insertions, 2 deletions
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 3bfa122ec0..cfb32b4323 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -89,6 +89,13 @@ int clock_twi_onoff(int port, int state) return 0; } +static inline void wait_for_pll_lock(u32 *reg) +{ + do { + /* spin */ + } while ((readl(reg) & CCM_PLLx_CTRL_LOCK) != CCM_PLLx_CTRL_LOCK); +} + #ifdef CONFIG_SPL_BUILD void clock_set_pll1(unsigned int clk) { @@ -118,7 +125,8 @@ void clock_set_pll1(unsigned int clk) writel(CCM_PLL1_CTRL_EN | CCM_PLL1_CTRL_P(p) | CCM_PLL1_CTRL_N(clk / (24000000 * k / m)) | CCM_PLL1_CTRL_K(k) | CCM_PLL1_CTRL_M(m), &ccm->pll1_cfg); - sdelay(200); + + wait_for_pll_lock(&ccm->pll1_cfg); /* Switch CPU to PLL1 */ writel(AXI_DIV_3 << AXI_DIV_SHIFT | @@ -143,6 +151,8 @@ void clock_set_pll3(unsigned int clk) writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | CCM_PLL3_CTRL_N(clk / (24000000 / m)) | CCM_PLL3_CTRL_M(m), &ccm->pll3_cfg); + + wait_for_pll_lock(&ccm->pll3_cfg); } void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) @@ -167,7 +177,7 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) CCM_PLL5_CTRL_N(clk / (24000000 * k / m)) | CCM_PLL5_CTRL_K(k) | CCM_PLL5_CTRL_M(m), &ccm->pll5_cfg); - udelay(5500); + wait_for_pll_lock(&ccm->pll5_cfg); } #ifdef CONFIG_MACH_SUN8I_A33 diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 8a26b9fc51..0962c819e0 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -173,6 +173,8 @@ struct sunxi_ccm_reg { #define CPU_CLK_SRC_OSC24M 1 #define CPU_CLK_SRC_PLL1 2 +#define CCM_PLLx_CTRL_LOCK (0x1 << 28) + #define CCM_PLL1_CTRL_M(n) ((((n) - 1) & 0x3) << 0) #define CCM_PLL1_CTRL_K(n) ((((n) - 1) & 0x3) << 4) #define CCM_PLL1_CTRL_N(n) ((((n) - 1) & 0x1f) << 8) |