1 /*
2 * Copyright (c) 2019 STMicroelectronics
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <soc.h>
8 #include <stm32_ll_bus.h>
9 #include <stm32_ll_rcc.h>
10 #include <zephyr/drivers/clock_control.h>
11 #include <zephyr/sys/util.h>
12 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
13
14 /**
15 * @brief fill in AHB/APB buses configuration structure
16 */
stm32_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)17 static int stm32_clock_control_on(const struct device *dev, clock_control_subsys_t sub_system)
18 {
19 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
20
21 ARG_UNUSED(dev);
22
23 switch (pclken->bus) {
24 case STM32_CLOCK_BUS_APB1:
25 LL_APB1_GRP1_EnableClock(pclken->enr);
26 break;
27 case STM32_CLOCK_BUS_APB2:
28 LL_APB2_GRP1_EnableClock(pclken->enr);
29 break;
30 case STM32_CLOCK_BUS_APB3:
31 LL_APB3_GRP1_EnableClock(pclken->enr);
32 break;
33 case STM32_CLOCK_BUS_APB4:
34 LL_APB4_GRP1_EnableClock(pclken->enr);
35 break;
36 case STM32_CLOCK_BUS_APB5:
37 LL_APB5_GRP1_EnableClock(pclken->enr);
38 break;
39 case STM32_CLOCK_BUS_AHB2:
40 LL_AHB2_GRP1_EnableClock(pclken->enr);
41 break;
42 case STM32_CLOCK_BUS_AHB3:
43 LL_AHB3_GRP1_EnableClock(pclken->enr);
44 break;
45 case STM32_CLOCK_BUS_AHB4:
46 LL_AHB4_GRP1_EnableClock(pclken->enr);
47 break;
48 case STM32_CLOCK_BUS_AHB5:
49 LL_AHB5_GRP1_EnableClock(pclken->enr);
50 break;
51 case STM32_CLOCK_BUS_AHB6:
52 LL_AHB6_GRP1_EnableClock(pclken->enr);
53 break;
54 case STM32_CLOCK_BUS_AXI:
55 LL_AXI_GRP1_EnableClock(pclken->enr);
56 break;
57 case STM32_CLOCK_BUS_MLAHB:
58 LL_MLAHB_GRP1_EnableClock(pclken->enr);
59 break;
60 default:
61 return -ENOTSUP;
62 }
63
64 return 0;
65 }
66
stm32_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)67 static int stm32_clock_control_off(const struct device *dev, clock_control_subsys_t sub_system)
68 {
69 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
70
71 ARG_UNUSED(dev);
72
73 switch (pclken->bus) {
74 case STM32_CLOCK_BUS_APB1:
75 LL_APB1_GRP1_DisableClock(pclken->enr);
76 break;
77 case STM32_CLOCK_BUS_APB2:
78 LL_APB2_GRP1_DisableClock(pclken->enr);
79 break;
80 case STM32_CLOCK_BUS_APB3:
81 LL_APB3_GRP1_DisableClock(pclken->enr);
82 break;
83 case STM32_CLOCK_BUS_APB4:
84 LL_APB4_GRP1_DisableClock(pclken->enr);
85 break;
86 case STM32_CLOCK_BUS_APB5:
87 LL_APB5_GRP1_DisableClock(pclken->enr);
88 break;
89 case STM32_CLOCK_BUS_AHB2:
90 LL_AHB2_GRP1_DisableClock(pclken->enr);
91 break;
92 case STM32_CLOCK_BUS_AHB3:
93 LL_AHB3_GRP1_DisableClock(pclken->enr);
94 break;
95 case STM32_CLOCK_BUS_AHB4:
96 LL_AHB4_GRP1_DisableClock(pclken->enr);
97 break;
98 case STM32_CLOCK_BUS_AHB5:
99 LL_AHB5_GRP1_DisableClock(pclken->enr);
100 break;
101 case STM32_CLOCK_BUS_AHB6:
102 LL_AHB6_GRP1_DisableClock(pclken->enr);
103 break;
104 case STM32_CLOCK_BUS_AXI:
105 LL_AXI_GRP1_DisableClock(pclken->enr);
106 break;
107 case STM32_CLOCK_BUS_MLAHB:
108 LL_MLAHB_GRP1_DisableClock(pclken->enr);
109 break;
110 default:
111 return -ENOTSUP;
112 }
113
114 return 0;
115 }
116
stm32_clock_control_get_subsys_rate(const struct device * clock,clock_control_subsys_t sub_system,uint32_t * rate)117 static int stm32_clock_control_get_subsys_rate(const struct device *clock,
118 clock_control_subsys_t sub_system,
119 uint32_t *rate)
120 {
121 struct stm32_pclken *pclken = (struct stm32_pclken *)(sub_system);
122
123 ARG_UNUSED(clock);
124
125 switch (pclken->bus) {
126 case STM32_CLOCK_BUS_APB1:
127 switch (pclken->enr) {
128 case LL_APB1_GRP1_PERIPH_TIM2:
129 case LL_APB1_GRP1_PERIPH_TIM3:
130 case LL_APB1_GRP1_PERIPH_TIM4:
131 case LL_APB1_GRP1_PERIPH_TIM5:
132 case LL_APB1_GRP1_PERIPH_TIM6:
133 case LL_APB1_GRP1_PERIPH_TIM7:
134 case LL_APB1_GRP1_PERIPH_TIM12:
135 case LL_APB1_GRP1_PERIPH_TIM13:
136 case LL_APB1_GRP1_PERIPH_TIM14:
137 *rate = LL_RCC_GetTIMGClockFreq(LL_RCC_TIMG1PRES);
138 break;
139 case LL_APB1_GRP1_PERIPH_LPTIM1:
140 *rate = LL_RCC_GetLPTIMClockFreq(
141 LL_RCC_LPTIM1_CLKSOURCE);
142 break;
143 case LL_APB1_GRP1_PERIPH_SPI2:
144 case LL_APB1_GRP1_PERIPH_SPI3:
145 *rate = LL_RCC_GetSPIClockFreq(LL_RCC_SPI23_CLKSOURCE);
146 break;
147 case LL_APB1_GRP1_PERIPH_USART2:
148 case LL_APB1_GRP1_PERIPH_UART4:
149 *rate = LL_RCC_GetUARTClockFreq(
150 LL_RCC_UART24_CLKSOURCE);
151 break;
152 case LL_APB1_GRP1_PERIPH_USART3:
153 case LL_APB1_GRP1_PERIPH_UART5:
154 *rate = LL_RCC_GetUARTClockFreq(
155 LL_RCC_UART35_CLKSOURCE);
156 break;
157 case LL_APB1_GRP1_PERIPH_UART7:
158 case LL_APB1_GRP1_PERIPH_UART8:
159 *rate = LL_RCC_GetUARTClockFreq(
160 LL_RCC_UART78_CLKSOURCE);
161 break;
162 case LL_APB1_GRP1_PERIPH_I2C1:
163 case LL_APB1_GRP1_PERIPH_I2C2:
164 *rate = LL_RCC_GetI2CClockFreq(LL_RCC_I2C12_CLKSOURCE);
165 break;
166 case LL_APB1_GRP1_PERIPH_I2C3:
167 case LL_APB1_GRP1_PERIPH_I2C5:
168 *rate = LL_RCC_GetI2CClockFreq(LL_RCC_I2C35_CLKSOURCE);
169 break;
170 case LL_APB1_GRP1_PERIPH_SPDIF:
171 *rate = LL_RCC_GetSPDIFRXClockFreq(
172 LL_RCC_SPDIFRX_CLKSOURCE);
173 break;
174 case LL_APB1_GRP1_PERIPH_CEC:
175 *rate = LL_RCC_GetCECClockFreq(LL_RCC_CEC_CLKSOURCE);
176 break;
177 case LL_APB1_GRP1_PERIPH_WWDG1:
178 case LL_APB1_GRP1_PERIPH_DAC12:
179 case LL_APB1_GRP1_PERIPH_MDIOS:
180 default:
181 return -ENOTSUP;
182 }
183 break;
184 case STM32_CLOCK_BUS_APB2:
185 switch (pclken->enr) {
186 case LL_APB2_GRP1_PERIPH_TIM1:
187 case LL_APB2_GRP1_PERIPH_TIM8:
188 case LL_APB2_GRP1_PERIPH_TIM15:
189 case LL_APB2_GRP1_PERIPH_TIM16:
190 case LL_APB2_GRP1_PERIPH_TIM17:
191 *rate = LL_RCC_GetTIMGClockFreq(LL_RCC_TIMG2PRES);
192 break;
193 case LL_APB2_GRP1_PERIPH_SPI1:
194 *rate = LL_RCC_GetSPIClockFreq(LL_RCC_SPI1_CLKSOURCE);
195 break;
196 case LL_APB2_GRP1_PERIPH_SPI4:
197 case LL_APB2_GRP1_PERIPH_SPI5:
198 *rate = LL_RCC_GetSPIClockFreq(LL_RCC_SPI45_CLKSOURCE);
199 break;
200 case LL_APB2_GRP1_PERIPH_USART6:
201 *rate = LL_RCC_GetUARTClockFreq(
202 LL_RCC_USART6_CLKSOURCE);
203 break;
204 case LL_APB2_GRP1_PERIPH_SAI1:
205 *rate = LL_RCC_GetSAIClockFreq(LL_RCC_SAI1_CLKSOURCE);
206 break;
207 case LL_APB2_GRP1_PERIPH_SAI2:
208 *rate = LL_RCC_GetSAIClockFreq(LL_RCC_SAI2_CLKSOURCE);
209 break;
210 case LL_APB2_GRP1_PERIPH_SAI3:
211 *rate = LL_RCC_GetSAIClockFreq(LL_RCC_SAI3_CLKSOURCE);
212 break;
213 case LL_APB2_GRP1_PERIPH_DFSDM1:
214 *rate = LL_RCC_GetDFSDMClockFreq(
215 LL_RCC_DFSDM_CLKSOURCE);
216 break;
217 case LL_APB2_GRP1_PERIPH_FDCAN:
218 *rate = LL_RCC_GetFDCANClockFreq(
219 LL_RCC_FDCAN_CLKSOURCE);
220 break;
221 case LL_APB2_GRP1_PERIPH_ADFSDM1:
222 default:
223 return -ENOTSUP;
224 }
225 break;
226 case STM32_CLOCK_BUS_APB3:
227 switch (pclken->enr) {
228 case LL_APB3_GRP1_PERIPH_LPTIM2:
229 case LL_APB3_GRP1_PERIPH_LPTIM3:
230 *rate = LL_RCC_GetLPTIMClockFreq(
231 LL_RCC_LPTIM23_CLKSOURCE);
232 break;
233 case LL_APB3_GRP1_PERIPH_LPTIM4:
234 case LL_APB3_GRP1_PERIPH_LPTIM5:
235 *rate = LL_RCC_GetLPTIMClockFreq(
236 LL_RCC_LPTIM45_CLKSOURCE);
237 break;
238 case LL_APB3_GRP1_PERIPH_SAI4:
239 *rate = LL_RCC_GetSAIClockFreq(LL_RCC_SAI4_CLKSOURCE);
240 break;
241 case LL_APB3_GRP1_PERIPH_SYSCFG:
242 case LL_APB3_GRP1_PERIPH_VREF:
243 case LL_APB3_GRP1_PERIPH_TMPSENS:
244 case LL_APB3_GRP1_PERIPH_HDP:
245 default:
246 return -ENOTSUP;
247 }
248 break;
249 case STM32_CLOCK_BUS_APB4:
250 switch (pclken->enr) {
251 case LL_APB4_GRP1_PERIPH_LTDC:
252 *rate = LL_RCC_GetLTDCClockFreq();
253 break;
254 case LL_APB4_GRP1_PERIPH_DSI:
255 *rate = LL_RCC_GetDSIClockFreq(LL_RCC_DSI_CLKSOURCE);
256 break;
257 case LL_APB4_GRP1_PERIPH_USBPHY:
258 *rate = LL_RCC_GetUSBPHYClockFreq(
259 LL_RCC_USBPHY_CLKSOURCE);
260 break;
261 case LL_APB4_GRP1_PERIPH_DDRPERFM:
262 case LL_APB4_GRP1_PERIPH_STGENRO:
263 case LL_APB4_GRP1_PERIPH_STGENROSTP:
264 default:
265 return -ENOTSUP;
266 }
267 break;
268 case STM32_CLOCK_BUS_APB5:
269 switch (pclken->enr) {
270 case LL_APB5_GRP1_PERIPH_SPI6:
271 *rate = LL_RCC_GetSPIClockFreq(LL_RCC_SPI6_CLKSOURCE);
272 break;
273 case LL_APB5_GRP1_PERIPH_I2C4:
274 case LL_APB5_GRP1_PERIPH_I2C6:
275 *rate = LL_RCC_GetI2CClockFreq(LL_RCC_I2C46_CLKSOURCE);
276 break;
277 case LL_APB5_GRP1_PERIPH_USART1:
278 *rate = LL_RCC_GetUARTClockFreq(
279 LL_RCC_USART1_CLKSOURCE);
280 break;
281 case LL_APB5_GRP1_PERIPH_STGEN:
282 case LL_APB5_GRP1_PERIPH_STGENSTP:
283 *rate = LL_RCC_GetSTGENClockFreq(
284 LL_RCC_STGEN_CLKSOURCE);
285 break;
286 case LL_APB5_GRP1_PERIPH_RTCAPB:
287 *rate = LL_RCC_GetRTCClockFreq();
288 break;
289 case LL_APB5_GRP1_PERIPH_TZC1:
290 case LL_APB5_GRP1_PERIPH_TZC2:
291 case LL_APB5_GRP1_PERIPH_TZPC:
292 case LL_APB5_GRP1_PERIPH_BSEC:
293 default:
294 return -ENOTSUP;
295 }
296 break;
297 case STM32_CLOCK_BUS_AHB2:
298 switch (pclken->enr) {
299 case LL_AHB2_GRP1_PERIPH_ADC12:
300 *rate = LL_RCC_GetADCClockFreq(LL_RCC_ADC_CLKSOURCE);
301 break;
302 case LL_AHB2_GRP1_PERIPH_USBO:
303 *rate = LL_RCC_GetUSBOClockFreq(LL_RCC_USBO_CLKSOURCE);
304 break;
305 case LL_AHB2_GRP1_PERIPH_SDMMC3:
306 *rate = LL_RCC_GetSDMMCClockFreq(
307 LL_RCC_SDMMC3_CLKSOURCE);
308 break;
309 case LL_AHB2_GRP1_PERIPH_DMA1:
310 case LL_AHB2_GRP1_PERIPH_DMA2:
311 case LL_AHB2_GRP1_PERIPH_DMAMUX:
312 default:
313 return -ENOTSUP;
314 }
315 break;
316 case STM32_CLOCK_BUS_AHB3:
317 switch (pclken->enr) {
318 case LL_AHB3_GRP1_PERIPH_RNG2:
319 *rate = LL_RCC_GetRNGClockFreq(LL_RCC_RNG2_CLKSOURCE);
320 break;
321 case LL_AHB3_GRP1_PERIPH_DCMI:
322 case LL_AHB3_GRP1_PERIPH_CRYP2:
323 case LL_AHB3_GRP1_PERIPH_HASH2:
324 case LL_AHB3_GRP1_PERIPH_CRC2:
325 case LL_AHB3_GRP1_PERIPH_HSEM:
326 case LL_AHB3_GRP1_PERIPH_IPCC:
327 default:
328 return -ENOTSUP;
329 }
330 break;
331 case STM32_CLOCK_BUS_AHB4:
332 return -ENOTSUP;
333 case STM32_CLOCK_BUS_AHB5:
334 switch (pclken->enr) {
335 case LL_AHB5_GRP1_PERIPH_RNG1:
336 *rate = LL_RCC_GetRNGClockFreq(LL_RCC_RNG1_CLKSOURCE);
337 break;
338 case LL_AHB5_GRP1_PERIPH_GPIOZ:
339 case LL_AHB5_GRP1_PERIPH_CRYP1:
340 case LL_AHB5_GRP1_PERIPH_HASH1:
341 case LL_AHB5_GRP1_PERIPH_BKPSRAM:
342 default:
343 return -ENOTSUP;
344 }
345 break;
346 case STM32_CLOCK_BUS_AHB6:
347 switch (pclken->enr) {
348 case LL_AHB6_GRP1_PERIPH_ETH1CK:
349 case LL_AHB6_GRP1_PERIPH_ETH1TX:
350 case LL_AHB6_GRP1_PERIPH_ETH1RX:
351 case LL_AHB6_GRP1_PERIPH_ETH1MAC:
352 case LL_AHB6_GRP1_PERIPH_ETH1STP:
353 *rate = LL_RCC_GetETHClockFreq(LL_RCC_ETH_CLKSOURCE);
354 break;
355 case LL_AHB6_GRP1_PERIPH_FMC:
356 *rate = LL_RCC_GetFMCClockFreq(LL_RCC_FMC_CLKSOURCE);
357 break;
358 case LL_AHB6_GRP1_PERIPH_QSPI:
359 *rate = LL_RCC_GetQSPIClockFreq(LL_RCC_QSPI_CLKSOURCE);
360 break;
361 case LL_AHB6_GRP1_PERIPH_SDMMC1:
362 case LL_AHB6_GRP1_PERIPH_SDMMC2:
363 *rate = LL_RCC_GetSDMMCClockFreq(
364 LL_RCC_SDMMC12_CLKSOURCE);
365 break;
366 case LL_AHB6_GRP1_PERIPH_MDMA:
367 case LL_AHB6_GRP1_PERIPH_GPU:
368 case LL_AHB6_GRP1_PERIPH_CRC1:
369 case LL_AHB6_GRP1_PERIPH_USBH:
370 default:
371 return -ENOTSUP;
372 }
373 break;
374 case STM32_CLOCK_BUS_AXI:
375 switch (pclken->enr) {
376 case LL_AXI_GRP1_PERIPH_SYSRAMEN:
377 default:
378 return -ENOTSUP;
379 }
380 break;
381 case STM32_CLOCK_BUS_MLAHB:
382 switch (pclken->enr) {
383 case LL_MLAHB_GRP1_PERIPH_RETRAMEN:
384 default:
385 return -ENOTSUP;
386 }
387 break;
388 default:
389 return -ENOTSUP;
390 }
391
392 if (pclken->div) {
393 *rate /= (pclken->div + 1);
394 }
395
396 return 0;
397 }
398
399 static DEVICE_API(clock_control, stm32_clock_control_api) = {
400 .on = stm32_clock_control_on,
401 .off = stm32_clock_control_off,
402 .get_rate = stm32_clock_control_get_subsys_rate,
403 };
404
stm32_clock_control_init(const struct device * dev)405 static int stm32_clock_control_init(const struct device *dev)
406 {
407 ARG_UNUSED(dev);
408 return 0;
409 }
410
411 /**
412 * @brief RCC device, note that priority is intentionally set to 1 so
413 * that the device init runs just after SOC init
414 */
415 DEVICE_DT_DEFINE(DT_NODELABEL(rcc),
416 stm32_clock_control_init,
417 NULL,
418 NULL, NULL,
419 PRE_KERNEL_1,
420 CONFIG_CLOCK_CONTROL_INIT_PRIORITY,
421 &stm32_clock_control_api);
422