1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 2017 NXP
4 *
5 * Peng Fan <peng.fan@nxp.com>
6 */
7
8 #include <common.h>
9 #include <asm/arch/clock.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/io.h>
12 #include <errno.h>
13
14 static struct ccm_reg *ccm_reg = (struct ccm_reg *)CCM_BASE_ADDR;
15
16 static struct clk_root_map root_array[] = {
17 {ARM_A53_CLK_ROOT, CORE_CLOCK_SLICE, 0,
18 {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK,
19 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK,
20 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL3_CLK}
21 },
22 {ARM_M4_CLK_ROOT, CORE_CLOCK_SLICE, 1,
23 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_250M_CLK,
24 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
25 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK}
26 },
27 {VPU_A53_CLK_ROOT, CORE_CLOCK_SLICE, 2,
28 {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK,
29 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK,
30 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VPU_PLL_CLK}
31 },
32 {GPU_CORE_CLK_ROOT, CORE_CLOCK_SLICE, 3,
33 {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
34 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK,
35 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
36 },
37 {GPU_SHADER_CLK_ROOT, CORE_CLOCK_SLICE, 4,
38 {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
39 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK,
40 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
41 },
42 {MAIN_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 0,
43 {OSC_25M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_800M_CLK,
44 SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_1000M_CLK,
45 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL1_100M_CLK}
46 },
47 {ENET_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 1,
48 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
49 SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK,
50 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK}
51 },
52 {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2,
53 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
54 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK,
55 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK}
56 },
57 {VPU_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 3,
58 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, VPU_PLL_CLK,
59 AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK,
60 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_100M_CLK}
61 },
62 {DISPLAY_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4,
63 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK,
64 SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK,
65 EXT_CLK_1, EXT_CLK_4}
66 },
67 {DISPLAY_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5,
68 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK,
69 SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK,
70 EXT_CLK_1, EXT_CLK_3}
71 },
72 {DISPLAY_RTRM_CLK_ROOT, BUS_CLOCK_SLICE, 6,
73 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_200M_CLK,
74 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK,
75 EXT_CLK_2, EXT_CLK_3}
76 },
77 {USB_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 7,
78 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK,
79 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK,
80 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK}
81 },
82 {GPU_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 8,
83 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK,
84 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK,
85 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
86 },
87 {GPU_AHB_CLK_ROOT, BUS_CLOCK_SLICE, 9,
88 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK,
89 SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK,
90 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
91 },
92 {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10,
93 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK,
94 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK,
95 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
96 },
97 {NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11,
98 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK,
99 SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK,
100 SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK}
101 },
102 {AHB_CLK_ROOT, AHB_CLOCK_SLICE, 0,
103 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_800M_CLK,
104 SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK,
105 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK}
106 },
107 {IPG_CLK_ROOT, IPG_CLOCK_SLICE, 0,
108 {}
109 },
110 {AUDIO_AHB_CLK_ROOT, AHB_CLOCK_SLICE, 1,
111 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK,
112 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_166M_CLK,
113 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK}
114 },
115 {MIPI_DSI_ESC_RX_CLK_ROOT, AHB_CLOCK_SLICE, 2,
116 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_40M_CLK,
117 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
118 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL1_CLK },
119 },
120 {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0,
121 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK,
122 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_250M_CLK,
123 SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL1_266M_CLK}
124 },
125 {DRAM_APB_CLK_ROOT, IP_CLOCK_SLICE, 1,
126 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK,
127 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK,
128 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK}
129 },
130 {VPU_G1_CLK_ROOT, IP_CLOCK_SLICE, 2,
131 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
132 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK,
133 SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK}
134 },
135 {VPU_G2_CLK_ROOT, IP_CLOCK_SLICE, 3,
136 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
137 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK,
138 SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK}
139 },
140 {DISPLAY_DTRC_CLK_ROOT, IP_CLOCK_SLICE, 4,
141 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
142 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK,
143 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK}
144 },
145 {DISPLAY_DC8000_CLK_ROOT, IP_CLOCK_SLICE, 5,
146 {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
147 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK,
148 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK}
149 },
150 {PCIE1_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 6,
151 {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK,
152 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
153 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK}
154 },
155 {PCIE1_PHY_CLK_ROOT, IP_CLOCK_SLICE, 7,
156 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK,
157 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4,
158 SYSTEM_PLL1_400M_CLK}
159 },
160 {PCIE1_AUX_CLK_ROOT, IP_CLOCK_SLICE, 8,
161 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK,
162 SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK,
163 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK}
164 },
165 {DC_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 9,
166 {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK,
167 AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK,
168 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4}
169 },
170 {LCDIF_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 10,
171 {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK,
172 AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK,
173 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4}
174 },
175 {SAI1_CLK_ROOT, IP_CLOCK_SLICE, 11,
176 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
177 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
178 OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2}
179 },
180 {SAI2_CLK_ROOT, IP_CLOCK_SLICE, 12,
181 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
182 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
183 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3}
184 },
185 {SAI3_CLK_ROOT, IP_CLOCK_SLICE, 13,
186 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
187 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
188 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4}
189 },
190 {SAI4_CLK_ROOT, IP_CLOCK_SLICE, 14,
191 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
192 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
193 OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2}
194 },
195 {SAI5_CLK_ROOT, IP_CLOCK_SLICE, 15,
196 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
197 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
198 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3}
199 },
200 {SAI6_CLK_ROOT, IP_CLOCK_SLICE, 16,
201 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
202 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
203 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4}
204 },
205 {SPDIF1_CLK_ROOT, IP_CLOCK_SLICE, 17,
206 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
207 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
208 OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3}
209 },
210 {SPDIF2_CLK_ROOT, IP_CLOCK_SLICE, 18,
211 {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK,
212 VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK,
213 OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4}
214 },
215 {ENET_REF_CLK_ROOT, IP_CLOCK_SLICE, 19,
216 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_50M_CLK,
217 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK,
218 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, EXT_CLK_4}
219 },
220 {ENET_TIMER_CLK_ROOT, IP_CLOCK_SLICE, 20,
221 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK,
222 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4,
223 VIDEO_PLL_CLK}
224 },
225 {ENET_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 21,
226 {OSC_25M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL2_125M_CLK,
227 SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_500M_CLK,
228 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK}
229 },
230 {NAND_CLK_ROOT, IP_CLOCK_SLICE, 22,
231 {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK,
232 SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK,
233 SYSTEM_PLL2_250M_CLK, VIDEO_PLL_CLK}
234 },
235 {QSPI_CLK_ROOT, IP_CLOCK_SLICE, 23,
236 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK,
237 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK,
238 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK}
239 },
240 {USDHC1_CLK_ROOT, IP_CLOCK_SLICE, 24,
241 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK,
242 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK,
243 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK}
244 },
245 {USDHC2_CLK_ROOT, IP_CLOCK_SLICE, 25,
246 {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK,
247 SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK,
248 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK}
249 },
250 {I2C1_CLK_ROOT, IP_CLOCK_SLICE, 26,
251 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK,
252 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK,
253 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK}
254 },
255 {I2C2_CLK_ROOT, IP_CLOCK_SLICE, 27,
256 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK,
257 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK,
258 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK}
259 },
260 {I2C3_CLK_ROOT, IP_CLOCK_SLICE, 28,
261 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK,
262 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK,
263 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK}
264 },
265 {I2C4_CLK_ROOT, IP_CLOCK_SLICE, 29,
266 {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK,
267 SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK,
268 AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK}
269 },
270 {UART1_CLK_ROOT, IP_CLOCK_SLICE, 30,
271 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK,
272 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK,
273 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK}
274 },
275 {UART2_CLK_ROOT, IP_CLOCK_SLICE, 31,
276 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK,
277 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK,
278 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK}
279 },
280 {UART3_CLK_ROOT, IP_CLOCK_SLICE, 32,
281 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK,
282 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK,
283 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK}
284 },
285 {UART4_CLK_ROOT, IP_CLOCK_SLICE, 33,
286 {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK,
287 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK,
288 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK}
289 },
290 {USB_CORE_REF_CLK_ROOT, IP_CLOCK_SLICE, 34,
291 {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK,
292 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK,
293 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK}
294 },
295 {USB_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 35,
296 {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK,
297 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK,
298 EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK}
299 },
300 {GIC_CLK_ROOT, IP_CLOCK_SLICE, 36,
301 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK,
302 SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_800M_CLK,
303 EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK}
304 },
305 {ECSPI1_CLK_ROOT, IP_CLOCK_SLICE, 37,
306 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK,
307 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK,
308 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK}
309 },
310 {ECSPI2_CLK_ROOT, IP_CLOCK_SLICE, 38,
311 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK,
312 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK,
313 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK}
314 },
315 {PWM1_CLK_ROOT, IP_CLOCK_SLICE, 39,
316 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK,
317 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1,
318 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK}
319 },
320 {PWM2_CLK_ROOT, IP_CLOCK_SLICE, 40,
321 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK,
322 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1,
323 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK}
324 },
325 {PWM3_CLK_ROOT, IP_CLOCK_SLICE, 41,
326 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK,
327 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1,
328 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK}
329 },
330 {PWM4_CLK_ROOT, IP_CLOCK_SLICE, 42,
331 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK,
332 SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1,
333 SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK}
334 },
335 {GPT1_CLK_ROOT, IP_CLOCK_SLICE, 43,
336 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
337 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
338 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1}
339 },
340 {GPT2_CLK_ROOT, IP_CLOCK_SLICE, 44,
341 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
342 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
343 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2}
344 },
345 {GPT3_CLK_ROOT, IP_CLOCK_SLICE, 45,
346 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
347 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
348 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3}
349 },
350 {GPT4_CLK_ROOT, IP_CLOCK_SLICE, 46,
351 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
352 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
353 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1}
354 },
355 {GPT5_CLK_ROOT, IP_CLOCK_SLICE, 47,
356 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
357 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
358 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2}
359 },
360 {GPT6_CLK_ROOT, IP_CLOCK_SLICE, 48,
361 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK,
362 SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK,
363 SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3}
364 },
365 {TRACE_CLK_ROOT, IP_CLOCK_SLICE, 49,
366 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK,
367 VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK,
368 SYSTEM_PLL3_CLK, EXT_CLK_1, EXT_CLK_3}
369 },
370 {WDOG_CLK_ROOT, IP_CLOCK_SLICE, 50,
371 {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK,
372 VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK,
373 SYSTEM_PLL3_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_166M_CLK}
374 },
375 {WRCLK_CLK_ROOT, IP_CLOCK_SLICE, 51,
376 {OSC_25M_CLK, SYSTEM_PLL1_40M_CLK, VPU_PLL_CLK,
377 SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK,
378 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK}
379 },
380 {IPP_DO_CLKO1, IP_CLOCK_SLICE, 52,
381 {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, OSC_27M_CLK,
382 SYSTEM_PLL1_200M_CLK, AUDIO_PLL2_CLK,
383 SYSTEM_PLL2_500M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_80M_CLK}
384 },
385 {IPP_DO_CLKO2, IP_CLOCK_SLICE, 53,
386 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_400M_CLK,
387 SYSTEM_PLL2_166M_CLK, SYSTEM_PLL3_CLK,
388 AUDIO_PLL1_CLK, VIDEO_PLL_CLK, OSC_32K_CLK}
389 },
390 {MIPI_DSI_CORE_CLK_ROOT, IP_CLOCK_SLICE, 54,
391 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK,
392 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
393 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
394 },
395 {MIPI_DSI_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 55,
396 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK,
397 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
398 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
399 },
400 {MIPI_DSI_DBI_CLK_ROOT, IP_CLOCK_SLICE, 56,
401 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_100M_CLK,
402 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
403 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
404 },
405 {OLD_MIPI_DSI_ESC_CLK_ROOT, IP_CLOCK_SLICE, 57,
406 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK,
407 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
408 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}
409 },
410 {MIPI_CSI1_CORE_CLK_ROOT, IP_CLOCK_SLICE, 58,
411 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK,
412 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
413 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
414 },
415 {MIPI_CSI1_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 59,
416 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK,
417 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
418 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
419 },
420 {MIPI_CSI1_ESC_CLK_ROOT, IP_CLOCK_SLICE, 60,
421 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK,
422 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
423 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}
424 },
425 {MIPI_CSI2_CORE_CLK_ROOT, IP_CLOCK_SLICE, 61,
426 {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK,
427 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
428 SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
429 },
430 {MIPI_CSI2_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 62,
431 {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK,
432 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
433 EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK}
434 },
435 {MIPI_CSI2_ESC_CLK_ROOT, IP_CLOCK_SLICE, 63,
436 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK,
437 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
438 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}
439 },
440 {PCIE2_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 64,
441 {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK,
442 SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK,
443 SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK}
444 },
445 {PCIE2_PHY_CLK_ROOT, IP_CLOCK_SLICE, 65,
446 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK,
447 EXT_CLK_1, EXT_CLK_2, EXT_CLK_3,
448 EXT_CLK_4, SYSTEM_PLL1_400M_CLK}
449 },
450 {PCIE2_AUX_CLK_ROOT, IP_CLOCK_SLICE, 66,
451 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK,
452 SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK,
453 SYSTEM_PLL1_80M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK}
454 },
455 {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67,
456 {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK,
457 SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK,
458 SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK}
459 },
460 {OLD_MIPI_DSI_ESC_RX_ROOT, IP_CLOCK_SLICE, 68,
461 {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK,
462 SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK,
463 SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK},
464 },
465 {DISPLAY_HDMI_CLK_ROOT, IP_CLOCK_SLICE, 69,
466 {OSC_25M_CLK, SYSTEM_PLL1_200M_CLK, SYSTEM_PLL2_200M_CLK,
467 VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK,
468 SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4}
469 },
470 {DRAM_SEL_CFG, DRAM_SEL_CLOCK_SLICE, 0,
471 {DRAM_PLL1_CLK}
472 },
473 {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0,
474 {DRAM_PLL1_CLK}
475 },
476 };
477
select(enum clk_root_index clock_id)478 static int select(enum clk_root_index clock_id)
479 {
480 int i, size;
481 struct clk_root_map *p = root_array;
482
483 size = ARRAY_SIZE(root_array);
484
485 for (i = 0; i < size; i++, p++) {
486 if (clock_id == p->entry)
487 return i;
488 }
489
490 return -EINVAL;
491 }
492
get_clk_root_target(enum clk_slice_type slice_type,u32 slice_index)493 static void __iomem *get_clk_root_target(enum clk_slice_type slice_type,
494 u32 slice_index)
495 {
496 void __iomem *clk_root_target;
497
498 switch (slice_type) {
499 case CORE_CLOCK_SLICE:
500 clk_root_target =
501 (void __iomem *)&ccm_reg->core_root[slice_index];
502 break;
503 case BUS_CLOCK_SLICE:
504 clk_root_target =
505 (void __iomem *)&ccm_reg->bus_root[slice_index];
506 break;
507 case IP_CLOCK_SLICE:
508 clk_root_target =
509 (void __iomem *)&ccm_reg->ip_root[slice_index];
510 break;
511 case AHB_CLOCK_SLICE:
512 clk_root_target =
513 (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2];
514 break;
515 case IPG_CLOCK_SLICE:
516 clk_root_target =
517 (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2 + 1];
518 break;
519 case CORE_SEL_CLOCK_SLICE:
520 clk_root_target = (void __iomem *)&ccm_reg->core_sel;
521 break;
522 case DRAM_SEL_CLOCK_SLICE:
523 clk_root_target = (void __iomem *)&ccm_reg->dram_sel;
524 break;
525 default:
526 return NULL;
527 }
528
529 return clk_root_target;
530 }
531
clock_get_target_val(enum clk_root_index clock_id,u32 * val)532 int clock_get_target_val(enum clk_root_index clock_id, u32 *val)
533 {
534 int root_entry;
535 struct clk_root_map *p;
536 void __iomem *clk_root_target;
537
538 if (clock_id >= CLK_ROOT_MAX)
539 return -EINVAL;
540
541 root_entry = select(clock_id);
542 if (root_entry < 0)
543 return -EINVAL;
544
545 p = &root_array[root_entry];
546 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index);
547 if (!clk_root_target)
548 return -EINVAL;
549
550 *val = readl(clk_root_target);
551
552 return 0;
553 }
554
clock_set_target_val(enum clk_root_index clock_id,u32 val)555 int clock_set_target_val(enum clk_root_index clock_id, u32 val)
556 {
557 int root_entry;
558 struct clk_root_map *p;
559 void __iomem *clk_root_target;
560
561 if (clock_id >= CLK_ROOT_MAX)
562 return -EINVAL;
563
564 root_entry = select(clock_id);
565 if (root_entry < 0)
566 return -EINVAL;
567
568 p = &root_array[root_entry];
569 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index);
570 if (!clk_root_target)
571 return -EINVAL;
572
573 writel(val, clk_root_target);
574
575 return 0;
576 }
577
clock_root_enabled(enum clk_root_index clock_id)578 int clock_root_enabled(enum clk_root_index clock_id)
579 {
580 void __iomem *clk_root_target;
581 u32 slice_index, slice_type;
582 u32 val;
583 int root_entry;
584
585 if (clock_id >= CLK_ROOT_MAX)
586 return -EINVAL;
587
588 root_entry = select(clock_id);
589 if (root_entry < 0)
590 return -EINVAL;
591
592 slice_type = root_array[root_entry].slice_type;
593 slice_index = root_array[root_entry].slice_index;
594
595 if ((slice_type == IPG_CLOCK_SLICE) ||
596 (slice_type == DRAM_SEL_CLOCK_SLICE) ||
597 (slice_type == CORE_SEL_CLOCK_SLICE)) {
598 /*
599 * Not supported, from CCM doc
600 * TODO
601 */
602 return 0;
603 }
604
605 clk_root_target = get_clk_root_target(slice_type, slice_index);
606 if (!clk_root_target)
607 return -EINVAL;
608
609 val = readl(clk_root_target);
610
611 return (val & CLK_ROOT_ON) ? 1 : 0;
612 }
613
614 /* CCGR CLK gate operation */
clock_enable(enum clk_ccgr_index index,bool enable)615 int clock_enable(enum clk_ccgr_index index, bool enable)
616 {
617 void __iomem *ccgr;
618
619 if (index >= CCGR_MAX)
620 return -EINVAL;
621
622 if (enable)
623 ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_set;
624 else
625 ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_clr;
626
627 writel(CCGR_CLK_ON_MASK, ccgr);
628
629 return 0;
630 }
631
clock_get_prediv(enum clk_root_index clock_id,enum root_pre_div * pre_div)632 int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div)
633 {
634 u32 val;
635 int root_entry;
636 struct clk_root_map *p;
637 void __iomem *clk_root_target;
638
639 if (clock_id >= CLK_ROOT_MAX)
640 return -EINVAL;
641
642 root_entry = select(clock_id);
643 if (root_entry < 0)
644 return -EINVAL;
645
646 p = &root_array[root_entry];
647
648 if ((p->slice_type == CORE_CLOCK_SLICE) ||
649 (p->slice_type == IPG_CLOCK_SLICE) ||
650 (p->slice_type == CORE_SEL_CLOCK_SLICE) ||
651 (p->slice_type == DRAM_SEL_CLOCK_SLICE)) {
652 *pre_div = 0;
653 return 0;
654 }
655
656 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index);
657 if (!clk_root_target)
658 return -EINVAL;
659
660 val = readl(clk_root_target);
661 val &= CLK_ROOT_PRE_DIV_MASK;
662 val >>= CLK_ROOT_PRE_DIV_SHIFT;
663
664 *pre_div = val;
665
666 return 0;
667 }
668
clock_get_postdiv(enum clk_root_index clock_id,enum root_post_div * post_div)669 int clock_get_postdiv(enum clk_root_index clock_id,
670 enum root_post_div *post_div)
671 {
672 u32 val, mask;
673 int root_entry;
674 struct clk_root_map *p;
675 void __iomem *clk_root_target;
676
677 if (clock_id >= CLK_ROOT_MAX)
678 return -EINVAL;
679
680 root_entry = select(clock_id);
681 if (root_entry < 0)
682 return -EINVAL;
683
684 p = &root_array[root_entry];
685
686 if ((p->slice_type == CORE_SEL_CLOCK_SLICE) ||
687 (p->slice_type == DRAM_SEL_CLOCK_SLICE)) {
688 *post_div = 0;
689 return 0;
690 }
691
692 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index);
693 if (!clk_root_target)
694 return -EINVAL;
695
696 if (p->slice_type == IPG_CLOCK_SLICE)
697 mask = CLK_ROOT_IPG_POST_DIV_MASK;
698 else if (p->slice_type == CORE_CLOCK_SLICE)
699 mask = CLK_ROOT_CORE_POST_DIV_MASK;
700 else
701 mask = CLK_ROOT_POST_DIV_MASK;
702
703 val = readl(clk_root_target);
704 val &= mask;
705 val >>= CLK_ROOT_POST_DIV_SHIFT;
706
707 *post_div = val;
708
709 return 0;
710 }
711
clock_get_src(enum clk_root_index clock_id,enum clk_root_src * p_clock_src)712 int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src)
713 {
714 u32 val;
715 int root_entry;
716 struct clk_root_map *p;
717 void __iomem *clk_root_target;
718
719 if (clock_id >= CLK_ROOT_MAX)
720 return -EINVAL;
721
722 root_entry = select(clock_id);
723 if (root_entry < 0)
724 return -EINVAL;
725
726 p = &root_array[root_entry];
727
728 clk_root_target = get_clk_root_target(p->slice_type, p->slice_index);
729 if (!clk_root_target)
730 return -EINVAL;
731
732 val = readl(clk_root_target);
733 val &= CLK_ROOT_SRC_MUX_MASK;
734 val >>= CLK_ROOT_SRC_MUX_SHIFT;
735
736 *p_clock_src = p->src_mux[val];
737
738 return 0;
739 }
740