1 /*
2 * Copyright 2020-2024 NXP
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT nxp_lpc_syscon
8 #include <errno.h>
9 #include <zephyr/drivers/clock_control.h>
10 #include <zephyr/dt-bindings/clock/mcux_lpc_syscon_clock.h>
11 #include <soc.h>
12 #include <fsl_clock.h>
13
14 #define LOG_LEVEL CONFIG_CLOCK_CONTROL_LOG_LEVEL
15 #include <zephyr/logging/log.h>
16 LOG_MODULE_REGISTER(clock_control);
17
mcux_lpc_syscon_clock_control_on(const struct device * dev,clock_control_subsys_t sub_system)18 static int mcux_lpc_syscon_clock_control_on(const struct device *dev,
19 clock_control_subsys_t sub_system)
20 {
21 #if defined(CONFIG_CAN_MCUX_MCAN)
22 if ((uint32_t)sub_system == MCUX_MCAN_CLK) {
23 CLOCK_EnableClock(kCLOCK_Mcan);
24 }
25 #endif /* defined(CONFIG_CAN_MCUX_MCAN) */
26 #if defined(CONFIG_COUNTER_NXP_MRT)
27 if ((uint32_t)sub_system == MCUX_MRT_CLK) {
28 #if defined(CONFIG_SOC_FAMILY_LPC) || defined(CONFIG_SOC_SERIES_RW6XX) || \
29 defined(CONFIG_SOC_SERIES_MCXN)
30 CLOCK_EnableClock(kCLOCK_Mrt);
31 #elif defined(CONFIG_SOC_FAMILY_NXP_IMXRT)
32 CLOCK_EnableClock(kCLOCK_Mrt0);
33 #endif
34 }
35 #if defined(CONFIG_SOC_SERIES_RW6XX)
36 if ((uint32_t)sub_system == MCUX_FREEMRT_CLK) {
37 CLOCK_EnableClock(kCLOCK_FreeMrt);
38 }
39 #endif
40 #endif /* defined(CONFIG_COUNTER_NXP_MRT) */
41 #if defined(CONFIG_MIPI_DBI_NXP_LCDIC)
42 if ((uint32_t)sub_system == MCUX_LCDIC_CLK) {
43 CLOCK_EnableClock(kCLOCK_Lcdic);
44 }
45 #endif
46
47 #if defined(CONFIG_PINCTRL_NXP_PORT)
48 switch ((uint32_t)sub_system) {
49 #if defined(CONFIG_SOC_SERIES_MCXA)
50 case MCUX_PORT0_CLK:
51 CLOCK_EnableClock(kCLOCK_GatePORT0);
52 break;
53 case MCUX_PORT1_CLK:
54 CLOCK_EnableClock(kCLOCK_GatePORT1);
55 break;
56 case MCUX_PORT2_CLK:
57 CLOCK_EnableClock(kCLOCK_GatePORT2);
58 break;
59 case MCUX_PORT3_CLK:
60 CLOCK_EnableClock(kCLOCK_GatePORT3);
61 break;
62 case MCUX_PORT4_CLK:
63 CLOCK_EnableClock(kCLOCK_GatePORT4);
64 break;
65 #else
66 case MCUX_PORT0_CLK:
67 CLOCK_EnableClock(kCLOCK_Port0);
68 break;
69 case MCUX_PORT1_CLK:
70 CLOCK_EnableClock(kCLOCK_Port1);
71 break;
72 case MCUX_PORT2_CLK:
73 CLOCK_EnableClock(kCLOCK_Port2);
74 break;
75 case MCUX_PORT3_CLK:
76 CLOCK_EnableClock(kCLOCK_Port3);
77 break;
78 case MCUX_PORT4_CLK:
79 CLOCK_EnableClock(kCLOCK_Port4);
80 break;
81 #endif /* defined(CONFIG_SOC_SERIES_MCXA) */
82 default:
83 break;
84 }
85 #endif /* defined(CONFIG_PINCTRL_NXP_PORT) */
86
87 #ifdef CONFIG_ETH_NXP_ENET_QOS
88 if ((uint32_t)sub_system == MCUX_ENET_QOS_CLK) {
89 CLOCK_EnableClock(kCLOCK_Enet);
90 }
91 #endif
92
93 #if defined(CONFIG_CAN_MCUX_FLEXCAN)
94 switch ((uint32_t)sub_system) {
95 #if defined(CONFIG_SOC_SERIES_MCXA)
96 case MCUX_FLEXCAN0_CLK:
97 CLOCK_EnableClock(kCLOCK_GateFLEXCAN0);
98 break;
99 #else
100 case MCUX_FLEXCAN0_CLK:
101 CLOCK_EnableClock(kCLOCK_Flexcan0);
102 break;
103 case MCUX_FLEXCAN1_CLK:
104 CLOCK_EnableClock(kCLOCK_Flexcan1);
105 break;
106 #endif /* defined(CONFIG_SOC_SERIES_MCXA) */
107 default:
108 break;
109 }
110 #endif /* defined(CONFIG_CAN_MCUX_MCAN) */
111
112 #ifdef CONFIG_ETH_NXP_ENET
113 if ((uint32_t)sub_system == MCUX_ENET_CLK) {
114 #ifdef CONFIG_SOC_SERIES_RW6XX
115 CLOCK_EnableClock(kCLOCK_TddrMciEnetClk);
116 CLOCK_EnableClock(kCLOCK_EnetIpg);
117 CLOCK_EnableClock(kCLOCK_EnetIpgS);
118 #endif
119 }
120 #endif
121
122 #if DT_NODE_HAS_STATUS(DT_NODELABEL(rtc), okay)
123 #if CONFIG_SOC_SERIES_IMXRT5XX
124 CLOCK_EnableOsc32K(true);
125 #elif CONFIG_SOC_SERIES_IMXRT6XX
126 /* No configuration */
127 #else /* !CONFIG_SOC_SERIES_IMXRT5XX | !CONFIG_SOC_SERIES_IMXRT6XX */
128 /* 0x0 Clock Select Value Set IRTC to use FRO 16K Clk */
129 #if DT_PROP(DT_NODELABEL(rtc), clock_select) == 0x0
130 CLOCK_SetupClk16KClocking(kCLOCK_Clk16KToVbat | kCLOCK_Clk16KToMain);
131 /* 0x1 Clock Select Value Set IRTC to use Osc 32K Clk */
132 #elif DT_PROP(DT_NODELABEL(rtc), clock_select) == 0x1
133 CLOCK_SetupOsc32KClocking(kCLOCK_Osc32kToVbat | kCLOCK_Osc32kToMain);
134 #endif /* DT_PROP(DT_NODELABEL(rtc), clock_select) */
135 CLOCK_EnableClock(kCLOCK_Rtc0);
136 #endif /* CONFIG_SOC_SERIES_IMXRT5XX */
137 #endif /* DT_NODE_HAS_STATUS(DT_NODELABEL(rtc), okay) */
138
139 return 0;
140 }
141
mcux_lpc_syscon_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)142 static int mcux_lpc_syscon_clock_control_off(const struct device *dev,
143 clock_control_subsys_t sub_system)
144 {
145 return 0;
146 }
147
mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)148 static int mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device *dev,
149 clock_control_subsys_t sub_system,
150 uint32_t *rate)
151 {
152 uint32_t clock_name = (uint32_t)sub_system;
153
154 switch (clock_name) {
155
156 #if defined(CONFIG_I2C_MCUX_FLEXCOMM) || defined(CONFIG_SPI_MCUX_FLEXCOMM) || \
157 defined(CONFIG_UART_MCUX_FLEXCOMM)
158 case MCUX_FLEXCOMM0_CLK:
159 *rate = CLOCK_GetFlexCommClkFreq(0);
160 break;
161 case MCUX_FLEXCOMM1_CLK:
162 *rate = CLOCK_GetFlexCommClkFreq(1);
163 break;
164 case MCUX_FLEXCOMM2_CLK:
165 *rate = CLOCK_GetFlexCommClkFreq(2);
166 break;
167 case MCUX_FLEXCOMM3_CLK:
168 *rate = CLOCK_GetFlexCommClkFreq(3);
169 break;
170 case MCUX_FLEXCOMM4_CLK:
171 *rate = CLOCK_GetFlexCommClkFreq(4);
172 break;
173 case MCUX_FLEXCOMM5_CLK:
174 *rate = CLOCK_GetFlexCommClkFreq(5);
175 break;
176 case MCUX_FLEXCOMM6_CLK:
177 *rate = CLOCK_GetFlexCommClkFreq(6);
178 break;
179 case MCUX_FLEXCOMM7_CLK:
180 *rate = CLOCK_GetFlexCommClkFreq(7);
181 break;
182 case MCUX_FLEXCOMM8_CLK:
183 *rate = CLOCK_GetFlexCommClkFreq(8);
184 break;
185 case MCUX_FLEXCOMM9_CLK:
186 *rate = CLOCK_GetFlexCommClkFreq(9);
187 break;
188 case MCUX_FLEXCOMM10_CLK:
189 *rate = CLOCK_GetFlexCommClkFreq(10);
190 break;
191 case MCUX_FLEXCOMM11_CLK:
192 *rate = CLOCK_GetFlexCommClkFreq(11);
193 break;
194 case MCUX_FLEXCOMM12_CLK:
195 *rate = CLOCK_GetFlexCommClkFreq(12);
196 break;
197 case MCUX_FLEXCOMM13_CLK:
198 *rate = CLOCK_GetFlexCommClkFreq(13);
199 break;
200 case MCUX_PMIC_I2C_CLK:
201 *rate = CLOCK_GetFlexCommClkFreq(15);
202 break;
203 case MCUX_HS_SPI_CLK:
204 #if defined(SYSCON_HSLSPICLKSEL_SEL_MASK)
205 *rate = CLOCK_GetHsLspiClkFreq();
206 #else
207 *rate = CLOCK_GetFlexCommClkFreq(14);
208 #endif
209 break;
210 case MCUX_HS_SPI1_CLK:
211 *rate = CLOCK_GetFlexCommClkFreq(16);
212 break;
213 #elif defined(CONFIG_NXP_LP_FLEXCOMM)
214 case MCUX_FLEXCOMM0_CLK:
215 *rate = CLOCK_GetLPFlexCommClkFreq(0);
216 break;
217 case MCUX_FLEXCOMM1_CLK:
218 *rate = CLOCK_GetLPFlexCommClkFreq(1);
219 break;
220 case MCUX_FLEXCOMM2_CLK:
221 *rate = CLOCK_GetLPFlexCommClkFreq(2);
222 break;
223 case MCUX_FLEXCOMM3_CLK:
224 *rate = CLOCK_GetLPFlexCommClkFreq(3);
225 break;
226 case MCUX_FLEXCOMM4_CLK:
227 *rate = CLOCK_GetLPFlexCommClkFreq(4);
228 break;
229 case MCUX_FLEXCOMM5_CLK:
230 *rate = CLOCK_GetLPFlexCommClkFreq(5);
231 break;
232 case MCUX_FLEXCOMM6_CLK:
233 *rate = CLOCK_GetLPFlexCommClkFreq(6);
234 break;
235 case MCUX_FLEXCOMM7_CLK:
236 *rate = CLOCK_GetLPFlexCommClkFreq(7);
237 break;
238 case MCUX_FLEXCOMM8_CLK:
239 *rate = CLOCK_GetLPFlexCommClkFreq(8);
240 break;
241 case MCUX_FLEXCOMM9_CLK:
242 *rate = CLOCK_GetLPFlexCommClkFreq(9);
243 break;
244
245 case MCUX_FLEXCOMM10_CLK:
246 *rate = CLOCK_GetLPFlexCommClkFreq(10);
247 break;
248
249 case MCUX_FLEXCOMM11_CLK:
250 *rate = CLOCK_GetLPFlexCommClkFreq(11);
251 break;
252
253 case MCUX_FLEXCOMM12_CLK:
254 *rate = CLOCK_GetLPFlexCommClkFreq(12);
255 break;
256
257 case MCUX_FLEXCOMM13_CLK:
258 *rate = CLOCK_GetLPFlexCommClkFreq(13);
259 break;
260
261 case MCUX_FLEXCOMM17_CLK:
262 *rate = CLOCK_GetLPFlexCommClkFreq(17);
263 break;
264
265 case MCUX_FLEXCOMM18_CLK:
266 *rate = CLOCK_GetLPFlexCommClkFreq(18);
267 break;
268
269 case MCUX_FLEXCOMM19_CLK:
270 *rate = CLOCK_GetLPFlexCommClkFreq(19);
271 break;
272
273 case MCUX_FLEXCOMM20_CLK:
274 *rate = CLOCK_GetLPFlexCommClkFreq(20);
275 break;
276 #endif
277
278 /* On RT7xx, flexcomm14 and 16 only can be LPSPI, flexcomm15 only can be I2C. */
279 #if defined(CONFIG_SOC_SERIES_IMXRT7XX) && defined(CONFIG_SOC_FAMILY_NXP_IMXRT)
280 case MCUX_LPSPI14_CLK:
281 *rate = CLOCK_GetLPSpiClkFreq(14);
282 break;
283 case MCUX_LPI2C15_CLK:
284 *rate = CLOCK_GetLPI2cClkFreq(15);
285 break;
286 case MCUX_LPSPI16_CLK:
287 *rate = CLOCK_GetLPSpiClkFreq(16);
288 break;
289 #endif
290
291 #if (defined(FSL_FEATURE_SOC_USDHC_COUNT) && FSL_FEATURE_SOC_USDHC_COUNT)
292
293 #if defined(CONFIG_SOC_SERIES_MCXN)
294 case MCUX_USDHC1_CLK:
295 *rate = CLOCK_GetUsdhcClkFreq();
296 break;
297 #elif defined(CONFIG_SOC_SERIES_IMXRT7XX)
298 case MCUX_USDHC1_CLK:
299 *rate = CLOCK_GetUsdhcClkFreq(0);
300 break;
301 case MCUX_USDHC2_CLK:
302 *rate = CLOCK_GetUsdhcClkFreq(1);
303 break;
304 #else
305 case MCUX_USDHC1_CLK:
306 *rate = CLOCK_GetSdioClkFreq(0);
307 break;
308 case MCUX_USDHC2_CLK:
309 *rate = CLOCK_GetSdioClkFreq(1);
310 break;
311 #endif
312
313 #endif
314
315 #if (defined(FSL_FEATURE_SOC_SDIF_COUNT) && (FSL_FEATURE_SOC_SDIF_COUNT)) && CONFIG_MCUX_SDIF
316 case MCUX_SDIF_CLK:
317 *rate = CLOCK_GetSdioClkFreq();
318 break;
319 #endif
320
321 #if defined(CONFIG_CAN_MCUX_MCAN)
322 case MCUX_MCAN_CLK:
323 *rate = CLOCK_GetMCanClkFreq();
324 break;
325 #endif /* defined(CONFIG_CAN_MCUX_MCAN) */
326
327 #if defined(CONFIG_COUNTER_MCUX_CTIMER) || defined(CONFIG_PWM_MCUX_CTIMER)
328 case MCUX_CTIMER0_CLK:
329 *rate = CLOCK_GetCTimerClkFreq(0);
330 break;
331 case MCUX_CTIMER1_CLK:
332 *rate = CLOCK_GetCTimerClkFreq(1);
333 break;
334 case MCUX_CTIMER2_CLK:
335 *rate = CLOCK_GetCTimerClkFreq(2);
336 break;
337 case MCUX_CTIMER3_CLK:
338 *rate = CLOCK_GetCTimerClkFreq(3);
339 break;
340 case MCUX_CTIMER4_CLK:
341 *rate = CLOCK_GetCTimerClkFreq(4);
342 break;
343 case MCUX_CTIMER5_CLK:
344 *rate = CLOCK_GetCTimerClkFreq(5);
345 break;
346 case MCUX_CTIMER6_CLK:
347 *rate = CLOCK_GetCTimerClkFreq(6);
348 break;
349 case MCUX_CTIMER7_CLK:
350 *rate = CLOCK_GetCTimerClkFreq(7);
351 break;
352 #endif
353
354 #if defined(CONFIG_COUNTER_NXP_MRT)
355 case MCUX_MRT_CLK:
356 #if defined(CONFIG_SOC_SERIES_RW6XX)
357 case MCUX_FREEMRT_CLK:
358 #endif /* RW */
359 #endif /* MRT */
360 #if defined(CONFIG_PWM_MCUX_SCTIMER)
361 case MCUX_SCTIMER_CLK:
362 #endif
363 #ifdef CONFIG_SOC_SERIES_RW6XX
364 /* RW6XX uses core clock for SCTimer, not bus clock */
365 *rate = CLOCK_GetCoreSysClkFreq();
366 break;
367 #else
368 case MCUX_BUS_CLK:
369 *rate = CLOCK_GetFreq(kCLOCK_BusClk);
370 break;
371 #endif
372
373 #if defined(CONFIG_I3C_MCUX)
374 case MCUX_I3C_CLK:
375 #if CONFIG_SOC_SERIES_MCXN
376 *rate = CLOCK_GetI3cClkFreq(0);
377 #else
378 *rate = CLOCK_GetI3cClkFreq();
379 #endif
380 break;
381 #if (FSL_FEATURE_SOC_I3C_COUNT == 2)
382 case MCUX_I3C2_CLK:
383 #if CONFIG_SOC_SERIES_MCXN
384 *rate = CLOCK_GetI3cClkFreq(1);
385 #else
386 *rate = CLOCK_GetI3cClkFreq();
387 #endif
388 break;
389 #endif
390
391 #endif /* CONFIG_I3C_MCUX */
392
393 #if defined(CONFIG_MIPI_DSI_MCUX_2L)
394 case MCUX_MIPI_DSI_DPHY_CLK:
395 *rate = CLOCK_GetMipiDphyClkFreq();
396 break;
397 case MCUX_MIPI_DSI_ESC_CLK:
398 *rate = CLOCK_GetMipiDphyEscTxClkFreq();
399 break;
400 case MCUX_LCDIF_PIXEL_CLK:
401 *rate = CLOCK_GetDcPixelClkFreq();
402 break;
403 #endif
404 #if defined(CONFIG_AUDIO_DMIC_MCUX)
405 case MCUX_DMIC_CLK:
406 *rate = CLOCK_GetDmicClkFreq();
407 break;
408 #endif
409 #if defined(CONFIG_MEMC_MCUX_FLEXSPI)
410 case MCUX_FLEXSPI_CLK:
411 #if (FSL_FEATURE_SOC_FLEXSPI_COUNT == 1)
412 *rate = CLOCK_GetFlexspiClkFreq();
413 #else
414 *rate = CLOCK_GetFlexspiClkFreq(0);
415 #endif
416 break;
417 #if (FSL_FEATURE_SOC_FLEXSPI_COUNT == 2)
418 case MCUX_FLEXSPI2_CLK:
419 *rate = CLOCK_GetFlexspiClkFreq(1);
420 break;
421 #endif
422 #endif /* CONFIG_MEMC_MCUX_FLEXSPI */
423
424 #if defined(CONFIG_I2S_MCUX_SAI)
425 case MCUX_SAI0_CLK:
426 #if (FSL_FEATURE_SOC_I2S_COUNT == 1)
427 *rate = CLOCK_GetSaiClkFreq();
428 #else
429 *rate = CLOCK_GetSaiClkFreq(0);
430 #endif
431 break;
432 #if (FSL_FEATURE_SOC_I2S_COUNT == 2)
433 case MCUX_SAI1_CLK:
434 *rate = CLOCK_GetSaiClkFreq(1);
435 break;
436 #endif
437 #endif /* CONFIG_I2S_MCUX_SAI */
438
439 #ifdef CONFIG_ETH_NXP_ENET_QOS
440 case MCUX_ENET_QOS_CLK:
441 *rate = CLOCK_GetFreq(kCLOCK_BusClk);
442 break;
443 #endif
444
445 #ifdef CONFIG_ETH_NXP_ENET
446 case MCUX_ENET_CLK:
447 #ifdef CONFIG_SOC_SERIES_RW6XX
448 *rate = CLOCK_GetTddrMciEnetClkFreq();
449 #endif
450 break;
451 #endif
452
453 #if defined(CONFIG_MIPI_DBI_NXP_LCDIC)
454 case MCUX_LCDIC_CLK:
455 *rate = CLOCK_GetLcdClkFreq();
456 break;
457 #endif
458
459 #if defined(CONFIG_ADC_MCUX_LPADC)
460 case MCUX_LPADC1_CLK:
461 #if (FSL_FEATURE_SOC_LPADC_COUNT == 1)
462 *rate = CLOCK_GetAdcClkFreq();
463 #else
464 *rate = CLOCK_GetAdcClkFreq(0);
465 #endif
466 break;
467 #if (FSL_FEATURE_SOC_LPADC_COUNT == 2)
468 case MCUX_LPADC2_CLK:
469 *rate = CLOCK_GetAdcClkFreq(1);
470 break;
471 #endif
472 #endif /* CONFIG_ADC_MCUX_LPADC */
473
474 #if defined(CONFIG_CAN_MCUX_FLEXCAN)
475 #if defined(CONFIG_SOC_SERIES_MCXA)
476 case MCUX_FLEXCAN0_CLK:
477 *rate = CLOCK_GetFlexcanClkFreq();
478 break;
479 #else
480 case MCUX_FLEXCAN0_CLK:
481 *rate = CLOCK_GetFlexcanClkFreq(0);
482 break;
483 case MCUX_FLEXCAN1_CLK:
484 *rate = CLOCK_GetFlexcanClkFreq(1);
485 break;
486 #endif /* defined(CONFIG_SOC_SERIES_MCXA) */
487 #endif /* defined(CONFIG_CAN_MCUX_FLEXCAN) */
488
489 #if defined(CONFIG_MCUX_FLEXIO)
490 case MCUX_FLEXIO0_CLK:
491 *rate = CLOCK_GetFlexioClkFreq();
492 break;
493 #endif /* defined(CONFIG_MCUX_FLEXIO) */
494
495 #if defined(CONFIG_I2S_MCUX_FLEXCOMM)
496 case MCUX_AUDIO_MCLK:
497 *rate = CLOCK_GetMclkClkFreq();
498 break;
499 #endif /* defined(CONFIG_I2S_MCUX_FLEXCOMM) */
500
501 #if (defined(CONFIG_UART_MCUX_LPUART) && CONFIG_SOC_SERIES_MCXA)
502 case MCUX_LPUART0_CLK:
503 *rate = CLOCK_GetLpuartClkFreq(0);
504 break;
505 case MCUX_LPUART1_CLK:
506 *rate = CLOCK_GetLpuartClkFreq(1);
507 break;
508 case MCUX_LPUART2_CLK:
509 *rate = CLOCK_GetLpuartClkFreq(2);
510 break;
511 case MCUX_LPUART3_CLK:
512 *rate = CLOCK_GetLpuartClkFreq(3);
513 break;
514 case MCUX_LPUART4_CLK:
515 *rate = CLOCK_GetLpuartClkFreq(4);
516 break;
517 #endif /* defined(CONFIG_UART_MCUX_LPUART) */
518
519 #if (defined(CONFIG_I2C_MCUX_LPI2C) && CONFIG_SOC_SERIES_MCXA)
520 case MCUX_LPI2C0_CLK:
521 *rate = CLOCK_GetLpi2cClkFreq(0);
522 break;
523 case MCUX_LPI2C1_CLK:
524 *rate = CLOCK_GetLpi2cClkFreq(1);
525 break;
526 case MCUX_LPI2C2_CLK:
527 *rate = CLOCK_GetLpi2cClkFreq(2);
528 break;
529 case MCUX_LPI2C3_CLK:
530 *rate = CLOCK_GetLpi2cClkFreq(3);
531 break;
532 #endif /* defined(CONFIG_I2C_MCUX_LPI2C) */
533
534 #if defined(CONFIG_DT_HAS_NXP_XSPI_ENABLED)
535 case MCUX_XSPI0_CLK:
536 *rate = CLOCK_GetXspiClkFreq(0);
537 break;
538 case MCUX_XSPI1_CLK:
539 *rate = CLOCK_GetXspiClkFreq(1);
540 break;
541 case MCUX_XSPI2_CLK:
542 *rate = CLOCK_GetXspiClkFreq(2);
543 break;
544 #endif /* defined(CONFIG_DT_HAS_NXP_XSPI_ENABLED) */
545
546 #if (defined(CONFIG_SPI_MCUX_LPSPI) && CONFIG_SOC_SERIES_MCXA)
547 case MCUX_LPSPI0_CLK:
548 *rate = CLOCK_GetLpspiClkFreq(0);
549 break;
550 case MCUX_LPSPI1_CLK:
551 *rate = CLOCK_GetLpspiClkFreq(1);
552 break;
553 #endif /* defined(CONFIG_SPI_MCUX_LPSPI) */
554 }
555
556 return 0;
557 }
558
559 #if defined(CONFIG_MEMC)
560 /*
561 * Weak implemenetation of flexspi_clock_set_freq- SOC implementations are
562 * expected to override this
563 */
flexspi_clock_set_freq(uint32_t clock_name,uint32_t freq)564 __weak int flexspi_clock_set_freq(uint32_t clock_name, uint32_t freq)
565 {
566 ARG_UNUSED(clock_name);
567 ARG_UNUSED(freq);
568 return -ENOTSUP;
569 }
570 #endif
571
572 /*
573 * Since this function is used to reclock the FlexSPI when running in
574 * XIP, it must be located in RAM when MEMC driver is enabled.
575 */
576 #ifdef CONFIG_MEMC
577 #define SYSCON_SET_FUNC_ATTR __ramfunc
578 #else
579 #define SYSCON_SET_FUNC_ATTR
580 #endif
581
mcux_lpc_syscon_clock_control_set_subsys_rate(const struct device * dev,clock_control_subsys_t subsys,clock_control_subsys_rate_t rate)582 static int SYSCON_SET_FUNC_ATTR mcux_lpc_syscon_clock_control_set_subsys_rate(
583 const struct device *dev, clock_control_subsys_t subsys, clock_control_subsys_rate_t rate)
584 {
585 uint32_t clock_name = (uintptr_t)subsys;
586 uint32_t clock_rate = (uintptr_t)rate;
587
588 switch (clock_name) {
589 case MCUX_FLEXSPI_CLK:
590 #if defined(CONFIG_MEMC)
591 /* The SOC is using the FlexSPI for XIP. Therefore,
592 * the FlexSPI itself must be managed within the function,
593 * which is SOC specific.
594 */
595 return flexspi_clock_set_freq(clock_name, clock_rate);
596 #endif
597 #if defined(CONFIG_MIPI_DBI_NXP_LCDIC)
598 case MCUX_LCDIC_CLK:
599 /* Set LCDIC clock div */
600 uint32_t root_rate = (CLOCK_GetLcdClkFreq() *
601 ((CLKCTL0->LCDFCLKDIV & CLKCTL0_LCDFCLKDIV_DIV_MASK) + 1));
602 CLOCK_SetClkDiv(kCLOCK_DivLcdClk, (root_rate / clock_rate));
603 return 0;
604 #endif
605 default:
606 /* Silence unused variable warning */
607 ARG_UNUSED(clock_rate);
608 return -ENOTSUP;
609 }
610 }
611
612 static DEVICE_API(clock_control, mcux_lpc_syscon_api) = {
613 .on = mcux_lpc_syscon_clock_control_on,
614 .off = mcux_lpc_syscon_clock_control_off,
615 .get_rate = mcux_lpc_syscon_clock_control_get_subsys_rate,
616 .set_rate = mcux_lpc_syscon_clock_control_set_subsys_rate,
617 };
618
619 #define LPC_CLOCK_INIT(n) \
620 \
621 DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, NULL, PRE_KERNEL_1, \
622 CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &mcux_lpc_syscon_api);
623
624 DT_INST_FOREACH_STATUS_OKAY(LPC_CLOCK_INIT)
625