[U-Boot] [PATCH 1/3] sunxi: Add clock_get_pll5p() function

This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 11 +++++++++++ arch/arm/include/asm/arch-sunxi/clock.h | 1 + arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 3 +++ 3 files changed, 15 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c index ecbdb01..4a0d64f 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c @@ -180,6 +180,17 @@ void clock_set_pll1(unsigned int hz) } #endif
+unsigned int clock_get_pll5p(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + uint32_t rval = readl(&ccm->pll5_cfg); + int n = ((rval & CCM_PLL5_CTRL_N_MASK) >> CCM_PLL5_CTRL_N_SHIFT); + int k = ((rval & CCM_PLL5_CTRL_K_MASK) >> CCM_PLL5_CTRL_K_SHIFT) + 1; + int p = ((rval & CCM_PLL5_CTRL_P_MASK) >> CCM_PLL5_CTRL_P_SHIFT); + return (24000000 * n * k) >> p; +} + unsigned int clock_get_pll6(void) { struct sunxi_ccm_reg *const ccm = diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h index 8f5d860..9775c85 100644 --- a/arch/arm/include/asm/arch-sunxi/clock.h +++ b/arch/arm/include/asm/arch-sunxi/clock.h @@ -25,6 +25,7 @@ int clock_init(void); int clock_twi_onoff(int port, int state); void clock_set_pll1(unsigned int hz); +unsigned int clock_get_pll5p(void); unsigned int clock_get_pll6(void); void clock_init_safe(void); void clock_init_uart(void); diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h index 1ba997a..90af8e2 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h @@ -199,13 +199,16 @@ struct sunxi_ccm_reg { #define CCM_PLL5_CTRL_M1_MASK CCM_PLL5_CTRL_M1(0x3) #define CCM_PLL5_CTRL_M1_X(n) ((n) - 1) #define CCM_PLL5_CTRL_K(n) (((n) & 0x3) << 4) +#define CCM_PLL5_CTRL_K_SHIFT 4 #define CCM_PLL5_CTRL_K_MASK CCM_PLL5_CTRL_K(0x3) #define CCM_PLL5_CTRL_K_X(n) ((n) - 1) #define CCM_PLL5_CTRL_LDO (0x1 << 7) #define CCM_PLL5_CTRL_N(n) (((n) & 0x1f) << 8) +#define CCM_PLL5_CTRL_N_SHIFT 8 #define CCM_PLL5_CTRL_N_MASK CCM_PLL5_CTRL_N(0x1f) #define CCM_PLL5_CTRL_N_X(n) (n) #define CCM_PLL5_CTRL_P(n) (((n) & 0x3) << 16) +#define CCM_PLL5_CTRL_P_SHIFT 16 #define CCM_PLL5_CTRL_P_MASK CCM_PLL5_CTRL_P(0x3) #define CCM_PLL5_CTRL_P_X(n) ((n) - 1) #define CCM_PLL5_CTRL_BW (0x1 << 18)

This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/dram.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 584f742..0cbcf57 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -252,15 +252,9 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) { u32 reg_val; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - - /* PLL5P and PLL6 are the potential clock sources for MBUS */ - u32 pll6x_div, pll5p_div; - u32 pll6x_clk = clock_get_pll6() / 1000000; - u32 pll5p_clk = clk / 24 * 48; + u32 pll5p_clk, pll6x_clk; + u32 pll5p_div, pll6x_div; u32 pll5p_rate, pll6x_rate; -#ifdef CONFIG_SUN7I - pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */ -#endif
/* setup DRAM PLL */ reg_val = readl(&ccm->pll5_cfg); @@ -269,32 +263,27 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) reg_val &= ~CCM_PLL5_CTRL_N_MASK; /* set N to 0 (x0) */ reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ if (clk >= 540 && clk < 552) { - /* dram = 540MHz, pll5p = 1080MHz */ - pll5p_clk = 1080; + /* dram = 540MHz */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(15)); } else if (clk >= 512 && clk < 528) { - /* dram = 512MHz, pll5p = 1536MHz */ - pll5p_clk = 1536; + /* dram = 512MHz */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(4)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(16)); } else if (clk >= 496 && clk < 504) { - /* dram = 496MHz, pll5p = 1488MHz */ - pll5p_clk = 1488; + /* dram = 496MHz */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(3)); reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(31)); } else if (clk >= 468 && clk < 480) { - /* dram = 468MHz, pll5p = 936MHz */ - pll5p_clk = 936; + /* dram = 468MHz */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(13)); } else if (clk >= 396 && clk < 408) { - /* dram = 396MHz, pll5p = 792MHz */ - pll5p_clk = 792; + /* dram = 396MHz */ reg_val |= CCM_PLL5_CTRL_M(CCM_PLL5_CTRL_M_X(2)); reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(3)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(11)); @@ -322,6 +311,13 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) /* setup MBUS clock */ if (!mbus_clk) mbus_clk = 300; + + /* PLL5P and PLL6 are the potential clock sources for MBUS */ + pll6x_clk = clock_get_pll6() / 1000000; +#ifdef CONFIG_SUN7I + pll6x_clk *= 2; /* sun7i uses PLL6*2, sun5i uses just PLL6 */ +#endif + pll5p_clk = clock_get_pll5p() / 1000000; pll6x_div = DIV_ROUND_UP(pll6x_clk, mbus_clk); pll5p_div = DIV_ROUND_UP(pll5p_clk, mbus_clk); pll6x_rate = pll6x_clk / pll6x_div;

