1 /*
2 *
3 * Copyright (c) 2021 Linaro Limited
4 * Copyright (c) 2022 Thomas Stranger
5 * Copyright (c) 2023 STMicroelectronics
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 */
9
10
11 #include <soc.h>
12 #include <stm32_ll_bus.h>
13 #include <stm32_ll_pwr.h>
14 #include <stm32_ll_rcc.h>
15 #include <stm32_ll_utils.h>
16 #include <stm32_ll_system.h>
17 #include <zephyr/arch/cpu.h>
18 #include <zephyr/drivers/clock_control.h>
19 #include <zephyr/sys/util.h>
20 #include <zephyr/drivers/clock_control/stm32_clock_control.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 #define z_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
27 #define ahb_prescaler(v) z_ahb_prescaler(v)
28
29 #define z_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
30 #define apb1_prescaler(v) z_apb1_prescaler(v)
31
32 #define z_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
33 #define apb2_prescaler(v) z_apb2_prescaler(v)
34
35 #define z_apb3_prescaler(v) LL_RCC_APB3_DIV_ ## v
36 #define apb3_prescaler(v) z_apb3_prescaler(v)
37
38 #define PLL1_ID 1
39 #define PLL2_ID 2
40 #define PLL3_ID 3
41
get_bus_clock(uint32_t clock,uint32_t prescaler)42 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
43 {
44 return clock / prescaler;
45 }
46
47 __unused
48 /** @brief returns the pll source frequency of given pll_id */
get_pllsrc_frequency(size_t pll_id)49 static uint32_t get_pllsrc_frequency(size_t pll_id)
50 {
51
52 if ((IS_ENABLED(STM32_PLL_SRC_HSI) && pll_id == PLL1_ID) ||
53 (IS_ENABLED(STM32_PLL2_SRC_HSI) && pll_id == PLL2_ID) ||
54 (IS_ENABLED(STM32_PLL3_SRC_HSI) && pll_id == PLL3_ID)) {
55 return STM32_HSI_FREQ;
56 } else if ((IS_ENABLED(STM32_PLL_SRC_HSE) && pll_id == PLL1_ID) ||
57 (IS_ENABLED(STM32_PLL2_SRC_HSE) && pll_id == PLL2_ID) ||
58 (IS_ENABLED(STM32_PLL3_SRC_HSE) && pll_id == PLL3_ID)) {
59 return STM32_HSE_FREQ;
60 } else if ((IS_ENABLED(STM32_PLL_SRC_CSI) && pll_id == PLL1_ID) ||
61 (IS_ENABLED(STM32_PLL2_SRC_CSI) && pll_id == PLL2_ID) ||
62 (IS_ENABLED(STM32_PLL3_SRC_CSI) && pll_id == PLL3_ID)) {
63 return STM32_CSI_FREQ;
64 }
65
66 __ASSERT(0, "No PLL Source configured");
67 return 0;
68 }
69
get_startup_frequency(void)70 static uint32_t get_startup_frequency(void)
71 {
72 switch (LL_RCC_GetSysClkSource()) {
73 case LL_RCC_SYS_CLKSOURCE_STATUS_CSI:
74 return STM32_CSI_FREQ;
75 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:
76 return STM32_HSI_FREQ;
77 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:
78 return STM32_HSE_FREQ;
79 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL1:
80 return get_pllsrc_frequency(PLL1_ID);
81 default:
82 __ASSERT(0, "Unexpected startup freq");
83 return 0;
84 }
85 }
86
87 __unused
get_pllout_frequency(uint32_t pllsrc_freq,int pllm_div,int plln_mul,int pllout_div)88 static uint32_t get_pllout_frequency(uint32_t pllsrc_freq,
89 int pllm_div,
90 int plln_mul,
91 int pllout_div)
92 {
93 __ASSERT_NO_MSG(pllm_div && pllout_div);
94
95 return (pllsrc_freq / pllm_div) * plln_mul / pllout_div;
96 }
97
get_sysclk_frequency(void)98 static uint32_t get_sysclk_frequency(void)
99 {
100 #if defined(STM32_SYSCLK_SRC_PLL)
101 return get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
102 STM32_PLL_M_DIVISOR,
103 STM32_PLL_N_MULTIPLIER,
104 STM32_PLL_R_DIVISOR);
105 #elif defined(STM32_SYSCLK_SRC_CSI)
106 return STM32_CSI_FREQ;
107 #elif defined(STM32_SYSCLK_SRC_HSE)
108 return STM32_HSE_FREQ;
109 #elif defined(STM32_SYSCLK_SRC_HSI)
110 return STM32_HSI_FREQ;
111 #else
112 __ASSERT(0, "No SYSCLK Source configured");
113 return 0;
114 #endif
115
116 }
117
118 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)119 int enabled_clock(uint32_t src_clk)
120 {
121 if ((src_clk == STM32_SRC_SYSCLK) ||
122 (src_clk == STM32_SRC_HCLK) ||
123 (src_clk == STM32_SRC_PCLK1) ||
124 (src_clk == STM32_SRC_PCLK2) ||
125 (src_clk == STM32_SRC_PCLK3) ||
126 ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) ||
127 ((src_clk == STM32_SRC_HSI) && IS_ENABLED(STM32_HSI_ENABLED)) ||
128 ((src_clk == STM32_SRC_HSI48) && IS_ENABLED(STM32_HSI48_ENABLED)) ||
129 ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) ||
130 ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) ||
131 ((src_clk == STM32_SRC_CSI) && IS_ENABLED(STM32_CSI_ENABLED)) ||
132 ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) ||
133 ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) ||
134 ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED)) ||
135 ((src_clk == STM32_SRC_PLL2_P) && IS_ENABLED(STM32_PLL2_P_ENABLED)) ||
136 ((src_clk == STM32_SRC_PLL2_Q) && IS_ENABLED(STM32_PLL2_Q_ENABLED)) ||
137 ((src_clk == STM32_SRC_PLL2_R) && IS_ENABLED(STM32_PLL2_R_ENABLED)) ||
138 ((src_clk == STM32_SRC_PLL3_P) && IS_ENABLED(STM32_PLL3_P_ENABLED)) ||
139 ((src_clk == STM32_SRC_PLL3_Q) && IS_ENABLED(STM32_PLL3_Q_ENABLED)) ||
140 ((src_clk == STM32_SRC_PLL3_R) && IS_ENABLED(STM32_PLL3_R_ENABLED))) {
141 return 0;
142 }
143
144 return -ENOTSUP;
145 }
146
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)147 static inline int stm32_clock_control_on(const struct device *dev,
148 clock_control_subsys_t sub_system)
149 {
150 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
151 volatile int temp;
152
153 ARG_UNUSED(dev);
154
155 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
156 /* Attempt to toggle a wrong periph clock bit */
157 return -ENOTSUP;
158 }
159
160 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
161 pclken->enr);
162 /* Delay after enabling the clock, to allow it to become active */
163 temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus);
164 UNUSED(temp);
165
166 return 0;
167 }
168
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)169 static inline int stm32_clock_control_off(const struct device *dev,
170 clock_control_subsys_t sub_system)
171 {
172 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
173
174 ARG_UNUSED(dev);
175
176 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
177 /* Attempt to toggle a wrong periph clock bit */
178 return -ENOTSUP;
179 }
180
181 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
182 pclken->enr);
183
184 return 0;
185 }
186
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)187 static inline int stm32_clock_control_configure(const struct device *dev,
188 clock_control_subsys_t sub_system,
189 void *data)
190 {
191 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
192 int err;
193
194 ARG_UNUSED(dev);
195 ARG_UNUSED(data);
196
197 err = enabled_clock(pclken->bus);
198 if (err < 0) {
199 /* Attempt to configure a src clock not available or not valid */
200 return err;
201 }
202
203 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr),
204 STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr));
205
206 return 0;
207 }
208
stm32_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sys,uint32_t * rate)209 static int stm32_clock_control_get_subsys_rate(const struct device *dev,
210 clock_control_subsys_t sys,
211 uint32_t *rate)
212 {
213 struct stm32_pclken *pclken = (struct stm32_pclken *)(sys);
214
215 /*
216 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
217 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
218 * since it will be updated after clock configuration and hence
219 * more likely to contain actual clock speed
220 */
221 uint32_t ahb_clock = SystemCoreClock;
222 uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
223 uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
224 uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_APB3_PRESCALER);
225
226 ARG_UNUSED(dev);
227
228 switch (pclken->bus) {
229 case STM32_CLOCK_BUS_AHB1:
230 case STM32_CLOCK_BUS_AHB2:
231 case STM32_CLOCK_BUS_AHB4:
232 case STM32_SRC_HCLK:
233 *rate = ahb_clock;
234 break;
235 case STM32_CLOCK_BUS_APB1:
236 case STM32_CLOCK_BUS_APB1_2:
237 case STM32_SRC_PCLK1:
238 *rate = apb1_clock;
239 break;
240 case STM32_CLOCK_BUS_APB2:
241 case STM32_SRC_PCLK2:
242 *rate = apb2_clock;
243 break;
244 case STM32_CLOCK_BUS_APB3:
245 case STM32_SRC_PCLK3:
246 *rate = apb3_clock;
247 break;
248 case STM32_SRC_SYSCLK:
249 *rate = get_sysclk_frequency();
250 break;
251 #if defined(STM32_HSI_ENABLED)
252 case STM32_SRC_HSI:
253 *rate = STM32_HSI_FREQ;
254 break;
255 #endif /* STM32_HSI_ENABLED */
256 #if defined(STM32_CSI_ENABLED)
257 case STM32_SRC_CSI:
258 *rate = STM32_CSI_FREQ;
259 break;
260 #endif /* STM32_MSIS_ENABLED */
261 #if defined(STM32_HSE_ENABLED)
262 case STM32_SRC_HSE:
263 *rate = STM32_HSE_FREQ;
264 break;
265 #endif /* STM32_HSE_ENABLED */
266 #if defined(STM32_LSE_ENABLED)
267 case STM32_SRC_LSE:
268 *rate = STM32_LSE_FREQ;
269 break;
270 #endif /* STM32_LSE_ENABLED */
271 #if defined(STM32_LSI_ENABLED)
272 case STM32_SRC_LSI:
273 *rate = STM32_LSI_FREQ;
274 break;
275 #endif /* STM32_LSI_ENABLED */
276 #if defined(STM32_HSI48_ENABLED)
277 case STM32_SRC_HSI48:
278 *rate = STM32_HSI48_FREQ;
279 break;
280 #endif /* STM32_HSI48_ENABLED */
281 #if defined(STM32_PLL_ENABLED)
282 case STM32_SRC_PLL1_P:
283 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
284 STM32_PLL_M_DIVISOR,
285 STM32_PLL_N_MULTIPLIER,
286 STM32_PLL_P_DIVISOR);
287 break;
288 case STM32_SRC_PLL1_Q:
289 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
290 STM32_PLL_M_DIVISOR,
291 STM32_PLL_N_MULTIPLIER,
292 STM32_PLL_Q_DIVISOR);
293 break;
294 case STM32_SRC_PLL1_R:
295 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
296 STM32_PLL_M_DIVISOR,
297 STM32_PLL_N_MULTIPLIER,
298 STM32_PLL_R_DIVISOR);
299 break;
300 #endif /* STM32_PLL_ENABLED */
301 #if defined(STM32_PLL2_ENABLED)
302 case STM32_SRC_PLL2_P:
303 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
304 STM32_PLL2_M_DIVISOR,
305 STM32_PLL2_N_MULTIPLIER,
306 STM32_PLL2_P_DIVISOR);
307 break;
308 case STM32_SRC_PLL2_Q:
309 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
310 STM32_PLL2_M_DIVISOR,
311 STM32_PLL2_N_MULTIPLIER,
312 STM32_PLL2_Q_DIVISOR);
313 break;
314 case STM32_SRC_PLL2_R:
315 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
316 STM32_PLL2_M_DIVISOR,
317 STM32_PLL2_N_MULTIPLIER,
318 STM32_PLL2_R_DIVISOR);
319 break;
320 #endif /* STM32_PLL2_ENABLED */
321 #if defined(STM32_PLL3_ENABLED)
322 case STM32_SRC_PLL3_P:
323 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
324 STM32_PLL3_M_DIVISOR,
325 STM32_PLL3_N_MULTIPLIER,
326 STM32_PLL3_P_DIVISOR);
327 break;
328 case STM32_SRC_PLL3_Q:
329 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
330 STM32_PLL3_M_DIVISOR,
331 STM32_PLL3_N_MULTIPLIER,
332 STM32_PLL3_Q_DIVISOR);
333 break;
334 case STM32_SRC_PLL3_R:
335 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
336 STM32_PLL3_M_DIVISOR,
337 STM32_PLL3_N_MULTIPLIER,
338 STM32_PLL3_R_DIVISOR);
339 break;
340 #endif /* STM32_PLL3_ENABLED */
341 default:
342 return -ENOTSUP;
343 }
344
345 if (pclken->div) {
346 *rate /= (pclken->div + 1);
347 }
348
349 return 0;
350 }
351
352 static DEVICE_API(clock_control, stm32_clock_control_api) = {
353 .on = stm32_clock_control_on,
354 .off = stm32_clock_control_off,
355 .get_rate = stm32_clock_control_get_subsys_rate,
356 .configure = stm32_clock_control_configure,
357 };
358
359 __unused
get_vco_input_range(uint32_t m_div,uint32_t * range,size_t pll_id)360 static int get_vco_input_range(uint32_t m_div, uint32_t *range, size_t pll_id)
361 {
362 uint32_t vco_freq;
363
364 vco_freq = get_pllsrc_frequency(pll_id) / m_div;
365
366 if (MHZ(1) <= vco_freq && vco_freq <= MHZ(2)) {
367 *range = LL_RCC_PLLINPUTRANGE_1_2;
368 } else if (MHZ(2) < vco_freq && vco_freq <= MHZ(4)) {
369 *range = LL_RCC_PLLINPUTRANGE_2_4;
370 } else if (MHZ(4) < vco_freq && vco_freq <= MHZ(8)) {
371 *range = LL_RCC_PLLINPUTRANGE_4_8;
372 } else if (MHZ(8) < vco_freq && vco_freq <= MHZ(16)) {
373 *range = LL_RCC_PLLINPUTRANGE_8_16;
374 } else {
375 return -ERANGE;
376 }
377
378 return 0;
379 }
380
381
382 __unused
get_vco_output_range(uint32_t vco_input_range)383 static uint32_t get_vco_output_range(uint32_t vco_input_range)
384 {
385 if (vco_input_range == LL_RCC_PLLINPUTRANGE_1_2) {
386 return LL_RCC_PLLVCORANGE_MEDIUM;
387 }
388
389 return LL_RCC_PLLVCORANGE_WIDE;
390 }
391
set_regu_voltage(uint32_t hclk_freq)392 static void set_regu_voltage(uint32_t hclk_freq)
393 {
394 if (hclk_freq <= MHZ(100)) {
395 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE3);
396 } else if (hclk_freq <= MHZ(150)) {
397 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2);
398 } else if (hclk_freq <= MHZ(200)) {
399 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
400 } else {
401 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
402 }
403 while (LL_PWR_IsActiveFlag_VOS() == 0) {
404 }
405 }
406
407 __unused
clock_switch_to_hsi(void)408 static void clock_switch_to_hsi(void)
409 {
410 /* Enable HSI if not enabled */
411 if (LL_RCC_HSI_IsReady() != 1) {
412 /* Enable HSI */
413 LL_RCC_HSI_Enable();
414 while (LL_RCC_HSI_IsReady() != 1) {
415 /* Wait for HSI ready */
416 }
417 }
418
419 /* Set HSI as SYSCLCK source */
420 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
421 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
422 }
423
424 LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
425 }
426
427 __unused
set_up_plls(void)428 static int set_up_plls(void)
429 {
430 #if defined(STM32_PLL_ENABLED) || defined(STM32_PLL2_ENABLED) || \
431 defined(STM32_PLL3_ENABLED)
432 int r;
433 uint32_t vco_input_range;
434 uint32_t vco_output_range;
435 #endif
436
437 #if defined(STM32_PLL_ENABLED)
438 /*
439 * Switch to HSI and disable the PLL before configuration.
440 * (Switching to HSI makes sure we have a SYSCLK source in
441 * case we're currently running from the PLL we're about to
442 * turn off and reconfigure.)
443 */
444 if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
445 clock_switch_to_hsi();
446 }
447
448 LL_RCC_PLL1_Disable();
449
450 /* Configure PLL source : Can be HSE, HSI, MSIS */
451 if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
452 /* Main PLL configuration and activation */
453 LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_HSE);
454 } else if (IS_ENABLED(STM32_PLL_SRC_CSI)) {
455 /* Main PLL configuration and activation */
456 LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_CSI);
457 } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
458 /* Main PLL configuration and activation */
459 LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_HSI);
460 } else {
461 return -ENOTSUP;
462 }
463
464 r = get_vco_input_range(STM32_PLL_M_DIVISOR, &vco_input_range, PLL1_ID);
465 if (r < 0) {
466 return r;
467 }
468
469 vco_output_range = get_vco_output_range(vco_input_range);
470
471 LL_RCC_PLL1_SetM(STM32_PLL_M_DIVISOR);
472
473 /* Set VCO Input before enabling the PLL, depends on the freq of the PLL1 */
474 LL_RCC_PLL1_SetVCOInputRange(vco_input_range);
475 /* Select VCO freq range before enabling the PLL, depends on the freq of the PLL1 */
476 LL_RCC_PLL1_SetVCOOutputRange(vco_output_range);
477
478 LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER);
479
480 LL_RCC_PLL1FRACN_Disable();
481
482 if (IS_ENABLED(STM32_PLL_P_ENABLED)) {
483 LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR);
484 LL_RCC_PLL1P_Enable();
485 }
486
487 if (IS_ENABLED(STM32_PLL_Q_ENABLED)) {
488 LL_RCC_PLL1_SetQ(STM32_PLL_Q_DIVISOR);
489 LL_RCC_PLL1Q_Enable();
490 }
491
492 if (IS_ENABLED(STM32_PLL_R_ENABLED)) {
493 LL_RCC_PLL1_SetR(STM32_PLL_R_DIVISOR);
494 LL_RCC_PLL1R_Enable();
495 }
496
497 LL_RCC_PLL1_Enable();
498 while (LL_RCC_PLL1_IsReady() != 1U) {
499 }
500 #else
501 /* Init PLL source to None */
502 LL_RCC_PLL1_SetSource(LL_RCC_PLL1SOURCE_NONE);
503 #endif /* STM32_PLL_ENABLED */
504
505 #if defined(STM32_PLL2_ENABLED)
506 /* Configure PLL2 source */
507 if (IS_ENABLED(STM32_PLL2_SRC_HSE)) {
508 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_HSE);
509 } else if (IS_ENABLED(STM32_PLL2_SRC_CSI)) {
510 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_CSI);
511 } else if (IS_ENABLED(STM32_PLL2_SRC_HSI)) {
512 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_HSI);
513 } else {
514 return -ENOTSUP;
515 }
516
517 r = get_vco_input_range(STM32_PLL2_M_DIVISOR, &vco_input_range, PLL2_ID);
518 if (r < 0) {
519 return r;
520 }
521
522 vco_output_range = get_vco_output_range(vco_input_range);
523
524 LL_RCC_PLL2_SetM(STM32_PLL2_M_DIVISOR);
525
526 /* Set VCO Input before enabling the PLL, depends on the freq of the PLL2 */
527 LL_RCC_PLL2_SetVCOInputRange(vco_input_range);
528 /* Select VCO freq range before enabling the PLL, depends on the freq of the PLL2 */
529 LL_RCC_PLL2_SetVCOOutputRange(vco_output_range);
530
531 LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER);
532
533 LL_RCC_PLL2FRACN_Disable();
534
535 if (IS_ENABLED(STM32_PLL2_P_ENABLED)) {
536 LL_RCC_PLL2_SetP(STM32_PLL2_P_DIVISOR);
537 LL_RCC_PLL2P_Enable();
538 }
539
540 if (IS_ENABLED(STM32_PLL2_Q_ENABLED)) {
541 LL_RCC_PLL2_SetQ(STM32_PLL2_Q_DIVISOR);
542 LL_RCC_PLL2Q_Enable();
543 }
544
545 if (IS_ENABLED(STM32_PLL2_R_ENABLED)) {
546 LL_RCC_PLL2_SetR(STM32_PLL2_R_DIVISOR);
547 LL_RCC_PLL2R_Enable();
548 }
549
550 LL_RCC_PLL2_Enable();
551 while (LL_RCC_PLL2_IsReady() != 1U) {
552 }
553 #else
554 /* Init PLL2 source to None */
555 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_NONE);
556 #endif /* STM32_PLL2_ENABLED */
557
558 #if defined(RCC_CR_PLL3ON)
559 #if defined(STM32_PLL3_ENABLED)
560 /* Configure PLL3 source */
561 if (IS_ENABLED(STM32_PLL3_SRC_HSE)) {
562 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_HSE);
563 } else if (IS_ENABLED(STM32_PLL3_SRC_CSI)) {
564 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_CSI);
565 } else if (IS_ENABLED(STM32_PLL3_SRC_HSI)) {
566 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_HSI);
567 } else {
568 return -ENOTSUP;
569 }
570
571 r = get_vco_input_range(STM32_PLL3_M_DIVISOR, &vco_input_range, PLL3_ID);
572 if (r < 0) {
573 return r;
574 }
575
576 vco_output_range = get_vco_output_range(vco_input_range);
577
578 LL_RCC_PLL3_SetM(STM32_PLL3_M_DIVISOR);
579
580 /* Set VCO Input before enabling the PLL, depends on the freq of the PLL3 */
581 LL_RCC_PLL3_SetVCOInputRange(vco_input_range);
582 /* Select VCO freq range before enabling the PLL, depends on the freq of the PLL3 */
583 LL_RCC_PLL3_SetVCOOutputRange(vco_output_range);
584
585 LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER);
586
587 LL_RCC_PLL3FRACN_Disable();
588
589 if (IS_ENABLED(STM32_PLL3_P_ENABLED)) {
590 LL_RCC_PLL3_SetP(STM32_PLL3_P_DIVISOR);
591 LL_RCC_PLL3P_Enable();
592 }
593
594 if (IS_ENABLED(STM32_PLL3_Q_ENABLED)) {
595 LL_RCC_PLL3_SetQ(STM32_PLL3_Q_DIVISOR);
596 LL_RCC_PLL3Q_Enable();
597 }
598
599 if (IS_ENABLED(STM32_PLL3_R_ENABLED)) {
600 LL_RCC_PLL3_SetR(STM32_PLL3_R_DIVISOR);
601 LL_RCC_PLL3R_Enable();
602 }
603
604 LL_RCC_PLL3_Enable();
605 while (LL_RCC_PLL3_IsReady() != 1U) {
606 }
607 #else
608 /* Init PLL3 source to None */
609 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_NONE);
610 #endif /* STM32_PLL3_ENABLED */
611 #endif /* (RCC_CR_PLL3ON) */
612
613 return 0;
614 }
615
set_up_fixed_clock_sources(void)616 static void set_up_fixed_clock_sources(void)
617 {
618
619 if (IS_ENABLED(STM32_HSE_ENABLED)) {
620 /* Check if need to enable HSE bypass feature or not */
621 if (IS_ENABLED(STM32_HSE_BYPASS)) {
622 LL_RCC_HSE_EnableBypass();
623 } else {
624 LL_RCC_HSE_DisableBypass();
625 }
626
627 /* Enable HSE */
628 LL_RCC_HSE_Enable();
629 while (LL_RCC_HSE_IsReady() != 1) {
630 /* Wait for HSE ready */
631 }
632 }
633
634 if (IS_ENABLED(STM32_HSI_ENABLED)) {
635 if (IS_ENABLED(STM32_PLL_SRC_HSI) ||
636 IS_ENABLED(STM32_PLL2_SRC_HSI) || IS_ENABLED(STM32_PLL3_SRC_HSI)) {
637 /* HSI calibration */
638 LL_RCC_HSI_SetCalibTrimming(RCC_HSICALIBRATION_DEFAULT);
639 }
640 /* Enable HSI if not enabled */
641 if (LL_RCC_HSI_IsReady() != 1) {
642 /* Enable HSI */
643 LL_RCC_HSI_Enable();
644 while (LL_RCC_HSI_IsReady() != 1) {
645 /* Wait for HSI ready */
646 }
647 }
648 /* HSI divider configuration */
649 LL_RCC_HSI_SetDivider(hsi_divider(STM32_HSI_DIVISOR));
650 }
651
652 if (IS_ENABLED(STM32_LSE_ENABLED)) {
653 if (!LL_PWR_IsEnabledBkUpAccess()) {
654 /* Enable write access to Backup domain */
655 LL_PWR_EnableBkUpAccess();
656 while (!LL_PWR_IsEnabledBkUpAccess()) {
657 /* Wait for Backup domain access */
658 }
659 }
660
661 /* Configure driving capability before enabling the LSE oscillator */
662 LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos);
663
664 if (IS_ENABLED(STM32_LSE_BYPASS)) {
665 /* Configure LSE bypass */
666 LL_RCC_LSE_EnableBypass();
667 }
668
669 /* Enable LSE Oscillator */
670 LL_RCC_LSE_Enable();
671 /* Wait for LSE ready */
672 while (!LL_RCC_LSE_IsReady()) {
673 }
674
675 LL_PWR_DisableBkUpAccess();
676 }
677
678 if (IS_ENABLED(STM32_CSI_ENABLED)) {
679 if (IS_ENABLED(STM32_PLL_SRC_CSI) ||
680 IS_ENABLED(STM32_PLL2_SRC_CSI) || IS_ENABLED(STM32_PLL3_SRC_CSI)) {
681 /* CSI calibration */
682 LL_RCC_CSI_SetCalibTrimming(RCC_CSICALIBRATION_DEFAULT);
683 }
684
685 /* Enable CSI */
686 LL_RCC_CSI_Enable();
687
688 /* Wait till CSI is ready */
689 while (LL_RCC_CSI_IsReady() != 1) {
690 }
691 }
692
693 if (IS_ENABLED(STM32_LSI_ENABLED)) {
694 /* Enable LSI oscillator */
695 LL_RCC_LSI_Enable();
696 while (LL_RCC_LSI_IsReady() != 1) {
697 }
698 }
699
700 if (IS_ENABLED(STM32_HSI48_ENABLED)) {
701 LL_RCC_HSI48_Enable();
702 while (LL_RCC_HSI48_IsReady() != 1) {
703 }
704 }
705
706 }
707
stm32_clock_control_init(const struct device * dev)708 int stm32_clock_control_init(const struct device *dev)
709 {
710 uint32_t old_hclk_freq;
711 int r;
712
713 ARG_UNUSED(dev);
714
715 /* Current hclk value */
716 old_hclk_freq = __LL_RCC_CALC_HCLK_FREQ(get_startup_frequency(), LL_RCC_GetAHBPrescaler());
717
718 /* Set voltage regulator to comply with targeted system frequency */
719 set_regu_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
720
721 /* Set flash latency */
722 /* If freq increases, set flash latency before any clock setting */
723 if (old_hclk_freq < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
724 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
725 }
726
727 /* Set up individual enabled clocks */
728 set_up_fixed_clock_sources();
729
730 /* Set up PLLs */
731 r = set_up_plls();
732 if (r < 0) {
733 return r;
734 }
735
736 /* Set peripheral buses prescalers */
737 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_AHB_PRESCALER));
738 LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
739 LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
740 LL_RCC_SetAPB3Prescaler(apb3_prescaler(STM32_APB3_PRESCALER));
741
742 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
743 /* Set PLL1 as System Clock Source */
744 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
745 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
746 }
747 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) {
748 /* Set HSE as SYSCLCK source */
749 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
750 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
751 }
752 } else if (IS_ENABLED(STM32_SYSCLK_SRC_CSI)) {
753 /* Set CSI as SYSCLCK source */
754 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_CSI);
755 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_CSI) {
756 }
757 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) {
758 /* Set HSI as SYSCLCK source */
759 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
760 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
761 }
762 } else {
763 return -ENOTSUP;
764 }
765
766 /* Set FLASH latency */
767 /* If freq not increased, set flash latency after all clock setting */
768 if (old_hclk_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
769 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
770 }
771
772 /* Update CMSIS variable */
773 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
774
775 return 0;
776 }
777
778 /**
779 * @brief RCC device, note that priority is intentionally set to 1 so
780 * that the device init runs just after SOC init
781 */
782 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
783 stm32_clock_control_init,
784 NULL,
785 NULL, NULL,
786 PRE_KERNEL_1,
787 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
788 &stm32_clock_control_api);
789