From 098e4100da724481e9cf117ec87aa29fd7680feb Mon Sep 17 00:00:00 2001 From: Philipp Tomsich Date: Tue, 16 Jun 2015 10:12:34 +0200 Subject: ARM: sun6i: Initialize PLL6 to 600MHz This replaces the previous initialization of PLL6 using a magic value instead of a properly constructed setting for 600MHz and documents the recommendation/requirement to have PLL6 operating at 600MHz. The following issues with the original intialization sequence are fixed with this: * we now wait for PLL6 to lock, before proceeding * we no longer write the lock-bit (which is specified R/O) * we don't write the (unused) bits where other PLLs have their divider configuration field --- arch/arm/cpu/armv7/sunxi/clock_sun6i.c | 26 +++++++++++++++++++++++++- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 9 +++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c index 2986539625..fa7ebd8060 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun6i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun6i.c @@ -36,7 +36,8 @@ void clock_init_safe(void) writel(AHB1_ABP1_DIV_DEFAULT, &ccm->ahb1_apb1_div); - writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); + /* Enable PLL6 at 600MHz */ + clock_pll6_init(); writel(MBUS_CLK_DEFAULT, &ccm->mbus0_clk_cfg); writel(MBUS_CLK_DEFAULT, &ccm->mbus1_clk_cfg); @@ -181,6 +182,29 @@ void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) wait_for_pll_lock(&ccm->pll5_cfg); } +void clock_pll6_init() +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* The A31 reference manual states, that "the PLL6 output + * should be fixed to 600MHz, and is not recommended to be + * modified.". + * + * We always configure this to N=25 and K=2 for 600Mhz: + * 600MHz = 24MHz x N(25) x K(2) / 2 + * + * N.B.: The lowest 2 bits need to be writte 01b (0x1), + * as the fixed divider doesn't seem to be fixed. + */ + writel(CCM_PLL6_CTRL_EN | CCM_PLL6_CTRL_24M_OUT_EN | + CCM_PLL6_CTRL_N(25) | CCM_PLL6_CTRL_K(2) | + CCM_PLL6_CTRL_M(2), + &ccm->pll6_cfg); + + wait_for_pll_lock(&ccm->pll6_cfg); +} + #ifdef CONFIG_MACH_SUN8I_A33 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) { diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 0962c819e0..17774cba60 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -193,13 +193,17 @@ struct sunxi_ccm_reg { #define CCM_PLL5_CTRL_SIGMA_DELTA_EN (0x1 << 24) #define CCM_PLL5_CTRL_EN (0x1 << 31) -#define PLL6_CFG_DEFAULT 0x90041811 /* 600 MHz */ - #define CCM_PLL6_CTRL_N_SHIFT 8 #define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) #define CCM_PLL6_CTRL_K_SHIFT 4 #define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) +#define CCM_PLL6_CTRL_M(n) ((((n) - 1) & 0x3) << 0) +#define CCM_PLL6_CTRL_K(n) ((((n) - 1) & 0x3) << 4) +#define CCM_PLL6_CTRL_N(n) ((((n) - 1) & 0x1f) << 8) +#define CCM_PLL6_CTRL_24M_OUT_EN (0x1 << 18) +#define CCM_PLL6_CTRL_EN (0x1 << 31) + #define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) #define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) #define CCM_PLL11_CTRL_UPD (0x1 << 30) @@ -360,6 +364,7 @@ struct sunxi_ccm_reg { void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); +void clock_pll6_init(void); void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); unsigned int clock_get_pll6(void); #endif -- cgit v1.2.3