Line data Source code
1 0 : /*
2 : * Copyright (c) 2016 Open-RnD Sp. z o.o.
3 : * Copyright (c) 2016 BayLibre, SAS
4 : * Copyright (c) 2017-2022 Linaro Limited.
5 : * Copyright (c) 2017 RnDity Sp. z o.o.
6 : * Copyright (c) 2023 STMicroelectronics
7 : *
8 : * SPDX-License-Identifier: Apache-2.0
9 : */
10 : #ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_STM32_CLOCK_CONTROL_H_
11 : #define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_STM32_CLOCK_CONTROL_H_
12 :
13 : #include <zephyr/drivers/clock_control.h>
14 :
15 : #if defined(CONFIG_SOC_SERIES_STM32C0X)
16 : #include <zephyr/dt-bindings/clock/stm32c0_clock.h>
17 : #elif defined(CONFIG_SOC_SERIES_STM32F0X)
18 : #include <zephyr/dt-bindings/clock/stm32f0_clock.h>
19 : #elif defined(CONFIG_SOC_SERIES_STM32F1X)
20 : #if defined(CONFIG_SOC_STM32F10X_CONNECTIVITY_LINE_DEVICE)
21 : #include <zephyr/dt-bindings/clock/stm32f10x_clock.h>
22 : #else
23 : #include <zephyr/dt-bindings/clock/stm32f1_clock.h>
24 : #endif
25 : #elif defined(CONFIG_SOC_SERIES_STM32F3X)
26 : #include <zephyr/dt-bindings/clock/stm32f3_clock.h>
27 : #elif defined(CONFIG_SOC_SERIES_STM32F2X) || \
28 : defined(CONFIG_SOC_SERIES_STM32F4X)
29 : #include <zephyr/dt-bindings/clock/stm32f4_clock.h>
30 : #include <zephyr/dt-bindings/clock/stm32f410_clock.h>
31 : #elif defined(CONFIG_SOC_SERIES_STM32F7X)
32 : #include <zephyr/dt-bindings/clock/stm32f7_clock.h>
33 : #elif defined(CONFIG_SOC_SERIES_STM32G0X)
34 : #include <zephyr/dt-bindings/clock/stm32g0_clock.h>
35 : #elif defined(CONFIG_SOC_SERIES_STM32G4X)
36 : #include <zephyr/dt-bindings/clock/stm32g4_clock.h>
37 : #elif defined(CONFIG_SOC_SERIES_STM32L0X)
38 : #include <zephyr/dt-bindings/clock/stm32l0_clock.h>
39 : #elif defined(CONFIG_SOC_SERIES_STM32L1X)
40 : #include <zephyr/dt-bindings/clock/stm32l1_clock.h>
41 : #elif defined(CONFIG_SOC_SERIES_STM32L4X) || \
42 : defined(CONFIG_SOC_SERIES_STM32L5X)
43 : #include <zephyr/dt-bindings/clock/stm32l4_clock.h>
44 : #elif defined(CONFIG_SOC_SERIES_STM32WBX)
45 : #include <zephyr/dt-bindings/clock/stm32wb_clock.h>
46 : #elif defined(CONFIG_SOC_SERIES_STM32WB0X)
47 : #include <zephyr/dt-bindings/clock/stm32wb0_clock.h>
48 : #elif defined(CONFIG_SOC_SERIES_STM32WLX)
49 : #include <zephyr/dt-bindings/clock/stm32wl_clock.h>
50 : #elif defined(CONFIG_SOC_SERIES_STM32H5X)
51 : #include <zephyr/dt-bindings/clock/stm32h5_clock.h>
52 : #elif defined(CONFIG_SOC_SERIES_STM32H7X)
53 : #include <zephyr/dt-bindings/clock/stm32h7_clock.h>
54 : #elif defined(CONFIG_SOC_SERIES_STM32H7RSX)
55 : #include <zephyr/dt-bindings/clock/stm32h7rs_clock.h>
56 : #elif defined(CONFIG_SOC_SERIES_STM32U0X)
57 : #include <zephyr/dt-bindings/clock/stm32u0_clock.h>
58 : #elif defined(CONFIG_SOC_SERIES_STM32U5X)
59 : #include <zephyr/dt-bindings/clock/stm32u5_clock.h>
60 : #elif defined(CONFIG_SOC_SERIES_STM32WBAX)
61 : #include <zephyr/dt-bindings/clock/stm32wba_clock.h>
62 : #else
63 : #include <zephyr/dt-bindings/clock/stm32_clock.h>
64 : #endif
65 :
66 : /** Common clock control device node for all STM32 chips */
67 1 : #define STM32_CLOCK_CONTROL_NODE DT_NODELABEL(rcc)
68 :
69 : /** RCC node related symbols */
70 :
71 1 : #define STM32_AHB_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb_prescaler)
72 0 : #define STM32_APB1_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb1_prescaler)
73 0 : #define STM32_APB2_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb2_prescaler)
74 0 : #define STM32_APB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb3_prescaler)
75 0 : #define STM32_APB5_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb5_prescaler)
76 0 : #define STM32_APB7_PRESCALER DT_PROP(DT_NODELABEL(rcc), apb7_prescaler)
77 0 : #define STM32_AHB3_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
78 0 : #define STM32_AHB4_PRESCALER DT_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
79 0 : #define STM32_AHB5_PRESCALER DT_PROP_OR(DT_NODELABEL(rcc), ahb5_prescaler, 1)
80 0 : #define STM32_CPU1_PRESCALER DT_PROP(DT_NODELABEL(rcc), cpu1_prescaler)
81 0 : #define STM32_CPU2_PRESCALER DT_PROP(DT_NODELABEL(rcc), cpu2_prescaler)
82 :
83 : #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb_prescaler)
84 : #define STM32_CORE_PRESCALER STM32_AHB_PRESCALER
85 : #elif DT_NODE_HAS_PROP(DT_NODELABEL(rcc), cpu1_prescaler)
86 : #define STM32_CORE_PRESCALER STM32_CPU1_PRESCALER
87 : #endif
88 :
89 : #if DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb3_prescaler)
90 : #define STM32_FLASH_PRESCALER STM32_AHB3_PRESCALER
91 : #elif DT_NODE_HAS_PROP(DT_NODELABEL(rcc), ahb4_prescaler)
92 : #define STM32_FLASH_PRESCALER STM32_AHB4_PRESCALER
93 : #else
94 0 : #define STM32_FLASH_PRESCALER STM32_CORE_PRESCALER
95 : #endif
96 :
97 0 : #define STM32_ADC_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc_prescaler)
98 0 : #define STM32_ADC12_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc12_prescaler)
99 0 : #define STM32_ADC34_PRESCALER DT_PROP(DT_NODELABEL(rcc), adc34_prescaler)
100 :
101 : /** STM2H7RS specific RCC dividers */
102 : #if defined(CONFIG_SOC_SERIES_STM32H7RSX)
103 : #define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), dcpre)
104 : #define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre)
105 : #define STM32_PPRE1 DT_PROP(DT_NODELABEL(rcc), ppre1)
106 : #define STM32_PPRE2 DT_PROP(DT_NODELABEL(rcc), ppre2)
107 : #define STM32_PPRE4 DT_PROP(DT_NODELABEL(rcc), ppre4)
108 : #define STM32_PPRE5 DT_PROP(DT_NODELABEL(rcc), ppre5)
109 : #else
110 1 : #define STM32_D1CPRE DT_PROP(DT_NODELABEL(rcc), d1cpre)
111 0 : #define STM32_HPRE DT_PROP(DT_NODELABEL(rcc), hpre)
112 0 : #define STM32_D2PPRE1 DT_PROP(DT_NODELABEL(rcc), d2ppre1)
113 0 : #define STM32_D2PPRE2 DT_PROP(DT_NODELABEL(rcc), d2ppre2)
114 0 : #define STM32_D1PPRE DT_PROP(DT_NODELABEL(rcc), d1ppre)
115 0 : #define STM32_D3PPRE DT_PROP(DT_NODELABEL(rcc), d3ppre)
116 : #endif /* CONFIG_SOC_SERIES_STM32H7RSX */
117 :
118 : /** STM2WBA specifics RCC dividers */
119 1 : #define STM32_AHB5_DIV DT_PROP(DT_NODELABEL(rcc), ahb5_div)
120 :
121 0 : #define DT_RCC_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(rcc))
122 :
123 : /* To enable use of IS_ENABLED utility macro, these symbols
124 : * should not be defined directly using DT_SAME_NODE.
125 : */
126 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(pll))
127 : #define STM32_SYSCLK_SRC_PLL 1
128 : #endif
129 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
130 : #define STM32_SYSCLK_SRC_HSI 1
131 : #endif
132 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
133 : #define STM32_SYSCLK_SRC_HSE 1
134 : #endif
135 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_msi))
136 : #define STM32_SYSCLK_SRC_MSI 1
137 : #endif
138 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_msis))
139 : #define STM32_SYSCLK_SRC_MSIS 1
140 : #endif
141 : #if DT_SAME_NODE(DT_RCC_CLOCKS_CTRL, DT_NODELABEL(clk_csi))
142 : #define STM32_SYSCLK_SRC_CSI 1
143 : #endif
144 :
145 :
146 : /** PLL node related symbols */
147 :
148 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f2_pll_clock, okay) || \
149 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f4_pll_clock, okay) || \
150 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f7_pll_clock, okay) || \
151 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32g0_pll_clock, okay) || \
152 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32g4_pll_clock, okay) || \
153 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32l4_pll_clock, okay) || \
154 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32u0_pll_clock, okay) || \
155 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32u5_pll_clock, okay) || \
156 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wb_pll_clock, okay) || \
157 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32wba_pll_clock, okay) || \
158 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7_pll_clock, okay) || \
159 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32h7rs_pll_clock, okay)
160 : #define STM32_PLL_ENABLED 1
161 : #define STM32_PLL_M_DIVISOR DT_PROP(DT_NODELABEL(pll), div_m)
162 : #define STM32_PLL_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul_n)
163 : #define STM32_PLL_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_p)
164 : #define STM32_PLL_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_p, 1)
165 : #define STM32_PLL_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_q)
166 : #define STM32_PLL_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_q, 1)
167 : #define STM32_PLL_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_r)
168 : #define STM32_PLL_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_r, 1)
169 : #define STM32_PLL_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), div_s)
170 : #define STM32_PLL_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll), div_s, 1)
171 : #define STM32_PLL_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll), fracn)
172 : #define STM32_PLL_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll), fracn, 1)
173 : #endif
174 :
175 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f4_plli2s_clock, okay)
176 : #define STM32_PLLI2S_ENABLED 1
177 : #define STM32_PLLI2S_M_DIVISOR STM32_PLL_M_DIVISOR
178 : #define STM32_PLLI2S_N_MULTIPLIER DT_PROP(DT_NODELABEL(plli2s), mul_n)
179 : #define STM32_PLLI2S_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_r)
180 : #define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1)
181 : #endif
182 :
183 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(plli2s), st_stm32f412_plli2s_clock, okay)
184 : #define STM32_PLLI2S_ENABLED 1
185 : #define STM32_PLLI2S_M_DIVISOR DT_PROP(DT_NODELABEL(plli2s), div_m)
186 : #define STM32_PLLI2S_N_MULTIPLIER DT_PROP(DT_NODELABEL(plli2s), mul_n)
187 : #define STM32_PLLI2S_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_q)
188 : #define STM32_PLLI2S_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_q, 1)
189 : #define STM32_PLLI2S_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(plli2s), div_r)
190 : #define STM32_PLLI2S_R_DIVISOR DT_PROP_OR(DT_NODELABEL(plli2s), div_r, 1)
191 : #endif
192 :
193 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32u5_pll_clock, okay) || \
194 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7_pll_clock, okay) || \
195 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32h7rs_pll_clock, okay)
196 : #define STM32_PLL2_ENABLED 1
197 : #define STM32_PLL2_M_DIVISOR DT_PROP(DT_NODELABEL(pll2), div_m)
198 : #define STM32_PLL2_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll2), mul_n)
199 : #define STM32_PLL2_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_p)
200 : #define STM32_PLL2_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_p, 1)
201 : #define STM32_PLL2_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_q)
202 : #define STM32_PLL2_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_q, 1)
203 : #define STM32_PLL2_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_r)
204 : #define STM32_PLL2_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_r, 1)
205 : #define STM32_PLL2_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_s)
206 : #define STM32_PLL2_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_s, 1)
207 : #define STM32_PLL2_T_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), div_t)
208 : #define STM32_PLL2_T_DIVISOR DT_PROP_OR(DT_NODELABEL(pll2), div_t, 1)
209 : #define STM32_PLL2_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll2), fracn)
210 : #define STM32_PLL2_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll2), fracn, 1)
211 : #endif
212 :
213 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7_pll_clock, okay) || \
214 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32u5_pll_clock, okay) || \
215 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll3), st_stm32h7rs_pll_clock, okay)
216 : #define STM32_PLL3_ENABLED 1
217 : #define STM32_PLL3_M_DIVISOR DT_PROP(DT_NODELABEL(pll3), div_m)
218 : #define STM32_PLL3_N_MULTIPLIER DT_PROP(DT_NODELABEL(pll3), mul_n)
219 : #define STM32_PLL3_P_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_p)
220 : #define STM32_PLL3_P_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_p, 1)
221 : #define STM32_PLL3_Q_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_q)
222 : #define STM32_PLL3_Q_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_q, 1)
223 : #define STM32_PLL3_R_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_r)
224 : #define STM32_PLL3_R_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_r, 1)
225 : #define STM32_PLL3_S_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), div_s)
226 : #define STM32_PLL3_S_DIVISOR DT_PROP_OR(DT_NODELABEL(pll3), div_s, 1)
227 : #define STM32_PLL3_FRACN_ENABLED DT_NODE_HAS_PROP(DT_NODELABEL(pll3), fracn)
228 : #define STM32_PLL3_FRACN_VALUE DT_PROP_OR(DT_NODELABEL(pll3), fracn, 1)
229 : #endif
230 :
231 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f1_pll_clock, okay)
232 : #define STM32_PLL_ENABLED 1
233 : #define STM32_PLL_XTPRE DT_PROP(DT_NODELABEL(pll), xtpre)
234 : #define STM32_PLL_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul)
235 : #define STM32_PLL_USBPRE DT_PROP(DT_NODELABEL(pll), usbpre)
236 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f0_pll_clock, okay) || \
237 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f100_pll_clock, okay) || \
238 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32f105_pll_clock, okay)
239 : #define STM32_PLL_ENABLED 1
240 : #define STM32_PLL_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul)
241 : #define STM32_PLL_PREDIV DT_PROP(DT_NODELABEL(pll), prediv)
242 : #define STM32_PLL_USBPRE DT_PROP(DT_NODELABEL(pll), otgfspre)
243 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll), st_stm32l0_pll_clock, okay)
244 : #define STM32_PLL_ENABLED 1
245 : #define STM32_PLL_DIVISOR DT_PROP(DT_NODELABEL(pll), div)
246 : #define STM32_PLL_MULTIPLIER DT_PROP(DT_NODELABEL(pll), mul)
247 : #endif
248 :
249 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(pll2), st_stm32f105_pll2_clock, okay)
250 : #define STM32_PLL2_ENABLED 1
251 : #define STM32_PLL2_MULTIPLIER DT_PROP(DT_NODELABEL(pll2), mul)
252 : #define STM32_PLL2_PREDIV DT_PROP(DT_NODELABEL(pll2), prediv)
253 : #endif
254 :
255 : /** PLL/PLL1 clock source */
256 : #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll)) && \
257 : DT_NODE_HAS_PROP(DT_NODELABEL(pll), clocks)
258 : #define DT_PLL_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll))
259 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_msi))
260 : #define STM32_PLL_SRC_MSI 1
261 : #endif
262 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_msis))
263 : #define STM32_PLL_SRC_MSIS 1
264 : #endif
265 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
266 : #define STM32_PLL_SRC_HSI 1
267 : #endif
268 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_csi))
269 : #define STM32_PLL_SRC_CSI 1
270 : #endif
271 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
272 : #define STM32_PLL_SRC_HSE 1
273 : #endif
274 : #if DT_SAME_NODE(DT_PLL_CLOCKS_CTRL, DT_NODELABEL(pll2))
275 : #define STM32_PLL_SRC_PLL2 1
276 : #endif
277 :
278 : #endif
279 :
280 : /** PLL2 clock source */
281 : #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll2)) && \
282 : DT_NODE_HAS_PROP(DT_NODELABEL(pll2), clocks)
283 : #define DT_PLL2_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll2))
284 : #if DT_SAME_NODE(DT_PLL2_CLOCKS_CTRL, DT_NODELABEL(clk_msis))
285 : #define STM32_PLL2_SRC_MSIS 1
286 : #endif
287 : #if DT_SAME_NODE(DT_PLL2_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
288 : #define STM32_PLL2_SRC_HSI 1
289 : #endif
290 : #if DT_SAME_NODE(DT_PLL2_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
291 : #define STM32_PLL2_SRC_HSE 1
292 : #endif
293 :
294 : #endif
295 :
296 : /** PLL3 clock source */
297 : #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(pll3)) && \
298 : DT_NODE_HAS_PROP(DT_NODELABEL(pll3), clocks)
299 : #define DT_PLL3_CLOCKS_CTRL DT_CLOCKS_CTLR(DT_NODELABEL(pll3))
300 : #if DT_SAME_NODE(DT_PLL3_CLOCKS_CTRL, DT_NODELABEL(clk_msis))
301 : #define STM32_PLL3_SRC_MSIS 1
302 : #endif
303 : #if DT_SAME_NODE(DT_PLL3_CLOCKS_CTRL, DT_NODELABEL(clk_hsi))
304 : #define STM32_PLL3_SRC_HSI 1
305 : #endif
306 : #if DT_SAME_NODE(DT_PLL3_CLOCKS_CTRL, DT_NODELABEL(clk_hse))
307 : #define STM32_PLL3_SRC_HSE 1
308 : #endif
309 :
310 : #endif
311 :
312 :
313 : /** Fixed clocks related symbols */
314 :
315 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_lse), fixed_clock, okay)
316 : #define STM32_LSE_ENABLED 1
317 : #define STM32_LSE_FREQ DT_PROP(DT_NODELABEL(clk_lse), clock_frequency)
318 : #define STM32_LSE_DRIVING 0
319 : #define STM32_LSE_BYPASS DT_PROP(DT_NODELABEL(clk_lse), lse_bypass)
320 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_lse), st_stm32_lse_clock, okay)
321 : #define STM32_LSE_ENABLED 1
322 : #define STM32_LSE_FREQ DT_PROP(DT_NODELABEL(clk_lse), clock_frequency)
323 : #define STM32_LSE_DRIVING DT_PROP(DT_NODELABEL(clk_lse), driving_capability)
324 : #define STM32_LSE_BYPASS DT_PROP(DT_NODELABEL(clk_lse), lse_bypass)
325 : #else
326 1 : #define STM32_LSE_ENABLED 0
327 0 : #define STM32_LSE_FREQ 0
328 0 : #define STM32_LSE_DRIVING 0
329 0 : #define STM32_LSE_BYPASS 0
330 : #endif
331 :
332 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msi), st_stm32_msi_clock, okay) || \
333 : DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msi), st_stm32l0_msi_clock, okay)
334 : #define STM32_MSI_ENABLED 1
335 : #define STM32_MSI_RANGE DT_PROP(DT_NODELABEL(clk_msi), msi_range)
336 : #endif
337 :
338 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msi), st_stm32_msi_clock, okay)
339 : #define STM32_MSI_ENABLED 1
340 : #define STM32_MSI_PLL_MODE DT_PROP(DT_NODELABEL(clk_msi), msi_pll_mode)
341 : #endif
342 :
343 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msis), st_stm32u5_msi_clock, okay)
344 : #define STM32_MSIS_ENABLED 1
345 : #define STM32_MSIS_RANGE DT_PROP(DT_NODELABEL(clk_msis), msi_range)
346 : #define STM32_MSIS_PLL_MODE DT_PROP(DT_NODELABEL(clk_msis), msi_pll_mode)
347 : #else
348 0 : #define STM32_MSIS_ENABLED 0
349 0 : #define STM32_MSIS_RANGE 0
350 0 : #define STM32_MSIS_PLL_MODE 0
351 : #endif
352 :
353 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_msik), st_stm32u5_msi_clock, okay)
354 : #define STM32_MSIK_ENABLED 1
355 : #define STM32_MSIK_RANGE DT_PROP(DT_NODELABEL(clk_msik), msi_range)
356 : #define STM32_MSIK_PLL_MODE DT_PROP(DT_NODELABEL(clk_msik), msi_pll_mode)
357 : #else
358 0 : #define STM32_MSIK_ENABLED 0
359 0 : #define STM32_MSIK_RANGE 0
360 0 : #define STM32_MSIK_PLL_MODE 0
361 : #endif
362 :
363 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_csi), fixed_clock, okay)
364 : #define STM32_CSI_ENABLED 1
365 : #define STM32_CSI_FREQ DT_PROP(DT_NODELABEL(clk_csi), clock_frequency)
366 : #else
367 0 : #define STM32_CSI_FREQ 0
368 : #endif
369 :
370 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_lsi), fixed_clock, okay)
371 : #define STM32_LSI_ENABLED 1
372 : #define STM32_LSI_FREQ DT_PROP(DT_NODELABEL(clk_lsi), clock_frequency)
373 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_lsi1), fixed_clock, okay)
374 : #define STM32_LSI_ENABLED 1
375 : #define STM32_LSI_FREQ DT_PROP(DT_NODELABEL(clk_lsi1), clock_frequency)
376 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_lsi2), fixed_clock, okay)
377 : #define STM32_LSI_ENABLED 1
378 : #define STM32_LSI_FREQ DT_PROP(DT_NODELABEL(clk_lsi2), clock_frequency)
379 : #else
380 0 : #define STM32_LSI_FREQ 0
381 : #endif
382 :
383 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), fixed_clock, okay)
384 : #define STM32_HSI_DIV_ENABLED 0
385 : #define STM32_HSI_ENABLED 1
386 : #define STM32_HSI_FREQ DT_PROP(DT_NODELABEL(clk_hsi), clock_frequency)
387 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), st_stm32h7_hsi_clock, okay) \
388 : || DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), st_stm32g0_hsi_clock, okay) \
389 : || DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi), st_stm32c0_hsi_clock, okay)
390 : #define STM32_HSI_DIV_ENABLED 1
391 : #define STM32_HSI_ENABLED 1
392 : #define STM32_HSI_DIVISOR DT_PROP(DT_NODELABEL(clk_hsi), hsi_div)
393 : #define STM32_HSI_FREQ DT_PROP(DT_NODELABEL(clk_hsi), clock_frequency)
394 : #else
395 0 : #define STM32_HSI_DIV_ENABLED 0
396 0 : #define STM32_HSI_DIVISOR 1
397 0 : #define STM32_HSI_FREQ 0
398 : #endif
399 :
400 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), fixed_clock, okay)
401 : #define STM32_HSE_ENABLED 1
402 : #define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency)
403 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), st_stm32_hse_clock, okay)
404 : #define STM32_HSE_ENABLED 1
405 : #define STM32_HSE_BYPASS DT_PROP(DT_NODELABEL(clk_hse), hse_bypass)
406 : #define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency)
407 : #define STM32_HSE_CSS DT_PROP(DT_NODELABEL(clk_hse), css_enabled)
408 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), st_stm32wl_hse_clock, okay)
409 : #define STM32_HSE_ENABLED 1
410 : #define STM32_HSE_TCXO DT_PROP(DT_NODELABEL(clk_hse), hse_tcxo)
411 : #define STM32_HSE_DIV2 DT_PROP(DT_NODELABEL(clk_hse), hse_div2)
412 : #define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency)
413 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hse), st_stm32wba_hse_clock, okay)
414 : #define STM32_HSE_ENABLED 1
415 : #define STM32_HSE_DIV2 DT_PROP(DT_NODELABEL(clk_hse), hse_div2)
416 : #define STM32_HSE_FREQ DT_PROP(DT_NODELABEL(clk_hse), clock_frequency)
417 : #else
418 0 : #define STM32_HSE_FREQ 0
419 : #endif
420 :
421 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi48), fixed_clock, okay)
422 : #define STM32_HSI48_ENABLED 1
423 : #define STM32_HSI48_FREQ DT_PROP(DT_NODELABEL(clk_hsi48), clock_frequency)
424 : #elif DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(clk_hsi48), st_stm32_hsi48_clock, okay)
425 : #define STM32_HSI48_ENABLED 1
426 : #define STM32_HSI48_FREQ DT_PROP(DT_NODELABEL(clk_hsi48), clock_frequency)
427 : #define STM32_HSI48_CRS_USB_SOF DT_PROP(DT_NODELABEL(clk_hsi48), crs_usb_sof)
428 : #endif
429 :
430 : #if DT_NODE_HAS_COMPAT_STATUS(DT_NODELABEL(perck), st_stm32_clock_mux, okay)
431 : #define STM32_CKPER_ENABLED 1
432 : #endif
433 :
434 : /** Driver structure definition */
435 :
436 1 : struct stm32_pclken {
437 0 : uint32_t bus : STM32_CLOCK_DIV_SHIFT;
438 0 : uint32_t div : (32 - STM32_CLOCK_DIV_SHIFT);
439 0 : uint32_t enr;
440 : };
441 :
442 : /** Device tree clocks helpers */
443 :
444 1 : #define STM32_CLOCK_INFO(clk_index, node_id) \
445 : { \
446 : .enr = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bits), \
447 : .bus = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bus) & \
448 : GENMASK(STM32_CLOCK_DIV_SHIFT - 1, 0), \
449 : .div = DT_CLOCKS_CELL_BY_IDX(node_id, clk_index, bus) >> \
450 : STM32_CLOCK_DIV_SHIFT, \
451 : }
452 0 : #define STM32_DT_CLOCKS(node_id) \
453 : { \
454 : LISTIFY(DT_NUM_CLOCKS(node_id), \
455 : STM32_CLOCK_INFO, (,), node_id) \
456 : }
457 :
458 0 : #define STM32_DT_INST_CLOCKS(inst) \
459 : STM32_DT_CLOCKS(DT_DRV_INST(inst))
460 :
461 0 : #define STM32_DOMAIN_CLOCK_INST_SUPPORT(inst) DT_INST_CLOCKS_HAS_IDX(inst, 1) ||
462 0 : #define STM32_DT_INST_DEV_DOMAIN_CLOCK_SUPPORT \
463 : (DT_INST_FOREACH_STATUS_OKAY(STM32_DOMAIN_CLOCK_INST_SUPPORT) 0)
464 :
465 0 : #define STM32_DOMAIN_CLOCK_SUPPORT(id) DT_CLOCKS_HAS_IDX(DT_NODELABEL(id), 1) ||
466 0 : #define STM32_DT_DEV_DOMAIN_CLOCK_SUPPORT \
467 : (DT_FOREACH_STATUS_OKAY(STM32_DOMAIN_CLOCK_SUPPORT) 0)
468 :
469 : /** Clock source binding accessors */
470 :
471 : /**
472 : * @brief Obtain register field from clock configuration.
473 : *
474 : * @param clock clock bit field value.
475 : */
476 1 : #define STM32_CLOCK_REG_GET(clock) \
477 : (((clock) >> STM32_CLOCK_REG_SHIFT) & STM32_CLOCK_REG_MASK)
478 :
479 : /**
480 : * @brief Obtain position field from clock configuration.
481 : *
482 : * @param clock Clock bit field value.
483 : */
484 1 : #define STM32_CLOCK_SHIFT_GET(clock) \
485 : (((clock) >> STM32_CLOCK_SHIFT_SHIFT) & STM32_CLOCK_SHIFT_MASK)
486 :
487 : /**
488 : * @brief Obtain mask field from clock configuration.
489 : *
490 : * @param clock Clock bit field value.
491 : */
492 1 : #define STM32_CLOCK_MASK_GET(clock) \
493 : (((clock) >> STM32_CLOCK_MASK_SHIFT) & STM32_CLOCK_MASK_MASK)
494 :
495 : /**
496 : * @brief Obtain value field from clock configuration.
497 : *
498 : * @param clock Clock bit field value.
499 : */
500 1 : #define STM32_CLOCK_VAL_GET(clock) \
501 : (((clock) >> STM32_CLOCK_VAL_SHIFT) & STM32_CLOCK_VAL_MASK)
502 :
503 : /**
504 : * @brief Obtain register field from MCO configuration.
505 : *
506 : * @param mco_cfgr MCO configuration bit field value.
507 : */
508 1 : #define STM32_MCO_CFGR_REG_GET(mco_cfgr) \
509 : (((mco_cfgr) >> STM32_MCO_CFGR_REG_SHIFT) & STM32_MCO_CFGR_REG_MASK)
510 :
511 : /**
512 : * @brief Obtain position field from MCO configuration.
513 : *
514 : * @param mco_cfgr MCO configuration bit field value.
515 : */
516 1 : #define STM32_MCO_CFGR_SHIFT_GET(mco_cfgr) \
517 : (((mco_cfgr) >> STM32_MCO_CFGR_SHIFT_SHIFT) & STM32_MCO_CFGR_SHIFT_MASK)
518 :
519 : /**
520 : * @brief Obtain mask field from MCO configuration.
521 : *
522 : * @param mco_cfgr MCO configuration bit field value.
523 : */
524 1 : #define STM32_MCO_CFGR_MASK_GET(mco_cfgr) \
525 : (((mco_cfgr) >> STM32_MCO_CFGR_MASK_SHIFT) & STM32_MCO_CFGR_MASK_MASK)
526 :
527 : /**
528 : * @brief Obtain value field from MCO configuration.
529 : *
530 : * @param mco_cfgr MCO configuration bit field value.
531 : */
532 1 : #define STM32_MCO_CFGR_VAL_GET(mco_cfgr) \
533 : (((mco_cfgr) >> STM32_MCO_CFGR_VAL_SHIFT) & STM32_MCO_CFGR_VAL_MASK)
534 :
535 : #if defined(STM32_HSE_CSS)
536 : /**
537 : * @brief Called if the HSE clock security system detects a clock fault.
538 : *
539 : * The function is called in interrupt context.
540 : *
541 : * The default (weakly-linked) implementation does nothing and should be
542 : * overridden.
543 : */
544 : void stm32_hse_css_callback(void);
545 : #endif
546 :
547 : #ifdef CONFIG_SOC_SERIES_STM32WB0X
548 : /**
549 : * @internal
550 : * @brief Type definition for LSI frequency update callbacks
551 : */
552 : typedef void (*lsi_update_cb_t)(uint32_t new_lsi_frequency);
553 :
554 : /**
555 : * @internal
556 : * @brief Registers a callback to invoke after each runtime measure and
557 : * update of the LSI frequency is completed.
558 : *
559 : * @param cb Callback to invoke
560 : * @return 0 Registration successful
561 : * @return ENOMEM Too many callbacks registered
562 : *
563 : * @note Callbacks are NEVER invoked if runtime LSI measurement is disabled
564 : */
565 : int stm32wb0_register_lsi_update_callback(lsi_update_cb_t cb);
566 : #endif /* CONFIG_SOC_SERIES_STM32WB0X */
567 :
568 : #endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_STM32_CLOCK_CONTROL_H_ */
|