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