1616#include <zephyr/sys/__assert.h>
1717#include <zephyr/drivers/clock_control/stm32_clock_control.h>
1818#include "clock_stm32_ll_common.h"
19+ #include "stm32_hsem.h"
1920
2021/* Macros to fill up prescaler values */
2122#define fn_ahb_prescaler (v ) LL_RCC_SYSCLK_DIV_ ## v
3536#define fn_mco2_prescaler (v ) LL_RCC_MCO2_DIV_ ## v
3637#define mco2_prescaler (v ) fn_mco2_prescaler(v)
3738
38-
3939#if DT_NODE_HAS_PROP (DT_NODELABEL (rcc ), ahb4_prescaler )
4040#define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ
4141#define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler
@@ -52,6 +52,84 @@ static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
5252 return clock / prescaler ;
5353}
5454
55+ __unused
56+ static uint32_t get_msi_frequency (void )
57+ {
58+ #if defined(STM32_MSI_ENABLED )
59+ #if !defined(LL_RCC_MSIRANGESEL_RUN )
60+ return __LL_RCC_CALC_MSI_FREQ (LL_RCC_MSI_GetRange ());
61+ #else
62+ return __LL_RCC_CALC_MSI_FREQ (LL_RCC_MSIRANGESEL_RUN ,
63+ LL_RCC_MSI_GetRange ());
64+ #endif
65+ #endif
66+ return 0 ;
67+ }
68+
69+ /** @brief Verifies clock is part of active clock configuration */
70+ __unused
71+ static int enabled_clock (uint32_t src_clk )
72+ {
73+ int r = 0 ;
74+
75+ switch (src_clk ) {
76+ #if defined(STM32_SRC_SYSCLK )
77+ case STM32_SRC_SYSCLK :
78+ break ;
79+ #endif /* STM32_SRC_SYSCLK */
80+ #if defined(STM32_SRC_PCLK )
81+ case STM32_SRC_PCLK :
82+ break ;
83+ #endif /* STM32_SRC_PCLK */
84+ #if defined(STM32_SRC_HSE )
85+ case STM32_SRC_HSE :
86+ if (!IS_ENABLED (STM32_HSE_ENABLED )) {
87+ r = - ENOTSUP ;
88+ }
89+ break ;
90+ #endif /* STM32_SRC_HSE */
91+ #if defined(STM32_SRC_HSI )
92+ case STM32_SRC_HSI :
93+ if (!IS_ENABLED (STM32_HSI_ENABLED )) {
94+ r = - ENOTSUP ;
95+ }
96+ break ;
97+ #endif /* STM32_SRC_HSI */
98+ #if defined(STM32_SRC_LSE )
99+ case STM32_SRC_LSE :
100+ if (!IS_ENABLED (STM32_LSE_ENABLED )) {
101+ r = - ENOTSUP ;
102+ }
103+ break ;
104+ #endif /* STM32_SRC_LSE */
105+ #if defined(STM32_SRC_LSI )
106+ case STM32_SRC_LSI :
107+ if (!IS_ENABLED (STM32_LSI_ENABLED )) {
108+ r = - ENOTSUP ;
109+ }
110+ break ;
111+ #endif /* STM32_SRC_LSI */
112+ #if defined(STM32_SRC_MSI )
113+ case STM32_SRC_MSI :
114+ if (!IS_ENABLED (STM32_MSI_ENABLED )) {
115+ r = - ENOTSUP ;
116+ }
117+ break ;
118+ #endif /* STM32_SRC_MSI */
119+ #if defined(STM32_SRC_PLLCLK )
120+ case STM32_SRC_PLLCLK :
121+ if (!IS_ENABLED (STM32_PLL_ENABLED )) {
122+ r = - ENOTSUP ;
123+ }
124+ break ;
125+ #endif /* STM32_SRC_PLLCLK */
126+ default :
127+ return - ENOTSUP ;
128+ }
129+
130+ return r ;
131+ }
132+
55133static inline int stm32_clock_control_on (const struct device * dev ,
56134 clock_control_subsys_t sub_system )
57135{
@@ -69,7 +147,6 @@ static inline int stm32_clock_control_on(const struct device *dev,
69147 return 0 ;
70148}
71149
72-
73150static inline int stm32_clock_control_off (const struct device * dev ,
74151 clock_control_subsys_t sub_system )
75152{
@@ -92,6 +169,40 @@ static inline int stm32_clock_control_off(const struct device *dev,
92169 return 0 ;
93170}
94171
172+ static inline int stm32_clock_control_configure (const struct device * dev ,
173+ clock_control_subsys_t sub_system ,
174+ void * data )
175+ {
176+ #if defined(STM32_SRC_CLOCK_MIN )
177+ /* At least one alt src clock available */
178+ struct stm32_pclken * pclken = (struct stm32_pclken * )(sub_system );
179+ volatile uint32_t * reg ;
180+ uint32_t reg_val , dt_val ;
181+ int err ;
182+
183+ ARG_UNUSED (dev );
184+ ARG_UNUSED (data );
185+
186+ err = enabled_clock (pclken -> bus );
187+ if (err < 0 ) {
188+ /* Attempt to configure a src clock not available or not valid */
189+ return err ;
190+ }
191+
192+ dt_val = STM32_CLOCK_VAL_GET (pclken -> enr ) <<
193+ STM32_CLOCK_SHIFT_GET (pclken -> enr );
194+ reg = (uint32_t * )(DT_REG_ADDR (DT_NODELABEL (rcc )) +
195+ STM32_CLOCK_REG_GET (pclken -> enr ));
196+ reg_val = * reg ;
197+ reg_val |= dt_val ;
198+ * reg = reg_val ;
199+
200+ return 0 ;
201+ #else
202+ /* No src clock available: Not supported */
203+ return - ENOTSUP ;
204+ #endif
205+ }
95206
96207static int stm32_clock_control_get_subsys_rate (const struct device * clock ,
97208 clock_control_subsys_t sub_system ,
@@ -120,6 +231,14 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
120231 uint32_t ahb3_clock = ahb_clock ;
121232#endif
122233
234+ #if defined(STM32_SRC_PCLK )
235+ if (pclken -> bus == STM32_SRC_PCLK ) {
236+ /* STM32_SRC_PCLK can't be used to request a subsys freq */
237+ /* Use STM32_CLOCK_BUS_FOO instead. */
238+ return - ENOTSUP ;
239+ }
240+ #endif
241+
123242 ARG_UNUSED (clock );
124243
125244 switch (pclken -> bus ) {
@@ -153,6 +272,39 @@ static int stm32_clock_control_get_subsys_rate(const struct device *clock,
153272 /* STM32WL: AHB3 and APB3 share the same clock and prescaler. */
154273 * rate = ahb3_clock ;
155274 break ;
275+ #endif
276+ #if defined(STM32_SRC_SYSCLK )
277+ case STM32_SRC_SYSCLK :
278+ * rate = SystemCoreClock * STM32_CORE_PRESCALER ;
279+ break ;
280+ #endif
281+ #if defined(STM32_SRC_PLLCLK ) & defined(STM32_SYSCLK_SRC_PLL )
282+ case STM32_SRC_PLLCLK :
283+ if (get_pllout_frequency () == 0 ) {
284+ return - EIO ;
285+ }
286+ * rate = get_pllout_frequency ();
287+ break ;
288+ #endif
289+ #if defined(STM32_SRC_LSE )
290+ case STM32_SRC_LSE :
291+ * rate = STM32_LSE_FREQ ;
292+ break ;
293+ #endif
294+ #if defined(STM32_SRC_LSI )
295+ case STM32_SRC_LSI :
296+ * rate = STM32_LSI_FREQ ;
297+ break ;
298+ #endif
299+ #if defined(STM32_SRC_HSI )
300+ case STM32_SRC_HSI :
301+ * rate = STM32_HSI_FREQ ;
302+ break ;
303+ #endif
304+ #if defined(STM32_SRC_HSE )
305+ case STM32_SRC_HSE :
306+ * rate = STM32_HSE_FREQ ;
307+ break ;
156308#endif
157309 default :
158310 return - ENOTSUP ;
@@ -165,6 +317,7 @@ static struct clock_control_driver_api stm32_clock_control_api = {
165317 .on = stm32_clock_control_on ,
166318 .off = stm32_clock_control_off ,
167319 .get_rate = stm32_clock_control_get_subsys_rate ,
320+ .configure = stm32_clock_control_configure ,
168321};
169322
170323/*
@@ -206,10 +359,9 @@ static inline void stm32_clock_control_mco_init(void)
206359}
207360
208361__unused
209- static int set_up_plls (void )
362+ static void set_up_plls (void )
210363{
211364#if defined(STM32_PLL_ENABLED )
212- int r ;
213365
214366 /*
215367 * Case of chain-loaded applications:
@@ -245,10 +397,7 @@ static int set_up_plls(void)
245397 << RCC_PLLCFGR_PLLQ_Pos );
246398#endif
247399
248- r = config_pll_sysclock ();
249- if (r < 0 ) {
250- return - ENOTSUP ;
251- }
400+ config_pll_sysclock ();
252401
253402 /* Enable PLL */
254403 LL_RCC_PLL_Enable ();
@@ -257,8 +406,6 @@ static int set_up_plls(void)
257406 }
258407
259408#endif /* STM32_PLL_ENABLED */
260-
261- return 0 ;
262409}
263410
264411static void set_up_fixed_clock_sources (void )
@@ -328,6 +475,44 @@ static void set_up_fixed_clock_sources(void)
328475 }
329476#endif /* STM32_MSI_ENABLED */
330477
478+ if (IS_ENABLED (STM32_LSI_ENABLED )) {
479+ #if defined(CONFIG_SOC_SERIES_STM32WBX )
480+ LL_RCC_LSI1_Enable ();
481+ while (LL_RCC_LSI1_IsReady () != 1 ) {
482+ }
483+ #else
484+ LL_RCC_LSI_Enable ();
485+ while (LL_RCC_LSI_IsReady () != 1 ) {
486+ }
487+ #endif
488+ }
489+
490+ if (IS_ENABLED (STM32_LSE_ENABLED )) {
491+ /* LSE belongs to the back-up domain, enable access.*/
492+
493+ z_stm32_hsem_lock (CFG_HW_RCC_SEMID , HSEM_LOCK_DEFAULT_RETRY );
494+
495+ /* Set the DBP bit in the Power control register 1 (PWR_CR1) */
496+ LL_PWR_EnableBkUpAccess ();
497+ while (!LL_PWR_IsEnabledBkUpAccess ()) {
498+ /* Wait for Backup domain access */
499+ }
500+
501+ #if STM32_LSE_DRIVING
502+ /* Configure driving capability */
503+ LL_RCC_LSE_SetDriveCapability (STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos );
504+ #endif
505+
506+ /* Enable LSE Oscillator (32.768 kHz) */
507+ LL_RCC_LSE_Enable ();
508+ while (!LL_RCC_LSE_IsReady ()) {
509+ /* Wait for LSE ready */
510+ }
511+
512+ LL_PWR_DisableBkUpAccess ();
513+
514+ z_stm32_hsem_unlock (CFG_HW_RCC_SEMID );
515+ }
331516}
332517
333518/**
@@ -344,8 +529,6 @@ static void set_up_fixed_clock_sources(void)
344529 */
345530int stm32_clock_control_init (const struct device * dev )
346531{
347- int r ;
348-
349532 ARG_UNUSED (dev );
350533
351534 /* Some clocks would be activated by default */
@@ -371,10 +554,7 @@ int stm32_clock_control_init(const struct device *dev)
371554 set_up_fixed_clock_sources ();
372555
373556 /* Set up PLLs */
374- r = set_up_plls ();
375- if (r < 0 ) {
376- return r ;
377- }
557+ set_up_plls ();
378558
379559 if (DT_PROP (DT_NODELABEL (rcc ), undershoot_prevention ) &&
380560 (STM32_CORE_PRESCALER == LL_RCC_SYSCLK_DIV_1 ) &&
0 commit comments