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