[U-Boot] [PATCH v2 1/3] sunxi: sun4i: improve cpu clock selection method

clock_set_pll1 would pick the next highest available cpu clock speed if a value not in the pre defined table was selected. this potentially results in overclocking the soc.
reverse the selection method so that we select the next lowest speed and add the missing 912Mhz setting that's requested by sun7i which also uses the sun4i clock code.
Signed-off-by: Iain Paton ipaton0@gmail.com --- arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 35 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c index 49f4032..c3e04af 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c @@ -100,22 +100,23 @@ static struct { unsigned int freq; } pll1_para[] = { /* This array must be ordered by frequency. */ - { PLL1_CFG(16, 0, 0, 0), 384000000 }, - { PLL1_CFG(16, 1, 0, 0), 768000000 }, - { PLL1_CFG(20, 1, 0, 0), 960000000 }, - { PLL1_CFG(21, 1, 0, 0), 1008000000}, - { PLL1_CFG(22, 1, 0, 0), 1056000000}, - { PLL1_CFG(23, 1, 0, 0), 1104000000}, - { PLL1_CFG(24, 1, 0, 0), 1152000000}, - { PLL1_CFG(25, 1, 0, 0), 1200000000}, - { PLL1_CFG(26, 1, 0, 0), 1248000000}, - { PLL1_CFG(27, 1, 0, 0), 1296000000}, - { PLL1_CFG(28, 1, 0, 0), 1344000000}, - { PLL1_CFG(29, 1, 0, 0), 1392000000}, - { PLL1_CFG(30, 1, 0, 0), 1440000000}, { PLL1_CFG(31, 1, 0, 0), 1488000000}, - /* Final catchall entry */ - { PLL1_CFG(31, 1, 0, 0), ~0}, + { PLL1_CFG(30, 1, 0, 0), 1440000000}, + { PLL1_CFG(29, 1, 0, 0), 1392000000}, + { PLL1_CFG(28, 1, 0, 0), 1344000000}, + { PLL1_CFG(27, 1, 0, 0), 1296000000}, + { PLL1_CFG(26, 1, 0, 0), 1248000000}, + { PLL1_CFG(25, 1, 0, 0), 1200000000}, + { PLL1_CFG(24, 1, 0, 0), 1152000000}, + { PLL1_CFG(23, 1, 0, 0), 1104000000}, + { PLL1_CFG(22, 1, 0, 0), 1056000000}, + { PLL1_CFG(21, 1, 0, 0), 1008000000}, + { PLL1_CFG(20, 1, 0, 0), 960000000 }, + { PLL1_CFG(19, 1, 0, 0), 912000000 }, + { PLL1_CFG(16, 1, 0, 0), 768000000 }, + /* Final catchall entry 384MHz*/ + { PLL1_CFG(16, 0, 0, 0), 0 }, + };
void clock_set_pll1(unsigned int hz) @@ -126,10 +127,12 @@ void clock_set_pll1(unsigned int hz) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* Find target frequency */ - while (pll1_para[i].freq < hz) + while (pll1_para[i].freq > hz) i++;
hz = pll1_para[i].freq; + if (! hz) + hz = 384000000;
/* Calculate system clock divisors */ axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */

