Skip to contentSkip to conversation

sunxi: sun4i: improve cpu clock selection method

PATCH New Iain Paton 2 participants 6 messages Mar 28, 2015 – Mar 30, 2015

Subsystems (2)
lore
Share & tools
lore

Iain Paton

author
#0 lore raw

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.

---
 arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 35 ++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)
arch/arm/cpu/armv7/sunxi/clock_sun4i.c +19 -16
index 49f4032..c3e04af 100644
@@ -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 */
Signature · 1 line
2.1.3
author
#1 lore raw

PATCH v2 2/3 sunxi: use CONFIG_SYS_CLK_FREQ to set cpu clock

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

---
 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(-)
Kconfig +1 -1
index 8f96c94..a6aa7ac 100644
@@ -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
board/sunxi/Kconfig +4 -0
index 9d0eb91..2fcab60 100644
@@ -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
board/sunxi/board.c +1 -1
index e1891d1..808bf82 100644
@@ -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");
 }
include/configs/sun4i.h +0 -1
index 1537e53..7cd5c69 100644
@@ -11,7 +11,6 @@
 /*
  * A10 specific configuration
  */
-#define CONFIG_CLK_FULL_SPEED		1008000000
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
include/configs/sun5i.h +0 -1
index e755531..e0470d4 100644
@@ -11,7 +11,6 @@
 /*
  * High Level Configuration Options
  */
-#define CONFIG_CLK_FULL_SPEED		1008000000
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
include/configs/sun6i.h +0 -1
index f5e11dd..617c1cd 100644
@@ -14,7 +14,6 @@
 /*
  * A31 specific configuration
  */
-#define CONFIG_CLK_FULL_SPEED		1008000000
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
include/configs/sun7i.h +0 -1
index f817f73..0bb756f 100644
@@ -12,7 +12,6 @@
 /*
  * A20 specific configuration
  */
-#define CONFIG_CLK_FULL_SPEED		912000000
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
include/configs/sun8i.h +0 -1
index 3bdedb3..79796d7 100644
@@ -12,7 +12,6 @@
 /*
  * A23 specific configuration
  */
-#define CONFIG_CLK_FULL_SPEED	1008000000
 
 #ifdef CONFIG_USB_EHCI
 #define CONFIG_USB_EHCI_SUNXI
Signature · 1 line
2.1.3
author
#2 lore raw

PATCH v2 3/3 sunxi: a10-LIME set the cpu clock at boot to 912MHz

In reply to Iain Paton

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

---
 configs/A10-OLinuXino-Lime_defconfig | 1 +
 1 file changed, 1 insertion(+)
configs/A10-OLinuXino-Lime_defconfig +1 -0
index 48a0705..3e19424 100644
@@ -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
Signature · 1 line
2.1.3
#3 lore raw

PATCH v2 1/3 sunxi: sun4i: improve cpu clock selection method

In reply to Iain Paton

Hi,

Quoted 9 lines · Iain Paton

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.

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

Quoted 62 lines
---
  arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 35 ++++++++++++++++++----------------
  1 file changed, 19 insertions(+), 16 deletions(-)
arch/arm/cpu/armv7/sunxi/clock_sun4i.c +19 -16
index 49f4032..c3e04af 100644
@@ -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 */
author
#4 lore raw

PATCH v2 1/3 sunxi: sun4i: improve cpu clock selection method

Quoted 27 lines · Hans de Goede

Hi,

Quoted 9 lines · Iain Paton

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.

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:

Quoted 6 lines

#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

#5 lore raw

PATCH v2 1/3 sunxi: sun4i: improve cpu clock selection method

Hi,

Quoted 35 lines · Iain Paton
Quoted 27 lines · Hans de Goede

Hi,

Quoted 9 lines · Iain Paton

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.

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:

Quoted 6 lines

#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

Quoted 8 lines

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