imx: rename mx8m,MX8M to imx8m,IMX8M
[oweals/u-boot.git] / arch / arm / mach-imx / imx8m / clock_slice.c
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
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
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
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
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
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 */
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
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
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
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 }