1 /*
2  *
3  * Copyright (c) 2019 Linaro Limited.
4  * Copyright (c) 2020 Jeremy LOCHE
5  * Copyright (c) 2021 Electrolance Solutions
6  *
7  * SPDX-License-Identifier: Apache-2.0
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 <zephyr/arch/cpu.h>
16 #include <zephyr/drivers/clock_control.h>
17 #include <zephyr/sys/util.h>
18 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
19 #include "stm32_hsem.h"
20 
21 
22 /* Macros to fill up prescaler values */
23 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
24 #define z_hsi_divider(v) LL_RCC_HSI_DIV_ ## v
25 #else
26 #define z_hsi_divider(v) LL_RCC_HSI_DIV ## v
27 #endif
28 #define hsi_divider(v) z_hsi_divider(v)
29 
30 #define z_sysclk_prescaler(v) LL_RCC_SYSCLK_DIV_ ## v
31 #define sysclk_prescaler(v) z_sysclk_prescaler(v)
32 
33 #define z_ahb_prescaler(v) LL_RCC_AHB_DIV_ ## v
34 #define ahb_prescaler(v) z_ahb_prescaler(v)
35 
36 #define z_apb1_prescaler(v) LL_RCC_APB1_DIV_ ## v
37 #define apb1_prescaler(v) z_apb1_prescaler(v)
38 
39 #define z_apb2_prescaler(v) LL_RCC_APB2_DIV_ ## v
40 #define apb2_prescaler(v) z_apb2_prescaler(v)
41 
42 #define z_apb3_prescaler(v) LL_RCC_APB3_DIV_ ## v
43 #define apb3_prescaler(v) z_apb3_prescaler(v)
44 
45 #define z_apb4_prescaler(v) LL_RCC_APB4_DIV_ ## v
46 #define apb4_prescaler(v) z_apb4_prescaler(v)
47 
48 #define z_apb5_prescaler(v) LL_RCC_APB5_DIV_ ## v
49 #define apb5_prescaler(v) z_apb5_prescaler(v)
50 
51 /* Macro to check for clock feasibility */
52 /* It is Cortex M7's responsibility to setup clock tree */
53 /* This check should only be performed for the M7 core code */
54 #ifdef CONFIG_CPU_CORTEX_M7
55 
56 /* Choose PLL SRC */
57 #if defined(STM32_PLL_SRC_HSI)
58 #define PLLSRC_FREQ  ((STM32_HSI_FREQ)/(STM32_HSI_DIVISOR))
59 #elif defined(STM32_PLL_SRC_CSI)
60 #define PLLSRC_FREQ  STM32_CSI_FREQ
61 #elif defined(STM32_PLL_SRC_HSE)
62 #define PLLSRC_FREQ  STM32_HSE_FREQ
63 #else
64 #define PLLSRC_FREQ 0
65 #endif
66 
67 /* Given source clock and dividers, computed the output frequency of PLLP */
68 #define PLLP_FREQ(pllsrc_freq, divm, divn, divp)	(((pllsrc_freq)*\
69 							(divn))/((divm)*(divp)))
70 
71 /* PLL P output frequency value */
72 #define PLLP_VALUE	PLLP_FREQ(\
73 				PLLSRC_FREQ,\
74 				STM32_PLL_M_DIVISOR,\
75 				STM32_PLL_N_MULTIPLIER,\
76 				STM32_PLL_P_DIVISOR)
77 
78 /* SYSCLKSRC before the D1CPRE prescaler */
79 #if defined(STM32_SYSCLK_SRC_PLL)
80 #define SYSCLKSRC_FREQ	PLLP_VALUE
81 #elif defined(STM32_SYSCLK_SRC_HSI)
82 #define SYSCLKSRC_FREQ	((STM32_HSI_FREQ)/(STM32_HSI_DIVISOR))
83 #elif defined(STM32_SYSCLK_SRC_CSI)
84 #define SYSCLKSRC_FREQ	STM32_CSI_FREQ
85 #elif defined(STM32_SYSCLK_SRC_HSE)
86 #define SYSCLKSRC_FREQ	STM32_HSE_FREQ
87 #endif
88 
89 /* ARM Sys CPU Clock before HPRE prescaler */
90 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
91 #define SYSCLK_FREQ	((SYSCLKSRC_FREQ)/(STM32_D1CPRE))
92 #define AHB_FREQ	((SYSCLK_FREQ)/(STM32_HPRE))
93 #define APB1_FREQ	((AHB_FREQ)/(STM32_PPRE1))
94 #define APB2_FREQ	((AHB_FREQ)/(STM32_PPRE2))
95 #define APB4_FREQ	((AHB_FREQ)/(STM32_PPRE4))
96 #define APB5_FREQ	((AHB_FREQ)/(STM32_PPRE5))
97 #else
98 #define SYSCLK_FREQ	((SYSCLKSRC_FREQ)/(STM32_D1CPRE))
99 #define AHB_FREQ	((SYSCLK_FREQ)/(STM32_HPRE))
100 #define APB1_FREQ	((AHB_FREQ)/(STM32_D2PPRE1))
101 #define APB2_FREQ	((AHB_FREQ)/(STM32_D2PPRE2))
102 #define APB3_FREQ	((AHB_FREQ)/(STM32_D1PPRE))
103 #define APB4_FREQ	((AHB_FREQ)/(STM32_D3PPRE))
104 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
105 
106 /* Datasheet maximum frequency definitions */
107 #if defined(CONFIG_SOC_STM32H743XX) ||\
108 	defined(CONFIG_SOC_STM32H745XX_M7) || defined(CONFIG_SOC_STM32H745XX_M4) ||\
109 	defined(CONFIG_SOC_STM32H747XX_M7) || defined(CONFIG_SOC_STM32H747XX_M4) ||\
110 	defined(CONFIG_SOC_STM32H750XX) ||\
111 	defined(CONFIG_SOC_STM32H753XX) ||\
112 	defined(CONFIG_SOC_STM32H755XX_M7) || defined(CONFIG_SOC_STM32H755XX_M4) ||\
113 	defined(CONFIG_SOC_STM32H757XX_M7) || defined(CONFIG_SOC_STM32H757XX_M4)
114 /* All h7 SoC with maximum 480MHz SYSCLK */
115 #define SYSCLK_FREQ_MAX		480000000UL
116 #define AHB_FREQ_MAX		240000000UL
117 #define APBx_FREQ_MAX		120000000UL
118 #elif defined(CONFIG_SOC_STM32H723XX) ||\
119 	  defined(CONFIG_SOC_STM32H725XX) ||\
120 	  defined(CONFIG_SOC_STM32H730XX) || defined(CONFIG_SOC_STM32H730XXQ) ||\
121 	  defined(CONFIG_SOC_STM32H735XX)
122 /* All h7 SoC with maximum 550MHz SYSCLK */
123 #define SYSCLK_FREQ_MAX		550000000UL
124 #define AHB_FREQ_MAX		275000000UL
125 #define APBx_FREQ_MAX		137500000UL
126 #elif defined(CONFIG_SOC_STM32H7A3XX) || defined(CONFIG_SOC_STM32H7A3XXQ) ||\
127 	  defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) ||\
128 	  defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ)
129 #define SYSCLK_FREQ_MAX		280000000UL
130 #define AHB_FREQ_MAX		280000000UL
131 #define APBx_FREQ_MAX		140000000UL
132 #elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
133 /* All h7RS SoC with maximum 500MHz SYSCLK (refer to Datasheet DS14359 rev 1) */
134 #define SYSCLK_FREQ_MAX		500000000UL
135 #define AHB_FREQ_MAX		250000000UL
136 #define APBx_FREQ_MAX		125000000UL
137 #else
138 /* Default: All h7 SoC with maximum 280MHz SYSCLK */
139 #define SYSCLK_FREQ_MAX		280000000UL
140 #define AHB_FREQ_MAX		140000000UL
141 #define APBx_FREQ_MAX		70000000UL
142 #endif
143 
144 #if SYSCLK_FREQ > SYSCLK_FREQ_MAX
145 #error "SYSCLK frequency is too high!"
146 #endif
147 #if AHB_FREQ > AHB_FREQ_MAX
148 #error "AHB frequency is too high!"
149 #endif
150 #if APB1_FREQ > APBx_FREQ_MAX
151 #error "APB1 frequency is too high!"
152 #endif
153 #if APB2_FREQ > APBx_FREQ_MAX
154 #error "APB2 frequency is too high!"
155 #endif
156 #if APB3_FREQ > APBx_FREQ_MAX
157 #error "APB3 frequency is too high!"
158 #endif
159 #if APB4_FREQ > APBx_FREQ_MAX
160 #error "APB4 frequency is too high!"
161 #endif
162 
163 /* end of clock feasibility check */
164 #endif /* CONFIG_CPU_CORTEX_M7 */
165 
166 
167 #if defined(CONFIG_CPU_CORTEX_M7)
168 #if STM32_D1CPRE > 1
169 /*
170  * D1CPRE prescaler allows to set a HCLK frequency lower than SYSCLK frequency.
171  * Though, zephyr doesn't make a difference today between these two clocks.
172  * So, changing this prescaler is not allowed until it is made possible to
173  * use them independently in zephyr clock subsystem.
174  */
175 #error "D1CPRE prescaler can't be higher than 1"
176 #endif
177 #endif /* CONFIG_CPU_CORTEX_M7 */
178 
179 #if defined(CONFIG_CPU_CORTEX_M7)
180 /* Offset to access bus clock registers from M7 (or only) core */
181 #define STM32H7_BUS_CLK_REG	DT_REG_ADDR(DT_NODELABEL(rcc))
182 #elif defined(CONFIG_CPU_CORTEX_M4)
183 /* Offset to access bus clock registers from M4 core */
184 #define STM32H7_BUS_CLK_REG	DT_REG_ADDR(DT_NODELABEL(rcc)) + 0x60
185 #endif
186 
get_bus_clock(uint32_t clock,uint32_t prescaler)187 static uint32_t get_bus_clock(uint32_t clock, uint32_t prescaler)
188 {
189 	return clock / prescaler;
190 }
191 
192 __unused
get_pllout_frequency(uint32_t pllsrc_freq,int pllm_div,int plln_mul,int pllout_div)193 static uint32_t get_pllout_frequency(uint32_t pllsrc_freq,
194 				     int pllm_div,
195 				     int plln_mul,
196 				     int pllout_div)
197 {
198 	__ASSERT_NO_MSG(pllm_div && pllout_div);
199 
200 	return (pllsrc_freq / pllm_div) * plln_mul / pllout_div;
201 }
202 
203 __unused
get_pllsrc_frequency(void)204 static uint32_t get_pllsrc_frequency(void)
205 {
206 	switch (LL_RCC_PLL_GetSource()) {
207 	case LL_RCC_PLLSOURCE_HSI:
208 		return STM32_HSI_FREQ;
209 	case LL_RCC_PLLSOURCE_CSI:
210 		return STM32_CSI_FREQ;
211 	case LL_RCC_PLLSOURCE_HSE:
212 		return STM32_HSE_FREQ;
213 	case LL_RCC_PLLSOURCE_NONE:
214 	default:
215 		return 0;
216 	}
217 }
218 
219 __unused
get_hclk_frequency(void)220 static uint32_t get_hclk_frequency(void)
221 {
222 	uint32_t sysclk = 0;
223 
224 	/* Get the current system clock source */
225 	switch (LL_RCC_GetSysClkSource()) {
226 	case LL_RCC_SYS_CLKSOURCE_STATUS_HSI:
227 		sysclk = STM32_HSI_FREQ/STM32_HSI_DIVISOR;
228 		break;
229 	case LL_RCC_SYS_CLKSOURCE_STATUS_CSI:
230 		sysclk = STM32_CSI_FREQ;
231 		break;
232 	case LL_RCC_SYS_CLKSOURCE_STATUS_HSE:
233 		sysclk = STM32_HSE_FREQ;
234 		break;
235 #if defined(STM32_PLL_ENABLED)
236 	case LL_RCC_SYS_CLKSOURCE_STATUS_PLL1:
237 		sysclk = get_pllout_frequency(get_pllsrc_frequency(),
238 					      STM32_PLL_M_DIVISOR,
239 					      STM32_PLL_N_MULTIPLIER,
240 					      STM32_PLL_P_DIVISOR);
241 		break;
242 #endif /* STM32_PLL_ENABLED */
243 	}
244 
245 	return get_bus_clock(sysclk, STM32_HPRE);
246 }
247 
248 #if !defined(CONFIG_CPU_CORTEX_M4)
249 
prepare_regulator_voltage_scale(void)250 static int32_t prepare_regulator_voltage_scale(void)
251 {
252 	/* Apply system power supply configuration */
253 #if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS)
254 	LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
255 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO)
256 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_LDO);
257 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO)
258 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_LDO);
259 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO)
260 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO);
261 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO)
262 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO);
263 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT)
264 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT);
265 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT)
266 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT);
267 #elif defined(CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE)
268 	LL_PWR_ConfigSupply(LL_PWR_EXTERNAL_SOURCE_SUPPLY);
269 #else
270 	LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
271 #endif
272 
273 	/* Make sure to put the CPU in highest Voltage scale during clock configuration */
274 	/* Highest voltage is SCALE0 */
275 	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
276 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
277 	while (LL_PWR_IsActiveFlag_VOSRDY() == 0) {
278 #else
279 	while (LL_PWR_IsActiveFlag_VOS() == 0) {
280 #endif
281 	}
282 	return 0;
283 }
284 
285 static int32_t optimize_regulator_voltage_scale(uint32_t sysclk_freq)
286 {
287 
288 	/* After sysclock is configured, tweak the voltage scale down */
289 	/* to reduce power consumption */
290 
291 	/* Needs some smart work to configure properly */
292 	/* LL_PWR_REGULATOR_SCALE3 is lowest power consumption */
293 	/* Must be done in accordance to the Maximum allowed frequency vs VOS*/
294 	/* See RM0433 page 352 for more details */
295 #if defined(SMPS) && defined(CONFIG_POWER_SUPPLY_DIRECT_SMPS)
296 	LL_PWR_ConfigSupply(LL_PWR_DIRECT_SMPS_SUPPLY);
297 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_LDO)
298 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_LDO);
299 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_LDO)
300 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_LDO);
301 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT_AND_LDO)
302 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT_AND_LDO);
303 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT_AND_LDO)
304 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT_AND_LDO);
305 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_1V8_SUPPLIES_EXT)
306 	LL_PWR_ConfigSupply(LL_PWR_SMPS_1V8_SUPPLIES_EXT);
307 #elif defined(SMPS) && defined(CONFIG_POWER_SUPPLY_SMPS_2V5_SUPPLIES_EXT)
308 	LL_PWR_ConfigSupply(LL_PWR_SMPS_2V5_SUPPLIES_EXT);
309 #elif defined(CONFIG_POWER_SUPPLY_EXTERNAL_SOURCE)
310 	LL_PWR_ConfigSupply(LL_PWR_EXTERNAL_SOURCE_SUPPLY);
311 #else
312 	LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
313 #endif
314 	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
315 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
316 	while (LL_PWR_IsActiveFlag_VOSRDY() == 0) {
317 #else
318 	while (LL_PWR_IsActiveFlag_VOS() == 0) {
319 #endif
320 	};
321 	return 0;
322 }
323 
324 __unused
325 static int get_vco_input_range(uint32_t m_div, uint32_t *range)
326 {
327 	uint32_t vco_freq;
328 
329 	vco_freq = PLLSRC_FREQ / m_div;
330 
331 	if (MHZ(1) <= vco_freq && vco_freq <= MHZ(2)) {
332 		*range = LL_RCC_PLLINPUTRANGE_1_2;
333 	} else if (MHZ(2) < vco_freq && vco_freq <= MHZ(4)) {
334 		*range = LL_RCC_PLLINPUTRANGE_2_4;
335 	} else if (MHZ(4) < vco_freq && vco_freq <= MHZ(8)) {
336 		*range = LL_RCC_PLLINPUTRANGE_4_8;
337 	} else if (MHZ(8) < vco_freq && vco_freq <= MHZ(16)) {
338 		*range = LL_RCC_PLLINPUTRANGE_8_16;
339 	} else {
340 		return -ERANGE;
341 	}
342 
343 	return 0;
344 }
345 
346 __unused
347 static uint32_t get_vco_output_range(uint32_t vco_input_range)
348 {
349 	if (vco_input_range == LL_RCC_PLLINPUTRANGE_1_2) {
350 		return LL_RCC_PLLVCORANGE_MEDIUM;
351 	}
352 
353 	return LL_RCC_PLLVCORANGE_WIDE;
354 }
355 
356 #endif /* ! CONFIG_CPU_CORTEX_M4 */
357 
358 /** @brief Verifies clock is part of active clock configuration */
359 int enabled_clock(uint32_t src_clk)
360 {
361 
362 	if ((src_clk == STM32_SRC_SYSCLK) ||
363 	    ((src_clk == STM32_SRC_CKPER) && IS_ENABLED(STM32_CKPER_ENABLED)) ||
364 	    ((src_clk == STM32_SRC_HSE) && IS_ENABLED(STM32_HSE_ENABLED)) ||
365 	    ((src_clk == STM32_SRC_HSI_KER) && IS_ENABLED(STM32_HSI_ENABLED)) ||
366 	    ((src_clk == STM32_SRC_CSI_KER) && IS_ENABLED(STM32_CSI_ENABLED)) ||
367 	    ((src_clk == STM32_SRC_HSI48) && IS_ENABLED(STM32_HSI48_ENABLED)) ||
368 	    ((src_clk == STM32_SRC_LSE) && IS_ENABLED(STM32_LSE_ENABLED)) ||
369 	    ((src_clk == STM32_SRC_LSI) && IS_ENABLED(STM32_LSI_ENABLED)) ||
370 	    ((src_clk == STM32_SRC_PLL1_P) && IS_ENABLED(STM32_PLL_P_ENABLED)) ||
371 	    ((src_clk == STM32_SRC_PLL1_Q) && IS_ENABLED(STM32_PLL_Q_ENABLED)) ||
372 	    ((src_clk == STM32_SRC_PLL1_R) && IS_ENABLED(STM32_PLL_R_ENABLED)) ||
373 	    ((src_clk == STM32_SRC_PLL2_P) && IS_ENABLED(STM32_PLL2_P_ENABLED)) ||
374 	    ((src_clk == STM32_SRC_PLL2_Q) && IS_ENABLED(STM32_PLL2_Q_ENABLED)) ||
375 	    ((src_clk == STM32_SRC_PLL2_R) && IS_ENABLED(STM32_PLL2_R_ENABLED)) ||
376 	    ((src_clk == STM32_SRC_PLL3_P) && IS_ENABLED(STM32_PLL3_P_ENABLED)) ||
377 	    ((src_clk == STM32_SRC_PLL3_Q) && IS_ENABLED(STM32_PLL3_Q_ENABLED)) ||
378 	    ((src_clk == STM32_SRC_PLL3_R) && IS_ENABLED(STM32_PLL3_R_ENABLED))) {
379 		return 0;
380 	}
381 
382 	return -ENOTSUP;
383 }
384 
385 static inline int stm32_clock_control_on(const struct device *dev,
386 					 clock_control_subsys_t sub_system)
387 {
388 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
389 	volatile int temp;
390 
391 	ARG_UNUSED(dev);
392 
393 	if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
394 		/* Attempt to toggle a wrong periph clock bit */
395 		return -ENOTSUP;
396 	}
397 
398 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
399 
400 	sys_set_bits(STM32H7_BUS_CLK_REG + pclken->bus, pclken->enr);
401 	/* Delay after enabling the clock, to allow it to become active.
402 	 * See RM0433 8.5.10 "Clock enabling delays"
403 	 */
404 	temp = sys_read32(STM32H7_BUS_CLK_REG + pclken->bus);
405 	UNUSED(temp);
406 
407 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
408 
409 	return 0;
410 }
411 
412 static inline int stm32_clock_control_off(const struct device *dev,
413 					  clock_control_subsys_t sub_system)
414 {
415 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
416 
417 	ARG_UNUSED(dev);
418 
419 	if (IN_RANGE(pclken->bus, STM32_PERIPH_BUS_MIN, STM32_PERIPH_BUS_MAX) == 0) {
420 		/* Attempt to toggle a wrong periph clock bit */
421 		return -ENOTSUP;
422 	}
423 
424 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
425 
426 	sys_clear_bits(STM32H7_BUS_CLK_REG + pclken->bus, pclken->enr);
427 
428 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
429 
430 	return 0;
431 }
432 
433 static inline int stm32_clock_control_configure(const struct device *dev,
434 						clock_control_subsys_t sub_system,
435 						void *data)
436 {
437 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
438 	int err;
439 
440 	ARG_UNUSED(dev);
441 	ARG_UNUSED(data);
442 
443 	err = enabled_clock(pclken->bus);
444 	if (err < 0) {
445 		/* Attempt to configure a src clock not available or not valid */
446 		return err;
447 	}
448 
449 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
450 
451 	sys_clear_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
452 		       STM32_DT_CLKSEL_MASK_GET(pclken->enr) <<
453 			STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
454 	sys_set_bits(DT_REG_ADDR(DT_NODELABEL(rcc)) + STM32_DT_CLKSEL_REG_GET(pclken->enr),
455 		     STM32_DT_CLKSEL_VAL_GET(pclken->enr) <<
456 			STM32_DT_CLKSEL_SHIFT_GET(pclken->enr));
457 
458 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
459 
460 	return 0;
461 }
462 
463 static int stm32_clock_control_get_subsys_rate(const struct device *clock,
464 					       clock_control_subsys_t sub_system,
465 					       uint32_t *rate)
466 {
467 	struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
468 	/*
469 	 * Get AHB Clock (= SystemCoreClock = SYSCLK/prescaler)
470 	 * SystemCoreClock is preferred to CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
471 	 * since it will be updated after clock configuration and hence
472 	 * more likely to contain actual clock speed
473 	 */
474 #if defined(CONFIG_CPU_CORTEX_M4)
475 	uint32_t ahb_clock = SystemCoreClock;
476 #else
477 	uint32_t ahb_clock = get_bus_clock(SystemCoreClock, STM32_HPRE);
478 #endif
479 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
480 	uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_PPRE1);
481 	uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_PPRE2);
482 	uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_PPRE4);
483 	uint32_t apb5_clock = get_bus_clock(ahb_clock, STM32_PPRE5);
484 #else
485 	uint32_t apb1_clock = get_bus_clock(ahb_clock, STM32_D2PPRE1);
486 	uint32_t apb2_clock = get_bus_clock(ahb_clock, STM32_D2PPRE2);
487 	uint32_t apb3_clock = get_bus_clock(ahb_clock, STM32_D1PPRE);
488 	uint32_t apb4_clock = get_bus_clock(ahb_clock, STM32_D3PPRE);
489 #endif
490 
491 	ARG_UNUSED(clock);
492 
493 	switch (pclken->bus) {
494 	case STM32_CLOCK_BUS_AHB1:
495 	case STM32_CLOCK_BUS_AHB2:
496 	case STM32_CLOCK_BUS_AHB3:
497 	case STM32_CLOCK_BUS_AHB4:
498 		*rate = ahb_clock;
499 		break;
500 	case STM32_CLOCK_BUS_APB1:
501 	case STM32_CLOCK_BUS_APB1_2:
502 		*rate = apb1_clock;
503 		break;
504 	case STM32_CLOCK_BUS_APB2:
505 		*rate = apb2_clock;
506 		break;
507 #if !defined(CONFIG_SOC_SERIES_STM32H7RSX)
508 	case STM32_CLOCK_BUS_APB3:
509 		*rate = apb3_clock;
510 		break;
511 #endif /* !CONFIG_SOC_SERIES_STM32H7RSX */
512 	case STM32_CLOCK_BUS_APB4:
513 		*rate = apb4_clock;
514 		break;
515 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
516 	case STM32_CLOCK_BUS_APB5:
517 		*rate = apb5_clock;
518 		break;
519 	case STM32_CLOCK_BUS_AHB5:
520 		*rate = ahb_clock;
521 		break;
522 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
523 	case STM32_SRC_SYSCLK:
524 		*rate = get_hclk_frequency();
525 		break;
526 #if defined(STM32_CKPER_ENABLED)
527 	case STM32_SRC_CKPER:
528 		*rate = LL_RCC_GetCLKPClockFreq(LL_RCC_CLKP_CLKSOURCE);
529 		break;
530 #endif /* STM32_CKPER_ENABLED */
531 #if defined(STM32_HSE_ENABLED)
532 	case STM32_SRC_HSE:
533 		*rate = STM32_HSE_FREQ;
534 		break;
535 #endif /* STM32_HSE_ENABLED */
536 #if defined(STM32_LSE_ENABLED)
537 	case STM32_SRC_LSE:
538 		*rate = STM32_LSE_FREQ;
539 		break;
540 #endif /* STM32_LSE_ENABLED */
541 #if defined(STM32_LSI_ENABLED)
542 	case STM32_SRC_LSI:
543 		*rate = STM32_LSI_FREQ;
544 		break;
545 #endif /* STM32_LSI_ENABLED */
546 #if defined(STM32_HSI_ENABLED)
547 	case STM32_SRC_HSI_KER:
548 		*rate = STM32_HSI_FREQ/STM32_HSI_DIVISOR;
549 	break;
550 #endif /* STM32_HSI_ENABLED */
551 #if defined(STM32_HSI48_ENABLED)
552 	case STM32_SRC_HSI48:
553 		*rate = STM32_HSI48_FREQ;
554 		break;
555 #endif /* STM32_HSI48_ENABLED */
556 #if defined(STM32_PLL_ENABLED)
557 	case STM32_SRC_PLL1_P:
558 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
559 					      STM32_PLL_M_DIVISOR,
560 					      STM32_PLL_N_MULTIPLIER,
561 					      STM32_PLL_P_DIVISOR);
562 		break;
563 	case STM32_SRC_PLL1_Q:
564 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
565 					      STM32_PLL_M_DIVISOR,
566 					      STM32_PLL_N_MULTIPLIER,
567 					      STM32_PLL_Q_DIVISOR);
568 		break;
569 	case STM32_SRC_PLL1_R:
570 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
571 					      STM32_PLL_M_DIVISOR,
572 					      STM32_PLL_N_MULTIPLIER,
573 					      STM32_PLL_R_DIVISOR);
574 		break;
575 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
576 	case STM32_SRC_PLL1_S:
577 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
578 					      STM32_PLL_M_DIVISOR,
579 					      STM32_PLL_N_MULTIPLIER,
580 					      STM32_PLL_S_DIVISOR);
581 		break;
582 	/* PLL 1  has no T-divider */
583 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
584 #endif /* STM32_PLL_ENABLED */
585 #if defined(STM32_PLL2_ENABLED)
586 	case STM32_SRC_PLL2_P:
587 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
588 					      STM32_PLL2_M_DIVISOR,
589 					      STM32_PLL2_N_MULTIPLIER,
590 					      STM32_PLL2_P_DIVISOR);
591 		break;
592 	case STM32_SRC_PLL2_Q:
593 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
594 					      STM32_PLL2_M_DIVISOR,
595 					      STM32_PLL2_N_MULTIPLIER,
596 					      STM32_PLL2_Q_DIVISOR);
597 		break;
598 	case STM32_SRC_PLL2_R:
599 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
600 					      STM32_PLL2_M_DIVISOR,
601 					      STM32_PLL2_N_MULTIPLIER,
602 					      STM32_PLL2_R_DIVISOR);
603 		break;
604 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
605 	case STM32_SRC_PLL2_S:
606 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
607 					      STM32_PLL2_M_DIVISOR,
608 					      STM32_PLL2_N_MULTIPLIER,
609 					      STM32_PLL2_S_DIVISOR);
610 		break;
611 	case STM32_SRC_PLL2_T:
612 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
613 					      STM32_PLL2_M_DIVISOR,
614 					      STM32_PLL2_N_MULTIPLIER,
615 					      STM32_PLL2_T_DIVISOR);
616 		break;
617 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
618 #endif /* STM32_PLL2_ENABLED */
619 #if defined(STM32_PLL3_ENABLED)
620 	case STM32_SRC_PLL3_P:
621 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
622 					      STM32_PLL3_M_DIVISOR,
623 					      STM32_PLL3_N_MULTIPLIER,
624 					      STM32_PLL3_P_DIVISOR);
625 		break;
626 	case STM32_SRC_PLL3_Q:
627 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
628 					      STM32_PLL3_M_DIVISOR,
629 					      STM32_PLL3_N_MULTIPLIER,
630 					      STM32_PLL3_Q_DIVISOR);
631 		break;
632 	case STM32_SRC_PLL3_R:
633 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
634 					      STM32_PLL3_M_DIVISOR,
635 					      STM32_PLL3_N_MULTIPLIER,
636 					      STM32_PLL3_R_DIVISOR);
637 		break;
638 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
639 	case STM32_SRC_PLL3_S:
640 		*rate = get_pllout_frequency(get_pllsrc_frequency(),
641 					      STM32_PLL3_M_DIVISOR,
642 					      STM32_PLL3_N_MULTIPLIER,
643 					      STM32_PLL3_S_DIVISOR);
644 		break;
645 	/* PLL 3  has no T-divider */
646 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
647 #endif /* STM32_PLL3_ENABLED */
648 	default:
649 		return -ENOTSUP;
650 	}
651 
652 	if (pclken->div) {
653 		*rate /= (pclken->div + 1);
654 	}
655 
656 	return 0;
657 }
658 
659 static DEVICE_API(clock_control, stm32_clock_control_api) = {
660 	.on = stm32_clock_control_on,
661 	.off = stm32_clock_control_off,
662 	.get_rate = stm32_clock_control_get_subsys_rate,
663 	.configure = stm32_clock_control_configure,
664 };
665 
666 __unused
667 static void set_up_fixed_clock_sources(void)
668 {
669 
670 	if (IS_ENABLED(STM32_HSE_ENABLED)) {
671 		/* Enable HSE oscillator */
672 		if (IS_ENABLED(STM32_HSE_BYPASS)) {
673 			LL_RCC_HSE_EnableBypass();
674 		} else {
675 			LL_RCC_HSE_DisableBypass();
676 		}
677 
678 		LL_RCC_HSE_Enable();
679 		while (LL_RCC_HSE_IsReady() != 1) {
680 		}
681 		/* Check if we need to enable HSE clock security system or not */
682 #if STM32_HSE_CSS
683 		z_arm_nmi_set_handler(HAL_RCC_NMI_IRQHandler);
684 		LL_RCC_HSE_EnableCSS();
685 #endif /* STM32_HSE_CSS */
686 	}
687 
688 	if (IS_ENABLED(STM32_HSI_ENABLED)) {
689 		if (IS_ENABLED(STM32_PLL_SRC_HSI) || IS_ENABLED(STM32_PLL2_SRC_HSI) ||
690 +		    IS_ENABLED(STM32_PLL3_SRC_HSI)) {
691 			/* HSI calibration */
692 			LL_RCC_HSI_SetCalibTrimming(RCC_HSICALIBRATION_DEFAULT);
693 		}
694 		/* Enable HSI if not enabled */
695 		if (LL_RCC_HSI_IsReady() != 1) {
696 			/* Enable HSI oscillator */
697 			LL_RCC_HSI_Enable();
698 			while (LL_RCC_HSI_IsReady() != 1) {
699 			/* Wait for HSI ready */
700 			}
701 		}
702 		/* HSI divider configuration */
703 		LL_RCC_HSI_SetDivider(hsi_divider(STM32_HSI_DIVISOR));
704 	}
705 
706 	if (IS_ENABLED(STM32_CSI_ENABLED)) {
707 		/* Enable CSI oscillator */
708 		LL_RCC_CSI_Enable();
709 		while (LL_RCC_CSI_IsReady() != 1) {
710 		}
711 	}
712 
713 	if (IS_ENABLED(STM32_LSI_ENABLED)) {
714 		/* Enable LSI oscillator */
715 		LL_RCC_LSI_Enable();
716 		while (LL_RCC_LSI_IsReady() != 1) {
717 		}
718 	}
719 
720 	if (IS_ENABLED(STM32_LSE_ENABLED)) {
721 		/* Enable backup domain */
722 		LL_PWR_EnableBkUpAccess();
723 
724 		/* Configure driving capability */
725 		LL_RCC_LSE_SetDriveCapability(STM32_LSE_DRIVING << RCC_BDCR_LSEDRV_Pos);
726 
727 		if (IS_ENABLED(STM32_LSE_BYPASS)) {
728 			/* Configure LSE bypass */
729 			LL_RCC_LSE_EnableBypass();
730 		}
731 
732 		/* Enable LSE oscillator */
733 		LL_RCC_LSE_Enable();
734 		while (LL_RCC_LSE_IsReady() != 1) {
735 		}
736 	}
737 
738 	if (IS_ENABLED(STM32_HSI48_ENABLED)) {
739 		LL_RCC_HSI48_Enable();
740 		while (LL_RCC_HSI48_IsReady() != 1) {
741 		}
742 	}
743 }
744 
745 /*
746  * Unconditionally switch the system clock source to HSI.
747  */
748 __unused
749 static void stm32_clock_switch_to_hsi(void)
750 {
751 	/* Enable HSI if not enabled */
752 	if (LL_RCC_HSI_IsReady() != 1) {
753 		/* Enable HSI */
754 		LL_RCC_HSI_Enable();
755 		while (LL_RCC_HSI_IsReady() != 1) {
756 			/* Wait for HSI ready */
757 		}
758 	}
759 
760 	/* Set HSI as SYSCLCK source */
761 	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
762 	while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) {
763 	}
764 }
765 
766 __unused
767 static int set_up_plls(void)
768 {
769 #if defined(STM32_PLL_ENABLED) || defined(STM32_PLL2_ENABLED) || defined(STM32_PLL3_ENABLED)
770 	int r;
771 	uint32_t vco_input_range;
772 	uint32_t vco_output_range;
773 
774 	/*
775 	 * Case of chain-loaded applications:
776 	 * Switch to HSI and disable the PLL before configuration.
777 	 * (Switching to HSI makes sure we have a SYSCLK source in
778 	 * case we're currently running from the PLL we're about to
779 	 * turn off and reconfigure.)
780 	 *
781 	 */
782 	if (LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
783 		stm32_clock_switch_to_hsi();
784 		LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
785 	}
786 
787 #if defined(CONFIG_STM32_MEMMAP) && defined(CONFIG_BOOTLOADER_MCUBOOT)
788 	/*
789 	 * Don't disable PLL during application initialization
790 	 * that runs in memmap mode when (Q/O)SPI uses PLL
791 	 * as its clock source.
792 	 */
793 #if defined(OCTOSPI1) || defined(OCTOSPI2)
794 	if (LL_RCC_GetOSPIClockSource(LL_RCC_OSPI_CLKSOURCE) != LL_RCC_OSPI_CLKSOURCE_PLL1Q) {
795 		LL_RCC_PLL1_Disable();
796 	}
797 	if (LL_RCC_GetOSPIClockSource(LL_RCC_OSPI_CLKSOURCE) != LL_RCC_OSPI_CLKSOURCE_PLL2R) {
798 		LL_RCC_PLL2_Disable();
799 	}
800 #elif defined(QUADSPI)
801 	if (LL_RCC_GetQSPIClockSource(LL_RCC_QSPI_CLKSOURCE) != LL_RCC_QSPI_CLKSOURCE_PLL1Q) {
802 		LL_RCC_PLL1_Disable();
803 	}
804 	if (LL_RCC_GetQSPIClockSource(LL_RCC_QSPI_CLKSOURCE) != LL_RCC_QSPI_CLKSOURCE_PLL2R) {
805 		LL_RCC_PLL2_Disable();
806 	}
807 #else
808 	LL_RCC_PLL1_Disable();
809 	LL_RCC_PLL2_Disable();
810 #endif
811 #else
812 	LL_RCC_PLL1_Disable();
813 	LL_RCC_PLL2_Disable();
814 #endif
815 	LL_RCC_PLL3_Disable();
816 
817 	/* Configure PLL source */
818 
819 	/* Can be HSE , HSI 64Mhz/HSIDIV, CSI 4MHz*/
820 	if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
821 		/* Main PLL configuration and activation */
822 		LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);
823 	} else if (IS_ENABLED(STM32_PLL_SRC_CSI)) {
824 		/* Main PLL configuration and activation */
825 		LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_CSI);
826 	} else if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
827 		/* Main PLL configuration and activation */
828 		LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
829 	} else {
830 		return -ENOTSUP;
831 	}
832 
833 #if defined(STM32_PLL_ENABLED)
834 	r = get_vco_input_range(STM32_PLL_M_DIVISOR, &vco_input_range);
835 	if (r < 0) {
836 		return r;
837 	}
838 
839 	vco_output_range = get_vco_output_range(vco_input_range);
840 
841 	LL_RCC_PLL1_SetM(STM32_PLL_M_DIVISOR);
842 
843 	LL_RCC_PLL1_SetVCOInputRange(vco_input_range);
844 	LL_RCC_PLL1_SetVCOOutputRange(vco_output_range);
845 
846 	LL_RCC_PLL1_SetN(STM32_PLL_N_MULTIPLIER);
847 
848 	LL_RCC_PLL1FRACN_Disable();
849 	if (IS_ENABLED(STM32_PLL_FRACN_ENABLED)) {
850 		LL_RCC_PLL1_SetFRACN(STM32_PLL_FRACN_VALUE);
851 		LL_RCC_PLL1FRACN_Enable();
852 	}
853 
854 	if (IS_ENABLED(STM32_PLL_P_ENABLED)) {
855 		LL_RCC_PLL1_SetP(STM32_PLL_P_DIVISOR);
856 		LL_RCC_PLL1P_Enable();
857 	}
858 
859 	if (IS_ENABLED(STM32_PLL_Q_ENABLED)) {
860 		LL_RCC_PLL1_SetQ(STM32_PLL_Q_DIVISOR);
861 		LL_RCC_PLL1Q_Enable();
862 	}
863 
864 	if (IS_ENABLED(STM32_PLL_R_ENABLED)) {
865 		LL_RCC_PLL1_SetR(STM32_PLL_R_DIVISOR);
866 		LL_RCC_PLL1R_Enable();
867 	}
868 
869 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
870 	if (IS_ENABLED(STM32_PLL_S_ENABLED)) {
871 		LL_RCC_PLL1_SetS(STM32_PLL_S_DIVISOR);
872 		LL_RCC_PLL1S_Enable();
873 	}
874 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
875 	LL_RCC_PLL1_Enable();
876 	while (LL_RCC_PLL1_IsReady() != 1U) {
877 	}
878 
879 #endif /* STM32_PLL_ENABLED */
880 
881 #if defined(STM32_PLL2_ENABLED)
882 	r = get_vco_input_range(STM32_PLL2_M_DIVISOR, &vco_input_range);
883 	if (r < 0) {
884 		return r;
885 	}
886 
887 	vco_output_range = get_vco_output_range(vco_input_range);
888 
889 	LL_RCC_PLL2_SetM(STM32_PLL2_M_DIVISOR);
890 
891 	LL_RCC_PLL2_SetVCOInputRange(vco_input_range);
892 	LL_RCC_PLL2_SetVCOOutputRange(vco_output_range);
893 
894 	LL_RCC_PLL2_SetN(STM32_PLL2_N_MULTIPLIER);
895 
896 	LL_RCC_PLL2FRACN_Disable();
897 	if (IS_ENABLED(STM32_PLL2_FRACN_ENABLED)) {
898 		LL_RCC_PLL2_SetFRACN(STM32_PLL2_FRACN_VALUE);
899 		LL_RCC_PLL2FRACN_Enable();
900 	}
901 
902 	if (IS_ENABLED(STM32_PLL2_P_ENABLED)) {
903 		LL_RCC_PLL2_SetP(STM32_PLL2_P_DIVISOR);
904 		LL_RCC_PLL2P_Enable();
905 	}
906 
907 	if (IS_ENABLED(STM32_PLL2_Q_ENABLED)) {
908 		LL_RCC_PLL2_SetQ(STM32_PLL2_Q_DIVISOR);
909 		LL_RCC_PLL2Q_Enable();
910 	}
911 
912 	if (IS_ENABLED(STM32_PLL2_R_ENABLED)) {
913 		LL_RCC_PLL2_SetR(STM32_PLL2_R_DIVISOR);
914 		LL_RCC_PLL2R_Enable();
915 	}
916 
917 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
918 	if (IS_ENABLED(STM32_PLL2_S_ENABLED)) {
919 		LL_RCC_PLL2_SetS(STM32_PLL2_S_DIVISOR);
920 		LL_RCC_PLL2S_Enable();
921 	}
922 
923 	if (IS_ENABLED(STM32_PLL2_T_ENABLED)) {
924 		LL_RCC_PLL2_SetT(STM32_PLL2_T_DIVISOR);
925 		LL_RCC_PLL2T_Enable();
926 	}
927 
928 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
929 	LL_RCC_PLL2_Enable();
930 	while (LL_RCC_PLL2_IsReady() != 1U) {
931 	}
932 
933 #endif /* STM32_PLL2_ENABLED */
934 
935 #if defined(STM32_PLL3_ENABLED)
936 	r = get_vco_input_range(STM32_PLL3_M_DIVISOR, &vco_input_range);
937 	if (r < 0) {
938 		return r;
939 	}
940 
941 	vco_output_range = get_vco_output_range(vco_input_range);
942 
943 	LL_RCC_PLL3_SetM(STM32_PLL3_M_DIVISOR);
944 
945 	LL_RCC_PLL3_SetVCOInputRange(vco_input_range);
946 	LL_RCC_PLL3_SetVCOOutputRange(vco_output_range);
947 
948 	LL_RCC_PLL3_SetN(STM32_PLL3_N_MULTIPLIER);
949 
950 	LL_RCC_PLL3FRACN_Disable();
951 	if (IS_ENABLED(STM32_PLL3_FRACN_ENABLED)) {
952 		LL_RCC_PLL3_SetFRACN(STM32_PLL3_FRACN_VALUE);
953 		LL_RCC_PLL3FRACN_Enable();
954 	}
955 
956 	if (IS_ENABLED(STM32_PLL3_P_ENABLED)) {
957 		LL_RCC_PLL3_SetP(STM32_PLL3_P_DIVISOR);
958 		LL_RCC_PLL3P_Enable();
959 	}
960 
961 	if (IS_ENABLED(STM32_PLL3_Q_ENABLED)) {
962 		LL_RCC_PLL3_SetQ(STM32_PLL3_Q_DIVISOR);
963 		LL_RCC_PLL3Q_Enable();
964 	}
965 
966 	if (IS_ENABLED(STM32_PLL3_R_ENABLED)) {
967 		LL_RCC_PLL3_SetR(STM32_PLL3_R_DIVISOR);
968 		LL_RCC_PLL3R_Enable();
969 	}
970 
971 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
972 	if (IS_ENABLED(STM32_PLL3_S_ENABLED)) {
973 		LL_RCC_PLL3_SetS(STM32_PLL3_S_DIVISOR);
974 		LL_RCC_PLL3S_Enable();
975 	}
976 
977 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
978 	LL_RCC_PLL3_Enable();
979 	while (LL_RCC_PLL3_IsReady() != 1U) {
980 	}
981 
982 #endif /* STM32_PLL3_ENABLED */
983 
984 #else
985 	/* Init PLL source to None */
986 	LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_NONE);
987 
988 #endif /* STM32_PLL_ENABLED || STM32_PLL2_ENABLED || STM32_PLL3_ENABLED */
989 
990 	return 0;
991 }
992 
993 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
994 /*  adapted from the stm32cube SystemCoreClockUpdate*/
995 void stm32_system_clock_update(void)
996 {
997 	uint32_t sysclk, hsivalue, pllsource, pllm, pllp, core_presc;
998 	float_t pllfracn, pllvco;
999 
1000 	/* Get SYSCLK source */
1001 	switch (RCC->CFGR & RCC_CFGR_SWS) {
1002 	case 0x00: /* HSI used as system clock source (default after reset) */
1003 		sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV)
1004 			>> RCC_CR_HSIDIV_Pos));
1005 		break;
1006 
1007 	case 0x08: /* CSI used as system clock source */
1008 		sysclk = CSI_VALUE;
1009 		break;
1010 
1011 	case 0x10: /* HSE used as system clock source */
1012 		sysclk = HSE_VALUE;
1013 		break;
1014 
1015 	case 0x18:  /* PLL1 used as system clock  source */
1016 		/*
1017 		 * PLL1_VCO = (HSE_VALUE or HSI_VALUE or CSI_VALUE/ PLLM) * PLLN
1018 		 * SYSCLK = PLL1_VCO / PLL1R
1019 		 */
1020 		pllsource = (RCC->PLLCKSELR & RCC_PLLCKSELR_PLLSRC);
1021 		pllm = ((RCC->PLLCKSELR & RCC_PLLCKSELR_DIVM1) >> RCC_PLLCKSELR_DIVM1_Pos);
1022 
1023 		if ((RCC->PLLCFGR & RCC_PLLCFGR_PLL1FRACEN) != 0U) {
1024 			pllfracn = (float_t)(uint32_t)(((RCC->PLL1FRACR & RCC_PLL1FRACR_FRACN)
1025 			>> RCC_PLL1FRACR_FRACN_Pos));
1026 		} else {
1027 			pllfracn = (float_t)0U;
1028 		}
1029 
1030 		if (pllm != 0U) {
1031 			switch (pllsource) {
1032 			case 0x02: /* HSE used as PLL1 clock source */
1033 				pllvco = ((float_t)HSE_VALUE / (float_t)pllm) *
1034 					((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
1035 					(pllfracn/(float_t)0x2000) + (float_t)1);
1036 				break;
1037 
1038 			case 0x01: /* CSI used as PLL1 clock source */
1039 				pllvco = ((float_t)CSI_VALUE / (float_t)pllm) *
1040 				((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
1041 				(pllfracn/(float_t)0x2000) + (float_t)1);
1042 				break;
1043 
1044 			case 0x00: /* HSI used as PLL1 clock source */
1045 			default:
1046 				hsivalue = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >>
1047 					RCC_CR_HSIDIV_Pos));
1048 				pllvco = ((float_t)hsivalue / (float_t)pllm) *
1049 					((float_t)(uint32_t)(RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVN) +
1050 					(pllfracn/(float_t)0x2000) + (float_t)1);
1051 				break;
1052 			}
1053 
1054 			pllp = (((RCC->PLL1DIVR1 & RCC_PLL1DIVR1_DIVP) >>
1055 				RCC_PLL1DIVR1_DIVP_Pos) + 1U);
1056 			sysclk =  (uint32_t)(float_t)(pllvco/(float_t)pllp);
1057 		} else {
1058 			sysclk = 0U;
1059 		}
1060 		break;
1061 
1062 	default: /* Unexpected, default to HSI used as system clk source (default after reset) */
1063 		sysclk = (HSI_VALUE >> ((RCC->CR & RCC_CR_HSIDIV) >> RCC_CR_HSIDIV_Pos));
1064 		break;
1065 	}
1066 
1067 	/* system clock frequency : CM7 CPU frequency  */
1068 	core_presc = (RCC->CDCFGR & RCC_CDCFGR_CPRE);
1069 
1070 	if (core_presc >= 8U) {
1071 		SystemCoreClock = (sysclk >> (core_presc - RCC_CDCFGR_CPRE_3 + 1U));
1072 	} else {
1073 		SystemCoreClock = sysclk;
1074 	}
1075 }
1076 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
1077 
1078 int stm32_clock_control_init(const struct device *dev)
1079 {
1080 	int r = 0;
1081 
1082 #if defined(CONFIG_CPU_CORTEX_M7)
1083 	uint32_t old_hclk_freq;
1084 	uint32_t new_hclk_freq;
1085 
1086 	/* HW semaphore Clock enable */
1087 #if defined(CONFIG_SOC_STM32H7A3XX) || defined(CONFIG_SOC_STM32H7A3XXQ) || \
1088 	defined(CONFIG_SOC_STM32H7B0XX) || defined(CONFIG_SOC_STM32H7B0XXQ) || \
1089 	defined(CONFIG_SOC_STM32H7B3XX) || defined(CONFIG_SOC_STM32H7B3XXQ)
1090 	LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_HSEM);
1091 #elif !defined(CONFIG_SOC_SERIES_STM32H7RSX)
1092 	/* The stm32h7RS serie has no HSEM peripheral */
1093 	LL_AHB4_GRP1_EnableClock(LL_AHB4_GRP1_PERIPH_HSEM);
1094 #endif
1095 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
1096 
1097 	/* Set up individual enabled clocks */
1098 	set_up_fixed_clock_sources();
1099 
1100 	/* Set up PLLs */
1101 	r = set_up_plls();
1102 	if (r < 0) {
1103 		return r;
1104 	}
1105 
1106 	/* Configure Voltage scale to comply with the desired system frequency */
1107 	prepare_regulator_voltage_scale();
1108 
1109 	/* Current hclk value */
1110 	old_hclk_freq = get_hclk_frequency();
1111 	/* AHB is HCLK clock to configure */
1112 	new_hclk_freq = get_bus_clock(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC,
1113 				      STM32_HPRE);
1114 
1115 	/* Set flash latency */
1116 
1117 	/* AHB/AXI/HCLK clock is SYSCLK / HPRE */
1118 	/* If freq increases, set flash latency before any clock setting */
1119 	if (new_hclk_freq > old_hclk_freq) {
1120 		LL_SetFlashLatency(new_hclk_freq);
1121 	}
1122 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
1123 	/*
1124 	 * The default Flash latency is 3 WS which is not enough,
1125 	 * set higher and correct later if needed
1126 	 */
1127 	LL_FLASH_SetLatency(LL_FLASH_LATENCY_6);
1128 #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
1129 
1130 	/* Preset the prescalers prior to choosing SYSCLK */
1131 	/* Prevents APB clock to go over limits */
1132 	/* Set buses (Sys,AHB, APB1, APB2 & APB4) prescalers */
1133 	LL_RCC_SetSysPrescaler(sysclk_prescaler(STM32_D1CPRE));
1134 	LL_RCC_SetAHBPrescaler(ahb_prescaler(STM32_HPRE));
1135 #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
1136 	LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_PPRE1));
1137 	LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_PPRE2));
1138 	LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_PPRE4));
1139 	LL_RCC_SetAPB5Prescaler(apb5_prescaler(STM32_PPRE5));
1140 
1141 #else
1142 	LL_RCC_SetAPB1Prescaler(apb1_prescaler(STM32_D2PPRE1));
1143 	LL_RCC_SetAPB2Prescaler(apb2_prescaler(STM32_D2PPRE2));
1144 	LL_RCC_SetAPB3Prescaler(apb3_prescaler(STM32_D1PPRE));
1145 	LL_RCC_SetAPB4Prescaler(apb4_prescaler(STM32_D3PPRE));
1146 
1147 #endif
1148 	/* Set up sys clock */
1149 	if (IS_ENABLED(STM32_SYSCLK_SRC_PLL)) {
1150 		/* Set PLL1 as System Clock Source */
1151 		LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
1152 		while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1) {
1153 		}
1154 	} else if (IS_ENABLED(STM32_SYSCLK_SRC_HSE)) {
1155 		/* Set sysclk source to HSE */
1156 		LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
1157 		while (LL_RCC_GetSysClkSource() !=
1158 					LL_RCC_SYS_CLKSOURCE_STATUS_HSE) {
1159 		}
1160 	} else if (IS_ENABLED(STM32_SYSCLK_SRC_HSI)) {
1161 		/* Set sysclk source to HSI */
1162 		stm32_clock_switch_to_hsi();
1163 	} else if (IS_ENABLED(STM32_SYSCLK_SRC_CSI)) {
1164 		/* Set sysclk source to CSI */
1165 		LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_CSI);
1166 		while (LL_RCC_GetSysClkSource() !=
1167 					LL_RCC_SYS_CLKSOURCE_STATUS_CSI) {
1168 		}
1169 	} else {
1170 		return -ENOTSUP;
1171 	}
1172 
1173 	/* Set FLASH latency */
1174 	/* AHB/AXI/HCLK clock is SYSCLK / HPRE */
1175 	/* If freq not increased, set flash latency after all clock setting */
1176 	if (new_hclk_freq <= old_hclk_freq) {
1177 		LL_SetFlashLatency(new_hclk_freq);
1178 	}
1179 
1180 	optimize_regulator_voltage_scale(CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC);
1181 
1182 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
1183 #endif /* CONFIG_CPU_CORTEX_M7 */
1184 
1185 	ARG_UNUSED(dev);
1186 
1187 	/* Update CMSIS variable */
1188 	SystemCoreClock = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC;
1189 
1190 	return r;
1191 }
1192 
1193 #if defined(STM32_HSE_CSS)
1194 void __weak stm32_hse_css_callback(void) {}
1195 
1196 /* Called by the HAL in response to an HSE CSS interrupt */
1197 void HAL_RCC_CSSCallback(void)
1198 {
1199 	stm32_hse_css_callback();
1200 }
1201 #endif
1202 
1203 /**
1204  * @brief RCC device, note that priority is intentionally set to 1 so
1205  * that the device init runs just after SOC init
1206  */
1207 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
1208 		    stm32_clock_control_init,
1209 		    NULL,
1210 		    NULL, NULL,
1211 		    PRE_KERNEL_1,
1212 		    CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
1213 		    &stm32_clock_control_api);
1214