On Wed, 2014-10-22 at 15:44 +0200, Hans de Goede wrote:
This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk

Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.
Signed-off-by: Hans de Goede hdegoede@redhat.com --- arch/arm/cpu/armv7/sunxi/dram.c | 4 ++++ board/sunxi/Kconfig | 7 +++++++ 2 files changed, 11 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 0cbcf57..c0dc456 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -293,6 +293,10 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); } +#ifdef CONFIG_OLD_KERNEL_COMPAT + /* Old kernels are hardcoded to P=1 (divide by 2) */ + reg_val |= CCM_PLL5_CTRL_P(1); +#endif reg_val &= ~CCM_PLL5_CTRL_VCO_GAIN; /* PLL VCO Gain off */ reg_val |= CCM_PLL5_CTRL_EN; /* PLL On */ writel(reg_val, &ccm->pll5_cfg); diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 66261fc..0331088 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -19,6 +19,13 @@ config SYS_SOC config FDTFILE string "Default fdtfile env setting for this board"
+config OLD_KERNEL_COMPAT + boolean "Enable workarounds for booting old kernels" + default n + ---help--- + Set this to enable various workarounds for old kernels, this results in + sub-optimal settings for newer kernels, only enable if needed. + config MMC0_CD_PIN string "Card detect pin for mmc0" default ""

On Wed, 2014-10-22 at 15:44 +0200, Hans de Goede wrote:
Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.
Signed-off-by: Hans de Goede hdegoede@redhat.com
arch/arm/cpu/armv7/sunxi/dram.c | 4 ++++ board/sunxi/Kconfig | 7 +++++++ 2 files changed, 11 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 0cbcf57..c0dc456 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -293,6 +293,10 @@ static void mctl_setup_dram_clock(u32 clk, u32 mbus_clk) reg_val |= CCM_PLL5_CTRL_K(CCM_PLL5_CTRL_K_X(2)); reg_val |= CCM_PLL5_CTRL_N(CCM_PLL5_CTRL_N_X(clk / 24)); } +#ifdef CONFIG_OLD_KERNEL_COMPAT
- /* Old kernels are hardcoded to P=1 (divide by 2) */
- reg_val |= CCM_PLL5_CTRL_P(1);
+#endif
I think this would be better placed above the if/else ladder, just next to the: reg_val &= ~CCM_PLL5_CTRL_P_MASK; /* set P to 0 (x1) */ i.e. keep the frobbings of P in the same place.
Ian.

On Wed, Oct 22, 2014 at 03:44:36PM +0200, Hans de Goede wrote:
Add a Kconfig option which users can select when they want to boot older kernels, e.g. the linux-sunxi 3.4 kernels. For now this just forces the pll5 "p" value to 1 (divide by 2) as that is what those kernels are hardcoded too, in the future this may enable further workarounds.
Conceptually fine, but please do CONFIG_OLD_SUNXI_KERNEL_COMPAT so that we don't start using this symbol more broadly and so it's clear where exactly it's compat for. Thanks!

On Wed, 2014-10-22 at 15:44 +0200, Hans de Goede wrote:
This is a preparation patch for making the pll5 "p" divisor configurable through Kconfig.
Signed-off-by: Hans de Goede hdegoede@redhat.com
Acked-by: Ian Campbell ijc@hellion.org.uk
participants (3)
-
Hans de Goede
-
Ian Campbell
-
Tom Rini