From 0c60fcd40d2cb5fe86e12a90950c2454799ddee0 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Wed, 2 Mar 2022 16:53:31 +0100 Subject: [PATCH] drivers/clock_control: stm32u5: Use new clock bindings This change updates stm32u5 driver to make use of new clock bindings. Signed-off-by: Erwan Gouriou --- drivers/clock_control/clock_stm32_ll_u5.c | 96 +++++++++---------- .../clock_control/stm32_clock_control.h | 27 +++++- 2 files changed, 71 insertions(+), 52 deletions(-) diff --git a/drivers/clock_control/clock_stm32_ll_u5.c b/drivers/clock_control/clock_stm32_ll_u5.c index b85dc46ee00..b1b56d976ce 100644 --- a/drivers/clock_control/clock_stm32_ll_u5.c +++ b/drivers/clock_control/clock_stm32_ll_u5.c @@ -92,39 +92,47 @@ static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) return clock / prescaler; } +static uint32_t get_msis_frequency(void) +{ + return __LL_RCC_CALC_MSIS_FREQ(LL_RCC_MSIRANGESEL_RUN, + STM32_MSIS_RANGE << RCC_ICSCR1_MSISRANGE_Pos); +} + +__unused +static uint32_t get_pllsrc_frequency(void) +{ + + if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + return STM32_HSI_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + return STM32_HSE_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_MSIS)) { + return get_msis_frequency(); + } + + __ASSERT(0, "No PLL Source configured"); + return 0; +} + static inline int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val; ARG_UNUSED(dev); - switch (pclken->bus) { - case STM32_CLOCK_BUS_AHB1: - LL_AHB1_GRP1_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_AHB2: - LL_AHB2_GRP1_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_AHB3: - LL_AHB3_GRP1_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB1: - LL_APB1_GRP1_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB1_2: - LL_APB1_GRP2_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB2: - LL_APB2_GRP1_EnableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB3: - LL_APB3_GRP1_EnableClock(pclken->enr); - break; - default: + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) { + /* Attemp to toggle a wrong periph clock bit */ return -ENOTSUP; } + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus); + reg_val = *reg; + reg_val |= pclken->enr; + *reg = reg_val; + return 0; } @@ -132,35 +140,21 @@ static inline int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) { struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val; ARG_UNUSED(dev); - switch (pclken->bus) { - case STM32_CLOCK_BUS_AHB1: - LL_AHB1_GRP1_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_AHB2: - LL_AHB2_GRP1_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_AHB3: - LL_AHB3_GRP1_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB1: - LL_APB1_GRP1_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB1_2: - LL_APB1_GRP2_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB2: - LL_APB2_GRP1_DisableClock(pclken->enr); - break; - case STM32_CLOCK_BUS_APB3: - LL_APB3_GRP1_DisableClock(pclken->enr); - break; - default: + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) { + /* Attemp to toggle a wrong periph clock bit */ return -ENOTSUP; } + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus); + reg_val = *reg; + reg_val &= ~pclken->enr; + *reg = reg_val; + return 0; } @@ -169,6 +163,12 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, uint32_t *rate) { struct stm32_pclken *pclken = (struct stm32_pclken *)(sys); + + if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) { + /* Attemp to toggle a wrong periph clock bit */ + return -ENOTSUP; + } + /* * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler) * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC @@ -185,6 +185,7 @@ static int stm32_clock_control_get_subsys_rate(const struct device *dev, switch (pclken->bus) { case STM32_CLOCK_BUS_AHB1: case STM32_CLOCK_BUS_AHB2: + case STM32_CLOCK_BUS_AHB2_2: case STM32_CLOCK_BUS_AHB3: *rate = ahb_clock; break; @@ -428,8 +429,7 @@ void config_src_sysclk_msis(LL_UTILS_ClkInitTypeDef s_ClkInitStruct) /* 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_MSIS_FREQ(LL_RCC_MSIRANGESEL_RUN, - STM32_MSIS_RANGE << RCC_ICSCR1_MSISRANGE_Pos), + get_msis_frequency(), s_ClkInitStruct.AHBCLKDivider); __ASSERT(new_hclk_freq == CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC, diff --git a/include/zephyr/drivers/clock_control/stm32_clock_control.h b/include/zephyr/drivers/clock_control/stm32_clock_control.h index 0fa54ca41c8..c6bebb1a189 100644 --- a/include/zephyr/drivers/clock_control/stm32_clock_control.h +++ b/include/zephyr/drivers/clock_control/stm32_clock_control.h @@ -11,10 +11,12 @@ #include -#if !defined(CONFIG_SOC_SERIES_STM32H7X) -#include -#else +#if defined(CONFIG_SOC_SERIES_STM32H7X) #include +#elif defined(CONFIG_SOC_SERIES_STM32U5X) +#include +#else +#include #endif /** Common clock control device node for all STM32 chips */ @@ -160,6 +162,20 @@ #define STM32_MSIS_ENABLED 1 #define STM32_MSIS_RANGE DT_PROP(DT_NODELABEL(clk_msis), msi_range) #define STM32_MSIS_PLL_MODE DT_PROP(DT_NODELABEL(clk_msis), msi_pll_mode) +#else +#define STM32_MSIS_ENABLED 0 +#define STM32_MSIS_RANGE 0 +#define STM32_MSIS_PLL_MODE 0 +#endif + +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msik), st_stm32u5_msi_clock, okay) +#define STM32_MSIK_ENABLED 1 +#define STM32_MSIK_RANGE DT_PROP(DT_NODELABEL(clk_msik), msi_range) +#define STM32_MSIK_PLL_MODE DT_PROP(DT_NODELABEL(clk_msik), msi_pll_mode) +#else +#define STM32_MSIK_ENABLED 0 +#define STM32_MSIK_RANGE 0 +#define STM32_MSIK_PLL_MODE 0 #endif #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_csi), fixed_clock, okay) @@ -176,7 +192,10 @@ #define STM32_LSI_FREQ 0 #endif -#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), st_stm32h7_hsi_clock, okay) +#if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), fixed_clock, okay) +#define STM32_HSI_ENABLED 1 +#define STM32_HSI_FREQ DT_PROP(DT_NODELABEL(clk_hsi), clock_frequency) +#elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), st_stm32h7_hsi_clock, okay) #define STM32_HSI_ENABLED 1 #define STM32_HSI_DIVISOR DT_PROP(DT_NODELABEL(clk_hsi), hsi_div) #define STM32_HSI_FREQ DT_PROP(DT_NODELABEL(clk_hsi), clock_frequency)