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