1 /*
2 * Copyright (c) 2017-2022 Linaro Limited.
3 * Copyright (c) 2017 RnDity Sp. z o.o.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #include <soc.h>
9 #include <stm32_ll_bus.h>
10 #include <stm32_ll_pwr.h>
11 #include <stm32_ll_rcc.h>
12 #include <stm32_ll_system.h>
13 #include <stm32_ll_utils.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/drivers/clock_control.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/sys/__assert.h>
18 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
19 #include "clock_stm32_ll_common.h"
20 #include "stm32_hsem.h"
21
22 /* Macros to fill up prescaler values */
23 #define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v
24 #define hsi_divider(v) z_hsi_divider(v)
25
26 #if defined(LL_RCC_HCLK_DIV_1)
27 #define fn_ahb_prescaler(v) LL_RCC_HCLK_DIV_ ## v
28 #define ahb_prescaler(v) fn_ahb_prescaler(v)
29 #else
30 #define fn_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
31 #define ahb_prescaler(v) fn_ahb_prescaler(v)
32 #endif
33
34 #define fn_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
35 #define apb1_prescaler(v) fn_apb1_prescaler(v)
36
37 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
38 #define fn_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
39 #define apb2_prescaler(v) fn_apb2_prescaler(v)
40 #endif
41
42 #if defined(RCC_CFGR_ADCPRE)
43 #define z_adc12_prescaler(v) LL_RCC_ADC_CLKSRC_PCLK2_DIV_ ## v
44 #define adc12_prescaler(v) z_adc12_prescaler(v)
45 #elif defined(RCC_CFGR2_ADC1PRES)
46 #define z_adc12_prescaler(v) \
47 COND_CODE_1(IS_EQ(v, 0), \
48 LL_RCC_ADC1_CLKSRC_HCLK, \
49 LL_RCC_ADC1_CLKSRC_PLL_DIV_ ## v)
50 #define adc12_prescaler(v) z_adc12_prescaler(v)
51 #else
52 #define z_adc12_prescaler(v) \
53 COND_CODE_1(IS_EQ(v, 0), \
54 (LL_RCC_ADC12_CLKSRC_HCLK), \
55 (LL_RCC_ADC12_CLKSRC_PLL_DIV_ ## v))
56 #define adc12_prescaler(v) z_adc12_prescaler(v)
57 #define z_adc34_prescaler(v) \
58 COND_CODE_1(IS_EQ(v, 0), \
59 (LL_RCC_ADC34_CLKSRC_HCLK), \
60 (LL_RCC_ADC34_CLKSRC_PLL_DIV_ ## v))
61 #define adc34_prescaler(v) z_adc34_prescaler(v)
62 #endif
63
64 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
65 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ
66 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler
67 #elif DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
68 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK3_FREQ
69 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB3Prescaler
70 #else
71 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK_FREQ
72 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHBPrescaler
73 #endif
74
75 #if defined(RCC_PLLCFGR_PLLPEN)
76 #define RCC_PLLP_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN)
77 #else
78 #define RCC_PLLP_ENABLE()
79 #endif /* RCC_PLLCFGR_PLLPEN */
80 #if defined(RCC_PLLCFGR_PLLQEN)
81 #define RCC_PLLQ_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)
82 #else
83 #define RCC_PLLQ_ENABLE()
84 #endif /* RCC_PLLCFGR_PLLQEN */
85
86 /**
87 * @brief Return frequency for pll with 2 dividers and a multiplier
88 */
89 __unused
get_pll_div_frequency(uint32_t pllsrc_freq,int pllm_div,int plln_mul,int pllout_div)90 static uint32_t get_pll_div_frequency(uint32_t pllsrc_freq,
91 int pllm_div,
92 int plln_mul,
93 int pllout_div)
94 {
95 __ASSERT_NO_MSG(pllm_div && pllout_div);
96
97 return pllsrc_freq / pllm_div * plln_mul / pllout_div;
98 }
99
get_bus_clock(uint32_t clock,uint32_t prescaler)100 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
101 {
102 return clock / prescaler;
103 }
104
105 __unused
get_msi_frequency(void)106 static uint32_t get_msi_frequency(void)
107 {
108 #if defined(STM32_MSI_ENABLED)
109 #if !defined(LL_RCC_MSIRANGESEL_RUN)
110 return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
111 #else
112 return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN,
113 LL_RCC_MSI_GetRange());
114 #endif
115 #endif
116 return 0;
117 }
118
119 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)120 int enabled_clock(uint32_t src_clk)
121 {
122 int r = 0;
123
124 switch (src_clk) {
125 case STM32_SRC_SYSCLK:
126 break;
127 #if defined(STM32_SRC_PCLK)
128 case STM32_SRC_PCLK:
129 break;
130 #endif /* STM32_SRC_PCLK */
131 #if defined(STM32_SRC_HSE)
132 case STM32_SRC_HSE:
133 if (!IS_ENABLED(STM32_HSE_ENABLED)) {
134 r = -ENOTSUP;
135 }
136 break;
137 #endif /* STM32_SRC_HSE */
138 #if defined(STM32_SRC_EXT_HSE)
139 case STM32_SRC_EXT_HSE:
140 /* EXT_HSE is the raw OSC_IN signal, so it is always
141 * available, regardless of the clocks configuration.
142 */
143 break;
144 #endif /* STM32_SRC_HSE */
145 #if defined(STM32_SRC_HSI)
146 case STM32_SRC_HSI:
147 if (!IS_ENABLED(STM32_HSI_ENABLED)) {
148 r = -ENOTSUP;
149 }
150 break;
151 #endif /* STM32_SRC_HSI */
152 #if defined(STM32_SRC_LSE)
153 case STM32_SRC_LSE:
154 if (!IS_ENABLED(STM32_LSE_ENABLED)) {
155 r = -ENOTSUP;
156 }
157 break;
158 #endif /* STM32_SRC_LSE */
159 #if defined(STM32_SRC_LSI)
160 case STM32_SRC_LSI:
161 if (!IS_ENABLED(STM32_LSI_ENABLED)) {
162 r = -ENOTSUP;
163 }
164 break;
165 #endif /* STM32_SRC_LSI */
166 #if defined(STM32_SRC_HSI14)
167 case STM32_SRC_HSI14:
168 if (!IS_ENABLED(STM32_HSI14_ENABLED)) {
169 r = -ENOTSUP;
170 }
171 break;
172 #endif /* STM32_SRC_HSI14 */
173 #if defined(STM32_SRC_HSI48)
174 case STM32_SRC_HSI48:
175 if (!IS_ENABLED(STM32_HSI48_ENABLED)) {
176 r = -ENOTSUP;
177 }
178 break;
179 #endif /* STM32_SRC_HSI48 */
180 #if defined(STM32_SRC_MSI)
181 case STM32_SRC_MSI:
182 if (!IS_ENABLED(STM32_MSI_ENABLED)) {
183 r = -ENOTSUP;
184 }
185 break;
186 #endif /* STM32_SRC_MSI */
187 #if defined(STM32_SRC_PLLCLK)
188 case STM32_SRC_PLLCLK:
189 if (!IS_ENABLED(STM32_PLL_ENABLED)) {
190 r = -ENOTSUP;
191 }
192 break;
193 #endif /* STM32_SRC_PLLCLK */
194 #if defined(STM32_SRC_PLL_P)
195 case STM32_SRC_PLL_P:
196 if (!IS_ENABLED(STM32_PLL_P_ENABLED)) {
197 r = -ENOTSUP;
198 }
199 break;
200 #endif /* STM32_SRC_PLL_P */
201 #if defined(STM32_SRC_PLL_Q)
202 case STM32_SRC_PLL_Q:
203 if (!IS_ENABLED(STM32_PLL_Q_ENABLED)) {
204 r = -ENOTSUP;
205 }
206 break;
207 #endif /* STM32_SRC_PLL_Q */
208 #if defined(STM32_SRC_PLL_R)
209 case STM32_SRC_PLL_R:
210 if (!IS_ENABLED(STM32_PLL_R_ENABLED)) {
211 r = -ENOTSUP;
212 }
213 break;
214 #endif /* STM32_SRC_PLL_R */
215 #if defined(STM32_SRC_PLLI2S_Q)
216 case STM32_SRC_PLLI2S_Q:
217 if (!IS_ENABLED(STM32_PLLI2S_Q_ENABLED)) {
218 r = -ENOTSUP;
219 }
220 break;
221 #endif /* STM32_SRC_PLLI2S_Q */
222 #if defined(STM32_SRC_PLLI2S_R)
223 case STM32_SRC_PLLI2S_R:
224 if (!IS_ENABLED(STM32_PLLI2S_R_ENABLED)) {
225 r = -ENOTSUP;
226 }
227 break;
228 #endif /* STM32_SRC_PLLI2S_R */
229 #if defined(STM32_SRC_PLL2CLK)
230 case STM32_SRC_PLL2CLK:
231 if (!IS_ENABLED(STM32_PLL2_ENABLED)) {
232 r = -ENOTSUP;
233 }
234 break;
235 #endif
236 #if defined(STM32_SRC_PLL3CLK)
237 case STM32_SRC_PLL3CLK:
238 if (!IS_ENABLED(STM32_PLL3_ENABLED)) {
239 r = -ENOTSUP;
240 }
241 break;
242 #endif
243 default:
244 return -ENOTSUP;
245 }
246
247 return r;
248 }
249
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)250 static inline int stm32_clock_control_on(const struct device *dev,
251 clock_control_subsys_t sub_system)
252 {
253 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
254 volatile int temp;
255
256 ARG_UNUSED(dev);
257
258 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
259 /* Attempt to change a wrong periph clock bit */
260 return -ENOTSUP;
261 }
262
263 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
264 pclken->enr);
265 /* Delay after enabling the clock, to allow it to become active.
266 * See (for example) RM0440 7.2.17
267 */
268 temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus);
269 UNUSED(temp);
270
271 return 0;
272 }
273
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)274 static inline int stm32_clock_control_off(const struct device *dev,
275 clock_control_subsys_t sub_system)
276 {
277 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
278
279 ARG_UNUSED(dev);
280
281 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
282 /* Attempt to toggle a wrong periph clock bit */
283 return -ENOTSUP;
284 }
285
286 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
287 pclken->enr);
288
289 return 0;
290 }
291
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)292 static inline int stm32_clock_control_configure(const struct device *dev,
293 clock_control_subsys_t sub_system,
294 void *data)
295 {
296 /* At least one alt src clock available */
297 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
298 int err;
299
300 ARG_UNUSED(dev);
301 ARG_UNUSED(data);
302
303 err = enabled_clock(pclken->bus);
304 if (err < 0) {
305 /* Attempt to configure a src clock not available or not valid */
306 return err;
307 }
308
309 if (pclken->enr == NO_SEL) {
310 /* Domain clock is fixed. Nothing to set. Exit */
311 return 0;
312 }
313
314 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
315 STM32_DT_CLKSEL_MASK_GET(pclken->enr) <<
316 STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
317 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
318 STM32_DT_CLKSEL_VAL_GET(pclken->enr) <<
319 STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
320
321 return 0;
322 }
323
stm32_clock_control_get_subsys_rate(const struct device * clock,clock_control_subsys_t sub_system,uint32_t * rate)324 static int stm32_clock_control_get_subsys_rate(const struct device *clock,
325 clock_control_subsys_t sub_system,
326 uint32_t *rate)
327 {
328 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
329 /*
330 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
331 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
332 * since it will be updated after clock configuration and hence
333 * more likely to contain actual clock speed
334 */
335 uint32_t ahb_clock = SystemCoreClock;
336 uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
337 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
338 uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
339 #elif defined(STM32_CLOCK_BUS_APB2)
340 /* APB2 bus exists, but w/o dedicated prescaler */
341 uint32_t apb2_clock = apb1_clock;
342 #endif
343 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
344 uint32_t ahb3_clock = get_bus_clock(ahb_clock * STM32_CPU1_PRESCALER,
345 STM32_AHB3_PRESCALER);
346 #elif defined(STM32_CLOCK_BUS_AHB3)
347 /* AHB3 bus exists, but w/o dedicated prescaler */
348 uint32_t ahb3_clock = ahb_clock;
349 #endif
350
351 #if defined(STM32_SRC_PCLK)
352 if (pclken->bus == STM32_SRC_PCLK) {
353 /* STM32_SRC_PCLK can't be used to request a subsys freq */
354 /* Use STM32_CLOCK_BUS_FOO instead. */
355 return -ENOTSUP;
356 }
357 #endif
358
359 ARG_UNUSED(clock);
360
361 switch (pclken->bus) {
362 case STM32_CLOCK_BUS_AHB1:
363 #if defined(STM32_CLOCK_BUS_AHB2)
364 case STM32_CLOCK_BUS_AHB2:
365 #endif
366 #if defined(STM32_CLOCK_BUS_IOP)
367 case STM32_CLOCK_BUS_IOP:
368 #endif
369 *rate = ahb_clock;
370 break;
371 #if defined(STM32_CLOCK_BUS_AHB3)
372 case STM32_CLOCK_BUS_AHB3:
373 *rate = ahb3_clock;
374 break;
375 #endif
376 case STM32_CLOCK_BUS_APB1:
377 #if defined(STM32_CLOCK_BUS_APB1_2)
378 case STM32_CLOCK_BUS_APB1_2:
379 #endif
380 *rate = apb1_clock;
381 break;
382 #if defined(STM32_CLOCK_BUS_APB2)
383 case STM32_CLOCK_BUS_APB2:
384 *rate = apb2_clock;
385 break;
386 #endif
387 #if defined(STM32_CLOCK_BUS_APB3)
388 case STM32_CLOCK_BUS_APB3:
389 /* STM32WL: AHB3 and APB3 share the same clock and prescaler. */
390 *rate = ahb3_clock;
391 break;
392 #endif
393 case STM32_SRC_SYSCLK:
394 *rate = SystemCoreClock * STM32_CORE_PRESCALER;
395 break;
396 #if defined(STM32_SRC_PLLCLK) & defined(STM32_SYSCLK_SRC_PLL)
397 case STM32_SRC_PLLCLK:
398 if (get_pllout_frequency() == 0) {
399 return -EIO;
400 }
401 *rate = get_pllout_frequency();
402 break;
403 #endif
404 #if defined(STM32_SRC_PLL_P) & STM32_PLL_P_ENABLED
405 case STM32_SRC_PLL_P:
406 *rate = get_pll_div_frequency(get_pllsrc_frequency(),
407 STM32_PLL_M_DIVISOR,
408 STM32_PLL_N_MULTIPLIER,
409 STM32_PLL_P_DIVISOR);
410 break;
411 #endif
412 #if defined(STM32_SRC_PLL_Q) & STM32_PLL_Q_ENABLED
413 case STM32_SRC_PLL_Q:
414 *rate = get_pll_div_frequency(get_pllsrc_frequency(),
415 STM32_PLL_M_DIVISOR,
416 STM32_PLL_N_MULTIPLIER,
417 STM32_PLL_Q_DIVISOR);
418 break;
419 #endif
420 #if defined(STM32_SRC_PLL_R) & STM32_PLL_R_ENABLED
421 case STM32_SRC_PLL_R:
422 *rate = get_pll_div_frequency(get_pllsrc_frequency(),
423 STM32_PLL_M_DIVISOR,
424 STM32_PLL_N_MULTIPLIER,
425 STM32_PLL_R_DIVISOR);
426 break;
427 #endif
428 #if defined(STM32_SRC_PLLI2S_Q) & STM32_PLLI2S_Q_ENABLED & STM32_PLLI2S_ENABLED
429 case STM32_SRC_PLLI2S_Q:
430 *rate = get_pll_div_frequency(get_pllsrc_frequency(),
431 STM32_PLLI2S_M_DIVISOR,
432 STM32_PLLI2S_N_MULTIPLIER,
433 STM32_PLLI2S_Q_DIVISOR);
434 break;
435 #endif /* STM32_SRC_PLLI2S_Q */
436 #if defined(STM32_SRC_PLLI2S_R) & STM32_PLLI2S_ENABLED
437 case STM32_SRC_PLLI2S_R:
438 *rate = get_pll_div_frequency(get_pllsrc_frequency(),
439 STM32_PLLI2S_M_DIVISOR,
440 STM32_PLLI2S_N_MULTIPLIER,
441 STM32_PLLI2S_R_DIVISOR);
442 break;
443 #endif /* STM32_SRC_PLLI2S_R */
444
445 /* PLLSAI1x not supported yet */
446 /* PLLSAI2x not supported yet */
447 #if defined(STM32_SRC_LSE)
448 case STM32_SRC_LSE:
449 *rate = STM32_LSE_FREQ;
450 break;
451 #endif
452 #if defined(STM32_SRC_LSI)
453 case STM32_SRC_LSI:
454 *rate = STM32_LSI_FREQ;
455 break;
456 #endif
457 #if defined(STM32_SRC_HSI)
458 case STM32_SRC_HSI:
459 *rate = STM32_HSI_FREQ;
460 break;
461 #endif
462 #if defined(STM32_SRC_MSI)
463 case STM32_SRC_MSI:
464 *rate = get_msi_frequency();
465 break;
466 #endif
467 #if defined(STM32_SRC_HSE)
468 case STM32_SRC_HSE:
469 *rate = STM32_HSE_FREQ;
470 break;
471 #endif
472 #if defined(STM32_HSI48_ENABLED)
473 case STM32_SRC_HSI48:
474 *rate = STM32_HSI48_FREQ;
475 break;
476 #endif /* STM32_HSI48_ENABLED */
477 #if defined(STM32_CK48_ENABLED)
478 case STM32_SRC_CK48:
479 *rate = get_ck48_frequency();
480 break;
481 #endif /* STM32_CK48_ENABLED */
482
483 default:
484 return -ENOTSUP;
485 }
486
487 if (pclken->div) {
488 *rate /= (pclken->div + 1);
489 }
490
491 return 0;
492 }
493
stm32_clock_control_get_status(const struct device * dev,clock_control_subsys_t sub_system)494 static enum clock_control_status stm32_clock_control_get_status(const struct device *dev,
495 clock_control_subsys_t sub_system)
496 {
497 struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system;
498
499 ARG_UNUSED(dev);
500
501 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == true) {
502 /* Gated clocks */
503 if ((sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus) & pclken->enr)
504 == pclken->enr) {
505 return CLOCK_CONTROL_STATUS_ON;
506 } else {
507 return CLOCK_CONTROL_STATUS_OFF;
508 }
509 } else {
510 /* Domain clock sources */
511 if (enabled_clock(pclken->bus) == 0) {
512 return CLOCK_CONTROL_STATUS_ON;
513 } else {
514 return CLOCK_CONTROL_STATUS_OFF;
515 }
516 }
517 }
518
519 static DEVICE_API(clock_control, stm32_clock_control_api) = {
520 .on = stm32_clock_control_on,
521 .off = stm32_clock_control_off,
522 .get_rate = stm32_clock_control_get_subsys_rate,
523 .get_status = stm32_clock_control_get_status,
524 .configure = stm32_clock_control_configure,
525 };
526
527 /*
528 * Unconditionally switch the system clock source to HSI.
529 */
530 __unused
stm32_clock_switch_to_hsi(void)531 static void stm32_clock_switch_to_hsi(void)
532 {
533 /* Enable HSI if not enabled */
534 if (LL_RCC_HSI_IsReady() != 1) {
535 /* Enable HSI */
536 LL_RCC_HSI_Enable();
537 while (LL_RCC_HSI_IsReady() != 1) {
538 /* Wait for HSI ready */
539 }
540 }
541
542 /* Set HSI as SYSCLCK source */
543 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
544 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
545 }
546 }
547
548 __unused
set_up_plls(void)549 static void set_up_plls(void)
550 {
551 #if defined(STM32_PLL_ENABLED)
552
553 /*
554 * Case of chain-loaded applications:
555 * Switch to HSI and disable the PLL before configuration.
556 * (Switching to HSI makes sure we have a SYSCLK source in
557 * case we're currently running from the PLL we're about to
558 * turn off and reconfigure.)
559 *
560 */
561 if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
562 stm32_clock_switch_to_hsi();
563 LL_RCC_SetAHBPrescaler(ahb_prescaler(1));
564 }
565 /* Disable PLL */
566 LL_RCC_PLL_Disable();
567 while (LL_RCC_PLL_IsReady() != 0U) {
568 /* Wait for PLL to be disabled */
569 }
570
571 #endif
572
573 #if defined(STM32_PLL2_ENABLED)
574 /*
575 * Disable PLL2 after switching to HSI for SysClk
576 * and disabling PLL, but before enabling PLL again,
577 * since PLL source can be PLL2.
578 */
579 LL_RCC_PLL2_Disable();
580 while (LL_RCC_PLL2_IsReady() != 0U) {
581 /* Wait for PLL2 to be disabled */
582 }
583
584 config_pll2();
585
586 /* Enable PLL2 */
587 LL_RCC_PLL2_Enable();
588 while (LL_RCC_PLL2_IsReady() != 1U) {
589 /* Wait for PLL2 ready */
590 }
591 #endif /* STM32_PLL2_ENABLED */
592
593 #if defined(STM32_PLL_ENABLED)
594
595 #if defined(STM32_SRC_PLL_P) & STM32_PLL_P_ENABLED
596 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLP, pllp(STM32_PLL_P_DIVISOR));
597 RCC_PLLP_ENABLE();
598 #endif
599 #if defined(STM32_SRC_PLL_Q) & STM32_PLL_Q_ENABLED
600 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ, pllq(STM32_PLL_Q_DIVISOR));
601 RCC_PLLQ_ENABLE();
602 #endif
603
604 config_pll_sysclock();
605
606 /* Enable PLL */
607 LL_RCC_PLL_Enable();
608 while (LL_RCC_PLL_IsReady() != 1U) {
609 /* Wait for PLL ready */
610 }
611
612 #endif /* STM32_PLL_ENABLED */
613
614 #if defined(STM32_PLLI2S_ENABLED)
615 config_plli2s();
616
617 /* Enable PLL */
618 LL_RCC_PLLI2S_Enable();
619 while (LL_RCC_PLLI2S_IsReady() != 1U) {
620 /* Wait for PLL ready */
621 }
622 #endif /* STM32_PLLI2S_ENABLED */
623 }
624
set_up_fixed_clock_sources(void)625 static void set_up_fixed_clock_sources(void)
626 {
627
628 if (IS_ENABLED(STM32_HSE_ENABLED)) {
629 #if defined(STM32_HSE_BYPASS)
630 /* Check if need to enable HSE bypass feature or not */
631 if (IS_ENABLED(STM32_HSE_BYPASS)) {
632 LL_RCC_HSE_EnableBypass();
633 } else {
634 LL_RCC_HSE_DisableBypass();
635 }
636 #endif
637 #if STM32_HSE_TCXO
638 LL_RCC_HSE_EnableTcxo();
639 #endif
640 #if STM32_HSE_DIV2
641 LL_RCC_HSE_EnableDiv2();
642 #endif
643 /* Enable HSE */
644 LL_RCC_HSE_Enable();
645 while (LL_RCC_HSE_IsReady() != 1) {
646 /* Wait for HSE ready */
647 }
648 /* Check if we need to enable HSE clock security system or not */
649 #if STM32_HSE_CSS
650 z_arm_nmi_set_handler(HAL_RCC_NMI_IRQHandler);
651 LL_RCC_HSE_EnableCSS();
652 #endif /* STM32_HSE_CSS */
653 }
654
655 if (IS_ENABLED(STM32_HSI_ENABLED)) {
656 /* Enable HSI if not enabled */
657 if (LL_RCC_HSI_IsReady() != 1) {
658 /* Enable HSI */
659 LL_RCC_HSI_Enable();
660 while (LL_RCC_HSI_IsReady() != 1) {
661 /* Wait for HSI ready */
662 }
663 }
664 #if STM32_HSI_DIV_ENABLED
665 LL_RCC_SetHSIDiv(hsi_divider(STM32_HSI_DIVISOR));
666 #endif
667 }
668
669 #if defined(STM32_MSI_ENABLED)
670 if (IS_ENABLED(STM32_MSI_ENABLED)) {
671 /* Set MSI Range */
672 #if defined(RCC_CR_MSIRGSEL)
673 LL_RCC_MSI_EnableRangeSelection();
674 #endif /* RCC_CR_MSIRGSEL */
675
676 #if defined(CONFIG_SOC_SERIES_STM32L0X) || defined(CONFIG_SOC_SERIES_STM32L1X)
677 LL_RCC_MSI_SetRange(STM32_MSI_RANGE << RCC_ICSCR_MSIRANGE_Pos);
678 #else
679 LL_RCC_MSI_SetRange(STM32_MSI_RANGE << RCC_CR_MSIRANGE_Pos);
680 #endif /* CONFIG_SOC_SERIES_STM32L0X || CONFIG_SOC_SERIES_STM32L1X */
681
682 #if STM32_MSI_PLL_MODE
683 /* Enable MSI hardware auto calibration */
684 LL_RCC_MSI_EnablePLLMode();
685 #endif
686
687 LL_RCC_MSI_SetCalibTrimming(0);
688
689 /* Enable MSI if not enabled */
690 if (LL_RCC_MSI_IsReady() != 1) {
691 /* Enable MSI */
692 LL_RCC_MSI_Enable();
693 while (LL_RCC_MSI_IsReady() != 1) {
694 /* Wait for MSI ready */
695 }
696 }
697 }
698 #endif /* STM32_MSI_ENABLED */
699
700 if (IS_ENABLED(STM32_LSI_ENABLED)) {
701 #if defined(CONFIG_SOC_SERIES_STM32WBX)
702 LL_RCC_LSI1_Enable();
703 while (LL_RCC_LSI1_IsReady() != 1) {
704 }
705 #else
706 LL_RCC_LSI_Enable();
707 while (LL_RCC_LSI_IsReady() != 1) {
708 }
709 #endif
710 }
711
712 if (IS_ENABLED(STM32_LSE_ENABLED)) {
713 /* LSE belongs to the back-up domain, enable access.*/
714
715 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
716
717 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPR_DBP)
718 /* Set the DBP bit in the Power control register 1 (PWR_CR1) */
719 LL_PWR_EnableBkUpAccess();
720 while (!LL_PWR_IsEnabledBkUpAccess()) {
721 /* Wait for Backup domain access */
722 }
723 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
724
725 #if STM32_LSE_DRIVING
726 /* Configure driving capability */
727 LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos);
728 #endif
729
730 if (IS_ENABLED(STM32_LSE_BYPASS)) {
731 /* Configure LSE bypass */
732 LL_RCC_LSE_EnableBypass();
733 }
734
735 /* Enable LSE Oscillator (32.768 kHz) */
736 LL_RCC_LSE_Enable();
737 while (!LL_RCC_LSE_IsReady()) {
738 /* Wait for LSE ready */
739 }
740
741 #ifdef RCC_BDCR_LSESYSEN
742 LL_RCC_LSE_EnablePropagation();
743 /* Wait till LSESYS is ready */
744 while (!LL_RCC_LSE_IsPropagationReady()) {
745 }
746 #endif /* RCC_BDCR_LSESYSEN */
747
748 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPR_DBP)
749 LL_PWR_DisableBkUpAccess();
750 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
751
752 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
753 }
754
755 #if defined(STM32_HSI14_ENABLED)
756 /* For all series with HSI 14 clock support */
757 if (IS_ENABLED(STM32_HSI14_ENABLED)) {
758 LL_RCC_HSI14_Enable();
759 while (LL_RCC_HSI14_IsReady() != 1) {
760 }
761 }
762 #endif /* STM32_HSI48_ENABLED */
763
764 #if defined(STM32_HSI48_ENABLED)
765 /* For all series with HSI 48 clock support */
766 if (IS_ENABLED(STM32_HSI48_ENABLED)) {
767 #if defined(CONFIG_SOC_SERIES_STM32L0X)
768 /*
769 * HSI48 requires VREFINT (see RM0376 section 7.2.4).
770 * The SYSCFG is needed to control VREFINT, so clock it.
771 */
772 LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
773 LL_SYSCFG_VREFINT_EnableHSI48();
774 #endif /* CONFIG_SOC_SERIES_STM32L0X */
775
776 /*
777 * STM32WB: Lock the CLK48 HSEM and do not release to prevent
778 * M0 core to disable this clock (used for RNG on M0).
779 * No-op on other series.
780 */
781 z_stm32_hsem_lock(CFG_HW_CLK48_CONFIG_SEMID, HSEM_LOCK_DEFAULT_RETRY);
782
783 LL_RCC_HSI48_Enable();
784 while (LL_RCC_HSI48_IsReady() != 1) {
785 }
786 }
787 #endif /* STM32_HSI48_ENABLED */
788 }
789
790 /**
791 * @brief Initialize clocks for the stm32
792 *
793 * This routine is called to enable and configure the clocks and PLL
794 * of the soc on the board. It depends on the board definition.
795 * This function is called on the startup and also to restore the config
796 * when exiting for low power mode.
797 *
798 * @param dev clock device struct
799 *
800 * @return 0
801 */
stm32_clock_control_init(const struct device * dev)802 int stm32_clock_control_init(const struct device *dev)
803 {
804 ARG_UNUSED(dev);
805
806 /* Some clocks would be activated by default */
807 config_enable_default_clocks();
808 config_regulator_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
809
810 #if defined(FLASH_ACR_LATENCY)
811 uint32_t old_flash_freq;
812 uint32_t new_flash_freq;
813
814 old_flash_freq = RCC_CALC_FLASH_FREQ(HAL_RCC_GetSysClockFreq(),
815 GET_CURRENT_FLASH_PRESCALER());
816
817 new_flash_freq = RCC_CALC_FLASH_FREQ(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
818 STM32_FLASH_PRESCALER);
819
820 /* If HCLK increases, set flash latency before any clock setting */
821 if (old_flash_freq < new_flash_freq) {
822 LL_SetFlashLatency(new_flash_freq);
823 }
824 #endif /* FLASH_ACR_LATENCY */
825
826 /* Set up individual enabled clocks */
827 set_up_fixed_clock_sources();
828
829 /* Set up PLLs */
830 set_up_plls();
831
832 if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) &&
833 (ahb_prescaler(STM32_CORE_PRESCALER) == ahb_prescaler(1)) &&
834 (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) {
835 LL_RCC_SetAHBPrescaler(ahb_prescaler(2));
836 } else {
837 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER));
838 }
839
840 #if STM32_SYSCLK_SRC_PLL
841 /* Set PLL as System Clock Source */
842 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
843 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
844 }
845 #elif STM32_SYSCLK_SRC_HSE
846 /* Set HSE as SYSCLCK source */
847 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
848 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
849 }
850 #elif STM32_SYSCLK_SRC_MSI
851 /* Set MSI as SYSCLCK source */
852 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
853 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
854 }
855 #elif STM32_SYSCLK_SRC_HSI
856 stm32_clock_switch_to_hsi();
857 #endif /* STM32_SYSCLK_SRC_... */
858
859 if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) &&
860 (ahb_prescaler(STM32_CORE_PRESCALER) == ahb_prescaler(1)) &&
861 (MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) {
862 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER));
863 }
864
865 #if defined(FLASH_ACR_LATENCY)
866 /* If HCLK not increased, set flash latency after all clock setting */
867 if (old_flash_freq >= new_flash_freq) {
868 LL_SetFlashLatency(new_flash_freq);
869 }
870 #endif /* FLASH_ACR_LATENCY */
871
872 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
873
874 /* Set bus prescalers prescaler */
875 LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
876 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
877 LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
878 #endif
879 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), cpu2_prescaler)
880 LL_C2_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CPU2_PRESCALER));
881 #endif
882 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
883 LL_RCC_SetAHB3Prescaler(ahb_prescaler(STM32_AHB3_PRESCALER));
884 #endif
885 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
886 LL_RCC_SetAHB4Prescaler(ahb_prescaler(STM32_AHB4_PRESCALER));
887 #endif
888 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc_prescaler)
889 LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC_PRESCALER));
890 #endif
891 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc12_prescaler)
892 LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC12_PRESCALER));
893 #endif
894 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc34_prescaler)
895 LL_RCC_SetADCClockSource(adc34_prescaler(STM32_ADC34_PRESCALER));
896 #endif
897
898 return 0;
899 }
900
901 #if defined(STM32_HSE_CSS)
stm32_hse_css_callback(void)902 void __weak stm32_hse_css_callback(void) {}
903
904 /* Called by the HAL in response to an HSE CSS interrupt */
HAL_RCC_CSSCallback(void)905 void HAL_RCC_CSSCallback(void)
906 {
907 stm32_hse_css_callback();
908 }
909 #endif
910
config_regulator_voltage(uint32_t hclk_freq)911 void __weak config_regulator_voltage(uint32_t hclk_freq) {}
912 /**
913 * @brief RCC device, note that priority is intentionally set to 1 so
914 * that the device init runs just after SOC init
915 */
916 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
917 stm32_clock_control_init,
918 NULL,
919 NULL, NULL,
920 PRE_KERNEL_1,
921 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
922 &stm32_clock_control_api);
923