1 /*
2 * Copyright (c) 2020-23, 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 uint32_t clock_name = (uint32_t)sub_system;
23
24 if (clock_name == MCUX_MCAN_CLK) {
25 CLOCK_EnableClock(kCLOCK_Mcan);
26 }
27 #endif /* defined(CONFIG_CAN_MCUX_MCAN) */
28
29 return 0;
30 }
31
mcux_lpc_syscon_clock_control_off(const struct device * dev,clock_control_subsys_t sub_system)32 static int mcux_lpc_syscon_clock_control_off(const struct device *dev,
33 clock_control_subsys_t sub_system)
34 {
35 return 0;
36 }
37
mcux_lpc_syscon_clock_control_get_subsys_rate(const struct device * dev,clock_control_subsys_t sub_system,uint32_t * rate)38 static int mcux_lpc_syscon_clock_control_get_subsys_rate(
39 const struct device *dev,
40 clock_control_subsys_t sub_system,
41 uint32_t *rate)
42 {
43 uint32_t clock_name = (uint32_t) sub_system;
44
45 switch (clock_name) {
46
47 #if defined(CONFIG_I2C_MCUX_FLEXCOMM) || \
48 defined(CONFIG_SPI_MCUX_FLEXCOMM) || \
49 defined(CONFIG_UART_MCUX_FLEXCOMM)
50 case MCUX_FLEXCOMM0_CLK:
51 *rate = CLOCK_GetFlexCommClkFreq(0);
52 break;
53 case MCUX_FLEXCOMM1_CLK:
54 *rate = CLOCK_GetFlexCommClkFreq(1);
55 break;
56 case MCUX_FLEXCOMM2_CLK:
57 *rate = CLOCK_GetFlexCommClkFreq(2);
58 break;
59 case MCUX_FLEXCOMM3_CLK:
60 *rate = CLOCK_GetFlexCommClkFreq(3);
61 break;
62 case MCUX_FLEXCOMM4_CLK:
63 *rate = CLOCK_GetFlexCommClkFreq(4);
64 break;
65 case MCUX_FLEXCOMM5_CLK:
66 *rate = CLOCK_GetFlexCommClkFreq(5);
67 break;
68 case MCUX_FLEXCOMM6_CLK:
69 *rate = CLOCK_GetFlexCommClkFreq(6);
70 break;
71 case MCUX_FLEXCOMM7_CLK:
72 *rate = CLOCK_GetFlexCommClkFreq(7);
73 break;
74 case MCUX_FLEXCOMM8_CLK:
75 *rate = CLOCK_GetFlexCommClkFreq(8);
76 break;
77 case MCUX_FLEXCOMM9_CLK:
78 *rate = CLOCK_GetFlexCommClkFreq(9);
79 break;
80 case MCUX_FLEXCOMM10_CLK:
81 *rate = CLOCK_GetFlexCommClkFreq(10);
82 break;
83 case MCUX_FLEXCOMM11_CLK:
84 *rate = CLOCK_GetFlexCommClkFreq(11);
85 break;
86 case MCUX_FLEXCOMM12_CLK:
87 *rate = CLOCK_GetFlexCommClkFreq(12);
88 break;
89 case MCUX_FLEXCOMM13_CLK:
90 *rate = CLOCK_GetFlexCommClkFreq(13);
91 break;
92 case MCUX_PMIC_I2C_CLK:
93 *rate = CLOCK_GetFlexCommClkFreq(15);
94 break;
95 case MCUX_HS_SPI_CLK:
96 #if defined(SYSCON_HSLSPICLKSEL_SEL_MASK)
97 *rate = CLOCK_GetHsLspiClkFreq();
98 #else
99 *rate = CLOCK_GetFlexCommClkFreq(14);
100 #endif
101 break;
102 case MCUX_HS_SPI1_CLK:
103 *rate = CLOCK_GetFlexCommClkFreq(16);
104 break;
105 #endif
106
107 #if (defined(FSL_FEATURE_SOC_USDHC_COUNT) && FSL_FEATURE_SOC_USDHC_COUNT)
108 case MCUX_USDHC1_CLK:
109 *rate = CLOCK_GetSdioClkFreq(0);
110 break;
111 case MCUX_USDHC2_CLK:
112 *rate = CLOCK_GetSdioClkFreq(1);
113 break;
114 #endif
115
116 #if (defined(FSL_FEATURE_SOC_SDIF_COUNT) && \
117 (FSL_FEATURE_SOC_SDIF_COUNT)) && \
118 CONFIG_MCUX_SDIF
119 case MCUX_SDIF_CLK:
120 *rate = CLOCK_GetSdioClkFreq();
121 break;
122 #endif
123
124 #if defined(CONFIG_CAN_MCUX_MCAN)
125 case MCUX_MCAN_CLK:
126 *rate = CLOCK_GetMCanClkFreq();
127 break;
128 #endif /* defined(CONFIG_CAN_MCUX_MCAN) */
129
130 #if defined(CONFIG_COUNTER_MCUX_CTIMER)
131 case (MCUX_CTIMER0_CLK + MCUX_CTIMER_CLK_OFFSET):
132 *rate = CLOCK_GetCTimerClkFreq(0);
133 break;
134 case (MCUX_CTIMER1_CLK + MCUX_CTIMER_CLK_OFFSET):
135 *rate = CLOCK_GetCTimerClkFreq(1);
136 break;
137 case (MCUX_CTIMER2_CLK + MCUX_CTIMER_CLK_OFFSET):
138 *rate = CLOCK_GetCTimerClkFreq(2);
139 break;
140 case (MCUX_CTIMER3_CLK + MCUX_CTIMER_CLK_OFFSET):
141 *rate = CLOCK_GetCTimerClkFreq(3);
142 break;
143 case (MCUX_CTIMER4_CLK + MCUX_CTIMER_CLK_OFFSET):
144 *rate = CLOCK_GetCTimerClkFreq(4);
145 break;
146 #endif
147
148 case MCUX_BUS_CLK:
149 *rate = CLOCK_GetFreq(kCLOCK_BusClk);
150 break;
151
152 #if defined(CONFIG_I3C_MCUX)
153 case MCUX_I3C_CLK:
154 *rate = CLOCK_GetI3cClkFreq();
155 break;
156 #endif
157
158 #if defined(CONFIG_MIPI_DSI_MCUX_2L)
159 case MCUX_MIPI_DSI_DPHY_CLK:
160 *rate = CLOCK_GetMipiDphyClkFreq();
161 break;
162 case MCUX_MIPI_DSI_ESC_CLK:
163 *rate = CLOCK_GetMipiDphyEscTxClkFreq();
164 break;
165 case MCUX_LCDIF_PIXEL_CLK:
166 *rate = CLOCK_GetDcPixelClkFreq();
167 break;
168 #endif
169 }
170
171 return 0;
172 }
173
174 static const struct clock_control_driver_api mcux_lpc_syscon_api = {
175 .on = mcux_lpc_syscon_clock_control_on,
176 .off = mcux_lpc_syscon_clock_control_off,
177 .get_rate = mcux_lpc_syscon_clock_control_get_subsys_rate,
178 };
179
180 #define LPC_CLOCK_INIT(n) \
181 \
182 DEVICE_DT_INST_DEFINE(n, \
183 NULL, \
184 NULL, \
185 NULL, NULL, \
186 PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \
187 &mcux_lpc_syscon_api);
188
189 DT_INST_FOREACH_STATUS_OKAY(LPC_CLOCK_INIT)
190