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