1 /*
2 *
3 * Copyright (c) 2021 Linaro Limited
4 * Copyright (c) 2022 Thomas Stranger
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9
10 #include <soc.h>
11 #include <stm32_ll_bus.h>
12 #include <stm32_ll_pwr.h>
13 #include <stm32_ll_rcc.h>
14 #include <stm32_ll_utils.h>
15 #include <stm32_ll_system.h>
16 #include <zephyr/arch/cpu.h>
17 #include <zephyr/drivers/clock_control.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
20
21 /* Macros to fill up prescaler values */
22 #define z_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
23 #define ahb_prescaler(v) z_ahb_prescaler(v)
24
25 #define z_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
26 #define apb1_prescaler(v) z_apb1_prescaler(v)
27
28 #define z_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
29 #define apb2_prescaler(v) z_apb2_prescaler(v)
30
31 #define z_apb3_prescaler(v) LL_RCC_APB3_DIV_ ## v
32 #define apb3_prescaler(v) z_apb3_prescaler(v)
33
34 #define PLL1_ID 1
35 #define PLL2_ID 2
36 #define PLL3_ID 3
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
get_msis_frequency(void)43 static uint32_t get_msis_frequency(void)
44 {
45 return __LL_RCC_CALC_MSIS_FREQ(LL_RCC_MSI_IsEnabledRangeSelect(),
46 ((LL_RCC_MSI_IsEnabledRangeSelect() == 1U) ?
47 LL_RCC_MSIS_GetRange() :
48 LL_RCC_MSIS_GetRangeAfterStandby()));
49 }
50
51 __unused
52 /** @brief returns the pll source frequency of given pll_id */
get_pllsrc_frequency(size_t pll_id)53 static uint32_t get_pllsrc_frequency(size_t pll_id)
54 {
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 return STM32_HSI_FREQ;
60 } else if ((IS_ENABLED(STM32_PLL_SRC_HSE) && pll_id == PLL1_ID) ||
61 (IS_ENABLED(STM32_PLL2_SRC_HSE) && pll_id == PLL2_ID) ||
62 (IS_ENABLED(STM32_PLL3_SRC_HSE) && pll_id == PLL3_ID)) {
63 return STM32_HSE_FREQ;
64 } else if ((IS_ENABLED(STM32_PLL_SRC_MSIS) && pll_id == PLL1_ID) ||
65 (IS_ENABLED(STM32_PLL2_SRC_MSIS) && pll_id == PLL2_ID) ||
66 (IS_ENABLED(STM32_PLL3_SRC_MSIS) && pll_id == PLL3_ID)) {
67 return get_msis_frequency();
68 }
69
70 __ASSERT(0, "No PLL Source configured");
71 return 0;
72 }
73
get_startup_frequency(void)74 static uint32_t get_startup_frequency(void)
75 {
76 switch (LL_RCC_GetSysClkSource()) {
77 case LL_RCC_SYS_CLKSOURCE_STATUS_MSIS:
78 return get_msis_frequency();
79 case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:
80 return STM32_HSI_FREQ;
81 case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:
82 return STM32_HSE_FREQ;
83 case LL_RCC_SYS_CLKSOURCE_STATUS_PLL1:
84 return get_pllsrc_frequency(PLL1_ID);
85 default:
86 __ASSERT(0, "Unexpected startup freq");
87 return 0;
88 }
89 }
90
91 __unused
get_pllout_frequency(uint32_t pllsrc_freq,int pllm_div,int plln_mul,int pllout_div)92 static uint32_t get_pllout_frequency(uint32_t pllsrc_freq,
93 int pllm_div,
94 int plln_mul,
95 int pllout_div)
96 {
97 __ASSERT_NO_MSG(pllm_div && pllout_div);
98
99 return (pllsrc_freq / pllm_div) * plln_mul / pllout_div;
100 }
101
get_sysclk_frequency(void)102 static uint32_t get_sysclk_frequency(void)
103 {
104 #if defined(STM32_SYSCLK_SRC_PLL)
105 return get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
106 STM32_PLL_M_DIVISOR,
107 STM32_PLL_N_MULTIPLIER,
108 STM32_PLL_R_DIVISOR);
109 #elif defined(STM32_SYSCLK_SRC_MSIS)
110 return get_msis_frequency();
111 #elif defined(STM32_SYSCLK_SRC_HSE)
112 return STM32_HSE_FREQ;
113 #elif defined(STM32_SYSCLK_SRC_HSI)
114 return STM32_HSI_FREQ;
115 #else
116 __ASSERT(0, "No SYSCLK Source configured");
117 return 0;
118 #endif
119
120 }
121
122 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)123 static int enabled_clock(uint32_t src_clk)
124 {
125 if ((src_clk == STM32_SRC_SYSCLK) ||
126 ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) ||
127 ((src_clk == STM32_SRC_HSI16) && 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_MSIS) && IS_ENABLED(STM32_MSIS_ENABLED)) ||
132 ((src_clk == STM32_SRC_MSIK) && IS_ENABLED(STM32_MSIK_ENABLED)) ||
133 ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) ||
134 ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) ||
135 ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED)) ||
136 ((src_clk == STM32_SRC_PLL2_P) && IS_ENABLED(STM32_PLL2_P_ENABLED)) ||
137 ((src_clk == STM32_SRC_PLL2_Q) && IS_ENABLED(STM32_PLL2_Q_ENABLED)) ||
138 ((src_clk == STM32_SRC_PLL2_R) && IS_ENABLED(STM32_PLL2_R_ENABLED)) ||
139 ((src_clk == STM32_SRC_PLL3_P) && IS_ENABLED(STM32_PLL3_P_ENABLED)) ||
140 ((src_clk == STM32_SRC_PLL3_Q) && IS_ENABLED(STM32_PLL3_Q_ENABLED)) ||
141 ((src_clk == STM32_SRC_PLL3_R) && IS_ENABLED(STM32_PLL3_R_ENABLED))) {
142 return 0;
143 }
144
145 return -ENOTSUP;
146 }
147
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)148 static inline int stm32_clock_control_on(const struct device *dev,
149 clock_control_subsys_t sub_system)
150 {
151 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
152
153 ARG_UNUSED(dev);
154
155 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
156 /* Attemp 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
163 return 0;
164 }
165
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)166 static inline int stm32_clock_control_off(const struct device *dev,
167 clock_control_subsys_t sub_system)
168 {
169 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
170
171 ARG_UNUSED(dev);
172
173 if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
174 /* Attemp to toggle a wrong periph clock bit */
175 return -ENOTSUP;
176 }
177
178 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
179 pclken->enr);
180
181 return 0;
182 }
183
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)184 static inline int stm32_clock_control_configure(const struct device *dev,
185 clock_control_subsys_t sub_system,
186 void *data)
187 {
188 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
189 int err;
190
191 ARG_UNUSED(dev);
192 ARG_UNUSED(data);
193
194 err = enabled_clock(pclken->bus);
195 if (err < 0) {
196 /* Attempt to configure a src clock not available or not valid */
197 return err;
198 }
199
200 sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr),
201 STM32_CLOCK_MASK_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr));
202 sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_CLOCK_REG_GET(pclken->enr),
203 STM32_CLOCK_VAL_GET(pclken->enr) << STM32_CLOCK_SHIFT_GET(pclken->enr));
204
205 return 0;
206 }
207
stm32_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sys,uint32_t * rate)208 static int stm32_clock_control_get_subsys_rate(const struct device *dev,
209 clock_control_subsys_t sys,
210 uint32_t *rate)
211 {
212 struct stm32_pclken *pclken = (struct stm32_pclken *)(sys);
213
214 /*
215 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
216 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
217 * since it will be updated after clock configuration and hence
218 * more likely to contain actual clock speed
219 */
220 uint32_t ahb_clock = SystemCoreClock;
221 uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
222 uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
223 uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_APB3_PRESCALER);
224
225 ARG_UNUSED(dev);
226
227 switch (pclken->bus) {
228 case STM32_CLOCK_BUS_AHB1:
229 case STM32_CLOCK_BUS_AHB2:
230 case STM32_CLOCK_BUS_AHB2_2:
231 case STM32_CLOCK_BUS_AHB3:
232 *rate = ahb_clock;
233 break;
234 case STM32_CLOCK_BUS_APB1:
235 case STM32_CLOCK_BUS_APB1_2:
236 *rate = apb1_clock;
237 break;
238 case STM32_CLOCK_BUS_APB2:
239 *rate = apb2_clock;
240 break;
241 case STM32_CLOCK_BUS_APB3:
242 *rate = apb3_clock;
243 break;
244 case STM32_SRC_SYSCLK:
245 *rate = get_sysclk_frequency();
246 break;
247 #if defined(STM32_HSI_ENABLED)
248 case STM32_SRC_HSI16:
249 *rate = STM32_HSI_FREQ;
250 break;
251 #endif /* STM32_HSI_ENABLED */
252 #if defined(STM32_MSIS_ENABLED)
253 case STM32_SRC_MSIS:
254 *rate = get_msis_frequency();
255 break;
256 #endif /* STM32_MSIS_ENABLED */
257 #if defined(STM32_MSIK_ENABLED)
258 case STM32_SRC_MSIK:
259 *rate = __LL_RCC_CALC_MSIK_FREQ(LL_RCC_MSIRANGESEL_RUN,
260 STM32_MSIK_RANGE << RCC_ICSCR1_MSIKRANGE_Pos);
261 break;
262 #endif /* STM32_MSIK_ENABLED */
263 #if defined(STM32_HSE_ENABLED)
264 case STM32_SRC_HSE:
265 *rate = STM32_HSE_FREQ;
266 break;
267 #endif /* STM32_HSE_ENABLED */
268 #if defined(STM32_LSE_ENABLED)
269 case STM32_SRC_LSE:
270 *rate = STM32_LSE_FREQ;
271 break;
272 #endif /* STM32_LSE_ENABLED */
273 #if defined(STM32_LSI_ENABLED)
274 case STM32_SRC_LSI:
275 *rate = STM32_LSI_FREQ;
276 break;
277 #endif /* STM32_LSI_ENABLED */
278 #if defined(STM32_HSI48_ENABLED)
279 case STM32_SRC_HSI48:
280 *rate = STM32_HSI48_FREQ;
281 break;
282 #endif /* STM32_HSI48_ENABLED */
283 #if defined(STM32_PLL_ENABLED)
284 case STM32_SRC_PLL1_P:
285 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
286 STM32_PLL_M_DIVISOR,
287 STM32_PLL_N_MULTIPLIER,
288 STM32_PLL_P_DIVISOR);
289 break;
290 case STM32_SRC_PLL1_Q:
291 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
292 STM32_PLL_M_DIVISOR,
293 STM32_PLL_N_MULTIPLIER,
294 STM32_PLL_Q_DIVISOR);
295 break;
296 case STM32_SRC_PLL1_R:
297 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL1_ID),
298 STM32_PLL_M_DIVISOR,
299 STM32_PLL_N_MULTIPLIER,
300 STM32_PLL_R_DIVISOR);
301 break;
302 #endif /* STM32_PLL_ENABLED */
303 #if defined(STM32_PLL2_ENABLED)
304 case STM32_SRC_PLL2_P:
305 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
306 STM32_PLL2_M_DIVISOR,
307 STM32_PLL2_N_MULTIPLIER,
308 STM32_PLL2_P_DIVISOR);
309 break;
310 case STM32_SRC_PLL2_Q:
311 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
312 STM32_PLL2_M_DIVISOR,
313 STM32_PLL2_N_MULTIPLIER,
314 STM32_PLL2_Q_DIVISOR);
315 break;
316 case STM32_SRC_PLL2_R:
317 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL2_ID),
318 STM32_PLL2_M_DIVISOR,
319 STM32_PLL2_N_MULTIPLIER,
320 STM32_PLL2_R_DIVISOR);
321 break;
322 #endif /* STM32_PLL2_ENABLED */
323 #if defined(STM32_PLL3_ENABLED)
324 case STM32_SRC_PLL3_P:
325 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
326 STM32_PLL3_M_DIVISOR,
327 STM32_PLL3_N_MULTIPLIER,
328 STM32_PLL3_P_DIVISOR);
329 break;
330 case STM32_SRC_PLL3_Q:
331 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
332 STM32_PLL3_M_DIVISOR,
333 STM32_PLL3_N_MULTIPLIER,
334 STM32_PLL3_Q_DIVISOR);
335 break;
336 case STM32_SRC_PLL3_R:
337 *rate = get_pllout_frequency(get_pllsrc_frequency(PLL3_ID),
338 STM32_PLL3_M_DIVISOR,
339 STM32_PLL3_N_MULTIPLIER,
340 STM32_PLL3_R_DIVISOR);
341 break;
342 #endif /* STM32_PLL3_ENABLED */
343 default:
344 return -ENOTSUP;
345 }
346
347 return 0;
348 }
349
350 static struct clock_control_driver_api stm32_clock_control_api = {
351 .on = stm32_clock_control_on,
352 .off = stm32_clock_control_off,
353 .get_rate = stm32_clock_control_get_subsys_rate,
354 .configure = stm32_clock_control_configure,
355 };
356
357 __unused
get_vco_input_range(uint32_t m_div,uint32_t * range,size_t pll_id)358 static int get_vco_input_range(uint32_t m_div, uint32_t *range, size_t pll_id)
359 {
360 uint32_t vco_freq;
361
362 vco_freq = get_pllsrc_frequency(pll_id) / m_div;
363
364 if (MHZ(4) <= vco_freq && vco_freq <= MHZ(8)) {
365 *range = LL_RCC_PLLINPUTRANGE_4_8;
366 } else if (MHZ(8) < vco_freq && vco_freq <= MHZ(16)) {
367 *range = LL_RCC_PLLINPUTRANGE_8_16;
368 } else {
369 return -ERANGE;
370 }
371
372 return 0;
373 }
374
set_regu_voltage(uint32_t hclk_freq)375 static void set_regu_voltage(uint32_t hclk_freq)
376 {
377 if (hclk_freq < MHZ(25)) {
378 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE4);
379 } else if (hclk_freq < MHZ(55)) {
380 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE3);
381 } else if (hclk_freq < MHZ(110)) {
382 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE2);
383 } else {
384 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
385 }
386 while (LL_PWR_IsActiveFlag_VOS() == 0) {
387 }
388 }
389
390 #if defined(STM32_PLL_ENABLED)
391 /*
392 * Dynamic voltage scaling:
393 * Enable the Booster mode before enabling then PLL for sysclock above 55MHz
394 * The goal of this function is to set the epod prescaler, so that epod clock freq
395 * is between 4MHz and 16MHz.
396 * Up to now only MSI as PLL1 source clock can be > 16MHz, requiring a epod prescaler > 1
397 * For HSI16, epod prescaler is default (div1, not divided).
398 * Once HSE is > 16MHz, the epod prescaler would also be also required.
399 */
set_epod_booster(void)400 static void set_epod_booster(void)
401 {
402 /* Reset Epod Prescaler in case it was set earlier with another DIV value */
403 LL_PWR_DisableEPODBooster();
404 while (LL_PWR_IsActiveFlag_BOOST() == 1) {
405 }
406
407 LL_RCC_SetPll1EPodPrescaler(LL_RCC_PLL1MBOOST_DIV_1);
408
409 if (MHZ(55) <= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
410 /*
411 * Set EPOD clock prescaler based on PLL1 input freq
412 * (MSI/PLLM or HSE/PLLM when HSE is > 16MHz
413 * Booster clock frequency should be between 4 and 16MHz
414 * This is done in following steps:
415 * Read MSI Frequency or HSE oscillaor freq
416 * Divide PLL1 input freq (MSI/PLL or HSE/PLLM)
417 * by the targeted freq (8MHz).
418 * Make sure value is not higher than 16
419 * Shift in the register space (/2)
420 */
421 int tmp;
422
423 if (IS_ENABLED(STM32_PLL_SRC_MSIS)) {
424 tmp = __LL_RCC_CALC_MSIS_FREQ(LL_RCC_MSIRANGESEL_RUN,
425 STM32_MSIS_RANGE << RCC_ICSCR1_MSISRANGE_Pos);
426 } else if (IS_ENABLED(STM32_PLL_SRC_HSE) && (MHZ(16) < STM32_HSE_FREQ)) {
427 tmp = STM32_HSE_FREQ;
428 } else {
429 return;
430 }
431
432 tmp = MIN(tmp / STM32_PLL_M_DIVISOR / 8000000, 16);
433 tmp = tmp / 2;
434
435 /* Configure the epod clock frequency between 4 and 16 MHz */
436 LL_RCC_SetPll1EPodPrescaler(tmp << RCC_PLL1CFGR_PLL1MBOOST_Pos);
437
438 /* Enable EPOD booster and wait for booster ready flag set */
439 LL_PWR_EnableEPODBooster();
440 while (LL_PWR_IsActiveFlag_BOOST() == 0) {
441 }
442 }
443 }
444 #endif /* STM32_PLL_ENABLED */
445
446 __unused
clock_switch_to_hsi(void)447 static void clock_switch_to_hsi(void)
448 {
449 /* Enable HSI if not enabled */
450 if (LL_RCC_HSI_IsReady() != 1) {
451 /* Enable HSI */
452 LL_RCC_HSI_Enable();
453 while (LL_RCC_HSI_IsReady() != 1) {
454 /* Wait for HSI ready */
455 }
456 }
457
458 /* Set HSI as SYSCLCK source */
459 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
460 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
461 }
462
463 LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
464 }
465
466 __unused
set_up_plls(void)467 static int set_up_plls(void)
468 {
469 #if defined(STM32_PLL_ENABLED) || defined(STM32_PLL2_ENABLED) || \
470 defined(STM32_PLL3_ENABLED)
471 int r;
472 uint32_t vco_input_range;
473 #endif
474
475 #if defined(STM32_PLL_ENABLED)
476 /*
477 * Switch to HSI and disable the PLL before configuration.
478 * (Switching to HSI makes sure we have a SYSCLK source in
479 * case we're currently running from the PLL we're about to
480 * turn off and reconfigure.)
481 */
482 if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
483 clock_switch_to_hsi();
484 }
485
486 LL_RCC_PLL1_Disable();
487
488 /* Configure PLL source : Can be HSE, HSI, MSIS */
489 if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
490 /* Main PLL configuration and activation */
491 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_HSE);
492 } else if (IS_ENABLED(STM32_PLL_SRC_MSIS)) {
493 /* Main PLL configuration and activation */
494 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_MSIS);
495 } else if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
496 /* Main PLL configuration and activation */
497 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_HSI);
498 } else {
499 return -ENOTSUP;
500 }
501
502 /*
503 * Configure the EPOD booster
504 * before increasing the system clock freq
505 * and after pll clock source is set
506 */
507 set_epod_booster();
508
509 r = get_vco_input_range(STM32_PLL_M_DIVISOR, &vco_input_range, PLL1_ID);
510 if (r < 0) {
511 return r;
512 }
513
514 LL_RCC_PLL1_SetDivider(STM32_PLL_M_DIVISOR);
515
516 /* Set VCO Input before enabling the PLL, depends on freq used for PLL1 */
517 LL_RCC_PLL1_SetVCOInputRange(vco_input_range);
518
519 LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER);
520
521 LL_RCC_PLL1FRACN_Disable();
522 if (IS_ENABLED(STM32_PLL_FRACN_ENABLED)) {
523 LL_RCC_PLL1_SetFRACN(STM32_PLL_FRACN_VALUE);
524 LL_RCC_PLL1FRACN_Enable();
525 }
526
527 if (IS_ENABLED(STM32_PLL_P_ENABLED)) {
528 LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR);
529 LL_RCC_PLL1_EnableDomain_SAI();
530 }
531
532 if (IS_ENABLED(STM32_PLL_Q_ENABLED)) {
533 LL_RCC_PLL1_SetQ(STM32_PLL_Q_DIVISOR);
534 LL_RCC_PLL1_EnableDomain_48M();
535 }
536
537 if (IS_ENABLED(STM32_PLL_R_ENABLED)) {
538 __ASSERT_NO_MSG((STM32_PLL_R_DIVISOR == 1) ||
539 (STM32_PLL_R_DIVISOR % 2 == 0));
540 LL_RCC_PLL1_SetR(STM32_PLL_R_DIVISOR);
541 LL_RCC_PLL1_EnableDomain_SYS();
542 }
543
544 LL_RCC_PLL1_Enable();
545 while (LL_RCC_PLL1_IsReady() != 1U) {
546 }
547 #else
548 /* Init PLL source to None */
549 LL_RCC_PLL1_SetMainSource(LL_RCC_PLL1SOURCE_NONE);
550 #endif /* STM32_PLL_ENABLED */
551
552 #if defined(STM32_PLL2_ENABLED)
553 /* Configure PLL2 source */
554 if (IS_ENABLED(STM32_PLL2_SRC_HSE)) {
555 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_HSE);
556 } else if (IS_ENABLED(STM32_PLL2_SRC_MSIS)) {
557 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_MSIS);
558 } else if (IS_ENABLED(STM32_PLL2_SRC_HSI)) {
559 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_HSI);
560 } else {
561 return -ENOTSUP;
562 }
563
564 r = get_vco_input_range(STM32_PLL2_M_DIVISOR, &vco_input_range, PLL2_ID);
565 if (r < 0) {
566 return r;
567 }
568
569 LL_RCC_PLL2_SetDivider(STM32_PLL2_M_DIVISOR);
570
571 LL_RCC_PLL2_SetVCOInputRange(vco_input_range);
572
573 LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER);
574
575 LL_RCC_PLL2FRACN_Disable();
576 if (IS_ENABLED(STM32_PLL2_FRACN_ENABLED)) {
577 LL_RCC_PLL2_SetFRACN(STM32_PLL2_FRACN_VALUE);
578 LL_RCC_PLL2FRACN_Enable();
579 }
580
581 if (IS_ENABLED(STM32_PLL2_P_ENABLED)) {
582 LL_RCC_PLL2_SetP(STM32_PLL2_P_DIVISOR);
583 SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2PEN);
584 }
585
586 if (IS_ENABLED(STM32_PLL2_Q_ENABLED)) {
587 LL_RCC_PLL2_SetQ(STM32_PLL2_Q_DIVISOR);
588 SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2QEN);
589 }
590
591 if (IS_ENABLED(STM32_PLL2_R_ENABLED)) {
592 LL_RCC_PLL2_SetR(STM32_PLL2_R_DIVISOR);
593 SET_BIT(RCC->PLL2CFGR, RCC_PLL2CFGR_PLL2REN);
594 }
595
596 LL_RCC_PLL2_Enable();
597 while (LL_RCC_PLL2_IsReady() != 1U) {
598 }
599 #else
600 /* Init PLL2 source to None */
601 LL_RCC_PLL2_SetSource(LL_RCC_PLL2SOURCE_NONE);
602 #endif /* STM32_PLL2_ENABLED */
603
604 #if defined(STM32_PLL3_ENABLED)
605 /* Configure PLL3 source */
606 if (IS_ENABLED(STM32_PLL3_SRC_HSE)) {
607 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_HSE);
608 } else if (IS_ENABLED(STM32_PLL3_SRC_MSIS)) {
609 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_MSIS);
610 } else if (IS_ENABLED(STM32_PLL3_SRC_HSI)) {
611 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_HSI);
612 } else {
613 return -ENOTSUP;
614 }
615
616 r = get_vco_input_range(STM32_PLL3_M_DIVISOR, &vco_input_range, PLL3_ID);
617 if (r < 0) {
618 return r;
619 }
620
621 LL_RCC_PLL3_SetDivider(STM32_PLL3_M_DIVISOR);
622
623 LL_RCC_PLL3_SetVCOInputRange(vco_input_range);
624
625 LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER);
626
627 LL_RCC_PLL3FRACN_Disable();
628 if (IS_ENABLED(STM32_PLL3_FRACN_ENABLED)) {
629 LL_RCC_PLL3_SetFRACN(STM32_PLL3_FRACN_VALUE);
630 LL_RCC_PLL3FRACN_Enable();
631 }
632
633 if (IS_ENABLED(STM32_PLL3_P_ENABLED)) {
634 LL_RCC_PLL3_SetP(STM32_PLL3_P_DIVISOR);
635 SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3PEN);
636 }
637
638 if (IS_ENABLED(STM32_PLL3_Q_ENABLED)) {
639 LL_RCC_PLL3_SetQ(STM32_PLL3_Q_DIVISOR);
640 SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3QEN);
641 }
642
643 if (IS_ENABLED(STM32_PLL3_R_ENABLED)) {
644 LL_RCC_PLL3_SetR(STM32_PLL3_R_DIVISOR);
645 SET_BIT(RCC->PLL3CFGR, RCC_PLL3CFGR_PLL3REN);
646 }
647
648 LL_RCC_PLL3_Enable();
649 while (LL_RCC_PLL3_IsReady() != 1U) {
650 }
651 #else
652 /* Init PLL3 source to None */
653 LL_RCC_PLL3_SetSource(LL_RCC_PLL3SOURCE_NONE);
654 #endif /* STM32_PLL3_ENABLED */
655
656 return 0;
657 }
658
set_up_fixed_clock_sources(void)659 static void set_up_fixed_clock_sources(void)
660 {
661
662 if (IS_ENABLED(STM32_HSE_ENABLED)) {
663 /* Check if need to enable HSE bypass feature or not */
664 if (IS_ENABLED(STM32_HSE_BYPASS)) {
665 LL_RCC_HSE_EnableBypass();
666 } else {
667 LL_RCC_HSE_DisableBypass();
668 }
669
670 /* Enable HSE */
671 LL_RCC_HSE_Enable();
672 while (LL_RCC_HSE_IsReady() != 1) {
673 /* Wait for HSE ready */
674 }
675 }
676
677 if (IS_ENABLED(STM32_HSI_ENABLED)) {
678 /* Enable HSI if not enabled */
679 if (LL_RCC_HSI_IsReady() != 1) {
680 /* Enable HSI */
681 LL_RCC_HSI_Enable();
682 while (LL_RCC_HSI_IsReady() != 1) {
683 /* Wait for HSI ready */
684 }
685 }
686 }
687
688 if (IS_ENABLED(STM32_LSE_ENABLED)) {
689 /* Enable the power interface clock */
690 LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PWR);
691
692 if (!LL_PWR_IsEnabledBkUpAccess()) {
693 /* Enable write access to Backup domain */
694 LL_PWR_EnableBkUpAccess();
695 while (!LL_PWR_IsEnabledBkUpAccess()) {
696 /* Wait for Backup domain access */
697 }
698 }
699
700 /* Configure driving capability */
701 LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos);
702
703 if (IS_ENABLED(STM32_LSE_BYPASS)) {
704 /* Configure LSE bypass */
705 LL_RCC_LSE_EnableBypass();
706 }
707
708 /* Enable LSE Oscillator */
709 LL_RCC_LSE_Enable();
710 /* Wait for LSE ready */
711 while (!LL_RCC_LSE_IsReady()) {
712 }
713
714 /* Enable LSESYS additionnally */
715 LL_RCC_LSE_EnablePropagation();
716 /* Wait till LSESYS is ready */
717 while (!LL_RCC_LSESYS_IsReady()) {
718 }
719
720 LL_PWR_DisableBkUpAccess();
721 }
722
723 if (IS_ENABLED(STM32_MSIS_ENABLED)) {
724 /* Set MSIS Range */
725 LL_RCC_MSI_EnableRangeSelection();
726
727 LL_RCC_MSIS_SetRange(STM32_MSIS_RANGE << RCC_ICSCR1_MSISRANGE_Pos);
728
729 if (IS_ENABLED(STM32_MSIS_PLL_MODE)) {
730 __ASSERT(STM32_LSE_ENABLED,
731 "MSIS Hardware auto calibration needs LSE clock activation");
732 /* Enable MSI hardware auto calibration */
733 LL_RCC_SetMSIPLLMode(LL_RCC_PLLMODE_MSIS);
734 LL_RCC_MSI_EnablePLLMode();
735 }
736
737 /* Enable MSIS */
738 LL_RCC_MSIS_Enable();
739
740 /* Wait till MSIS is ready */
741 while (LL_RCC_MSIS_IsReady() != 1) {
742 }
743 }
744
745 if (IS_ENABLED(STM32_MSIK_ENABLED)) {
746 /* Set MSIK Range */
747 LL_RCC_MSI_EnableRangeSelection();
748
749 LL_RCC_MSIK_SetRange(STM32_MSIK_RANGE << RCC_ICSCR1_MSIKRANGE_Pos);
750
751 if (IS_ENABLED(STM32_MSIK_PLL_MODE)) {
752 __ASSERT(STM32_LSE_ENABLED,
753 "MSIK Hardware auto calibration needs LSE clock activation");
754 /* Enable MSI hardware auto calibration */
755 LL_RCC_SetMSIPLLMode(LL_RCC_PLLMODE_MSIK);
756 LL_RCC_MSI_EnablePLLMode();
757 }
758
759 if (IS_ENABLED(STM32_MSIS_ENABLED)) {
760 __ASSERT((STM32_MSIK_PLL_MODE == STM32_MSIS_PLL_MODE),
761 "Please check MSIS/MSIK config consistency");
762 }
763
764 /* Enable MSIK */
765 LL_RCC_MSIK_Enable();
766
767 /* Wait till MSIK is ready */
768 while (LL_RCC_MSIK_IsReady() != 1) {
769 }
770 }
771
772 if (IS_ENABLED(STM32_LSI_ENABLED)) {
773 if (!LL_AHB3_GRP1_IsEnabledClock(LL_AHB3_GRP1_PERIPH_PWR)) {
774 /* Enable the power interface clock */
775 LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PWR);
776 }
777
778 if (!LL_PWR_IsEnabledBkUpAccess()) {
779 /* Enable write access to Backup domain */
780 LL_PWR_EnableBkUpAccess();
781 while (!LL_PWR_IsEnabledBkUpAccess()) {
782 /* Wait for Backup domain access */
783 }
784 }
785
786 /* Enable LSI oscillator */
787 LL_RCC_LSI_Enable();
788 while (LL_RCC_LSI_IsReady() != 1) {
789 }
790
791 LL_PWR_DisableBkUpAccess();
792 }
793
794 if (IS_ENABLED(STM32_HSI48_ENABLED)) {
795 LL_RCC_HSI48_Enable();
796 while (LL_RCC_HSI48_IsReady() != 1) {
797 }
798 }
799 }
800
stm32_clock_control_init(const struct device * dev)801 int stm32_clock_control_init(const struct device *dev)
802 {
803 uint32_t old_hclk_freq = 0;
804 int r = 0;
805
806 ARG_UNUSED(dev);
807
808 /* Current hclk value */
809 old_hclk_freq = __LL_RCC_CALC_HCLK_FREQ(get_startup_frequency(), LL_RCC_GetAHBPrescaler());
810
811 /* Set voltage regulator to comply with targeted system frequency */
812 set_regu_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
813
814 /* Set flash latency */
815 /* If freq increases, set flash latency before any clock setting */
816 if (old_hclk_freq < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
817 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
818 }
819
820 /* Set up individual enabled clocks */
821 set_up_fixed_clock_sources();
822
823 /* Set up PLLs */
824 r = set_up_plls();
825 if (r < 0) {
826 return r;
827 }
828
829 /* Set peripheral busses prescalers */
830 LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_AHB_PRESCALER));
831 LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
832 LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
833 LL_RCC_SetAPB3Prescaler(apb3_prescaler(STM32_APB3_PRESCALER));
834
835 if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
836 /* Set PLL1 as System Clock Source */
837 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
838 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
839 }
840 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) {
841 /* Set HSE as SYSCLCK source */
842 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
843 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
844 }
845 } else if (IS_ENABLED(STM32_SYSCLK_SRC_MSIS)) {
846 /* Set MSIS as SYSCLCK source */
847 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSIS);
848 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSIS) {
849 }
850 } else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) {
851 /* Set HSI as SYSCLCK source */
852 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
853 while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
854 }
855 } else {
856 return -ENOTSUP;
857 }
858
859 /* Set FLASH latency */
860 /* If freq not increased, set flash latency after all clock setting */
861 if (old_hclk_freq >= CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC) {
862 LL_SetFlashLatency(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
863 }
864
865 /* Update CMSIS variable */
866 SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
867
868 return 0;
869 }
870
871 /**
872 * @brief RCC device, note that priority is intentionally set to 1 so
873 * that the device init runs just after SOC init
874 */
875 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
876 &stm32_clock_control_init,
877 NULL,
878 NULL, NULL,
879 PRE_KERNEL_1,
880 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
881 &stm32_clock_control_api);
882