diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index e92224ee2ae..8e956d41f4a 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include "clock_stm32_ll_common.h" @@ -286,6 +287,11 @@ static int stm32_clock_control_init(struct device *dev) { LL_UTILS_ClkInitTypeDef s_ClkInitStruct; uint32_t hclk_prescaler; +#if defined(CONFIG_CLOCK_STM32_SYSCLK_SRC_HSE) || \ + defined(CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI) + uint32_t old_hclk_freq; + uint32_t new_hclk_freq; +#endif ARG_UNUSED(dev); @@ -381,6 +387,22 @@ static int stm32_clock_control_init(struct device *dev) #elif CONFIG_CLOCK_STM32_SYSCLK_SRC_HSE + old_hclk_freq = HAL_RCC_GetHCLKFreq(); + + /* Calculate new SystemCoreClock variable based on HSE freq */ + new_hclk_freq = __LL_RCC_CALC_HCLK_FREQ(CONFIG_CLOCK_STM32_HSE_CLOCK, + hclk_prescaler); +#if defined(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) + __ASSERT(new_hclk_freq == CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, + "Config mismatch HCLK frequency %u %u", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, new_hclk_freq); +#endif + + /* If freq increases, set flash latency before any clock setting */ + if (new_hclk_freq > old_hclk_freq) { + LL_SetFlashLatency(new_hclk_freq); + } + /* Enable HSE if not enabled */ if (LL_RCC_HSE_IsReady() != 1) { /* Check if need to enable HSE bypass feature or not */ @@ -404,9 +426,7 @@ static int stm32_clock_control_init(struct device *dev) } /* Update SystemCoreClock variable */ - LL_SetSystemCoreClock(__LL_RCC_CALC_HCLK_FREQ( - CONFIG_CLOCK_STM32_HSE_CLOCK, - hclk_prescaler)); + LL_SetSystemCoreClock(new_hclk_freq); /* Set APB1 & APB2 prescaler*/ LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider); @@ -414,9 +434,10 @@ static int stm32_clock_control_init(struct device *dev) LL_RCC_SetAPB2Prescaler(s_ClkInitStruct.APB2CLKDivider); #endif /* CONFIG_SOC_SERIES_STM32F0X && CONFIG_SOC_SERIES_STM32G0X */ - /* Set flash latency */ - /* HSI used as SYSCLK, set latency to 0 */ - LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); + /* If freq not increased, set flash latency after all clock setting */ + if (new_hclk_freq <= old_hclk_freq) { + LL_SetFlashLatency(new_hclk_freq); + } /* Disable other clocks */ LL_RCC_HSI_Disable(); @@ -425,6 +446,27 @@ static int stm32_clock_control_init(struct device *dev) #elif CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI + old_hclk_freq = HAL_RCC_GetHCLKFreq(); + + /* Calculate new SystemCoreClock variable with MSI freq */ + /* MSI freq is defined from RUN range selection */ + new_hclk_freq = + __LL_RCC_CALC_HCLK_FREQ( + __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, + CONFIG_CLOCK_STM32_MSI_RANGE << RCC_CR_MSIRANGE_Pos), + hclk_prescaler); + +#if defined(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) + __ASSERT(new_hclk_freq == CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, + "Config mismatch HCLK frequency %u %u", + CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, new_hclk_freq); +#endif + + /* If freq increases, set flash latency before any clock setting */ + if (new_hclk_freq > old_hclk_freq) { + LL_SetFlashLatency(new_hclk_freq); + } + /* Set MSI Range */ LL_RCC_MSI_EnableRangeSelection(); LL_RCC_MSI_SetRange(CONFIG_CLOCK_STM32_MSI_RANGE << RCC_CR_MSIRANGE_Pos); @@ -448,10 +490,8 @@ static int stm32_clock_control_init(struct device *dev) while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) { } - /* Update SystemCoreClock variable with MSI freq */ - /* MSI freq is defined from RUN range selection */ - LL_SetSystemCoreClock(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, - LL_RCC_MSI_GetRange())); + /* Update SystemCoreClock variable */ + LL_SetSystemCoreClock(new_hclk_freq); /* Set APB1 & APB2 prescaler*/ LL_RCC_SetAPB1Prescaler(s_ClkInitStruct.APB1CLKDivider); @@ -462,9 +502,10 @@ static int stm32_clock_control_init(struct device *dev) LL_RCC_SetAHB4Prescaler(s_ClkInitStruct->AHB4CLKDivider); #endif /* CONFIG_SOC_SERIES_STM32WBX */ - /* Set flash latency */ - /* MSI used as SYSCLK (16MHz), set latency to 0 */ - LL_FLASH_SetLatency(LL_FLASH_LATENCY_0); + /* If freq not increased, set flash latency after all clock setting */ + if (new_hclk_freq <= old_hclk_freq) { + LL_SetFlashLatency(new_hclk_freq); + } /* Disable other clocks */ LL_RCC_HSE_Disable(); diff --git a/west.yml b/west.yml index eaf1e3157bd..5a12af98394 100644 --- a/west.yml +++ b/west.yml @@ -71,7 +71,7 @@ manifest: revision: 5b3ec3e182d4310e8943cc34c6c70ae57d9711da path: modules/hal/st - name: hal_stm32 - revision: 6812113dc58d134b74acdeebbffb4f80b8eeab75 + revision: pull/54/head path: modules/hal/stm32 - name: hal_ti revision: aabc6a04a8e871cbb01e02c22bb409f68001dc64