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