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