[U-Boot] [PATCH 1/4] arm: timer: get frequency for arch timer armv7 in cp15 cntfrq

Manage dynamic value for armv7 arch clock timer, when CONFIG_SYS_HZ_CLOCK is not defined. Get frequency from CP15 cntfrq information, initialized for example by first boot stage, clock driver or by BootRom.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
arch/arm/cpu/armv7/arch_timer.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/arch_timer.c b/arch/arm/cpu/armv7/arch_timer.c index 545c518..3bcb944 100644 --- a/arch/arm/cpu/armv7/arch_timer.c +++ b/arch/arm/cpu/armv7/arch_timer.c @@ -12,12 +12,26 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifndef CONFIG_SYS_HZ_CLOCK +static inline u32 read_cntfrq(void) +{ + u32 frq; + + asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (frq)); + return frq; +} +#endif + int timer_init(void) { gd->arch.tbl = 0; gd->arch.tbu = 0;
+#ifdef CONFIG_SYS_HZ_CLOCK gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK; +#else + gd->arch.timer_rate_hz = read_cntfrq(); +#endif return 0; }
@@ -36,7 +50,7 @@ unsigned long long get_ticks(void)
ulong timer_get_boot_us(void) { - return lldiv(get_ticks(), CONFIG_SYS_HZ_CLOCK / 1000000); + return lldiv(get_ticks(), gd->arch.timer_rate_hz / 1000000); }
ulong get_tbclk(void)

The STGEN is the clock source for the Cortex A7 arch timer. So after modification of its frequency, CP15 cntfreq is updated and a new timer init is performed.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
drivers/clk/clk_stm32mp1.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index 55b0f79..c67aa44 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -27,6 +27,15 @@ #define TIMEOUT_200MS 200000 #define TIMEOUT_1S 1000000
+/* STGEN registers */ +#define STGENC_CNTCR 0x00 +#define STGENC_CNTSR 0x04 +#define STGENC_CNTCVL 0x08 +#define STGENC_CNTCVU 0x0C +#define STGENC_CNTFID0 0x20 + +#define STGENC_CNTCR_EN BIT(0) + /* RCC registers */ #define RCC_OCENSETR 0x0C #define RCC_OCENCLRR 0x10 @@ -1377,6 +1386,36 @@ static int set_clksrc(struct stm32mp1_clk_priv *priv, unsigned int clksrc) return ret; }
+static void stgen_config(struct stm32mp1_clk_priv *priv) +{ + int p; + u32 stgenc, cntfid0; + ulong rate; + + stgenc = (u32)syscon_get_first_range(STM32MP_SYSCON_STGEN); + + cntfid0 = readl(stgenc + STGENC_CNTFID0); + p = stm32mp1_clk_get_parent(priv, STGEN_K); + rate = stm32mp1_clk_get(priv, p); + + if (cntfid0 != rate) { + pr_debug("System Generic Counter (STGEN) update\n"); + clrbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN); + writel(0x0, stgenc + STGENC_CNTCVL); + writel(0x0, stgenc + STGENC_CNTCVU); + writel(rate, stgenc + STGENC_CNTFID0); + setbits_le32(stgenc + STGENC_CNTCR, STGENC_CNTCR_EN); + + __asm__ volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (rate)); + + /* need to update gd->arch.timer_rate_hz with new frequency */ + timer_init(); + pr_debug("gd->arch.timer_rate_hz = %x\n", + (u32)gd->arch.timer_rate_hz); + pr_debug("Tick = %x\n", (u32)(get_ticks())); + } +} + static int set_clkdiv(unsigned int clkdiv, u32 address) { u32 val; @@ -1544,8 +1583,10 @@ static int stm32mp1_clktree(struct udevice *dev)
/* configure HSIDIV */ debug("configure HSIDIV\n"); - if (priv->osc[_HSI]) + if (priv->osc[_HSI]) { stm32mp1_hsidiv(rcc, priv->osc[_HSI]); + stgen_config(priv); + }
/* select DIV */ debug("select DIV\n"); @@ -1634,6 +1675,9 @@ static int stm32mp1_clktree(struct udevice *dev) pkcs_config(priv, CLK_CKPER_DISABLED); }
+ /* STGEN clock source can change with CLK_STGEN_XXX */ + stgen_config(priv); + debug("oscillator off\n"); /* switch OFF HSI if not found in device-tree */ if (!priv->osc[_HSI])

On Tue, Mar 20, 2018 at 11:41:25AM +0100, Patrick Delaunay wrote:
The STGEN is the clock source for the Cortex A7 arch timer. So after modification of its frequency, CP15 cntfreq is updated and a new timer init is performed.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Applied to u-boot/master, thanks!

No more use static frequency HSI = 64MHz for STGEN clock but HSE (with higher accurency) by default.
Need to remove CONFIG_SYS_HZ_CLOCK as arch timer frequency is provided at boot by BootRom and cp15 cntfrq and modified during clock tree initialization if needed.
When HSI is no more used by any device, this internal oscillator can be switched off to reduce consumption.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com ---
arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi | 1 + include/configs/stm32mp1.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi index 5d43753..2caa939 100644 --- a/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-u-boot.dtsi @@ -76,6 +76,7 @@ st,pkcs = < CLK_CKPER_DISABLED CLK_SDMMC12_PLL3R + CLK_STGEN_HSE CLK_I2C46_PCLK5 CLK_I2C12_PCLK1 CLK_SDMMC3_PLL3R diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h index 8159101..da0e259 100644 --- a/include/configs/stm32mp1.h +++ b/include/configs/stm32mp1.h @@ -18,7 +18,6 @@ */ #define CONFIG_SYS_HZ 1000 #define CONFIG_SYS_ARCH_TIMER -#define CONFIG_SYS_HZ_CLOCK 64000000
/* * malloc() pool size

On Tue, Mar 20, 2018 at 11:41:26AM +0100, Patrick Delaunay wrote:
No more use static frequency HSI = 64MHz for STGEN clock but HSE (with higher accurency) by default.
Need to remove CONFIG_SYS_HZ_CLOCK as arch timer frequency is provided at boot by BootRom and cp15 cntfrq and modified during clock tree initialization if needed.
When HSI is no more used by any device, this internal oscillator can be switched off to reduce consumption.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Applied to u-boot/master, thanks!

On Tue, Mar 20, 2018 at 11:41:23AM +0100, Patrick Delaunay wrote:
Manage dynamic value for armv7 arch clock timer, when CONFIG_SYS_HZ_CLOCK is not defined. Get frequency from CP15 cntfrq information, initialized for example by first boot stage, clock driver or by BootRom.
Signed-off-by: Patrick Delaunay patrick.delaunay@st.com
Applied to u-boot/master, thanks!
participants (2)
-
Patrick Delaunay
-
Tom Rini