1 /*
2  *
3  * Copyright (c) 2017 Linaro Limited.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 
9 #include <soc.h>
10 #include <stm32_ll_bus.h>
11 #include <stm32_ll_pwr.h>
12 #include <stm32_ll_rcc.h>
13 #include <stm32_ll_utils.h>
14 #include <zephyr/drivers/clock_control.h>
15 #include <zephyr/sys/util.h>
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include <zephyr/sys/time_units.h>
18 #include "clock_stm32_ll_common.h"
19 
20 #if defined(STM32_PLL_ENABLED)
21 
22 #if defined(LL_RCC_MSIRANGESEL_RUN)
23 #define CALC_RUN_MSI_FREQ(range) __LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, \
24 							range << RCC_CR_MSIRANGE_Pos);
25 #else
26 #define CALC_RUN_MSI_FREQ(range) __LL_RCC_CALC_MSI_FREQ(range << RCC_CR_MSIRANGE_Pos);
27 #endif
28 
29 /**
30  * @brief Return PLL source
31  */
32 __unused
get_pll_source(void)33 static uint32_t get_pll_source(void)
34 {
35 	/* Configure PLL source */
36 	if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
37 		return LL_RCC_PLLSOURCE_HSI;
38 	} else if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
39 		return LL_RCC_PLLSOURCE_HSE;
40 	} else if (IS_ENABLED(STM32_PLL_SRC_MSI)) {
41 		return LL_RCC_PLLSOURCE_MSI;
42 	}
43 
44 	__ASSERT(0, "Invalid source");
45 	return 0;
46 }
47 
48 /**
49  * @brief get the pll source frequency
50  */
51 __unused
get_pllsrc_frequency(void)52 uint32_t get_pllsrc_frequency(void)
53 {
54 	if (IS_ENABLED(STM32_PLL_SRC_HSI)) {
55 		return STM32_HSI_FREQ;
56 	} else if (IS_ENABLED(STM32_PLL_SRC_HSE)) {
57 		return STM32_HSE_FREQ;
58 #if defined(STM32_MSI_ENABLED)
59 	} else if (IS_ENABLED(STM32_PLL_SRC_MSI)) {
60 		return CALC_RUN_MSI_FREQ(STM32_MSI_RANGE);
61 #endif
62 	}
63 
64 	__ASSERT(0, "Invalid source");
65 	return 0;
66 }
67 
68 /**
69  * @brief Set up pll configuration
70  */
config_pll_sysclock(void)71 void config_pll_sysclock(void)
72 {
73 #ifdef PWR_CR5_R1MODE
74 	/* set power boost mode for sys clock greater than 80MHz */
75 	if (sys_clock_hw_cycles_per_sec() >= MHZ(80)) {
76 		LL_PWR_EnableRange1BoostMode();
77 	}
78 #endif /* PWR_CR5_R1MODE */
79 
80 	LL_RCC_PLL_ConfigDomain_SYS(get_pll_source(),
81 				    pllm(STM32_PLL_M_DIVISOR),
82 				    STM32_PLL_N_MULTIPLIER,
83 				    pllr(STM32_PLL_R_DIVISOR));
84 
85 	LL_RCC_PLL_EnableDomain_SYS();
86 }
87 
88 #endif /* defined(STM32_PLL_ENABLED) */
89 
90 /**
91  * @brief Activate default clocks
92  */
config_enable_default_clocks(void)93 void config_enable_default_clocks(void)
94 {
95 #ifdef LL_APB1_GRP1_PERIPH_PWR
96 	/* Enable the power interface clock */
97 	LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
98 #endif
99 #if defined(CONFIG_SOC_SERIES_STM32WBX)
100 	/* HW semaphore Clock enable */
101 	LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_HSEM);
102 #endif
103 }
104