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