make the CPU clock selectable via Kconfig
this removes the sunxi specific CONFIG_CLK_FULL_SPEED defined in each soc header and replaces it's use in board/sunxi/board.c with CONFIG_SYS_CLK_FREQ from Kconfig which allows us to configure board specific frequency on boot
Signed-off-by: Iain Paton ipaton0@gmail.com --- Kconfig | 2 +- board/sunxi/Kconfig | 4 ++++ board/sunxi/board.c | 2 +- include/configs/sun4i.h | 1 - include/configs/sun5i.h | 1 - include/configs/sun6i.h | 1 - include/configs/sun7i.h | 1 - include/configs/sun8i.h | 1 - 8 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/Kconfig b/Kconfig index 8f96c94..a6aa7ac 100644 --- a/Kconfig +++ b/Kconfig @@ -184,7 +184,7 @@ config SYS_TEXT_BASE TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
config SYS_CLK_FREQ - depends on ARC + depends on ARC || ARCH_SUNXI int "CPU clock frequency" help TODO: Move CONFIG_SYS_CLK_FREQ for all the architecture diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 9d0eb91..2fcab60 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -132,6 +132,10 @@ endchoice
endif
+config SYS_CLK_FREQ + default 912000000 if MACH_SUN7I + default 1008000000 if MACH_SUN4I || MACH_SUN5I || MACH_SUN6I || MACH_SUN8I + config SYS_CONFIG_NAME default "sun4i" if MACH_SUN4I default "sun5i" if MACH_SUN5I diff --git a/board/sunxi/board.c b/board/sunxi/board.c index e1891d1..808bf82 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -215,7 +215,7 @@ void sunxi_board_init(void) * assured it's being powered with suitable core voltage */ if (!power_failed) - clock_set_pll1(CONFIG_CLK_FULL_SPEED); + clock_set_pll1(CONFIG_SYS_CLK_FREQ); else printf("Failed to set core voltage! Can't set CPU frequency\n"); } diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h index 1537e53..7cd5c69 100644 --- a/include/configs/sun4i.h +++ b/include/configs/sun4i.h @@ -11,7 +11,6 @@ /* * A10 specific configuration */ -#define CONFIG_CLK_FULL_SPEED 1008000000
#ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h index e755531..e0470d4 100644 --- a/include/configs/sun5i.h +++ b/include/configs/sun5i.h @@ -11,7 +11,6 @@ /* * High Level Configuration Options */ -#define CONFIG_CLK_FULL_SPEED 1008000000
#ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI diff --git a/include/configs/sun6i.h b/include/configs/sun6i.h index f5e11dd..617c1cd 100644 --- a/include/configs/sun6i.h +++ b/include/configs/sun6i.h @@ -14,7 +14,6 @@ /* * A31 specific configuration */ -#define CONFIG_CLK_FULL_SPEED 1008000000
#ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI diff --git a/include/configs/sun7i.h b/include/configs/sun7i.h index f817f73..0bb756f 100644 --- a/include/configs/sun7i.h +++ b/include/configs/sun7i.h @@ -12,7 +12,6 @@ /* * A20 specific configuration */ -#define CONFIG_CLK_FULL_SPEED 912000000
#ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 3bdedb3..79796d7 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -12,7 +12,6 @@ /* * A23 specific configuration */ -#define CONFIG_CLK_FULL_SPEED 1008000000
#ifdef CONFIG_USB_EHCI #define CONFIG_USB_EHCI_SUNXI

following kernel patches to reduce the cpu clock to 912MHz due to reported instability at 1008MHz, select 912MHz as the boot speed for the a10-lime
Signed-off-by: Iain Paton ipaton0@gmail.com --- configs/A10-OLinuXino-Lime_defconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig index 48a0705..3e19424 100644 --- a/configs/A10-OLinuXino-Lime_defconfig +++ b/configs/A10-OLinuXino-Lime_defconfig @@ -7,3 +7,4 @@ CONFIG_MACH_SUN4I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_ZQ=123 CONFIG_DRAM_EMR1=4 +CONFIG_SYS_CLK_FREQ=912000000

Hi,
On 28-03-15 11:25, Iain Paton wrote:
clock_set_pll1 would pick the next highest available cpu clock speed if a value not in the pre defined table was selected. this potentially results in overclocking the soc.
reverse the selection method so that we select the next lowest speed and add the missing 912Mhz setting that's requested by sun7i which also uses the sun4i clock code.
Signed-off-by: Iain Paton ipaton0@gmail.com
Thanks for the new set.
I've found one small issue with the second patch: "sunxi: use CONFIG_SYS_CLK_FREQ to set cpu clock"
sun7i.h contained the following:
#define CONFIG_SYS_CLK_FREQ 24000000 #define CONFIG_TIMER_CLK_FREQ CONFIG_SYS_CLK_FREQ
Which is a conflicting usage of CONFIG_SYS_CLK_FREQ compared to the new usage introduced by your patch. I've fixed this by changing the above to:
#define CONFIG_TIMER_CLK_FREQ 24000000
And run some compile and runtime tests.
Everything builds and works fine with this change added, so I've pushed these 3 commits + one other fix to: u-boot-sunxi/master
And I will send out a pull-req shortly to get these fixes included into the upcoming u-boot v2015.04 release.
Regards,
Hans
arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 35 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c index 49f4032..c3e04af 100644 --- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c @@ -100,22 +100,23 @@ static struct { unsigned int freq; } pll1_para[] = { /* This array must be ordered by frequency. */
- { PLL1_CFG(16, 0, 0, 0), 384000000 },
- { PLL1_CFG(16, 1, 0, 0), 768000000 },
- { PLL1_CFG(20, 1, 0, 0), 960000000 },
- { PLL1_CFG(21, 1, 0, 0), 1008000000},
- { PLL1_CFG(22, 1, 0, 0), 1056000000},
- { PLL1_CFG(23, 1, 0, 0), 1104000000},
- { PLL1_CFG(24, 1, 0, 0), 1152000000},
- { PLL1_CFG(25, 1, 0, 0), 1200000000},
- { PLL1_CFG(26, 1, 0, 0), 1248000000},
- { PLL1_CFG(27, 1, 0, 0), 1296000000},
- { PLL1_CFG(28, 1, 0, 0), 1344000000},
- { PLL1_CFG(29, 1, 0, 0), 1392000000},
- { PLL1_CFG(30, 1, 0, 0), 1440000000}, { PLL1_CFG(31, 1, 0, 0), 1488000000},
- /* Final catchall entry */
- { PLL1_CFG(31, 1, 0, 0), ~0},
{ PLL1_CFG(30, 1, 0, 0), 1440000000},
{ PLL1_CFG(29, 1, 0, 0), 1392000000},
{ PLL1_CFG(28, 1, 0, 0), 1344000000},
{ PLL1_CFG(27, 1, 0, 0), 1296000000},
{ PLL1_CFG(26, 1, 0, 0), 1248000000},
{ PLL1_CFG(25, 1, 0, 0), 1200000000},
{ PLL1_CFG(24, 1, 0, 0), 1152000000},
{ PLL1_CFG(23, 1, 0, 0), 1104000000},
{ PLL1_CFG(22, 1, 0, 0), 1056000000},
{ PLL1_CFG(21, 1, 0, 0), 1008000000},
{ PLL1_CFG(20, 1, 0, 0), 960000000 },
{ PLL1_CFG(19, 1, 0, 0), 912000000 },
{ PLL1_CFG(16, 1, 0, 0), 768000000 },
/* Final catchall entry 384MHz*/
{ PLL1_CFG(16, 0, 0, 0), 0 },
};
void clock_set_pll1(unsigned int hz)
@@ -126,10 +127,12 @@ void clock_set_pll1(unsigned int hz) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
/* Find target frequency */
- while (pll1_para[i].freq < hz)
while (pll1_para[i].freq > hz) i++;
hz = pll1_para[i].freq;
if (! hz)
hz = 384000000;
/* Calculate system clock divisors */ axi = DIV_ROUND_UP(hz, 432000000); /* Max 450MHz */

