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