1 /*
2 * Copyright (c) 2024 STMicroelectronics
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
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_utils.h>
13 #include <stm32_ll_system.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/drivers/clock_control.h>
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include <zephyr/sys/util.h>
18
19 /* Macros to fill up prescaler values */
20 #define z_ic_src_pll(v) LL_RCC_ICCLKSOURCE_PLL ## v
21 #define ic_src_pll(v) z_ic_src_pll(v)
22
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_AHB_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_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v
36 #define apb4_prescaler(v) z_apb4_prescaler(v)
37
38 #define z_apb5_prescaler(v) LL_RCC_APB5_DIV_ ## v
39 #define apb5_prescaler(v) z_apb5_prescaler(v)
40
41 #define PLL1_ID 1
42 #define PLL2_ID 2
43 #define PLL3_ID 3
44 #define PLL4_ID 4
45
46
get_bus_clock(uint32_t clock,uint32_t prescaler)47 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
48 {
49 return clock / prescaler;
50 }
51
52 __unused
53 /** @brief returns the pll source frequency of given pll_id */
get_pllsrc_frequency(int pll_id)54 static uint32_t get_pllsrc_frequency(int pll_id)
55 {
56 if ((IS_ENABLED(STM32_PLL_SRC_HSI) && pll_id == PLL1_ID) ||
57 (IS_ENABLED(STM32_PLL2_SRC_HSI) && pll_id == PLL2_ID) ||
58 (IS_ENABLED(STM32_PLL3_SRC_HSI) && pll_id == PLL3_ID) ||
59 (IS_ENABLED(STM32_PLL4_SRC_HSI) && pll_id == PLL4_ID)) {
60 return STM32_HSI_FREQ;
61 } else if ((IS_ENABLED(STM32_PLL_SRC_HSE) && pll_id == PLL1_ID) ||
62 (IS_ENABLED(STM32_PLL2_SRC_HSE) && pll_id == PLL2_ID) ||
63 (IS_ENABLED(STM32_PLL3_SRC_HSE) && pll_id == PLL3_ID) ||
64 (IS_ENABLED(STM32_PLL4_SRC_HSE) && pll_id == PLL4_ID)) {
65 return STM32_HSE_FREQ;
66 }
67
68 __ASSERT(0, "No PLL Source configured");
69 return 0;
70 }
71
get_pllout_frequency(int pll_id)72 static uint32_t get_pllout_frequency(int pll_id)
73 {
74 uint32_t pllsrc_freq = get_pllsrc_frequency(pll_id);
75 int pllm_div;
76 int plln_mul;
77 int pllout_div1;
78 int pllout_div2;
79
80 switch (pll_id) {
81 #if defined(STM32_PLL1_ENABLED)
82 case PLL1_ID:
83 pllm_div = STM32_PLL1_M_DIVISOR;
84 plln_mul = STM32_PLL1_N_MULTIPLIER;
85 pllout_div1 = STM32_PLL1_P1_DIVISOR;
86 pllout_div2 = STM32_PLL1_P2_DIVISOR;
87 break;
88 #endif /* STM32_PLL1_ENABLED */
89 #if defined(STM32_PLL2_ENABLED)
90 case PLL2_ID:
91 pllm_div = STM32_PLL2_M_DIVISOR;
92 plln_mul = STM32_PLL2_N_MULTIPLIER;
93 pllout_div1 = STM32_PLL2_P1_DIVISOR;
94 pllout_div2 = STM32_PLL2_P2_DIVISOR;
95 break;
96 #endif /* STM32_PLL2_ENABLED */
97 #if defined(STM32_PLL3_ENABLED)
98 case PLL3_ID:
99 pllm_div = STM32_PLL3_M_DIVISOR;
100 plln_mul = STM32_PLL3_N_MULTIPLIER;
101 pllout_div1 = STM32_PLL3_P1_DIVISOR;
102 pllout_div2 = STM32_PLL3_P2_DIVISOR;
103 break;
104 #endif /* STM32_PLL3_ENABLED */
105 #if defined(STM32_PLL4_ENABLED)
106 case PLL4_ID:
107 pllm_div = STM32_PLL4_M_DIVISOR;
108 plln_mul = STM32_PLL4_N_MULTIPLIER;
109 pllout_div1 = STM32_PLL4_P1_DIVISOR;
110 pllout_div2 = STM32_PLL4_P2_DIVISOR;
111 break;
112 #endif /* STM32_PLL4_ENABLED */
113 default:
114 __ASSERT(0, "No PLL configured");
115 return 0;
116 }
117
118 __ASSERT_NO_MSG(pllm_div && pllout_div1 && pllout_div2);
119
120 return (pllsrc_freq / pllm_div) * plln_mul / (pllout_div1 * pllout_div2);
121 }
122
get_icout_frequency(uint32_t icsrc,int div)123 __unused uint32_t get_icout_frequency(uint32_t icsrc, int div)
124 {
125 if (icsrc == LL_RCC_ICCLKSOURCE_PLL1) {
126 return get_pllout_frequency(PLL1_ID) / div;
127 } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL2) {
128 return get_pllout_frequency(PLL2_ID) / div;
129 } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL3) {
130 return get_pllout_frequency(PLL3_ID) / div;
131 } else if (icsrc == LL_RCC_ICCLKSOURCE_PLL4) {
132 return get_pllout_frequency(PLL4_ID) / div;
133 }
134
135 __ASSERT(0, "No IC Source configured");
136 return 0;
137 }
138
get_sysclk_frequency(void)139 static uint32_t get_sysclk_frequency(void)
140 {
141 #if defined(STM32_SYSCLK_SRC_HSE)
142 return STM32_HSE_FREQ;
143 #elif defined(STM32_SYSCLK_SRC_HSI)
144 return STM32_HSI_FREQ;
145 #elif defined(STM32_SYSCLK_SRC_IC2)
146 return get_icout_frequency(LL_RCC_IC2_GetSource(), STM32_IC2_DIV);
147 #else
148 __ASSERT(0, "No SYSCLK Source configured");
149 return 0;
150 #endif
151
152 }
153
154
155 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)156 static int enabled_clock(uint32_t src_clk)
157 {
158 if ((src_clk == STM32_SRC_SYSCLK) ||
159 ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) ||
160 ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) ||
161 ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) ||
162 ((src_clk == STM32_SRC_HSI) && IS_ENABLED(STM32_HSI_ENABLED)) ||
163 ((src_clk == STM32_SRC_PLL1) && IS_ENABLED(STM32_PLL1_ENABLED)) ||
164 ((src_clk == STM32_SRC_PLL2) && IS_ENABLED(STM32_PLL2_ENABLED)) ||
165 ((src_clk == STM32_SRC_PLL3) && IS_ENABLED(STM32_PLL3_ENABLED)) ||
166 ((src_clk == STM32_SRC_PLL4) && IS_ENABLED(STM32_PLL4_ENABLED)) ||
167 ((src_clk == STM32_SRC_CKPER) && IS_ENABLED(STM32_CKPER_ENABLED)) ||
168 ((src_clk == STM32_SRC_IC1) && IS_ENABLED(STM32_IC1_ENABLED)) ||
169 ((src_clk == STM32_SRC_IC2) && IS_ENABLED(STM32_IC2_ENABLED)) ||
170 ((src_clk == STM32_SRC_IC3) && IS_ENABLED(STM32_IC3_ENABLED)) ||
171 ((src_clk == STM32_SRC_IC4) && IS_ENABLED(STM32_IC4_ENABLED)) ||
172 ((src_clk == STM32_SRC_IC5) && IS_ENABLED(STM32_IC5_ENABLED)) ||
173 ((src_clk == STM32_SRC_IC6) && IS_ENABLED(STM32_IC6_ENABLED)) ||
174 ((src_clk == STM32_SRC_IC7) && IS_ENABLED(STM32_IC7_ENABLED)) ||
175 ((src_clk == STM32_SRC_IC8) && IS_ENABLED(STM32_IC8_ENABLED)) ||
176 ((src_clk == STM32_SRC_IC9) && IS_ENABLED(STM32_IC9_ENABLED)) ||
177 ((src_clk == STM32_SRC_IC10) && IS_ENABLED(STM32_IC10_ENABLED)) ||
178 ((src_clk == STM32_SRC_IC11) && IS_ENABLED(STM32_IC11_ENABLED)) ||
179 ((src_clk == STM32_SRC_IC12) && IS_ENABLED(STM32_IC12_ENABLED)) ||
180 ((src_clk == STM32_SRC_IC13) && IS_ENABLED(STM32_IC13_ENABLED)) ||
181 ((src_clk == STM32_SRC_IC14) && IS_ENABLED(STM32_IC14_ENABLED)) ||
182 ((src_clk == STM32_SRC_IC15) && IS_ENABLED(STM32_IC15_ENABLED)) ||
183 ((src_clk == STM32_SRC_IC16) && IS_ENABLED(STM32_IC16_ENABLED)) ||
184 ((src_clk == STM32_SRC_IC17) && IS_ENABLED(STM32_IC17_ENABLED)) ||
185 ((src_clk == STM32_SRC_IC18) && IS_ENABLED(STM32_IC18_ENABLED)) ||
186 ((src_clk == STM32_SRC_IC19) && IS_ENABLED(STM32_IC19_ENABLED)) ||
187 ((src_clk == STM32_SRC_IC20) && IS_ENABLED(STM32_IC20_ENABLED))) {
188 return 0;
189 }
190
191 return -ENOTSUP;
192 }
193
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)194 static inline int stm32_clock_control_on(const struct device *dev,
195 clock_control_subsys_t sub_system)
196 {
197 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
198
199 ARG_UNUSED(dev);
200
201 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
202 /* Attempt to toggle a wrong periph clock bit */
203 return -ENOTSUP;
204 }
205
206 /* Set Run clock */
207 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
208 pclken->enr);
209
210 /* Set Low Power clock */
211 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus + STM32_CLOCK_LP_BUS_SHIFT,
212 pclken->enr);
213
214 return 0;
215 }
216
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)217 static inline int stm32_clock_control_off(const struct device *dev,
218 clock_control_subsys_t sub_system)
219 {
220 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
221
222 ARG_UNUSED(dev);
223
224 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
225 /* Attempt to toggle a wrong periph clock bit */
226 return -ENOTSUP;
227 }
228
229 /* Clear Run clock */
230 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
231 pclken->enr);
232
233 /* Clear Low Power clock */
234 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus + STM32_CLOCK_LP_BUS_SHIFT,
235 pclken->enr);
236
237 return 0;
238 }
239
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)240 static inline int stm32_clock_control_configure(const struct device *dev,
241 clock_control_subsys_t sub_system,
242 void *data)
243 {
244 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
245 int err;
246
247 ARG_UNUSED(dev);
248 ARG_UNUSED(data);
249
250 err = enabled_clock(pclken->bus);
251 if (err < 0) {
252 /* Attempt to configure a src clock not available or not valid */
253 return err;
254 }
255
256 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
257 STM32_DT_CLKSEL_MASK_GET(pclken->enr) <<
258 STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
259 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
260 STM32_DT_CLKSEL_VAL_GET(pclken->enr) <<
261 STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
262
263 return 0;
264 }
265
stm32_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sys,uint32_t * rate)266 static int stm32_clock_control_get_subsys_rate(const struct device *dev,
267 clock_control_subsys_t sys,
268 uint32_t *rate)
269 {
270 struct stm32_pclken *pclken = (struct stm32_pclken *)(sys);
271
272 uint32_t sys_clock = get_sysclk_frequency();
273 uint32_t ahb_clock = get_bus_clock(sys_clock, STM32_AHB_PRESCALER);
274
275 ARG_UNUSED(dev);
276
277 switch (pclken->bus) {
278 case STM32_SRC_SYSCLK:
279 *rate = get_sysclk_frequency();
280 break;
281 case STM32_CLOCK_BUS_AHB1:
282 case STM32_CLOCK_BUS_AHB2:
283 case STM32_CLOCK_BUS_AHB3:
284 case STM32_CLOCK_BUS_AHB4:
285 case STM32_CLOCK_BUS_AHB5:
286 *rate = ahb_clock;
287 break;
288 case STM32_CLOCK_BUS_APB1:
289 case STM32_CLOCK_BUS_APB1_2:
290 *rate = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
291 break;
292 case STM32_CLOCK_BUS_APB2:
293 *rate = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
294 break;
295 case STM32_CLOCK_BUS_APB4:
296 case STM32_CLOCK_BUS_APB4_2:
297 *rate = get_bus_clock(ahb_clock, STM32_APB4_PRESCALER);
298 break;
299 case STM32_CLOCK_BUS_APB5:
300 *rate = get_bus_clock(ahb_clock, STM32_APB5_PRESCALER);
301 break;
302 #if defined(STM32_LSE_ENABLED)
303 case STM32_SRC_LSE:
304 *rate = STM32_LSE_FREQ;
305 break;
306 #endif /* STM32_LSE_ENABLED */
307 #if defined(STM32_LSI_ENABLED)
308 case STM32_SRC_LSI:
309 *rate = STM32_LSI_FREQ;
310 break;
311 #endif /* STM32_LSI_ENABLED */
312 #if defined(STM32_HSE_ENABLED)
313 case STM32_SRC_HSE:
314 *rate = STM32_HSE_FREQ;
315 break;
316 #endif /* STM32_HSE_ENABLED */
317 #if defined(STM32_HSI_ENABLED)
318 case STM32_SRC_HSI:
319 *rate = STM32_HSI_FREQ;
320 break;
321 #endif /* STM32_HSI_ENABLED */
322 case STM32_SRC_PLL1:
323 *rate = get_pllout_frequency(PLL1_ID);
324 break;
325 case STM32_SRC_PLL2:
326 *rate = get_pllout_frequency(PLL2_ID);
327 break;
328 case STM32_SRC_PLL3:
329 *rate = get_pllout_frequency(PLL3_ID);
330 break;
331 case STM32_SRC_PLL4:
332 *rate = get_pllout_frequency(PLL4_ID);
333 break;
334 #if defined(STM32_CKPER_ENABLED)
335 case STM32_SRC_CKPER:
336 *rate = LL_RCC_GetCLKPClockFreq(LL_RCC_CLKP_CLKSOURCE);
337 break;
338 #endif /* STM32_CKPER_ENABLED */
339 #if defined(STM32_IC1_ENABLED)
340 case STM32_SRC_IC1:
341 *rate = get_icout_frequency(LL_RCC_IC1_GetSource(), STM32_IC1_DIV);
342 break;
343 #endif /* STM32_IC1_ENABLED */
344 #if defined(STM32_IC2_ENABLED)
345 case STM32_SRC_IC2:
346 *rate = get_icout_frequency(LL_RCC_IC2_GetSource(), STM32_IC2_DIV);
347 break;
348 #endif /* STM32_IC2_ENABLED */
349 #if defined(STM32_IC3_ENABLED)
350 case STM32_SRC_IC3:
351 *rate = get_icout_frequency(LL_RCC_IC3_GetSource(), STM32_IC3_DIV);
352 break;
353 #endif /* STM32_IC3_ENABLED */
354 #if defined(STM32_IC4_ENABLED)
355 case STM32_SRC_IC4:
356 *rate = get_icout_frequency(LL_RCC_IC4_GetSource(), STM32_IC4_DIV);
357 break;
358 #endif /* STM32_IC4_ENABLED */
359 #if defined(STM32_IC5_ENABLED)
360 case STM32_SRC_IC5:
361 *rate = get_icout_frequency(LL_RCC_IC5_GetSource(), STM32_IC5_DIV);
362 break;
363 #endif /* STM32_IC5_ENABLED */
364 #if defined(STM32_IC6_ENABLED)
365 case STM32_SRC_IC6:
366 *rate = get_icout_frequency(LL_RCC_IC6_GetSource(), STM32_IC6_DIV);
367 break;
368 #endif /* STM32_IC6_ENABLED */
369 #if defined(STM32_IC7_ENABLED)
370 case STM32_SRC_IC7:
371 *rate = get_icout_frequency(LL_RCC_IC7_GetSource(), STM32_IC7_DIV);
372 break;
373 #endif /* STM32_IC7_ENABLED */
374 #if defined(STM32_IC8_ENABLED)
375 case STM32_SRC_IC8:
376 *rate = get_icout_frequency(LL_RCC_IC8_GetSource(), STM32_IC8_DIV);
377 break;
378 #endif /* STM32_IC8_ENABLED */
379 #if defined(STM32_IC9_ENABLED)
380 case STM32_SRC_IC9:
381 *rate = get_icout_frequency(LL_RCC_IC9_GetSource(), STM32_IC9_DIV);
382 break;
383 #endif /* STM32_IC9_ENABLED */
384 #if defined(STM32_IC10_ENABLED)
385 case STM32_SRC_IC10:
386 *rate = get_icout_frequency(LL_RCC_IC10_GetSource(), STM32_IC10_DIV);
387 break;
388 #endif /* STM32_IC10_ENABLED */
389 #if defined(STM32_IC11_ENABLED)
390 case STM32_SRC_IC11:
391 *rate = get_icout_frequency(LL_RCC_IC11_GetSource(), STM32_IC11_DIV);
392 break;
393 #endif /* STM32_IC11_ENABLED */
394 #if defined(STM32_IC12_ENABLED)
395 case STM32_SRC_IC12:
396 *rate = get_icout_frequency(LL_RCC_IC12_GetSource(), STM32_IC12_DIV);
397 break;
398 #endif /* STM32_IC12_ENABLED */
399 #if defined(STM32_IC13_ENABLED)
400 case STM32_SRC_IC13:
401 *rate = get_icout_frequency(LL_RCC_IC13_GetSource(), STM32_IC13_DIV);
402 break;
403 #endif /* STM32_IC13_ENABLED */
404 #if defined(STM32_IC14_ENABLED)
405 case STM32_SRC_IC14:
406 *rate = get_icout_frequency(LL_RCC_IC14_GetSource(), STM32_IC14_DIV);
407 break;
408 #endif /* STM32_IC14_ENABLED */
409 #if defined(STM32_IC15_ENABLED)
410 case STM32_SRC_IC15:
411 *rate = get_icout_frequency(LL_RCC_IC15_GetSource(), STM32_IC15_DIV);
412 break;
413 #endif /* STM32_IC15_ENABLED */
414 #if defined(STM32_IC16_ENABLED)
415 case STM32_SRC_IC16:
416 *rate = get_icout_frequency(LL_RCC_IC16_GetSource(), STM32_IC16_DIV);
417 break;
418 #endif /* STM32_IC16_ENABLED */
419 #if defined(STM32_IC17_ENABLED)
420 case STM32_SRC_IC17:
421 *rate = get_icout_frequency(LL_RCC_IC17_GetSource(), STM32_IC17_DIV);
422 break;
423 #endif /* STM32_IC17_ENABLED */
424 #if defined(STM32_IC18_ENABLED)
425 case STM32_SRC_IC18:
426 *rate = get_icout_frequency(LL_RCC_IC18_GetSource(), STM32_IC18_DIV);
427 break;
428 #endif /* STM32_IC18_ENABLED */
429 #if defined(STM32_IC19_ENABLED)
430 case STM32_SRC_IC19:
431 *rate = get_icout_frequency(LL_RCC_IC19_GetSource(), STM32_IC19_DIV);
432 break;
433 #endif /* STM32_IC19_ENABLED */
434 #if defined(STM32_IC20_ENABLED)
435 case STM32_SRC_IC20:
436 *rate = get_icout_frequency(LL_RCC_IC20_GetSource(), STM32_IC20_DIV);
437 break;
438 #endif /* STM32_IC20_ENABLED */
439 default:
440 return -ENOTSUP;
441 }
442
443 if (pclken->div) {
444 *rate /= (pclken->div + 1);
445 }
446
447 return 0;
448 }
449
450 static DEVICE_API(clock_control, stm32_clock_control_api) = {
451 .on = stm32_clock_control_on,
452 .off = stm32_clock_control_off,
453 .get_rate = stm32_clock_control_get_subsys_rate,
454 .configure = stm32_clock_control_configure,
455 };
456
457 /*
458 * Unconditionally switch the system clock source to HSI.
459 */
460 __unused
stm32_clock_switch_to_hsi(void)461 static void stm32_clock_switch_to_hsi(void)
462 {
463 /* Enable HSI if not enabled */
464 if (LL_RCC_HSI_IsReady() != 1) {
465 /* Enable HSI */
466 LL_RCC_HSI_Enable();
467 while (LL_RCC_HSI_IsReady() != 1) {
468 /* Wait for HSI ready */
469 }
470 }
471
472 /* Set HSI as SYSCLCK source */
473 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
474 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
475 }
476
477 LL_RCC_SetCpuClkSource(LL_RCC_CPU_CLKSOURCE_HSI);
478 while (LL_RCC_GetCpuClkSource() != LL_RCC_CPU_CLKSOURCE_STATUS_HSI) {
479 }
480 }
481
set_up_ics(void)482 static int set_up_ics(void)
483 {
484 #if defined(STM32_IC1_ENABLED)
485 LL_RCC_IC1_SetSource(ic_src_pll(STM32_IC1_PLL_SRC));
486 LL_RCC_IC1_SetDivider(STM32_IC1_DIV);
487 LL_RCC_IC1_Enable();
488 #endif
489
490 #if defined(STM32_IC2_ENABLED)
491 LL_RCC_IC2_SetSource(ic_src_pll(STM32_IC2_PLL_SRC));
492 LL_RCC_IC2_SetDivider(STM32_IC2_DIV);
493 LL_RCC_IC2_Enable();
494 #endif
495
496 #if defined(STM32_IC3_ENABLED)
497 LL_RCC_IC3_SetSource(ic_src_pll(STM32_IC3_PLL_SRC));
498 LL_RCC_IC3_SetDivider(STM32_IC3_DIV);
499 LL_RCC_IC3_Enable();
500 #endif
501
502 #if defined(STM32_IC4_ENABLED)
503 LL_RCC_IC4_SetSource(ic_src_pll(STM32_IC4_PLL_SRC));
504 LL_RCC_IC4_SetDivider(STM32_IC4_DIV);
505 LL_RCC_IC4_Enable();
506 #endif
507
508 #if defined(STM32_IC5_ENABLED)
509 LL_RCC_IC5_SetSource(ic_src_pll(STM32_IC5_PLL_SRC));
510 LL_RCC_IC5_SetDivider(STM32_IC5_DIV);
511 LL_RCC_IC5_Enable();
512 #endif
513
514 #if defined(STM32_IC6_ENABLED)
515 LL_RCC_IC6_SetSource(ic_src_pll(STM32_IC6_PLL_SRC));
516 LL_RCC_IC6_SetDivider(STM32_IC6_DIV);
517 LL_RCC_IC6_Enable();
518 #endif
519
520 #if defined(STM32_IC7_ENABLED)
521 LL_RCC_IC7_SetSource(ic_src_pll(STM32_IC7_PLL_SRC));
522 LL_RCC_IC7_SetDivider(STM32_IC7_DIV);
523 LL_RCC_IC7_Enable();
524 #endif
525
526 #if defined(STM32_IC8_ENABLED)
527 LL_RCC_IC8_SetSource(ic_src_pll(STM32_IC8_PLL_SRC));
528 LL_RCC_IC8_SetDivider(STM32_IC8_DIV);
529 LL_RCC_IC8_Enable();
530 #endif
531
532 #if defined(STM32_IC9_ENABLED)
533 LL_RCC_IC9_SetSource(ic_src_pll(STM32_IC9_PLL_SRC));
534 LL_RCC_IC9_SetDivider(STM32_IC9_DIV);
535 LL_RCC_IC9_Enable();
536 #endif
537
538 #if defined(STM32_IC10_ENABLED)
539 LL_RCC_IC10_SetSource(ic_src_pll(STM32_IC10_PLL_SRC));
540 LL_RCC_IC10_SetDivider(STM32_IC10_DIV);
541 LL_RCC_IC10_Enable();
542 #endif
543
544 #if defined(STM32_IC11_ENABLED)
545 LL_RCC_IC11_SetSource(ic_src_pll(STM32_IC11_PLL_SRC));
546 LL_RCC_IC11_SetDivider(STM32_IC11_DIV);
547 LL_RCC_IC11_Enable();
548 #endif
549
550 #if defined(STM32_IC12_ENABLED)
551 LL_RCC_IC12_SetSource(ic_src_pll(STM32_IC12_PLL_SRC));
552 LL_RCC_IC12_SetDivider(STM32_IC12_DIV);
553 LL_RCC_IC12_Enable();
554 #endif
555
556 #if defined(STM32_IC13_ENABLED)
557 LL_RCC_IC13_SetSource(ic_src_pll(STM32_IC13_PLL_SRC));
558 LL_RCC_IC13_SetDivider(STM32_IC13_DIV);
559 LL_RCC_IC13_Enable();
560 #endif
561
562 #if defined(STM32_IC14_ENABLED)
563 LL_RCC_IC14_SetSource(ic_src_pll(STM32_IC14_PLL_SRC));
564 LL_RCC_IC14_SetDivider(STM32_IC14_DIV);
565 LL_RCC_IC14_Enable();
566 #endif
567
568 #if defined(STM32_IC15_ENABLED)
569 LL_RCC_IC15_SetSource(ic_src_pll(STM32_IC15_PLL_SRC));
570 LL_RCC_IC15_SetDivider(STM32_IC15_DIV);
571 LL_RCC_IC15_Enable();
572 #endif
573
574 #if defined(STM32_IC16_ENABLED)
575 LL_RCC_IC16_SetSource(ic_src_pll(STM32_IC16_PLL_SRC));
576 LL_RCC_IC16_SetDivider(STM32_IC16_DIV);
577 LL_RCC_IC16_Enable();
578 #endif
579
580 #if defined(STM32_IC17_ENABLED)
581 LL_RCC_IC17_SetSource(ic_src_pll(STM32_IC17_PLL_SRC));
582 LL_RCC_IC17_SetDivider(STM32_IC17_DIV);
583 LL_RCC_IC17_Enable();
584 #endif
585
586 #if defined(STM32_IC18_ENABLED)
587 LL_RCC_IC18_SetSource(ic_src_pll(STM32_IC18_PLL_SRC));
588 LL_RCC_IC18_SetDivider(STM32_IC18_DIV);
589 LL_RCC_IC18_Enable();
590 #endif
591
592 #if defined(STM32_IC19_ENABLED)
593 LL_RCC_IC19_SetSource(ic_src_pll(STM32_IC19_PLL_SRC));
594 LL_RCC_IC19_SetDivider(STM32_IC19_DIV);
595 LL_RCC_IC19_Enable();
596 #endif
597
598 #if defined(STM32_IC20_ENABLED)
599 LL_RCC_IC20_SetSource(ic_src_pll(STM32_IC20_PLL_SRC));
600 LL_RCC_IC20_SetDivider(STM32_IC20_DIV);
601 LL_RCC_IC20_Enable();
602 #endif
603
604 return 0;
605 }
606
set_up_plls(void)607 static int set_up_plls(void)
608 {
609 #if defined(STM32_PLL1_ENABLED)
610 /* TODO: Do not switch systematically on HSI if not needed */
611 stm32_clock_switch_to_hsi();
612
613 LL_RCC_PLL1_Disable();
614
615 /* Configure PLL source : Can be HSE, HSI, MSI */
616 if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
617 /* Main PLL configuration and activation */
618 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSE);
619 } else if (IS_ENABLED(STM32_PLL_SRC_MSI)) {
620 /* Main PLL configuration and activation */
621 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_MSI);
622 } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
623 /* Main PLL configuration and activation */
624 LL_RCC_PLL1_SetSource(LL_RCC_PLLSOURCE_HSI);
625 } else {
626 return -ENOTSUP;
627 }
628
629 /* Disable PLL1 modulation spread-spectrum */
630 LL_RCC_PLL1_DisableModulationSpreadSpectrum();
631
632 /* Disable bypass to use the PLL VCO */
633 if (LL_RCC_PLL1_IsEnabledBypass()) {
634 LL_RCC_PLL1_DisableBypass();
635 }
636
637 /* Configure PLL */
638 LL_RCC_PLL1_SetM(STM32_PLL1_M_DIVISOR);
639 LL_RCC_PLL1_SetN(STM32_PLL1_N_MULTIPLIER);
640 LL_RCC_PLL1_SetP1(STM32_PLL1_P1_DIVISOR);
641 LL_RCC_PLL1_SetP2(STM32_PLL1_P2_DIVISOR);
642
643 /* Disable fractional mode */
644 LL_RCC_PLL1_SetFRACN(0);
645 LL_RCC_PLL1_DisableFractionalModulationSpreadSpectrum();
646
647 LL_RCC_PLL1_AssertModulationSpreadSpectrumReset();
648
649 /* Enable post division */
650 if (!LL_RCC_PLL1P_IsEnabled()) {
651 LL_RCC_PLL1P_Enable();
652 }
653
654 LL_RCC_PLL1_Enable();
655 while (LL_RCC_PLL1_IsReady() != 1U) {
656 }
657 #endif /* STM32_PLL1_ENABLED */
658
659 #if defined(STM32_PLL2_ENABLED)
660 LL_RCC_PLL2_Disable();
661
662 /* Configure PLL source : Can be HSE, HSI, MSI */
663 if (IS_ENABLED(STM32_PLL2_SRC_HSE)) {
664 /* Main PLL configuration and activation */
665 LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_HSE);
666 } else if (IS_ENABLED(STM32_PLL2_SRC_MSI)) {
667 /* Main PLL configuration and activation */
668 LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_MSI);
669 } else if (IS_ENABLED(STM32_PLL2_SRC_HSI)) {
670 /* Main PLL configuration and activation */
671 LL_RCC_PLL2_SetSource(LL_RCC_PLLSOURCE_HSI);
672 } else {
673 return -ENOTSUP;
674 }
675
676 /* Disable PLL2 modulation spread-spectrum */
677 LL_RCC_PLL2_DisableModulationSpreadSpectrum();
678
679 /* Disable bypass to use the PLL VCO */
680 if (LL_RCC_PLL2_IsEnabledBypass()) {
681 LL_RCC_PLL2_DisableBypass();
682 }
683
684 /* Configure PLL */
685 LL_RCC_PLL2_SetM(STM32_PLL2_M_DIVISOR);
686 LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER);
687 LL_RCC_PLL2_SetP1(STM32_PLL2_P1_DIVISOR);
688 LL_RCC_PLL2_SetP2(STM32_PLL2_P2_DIVISOR);
689
690 /* Disable fractional mode */
691 LL_RCC_PLL2_SetFRACN(0);
692 LL_RCC_PLL2_DisableFractionalModulationSpreadSpectrum();
693
694 LL_RCC_PLL2_AssertModulationSpreadSpectrumReset();
695
696 /* Enable post division */
697 if (!LL_RCC_PLL2P_IsEnabled()) {
698 LL_RCC_PLL2P_Enable();
699 }
700
701 LL_RCC_PLL2_Enable();
702 while (LL_RCC_PLL2_IsReady() != 1U) {
703 }
704 #endif
705
706 #if defined(STM32_PLL3_ENABLED)
707 LL_RCC_PLL3_Disable();
708
709 /* Configure PLL source : Can be HSE, HSI, MSIS */
710 if (IS_ENABLED(STM32_PLL3_SRC_HSE)) {
711 /* Main PLL configuration and activation */
712 LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_HSE);
713 } else if (IS_ENABLED(STM32_PLL3_SRC_MSI)) {
714 /* Main PLL configuration and activation */
715 LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_MSI);
716 } else if (IS_ENABLED(STM32_PLL3_SRC_HSI)) {
717 /* Main PLL configuration and activation */
718 LL_RCC_PLL3_SetSource(LL_RCC_PLLSOURCE_HSI);
719 } else {
720 return -ENOTSUP;
721 }
722
723 /* Disable PLL3 modulation spread-spectrum */
724 LL_RCC_PLL3_DisableModulationSpreadSpectrum();
725
726 /* Disable bypass to use the PLL VCO */
727 if (LL_RCC_PLL3_IsEnabledBypass()) {
728 LL_RCC_PLL3_DisableBypass();
729 }
730
731 /* Configure PLL */
732 LL_RCC_PLL3_SetM(STM32_PLL3_M_DIVISOR);
733 LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER);
734 LL_RCC_PLL3_SetP1(STM32_PLL3_P1_DIVISOR);
735 LL_RCC_PLL3_SetP2(STM32_PLL3_P2_DIVISOR);
736
737 /* Disable fractional mode */
738 LL_RCC_PLL3_SetFRACN(0);
739 LL_RCC_PLL3_DisableFractionalModulationSpreadSpectrum();
740
741 LL_RCC_PLL3_AssertModulationSpreadSpectrumReset();
742
743 /* Enable post division */
744 if (!LL_RCC_PLL3P_IsEnabled()) {
745 LL_RCC_PLL3P_Enable();
746 }
747
748 LL_RCC_PLL3_Enable();
749 while (LL_RCC_PLL3_IsReady() != 1U) {
750 }
751 #endif
752
753 #if defined(STM32_PLL4_ENABLED)
754 LL_RCC_PLL4_Disable();
755
756 /* Configure PLL source : Can be HSE, HSI, MSIS */
757 if (IS_ENABLED(STM32_PLL4_SRC_HSE)) {
758 /* Main PLL configuration and activation */
759 LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_HSE);
760 } else if (IS_ENABLED(STM32_PLL4_SRC_MSI)) {
761 /* Main PLL configuration and activation */
762 LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_MSI);
763 } else if (IS_ENABLED(STM32_PLL4_SRC_HSI)) {
764 /* Main PLL configuration and activation */
765 LL_RCC_PLL4_SetSource(LL_RCC_PLLSOURCE_HSI);
766 } else {
767 return -ENOTSUP;
768 }
769
770 /* Disable PLL4 modulation spread-spectrum */
771 LL_RCC_PLL4_DisableModulationSpreadSpectrum();
772
773 /* Disable bypass to use the PLL VCO */
774 if (LL_RCC_PLL4_IsEnabledBypass()) {
775 LL_RCC_PLL4_DisableBypass();
776 }
777
778 /* Configure PLL */
779 LL_RCC_PLL4_SetM(STM32_PLL4_M_DIVISOR);
780 LL_RCC_PLL4_SetN(STM32_PLL4_N_MULTIPLIER);
781 LL_RCC_PLL4_SetP1(STM32_PLL4_P1_DIVISOR);
782 LL_RCC_PLL4_SetP2(STM32_PLL4_P2_DIVISOR);
783
784 /* Disable fractional mode */
785 LL_RCC_PLL4_SetFRACN(0);
786 LL_RCC_PLL4_DisableFractionalModulationSpreadSpectrum();
787
788 LL_RCC_PLL4_AssertModulationSpreadSpectrumReset();
789
790 /* Enable post division */
791 if (!LL_RCC_PLL4P_IsEnabled()) {
792 LL_RCC_PLL4P_Enable();
793 }
794
795 LL_RCC_PLL4_Enable();
796 while (LL_RCC_PLL4_IsReady() != 1U) {
797 }
798 #endif
799
800 return 0;
801 }
802
set_up_fixed_clock_sources(void)803 static void set_up_fixed_clock_sources(void)
804 {
805 if (IS_ENABLED(STM32_HSE_ENABLED)) {
806 /* Check if need to enable HSE bypass feature or not */
807 if (IS_ENABLED(STM32_HSE_BYPASS)) {
808 LL_RCC_HSE_EnableBypass();
809 } else {
810 LL_RCC_HSE_DisableBypass();
811 }
812
813 if (IS_ENABLED(STM32_HSE_DIV2)) {
814 LL_RCC_HSE_SelectHSEDiv2AsDiv2Clock();
815 } else {
816 LL_RCC_HSE_SelectHSEAsDiv2Clock();
817 }
818
819 /* Enable HSE */
820 LL_RCC_HSE_Enable();
821 while (LL_RCC_HSE_IsReady() != 1) {
822 /* Wait for HSE ready */
823 }
824 }
825
826 if (IS_ENABLED(STM32_HSI_ENABLED)) {
827 /* Enable HSI oscillator */
828 LL_RCC_HSI_Enable();
829 while (LL_RCC_HSI_IsReady() != 1) {
830 }
831 /* HSI divider configuration */
832 LL_RCC_HSI_SetDivider(hsi_divider(STM32_HSI_DIVISOR));
833 }
834
835 if (IS_ENABLED(STM32_LSE_ENABLED)) {
836 /* Enable the power interface clock */
837 LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_PWR);
838
839 if (!LL_PWR_IsEnabledBkUpAccess()) {
840 /* Enable write access to Backup domain */
841 LL_PWR_EnableBkUpAccess();
842 while (!LL_PWR_IsEnabledBkUpAccess()) {
843 /* Wait for Backup domain access */
844 }
845 }
846
847 /* Configure driving capability */
848 LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_LSECFGR_LSEDRV_Pos);
849
850 if (IS_ENABLED(STM32_LSE_BYPASS)) {
851 /* Configure LSE bypass */
852 LL_RCC_LSE_EnableBypass();
853 }
854
855 /* Enable LSE Oscillator */
856 LL_RCC_LSE_Enable();
857 /* Wait for LSE ready */
858 while (!LL_RCC_LSE_IsReady()) {
859 }
860
861 LL_PWR_DisableBkUpAccess();
862 }
863
864 if (IS_ENABLED(STM32_LSI_ENABLED)) {
865 /* Enable LSI oscillator */
866 LL_RCC_LSI_Enable();
867 while (LL_RCC_LSI_IsReady() != 1) {
868 }
869 }
870 }
871
stm32_clock_control_init(const struct device * dev)872 int stm32_clock_control_init(const struct device *dev)
873 {
874 int r = 0;
875
876 ARG_UNUSED(dev);
877
878 /* For now, enable clocks (including low_power ones) of all RAM */
879 uint32_t all_ram = LL_MEM_AXISRAM1 | LL_MEM_AXISRAM2 | LL_MEM_AXISRAM3 | LL_MEM_AXISRAM4 |
880 LL_MEM_AXISRAM5 | LL_MEM_AXISRAM6 | LL_MEM_AHBSRAM1 | LL_MEM_AHBSRAM2 |
881 LL_MEM_BKPSRAM | LL_MEM_FLEXRAM | LL_MEM_CACHEAXIRAM | LL_MEM_VENCRAM;
882 LL_MEM_EnableClock(all_ram);
883 LL_MEM_EnableClockLowPower(all_ram);
884
885 /* Set up individual enabled clocks */
886 set_up_fixed_clock_sources();
887
888 /* Set up PLLs */
889 r = set_up_plls();
890 if (r < 0) {
891 return r;
892 }
893
894 /* Preset the prescalers prior to chosing SYSCLK */
895 /* Prevents APB clock to go over limits */
896 /* Set buses (AHB, APB1, APB2, APB4 & APB5) prescalers */
897 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_AHB_PRESCALER));
898 LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
899 LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
900 LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_APB4_PRESCALER));
901 LL_RCC_SetAPB5Prescaler(apb5_prescaler(STM32_APB5_PRESCALER));
902
903 if (IS_ENABLED(STM32_CKPER_ENABLED)) {
904 LL_MISC_EnableClock(LL_PER);
905 LL_MISC_EnableClockLowPower(LL_PER);
906 while (LL_MISC_IsEnabledClock(LL_PER) != 1) {
907 }
908 }
909
910 /* Set up ICs */
911 r = set_up_ics();
912 if (r < 0) {
913 return r;
914 }
915
916 /* Set up sys clock */
917 if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) {
918 /* Set sysclk source to HSE */
919 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
920 while (LL_RCC_GetSysClkSource() !=
921 LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
922 }
923 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) {
924 /* Set sysclk source to HSI */
925 stm32_clock_switch_to_hsi();
926 } else if (IS_ENABLED(STM32_SYSCLK_SRC_IC2)) {
927 /* Set sysclk source to IC2 */
928 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_IC2_IC6_IC11);
929 while (LL_RCC_GetSysClkSource() !=
930 LL_RCC_SYS_CLKSOURCE_STATUS_IC2_IC6_IC11) {
931 }
932 } else {
933 return -ENOTSUP;
934 }
935
936 /* Update CMSIS variable */
937 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
938
939 return r;
940 }
941
942 /**
943 * @brief RCC device, note that priority is intentionally set to 1 so
944 * that the device init runs just after SOC init
945 */
946 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
947 &stm32_clock_control_init,
948 NULL,
949 NULL, NULL,
950 PRE_KERNEL_1,
951 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
952 &stm32_clock_control_api);
953