On 29/03/15 13:39, Hans de Goede wrote:
Hi,
On 28-03-15 11:25, Iain Paton wrote:
clock_set_pll1 would pick the next highest available cpu clock speed if a value not in the pre defined table was selected. this potentially results in overclocking the soc.
reverse the selection method so that we select the next lowest speed and add the missing 912Mhz setting that's requested by sun7i which also uses the sun4i clock code.
Signed-off-by: Iain Paton ipaton0@gmail.com
Thanks for the new set.
I've found one small issue with the second patch: "sunxi: use CONFIG_SYS_CLK_FREQ to set cpu clock"
sun7i.h contained the following:
#define CONFIG_SYS_CLK_FREQ 24000000 #define CONFIG_TIMER_CLK_FREQ CONFIG_SYS_CLK_FREQ
Which is a conflicting usage of CONFIG_SYS_CLK_FREQ compared to the new usage introduced by your patch. I've fixed this by changing the above to:
#define CONFIG_TIMER_CLK_FREQ 24000000
And run some compile and runtime tests.
Everything builds and works fine with this change added, so I've pushed these 3 commits + one other fix to: u-boot-sunxi/master
Apologies for missing that. Thanks for the fixup.
Did you see any compile or runtime errors?
I definately did build and boot the result several times before sending it, especially to verify the behaviour of the first patch.
So I'm curious as to how I missed it and you found the issue.
Rgds, Iain

Hi,
On 30-03-15 09:52, Iain Paton wrote:
On 29/03/15 13:39, Hans de Goede wrote:
Hi,
On 28-03-15 11:25, Iain Paton wrote:
clock_set_pll1 would pick the next highest available cpu clock speed if a value not in the pre defined table was selected. this potentially results in overclocking the soc.
reverse the selection method so that we select the next lowest speed and add the missing 912Mhz setting that's requested by sun7i which also uses the sun4i clock code.
Signed-off-by: Iain Paton ipaton0@gmail.com
Thanks for the new set.
I've found one small issue with the second patch: "sunxi: use CONFIG_SYS_CLK_FREQ to set cpu clock"
sun7i.h contained the following:
#define CONFIG_SYS_CLK_FREQ 24000000 #define CONFIG_TIMER_CLK_FREQ CONFIG_SYS_CLK_FREQ
Which is a conflicting usage of CONFIG_SYS_CLK_FREQ compared to the new usage introduced by your patch. I've fixed this by changing the above to:
#define CONFIG_TIMER_CLK_FREQ 24000000
And run some compile and runtime tests.
Everything builds and works fine with this change added, so I've pushed these 3 commits + one other fix to: u-boot-sunxi/master
Apologies for missing that. Thanks for the fixup.
Did you see any compile or runtime errors?
I definately did build and boot the result several times before sending it, especially to verify the behaviour of the first patch.
So I'm curious as to how I missed it and you found the issue.
The problem caused compile time warnings when building for a sun7i (A20) board, and likely would have also caused runtime problems, but I did not test a build with the problem.
Regards,
Hans
participants (2)
-
Hans de Goede
-
Iain Paton