From 693ba0479609da3e49b94420057737a2e67d6ec9 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Fri, 25 Mar 2022 11:37:48 +0100 Subject: [PATCH] dts: stm32: Add rcc prop undershoot-prevention On some parts, it could be required to use steps before applying highest frequencies. This was previously done as part of LL_PLL_ConfigSystemClock_FOO utility functions which are no more used. Use device tree to mention when this is required and implement it in stm32_clock_control_init(). Additionally, fix the calls tp LL_RCC_SetAHBPrescaler, which require use of ahb_prescaler helper. Signed-off-by: Erwan Gouriou --- drivers/clock_control/clock_stm32_ll_common.c | 27 ++++++++++++++----- dts/arm/st/g4/stm32g4.dtsi | 1 + dts/arm/st/l4/stm32l4r5.dtsi | 4 +++ dts/arm/st/l5/stm32l5.dtsi | 1 + dts/bindings/clock/st,stm32-rcc.yaml | 10 +++++++ dts/bindings/clock/st,stm32mp1-rcc.yaml | 1 + dts/bindings/clock/st,stm32u5-rcc.yaml | 5 +++- 7 files changed, 42 insertions(+), 7 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 15aacb2ed9d..c5cb568072c 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -293,7 +293,7 @@ static struct clock_control_driver_api stm32_clock_control_api = { * Unconditionally switch the system clock source to HSI. */ __unused -static void stm32_clock_switch_to_hsi(uint32_t new_ahb_prescaler) +static void stm32_clock_switch_to_hsi(void) { /* Enable HSI if not enabled */ if (LL_RCC_HSI_IsReady() != 1) { @@ -306,7 +306,6 @@ static void stm32_clock_switch_to_hsi(uint32_t new_ahb_prescaler) /* Set HSI as SYSCLCK source */ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); - LL_RCC_SetAHBPrescaler(new_ahb_prescaler); while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) { } } @@ -343,7 +342,8 @@ static int set_up_plls(void) * */ if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { - stm32_clock_switch_to_hsi(LL_RCC_SYSCLK_DIV_1); + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + stm32_clock_switch_to_hsi(); } LL_RCC_PLL_Disable(); @@ -398,6 +398,9 @@ static void set_up_fixed_clock_sources(void) } else { LL_RCC_HSE_DisableBypass(); } +#endif +#if STM32_HSE_DIV2 + LL_RCC_HSE_EnableDiv2(); #endif /* Enable HSE */ LL_RCC_HSE_Enable(); @@ -495,6 +498,14 @@ int stm32_clock_control_init(const struct device *dev) return r; } + if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && + (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && + (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) { + LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); + } else { + LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER)); + } + #if STM32_SYSCLK_SRC_PLL /* Set PLL as System Clock Source */ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); @@ -503,19 +514,23 @@ int stm32_clock_control_init(const struct device *dev) #elif STM32_SYSCLK_SRC_HSE /* Set HSE as SYSCLCK source */ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE); - LL_RCC_SetAHBPrescaler(STM32_CORE_PRESCALER); while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) { } #elif STM32_SYSCLK_SRC_MSI /* Set MSI as SYSCLCK source */ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI); - LL_RCC_SetAHBPrescaler(STM32_CORE_PRESCALER); while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) { } #elif STM32_SYSCLK_SRC_HSI - stm32_clock_switch_to_hsi(STM32_CORE_PRESCALER); + stm32_clock_switch_to_hsi(); #endif /* STM32_SYSCLK_SRC_... */ + if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && + (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && + (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) { + LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER)); + } + /* If freq not increased, set flash latency after all clock setting */ if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) { LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC); diff --git a/dts/arm/st/g4/stm32g4.dtsi b/dts/arm/st/g4/stm32g4.dtsi index 932339c3a83..39023ec77d8 100644 --- a/dts/arm/st/g4/stm32g4.dtsi +++ b/dts/arm/st/g4/stm32g4.dtsi @@ -139,6 +139,7 @@ compatible = "st,stm32-rcc"; #clock-cells = <2>; reg = <0x40021000 0x400>; + undershoot-prevention; }; exti: interrupt-controller@40010400 { diff --git a/dts/arm/st/l4/stm32l4r5.dtsi b/dts/arm/st/l4/stm32l4r5.dtsi index 3af9e4dc55e..6a23bcc3ae6 100644 --- a/dts/arm/st/l4/stm32l4r5.dtsi +++ b/dts/arm/st/l4/stm32l4r5.dtsi @@ -19,6 +19,10 @@ }; }; + rcc: rcc@40021000 { + undershoot-prevention; + }; + pinctrl: pin-controller@48000000 { gpiod: gpio@48000c00 { compatible = "st,stm32-gpio"; diff --git a/dts/arm/st/l5/stm32l5.dtsi b/dts/arm/st/l5/stm32l5.dtsi index 15b717a8c97..2dddc41f348 100644 --- a/dts/arm/st/l5/stm32l5.dtsi +++ b/dts/arm/st/l5/stm32l5.dtsi @@ -115,6 +115,7 @@ clocks-controller; #clock-cells = <2>; reg = <0x40021000 0x400>; + undershoot-prevention; }; exti: interrupt-controller@4000f400 { diff --git a/dts/bindings/clock/st,stm32-rcc.yaml b/dts/bindings/clock/st,stm32-rcc.yaml index cc4319d7750..3ae1fe7a68a 100644 --- a/dts/bindings/clock/st,stm32-rcc.yaml +++ b/dts/bindings/clock/st,stm32-rcc.yaml @@ -91,6 +91,16 @@ properties: - 8 - 16 + undershoot-prevention: + type: boolean + required: false + description: | + On some parts, it could be required to set up highest core frequencies + (>80MHz) in two steps in order to prevent undershoot. + This is done by applying an intermediate AHB prescaler before switching + System Clock source to PLL. Once done, prescaler is set back to expected + value. + clock-cells: - bus - bits diff --git a/dts/bindings/clock/st,stm32mp1-rcc.yaml b/dts/bindings/clock/st,stm32mp1-rcc.yaml index 39f51f02f15..8282b46d112 100644 --- a/dts/bindings/clock/st,stm32mp1-rcc.yaml +++ b/dts/bindings/clock/st,stm32mp1-rcc.yaml @@ -15,3 +15,4 @@ include: - ahb-prescaler - apb1-prescaler - apb2-prescaler + - undershoot-prevention diff --git a/dts/bindings/clock/st,stm32u5-rcc.yaml b/dts/bindings/clock/st,stm32u5-rcc.yaml index cea21ffef9b..5aa4783b910 100644 --- a/dts/bindings/clock/st,stm32u5-rcc.yaml +++ b/dts/bindings/clock/st,stm32u5-rcc.yaml @@ -7,7 +7,10 @@ description: | compatible: "st,stm32u5-rcc" -include: st,stm32-rcc.yaml +include: + - name: st,stm32-rcc.yaml + property-blocklist: + - undershoot-prevention properties: