diff --git a/drivers/clock_control/clock_stm32_ll_common.c b/drivers/clock_control/clock_stm32_ll_common.c index 09a1bc331c7..726e13d9ee3 100644 --- a/drivers/clock_control/clock_stm32_ll_common.c +++ b/drivers/clock_control/clock_stm32_ll_common.c @@ -16,6 +16,7 @@ #include #include #include "clock_stm32_ll_common.h" +#include "stm32_hsem.h" /* Macros to fill up prescaler values */ #define fn_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v @@ -35,7 +36,6 @@ #define fn_mco2_prescaler(v) LL_RCC_MCO2_DIV_ ## v #define mco2_prescaler(v) fn_mco2_prescaler(v) - #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler) #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler @@ -52,6 +52,84 @@ static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler) return clock / prescaler; } +__unused +static uint32_t get_msi_frequency(void) +{ +#if defined(STM32_MSI_ENABLED) +#if !defined(LL_RCC_MSIRANGESEL_RUN) + return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange()); +#else + return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, + LL_RCC_MSI_GetRange()); +#endif +#endif + return 0; +} + +/** @brief Verifies clock is part of active clock configuration */ +__unused +static int enabled_clock(uint32_t src_clk) +{ + int r = 0; + + switch (src_clk) { +#if defined(STM32_SRC_SYSCLK) + case STM32_SRC_SYSCLK: + break; +#endif /* STM32_SRC_SYSCLK */ +#if defined(STM32_SRC_PCLK) + case STM32_SRC_PCLK: + break; +#endif /* STM32_SRC_PCLK */ +#if defined(STM32_SRC_HSE) + case STM32_SRC_HSE: + if (!IS_ENABLED(STM32_HSE_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_HSE */ +#if defined(STM32_SRC_HSI) + case STM32_SRC_HSI: + if (!IS_ENABLED(STM32_HSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_HSI */ +#if defined(STM32_SRC_LSE) + case STM32_SRC_LSE: + if (!IS_ENABLED(STM32_LSE_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_LSE */ +#if defined(STM32_SRC_LSI) + case STM32_SRC_LSI: + if (!IS_ENABLED(STM32_LSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_LSI */ +#if defined(STM32_SRC_MSI) + case STM32_SRC_MSI: + if (!IS_ENABLED(STM32_MSI_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_MSI */ +#if defined(STM32_SRC_PLLCLK) + case STM32_SRC_PLLCLK: + if (!IS_ENABLED(STM32_PLL_ENABLED)) { + r = -ENOTSUP; + } + break; +#endif /* STM32_SRC_PLLCLK */ + default: + return -ENOTSUP; + } + + return r; +} + static inline int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system) { @@ -69,7 +147,6 @@ static inline int stm32_clock_control_on(const struct device *dev, return 0; } - static inline int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system) { @@ -92,6 +169,40 @@ static inline int stm32_clock_control_off(const struct device *dev, return 0; } +static inline int stm32_clock_control_configure(const struct device *dev, + clock_control_subsys_t sub_system, + void *data) +{ +#if defined(STM32_SRC_CLOCK_MIN) + /* At least one alt src clock available */ + struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system); + volatile uint32_t *reg; + uint32_t reg_val, dt_val; + int err; + + ARG_UNUSED(dev); + ARG_UNUSED(data); + + err = enabled_clock(pclken->bus); + if (err < 0) { + /* Attempt to configure a src clock not available or not valid */ + return err; + } + + dt_val = STM32_CLOCK_VAL_GET(pclken->enr) << + STM32_CLOCK_SHIFT_GET(pclken->enr); + reg = (uint32_t *)(DT_REG_ADDR(DT_NODELABEL(rcc)) + + STM32_CLOCK_REG_GET(pclken->enr)); + reg_val = *reg; + reg_val |= dt_val; + *reg = reg_val; + + return 0; +#else + /* No src clock available: Not supported */ + return -ENOTSUP; +#endif +} static int stm32_clock_control_get_subsys_rate(const struct device *clock, clock_control_subsys_t sub_system, @@ -120,6 +231,14 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, uint32_t ahb3_clock = ahb_clock; #endif +#if defined(STM32_SRC_PCLK) + if (pclken->bus == STM32_SRC_PCLK) { + /* STM32_SRC_PCLK can't be used to request a subsys freq */ + /* Use STM32_CLOCK_BUS_FOO instead. */ + return -ENOTSUP; + } +#endif + ARG_UNUSED(clock); switch (pclken->bus) { @@ -153,6 +272,39 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock, /* STM32WL: AHB3 and APB3 share the same clock and prescaler. */ *rate = ahb3_clock; break; +#endif +#if defined(STM32_SRC_SYSCLK) + case STM32_SRC_SYSCLK: + *rate = SystemCoreClock * STM32_CORE_PRESCALER; + break; +#endif +#if defined(STM32_SRC_PLLCLK) & defined(STM32_SYSCLK_SRC_PLL) + case STM32_SRC_PLLCLK: + if (get_pllout_frequency() == 0) { + return -EIO; + } + *rate = get_pllout_frequency(); + break; +#endif +#if defined(STM32_SRC_LSE) + case STM32_SRC_LSE: + *rate = STM32_LSE_FREQ; + break; +#endif +#if defined(STM32_SRC_LSI) + case STM32_SRC_LSI: + *rate = STM32_LSI_FREQ; + break; +#endif +#if defined(STM32_SRC_HSI) + case STM32_SRC_HSI: + *rate = STM32_HSI_FREQ; + break; +#endif +#if defined(STM32_SRC_HSE) + case STM32_SRC_HSE: + *rate = STM32_HSE_FREQ; + break; #endif default: return -ENOTSUP; @@ -165,6 +317,7 @@ static struct clock_control_driver_api stm32_clock_control_api = { .on = stm32_clock_control_on, .off = stm32_clock_control_off, .get_rate = stm32_clock_control_get_subsys_rate, + .configure = stm32_clock_control_configure, }; /* @@ -206,10 +359,9 @@ static inline void stm32_clock_control_mco_init(void) } __unused -static int set_up_plls(void) +static void set_up_plls(void) { #if defined(STM32_PLL_ENABLED) - int r; /* * Case of chain-loaded applications: @@ -245,10 +397,7 @@ static int set_up_plls(void) << RCC_PLLCFGR_PLLQ_Pos); #endif - r = config_pll_sysclock(); - if (r < 0) { - return -ENOTSUP; - } + config_pll_sysclock(); /* Enable PLL */ LL_RCC_PLL_Enable(); @@ -257,8 +406,6 @@ static int set_up_plls(void) } #endif /* STM32_PLL_ENABLED */ - - return 0; } static void set_up_fixed_clock_sources(void) @@ -328,6 +475,44 @@ static void set_up_fixed_clock_sources(void) } #endif /* STM32_MSI_ENABLED */ + if (IS_ENABLED(STM32_LSI_ENABLED)) { +#if defined(CONFIG_SOC_SERIES_STM32WBX) + LL_RCC_LSI1_Enable(); + while (LL_RCC_LSI1_IsReady() != 1) { + } +#else + LL_RCC_LSI_Enable(); + while (LL_RCC_LSI_IsReady() != 1) { + } +#endif + } + + if (IS_ENABLED(STM32_LSE_ENABLED)) { + /* LSE belongs to the back-up domain, enable access.*/ + + z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); + + /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ + LL_PWR_EnableBkUpAccess(); + while (!LL_PWR_IsEnabledBkUpAccess()) { + /* Wait for Backup domain access */ + } + +#if STM32_LSE_DRIVING + /* Configure driving capability */ + LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); +#endif + + /* Enable LSE Oscillator (32.768 kHz) */ + LL_RCC_LSE_Enable(); + while (!LL_RCC_LSE_IsReady()) { + /* Wait for LSE ready */ + } + + LL_PWR_DisableBkUpAccess(); + + z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); + } } /** @@ -344,8 +529,6 @@ static void set_up_fixed_clock_sources(void) */ int stm32_clock_control_init(const struct device *dev) { - int r; - ARG_UNUSED(dev); /* Some clocks would be activated by default */ @@ -371,10 +554,7 @@ int stm32_clock_control_init(const struct device *dev) set_up_fixed_clock_sources(); /* Set up PLLs */ - r = set_up_plls(); - if (r < 0) { - return r; - } + set_up_plls(); if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) && (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1) && diff --git a/drivers/clock_control/clock_stm32_ll_common.h b/drivers/clock_control/clock_stm32_ll_common.h index 7db724c7f74..69280245c1f 100644 --- a/drivers/clock_control/clock_stm32_ll_common.h +++ b/drivers/clock_control/clock_stm32_ll_common.h @@ -33,7 +33,8 @@ #endif #ifdef STM32_SYSCLK_SRC_PLL -int config_pll_sysclock(void); +void config_pll_sysclock(void); +uint32_t get_pllout_frequency(void); #endif void config_enable_default_clocks(void); diff --git a/drivers/clock_control/clock_stm32f0_f3.c b/drivers/clock_control/clock_stm32f0_f3.c index f4bafff3d30..5b9aa0d6e21 100644 --- a/drivers/clock_control/clock_stm32f0_f3.c +++ b/drivers/clock_control/clock_stm32f0_f3.c @@ -15,13 +15,13 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +__unused +void config_pll_sysclock(void) { uint32_t pll_source, pll_mul, pll_div; @@ -59,7 +59,7 @@ int config_pll_sysclock(void) } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { pll_source = LL_RCC_PLLSOURCE_HSI; } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul, pll_div); @@ -70,13 +70,71 @@ int config_pll_sysclock(void) } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { pll_source = LL_RCC_PLLSOURCE_HSI_DIV_2; } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul); #endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ +} - return 0; +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + uint32_t pll_input_freq, pll_mul, pll_div; + + /* + * PLL MUL + * 2 -> LL_RCC_PLL_MUL_2 -> 0x00000000 + * 3 -> LL_RCC_PLL_MUL_3 -> 0x00040000 + * 4 -> LL_RCC_PLL_MUL_4 -> 0x00080000 + * ... + * 16 -> LL_RCC_PLL_MUL_16 -> 0x00380000 + */ + pll_mul = ((STM32_PLL_MULTIPLIER - 2) << RCC_CFGR_PLLMUL_Pos); + + /* + * PLL PREDIV + * 1 -> LL_RCC_PREDIV_DIV_1 -> 0x00000000 + * 2 -> LL_RCC_PREDIV_DIV_2 -> 0x00000001 + * 3 -> LL_RCC_PREDIV_DIV_3 -> 0x00000002 + * ... + * 16 -> LL_RCC_PREDIV_DIV_16 -> 0x0000000F + */ + pll_div = STM32_PLL_PREDIV - 1; + +#if defined(RCC_PLLSRC_PREDIV1_SUPPORT) + /* + * PREDIV1 support is a specific RCC configuration present on + * following SoCs: STM32F04xx, STM32F07xx, STM32F09xx, + * STM32F030xC, STM32F302xE, STM32F303xE and STM32F39xx + * cf Reference manual for more details + */ + + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + pll_input_freq = STM32_HSE_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + pll_input_freq = STM32_HSI_FREQ; + } else { + return 0; + } + + return __LL_RCC_CALC_PLLCLK_FREQ(pll_input_freq, pll_mul, pll_div); +#else + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + pll_input_freq = STM32_HSE_FREQ; + } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + pll_input_freq = STM32_HSI_FREQ / 2; + } else { + return 0; + } + + return __LL_RCC_CALC_PLLCLK_FREQ(pll_input_freq, pll_mul); +#endif /* RCC_PLLSRC_PREDIV1_SUPPORT */ } #endif /* STM32_SYSCLK_SRC_PLL */ diff --git a/drivers/clock_control/clock_stm32f1.c b/drivers/clock_control/clock_stm32f1.c index 41ff680e1f7..879bd86c014 100644 --- a/drivers/clock_control/clock_stm32f1.c +++ b/drivers/clock_control/clock_stm32f1.c @@ -15,8 +15,8 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL + /* * Select PLL source for STM32F1 Connectivity line devices (STM32F105xx and * STM32F107xx). @@ -26,7 +26,8 @@ /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +__unused +void config_pll_sysclock(void) { uint32_t pll_source, pll_mul, pll_div; @@ -88,13 +89,12 @@ int config_pll_sysclock(void) pll_source = LL_RCC_PLLSOURCE_PLL2 | pll_div; #endif } else { - return -ENOTSUP; + __ASSERT(0, "Invalid source"); } LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul); - - return 0; } + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32f2_f4_f7.c b/drivers/clock_control/clock_stm32f2_f4_f7.c index 02ceccf8ddf..7475fb246fc 100644 --- a/drivers/clock_control/clock_stm32f2_f4_f7.c +++ b/drivers/clock_control/clock_stm32f2_f4_f7.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up division factors values */ @@ -26,29 +25,45 @@ #define pllp(v) z_pllp(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_p; - - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_p = pllp(STM32_PLL_P_DIVISOR); - - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_p); - + __ASSERT(0, "Invalid source"); return 0; } + +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllp(STM32_PLL_P_DIVISOR)); +} + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllp(STM32_PLL_P_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32g0.c b/drivers/clock_control/clock_stm32g0.c index c707f3fd35d..d32646a3a94 100644 --- a/drivers/clock_control/clock_stm32g0.c +++ b/drivers/clock_control/clock_stm32g0.c @@ -16,7 +16,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up multiplication and division factors values */ @@ -27,31 +26,49 @@ #define pllr(v) z_pllr(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; - - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pll_div(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); - - LL_RCC_PLL_EnableDomain_SYS(); - + __ASSERT(0, "Invalid source"); return 0; } + +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pll_div(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); + + LL_RCC_PLL_EnableDomain_SYS(); +} + + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pll_div(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32g4.c b/drivers/clock_control/clock_stm32g4.c index 8dfb3ccb188..2af65bf6041 100644 --- a/drivers/clock_control/clock_stm32g4.c +++ b/drivers/clock_control/clock_stm32g4.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up division factors values */ @@ -25,37 +24,54 @@ #define z_pllr(v) LL_RCC_PLLR_DIV_ ## v #define pllr(v) z_pllr(v) +/** + * @brief Return PLL source + */ +__unused +static uint32_t get_pll_source(void) +{ + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + return LL_RCC_PLLSOURCE_HSI; + } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + return LL_RCC_PLLSOURCE_HSE; + } + + __ASSERT(0, "Invalid source"); + return 0; +} + /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +__unused +void config_pll_sysclock(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; - /* set power boost mode for sys clock greater than 150MHz */ if (sys_clock_hw_cycles_per_sec() >= MHZ(150)) { LL_PWR_EnableRange1BoostMode(); } - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - - /* Configure PLL source */ - if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; - } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; - } - - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); LL_RCC_PLL_EnableDomain_SYS(); - - return 0; } + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** @@ -65,24 +81,4 @@ void config_enable_default_clocks(void) { /* Enable the power interface clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); - -#if STM32_LSE_ENABLED - /* LSE belongs to the back-up domain, enable access.*/ - - /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ - LL_PWR_EnableBkUpAccess(); - while (!LL_PWR_IsEnabledBkUpAccess()) { - /* Wait for Backup domain access */ - } - - /* Configure driving capability */ - LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); - /* Enable LSE Oscillator (32.768 kHz) */ - LL_RCC_LSE_Enable(); - while (!LL_RCC_LSE_IsReady()) { - /* Wait for LSE ready */ - } - - LL_PWR_DisableBkUpAccess(); -#endif } diff --git a/drivers/clock_control/clock_stm32l0_l1.c b/drivers/clock_control/clock_stm32l0_l1.c index 82f17d342ba..2a4d5e8ecbe 100644 --- a/drivers/clock_control/clock_stm32l0_l1.c +++ b/drivers/clock_control/clock_stm32l0_l1.c @@ -15,7 +15,6 @@ #include #include "clock_stm32_ll_common.h" - #if STM32_SYSCLK_SRC_PLL /* Macros to fill up multiplication and division factors values */ @@ -26,29 +25,44 @@ #define pll_div(v) z_pll_div(v) /** - * @brief Set up pll configuration + * @brief Return PLL source */ -int config_pll_sysclock(void) +__unused +static uint32_t get_pll_source(void) { - uint32_t pll_source, pll_mul, pll_div; - - pll_mul = pll_mul(STM32_PLL_MULTIPLIER); - pll_div = pll_div(STM32_PLL_DIVISOR); - /* Configure PLL source */ if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; + return LL_RCC_PLLSOURCE_HSI; } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else { - return -ENOTSUP; + return LL_RCC_PLLSOURCE_HSE; } - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_mul, pll_div); - + __ASSERT(0, "Invalid source"); return 0; } +/** + * @brief Set up pll configuration + */ +__unused +void config_pll_sysclock(void) +{ + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pll_mul(STM32_PLL_MULTIPLIER), + pll_div(STM32_PLL_DIVISOR)); +} + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pll_mul(STM32_PLL_MULTIPLIER), + pll_div(STM32_PLL_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** diff --git a/drivers/clock_control/clock_stm32l4_l5_wb_wl.c b/drivers/clock_control/clock_stm32l4_l5_wb_wl.c index 1ad33315254..0fa87a62521 100644 --- a/drivers/clock_control/clock_stm32l4_l5_wb_wl.c +++ b/drivers/clock_control/clock_stm32l4_l5_wb_wl.c @@ -15,7 +15,6 @@ #include #include #include "clock_stm32_ll_common.h" -#include "stm32_hsem.h" #if STM32_SYSCLK_SRC_PLL @@ -26,13 +25,30 @@ #define z_pllr(v) LL_RCC_PLLR_DIV_ ## v #define pllr(v) z_pllr(v) +/** + * @brief Return PLL source + */ +__unused +static uint32_t get_pll_source(void) +{ + /* Configure PLL source */ + if (IS_ENABLED(STM32_PLL_SRC_HSI)) { + return LL_RCC_PLLSOURCE_HSI; + } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { + return LL_RCC_PLLSOURCE_HSE; + } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) { + return LL_RCC_PLLSOURCE_MSI; + } + + __ASSERT(0, "Invalid source"); + return 0; +} + /** * @brief Set up pll configuration */ -int config_pll_sysclock(void) +void config_pll_sysclock(void) { - uint32_t pll_source, pll_m, pll_n, pll_r; - #ifdef PWR_CR5_R1MODE /* set power boost mode for sys clock greater than 80MHz */ if (sys_clock_hw_cycles_per_sec() >= MHZ(80)) { @@ -40,27 +56,26 @@ int config_pll_sysclock(void) } #endif /* PWR_CR5_R1MODE */ - pll_n = STM32_PLL_N_MULTIPLIER; - pll_m = pllm(STM32_PLL_M_DIVISOR); - pll_r = pllr(STM32_PLL_R_DIVISOR); - - /* Configure PLL source */ - if (IS_ENABLED(STM32_PLL_SRC_HSI)) { - pll_source = LL_RCC_PLLSOURCE_HSI; - } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) { - pll_source = LL_RCC_PLLSOURCE_HSE; - } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) { - pll_source = LL_RCC_PLLSOURCE_MSI; - } else { - return -ENOTSUP; - } - - LL_RCC_PLL_ConfigDomain_SYS(pll_source, pll_m, pll_n, pll_r); + LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); LL_RCC_PLL_EnableDomain_SYS(); - - return 0; } + +/** + * @brief Return pllout frequency + */ +__unused +uint32_t get_pllout_frequency(void) +{ + return __LL_RCC_CALC_PLLCLK_FREQ(get_pll_source(), + pllm(STM32_PLL_M_DIVISOR), + STM32_PLL_N_MULTIPLIER, + pllr(STM32_PLL_R_DIVISOR)); +} + #endif /* STM32_SYSCLK_SRC_PLL */ /** @@ -72,33 +87,8 @@ void config_enable_default_clocks(void) /* Enable the power interface clock */ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR); #endif - -#if STM32_LSE_ENABLED - /* LSE belongs to the back-up domain, enable access.*/ - #if defined(CONFIG_SOC_SERIES_STM32WBX) /* HW semaphore Clock enable */ LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_HSEM); -#endif - z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY); - - /* Set the DBP bit in the Power control register 1 (PWR_CR1) */ - LL_PWR_EnableBkUpAccess(); - while (!LL_PWR_IsEnabledBkUpAccess()) { - /* Wait for Backup domain access */ - } - - /* Configure driving capability */ - LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos); - /* Enable LSE Oscillator (32.768 kHz) */ - LL_RCC_LSE_Enable(); - while (!LL_RCC_LSE_IsReady()) { - /* Wait for LSE ready */ - } - - LL_PWR_DisableBkUpAccess(); - - z_stm32_hsem_unlock(CFG_HW_RCC_SEMID); - #endif }