1 /*
2 * Copyright (c) 2023 STMicroelectronics
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <soc.h>
8 #include <stm32_ll_bus.h>
9 #include <stm32_ll_pwr.h>
10 #include <stm32_ll_rcc.h>
11 #include <stm32_ll_system.h>
12 #include <stm32_ll_utils.h>
13 #include <zephyr/drivers/clock_control.h>
14 #include <zephyr/sys/util.h>
15 #include <zephyr/sys/__assert.h>
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include "stm32_hsem.h"
18
19 /* Macros to fill up prescaler values */
20 #define fn_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
21 #define ahb_prescaler(v) fn_ahb_prescaler(v)
22
23 #define fn_ahb5_prescaler(v) LL_RCC_AHB5_DIV_ ## v
24 #define ahb5_prescaler(v) fn_ahb5_prescaler(v)
25
26 #define fn_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
27 #define apb1_prescaler(v) fn_apb1_prescaler(v)
28
29 #define fn_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
30 #define apb2_prescaler(v) fn_apb2_prescaler(v)
31
32 #define fn_apb7_prescaler(v) LL_RCC_APB7_DIV_ ## v
33 #define apb7_prescaler(v) fn_apb7_prescaler(v)
34
35 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK_FREQ
36 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHBPrescaler
37
get_bus_clock(uint32_t clock,uint32_t prescaler)38 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
39 {
40 return clock / prescaler;
41 }
42
43 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)44 int enabled_clock(uint32_t src_clk)
45 {
46 if ((src_clk == STM32_SRC_SYSCLK) ||
47 (src_clk == STM32_SRC_HCLK1) ||
48 (src_clk == STM32_SRC_HCLK5) ||
49 (src_clk == STM32_SRC_PCLK1) ||
50 (src_clk == STM32_SRC_PCLK2) ||
51 (src_clk == STM32_SRC_PCLK7) ||
52 ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) ||
53 ((src_clk == STM32_SRC_HSI16) && IS_ENABLED(STM32_HSI_ENABLED)) ||
54 ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) ||
55 ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) ||
56 ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) ||
57 ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) ||
58 ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED))) {
59 return 0;
60 }
61
62 return -ENOTSUP;
63 }
64
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)65 static inline int stm32_clock_control_on(const struct device *dev,
66 clock_control_subsys_t sub_system)
67 {
68 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
69 volatile int temp;
70
71 ARG_UNUSED(dev);
72
73 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
74 /* Attempt to toggle a wrong periph clock bit */
75 return -ENOTSUP;
76 }
77
78 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
79 pclken->enr);
80 /* Delay after enabling the clock, to allow it to become active */
81 temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus);
82 UNUSED(temp);
83
84 return 0;
85 }
86
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)87 static inline int stm32_clock_control_off(const struct device *dev,
88 clock_control_subsys_t sub_system)
89 {
90 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
91
92 ARG_UNUSED(dev);
93
94 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
95 /* Attempt to toggle a wrong periph clock bit */
96 return -ENOTSUP;
97 }
98
99 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
100 pclken->enr);
101
102 return 0;
103 }
104
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)105 static inline int stm32_clock_control_configure(const struct device *dev,
106 clock_control_subsys_t sub_system,
107 void *data)
108 {
109 #if defined(STM32_SRC_CLOCK_MIN)
110 /* At least one alt src clock available */
111 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
112 int err;
113
114 ARG_UNUSED(dev);
115 ARG_UNUSED(data);
116
117 err = enabled_clock(pclken->bus);
118 if (err < 0) {
119 /* Attempt to configure a src clock not available or not valid */
120 return err;
121 }
122
123 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr),
124 STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr));
125 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr),
126 STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr));
127
128 return 0;
129 #else
130 /* No src clock available: Not supported */
131 return -ENOTSUP;
132 #endif
133 }
134
135 __unused
get_pllsrc_frequency(void)136 static uint32_t get_pllsrc_frequency(void)
137 {
138
139 if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
140 return STM32_HSI_FREQ;
141 } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
142 return STM32_HSE_FREQ;
143 }
144
145 __ASSERT(0, "No PLL Source configured");
146 return 0;
147 }
148
149 __unused
get_pllsrc(void)150 static uint32_t get_pllsrc(void)
151 {
152
153 if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
154 return LL_RCC_PLL1SOURCE_HSI;
155 } else if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
156 return LL_RCC_PLL1SOURCE_HSE;
157 }
158
159 __ASSERT(0, "No PLL Source configured");
160 return 0;
161 }
162
stm32_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)163 static int stm32_clock_control_get_subsys_rate(const struct device *dev,
164 clock_control_subsys_t sub_system,
165 uint32_t *rate)
166 {
167 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
168 /*
169 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
170 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
171 * since it will be updated after clock configuration and hence
172 * more likely to contain actual clock speed
173 */
174 uint32_t ahb_clock = SystemCoreClock;
175 uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
176 uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
177 uint32_t apb7_clock = get_bus_clock(ahb_clock, STM32_APB7_PRESCALER);
178 uint32_t ahb5_clock;
179
180 ARG_UNUSED(dev);
181
182 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
183 /* PLL is the SYSCLK source, use 'ahb5-prescaler' */
184 ahb5_clock = get_bus_clock(ahb_clock * STM32_AHB_PRESCALER,
185 STM32_AHB5_PRESCALER);
186 } else {
187 /* PLL is not the SYSCLK source, use 'ahb5-div'(if set) */
188 if (IS_ENABLED(STM32_AHB5_DIV)) {
189 ahb5_clock = ahb_clock * STM32_AHB_PRESCALER / 2;
190 } else {
191 ahb5_clock = ahb_clock * STM32_AHB_PRESCALER;
192 }
193
194 }
195
196 __ASSERT(ahb5_clock <= MHZ(32), "AHB5 clock frequency exceeds 32 MHz");
197
198 switch (pclken->bus) {
199 case STM32_CLOCK_BUS_AHB1:
200 case STM32_CLOCK_BUS_AHB2:
201 case STM32_CLOCK_BUS_AHB4:
202 case STM32_SRC_HCLK1:
203 *rate = ahb_clock;
204 break;
205 case STM32_CLOCK_BUS_AHB5:
206 case STM32_SRC_HCLK5:
207 *rate = ahb5_clock;
208 break;
209 case STM32_CLOCK_BUS_APB1:
210 case STM32_CLOCK_BUS_APB1_2:
211 case STM32_SRC_PCLK1:
212 *rate = apb1_clock;
213 break;
214 case STM32_CLOCK_BUS_APB2:
215 case STM32_SRC_PCLK2:
216 *rate = apb2_clock;
217 break;
218 case STM32_CLOCK_BUS_APB7:
219 case STM32_SRC_PCLK7:
220 *rate = apb7_clock;
221 break;
222 case STM32_SRC_SYSCLK:
223 *rate = SystemCoreClock * STM32_CORE_PRESCALER;
224 break;
225 #if defined(STM32_PLL_ENABLED)
226 case STM32_SRC_PLL1_P:
227 *rate = __LL_RCC_CALC_PLL1PCLK_FREQ(get_pllsrc_frequency(),
228 STM32_PLL_M_DIVISOR,
229 STM32_PLL_N_MULTIPLIER,
230 STM32_PLL_P_DIVISOR);
231 break;
232 case STM32_SRC_PLL1_Q:
233 *rate = __LL_RCC_CALC_PLL1QCLK_FREQ(get_pllsrc_frequency(),
234 STM32_PLL_M_DIVISOR,
235 STM32_PLL_N_MULTIPLIER,
236 STM32_PLL_Q_DIVISOR);
237 break;
238 case STM32_SRC_PLL1_R:
239 *rate = __LL_RCC_CALC_PLL1RCLK_FREQ(get_pllsrc_frequency(),
240 STM32_PLL_M_DIVISOR,
241 STM32_PLL_N_MULTIPLIER,
242 STM32_PLL_R_DIVISOR);
243 break;
244 #endif /* STM32_PLL_ENABLED */
245 #if defined(STM32_LSE_ENABLED)
246 case STM32_SRC_LSE:
247 *rate = STM32_LSE_FREQ;
248 break;
249 #endif
250 #if defined(STM32_LSI_ENABLED)
251 case STM32_SRC_LSI:
252 *rate = STM32_LSI_FREQ;
253 break;
254 #endif
255 #if defined(STM32_HSI_ENABLED)
256 case STM32_SRC_HSI16:
257 *rate = STM32_HSI_FREQ;
258 break;
259 #endif
260 #if defined(STM32_HSE_ENABLED)
261 case STM32_SRC_HSE:
262 if (IS_ENABLED(STM32_HSE_DIV2)) {
263 *rate = STM32_HSE_FREQ / 2;
264 } else {
265 *rate = STM32_HSE_FREQ;
266 }
267
268 break;
269 #endif
270 default:
271 return -ENOTSUP;
272 }
273
274 if (pclken->div) {
275 *rate /= (pclken->div + 1);
276 }
277
278 return 0;
279 }
280
stm32_clock_control_get_status(const struct device * dev,clock_control_subsys_t sub_system)281 static enum clock_control_status stm32_clock_control_get_status(const struct device *dev,
282 clock_control_subsys_t sub_system)
283 {
284 struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system;
285
286 ARG_UNUSED(dev);
287
288 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == true) {
289 /* Gated clocks */
290 if ((sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus) & pclken->enr)
291 == pclken->enr) {
292 return CLOCK_CONTROL_STATUS_ON;
293 } else {
294 return CLOCK_CONTROL_STATUS_OFF;
295 }
296 } else {
297 /* Domain clock sources */
298 if (enabled_clock(pclken->bus) == 0) {
299 return CLOCK_CONTROL_STATUS_ON;
300 } else {
301 return CLOCK_CONTROL_STATUS_OFF;
302 }
303 }
304 }
305
306 static DEVICE_API(clock_control, stm32_clock_control_api) = {
307 .on = stm32_clock_control_on,
308 .off = stm32_clock_control_off,
309 .get_rate = stm32_clock_control_get_subsys_rate,
310 .get_status = stm32_clock_control_get_status,
311 .configure = stm32_clock_control_configure,
312 };
313
314 __unused
get_vco_input_range(uint32_t m_div,uint32_t * range)315 static int get_vco_input_range(uint32_t m_div, uint32_t *range)
316 {
317 uint32_t vco_freq;
318
319 vco_freq = get_pllsrc_frequency() / m_div;
320
321 if (MHZ(4) <= vco_freq && vco_freq <= MHZ(8)) {
322 *range = LL_RCC_PLLINPUTRANGE_4_8;
323 } else if (MHZ(8) < vco_freq && vco_freq <= MHZ(16)) {
324 *range = LL_RCC_PLLINPUTRANGE_8_16;
325 } else {
326 return -ERANGE;
327 }
328
329 return 0;
330 }
331
set_regu_voltage(uint32_t hclk_freq)332 static void set_regu_voltage(uint32_t hclk_freq)
333 {
334 if (hclk_freq <= MHZ(16)) {
335 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2);
336 } else {
337 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
338 }
339 while (LL_PWR_IsActiveFlag_VOS() == 0) {
340 }
341 }
342
343 /*
344 * Unconditionally switch the system clock source to HSI.
345 */
346 __unused
stm32_clock_switch_to_hsi(void)347 static void stm32_clock_switch_to_hsi(void)
348 {
349 /* Enable HSI if not enabled */
350 if (LL_RCC_HSI_IsReady() != 1) {
351 /* Enable HSI */
352 LL_RCC_HSI_Enable();
353 while (LL_RCC_HSI_IsReady() != 1) {
354 /* Wait for HSI ready */
355 }
356 }
357
358 /* Set HSI as SYSCLCK source */
359 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
360 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
361 }
362
363 /* Erratum 2.2.4: Spurious deactivation of HSE when HSI is selected as
364 * system clock source
365 * Re-enable HSE clock if required after switch source to HSI
366 */
367 if (IS_ENABLED(STM32_HSE_ENABLED)) {
368 if (IS_ENABLED(STM32_HSE_DIV2)) {
369 LL_RCC_HSE_EnablePrescaler();
370 }
371
372 /* Enable HSE */
373 LL_RCC_HSE_Enable();
374 while (LL_RCC_HSE_IsReady() != 1) {
375 /* Wait for HSE ready */
376 }
377 }
378 }
379
380 __unused
set_up_plls(void)381 static int set_up_plls(void)
382 {
383 #if defined(STM32_PLL_ENABLED)
384 int r;
385 uint32_t vco_input_range;
386
387 LL_RCC_PLL1_Disable();
388
389 /* Configure PLL source */
390 /* Can be HSE, HSI */
391 if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
392 /* Main PLL configuration and activation */
393 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_HSE);
394 } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
395 /* Main PLL configuration and activation */
396 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_HSI);
397 } else {
398 return -ENOTSUP;
399 }
400
401 r = get_vco_input_range(STM32_PLL_M_DIVISOR, &vco_input_range);
402 if (r < 0) {
403 return r;
404 }
405
406 LL_RCC_PLL1_SetDivider(STM32_PLL_M_DIVISOR);
407
408 LL_RCC_PLL1_SetVCOInputRange(vco_input_range);
409
410 LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER);
411
412 LL_RCC_PLL1FRACN_Disable();
413
414 if (IS_ENABLED(STM32_PLL_P_ENABLED)) {
415 LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR);
416 LL_RCC_PLL1_EnableDomain_PLL1P();
417 }
418
419 if (IS_ENABLED(STM32_PLL_Q_ENABLED)) {
420 LL_RCC_PLL1_SetQ(STM32_PLL_Q_DIVISOR);
421 LL_RCC_PLL1_EnableDomain_PLL1Q();
422 }
423
424 if (IS_ENABLED(STM32_PLL_R_ENABLED)) {
425 LL_RCC_PLL1_SetR(STM32_PLL_R_DIVISOR);
426
427 LL_RCC_PLL1_EnableDomain_PLL1R();
428 }
429
430 /* Enable PLL */
431 LL_RCC_PLL1_Enable();
432 while (LL_RCC_PLL1_IsReady() != 1U) {
433 /* Wait for PLL ready */
434 }
435 #else
436 /* Init PLL source to None */
437 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_NONE);
438 #endif /* STM32_PLL_ENABLED */
439
440 return 0;
441 }
442
set_up_fixed_clock_sources(void)443 static void set_up_fixed_clock_sources(void)
444 {
445
446 if (IS_ENABLED(STM32_HSE_ENABLED)) {
447 if (IS_ENABLED(STM32_HSE_DIV2)) {
448 LL_RCC_HSE_EnablePrescaler();
449 }
450
451 /* Enable HSE */
452 LL_RCC_HSE_Enable();
453 while (LL_RCC_HSE_IsReady() != 1) {
454 /* Wait for HSE ready */
455 }
456 }
457
458 if (IS_ENABLED(STM32_HSI_ENABLED)) {
459 /* Enable HSI if not enabled */
460 if (LL_RCC_HSI_IsReady() != 1) {
461 /* Enable HSI */
462 LL_RCC_HSI_Enable();
463 while (LL_RCC_HSI_IsReady() != 1) {
464 /* Wait for HSI ready */
465 }
466 }
467 }
468
469 if (IS_ENABLED(STM32_LSI_ENABLED)) {
470 /* LSI belongs to the back-up domain, enable access.*/
471
472 /* Set the DBP bit in the Power control register 1 (PWR_CR1) */
473 LL_PWR_EnableBkUpAccess();
474 while (!LL_PWR_IsEnabledBkUpAccess()) {
475 /* Wait for Backup domain access */
476 }
477
478 LL_RCC_LSI1_Enable();
479 while (LL_RCC_LSI1_IsReady() != 1) {
480 }
481
482 LL_PWR_DisableBkUpAccess();
483 }
484
485 if (IS_ENABLED(STM32_LSE_ENABLED)) {
486 /* LSE belongs to the back-up domain, enable access.*/
487
488 /* Set the DBP bit in the Power control register 1 (PWR_CR1) */
489 LL_PWR_EnableBkUpAccess();
490 while (!LL_PWR_IsEnabledBkUpAccess()) {
491 /* Wait for Backup domain access */
492 }
493
494 /* Configure driving capability */
495 LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR1_LSEDRV_Pos);
496
497 /* Enable LSE Oscillator (32.768 kHz) */
498 LL_RCC_LSE_Enable();
499 while (!LL_RCC_LSE_IsReady()) {
500 /* Wait for LSE ready */
501 }
502
503 /* Enable LSESYS additionally */
504 LL_RCC_LSE_EnablePropagation();
505 /* Wait till LSESYS is ready */
506 while (!LL_RCC_LSE_IsPropagationReady()) {
507 }
508 }
509 }
510
511 /**
512 * @brief Initialize clocks for the stm32
513 *
514 * This routine is called to enable and configure the clocks and PLL
515 * of the soc on the board. It depends on the board definition.
516 * This function is called on the startup and also to restore the config
517 * when exiting for low power mode.
518 *
519 * @param dev clock device struct
520 *
521 * @return 0
522 */
stm32_clock_control_init(const struct device * dev)523 int stm32_clock_control_init(const struct device *dev)
524 {
525 uint32_t old_flash_freq;
526 int r;
527
528 ARG_UNUSED(dev);
529
530 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL) &&
531 (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R)) {
532 /* In case of chainloaded application, it may happen that PLL
533 * was already configured as sysclk src by bootloader.
534 * Don't test other cases as there are multiple options but
535 * they will be handled smoothly by the function.
536 */
537 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
538 return 0;
539 }
540
541 old_flash_freq = RCC_CALC_FLASH_FREQ(HAL_RCC_GetSysClockFreq(),
542 GET_CURRENT_FLASH_PRESCALER());
543
544 /* Set up individual enabled clocks */
545 set_up_fixed_clock_sources();
546
547 /* Set voltage regulator to comply with targeted system frequency */
548 set_regu_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
549
550 /* If required, apply max step freq for Sysclock w/ PLL input */
551 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
552 LL_RCC_PLL1_SetPLL1RCLKDivisionStep(LL_RCC_PLL1RCLK_2_STEP_DIV);
553
554 /* Send 2 pulses on CLKPRE like it is done in STM32Cube HAL */
555 LL_RCC_PLL1_DisablePLL1RCLKDivision();
556 LL_RCC_PLL1_EnablePLL1RCLKDivision();
557 LL_RCC_PLL1_DisablePLL1RCLKDivision();
558 LL_RCC_PLL1_EnablePLL1RCLKDivision();
559 }
560
561 /* Set up PLLs */
562 r = set_up_plls();
563 if (r < 0) {
564 return r;
565 }
566
567 /* If freq increases, set flash latency before any clock setting */
568 if (old_flash_freq < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
569 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
570 }
571
572 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER));
573
574 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
575 /* PLL is the SYSCLK source, use 'ahb5-prescaler' */
576 LL_RCC_SetAHB5Prescaler(ahb5_prescaler(STM32_AHB5_PRESCALER));
577 } else {
578 /* PLL is not the SYSCLK source, use 'ahb5-div'(if set) */
579 if (IS_ENABLED(STM32_AHB5_DIV)) {
580 LL_RCC_SetAHB5Divider(LL_RCC_AHB5_DIVIDER_2);
581 } else {
582 LL_RCC_SetAHB5Divider(LL_RCC_AHB5_DIVIDER_1);
583 }
584 }
585
586 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
587 /* Set PLL as System Clock Source */
588 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1R);
589 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1R) {
590 }
591 LL_RCC_PLL1_DisablePLL1RCLKDivision();
592 while (LL_RCC_PLL1_IsPLL1RCLKDivisionReady() == 0) {
593 }
594 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) {
595 /* Set HSE as SYSCLCK source */
596 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
597 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
598 }
599 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) {
600 stm32_clock_switch_to_hsi();
601 }
602
603 /* If freq not increased, set flash latency after all clock setting */
604 if (old_flash_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
605 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
606 }
607
608 /* Set voltage regulator to comply with targeted system frequency */
609 set_regu_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
610
611 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
612
613 /* Set bus prescalers prescaler */
614 LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
615 LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
616 LL_RCC_SetAPB7Prescaler(apb7_prescaler(STM32_APB7_PRESCALER));
617
618 return 0;
619 }
620
621 /**
622 * @brief RCC device, note that priority is intentionally set to 1 so
623 * that the device init runs just after SOC init
624 */
625 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
626 stm32_clock_control_init,
627 NULL,
628 NULL, NULL,
629 PRE_KERNEL_1,
630 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
631 &stm32_clock_control_api);
632