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 <erwan.gouriou@linaro.org>
This commit is contained in:
Erwan Gouriou 2022-03-25 11:37:48 +01:00 committed by Carles Cufí
commit 693ba04796
7 changed files with 42 additions and 7 deletions

View file

@ -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);

View file

@ -139,6 +139,7 @@
compatible = "st,stm32-rcc";
#clock-cells = <2>;
reg = <0x40021000 0x400>;
undershoot-prevention;
};
exti: interrupt-controller@40010400 {

View file

@ -19,6 +19,10 @@
};
};
rcc: rcc@40021000 {
undershoot-prevention;
};
pinctrl: pin-controller@48000000 {
gpiod: gpio@48000c00 {
compatible = "st,stm32-gpio";

View file

@ -115,6 +115,7 @@
clocks-controller;
#clock-cells = <2>;
reg = <0x40021000 0x400>;
undershoot-prevention;
};
exti: interrupt-controller@4000f400 {

View file

@ -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

View file

@ -15,3 +15,4 @@ include:
- ahb-prescaler
- apb1-prescaler
- apb2-prescaler
- undershoot-prevention

View file

@ -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: