summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Tomsich <philipp.tomsich@theobroma-systems.com>2015-06-16 10:12:34 +0200
committerKlaus Goger <klaus.goger@theobroma-systems.com>2015-07-30 18:44:04 +0200
commit098e4100da724481e9cf117ec87aa29fd7680feb (patch)
tree216f4bb772a8453e09003a1a33e36e863ef5881c
parenta58eb20fb80f478038243e9e0f30f6984725e265 (diff)
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
-rw-r--r--arch/arm/cpu/armv7/sunxi/clock_sun6i.c26
-rw-r--r--arch/arm/include/asm/arch-sunxi/clock_sun6i.h9
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