summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2015-01-06 15:44:00 +0100
committerKlaus Goger <klaus.goger@theobroma-systems.com>2015-07-30 18:44:04 +0200
commit49b7887bbef2bb243229b04c0422465a1ae7f8a8 (patch)
tree97fa34e1d0e19f3b54bb9a3c21cf34448b41f5d8
parent33711bdd4a4dce942fb5ae85a68899a8357bdd94 (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.c14
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h2
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)