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:
parent
5202d40520
commit
693ba04796
7 changed files with 42 additions and 7 deletions
|
@ -293,7 +293,7 @@ static struct clock_control_driver_api stm32_clock_control_api = {
|
||||||
* Unconditionally switch the system clock source to HSI.
|
* Unconditionally switch the system clock source to HSI.
|
||||||
*/
|
*/
|
||||||
__unused
|
__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 */
|
/* Enable HSI if not enabled */
|
||||||
if (LL_RCC_HSI_IsReady() != 1) {
|
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 */
|
/* Set HSI as SYSCLCK source */
|
||||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
|
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
|
||||||
LL_RCC_SetAHBPrescaler(new_ahb_prescaler);
|
|
||||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
|
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) {
|
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();
|
LL_RCC_PLL_Disable();
|
||||||
|
|
||||||
|
@ -398,6 +398,9 @@ static void set_up_fixed_clock_sources(void)
|
||||||
} else {
|
} else {
|
||||||
LL_RCC_HSE_DisableBypass();
|
LL_RCC_HSE_DisableBypass();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if STM32_HSE_DIV2
|
||||||
|
LL_RCC_HSE_EnableDiv2();
|
||||||
#endif
|
#endif
|
||||||
/* Enable HSE */
|
/* Enable HSE */
|
||||||
LL_RCC_HSE_Enable();
|
LL_RCC_HSE_Enable();
|
||||||
|
@ -495,6 +498,14 @@ int stm32_clock_control_init(const struct device *dev)
|
||||||
return r;
|
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
|
#if STM32_SYSCLK_SRC_PLL
|
||||||
/* Set PLL as System Clock Source */
|
/* Set PLL as System Clock Source */
|
||||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
|
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
|
#elif STM32_SYSCLK_SRC_HSE
|
||||||
/* Set HSE as SYSCLCK source */
|
/* Set HSE as SYSCLCK source */
|
||||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
|
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
|
||||||
LL_RCC_SetAHBPrescaler(STM32_CORE_PRESCALER);
|
|
||||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
|
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
|
||||||
}
|
}
|
||||||
#elif STM32_SYSCLK_SRC_MSI
|
#elif STM32_SYSCLK_SRC_MSI
|
||||||
/* Set MSI as SYSCLCK source */
|
/* Set MSI as SYSCLCK source */
|
||||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
|
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
|
||||||
LL_RCC_SetAHBPrescaler(STM32_CORE_PRESCALER);
|
|
||||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
|
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
|
||||||
}
|
}
|
||||||
#elif STM32_SYSCLK_SRC_HSI
|
#elif STM32_SYSCLK_SRC_HSI
|
||||||
stm32_clock_switch_to_hsi(STM32_CORE_PRESCALER);
|
stm32_clock_switch_to_hsi();
|
||||||
#endif /* STM32_SYSCLK_SRC_... */
|
#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 freq not increased, set flash latency after all clock setting */
|
||||||
if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
|
if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
|
||||||
LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
|
LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
|
||||||
|
|
|
@ -139,6 +139,7 @@
|
||||||
compatible = "st,stm32-rcc";
|
compatible = "st,stm32-rcc";
|
||||||
#clock-cells = <2>;
|
#clock-cells = <2>;
|
||||||
reg = <0x40021000 0x400>;
|
reg = <0x40021000 0x400>;
|
||||||
|
undershoot-prevention;
|
||||||
};
|
};
|
||||||
|
|
||||||
exti: interrupt-controller@40010400 {
|
exti: interrupt-controller@40010400 {
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rcc: rcc@40021000 {
|
||||||
|
undershoot-prevention;
|
||||||
|
};
|
||||||
|
|
||||||
pinctrl: pin-controller@48000000 {
|
pinctrl: pin-controller@48000000 {
|
||||||
gpiod: gpio@48000c00 {
|
gpiod: gpio@48000c00 {
|
||||||
compatible = "st,stm32-gpio";
|
compatible = "st,stm32-gpio";
|
||||||
|
|
|
@ -115,6 +115,7 @@
|
||||||
clocks-controller;
|
clocks-controller;
|
||||||
#clock-cells = <2>;
|
#clock-cells = <2>;
|
||||||
reg = <0x40021000 0x400>;
|
reg = <0x40021000 0x400>;
|
||||||
|
undershoot-prevention;
|
||||||
};
|
};
|
||||||
|
|
||||||
exti: interrupt-controller@4000f400 {
|
exti: interrupt-controller@4000f400 {
|
||||||
|
|
|
@ -91,6 +91,16 @@ properties:
|
||||||
- 8
|
- 8
|
||||||
- 16
|
- 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:
|
clock-cells:
|
||||||
- bus
|
- bus
|
||||||
- bits
|
- bits
|
||||||
|
|
|
@ -15,3 +15,4 @@ include:
|
||||||
- ahb-prescaler
|
- ahb-prescaler
|
||||||
- apb1-prescaler
|
- apb1-prescaler
|
||||||
- apb2-prescaler
|
- apb2-prescaler
|
||||||
|
- undershoot-prevention
|
||||||
|
|
|
@ -7,7 +7,10 @@ description: |
|
||||||
|
|
||||||
compatible: "st,stm32u5-rcc"
|
compatible: "st,stm32u5-rcc"
|
||||||
|
|
||||||
include: st,stm32-rcc.yaml
|
include:
|
||||||
|
- name: st,stm32-rcc.yaml
|
||||||
|
property-blocklist:
|
||||||
|
- undershoot-prevention
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue