From 77db273f6f84b3d94d34b5e72070ec6bc31e41cf Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Fri, 2 Aug 2019 09:28:29 +0200 Subject: [PATCH] stm32: clock_control: Enforce HCLK prescaler value STM32 clock control subsystem allows to configure a different frequency value for core clock (SYSCLK) and AHB clock (HCLK). Though, it is HCLK which is used to feed Cortex Systick timer which is used in zephyr as reference system clock. If HCLK frequency is configured to a different value from SYSCLK frequency, whole system is exposed to desynchro between zephyr clock subsytem and STM32 HW configuration. To prevent this, and until zephyr clock subsystem is changed to be aware of this potential configuration, enforce AHB prescaler value to 1 (which is current default value in use for all STM32 based boards). On STM32H7, enforce D1CPRE which fills the same role as ABH precaler. On STM32MP1, the equivalent setting is done on A7 core, so it is not exposed to the same issue as long as SYS_CLOCK_HW_CYCLES_PER_SEC is set with the 'mlhclk_ck' clock frequency value. Update matching boards documentation. Fixes #17188 Signed-off-by: Erwan Gouriou --- boards/arm/96b_avenger96/96b_avenger96_defconfig | 2 +- boards/arm/96b_avenger96/doc/index.rst | 3 ++- boards/arm/stm32mp157c_dk2/doc/stm32mp157_dk2.rst | 3 ++- boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig | 2 +- drivers/clock_control/clock_stm32_ll_common.c | 11 +++++++++++ drivers/clock_control/clock_stm32_ll_h7.c | 12 ++++++++++++ 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/boards/arm/96b_avenger96/96b_avenger96_defconfig b/boards/arm/96b_avenger96/96b_avenger96_defconfig index 913606662b0..8bc6a68f33a 100644 --- a/boards/arm/96b_avenger96/96b_avenger96_defconfig +++ b/boards/arm/96b_avenger96/96b_avenger96_defconfig @@ -3,7 +3,7 @@ CONFIG_BOARD_96B_AVENGER96=y CONFIG_SOC_SERIES_STM32MP1X=y CONFIG_SOC_STM32MP15_M4=y CONFIG_CORTEX_M_SYSTICK=y -# 209 MHz system clock +# 209 MHz system clock (mlhclk_ck) CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=209000000 # enable GPIO diff --git a/boards/arm/96b_avenger96/doc/index.rst b/boards/arm/96b_avenger96/doc/index.rst index 89bb1473afa..e6c9a62e9dd 100644 --- a/boards/arm/96b_avenger96/doc/index.rst +++ b/boards/arm/96b_avenger96/doc/index.rst @@ -185,7 +185,8 @@ Default Zephyr Peripheral Mapping: System Clock ------------ -The Cortex®-M4 Core is configured to run at a 209 MHz clock speed. +The Cortex®-M4 Core is configured to run at a 209 MHz clock speed. This value +must match the configured mlhclk_ck frequency. Serial Port ----------- diff --git a/boards/arm/stm32mp157c_dk2/doc/stm32mp157_dk2.rst b/boards/arm/stm32mp157c_dk2/doc/stm32mp157_dk2.rst index 919fce8141b..4d5e0f58c59 100644 --- a/boards/arm/stm32mp157c_dk2/doc/stm32mp157_dk2.rst +++ b/boards/arm/stm32mp157c_dk2/doc/stm32mp157_dk2.rst @@ -199,7 +199,8 @@ Default Zephyr Peripheral Mapping: System Clock ------------ -The Cortex®-M4 Core is configured to run at a 209 MHz clock speed. +The Cortex®-M4 Core is configured to run at a 209 MHz clock speed. This value +must match the configured mlhclk_ck frequency. Serial Port ----------- diff --git a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig index 123074911e5..e1bf71988e3 100644 --- a/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig +++ b/boards/arm/stm32mp157c_dk2/stm32mp157c_dk2_defconfig @@ -3,7 +3,7 @@ CONFIG_BOARD_STM32MP157C_DK2=y CONFIG_SOC_SERIES_STM32MP1X=y CONFIG_SOC_STM32MP15_M4=y CONFIG_CORTEX_M_SYSTICK=y -# 209 MHz system clock +# 209 MHz system clock (mlhclk_ck) CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=209000000 # enable GPIO diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 5f143cb4c8f..61a8ebbabc9 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -34,6 +34,17 @@ #define __LL_RCC_CALC_HCLK_FREQ __LL_RCC_CALC_HCLK1_FREQ #endif /* CONFIG_SOC_SERIES_STM32F0X */ +#if CONFIG_CLOCK_STM32_AHB_PRESCALER > 1 +/* + * AHB prescaler allows to set a HCLK frequency (feeding cortex systick) + * lower than SYSCLK frequency (actual core frequency). + * Though, zephyr doesn't make a difference today between these two clocks. + * So, changing this prescaler is not allowed until it is made possible to + * use them independently in zephyr clock subsystem. + */ +#error "AHB presacler can't be higher than 1" +#endif + /** * @brief fill in AHB/APB buses configuration structure */ diff --git a/drivers/clock_control/clock_stm32_ll_h7.c b/drivers/clock_control/clock_stm32_ll_h7.c index c58df7ec8a6..5bab2d692e3 100644 --- a/drivers/clock_control/clock_stm32_ll_h7.c +++ b/drivers/clock_control/clock_stm32_ll_h7.c @@ -29,6 +29,18 @@ #define z_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v #define apb4_prescaler(v) z_apb4_prescaler(v) +#if defined(CONFIG_CPU_CORTEX_M7) +#if CONFIG_CLOCK_STM32_D1CPRE > 1 +/* + * D1CPRE prescaler allows to set a HCLK frequency lower than SYSCLK frequency. + * Though, zephyr doesn't make a difference today between these two clocks. + * So, changing this prescaler is not allowed until it is made possible to + * use them independently in zephyr clock subsystem. + */ +#error "D1CPRE presacler can't be higher than 1" +#endif +#endif /* CONFIG_CPU_CORTEX_M7 */ + /** * @brief fill in AHB/APB buses configuration structure */