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