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 }
740