1 /*
2  * Copyright (c) 2017-2022 Linaro Limited.
3  * Copyright (c) 2017 RnDity Sp. z o.o.
4  *
5  * SPDX-License-Identifier: Apache-2.0
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_system.h>
13 #include <stm32_ll_utils.h>
14 #include <zephyr/arch/cpu.h>
15 #include <zephyr/drivers/clock_control.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/sys/__assert.h>
18 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
19 #include "clock_stm32_ll_common.h"
20 #include "stm32_hsem.h"
21 
22 /* Macros to fill up prescaler values */
23 #define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v
24 #define hsi_divider(v) z_hsi_divider(v)
25 
26 #if defined(LL_RCC_HCLK_DIV_1)
27 #define fn_ahb_prescaler(v) LL_RCC_HCLK_DIV_ ## v
28 #define ahb_prescaler(v) fn_ahb_prescaler(v)
29 #else
30 #define fn_ahb_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
31 #define ahb_prescaler(v) fn_ahb_prescaler(v)
32 #endif
33 
34 #define fn_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
35 #define apb1_prescaler(v) fn_apb1_prescaler(v)
36 
37 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
38 #define fn_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
39 #define apb2_prescaler(v) fn_apb2_prescaler(v)
40 #endif
41 
42 #if defined(RCC_CFGR_ADCPRE)
43 #define z_adc12_prescaler(v) LL_RCC_ADC_CLKSRC_PCLK2_DIV_ ## v
44 #define adc12_prescaler(v) z_adc12_prescaler(v)
45 #elif defined(RCC_CFGR2_ADC1PRES)
46 #define z_adc12_prescaler(v) \
47 	COND_CODE_1(IS_EQ(v, 0), \
48 		    LL_RCC_ADC1_CLKSRC_HCLK, \
49 		    LL_RCC_ADC1_CLKSRC_PLL_DIV_ ## v)
50 #define adc12_prescaler(v) z_adc12_prescaler(v)
51 #else
52 #define z_adc12_prescaler(v) \
53 	COND_CODE_1(IS_EQ(v, 0), \
54 		    (LL_RCC_ADC12_CLKSRC_HCLK), \
55 		    (LL_RCC_ADC12_CLKSRC_PLL_DIV_ ## v))
56 #define adc12_prescaler(v) z_adc12_prescaler(v)
57 #define z_adc34_prescaler(v) \
58 	COND_CODE_1(IS_EQ(v, 0), \
59 		    (LL_RCC_ADC34_CLKSRC_HCLK), \
60 		    (LL_RCC_ADC34_CLKSRC_PLL_DIV_ ## v))
61 #define adc34_prescaler(v) z_adc34_prescaler(v)
62 #endif
63 
64 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
65 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK4_FREQ
66 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB4Prescaler
67 #elif DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
68 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK3_FREQ
69 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHB3Prescaler
70 #else
71 #define RCC_CALC_FLASH_FREQ __LL_RCC_CALC_HCLK_FREQ
72 #define GET_CURRENT_FLASH_PRESCALER LL_RCC_GetAHBPrescaler
73 #endif
74 
75 #if defined(RCC_PLLCFGR_PLLPEN)
76 #define RCC_PLLP_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPEN)
77 #else
78 #define RCC_PLLP_ENABLE()
79 #endif /* RCC_PLLCFGR_PLLPEN */
80 #if defined(RCC_PLLCFGR_PLLQEN)
81 #define RCC_PLLQ_ENABLE() SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN)
82 #else
83 #define RCC_PLLQ_ENABLE()
84 #endif /* RCC_PLLCFGR_PLLQEN */
85 
86 /**
87  * @brief Return frequency for pll with 2 dividers and a multiplier
88  */
89 __unused
get_pll_div_frequency(uint32_t pllsrc_freq,int pllm_div,int plln_mul,int pllout_div)90 static uint32_t get_pll_div_frequency(uint32_t pllsrc_freq,
91 				      int pllm_div,
92 				      int plln_mul,
93 				      int pllout_div)
94 {
95 	__ASSERT_NO_MSG(pllm_div && pllout_div);
96 
97 	return pllsrc_freq / pllm_div * plln_mul / pllout_div;
98 }
99 
get_bus_clock(uint32_t clock,uint32_t prescaler)100 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
101 {
102 	return clock / prescaler;
103 }
104 
105 __unused
get_msi_frequency(void)106 static uint32_t get_msi_frequency(void)
107 {
108 #if defined(STM32_MSI_ENABLED)
109 #if !defined(LL_RCC_MSIRANGESEL_RUN)
110 	return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSI_GetRange());
111 #else
112 	return __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN,
113 				      LL_RCC_MSI_GetRange());
114 #endif
115 #endif
116 	return 0;
117 }
118 
119 /** @brief Verifies clock is part of active clock configuration */
enabled_clock(uint32_t src_clk)120 int enabled_clock(uint32_t src_clk)
121 {
122 	int r = 0;
123 
124 	switch (src_clk) {
125 	case STM32_SRC_SYSCLK:
126 		break;
127 #if defined(STM32_SRC_PCLK)
128 	case STM32_SRC_PCLK:
129 		break;
130 #endif /* STM32_SRC_PCLK */
131 #if defined(STM32_SRC_HSE)
132 	case STM32_SRC_HSE:
133 		if (!IS_ENABLED(STM32_HSE_ENABLED)) {
134 			r = -ENOTSUP;
135 		}
136 		break;
137 #endif /* STM32_SRC_HSE */
138 #if defined(STM32_SRC_EXT_HSE)
139 	case STM32_SRC_EXT_HSE:
140 		/* EXT_HSE is the raw OSC_IN signal, so it is always
141 		 * available, regardless of the clocks configuration.
142 		 */
143 		break;
144 #endif /* STM32_SRC_HSE */
145 #if defined(STM32_SRC_HSI)
146 	case STM32_SRC_HSI:
147 		if (!IS_ENABLED(STM32_HSI_ENABLED)) {
148 			r = -ENOTSUP;
149 		}
150 		break;
151 #endif /* STM32_SRC_HSI */
152 #if defined(STM32_SRC_LSE)
153 	case STM32_SRC_LSE:
154 		if (!IS_ENABLED(STM32_LSE_ENABLED)) {
155 			r = -ENOTSUP;
156 		}
157 		break;
158 #endif /* STM32_SRC_LSE */
159 #if defined(STM32_SRC_LSI)
160 	case STM32_SRC_LSI:
161 		if (!IS_ENABLED(STM32_LSI_ENABLED)) {
162 			r = -ENOTSUP;
163 		}
164 		break;
165 #endif /* STM32_SRC_LSI */
166 #if defined(STM32_SRC_HSI14)
167 	case STM32_SRC_HSI14:
168 		if (!IS_ENABLED(STM32_HSI14_ENABLED)) {
169 			r = -ENOTSUP;
170 		}
171 		break;
172 #endif /* STM32_SRC_HSI14 */
173 #if defined(STM32_SRC_HSI48)
174 	case STM32_SRC_HSI48:
175 		if (!IS_ENABLED(STM32_HSI48_ENABLED)) {
176 			r = -ENOTSUP;
177 		}
178 		break;
179 #endif /* STM32_SRC_HSI48 */
180 #if defined(STM32_SRC_MSI)
181 	case STM32_SRC_MSI:
182 		if (!IS_ENABLED(STM32_MSI_ENABLED)) {
183 			r = -ENOTSUP;
184 		}
185 		break;
186 #endif /* STM32_SRC_MSI */
187 #if defined(STM32_SRC_PLLCLK)
188 	case STM32_SRC_PLLCLK:
189 		if (!IS_ENABLED(STM32_PLL_ENABLED)) {
190 			r = -ENOTSUP;
191 		}
192 		break;
193 #endif /* STM32_SRC_PLLCLK */
194 #if defined(STM32_SRC_PLL_P)
195 	case STM32_SRC_PLL_P:
196 		if (!IS_ENABLED(STM32_PLL_P_ENABLED)) {
197 			r = -ENOTSUP;
198 		}
199 		break;
200 #endif /* STM32_SRC_PLL_P */
201 #if defined(STM32_SRC_PLL_Q)
202 	case STM32_SRC_PLL_Q:
203 		if (!IS_ENABLED(STM32_PLL_Q_ENABLED)) {
204 			r = -ENOTSUP;
205 		}
206 		break;
207 #endif /* STM32_SRC_PLL_Q */
208 #if defined(STM32_SRC_PLL_R)
209 	case STM32_SRC_PLL_R:
210 		if (!IS_ENABLED(STM32_PLL_R_ENABLED)) {
211 			r = -ENOTSUP;
212 		}
213 		break;
214 #endif /* STM32_SRC_PLL_R */
215 #if defined(STM32_SRC_PLLI2S_Q)
216 	case STM32_SRC_PLLI2S_Q:
217 		if (!IS_ENABLED(STM32_PLLI2S_Q_ENABLED)) {
218 			r = -ENOTSUP;
219 		}
220 		break;
221 #endif /* STM32_SRC_PLLI2S_Q */
222 #if defined(STM32_SRC_PLLI2S_R)
223 	case STM32_SRC_PLLI2S_R:
224 		if (!IS_ENABLED(STM32_PLLI2S_R_ENABLED)) {
225 			r = -ENOTSUP;
226 		}
227 		break;
228 #endif /* STM32_SRC_PLLI2S_R */
229 #if defined(STM32_SRC_PLL2CLK)
230 	case STM32_SRC_PLL2CLK:
231 		if (!IS_ENABLED(STM32_PLL2_ENABLED)) {
232 			r = -ENOTSUP;
233 		}
234 		break;
235 #endif
236 #if defined(STM32_SRC_PLL3CLK)
237 	case STM32_SRC_PLL3CLK:
238 		if (!IS_ENABLED(STM32_PLL3_ENABLED)) {
239 			r = -ENOTSUP;
240 		}
241 		break;
242 #endif
243 	default:
244 		return -ENOTSUP;
245 	}
246 
247 	return r;
248 }
249 
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)250 static inline int stm32_clock_control_on(const struct device *dev,
251 					 clock_control_subsys_t sub_system)
252 {
253 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
254 	volatile int temp;
255 
256 	ARG_UNUSED(dev);
257 
258 	if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
259 		/* Attempt to change a wrong periph clock bit */
260 		return -ENOTSUP;
261 	}
262 
263 	sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
264 		     pclken->enr);
265 	/* Delay after enabling the clock, to allow it to become active.
266 	 * See (for example) RM0440 7.2.17
267 	 */
268 	temp = sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus);
269 	UNUSED(temp);
270 
271 	return 0;
272 }
273 
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)274 static inline int stm32_clock_control_off(const struct device *dev,
275 					  clock_control_subsys_t sub_system)
276 {
277 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
278 
279 	ARG_UNUSED(dev);
280 
281 	if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
282 		/* Attempt to toggle a wrong periph clock bit */
283 		return -ENOTSUP;
284 	}
285 
286 	sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus,
287 		       pclken->enr);
288 
289 	return 0;
290 }
291 
stm32_clock_control_configure(const struct device * dev,clock_control_subsys_t sub_system,void * data)292 static inline int stm32_clock_control_configure(const struct device *dev,
293 						clock_control_subsys_t sub_system,
294 						void *data)
295 {
296 	/* At least one alt src clock available */
297 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
298 	int err;
299 
300 	ARG_UNUSED(dev);
301 	ARG_UNUSED(data);
302 
303 	err = enabled_clock(pclken->bus);
304 	if (err < 0) {
305 		/* Attempt to configure a src clock not available or not valid */
306 		return err;
307 	}
308 
309 	if (pclken->enr == NO_SEL) {
310 		/* Domain clock is fixed. Nothing to set. Exit */
311 		return 0;
312 	}
313 
314 	sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
315 		       STM32_DT_CLKSEL_MASK_GET(pclken->enr) <<
316 			STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
317 	sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
318 		     STM32_DT_CLKSEL_VAL_GET(pclken->enr) <<
319 			STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
320 
321 	return 0;
322 }
323 
stm32_clock_control_get_subsys_rate(const struct device * clock,clock_control_subsys_t sub_system,uint32_t * rate)324 static int stm32_clock_control_get_subsys_rate(const struct device *clock,
325 						clock_control_subsys_t sub_system,
326 						uint32_t *rate)
327 {
328 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
329 	/*
330 	 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
331 	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
332 	 * since it will be updated after clock configuration and hence
333 	 * more likely to contain actual clock speed
334 	 */
335 	uint32_t ahb_clock = SystemCoreClock;
336 	uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_APB1_PRESCALER);
337 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
338 	uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_APB2_PRESCALER);
339 #elif defined(STM32_CLOCK_BUS_APB2)
340 	/* APB2 bus exists, but w/o dedicated prescaler */
341 	uint32_t apb2_clock = apb1_clock;
342 #endif
343 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
344 	uint32_t ahb3_clock = get_bus_clock(ahb_clock * STM32_CPU1_PRESCALER,
345 					    STM32_AHB3_PRESCALER);
346 #elif defined(STM32_CLOCK_BUS_AHB3)
347 	/* AHB3 bus exists, but w/o dedicated prescaler */
348 	uint32_t ahb3_clock = ahb_clock;
349 #endif
350 
351 #if defined(STM32_SRC_PCLK)
352 	if (pclken->bus == STM32_SRC_PCLK) {
353 		/* STM32_SRC_PCLK can't be used to request a subsys freq */
354 		/* Use STM32_CLOCK_BUS_FOO instead. */
355 		return -ENOTSUP;
356 	}
357 #endif
358 
359 	ARG_UNUSED(clock);
360 
361 	switch (pclken->bus) {
362 	case STM32_CLOCK_BUS_AHB1:
363 #if defined(STM32_CLOCK_BUS_AHB2)
364 	case STM32_CLOCK_BUS_AHB2:
365 #endif
366 #if defined(STM32_CLOCK_BUS_IOP)
367 	case STM32_CLOCK_BUS_IOP:
368 #endif
369 		*rate = ahb_clock;
370 		break;
371 #if defined(STM32_CLOCK_BUS_AHB3)
372 	case STM32_CLOCK_BUS_AHB3:
373 		*rate = ahb3_clock;
374 		break;
375 #endif
376 	case STM32_CLOCK_BUS_APB1:
377 #if defined(STM32_CLOCK_BUS_APB1_2)
378 	case STM32_CLOCK_BUS_APB1_2:
379 #endif
380 		*rate = apb1_clock;
381 		break;
382 #if defined(STM32_CLOCK_BUS_APB2)
383 	case STM32_CLOCK_BUS_APB2:
384 		*rate = apb2_clock;
385 		break;
386 #endif
387 #if defined(STM32_CLOCK_BUS_APB3)
388 	case STM32_CLOCK_BUS_APB3:
389 		/* STM32WL: AHB3 and APB3 share the same clock and prescaler. */
390 		*rate = ahb3_clock;
391 		break;
392 #endif
393 	case STM32_SRC_SYSCLK:
394 		*rate = SystemCoreClock * STM32_CORE_PRESCALER;
395 		break;
396 #if defined(STM32_SRC_PLLCLK) & defined(STM32_SYSCLK_SRC_PLL)
397 	case STM32_SRC_PLLCLK:
398 		if (get_pllout_frequency() == 0) {
399 			return -EIO;
400 		}
401 		*rate = get_pllout_frequency();
402 		break;
403 #endif
404 #if defined(STM32_SRC_PLL_P) & STM32_PLL_P_ENABLED
405 	case STM32_SRC_PLL_P:
406 		*rate = get_pll_div_frequency(get_pllsrc_frequency(),
407 					      STM32_PLL_M_DIVISOR,
408 					      STM32_PLL_N_MULTIPLIER,
409 					      STM32_PLL_P_DIVISOR);
410 		break;
411 #endif
412 #if defined(STM32_SRC_PLL_Q) & STM32_PLL_Q_ENABLED
413 	case STM32_SRC_PLL_Q:
414 		*rate = get_pll_div_frequency(get_pllsrc_frequency(),
415 					      STM32_PLL_M_DIVISOR,
416 					      STM32_PLL_N_MULTIPLIER,
417 					      STM32_PLL_Q_DIVISOR);
418 		break;
419 #endif
420 #if defined(STM32_SRC_PLL_R) & STM32_PLL_R_ENABLED
421 	case STM32_SRC_PLL_R:
422 		*rate = get_pll_div_frequency(get_pllsrc_frequency(),
423 					      STM32_PLL_M_DIVISOR,
424 					      STM32_PLL_N_MULTIPLIER,
425 					      STM32_PLL_R_DIVISOR);
426 		break;
427 #endif
428 #if defined(STM32_SRC_PLLI2S_Q) & STM32_PLLI2S_Q_ENABLED & STM32_PLLI2S_ENABLED
429 	case STM32_SRC_PLLI2S_Q:
430 		*rate = get_pll_div_frequency(get_pllsrc_frequency(),
431 					      STM32_PLLI2S_M_DIVISOR,
432 					      STM32_PLLI2S_N_MULTIPLIER,
433 					      STM32_PLLI2S_Q_DIVISOR);
434 		break;
435 #endif /* STM32_SRC_PLLI2S_Q */
436 #if defined(STM32_SRC_PLLI2S_R) & STM32_PLLI2S_ENABLED
437 	case STM32_SRC_PLLI2S_R:
438 		*rate = get_pll_div_frequency(get_pllsrc_frequency(),
439 					      STM32_PLLI2S_M_DIVISOR,
440 					      STM32_PLLI2S_N_MULTIPLIER,
441 					      STM32_PLLI2S_R_DIVISOR);
442 		break;
443 #endif /* STM32_SRC_PLLI2S_R */
444 
445 /* PLLSAI1x not supported yet */
446 /* PLLSAI2x not supported yet */
447 #if defined(STM32_SRC_LSE)
448 	case STM32_SRC_LSE:
449 		*rate = STM32_LSE_FREQ;
450 		break;
451 #endif
452 #if defined(STM32_SRC_LSI)
453 	case STM32_SRC_LSI:
454 		*rate = STM32_LSI_FREQ;
455 		break;
456 #endif
457 #if defined(STM32_SRC_HSI)
458 	case STM32_SRC_HSI:
459 		*rate = STM32_HSI_FREQ;
460 		break;
461 #endif
462 #if defined(STM32_SRC_MSI)
463 	case STM32_SRC_MSI:
464 		*rate = get_msi_frequency();
465 		break;
466 #endif
467 #if defined(STM32_SRC_HSE)
468 	case STM32_SRC_HSE:
469 		*rate = STM32_HSE_FREQ;
470 		break;
471 #endif
472 #if defined(STM32_HSI48_ENABLED)
473 	case STM32_SRC_HSI48:
474 		*rate = STM32_HSI48_FREQ;
475 		break;
476 #endif /* STM32_HSI48_ENABLED */
477 #if defined(STM32_CK48_ENABLED)
478 	case STM32_SRC_CK48:
479 		*rate = get_ck48_frequency();
480 		break;
481 #endif /* STM32_CK48_ENABLED */
482 
483 	default:
484 		return -ENOTSUP;
485 	}
486 
487 	if (pclken->div) {
488 		*rate /= (pclken->div + 1);
489 	}
490 
491 	return 0;
492 }
493 
stm32_clock_control_get_status(const struct device * dev,clock_control_subsys_t sub_system)494 static enum clock_control_status stm32_clock_control_get_status(const struct device *dev,
495 								clock_control_subsys_t sub_system)
496 {
497 	struct stm32_pclken *pclken = (struct stm32_pclken *)sub_system;
498 
499 	ARG_UNUSED(dev);
500 
501 	if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == true) {
502 		/* Gated clocks */
503 		if ((sys_read32(DT_REG_ADDR(DT_NODELABEL(rcc)) + pclken->bus) & pclken->enr)
504 		    == pclken->enr) {
505 			return CLOCK_CONTROL_STATUS_ON;
506 		} else {
507 			return CLOCK_CONTROL_STATUS_OFF;
508 		}
509 	} else {
510 		/* Domain clock sources */
511 		if (enabled_clock(pclken->bus) == 0) {
512 			return CLOCK_CONTROL_STATUS_ON;
513 		} else {
514 			return CLOCK_CONTROL_STATUS_OFF;
515 		}
516 	}
517 }
518 
519 static DEVICE_API(clock_control, stm32_clock_control_api) = {
520 	.on = stm32_clock_control_on,
521 	.off = stm32_clock_control_off,
522 	.get_rate = stm32_clock_control_get_subsys_rate,
523 	.get_status = stm32_clock_control_get_status,
524 	.configure = stm32_clock_control_configure,
525 };
526 
527 /*
528  * Unconditionally switch the system clock source to HSI.
529  */
530 __unused
stm32_clock_switch_to_hsi(void)531 static void stm32_clock_switch_to_hsi(void)
532 {
533 	/* Enable HSI if not enabled */
534 	if (LL_RCC_HSI_IsReady() != 1) {
535 		/* Enable HSI */
536 		LL_RCC_HSI_Enable();
537 		while (LL_RCC_HSI_IsReady() != 1) {
538 		/* Wait for HSI ready */
539 		}
540 	}
541 
542 	/* Set HSI as SYSCLCK source */
543 	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
544 	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
545 	}
546 }
547 
548 __unused
set_up_plls(void)549 static void set_up_plls(void)
550 {
551 #if defined(STM32_PLL_ENABLED)
552 
553 	/*
554 	 * Case of chain-loaded applications:
555 	 * Switch to HSI and disable the PLL before configuration.
556 	 * (Switching to HSI makes sure we have a SYSCLK source in
557 	 * case we're currently running from the PLL we're about to
558 	 * turn off and reconfigure.)
559 	 *
560 	 */
561 	if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
562 		stm32_clock_switch_to_hsi();
563 		LL_RCC_SetAHBPrescaler(ahb_prescaler(1));
564 	}
565 	/* Disable PLL */
566 	LL_RCC_PLL_Disable();
567 	while (LL_RCC_PLL_IsReady() != 0U) {
568 		/* Wait for PLL to be disabled */
569 	}
570 
571 #endif
572 
573 #if defined(STM32_PLL2_ENABLED)
574 	/*
575 	 * Disable PLL2 after switching to HSI for SysClk
576 	 * and disabling PLL, but before enabling PLL again,
577 	 * since PLL source can be PLL2.
578 	 */
579 	LL_RCC_PLL2_Disable();
580 	while (LL_RCC_PLL2_IsReady() != 0U) {
581 		/* Wait for PLL2 to be disabled */
582 	}
583 
584 	config_pll2();
585 
586 	/* Enable PLL2 */
587 	LL_RCC_PLL2_Enable();
588 	while (LL_RCC_PLL2_IsReady() != 1U) {
589 	/* Wait for PLL2 ready */
590 	}
591 #endif /* STM32_PLL2_ENABLED */
592 
593 #if defined(STM32_PLL_ENABLED)
594 
595 #if defined(STM32_SRC_PLL_P) & STM32_PLL_P_ENABLED
596 	MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLP, pllp(STM32_PLL_P_DIVISOR));
597 	RCC_PLLP_ENABLE();
598 #endif
599 #if defined(STM32_SRC_PLL_Q) & STM32_PLL_Q_ENABLED
600 	MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ, pllq(STM32_PLL_Q_DIVISOR));
601 	RCC_PLLQ_ENABLE();
602 #endif
603 
604 	config_pll_sysclock();
605 
606 	/* Enable PLL */
607 	LL_RCC_PLL_Enable();
608 	while (LL_RCC_PLL_IsReady() != 1U) {
609 	/* Wait for PLL ready */
610 	}
611 
612 #endif /* STM32_PLL_ENABLED */
613 
614 #if defined(STM32_PLLI2S_ENABLED)
615 	config_plli2s();
616 
617 	/* Enable PLL */
618 	LL_RCC_PLLI2S_Enable();
619 	while (LL_RCC_PLLI2S_IsReady() != 1U) {
620 		/* Wait for PLL ready */
621 	}
622 #endif /* STM32_PLLI2S_ENABLED */
623 }
624 
set_up_fixed_clock_sources(void)625 static void set_up_fixed_clock_sources(void)
626 {
627 
628 	if (IS_ENABLED(STM32_HSE_ENABLED)) {
629 #if defined(STM32_HSE_BYPASS)
630 		/* Check if need to enable HSE bypass feature or not */
631 		if (IS_ENABLED(STM32_HSE_BYPASS)) {
632 			LL_RCC_HSE_EnableBypass();
633 		} else {
634 			LL_RCC_HSE_DisableBypass();
635 		}
636 #endif
637 #if STM32_HSE_TCXO
638 		LL_RCC_HSE_EnableTcxo();
639 #endif
640 #if STM32_HSE_DIV2
641 		LL_RCC_HSE_EnableDiv2();
642 #endif
643 		/* Enable HSE */
644 		LL_RCC_HSE_Enable();
645 		while (LL_RCC_HSE_IsReady() != 1) {
646 		/* Wait for HSE ready */
647 		}
648 		/* Check if we need to enable HSE clock security system or not */
649 #if STM32_HSE_CSS
650 		z_arm_nmi_set_handler(HAL_RCC_NMI_IRQHandler);
651 		LL_RCC_HSE_EnableCSS();
652 #endif /* STM32_HSE_CSS */
653 	}
654 
655 	if (IS_ENABLED(STM32_HSI_ENABLED)) {
656 		/* Enable HSI if not enabled */
657 		if (LL_RCC_HSI_IsReady() != 1) {
658 			/* Enable HSI */
659 			LL_RCC_HSI_Enable();
660 			while (LL_RCC_HSI_IsReady() != 1) {
661 			/* Wait for HSI ready */
662 			}
663 		}
664 #if STM32_HSI_DIV_ENABLED
665 		LL_RCC_SetHSIDiv(hsi_divider(STM32_HSI_DIVISOR));
666 #endif
667 	}
668 
669 #if defined(STM32_MSI_ENABLED)
670 	if (IS_ENABLED(STM32_MSI_ENABLED)) {
671 		/* Set MSI Range */
672 #if defined(RCC_CR_MSIRGSEL)
673 		LL_RCC_MSI_EnableRangeSelection();
674 #endif /* RCC_CR_MSIRGSEL */
675 
676 #if defined(CONFIG_SOC_SERIES_STM32L0X) || defined(CONFIG_SOC_SERIES_STM32L1X)
677 		LL_RCC_MSI_SetRange(STM32_MSI_RANGE << RCC_ICSCR_MSIRANGE_Pos);
678 #else
679 		LL_RCC_MSI_SetRange(STM32_MSI_RANGE << RCC_CR_MSIRANGE_Pos);
680 #endif /* CONFIG_SOC_SERIES_STM32L0X || CONFIG_SOC_SERIES_STM32L1X */
681 
682 #if STM32_MSI_PLL_MODE
683 		/* Enable MSI hardware auto calibration */
684 		LL_RCC_MSI_EnablePLLMode();
685 #endif
686 
687 		LL_RCC_MSI_SetCalibTrimming(0);
688 
689 		/* Enable MSI if not enabled */
690 		if (LL_RCC_MSI_IsReady() != 1) {
691 			/* Enable MSI */
692 			LL_RCC_MSI_Enable();
693 			while (LL_RCC_MSI_IsReady() != 1) {
694 				/* Wait for MSI ready */
695 			}
696 		}
697 	}
698 #endif /* STM32_MSI_ENABLED */
699 
700 	if (IS_ENABLED(STM32_LSI_ENABLED)) {
701 #if defined(CONFIG_SOC_SERIES_STM32WBX)
702 		LL_RCC_LSI1_Enable();
703 		while (LL_RCC_LSI1_IsReady() != 1) {
704 		}
705 #else
706 		LL_RCC_LSI_Enable();
707 		while (LL_RCC_LSI_IsReady() != 1) {
708 		}
709 #endif
710 	}
711 
712 	if (IS_ENABLED(STM32_LSE_ENABLED)) {
713 		/* LSE belongs to the back-up domain, enable access.*/
714 
715 		z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
716 
717 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPR_DBP)
718 		/* Set the DBP bit in the Power control register 1 (PWR_CR1) */
719 		LL_PWR_EnableBkUpAccess();
720 		while (!LL_PWR_IsEnabledBkUpAccess()) {
721 			/* Wait for Backup domain access */
722 		}
723 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
724 
725 #if STM32_LSE_DRIVING
726 		/* Configure driving capability */
727 		LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos);
728 #endif
729 
730 		if (IS_ENABLED(STM32_LSE_BYPASS)) {
731 			/* Configure LSE bypass */
732 			LL_RCC_LSE_EnableBypass();
733 		}
734 
735 		/* Enable LSE Oscillator (32.768 kHz) */
736 		LL_RCC_LSE_Enable();
737 		while (!LL_RCC_LSE_IsReady()) {
738 			/* Wait for LSE ready */
739 		}
740 
741 #ifdef RCC_BDCR_LSESYSEN
742 		LL_RCC_LSE_EnablePropagation();
743 		/* Wait till LSESYS is ready */
744 		while (!LL_RCC_LSE_IsPropagationReady()) {
745 		}
746 #endif /* RCC_BDCR_LSESYSEN */
747 
748 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPR_DBP)
749 		LL_PWR_DisableBkUpAccess();
750 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
751 
752 		z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
753 	}
754 
755 #if defined(STM32_HSI14_ENABLED)
756 	/* For all series with HSI 14 clock support */
757 	if (IS_ENABLED(STM32_HSI14_ENABLED)) {
758 		LL_RCC_HSI14_Enable();
759 		while (LL_RCC_HSI14_IsReady() != 1) {
760 		}
761 	}
762 #endif /* STM32_HSI48_ENABLED */
763 
764 #if defined(STM32_HSI48_ENABLED)
765 	/* For all series with HSI 48 clock support */
766 	if (IS_ENABLED(STM32_HSI48_ENABLED)) {
767 #if defined(CONFIG_SOC_SERIES_STM32L0X)
768 		/*
769 		 * HSI48 requires VREFINT (see RM0376 section 7.2.4).
770 		 * The SYSCFG is needed to control VREFINT, so clock it.
771 		 */
772 		LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
773 		LL_SYSCFG_VREFINT_EnableHSI48();
774 #endif /* CONFIG_SOC_SERIES_STM32L0X */
775 
776 		/*
777 		 * STM32WB: Lock the CLK48 HSEM and do not release to prevent
778 		 * M0 core to disable this clock (used for RNG on M0).
779 		 * No-op on other series.
780 		 */
781 		z_stm32_hsem_lock(CFG_HW_CLK48_CONFIG_SEMID, HSEM_LOCK_DEFAULT_RETRY);
782 
783 		LL_RCC_HSI48_Enable();
784 		while (LL_RCC_HSI48_IsReady() != 1) {
785 		}
786 	}
787 #endif /* STM32_HSI48_ENABLED */
788 }
789 
790 /**
791  * @brief Initialize clocks for the stm32
792  *
793  * This routine is called to enable and configure the clocks and PLL
794  * of the soc on the board. It depends on the board definition.
795  * This function is called on the startup and also to restore the config
796  * when exiting for low power mode.
797  *
798  * @param dev clock device struct
799  *
800  * @return 0
801  */
stm32_clock_control_init(const struct device * dev)802 int stm32_clock_control_init(const struct device *dev)
803 {
804 	ARG_UNUSED(dev);
805 
806 	/* Some clocks would be activated by default */
807 	config_enable_default_clocks();
808 	config_regulator_voltage(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
809 
810 #if defined(FLASH_ACR_LATENCY)
811 	uint32_t old_flash_freq;
812 	uint32_t new_flash_freq;
813 
814 	old_flash_freq = RCC_CALC_FLASH_FREQ(HAL_RCC_GetSysClockFreq(),
815 					       GET_CURRENT_FLASH_PRESCALER());
816 
817 	new_flash_freq = RCC_CALC_FLASH_FREQ(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
818 				      STM32_FLASH_PRESCALER);
819 
820 	/* If HCLK increases, set flash latency before any clock setting */
821 	if (old_flash_freq < new_flash_freq) {
822 		LL_SetFlashLatency(new_flash_freq);
823 	}
824 #endif /* FLASH_ACR_LATENCY */
825 
826 	/* Set up individual enabled clocks */
827 	set_up_fixed_clock_sources();
828 
829 	/* Set up PLLs */
830 	set_up_plls();
831 
832 	if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) &&
833 		(ahb_prescaler(STM32_CORE_PRESCALER) == ahb_prescaler(1)) &&
834 		(MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) {
835 		LL_RCC_SetAHBPrescaler(ahb_prescaler(2));
836 	} else {
837 		LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER));
838 	}
839 
840 #if STM32_SYSCLK_SRC_PLL
841 	/* Set PLL as System Clock Source */
842 	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
843 	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) {
844 	}
845 #elif STM32_SYSCLK_SRC_HSE
846 	/* Set HSE as SYSCLCK source */
847 	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
848 	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
849 	}
850 #elif STM32_SYSCLK_SRC_MSI
851 	/* Set MSI as SYSCLCK source */
852 	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_MSI);
853 	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_MSI) {
854 	}
855 #elif STM32_SYSCLK_SRC_HSI
856 	stm32_clock_switch_to_hsi();
857 #endif /* STM32_SYSCLK_SRC_... */
858 
859 	if (DT_PROP(DT_NODELABEL(rcc), undershoot_prevention) &&
860 		(ahb_prescaler(STM32_CORE_PRESCALER) == ahb_prescaler(1)) &&
861 		(MHZ(80) < CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC)) {
862 		LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CORE_PRESCALER));
863 	}
864 
865 #if defined(FLASH_ACR_LATENCY)
866 	/* If HCLK not increased, set flash latency after all clock setting */
867 	if (old_flash_freq >= new_flash_freq) {
868 		LL_SetFlashLatency(new_flash_freq);
869 	}
870 #endif /* FLASH_ACR_LATENCY */
871 
872 	SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
873 
874 	/* Set bus prescalers prescaler */
875 	LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_APB1_PRESCALER));
876 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), apb2_prescaler)
877 	LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_APB2_PRESCALER));
878 #endif
879 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), cpu2_prescaler)
880 	LL_C2_RCC_SetAHBPrescaler(ahb_prescaler(STM32_CPU2_PRESCALER));
881 #endif
882 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
883 	LL_RCC_SetAHB3Prescaler(ahb_prescaler(STM32_AHB3_PRESCALER));
884 #endif
885 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
886 	LL_RCC_SetAHB4Prescaler(ahb_prescaler(STM32_AHB4_PRESCALER));
887 #endif
888 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc_prescaler)
889 	LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC_PRESCALER));
890 #endif
891 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc12_prescaler)
892 	LL_RCC_SetADCClockSource(adc12_prescaler(STM32_ADC12_PRESCALER));
893 #endif
894 #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), adc34_prescaler)
895 	LL_RCC_SetADCClockSource(adc34_prescaler(STM32_ADC34_PRESCALER));
896 #endif
897 
898 	return 0;
899 }
900 
901 #if defined(STM32_HSE_CSS)
stm32_hse_css_callback(void)902 void __weak stm32_hse_css_callback(void) {}
903 
904 /* Called by the HAL in response to an HSE CSS interrupt */
HAL_RCC_CSSCallback(void)905 void HAL_RCC_CSSCallback(void)
906 {
907 	stm32_hse_css_callback();
908 }
909 #endif
910 
config_regulator_voltage(uint32_t hclk_freq)911 void __weak config_regulator_voltage(uint32_t hclk_freq) {}
912 /**
913  * @brief RCC device, note that priority is intentionally set to 1 so
914  * that the device init runs just after SOC init
915  */
916 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
917 		    stm32_clock_control_init,
918 		    NULL,
919 		    NULL, NULL,
920 		    PRE_KERNEL_1,
921 		    CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
922 		    &stm32_clock_control_api);
923