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