xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_clock.c (revision b67e984664a8644d6cfd1812cabaa02cf24f09c9)
1 /*
2  * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
3  * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /*
9  * ZynqMP system level PM-API functions for clock control.
10  */
11 
12 #include <stdbool.h>
13 #include <string.h>
14 
15 #include <arch_helpers.h>
16 #include <lib/mmio.h>
17 #include <plat/common/platform.h>
18 
19 #include "pm_api_clock.h"
20 #include "pm_client.h"
21 #include "pm_common.h"
22 #include "pm_ipi.h"
23 #include "zynqmp_pm_api_sys.h"
24 
25 #define CLK_NODE_MAX			(6U)
26 
27 #define CLK_PARENTS_ID_LEN		(16U)
28 #define CLK_TOPOLOGY_NODE_OFFSET	(16U)
29 #define CLK_TOPOLOGY_PAYLOAD_LEN	(12U)
30 #define CLK_PARENTS_PAYLOAD_LEN		(12U)
31 #define CLK_TYPE_SHIFT			(2U)
32 #define CLK_CLKFLAGS_SHIFT		(8U)
33 #define CLK_TYPEFLAGS_SHIFT		(24U)
34 #define CLK_TYPEFLAGS2_SHIFT		(4U)
35 #define CLK_TYPEFLAGS_BITS_MASK		(0xFFU)
36 #define CLK_TYPEFLAGS2_BITS_MASK	(0x0F00U)
37 #define CLK_TYPEFLAGS_BITS		(8U)
38 
39 #define CLK_EXTERNAL_PARENT	(PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
40 
41 #define NA_MULT					(0U)
42 #define NA_DIV					(0U)
43 #define NA_SHIFT				(0U)
44 #define NA_WIDTH				(0U)
45 #define NA_CLK_FLAGS				(0U)
46 #define NA_TYPE_FLAGS				(0U)
47 
48 /* PLL nodes related definitions */
49 #define PLL_PRESRC_MUX_SHIFT			(20U)
50 #define PLL_PRESRC_MUX_WIDTH			(3U)
51 #define PLL_POSTSRC_MUX_SHIFT			(24U)
52 #define PLL_POSTSRC_MUX_WIDTH			(3U)
53 #define PLL_DIV2_MUX_SHIFT			(16U)
54 #define PLL_DIV2_MUX_WIDTH			(1U)
55 #define PLL_BYPASS_MUX_SHIFT			(3U)
56 #define PLL_BYPASS_MUX_WIDTH			(1U)
57 
58 /* Peripheral nodes related definitions */
59 /* Peripheral Clocks */
60 #define PERIPH_MUX_SHIFT			(0U)
61 #define PERIPH_MUX_WIDTH			(3U)
62 #define PERIPH_DIV1_SHIFT			(8U)
63 #define PERIPH_DIV1_WIDTH			(6U)
64 #define PERIPH_DIV2_SHIFT			(16U)
65 #define PERIPH_DIV2_WIDTH			(6U)
66 #define PERIPH_GATE_SHIFT			(24U)
67 #define PERIPH_GATE_WIDTH			(1U)
68 
69 #define USB_GATE_SHIFT				(25U)
70 
71 /* External clock related definitions */
72 
73 #define EXT_CLK_MIO_DATA(mio)				\
74 	[EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = {		\
75 		.name = "mio_clk_"#mio,			\
76 	}
77 
78 #define EXT_CLK_INDEX(n)	(n - CLK_MAX_OUTPUT_CLK)
79 
80 /* Clock control related definitions */
81 #define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
82 
83 #define ISPLL(id)	(id == CLK_APLL_INT ||	\
84 			 id == CLK_DPLL_INT ||  \
85 			 id == CLK_VPLL_INT ||  \
86 			 id == CLK_IOPLL_INT || \
87 			 id == CLK_RPLL_INT)
88 
89 
90 #define PLLCTRL_BP_MASK				BIT(3)
91 #define PLLCTRL_RESET_MASK			(1U)
92 #define PLL_FRAC_OFFSET				(8U)
93 #define PLL_FRAC_MODE				(1U)
94 #define PLL_INT_MODE				(0U)
95 #define PLL_FRAC_MODE_MASK			(0x80000000U)
96 #define PLL_FRAC_MODE_SHIFT			(31U)
97 #define PLL_FRAC_DATA_MASK			(0xFFFFU)
98 #define PLL_FRAC_DATA_SHIFT			(0U)
99 #define PLL_FBDIV_MASK				(0x7F00U)
100 #define PLL_FBDIV_WIDTH				(7U)
101 #define PLL_FBDIV_SHIFT				(8U)
102 
103 #define CLK_PLL_RESET_ASSERT			(1U)
104 #define CLK_PLL_RESET_RELEASE			(2U)
105 #define CLK_PLL_RESET_PULSE	(CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
106 
107 /* Common topology definitions */
108 #define GENERIC_MUX					\
109 	{						\
110 		.type = TYPE_MUX,			\
111 		.offset = PERIPH_MUX_SHIFT,		\
112 		.width = PERIPH_MUX_WIDTH,		\
113 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
114 			    CLK_IS_BASIC),		\
115 		.typeflags = NA_TYPE_FLAGS,		\
116 		.mult = NA_MULT,			\
117 		.div = NA_DIV,				\
118 	}
119 
120 #define IGNORE_UNUSED_MUX				\
121 	{						\
122 		.type = TYPE_MUX,			\
123 		.offset = PERIPH_MUX_SHIFT,		\
124 		.width = PERIPH_MUX_WIDTH,		\
125 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |\
126 			    CLK_SET_RATE_NO_REPARENT |	\
127 			    CLK_IS_BASIC),		\
128 		.typeflags = NA_TYPE_FLAGS,		\
129 		.mult = NA_MULT,			\
130 		.div = NA_DIV,				\
131 	}
132 
133 #define GENERIC_DIV1						\
134 	{							\
135 		.type = TYPE_DIV1,				\
136 		.offset = PERIPH_DIV1_SHIFT,			\
137 		.width = PERIPH_DIV1_WIDTH,			\
138 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
139 			    CLK_IS_BASIC),			\
140 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
141 			     CLK_DIVIDER_ALLOW_ZERO),		\
142 		.mult = NA_MULT,				\
143 		.div = NA_DIV,					\
144 	}
145 
146 #define GENERIC_DIV2						\
147 	{							\
148 		.type = TYPE_DIV2,				\
149 		.offset = PERIPH_DIV2_SHIFT,			\
150 		.width = PERIPH_DIV2_WIDTH,			\
151 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |\
152 			    CLK_SET_RATE_PARENT |		\
153 			    CLK_IS_BASIC),			\
154 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
155 			     CLK_DIVIDER_ALLOW_ZERO),		\
156 		.mult = NA_MULT,				\
157 		.div = NA_DIV,					\
158 	}
159 
160 #define IGNORE_UNUSED_DIV(id)					\
161 	{							\
162 		.type = TYPE_DIV##id,				\
163 		.offset = PERIPH_DIV##id##_SHIFT,		\
164 		.width = PERIPH_DIV##id##_WIDTH,		\
165 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |	\
166 			    CLK_SET_RATE_NO_REPARENT |		\
167 			    CLK_IS_BASIC),			\
168 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED |	\
169 			     CLK_DIVIDER_ALLOW_ZERO),		\
170 		.mult = NA_MULT,				\
171 		.div = NA_DIV,					\
172 	}
173 
174 #define GENERIC_GATE						\
175 	{							\
176 		.type = TYPE_GATE,				\
177 		.offset = PERIPH_GATE_SHIFT,			\
178 		.width = PERIPH_GATE_WIDTH,			\
179 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |	\
180 			    CLK_SET_RATE_GATE |			\
181 			    CLK_IS_BASIC),			\
182 		.typeflags = NA_TYPE_FLAGS,			\
183 		.mult = NA_MULT,				\
184 		.div = NA_DIV,					\
185 	}
186 
187 #define IGNORE_UNUSED_GATE					\
188 	{							\
189 		.type = TYPE_GATE,				\
190 		.offset = PERIPH_GATE_SHIFT,			\
191 		.width = PERIPH_GATE_WIDTH,			\
192 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |	\
193 			    CLK_IGNORE_UNUSED |			\
194 			    CLK_IS_BASIC),			\
195 		.typeflags = NA_TYPE_FLAGS,			\
196 		.mult = NA_MULT,				\
197 		.div = NA_DIV,					\
198 	}
199 
200 /**
201  * struct pm_clock_node - Clock topology node information.
202  * @type: Topology type (mux/div1/div2/gate/pll/fixed factor).
203  * @offset: Offset in control register.
204  * @width: Width of the specific type in control register.
205  * @clkflags: Clk specific flags.
206  * @typeflags: Type specific flags.
207  * @mult: Multiplier for fixed factor.
208  * @div: Divisor for fixed factor.
209  *
210  */
211 struct pm_clock_node {
212 	uint16_t clkflags;
213 	uint16_t typeflags;
214 	uint8_t type;
215 	uint8_t offset;
216 	uint8_t width;
217 	uint8_t mult:4;
218 	uint8_t div:4;
219 };
220 
221 /**
222  * struct pm_clock - Clock structure.
223  * @name: Clock name.
224  * @num_nodes: number of nodes.
225  * @control_reg: Control register address.
226  * @status_reg: Status register address.
227  * @parents: Parents for first clock node. Lower byte indicates parent
228  *           clock id and upper byte indicate flags for that id.
229  * @nodes: Clock nodes.
230  *
231  */
232 struct pm_clock {
233 	char name[CLK_NAME_LEN];
234 	uint8_t num_nodes;
235 	uint32_t control_reg;
236 	uint32_t status_reg;
237 	int32_t (*parents)[];
238 	struct pm_clock_node(*nodes)[];
239 };
240 
241 /**
242  * struct pm_ext_clock - Clock structure.
243  * @name: Clock name.
244  *
245  */
246 struct pm_ext_clock {
247 	char name[CLK_NAME_LEN];
248 };
249 
250 /* PLL Clocks */
251 static struct pm_clock_node generic_pll_nodes[] = {
252 	{
253 		.type = TYPE_PLL,
254 		.offset = NA_SHIFT,
255 		.width = NA_WIDTH,
256 		.clkflags = (uint16_t)CLK_SET_RATE_NO_REPARENT,
257 		.typeflags = NA_TYPE_FLAGS,
258 		.mult = NA_MULT,
259 		.div = NA_DIV,
260 	},
261 };
262 
263 static struct pm_clock_node ignore_unused_pll_nodes[] = {
264 	{
265 		.type = TYPE_PLL,
266 		.offset = NA_SHIFT,
267 		.width = NA_WIDTH,
268 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT),
269 		.typeflags = NA_TYPE_FLAGS,
270 		.mult = NA_MULT,
271 		.div = NA_DIV,
272 	},
273 };
274 
275 static struct pm_clock_node generic_pll_pre_src_nodes[] = {
276 	{
277 		.type = TYPE_MUX,
278 		.offset = PLL_PRESRC_MUX_SHIFT,
279 		.width = PLL_PRESRC_MUX_WIDTH,
280 		.clkflags = (uint16_t)CLK_IS_BASIC,
281 		.typeflags = NA_TYPE_FLAGS,
282 		.mult = NA_MULT,
283 		.div = NA_DIV,
284 	},
285 };
286 
287 static struct pm_clock_node generic_pll_half_nodes[] = {
288 	{
289 		.type = TYPE_FIXEDFACTOR,
290 		.offset = NA_SHIFT,
291 		.width = NA_WIDTH,
292 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT),
293 		.typeflags = NA_TYPE_FLAGS,
294 		.mult = 1,
295 		.div = 2,
296 	},
297 };
298 
299 static struct pm_clock_node generic_pll_int_nodes[] = {
300 	{
301 		.type = TYPE_MUX,
302 		.offset = PLL_DIV2_MUX_SHIFT,
303 		.width =  PLL_DIV2_MUX_WIDTH,
304 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
305 			    CLK_SET_RATE_PARENT |
306 			    CLK_IS_BASIC),
307 		.typeflags = NA_TYPE_FLAGS,
308 		.mult = NA_MULT,
309 		.div = NA_DIV,
310 	},
311 };
312 
313 static struct pm_clock_node generic_pll_post_src_nodes[] = {
314 	{
315 		.type = TYPE_MUX,
316 		.offset = PLL_POSTSRC_MUX_SHIFT,
317 		.width = PLL_POSTSRC_MUX_WIDTH,
318 		.clkflags = (uint16_t)CLK_IS_BASIC,
319 		.typeflags = NA_TYPE_FLAGS,
320 		.mult = NA_MULT,
321 		.div = NA_DIV,
322 	},
323 };
324 
325 static struct pm_clock_node generic_pll_system_nodes[] = {
326 	{
327 		.type = TYPE_MUX,
328 		.offset = PLL_BYPASS_MUX_SHIFT,
329 		.width = PLL_BYPASS_MUX_WIDTH,
330 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
331 			    CLK_SET_RATE_PARENT |
332 			    CLK_IS_BASIC),
333 		.typeflags = NA_TYPE_FLAGS,
334 		.mult = NA_MULT,
335 		.div = NA_DIV,
336 	},
337 };
338 
339 static struct pm_clock_node acpu_nodes[] = {
340 	{
341 		.type = TYPE_MUX,
342 		.offset = PERIPH_MUX_SHIFT,
343 		.width = PERIPH_MUX_WIDTH,
344 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
345 		.typeflags = NA_TYPE_FLAGS,
346 		.mult = NA_MULT,
347 		.div = NA_DIV,
348 	},
349 	{
350 		.type = TYPE_DIV1,
351 		.offset = PERIPH_DIV1_SHIFT,
352 		.width = PERIPH_DIV1_WIDTH,
353 		.clkflags = (uint16_t)CLK_IS_BASIC,
354 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
355 		.mult = NA_MULT,
356 		.div = NA_DIV,
357 	},
358 };
359 
360 static struct pm_clock_node generic_mux_div_nodes[] = {
361 	GENERIC_MUX,
362 	GENERIC_DIV1,
363 };
364 
365 static struct pm_clock_node generic_mux_div_gate_nodes[] = {
366 	GENERIC_MUX,
367 	GENERIC_DIV1,
368 	GENERIC_GATE,
369 };
370 
371 static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
372 	GENERIC_MUX,
373 	GENERIC_DIV1,
374 	IGNORE_UNUSED_GATE,
375 };
376 
377 static struct pm_clock_node generic_mux_div_div_gate_nodes[] = {
378 	GENERIC_MUX,
379 	GENERIC_DIV1,
380 	GENERIC_DIV2,
381 	GENERIC_GATE,
382 };
383 
384 static struct pm_clock_node dp_audio_video_ref_nodes[] = {
385 	{
386 		.type = TYPE_MUX,
387 		.offset = PERIPH_MUX_SHIFT,
388 		.width = PERIPH_MUX_WIDTH,
389 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT |
390 			    CLK_SET_RATE_PARENT | CLK_IS_BASIC),
391 		.typeflags = (uint16_t)CLK_FRAC,
392 		.mult = NA_MULT,
393 		.div = NA_DIV,
394 	},
395 	{
396 		.type = TYPE_DIV1,
397 		.offset = PERIPH_DIV1_SHIFT,
398 		.width = PERIPH_DIV1_WIDTH,
399 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
400 			    CLK_IS_BASIC),
401 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
402 			     CLK_FRAC),
403 		.mult = NA_MULT,
404 		.div = NA_DIV,
405 	},
406 	{
407 		.type = TYPE_DIV2,
408 		.offset = PERIPH_DIV2_SHIFT,
409 		.width = PERIPH_DIV2_WIDTH,
410 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
411 			    CLK_IS_BASIC),
412 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO |
413 			     CLK_FRAC),
414 		.mult = NA_MULT,
415 		.div = NA_DIV,
416 	},
417 	{
418 		.type = TYPE_GATE,
419 		.offset = PERIPH_GATE_SHIFT,
420 		.width = PERIPH_GATE_WIDTH,
421 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
422 			    CLK_SET_RATE_GATE |
423 			    CLK_IS_BASIC),
424 		.typeflags = NA_TYPE_FLAGS,
425 		.mult = NA_MULT,
426 		.div = NA_DIV,
427 	},
428 };
429 
430 static struct pm_clock_node usb_nodes[] = {
431 	GENERIC_MUX,
432 	GENERIC_DIV1,
433 	GENERIC_DIV2,
434 	{
435 		.type = TYPE_GATE,
436 		.offset = USB_GATE_SHIFT,
437 		.width = PERIPH_GATE_WIDTH,
438 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC |
439 			    CLK_SET_RATE_GATE),
440 		.typeflags = NA_TYPE_FLAGS,
441 		.mult = NA_MULT,
442 		.div = NA_DIV,
443 	},
444 };
445 
446 static struct pm_clock_node generic_domain_crossing_nodes[] = {
447 	{
448 		.type = TYPE_DIV1,
449 		.offset = 8,
450 		.width = 6,
451 		.clkflags = (uint16_t)CLK_IS_BASIC,
452 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
453 		.mult = NA_MULT,
454 		.div = NA_DIV,
455 	},
456 };
457 
458 static struct pm_clock_node rpll_to_fpd_nodes[] = {
459 	{
460 		.type = TYPE_DIV1,
461 		.offset = 8,
462 		.width = 6,
463 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
464 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
465 		.mult = NA_MULT,
466 		.div = NA_DIV,
467 	},
468 };
469 
470 static struct pm_clock_node acpu_half_nodes[] = {
471 	{
472 		.type = TYPE_FIXEDFACTOR,
473 		.offset = 0,
474 		.width = 1,
475 		.clkflags = 0,
476 		.typeflags = 0,
477 		.mult = 1,
478 		.div = 2,
479 	},
480 	{
481 		.type = TYPE_GATE,
482 		.offset = 25,
483 		.width = PERIPH_GATE_WIDTH,
484 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
485 			    CLK_SET_RATE_PARENT |
486 			    CLK_IS_BASIC),
487 		.typeflags = NA_TYPE_FLAGS,
488 		.mult = NA_MULT,
489 		.div = NA_DIV,
490 	},
491 };
492 
493 static struct pm_clock_node acpu_full_nodes[] = {
494 	{
495 		.type = TYPE_GATE,
496 		.offset = 24,
497 		.width = PERIPH_GATE_WIDTH,
498 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
499 			    CLK_SET_RATE_PARENT |
500 			    CLK_IS_BASIC),
501 		.typeflags = NA_TYPE_FLAGS,
502 		.mult = NA_MULT,
503 		.div = NA_DIV,
504 	},
505 };
506 
507 static struct pm_clock_node wdt_nodes[] = {
508 	{
509 		.type = TYPE_MUX,
510 		.offset = 0,
511 		.width = 1,
512 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
513 			    CLK_SET_RATE_NO_REPARENT |
514 			    CLK_IS_BASIC),
515 		.typeflags = NA_TYPE_FLAGS,
516 		.mult = NA_MULT,
517 		.div = NA_DIV,
518 	},
519 };
520 
521 static struct pm_clock_node ddr_nodes[] = {
522 	GENERIC_MUX,
523 	{
524 		.type = TYPE_DIV1,
525 		.offset = 8,
526 		.width = 6,
527 		.clkflags = (uint16_t)(CLK_IS_BASIC | CLK_IS_CRITICAL),
528 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
529 		.mult = NA_MULT,
530 		.div = NA_DIV,
531 	},
532 };
533 
534 static struct pm_clock_node pl_nodes[] = {
535 	GENERIC_MUX,
536 	{
537 		.type = TYPE_DIV1,
538 		.offset = PERIPH_DIV1_SHIFT,
539 		.width = PERIPH_DIV1_WIDTH,
540 		.clkflags = (uint16_t)(CLK_IS_BASIC),
541 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
542 		.mult = NA_MULT,
543 		.div = NA_DIV,
544 	},
545 	{
546 		.type = TYPE_DIV2,
547 		.offset = PERIPH_DIV2_SHIFT,
548 		.width = PERIPH_DIV2_WIDTH,
549 		.clkflags = (uint16_t)(CLK_IS_BASIC | CLK_SET_RATE_PARENT),
550 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
551 		.mult = NA_MULT,
552 		.div = NA_DIV,
553 	},
554 	{
555 		.type = TYPE_GATE,
556 		.offset = PERIPH_GATE_SHIFT,
557 		.width = PERIPH_GATE_WIDTH,
558 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
559 		.typeflags = NA_TYPE_FLAGS,
560 		.mult = NA_MULT,
561 		.div = NA_DIV,
562 	},
563 };
564 
565 static struct pm_clock_node gpu_pp0_nodes[] = {
566 	{
567 		.type = TYPE_GATE,
568 		.offset = 25,
569 		.width = PERIPH_GATE_WIDTH,
570 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
571 		.typeflags = NA_TYPE_FLAGS,
572 		.mult = NA_MULT,
573 		.div = NA_DIV,
574 	},
575 };
576 
577 static struct pm_clock_node gpu_pp1_nodes[] = {
578 	{
579 		.type = TYPE_GATE,
580 		.offset = 26,
581 		.width = PERIPH_GATE_WIDTH,
582 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
583 		.typeflags = NA_TYPE_FLAGS,
584 		.mult = NA_MULT,
585 		.div = NA_DIV,
586 	},
587 };
588 
589 static struct pm_clock_node gem_ref_ungated_nodes[] = {
590 	GENERIC_MUX,
591 	{
592 		.type = TYPE_DIV1,
593 		.offset = 8,
594 		.width = 6,
595 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC),
596 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
597 		.mult = NA_MULT,
598 		.div = NA_DIV,
599 	},
600 	{
601 		.type = TYPE_DIV2,
602 		.offset = 16,
603 		.width = 6,
604 		.clkflags = (uint16_t)(CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC |
605 			    CLK_SET_RATE_PARENT),
606 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
607 		.mult = NA_MULT,
608 		.div = NA_DIV,
609 	},
610 };
611 
612 static struct pm_clock_node gem0_ref_nodes[] = {
613 	{
614 		.type = TYPE_MUX,
615 		.offset = 1,
616 		.width = 1,
617 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
618 			    CLK_SET_RATE_NO_REPARENT |
619 			    CLK_IS_BASIC),
620 		.typeflags = NA_TYPE_FLAGS,
621 		.mult = NA_MULT,
622 		.div = NA_DIV,
623 	},
624 };
625 
626 static struct pm_clock_node gem1_ref_nodes[] = {
627 	{
628 		.type = TYPE_MUX,
629 		.offset = 6,
630 		.width = 1,
631 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
632 			    CLK_SET_RATE_NO_REPARENT |
633 			    CLK_IS_BASIC),
634 		.typeflags = NA_TYPE_FLAGS,
635 		.mult = NA_MULT,
636 		.div = NA_DIV,
637 	},
638 };
639 
640 static struct pm_clock_node gem2_ref_nodes[] = {
641 	{
642 		.type = TYPE_MUX,
643 		.offset = 11,
644 		.width = 1,
645 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
646 			    CLK_SET_RATE_NO_REPARENT |
647 			    CLK_IS_BASIC),
648 		.typeflags = NA_TYPE_FLAGS,
649 		.mult = NA_MULT,
650 		.div = NA_DIV,
651 	},
652 };
653 
654 static struct pm_clock_node gem3_ref_nodes[] = {
655 	{
656 		.type = TYPE_MUX,
657 		.offset = 16,
658 		.width = 1,
659 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
660 			    CLK_SET_RATE_NO_REPARENT |
661 			    CLK_IS_BASIC),
662 		.typeflags = NA_TYPE_FLAGS,
663 		.mult = NA_MULT,
664 		.div = NA_DIV,
665 	},
666 };
667 
668 static struct pm_clock_node gem_tx_nodes[] = {
669 	{
670 		.type = TYPE_GATE,
671 		.offset = 25,
672 		.width = PERIPH_GATE_WIDTH,
673 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT | CLK_IS_BASIC),
674 		.typeflags = NA_TYPE_FLAGS,
675 		.mult = NA_MULT,
676 		.div = NA_DIV,
677 	},
678 };
679 
680 static struct pm_clock_node gem_rx_nodes[] = {
681 	{
682 		.type = TYPE_GATE,
683 		.offset = 26,
684 		.width = PERIPH_GATE_WIDTH,
685 		.clkflags = (uint16_t)(CLK_IS_BASIC),
686 		.typeflags = NA_TYPE_FLAGS,
687 		.mult = NA_MULT,
688 		.div = NA_DIV,
689 	},
690 };
691 
692 static struct pm_clock_node gem_tsu_nodes[] = {
693 	{
694 		.type = TYPE_MUX,
695 		.offset = 20,
696 		.width = 2,
697 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
698 			    CLK_SET_RATE_NO_REPARENT |
699 			    CLK_IS_BASIC),
700 		.typeflags = NA_TYPE_FLAGS,
701 		.mult = NA_MULT,
702 		.div = NA_DIV,
703 	},
704 };
705 
706 static struct pm_clock_node can0_mio_nodes[] = {
707 	{
708 		.type = TYPE_MUX,
709 		.offset = 0,
710 		.width = 7,
711 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
712 			    CLK_SET_RATE_NO_REPARENT |
713 			    CLK_IS_BASIC),
714 		.typeflags = NA_TYPE_FLAGS,
715 		.mult = NA_MULT,
716 		.div = NA_DIV,
717 	},
718 };
719 
720 static struct pm_clock_node can1_mio_nodes[] = {
721 	{
722 		.type = TYPE_MUX,
723 		.offset = 15,
724 		.width = 1,
725 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
726 			    CLK_SET_RATE_NO_REPARENT |
727 			    CLK_IS_BASIC),
728 		.typeflags = NA_TYPE_FLAGS,
729 		.mult = NA_MULT,
730 		.div = NA_DIV,
731 	},
732 };
733 
734 static struct pm_clock_node can0_nodes[] = {
735 	{
736 		.type = TYPE_MUX,
737 		.offset = 7,
738 		.width = 1,
739 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
740 			    CLK_SET_RATE_NO_REPARENT |
741 			    CLK_IS_BASIC),
742 		.typeflags = NA_TYPE_FLAGS,
743 		.mult = NA_MULT,
744 		.div = NA_DIV,
745 	},
746 };
747 
748 static struct pm_clock_node can1_nodes[] = {
749 	{
750 		.type = TYPE_MUX,
751 		.offset = 22,
752 		.width = 1,
753 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
754 			    CLK_SET_RATE_NO_REPARENT |
755 			    CLK_IS_BASIC),
756 		.typeflags = NA_TYPE_FLAGS,
757 		.mult = NA_MULT,
758 		.div = NA_DIV,
759 	},
760 };
761 
762 static struct pm_clock_node cpu_r5_core_nodes[] = {
763 	{
764 		.type = TYPE_GATE,
765 		.offset = 25,
766 		.width = PERIPH_GATE_WIDTH,
767 		.clkflags = (uint16_t)(CLK_IGNORE_UNUSED |
768 			    CLK_IS_BASIC),
769 		.typeflags = NA_TYPE_FLAGS,
770 		.mult = NA_MULT,
771 		.div = NA_DIV,
772 	},
773 };
774 
775 static struct pm_clock_node dll_ref_nodes[] = {
776 	{
777 		.type = TYPE_MUX,
778 		.offset = 0,
779 		.width = 3,
780 		.clkflags = (uint16_t)(CLK_SET_RATE_PARENT |
781 			    CLK_SET_RATE_NO_REPARENT |
782 			    CLK_IS_BASIC),
783 		.typeflags = NA_TYPE_FLAGS,
784 		.mult = NA_MULT,
785 		.div = NA_DIV,
786 	},
787 };
788 
789 static struct pm_clock_node timestamp_ref_nodes[] = {
790 	GENERIC_MUX,
791 	{
792 		.type = TYPE_DIV1,
793 		.offset = 8,
794 		.width = 6,
795 		.clkflags = (uint16_t)CLK_IS_BASIC,
796 		.typeflags = (uint16_t)(CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO),
797 		.mult = NA_MULT,
798 		.div = NA_DIV,
799 	},
800 	IGNORE_UNUSED_GATE,
801 };
802 
803 static int32_t can_mio_parents[] = {
804 	EXT_CLK_MIO0, EXT_CLK_MIO1, EXT_CLK_MIO2, EXT_CLK_MIO3,
805 	EXT_CLK_MIO4, EXT_CLK_MIO5, EXT_CLK_MIO6, EXT_CLK_MIO7,
806 	EXT_CLK_MIO8, EXT_CLK_MIO9, EXT_CLK_MIO10, EXT_CLK_MIO11,
807 	EXT_CLK_MIO12, EXT_CLK_MIO13, EXT_CLK_MIO14, EXT_CLK_MIO15,
808 	EXT_CLK_MIO16, EXT_CLK_MIO17, EXT_CLK_MIO18, EXT_CLK_MIO19,
809 	EXT_CLK_MIO20, EXT_CLK_MIO21, EXT_CLK_MIO22, EXT_CLK_MIO23,
810 	EXT_CLK_MIO24, EXT_CLK_MIO25, EXT_CLK_MIO26, EXT_CLK_MIO27,
811 	EXT_CLK_MIO28, EXT_CLK_MIO29, EXT_CLK_MIO30, EXT_CLK_MIO31,
812 	EXT_CLK_MIO32, EXT_CLK_MIO33, EXT_CLK_MIO34, EXT_CLK_MIO35,
813 	EXT_CLK_MIO36, EXT_CLK_MIO37, EXT_CLK_MIO38, EXT_CLK_MIO39,
814 	EXT_CLK_MIO40, EXT_CLK_MIO41, EXT_CLK_MIO42, EXT_CLK_MIO43,
815 	EXT_CLK_MIO44, EXT_CLK_MIO45, EXT_CLK_MIO46, EXT_CLK_MIO47,
816 	EXT_CLK_MIO48, EXT_CLK_MIO49, EXT_CLK_MIO50, EXT_CLK_MIO51,
817 	EXT_CLK_MIO52, EXT_CLK_MIO53, EXT_CLK_MIO54, EXT_CLK_MIO55,
818 	EXT_CLK_MIO56, EXT_CLK_MIO57, EXT_CLK_MIO58, EXT_CLK_MIO59,
819 	EXT_CLK_MIO60, EXT_CLK_MIO61, EXT_CLK_MIO62, EXT_CLK_MIO63,
820 	EXT_CLK_MIO64, EXT_CLK_MIO65, EXT_CLK_MIO66, EXT_CLK_MIO67,
821 	EXT_CLK_MIO68, EXT_CLK_MIO69, EXT_CLK_MIO70, EXT_CLK_MIO71,
822 	EXT_CLK_MIO72, EXT_CLK_MIO73, EXT_CLK_MIO74, EXT_CLK_MIO75,
823 	EXT_CLK_MIO76, EXT_CLK_MIO77, CLK_NA_PARENT
824 };
825 
826 /* Clock array containing clock informaton */
827 static struct pm_clock clocks[] = {
828 	[CLK_APLL_INT] = {
829 		.name = "apll_int",
830 		.control_reg = CRF_APB_APLL_CTRL,
831 		.status_reg = CRF_APB_PLL_STATUS,
832 		.parents = &((int32_t []) {CLK_APLL_PRE_SRC, CLK_NA_PARENT}),
833 		.nodes = &ignore_unused_pll_nodes,
834 		.num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
835 	},
836 	[CLK_APLL_PRE_SRC] = {
837 		.name = "apll_pre_src",
838 		.control_reg = CRF_APB_APLL_CTRL,
839 		.status_reg = CRF_APB_PLL_STATUS,
840 		.parents = &((int32_t []) {
841 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
842 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
843 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
844 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
845 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
846 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
847 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
848 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
849 			CLK_NA_PARENT
850 		}),
851 		.nodes = &generic_pll_pre_src_nodes,
852 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
853 	},
854 	[CLK_APLL_HALF] = {
855 		.name = "apll_half",
856 		.control_reg = CRF_APB_APLL_CTRL,
857 		.status_reg = CRF_APB_PLL_STATUS,
858 		.parents = &((int32_t []) {CLK_APLL_INT, CLK_NA_PARENT}),
859 		.nodes = &generic_pll_half_nodes,
860 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
861 	},
862 	[CLK_APLL_INT_MUX] = {
863 		.name = "apll_int_mux",
864 		.control_reg = CRF_APB_APLL_CTRL,
865 		.status_reg = CRF_APB_PLL_STATUS,
866 		.parents = &((int32_t []) {
867 			CLK_APLL_INT,
868 			CLK_APLL_HALF,
869 			CLK_NA_PARENT
870 		}),
871 		.nodes = &generic_pll_int_nodes,
872 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
873 	},
874 	[CLK_APLL_POST_SRC] = {
875 		.name = "apll_post_src",
876 		.control_reg = CRF_APB_APLL_CTRL,
877 		.status_reg = CRF_APB_PLL_STATUS,
878 		.parents = &((int32_t []) {
879 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
880 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
881 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
882 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
883 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
884 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
885 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
886 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
887 			CLK_NA_PARENT
888 		}),
889 		.nodes = &generic_pll_post_src_nodes,
890 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
891 	},
892 	[CLK_APLL] = {
893 		.name = "apll",
894 		.control_reg = CRF_APB_APLL_CTRL,
895 		.status_reg = CRF_APB_PLL_STATUS,
896 		.parents = &((int32_t []) {
897 			CLK_APLL_INT_MUX,
898 			CLK_APLL_POST_SRC,
899 			CLK_NA_PARENT
900 		}),
901 		.nodes = &generic_pll_system_nodes,
902 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
903 	},
904 	[CLK_DPLL_INT] = {
905 		.name = "dpll_int",
906 		.control_reg = CRF_APB_DPLL_CTRL,
907 		.status_reg = CRF_APB_PLL_STATUS,
908 		.parents = &((int32_t []) {CLK_DPLL_PRE_SRC, CLK_NA_PARENT}),
909 		.nodes = &generic_pll_nodes,
910 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
911 	},
912 	[CLK_DPLL_PRE_SRC] = {
913 		.name = "dpll_pre_src",
914 		.control_reg = CRF_APB_DPLL_CTRL,
915 		.status_reg = CRF_APB_PLL_STATUS,
916 		.parents = &((int32_t []) {
917 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
918 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
919 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
920 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
921 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
922 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
923 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
924 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
925 			CLK_NA_PARENT
926 		}),
927 		.nodes = &generic_pll_pre_src_nodes,
928 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
929 	},
930 	[CLK_DPLL_HALF] = {
931 		.name = "dpll_half",
932 		.control_reg = CRF_APB_DPLL_CTRL,
933 		.status_reg = CRF_APB_PLL_STATUS,
934 		.parents = &((int32_t []) {CLK_DPLL_INT, CLK_NA_PARENT}),
935 		.nodes = &generic_pll_half_nodes,
936 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
937 	},
938 	[CLK_DPLL_INT_MUX] = {
939 		.name = "dpll_int_mux",
940 		.control_reg = CRF_APB_DPLL_CTRL,
941 		.status_reg = CRF_APB_PLL_STATUS,
942 		.parents = &((int32_t []) {
943 			CLK_DPLL_INT,
944 			CLK_DPLL_HALF,
945 			CLK_NA_PARENT
946 		}),
947 		.nodes = &generic_pll_int_nodes,
948 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
949 	},
950 	[CLK_DPLL_POST_SRC] = {
951 		.name = "dpll_post_src",
952 		.control_reg = CRF_APB_DPLL_CTRL,
953 		.status_reg = CRF_APB_PLL_STATUS,
954 		.parents = &((int32_t []) {
955 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
956 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
957 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
958 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
959 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
960 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
961 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
962 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
963 			CLK_NA_PARENT
964 		}),
965 		.nodes = &generic_pll_post_src_nodes,
966 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
967 	},
968 	[CLK_DPLL] = {
969 		.name = "dpll",
970 		.control_reg = CRF_APB_DPLL_CTRL,
971 		.status_reg = CRF_APB_PLL_STATUS,
972 		.parents = &((int32_t []) {
973 			CLK_DPLL_INT_MUX,
974 			CLK_DPLL_POST_SRC,
975 			CLK_NA_PARENT
976 		}),
977 		.nodes = &generic_pll_system_nodes,
978 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
979 	},
980 	[CLK_VPLL_INT] = {
981 		.name = "vpll_int",
982 		.control_reg = CRF_APB_VPLL_CTRL,
983 		.status_reg = CRF_APB_PLL_STATUS,
984 		.parents = &((int32_t []) {CLK_VPLL_PRE_SRC, CLK_NA_PARENT}),
985 		.nodes = &ignore_unused_pll_nodes,
986 		.num_nodes = (uint8_t)ARRAY_SIZE(ignore_unused_pll_nodes),
987 	},
988 	[CLK_VPLL_PRE_SRC] = {
989 		.name = "vpll_pre_src",
990 		.control_reg = CRF_APB_VPLL_CTRL,
991 		.status_reg = CRF_APB_PLL_STATUS,
992 		.parents = &((int32_t []) {
993 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
994 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
995 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
996 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
997 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
998 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
999 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1000 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1001 			CLK_NA_PARENT
1002 		}),
1003 		.nodes = &generic_pll_pre_src_nodes,
1004 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
1005 	},
1006 	[CLK_VPLL_HALF] = {
1007 		.name = "vpll_half",
1008 		.control_reg = CRF_APB_VPLL_CTRL,
1009 		.status_reg = CRF_APB_PLL_STATUS,
1010 		.parents = &((int32_t []) {CLK_VPLL_INT, CLK_NA_PARENT}),
1011 		.nodes = &generic_pll_half_nodes,
1012 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
1013 	},
1014 	[CLK_VPLL_INT_MUX] = {
1015 		.name = "vpll_int_mux",
1016 		.control_reg = CRF_APB_VPLL_CTRL,
1017 		.status_reg = CRF_APB_PLL_STATUS,
1018 		.parents = &((int32_t []) {
1019 			CLK_VPLL_INT,
1020 			CLK_VPLL_HALF,
1021 			CLK_NA_PARENT
1022 		}),
1023 		.nodes = &generic_pll_int_nodes,
1024 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
1025 	},
1026 	[CLK_VPLL_POST_SRC] = {
1027 		.name = "vpll_post_src",
1028 		.control_reg = CRF_APB_VPLL_CTRL,
1029 		.status_reg = CRF_APB_PLL_STATUS,
1030 		.parents = &((int32_t []) {
1031 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1032 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1033 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1034 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1035 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
1036 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
1037 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1038 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1039 			CLK_NA_PARENT
1040 		}),
1041 		.nodes = &generic_pll_post_src_nodes,
1042 		.num_nodes = ARRAY_SIZE(generic_pll_post_src_nodes),
1043 	},
1044 	[CLK_VPLL] = {
1045 		.name = "vpll",
1046 		.control_reg = CRF_APB_VPLL_CTRL,
1047 		.status_reg = CRF_APB_PLL_STATUS,
1048 		.parents = &((int32_t []) {
1049 			CLK_VPLL_INT_MUX,
1050 			CLK_VPLL_POST_SRC,
1051 			CLK_NA_PARENT
1052 		}),
1053 		.nodes = &generic_pll_system_nodes,
1054 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
1055 	},
1056 	[CLK_IOPLL_INT] = {
1057 		.name = "iopll_int",
1058 		.control_reg = CRL_APB_IOPLL_CTRL,
1059 		.status_reg = CRF_APB_PLL_STATUS,
1060 		.parents = &((int32_t []) {CLK_IOPLL_PRE_SRC, CLK_NA_PARENT}),
1061 		.nodes = &generic_pll_nodes,
1062 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
1063 	},
1064 	[CLK_IOPLL_PRE_SRC] = {
1065 		.name = "iopll_pre_src",
1066 		.control_reg = CRL_APB_IOPLL_CTRL,
1067 		.status_reg = CRF_APB_PLL_STATUS,
1068 		.parents = &((int32_t []) {
1069 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1070 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1071 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1072 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1073 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
1074 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
1075 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1076 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1077 			CLK_NA_PARENT
1078 		}),
1079 		.nodes = &generic_pll_pre_src_nodes,
1080 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
1081 	},
1082 	[CLK_IOPLL_HALF] = {
1083 		.name = "iopll_half",
1084 		.control_reg = CRL_APB_IOPLL_CTRL,
1085 		.status_reg = CRF_APB_PLL_STATUS,
1086 		.parents = &((int32_t []) {CLK_IOPLL_INT, CLK_NA_PARENT}),
1087 		.nodes = &generic_pll_half_nodes,
1088 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
1089 	},
1090 	[CLK_IOPLL_INT_MUX] = {
1091 		.name = "iopll_int_mux",
1092 		.control_reg = CRL_APB_IOPLL_CTRL,
1093 		.status_reg = CRF_APB_PLL_STATUS,
1094 		.parents = &((int32_t []) {
1095 			CLK_IOPLL_INT,
1096 			CLK_IOPLL_HALF,
1097 			CLK_NA_PARENT
1098 		}),
1099 		.nodes = &generic_pll_int_nodes,
1100 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
1101 	},
1102 	[CLK_IOPLL_POST_SRC] = {
1103 		.name = "iopll_post_src",
1104 		.control_reg = CRL_APB_IOPLL_CTRL,
1105 		.status_reg = CRF_APB_PLL_STATUS,
1106 		.parents = &((int32_t []) {
1107 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1108 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1109 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1110 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1111 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
1112 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
1113 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1114 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1115 			CLK_NA_PARENT
1116 		}),
1117 		.nodes = &generic_pll_post_src_nodes,
1118 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
1119 	},
1120 	[CLK_IOPLL] = {
1121 		.name = "iopll",
1122 		.control_reg = CRL_APB_IOPLL_CTRL,
1123 		.status_reg = CRF_APB_PLL_STATUS,
1124 		.parents = &((int32_t []) {
1125 			CLK_IOPLL_INT_MUX,
1126 			CLK_IOPLL_POST_SRC,
1127 			CLK_NA_PARENT
1128 		}),
1129 		.nodes = &generic_pll_system_nodes,
1130 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
1131 	},
1132 	[CLK_RPLL_INT] = {
1133 		.name = "rpll_int",
1134 		.control_reg = CRL_APB_RPLL_CTRL,
1135 		.status_reg = CRF_APB_PLL_STATUS,
1136 		.parents = &((int32_t []) {CLK_RPLL_PRE_SRC, CLK_NA_PARENT}),
1137 		.nodes = &generic_pll_nodes,
1138 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_nodes),
1139 	},
1140 	[CLK_RPLL_PRE_SRC] = {
1141 		.name = "rpll_pre_src",
1142 		.control_reg = CRL_APB_RPLL_CTRL,
1143 		.status_reg = CRF_APB_PLL_STATUS,
1144 		.parents = &((int32_t []) {
1145 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1146 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1147 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1148 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1149 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
1150 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
1151 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1152 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1153 			CLK_NA_PARENT
1154 		}),
1155 
1156 		.nodes = &generic_pll_pre_src_nodes,
1157 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_pre_src_nodes),
1158 	},
1159 	[CLK_RPLL_HALF] = {
1160 		.name = "rpll_half",
1161 		.control_reg = CRL_APB_RPLL_CTRL,
1162 		.status_reg = CRF_APB_PLL_STATUS,
1163 		.parents = &((int32_t []) {CLK_RPLL_INT, CLK_NA_PARENT}),
1164 		.nodes = &generic_pll_half_nodes,
1165 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_half_nodes),
1166 	},
1167 	[CLK_RPLL_INT_MUX] = {
1168 		.name = "rpll_int_mux",
1169 		.control_reg = CRL_APB_RPLL_CTRL,
1170 		.status_reg = CRF_APB_PLL_STATUS,
1171 		.parents = &((int32_t []) {
1172 			CLK_RPLL_INT,
1173 			CLK_RPLL_HALF,
1174 			CLK_NA_PARENT
1175 		}),
1176 		.nodes = &generic_pll_int_nodes,
1177 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_int_nodes),
1178 	},
1179 	[CLK_RPLL_POST_SRC] = {
1180 		.name = "rpll_post_src",
1181 		.control_reg = CRL_APB_RPLL_CTRL,
1182 		.status_reg = CRF_APB_PLL_STATUS,
1183 		.parents = &((int32_t []) {
1184 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1185 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1186 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1187 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1188 			EXT_CLK_VIDEO | CLK_EXTERNAL_PARENT,
1189 			EXT_CLK_PSS_ALT_REF | CLK_EXTERNAL_PARENT,
1190 			EXT_CLK_AUX_REF | CLK_EXTERNAL_PARENT,
1191 			EXT_CLK_GT_CRX_REF | CLK_EXTERNAL_PARENT,
1192 			CLK_NA_PARENT
1193 		}),
1194 		.nodes = &generic_pll_post_src_nodes,
1195 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_post_src_nodes),
1196 	},
1197 	[CLK_RPLL] = {
1198 		.name = "rpll",
1199 		.control_reg = CRL_APB_RPLL_CTRL,
1200 		.status_reg = CRL_APB_PLL_STATUS,
1201 		.parents = &((int32_t []) {
1202 			CLK_RPLL_INT_MUX,
1203 			CLK_RPLL_POST_SRC,
1204 			CLK_NA_PARENT
1205 		}),
1206 		.nodes = &generic_pll_system_nodes,
1207 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_pll_system_nodes),
1208 	},
1209 	/* Peripheral Clocks */
1210 	[CLK_ACPU] = {
1211 		.name = "acpu",
1212 		.control_reg = CRF_APB_ACPU_CTRL,
1213 		.status_reg = 0,
1214 		.parents = &((int32_t []) {
1215 			CLK_APLL,
1216 			CLK_DUMMY_PARENT,
1217 			CLK_DPLL,
1218 			CLK_VPLL,
1219 			CLK_NA_PARENT
1220 		}),
1221 		.nodes = &acpu_nodes,
1222 		.num_nodes = (uint8_t)ARRAY_SIZE(acpu_nodes),
1223 	},
1224 	[CLK_ACPU_FULL] = {
1225 		.name = "acpu_full",
1226 		.control_reg = CRF_APB_ACPU_CTRL,
1227 		.status_reg = 0,
1228 		.parents = &((int32_t []) {
1229 			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
1230 			CLK_NA_PARENT
1231 		}),
1232 		.nodes = &acpu_full_nodes,
1233 		.num_nodes = ARRAY_SIZE(acpu_full_nodes),
1234 	},
1235 	[CLK_DBG_TRACE] = {
1236 		.name = "dbg_trace",
1237 		.control_reg = CRF_APB_DBG_TRACE_CTRL,
1238 		.status_reg = 0,
1239 		.parents = &((int32_t []) {
1240 			CLK_IOPLL_TO_FPD,
1241 			CLK_DUMMY_PARENT,
1242 			CLK_DPLL,
1243 			CLK_APLL,
1244 			CLK_NA_PARENT
1245 		}),
1246 		.nodes = &generic_mux_div_gate_nodes,
1247 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1248 	},
1249 	[CLK_DBG_FPD] = {
1250 		.name = "dbg_fpd",
1251 		.control_reg = CRF_APB_DBG_FPD_CTRL,
1252 		.status_reg = 0,
1253 		.parents = &((int32_t []) {
1254 			CLK_IOPLL_TO_FPD,
1255 			CLK_DUMMY_PARENT,
1256 			CLK_DPLL,
1257 			CLK_APLL,
1258 			CLK_NA_PARENT
1259 		}),
1260 		.nodes = &generic_mux_div_gate_nodes,
1261 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1262 	},
1263 	[CLK_DBG_TSTMP] = {
1264 		.name = "dbg_tstmp",
1265 		.control_reg = CRF_APB_DBG_TSTMP_CTRL,
1266 		.status_reg = 0,
1267 		.parents = &((int32_t []) {
1268 			CLK_IOPLL_TO_FPD,
1269 			CLK_DUMMY_PARENT,
1270 			CLK_DPLL,
1271 			CLK_APLL,
1272 			CLK_NA_PARENT
1273 		}),
1274 		.nodes = &generic_mux_div_nodes,
1275 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_nodes),
1276 	},
1277 	[CLK_DP_VIDEO_REF] = {
1278 		.name = "dp_video_ref",
1279 		.control_reg = CRF_APB_DP_VIDEO_REF_CTRL,
1280 		.status_reg = 0,
1281 		.parents = &((int32_t []) {
1282 			CLK_VPLL,
1283 			CLK_DUMMY_PARENT,
1284 			CLK_DPLL,
1285 			CLK_RPLL_TO_FPD,
1286 			CLK_NA_PARENT
1287 		}),
1288 		.nodes = &dp_audio_video_ref_nodes,
1289 		.num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
1290 	},
1291 	[CLK_DP_AUDIO_REF] = {
1292 		.name = "dp_audio_ref",
1293 		.control_reg = CRF_APB_DP_AUDIO_REF_CTRL,
1294 		.status_reg = 0,
1295 		.parents = &((int32_t []) {
1296 			CLK_VPLL,
1297 			CLK_DUMMY_PARENT,
1298 			CLK_DPLL,
1299 			CLK_RPLL_TO_FPD,
1300 			CLK_NA_PARENT
1301 		}),
1302 		.nodes = &dp_audio_video_ref_nodes,
1303 		.num_nodes = (uint8_t)ARRAY_SIZE(dp_audio_video_ref_nodes),
1304 	},
1305 	[CLK_DP_STC_REF] = {
1306 		.name = "dp_stc_ref",
1307 		.control_reg = CRF_APB_DP_STC_REF_CTRL,
1308 		.status_reg = 0,
1309 		.parents = &((int32_t []) {
1310 			CLK_VPLL,
1311 			CLK_DUMMY_PARENT,
1312 			CLK_DPLL,
1313 			CLK_RPLL_TO_FPD,
1314 			CLK_NA_PARENT
1315 		}),
1316 		.nodes = &generic_mux_div_div_gate_nodes,
1317 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1318 	},
1319 	[CLK_DPDMA_REF] = {
1320 		.name = "dpdma_ref",
1321 		.control_reg = CRF_APB_DPDMA_REF_CTRL,
1322 		.status_reg = 0,
1323 		.parents = &((int32_t []) {
1324 			CLK_APLL,
1325 			CLK_DUMMY_PARENT,
1326 			CLK_VPLL,
1327 			CLK_DPLL,
1328 			CLK_NA_PARENT
1329 		}),
1330 		.nodes = &generic_mux_div_gate_nodes,
1331 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1332 	},
1333 	[CLK_DDR_REF] = {
1334 		.name = "ddr_ref",
1335 		.control_reg = CRF_APB_DDR_CTRL,
1336 		.status_reg = 0,
1337 		.parents = &((int32_t []) {
1338 			CLK_DPLL,
1339 			CLK_VPLL,
1340 			CLK_NA_PARENT
1341 		}),
1342 		.nodes = &ddr_nodes,
1343 		.num_nodes = (uint8_t)ARRAY_SIZE(ddr_nodes),
1344 	},
1345 	[CLK_GPU_REF] = {
1346 		.name = "gpu_ref",
1347 		.control_reg = CRF_APB_GPU_REF_CTRL,
1348 		.status_reg = 0,
1349 		.parents = &((int32_t []) {
1350 			CLK_IOPLL_TO_FPD,
1351 			CLK_DUMMY_PARENT,
1352 			CLK_VPLL,
1353 			CLK_DPLL,
1354 			CLK_NA_PARENT
1355 		}),
1356 		.nodes = &generic_mux_div_gate_nodes,
1357 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1358 	},
1359 	[CLK_SATA_REF] = {
1360 		.name = "sata_ref",
1361 		.control_reg = CRF_APB_SATA_REF_CTRL,
1362 		.status_reg = 0,
1363 		.parents = &((int32_t []) {
1364 			CLK_IOPLL_TO_FPD,
1365 			CLK_DUMMY_PARENT,
1366 			CLK_APLL,
1367 			CLK_DPLL,
1368 			CLK_NA_PARENT
1369 		}),
1370 		.nodes = &generic_mux_div_gate_nodes,
1371 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1372 	},
1373 	[CLK_PCIE_REF] = {
1374 		.name = "pcie_ref",
1375 		.control_reg = CRF_APB_PCIE_REF_CTRL,
1376 		.status_reg = 0,
1377 		.parents = &((int32_t []) {
1378 			CLK_IOPLL_TO_FPD,
1379 			CLK_DUMMY_PARENT,
1380 			CLK_RPLL_TO_FPD,
1381 			CLK_DPLL,
1382 			CLK_NA_PARENT
1383 		}),
1384 		.nodes = &generic_mux_div_gate_nodes,
1385 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1386 	},
1387 	[CLK_GDMA_REF] = {
1388 		.name = "gdma_ref",
1389 		.control_reg = CRF_APB_GDMA_REF_CTRL,
1390 		.status_reg = 0,
1391 		.parents = &((int32_t []) {
1392 			CLK_APLL,
1393 			CLK_DUMMY_PARENT,
1394 			CLK_VPLL,
1395 			CLK_DPLL,
1396 			CLK_NA_PARENT
1397 		}),
1398 		.nodes = &generic_mux_div_gate_nodes,
1399 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1400 	},
1401 	[CLK_GTGREF0_REF] = {
1402 		.name = "gtgref0_ref",
1403 		.control_reg = CRF_APB_GTGREF0_REF_CTRL,
1404 		.status_reg = 0,
1405 		.parents = &((int32_t []) {
1406 			CLK_IOPLL_TO_FPD,
1407 			CLK_DUMMY_PARENT,
1408 			CLK_APLL,
1409 			CLK_DPLL,
1410 			CLK_NA_PARENT
1411 		}),
1412 		.nodes = &generic_mux_div_gate_nodes,
1413 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1414 	},
1415 	[CLK_TOPSW_MAIN] = {
1416 		.name = "topsw_main",
1417 		.control_reg = CRF_APB_TOPSW_MAIN_CTRL,
1418 		.status_reg = 0,
1419 		.parents = &((int32_t []) {
1420 			CLK_APLL,
1421 			CLK_DUMMY_PARENT,
1422 			CLK_VPLL,
1423 			CLK_DPLL,
1424 			CLK_NA_PARENT
1425 		}),
1426 		.nodes = &generic_mux_div_unused_gate_nodes,
1427 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1428 	},
1429 	[CLK_TOPSW_LSBUS] = {
1430 		.name = "topsw_lsbus",
1431 		.control_reg = CRF_APB_TOPSW_LSBUS_CTRL,
1432 		.status_reg = 0,
1433 		.parents = &((int32_t []) {
1434 			CLK_APLL,
1435 			CLK_DUMMY_PARENT,
1436 			CLK_IOPLL_TO_FPD,
1437 			CLK_DPLL,
1438 			CLK_NA_PARENT
1439 		}),
1440 		.nodes = &generic_mux_div_unused_gate_nodes,
1441 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1442 	},
1443 	[CLK_IOU_SWITCH] = {
1444 		.name = "iou_switch",
1445 		.control_reg = CRL_APB_IOU_SWITCH_CTRL,
1446 		.status_reg = 0,
1447 		.parents = &((int32_t []) {
1448 			CLK_RPLL,
1449 			CLK_DUMMY_PARENT,
1450 			CLK_IOPLL,
1451 			CLK_DPLL_TO_LPD,
1452 			CLK_NA_PARENT
1453 		}),
1454 		.nodes = &generic_mux_div_unused_gate_nodes,
1455 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1456 	},
1457 	[CLK_GEM0_REF_UNGATED] = {
1458 		.name = "gem0_ref_ung",
1459 		.control_reg = CRL_APB_GEM0_REF_CTRL,
1460 		.status_reg = 0,
1461 		.parents = &((int32_t []) {
1462 			CLK_IOPLL,
1463 			CLK_DUMMY_PARENT,
1464 			CLK_RPLL,
1465 			CLK_DPLL_TO_LPD,
1466 			CLK_NA_PARENT
1467 		}),
1468 		.nodes = &gem_ref_ungated_nodes,
1469 		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
1470 	},
1471 	[CLK_GEM1_REF_UNGATED] = {
1472 		.name = "gem1_ref_ung",
1473 		.control_reg = CRL_APB_GEM1_REF_CTRL,
1474 		.status_reg = 0,
1475 		.parents = &((int32_t []) {
1476 			CLK_IOPLL,
1477 			CLK_DUMMY_PARENT,
1478 			CLK_RPLL,
1479 			CLK_DPLL_TO_LPD,
1480 			CLK_NA_PARENT
1481 		}),
1482 		.nodes = &gem_ref_ungated_nodes,
1483 		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
1484 	},
1485 	[CLK_GEM2_REF_UNGATED] = {
1486 		.name = "gem2_ref_ung",
1487 		.control_reg = CRL_APB_GEM2_REF_CTRL,
1488 		.status_reg = 0,
1489 		.parents = &((int32_t []) {
1490 			CLK_IOPLL,
1491 			CLK_DUMMY_PARENT,
1492 			CLK_RPLL,
1493 			CLK_DPLL_TO_LPD,
1494 			CLK_NA_PARENT
1495 		}),
1496 		.nodes = &gem_ref_ungated_nodes,
1497 		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
1498 	},
1499 	[CLK_GEM3_REF_UNGATED] = {
1500 		.name = "gem3_ref_ung",
1501 		.control_reg = CRL_APB_GEM3_REF_CTRL,
1502 		.status_reg = 0,
1503 		.parents = &((int32_t []) {
1504 			CLK_IOPLL,
1505 			CLK_DUMMY_PARENT,
1506 			CLK_RPLL,
1507 			CLK_DPLL_TO_LPD,
1508 			CLK_NA_PARENT
1509 		}),
1510 		.nodes = &gem_ref_ungated_nodes,
1511 		.num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes),
1512 	},
1513 	[CLK_GEM0_REF] = {
1514 		.name = "gem0_ref",
1515 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1516 		.status_reg = 0,
1517 		.parents = &((int32_t []) {
1518 			CLK_GEM0_REF_UNGATED |
1519 			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1520 			EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT,
1521 			CLK_NA_PARENT
1522 		}),
1523 		.nodes = &gem0_ref_nodes,
1524 		.num_nodes = ARRAY_SIZE(gem0_ref_nodes),
1525 	},
1526 	[CLK_GEM1_REF] = {
1527 		.name = "gem1_ref",
1528 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1529 		.status_reg = 0,
1530 		.parents = &((int32_t []) {
1531 			CLK_GEM1_REF_UNGATED |
1532 			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1533 			EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT,
1534 			CLK_NA_PARENT
1535 		}),
1536 		.nodes = &gem1_ref_nodes,
1537 		.num_nodes = ARRAY_SIZE(gem1_ref_nodes),
1538 	},
1539 	[CLK_GEM2_REF] = {
1540 		.name = "gem2_ref",
1541 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1542 		.status_reg = 0,
1543 		.parents = &((int32_t []) {
1544 			CLK_GEM2_REF_UNGATED |
1545 			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1546 			EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT,
1547 			CLK_NA_PARENT
1548 		}),
1549 		.nodes = &gem2_ref_nodes,
1550 		.num_nodes = ARRAY_SIZE(gem2_ref_nodes),
1551 	},
1552 	[CLK_GEM3_REF] = {
1553 		.name = "gem3_ref",
1554 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1555 		.status_reg = 0,
1556 		.parents = &((int32_t []) {
1557 			CLK_GEM3_REF_UNGATED |
1558 			(PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1559 			EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT,
1560 			CLK_NA_PARENT
1561 		}),
1562 		.nodes = &gem3_ref_nodes,
1563 		.num_nodes = ARRAY_SIZE(gem3_ref_nodes),
1564 	},
1565 	[CLK_USB0_BUS_REF] = {
1566 		.name = "usb0_bus_ref",
1567 		.control_reg = CRL_APB_USB0_BUS_REF_CTRL,
1568 		.status_reg = 0,
1569 		.parents = &((int32_t []) {
1570 			CLK_IOPLL,
1571 			CLK_DUMMY_PARENT,
1572 			CLK_RPLL,
1573 			CLK_DPLL_TO_LPD,
1574 			CLK_NA_PARENT
1575 		}),
1576 		.nodes = &usb_nodes,
1577 		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
1578 	},
1579 	[CLK_USB1_BUS_REF] = {
1580 		.name = "usb1_bus_ref",
1581 		.control_reg = CRL_APB_USB1_BUS_REF_CTRL,
1582 		.status_reg = 0,
1583 		.parents = &((int32_t []) {
1584 			CLK_IOPLL,
1585 			CLK_DUMMY_PARENT,
1586 			CLK_RPLL,
1587 			CLK_DPLL_TO_LPD,
1588 			CLK_NA_PARENT
1589 		}),
1590 		.nodes = &usb_nodes,
1591 		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
1592 	},
1593 	[CLK_USB3_DUAL_REF] = {
1594 		.name = "usb3_dual_ref",
1595 		.control_reg = CRL_APB_USB3_DUAL_REF_CTRL,
1596 		.status_reg = 0,
1597 		.parents = &((int32_t []) {
1598 			CLK_IOPLL,
1599 			CLK_DUMMY_PARENT,
1600 			CLK_RPLL,
1601 			CLK_DPLL_TO_LPD,
1602 			CLK_NA_PARENT
1603 		}),
1604 		.nodes = &usb_nodes,
1605 		.num_nodes = (uint8_t)ARRAY_SIZE(usb_nodes),
1606 	},
1607 	[CLK_QSPI_REF] = {
1608 		.name = "qspi_ref",
1609 		.control_reg = CRL_APB_QSPI_REF_CTRL,
1610 		.status_reg = 0,
1611 		.parents = &((int32_t []) {
1612 			CLK_IOPLL,
1613 			CLK_DUMMY_PARENT,
1614 			CLK_RPLL,
1615 			CLK_DPLL_TO_LPD,
1616 			CLK_NA_PARENT
1617 		}),
1618 		.nodes = &generic_mux_div_div_gate_nodes,
1619 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1620 	},
1621 	[CLK_SDIO0_REF] = {
1622 		.name = "sdio0_ref",
1623 		.control_reg = CRL_APB_SDIO0_REF_CTRL,
1624 		.status_reg = 0,
1625 		.parents = &((int32_t []) {
1626 			CLK_IOPLL,
1627 			CLK_DUMMY_PARENT,
1628 			CLK_RPLL,
1629 			CLK_VPLL_TO_LPD,
1630 			CLK_NA_PARENT
1631 		}),
1632 		.nodes = &generic_mux_div_div_gate_nodes,
1633 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1634 	},
1635 	[CLK_SDIO1_REF] = {
1636 		.name = "sdio1_ref",
1637 		.control_reg = CRL_APB_SDIO1_REF_CTRL,
1638 		.status_reg = 0,
1639 		.parents = &((int32_t []) {
1640 			CLK_IOPLL,
1641 			CLK_DUMMY_PARENT,
1642 			CLK_RPLL,
1643 			CLK_VPLL_TO_LPD,
1644 			CLK_NA_PARENT
1645 		}),
1646 		.nodes = &generic_mux_div_div_gate_nodes,
1647 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1648 	},
1649 	[CLK_UART0_REF] = {
1650 		.name = "uart0_ref",
1651 		.control_reg = CRL_APB_UART0_REF_CTRL,
1652 		.status_reg = 0,
1653 		.parents = &((int32_t []) {
1654 			CLK_IOPLL,
1655 			CLK_DUMMY_PARENT,
1656 			CLK_RPLL,
1657 			CLK_DPLL_TO_LPD,
1658 			CLK_NA_PARENT
1659 		}),
1660 		.nodes = &generic_mux_div_div_gate_nodes,
1661 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1662 	},
1663 	[CLK_UART1_REF] = {
1664 		.name = "uart1_ref",
1665 		.control_reg = CRL_APB_UART1_REF_CTRL,
1666 		.status_reg = 0,
1667 		.parents = &((int32_t []) {
1668 			CLK_IOPLL,
1669 			CLK_DUMMY_PARENT,
1670 			CLK_RPLL,
1671 			CLK_DPLL_TO_LPD,
1672 			CLK_NA_PARENT
1673 		}),
1674 		.nodes = &generic_mux_div_div_gate_nodes,
1675 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1676 	},
1677 	[CLK_SPI0_REF] = {
1678 		.name = "spi0_ref",
1679 		.control_reg = CRL_APB_SPI0_REF_CTRL,
1680 		.status_reg = 0,
1681 		.parents = &((int32_t []) {
1682 			CLK_IOPLL,
1683 			CLK_DUMMY_PARENT,
1684 			CLK_RPLL,
1685 			CLK_DPLL_TO_LPD,
1686 			CLK_NA_PARENT
1687 		}),
1688 		.nodes = &generic_mux_div_div_gate_nodes,
1689 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1690 	},
1691 	[CLK_SPI1_REF] = {
1692 		.name = "spi1_ref",
1693 		.control_reg = CRL_APB_SPI1_REF_CTRL,
1694 		.status_reg = 0,
1695 		.parents = &((int32_t []) {
1696 			CLK_IOPLL,
1697 			CLK_DUMMY_PARENT,
1698 			CLK_RPLL,
1699 			CLK_DPLL_TO_LPD,
1700 			CLK_NA_PARENT
1701 		}),
1702 		.nodes = &generic_mux_div_div_gate_nodes,
1703 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1704 	},
1705 	[CLK_CAN0_REF] = {
1706 		.name = "can0_ref",
1707 		.control_reg = CRL_APB_CAN0_REF_CTRL,
1708 		.status_reg = 0,
1709 		.parents = &((int32_t []) {
1710 			CLK_IOPLL,
1711 			CLK_DUMMY_PARENT,
1712 			CLK_RPLL,
1713 			CLK_DPLL_TO_LPD,
1714 			CLK_NA_PARENT
1715 		}),
1716 		.nodes = &generic_mux_div_div_gate_nodes,
1717 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1718 	},
1719 	[CLK_CAN1_REF] = {
1720 		.name = "can1_ref",
1721 		.control_reg = CRL_APB_CAN1_REF_CTRL,
1722 		.status_reg = 0,
1723 		.parents = &((int32_t []) {
1724 			CLK_IOPLL,
1725 			CLK_DUMMY_PARENT,
1726 			CLK_RPLL,
1727 			CLK_DPLL_TO_LPD,
1728 			CLK_NA_PARENT
1729 		}),
1730 		.nodes = &generic_mux_div_div_gate_nodes,
1731 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1732 	},
1733 	[CLK_NAND_REF] = {
1734 		.name = "nand_ref",
1735 		.control_reg = CRL_APB_NAND_REF_CTRL,
1736 		.status_reg = 0,
1737 		.parents = &((int32_t []) {
1738 			CLK_IOPLL,
1739 			CLK_DUMMY_PARENT,
1740 			CLK_RPLL,
1741 			CLK_DPLL_TO_LPD,
1742 			CLK_NA_PARENT
1743 		}),
1744 		.nodes = &generic_mux_div_div_gate_nodes,
1745 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1746 	},
1747 	[CLK_GEM_TSU_REF] = {
1748 		.name = "gem_tsu_ref",
1749 		.control_reg = CRL_APB_GEM_TSU_REF_CTRL,
1750 		.status_reg = 0,
1751 		.parents = &((int32_t []) {
1752 			CLK_IOPLL,
1753 			CLK_DUMMY_PARENT,
1754 			CLK_RPLL,
1755 			CLK_DPLL_TO_LPD,
1756 			CLK_NA_PARENT
1757 		}),
1758 		.nodes = &generic_mux_div_div_gate_nodes,
1759 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1760 	},
1761 	[CLK_DLL_REF] = {
1762 		.name = "dll_ref",
1763 		.control_reg = CRL_APB_DLL_REF_CTRL,
1764 		.status_reg = 0,
1765 		.parents = &((int32_t []) {
1766 			CLK_IOPLL,
1767 			CLK_RPLL,
1768 			CLK_NA_PARENT
1769 		}),
1770 		.nodes = &dll_ref_nodes,
1771 		.num_nodes = (uint8_t)ARRAY_SIZE(dll_ref_nodes),
1772 	},
1773 	[CLK_ADMA_REF] = {
1774 		.name = "adma_ref",
1775 		.control_reg = CRL_APB_ADMA_REF_CTRL,
1776 		.status_reg = 0,
1777 		.parents = &((int32_t []) {
1778 			CLK_RPLL,
1779 			CLK_DUMMY_PARENT,
1780 			CLK_IOPLL,
1781 			CLK_DPLL_TO_LPD,
1782 			CLK_NA_PARENT
1783 		}),
1784 		.nodes = &generic_mux_div_gate_nodes,
1785 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1786 	},
1787 	[CLK_DBG_LPD] = {
1788 		.name = "dbg_lpd",
1789 		.control_reg = CRL_APB_DBG_LPD_CTRL,
1790 		.status_reg = 0,
1791 		.parents = &((int32_t []) {
1792 			CLK_RPLL,
1793 			CLK_DUMMY_PARENT,
1794 			CLK_IOPLL,
1795 			CLK_DPLL_TO_LPD,
1796 			CLK_NA_PARENT
1797 		}),
1798 		.nodes = &generic_mux_div_gate_nodes,
1799 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1800 	},
1801 	[CLK_CPU_R5] = {
1802 		.name = "cpu_r5",
1803 		.control_reg = CRL_APB_CPU_R5_CTRL,
1804 		.status_reg = 0,
1805 		.parents = &((int32_t []) {
1806 			CLK_RPLL,
1807 			CLK_DUMMY_PARENT,
1808 			CLK_IOPLL,
1809 			CLK_DPLL_TO_LPD,
1810 			CLK_NA_PARENT
1811 		}),
1812 		.nodes = &generic_mux_div_unused_gate_nodes,
1813 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1814 	},
1815 	[CLK_CSU_PLL] = {
1816 		.name = "csu_pll",
1817 		.control_reg = CRL_APB_CSU_PLL_CTRL,
1818 		.status_reg = 0,
1819 		.parents = &((int32_t []) {
1820 			CLK_IOPLL,
1821 			CLK_DUMMY_PARENT,
1822 			CLK_RPLL,
1823 			CLK_DPLL_TO_LPD,
1824 			CLK_NA_PARENT
1825 		}),
1826 		.nodes = &generic_mux_div_gate_nodes,
1827 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1828 	},
1829 	[CLK_PCAP] = {
1830 		.name = "pcap",
1831 		.control_reg = CRL_APB_PCAP_CTRL,
1832 		.status_reg = 0,
1833 		.parents = &((int32_t []) {
1834 			CLK_IOPLL,
1835 			CLK_DUMMY_PARENT,
1836 			CLK_RPLL,
1837 			CLK_DPLL_TO_LPD,
1838 			CLK_NA_PARENT
1839 		}),
1840 		.nodes = &generic_mux_div_gate_nodes,
1841 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_gate_nodes),
1842 	},
1843 	[CLK_LPD_LSBUS] = {
1844 		.name = "lpd_lsbus",
1845 		.control_reg = CRL_APB_LPD_LSBUS_CTRL,
1846 		.status_reg = 0,
1847 		.parents = &((int32_t []) {
1848 			CLK_RPLL,
1849 			CLK_DUMMY_PARENT,
1850 			CLK_IOPLL,
1851 			CLK_DPLL_TO_LPD,
1852 			CLK_NA_PARENT
1853 		}),
1854 		.nodes = &generic_mux_div_unused_gate_nodes,
1855 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1856 	},
1857 	[CLK_LPD_SWITCH] = {
1858 		.name = "lpd_switch",
1859 		.control_reg = CRL_APB_LPD_SWITCH_CTRL,
1860 		.status_reg = 0,
1861 		.parents = &((int32_t []) {
1862 			CLK_RPLL,
1863 			CLK_DUMMY_PARENT,
1864 			CLK_IOPLL,
1865 			CLK_DPLL_TO_LPD,
1866 			CLK_NA_PARENT
1867 		}),
1868 		.nodes = &generic_mux_div_unused_gate_nodes,
1869 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1870 	},
1871 	[CLK_I2C0_REF] = {
1872 		.name = "i2c0_ref",
1873 		.control_reg = CRL_APB_I2C0_REF_CTRL,
1874 		.status_reg = 0,
1875 		.parents = &((int32_t []) {
1876 			CLK_IOPLL,
1877 			CLK_DUMMY_PARENT,
1878 			CLK_RPLL,
1879 			CLK_DPLL_TO_LPD,
1880 			CLK_NA_PARENT
1881 		}),
1882 		.nodes = &generic_mux_div_div_gate_nodes,
1883 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1884 	},
1885 	[CLK_I2C1_REF] = {
1886 		.name = "i2c1_ref",
1887 		.control_reg = CRL_APB_I2C1_REF_CTRL,
1888 		.status_reg = 0,
1889 		.parents = &((int32_t []) {
1890 			CLK_IOPLL,
1891 			CLK_DUMMY_PARENT,
1892 			CLK_RPLL,
1893 			CLK_DPLL_TO_LPD,
1894 			CLK_NA_PARENT
1895 		}),
1896 		.nodes = &generic_mux_div_div_gate_nodes,
1897 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1898 	},
1899 	[CLK_TIMESTAMP_REF] = {
1900 		.name = "timestamp_ref",
1901 		.control_reg = CRL_APB_TIMESTAMP_REF_CTRL,
1902 		.status_reg = 0,
1903 		.parents = &((int32_t []) {
1904 			CLK_IOPLL,
1905 			CLK_DUMMY_PARENT,
1906 			CLK_RPLL,
1907 			CLK_DPLL_TO_LPD,
1908 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1909 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1910 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1911 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1912 			CLK_NA_PARENT
1913 		}),
1914 		.nodes = &timestamp_ref_nodes,
1915 		.num_nodes = (uint8_t)ARRAY_SIZE(timestamp_ref_nodes),
1916 	},
1917 	[CLK_PL0_REF] = {
1918 		.name = "pl0_ref",
1919 		.control_reg = CRL_APB_PL0_REF_CTRL,
1920 		.status_reg = 0,
1921 		.parents = &((int32_t []) {
1922 			CLK_IOPLL,
1923 			CLK_DUMMY_PARENT,
1924 			CLK_RPLL,
1925 			CLK_DPLL_TO_LPD,
1926 			CLK_NA_PARENT
1927 		}),
1928 		.nodes = &pl_nodes,
1929 		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
1930 	},
1931 	[CLK_PL1_REF] = {
1932 		.name = "pl1_ref",
1933 		.control_reg = CRL_APB_PL1_REF_CTRL,
1934 		.status_reg = 0,
1935 		.parents = &((int32_t []) {
1936 			CLK_IOPLL,
1937 			CLK_DUMMY_PARENT,
1938 			CLK_RPLL,
1939 			CLK_DPLL_TO_LPD,
1940 			CLK_NA_PARENT
1941 		}),
1942 		.nodes = &pl_nodes,
1943 		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
1944 	},
1945 	[CLK_PL2_REF] = {
1946 		.name = "pl2_ref",
1947 		.control_reg = CRL_APB_PL2_REF_CTRL,
1948 		.status_reg = 0,
1949 		.parents = &((int32_t []) {
1950 			CLK_IOPLL,
1951 			CLK_DUMMY_PARENT,
1952 			CLK_RPLL,
1953 			CLK_DPLL_TO_LPD,
1954 			CLK_NA_PARENT
1955 		}),
1956 		.nodes = &pl_nodes,
1957 		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
1958 	},
1959 	[CLK_PL3_REF] = {
1960 		.name = "pl3_ref",
1961 		.control_reg = CRL_APB_PL3_REF_CTRL,
1962 		.status_reg = 0,
1963 		.parents = &((int32_t []) {
1964 			CLK_IOPLL,
1965 			CLK_DUMMY_PARENT,
1966 			CLK_RPLL,
1967 			CLK_DPLL_TO_LPD,
1968 			CLK_NA_PARENT
1969 		}),
1970 		.nodes = &pl_nodes,
1971 		.num_nodes = (uint8_t)ARRAY_SIZE(pl_nodes),
1972 	},
1973 	[CLK_AMS_REF] = {
1974 		.name = "ams_ref",
1975 		.control_reg = CRL_APB_AMS_REF_CTRL,
1976 		.status_reg = 0,
1977 		.parents = &((int32_t []) {
1978 			CLK_RPLL,
1979 			CLK_DUMMY_PARENT,
1980 			CLK_IOPLL,
1981 			CLK_DPLL_TO_LPD,
1982 			CLK_NA_PARENT
1983 		}),
1984 		.nodes = &generic_mux_div_div_gate_nodes,
1985 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1986 	},
1987 	[CLK_IOPLL_TO_FPD] = {
1988 		.name = "iopll_to_fpd",
1989 		.control_reg = CRL_APB_IOPLL_TO_FPD_CTRL,
1990 		.status_reg = 0,
1991 		.parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
1992 		.nodes = &generic_domain_crossing_nodes,
1993 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
1994 	},
1995 	[CLK_RPLL_TO_FPD] = {
1996 		.name = "rpll_to_fpd",
1997 		.control_reg = CRL_APB_RPLL_TO_FPD_CTRL,
1998 		.status_reg = 0,
1999 		.parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
2000 		.nodes = &rpll_to_fpd_nodes,
2001 		.num_nodes = (uint8_t)ARRAY_SIZE(rpll_to_fpd_nodes),
2002 	},
2003 	[CLK_APLL_TO_LPD] = {
2004 		.name = "apll_to_lpd",
2005 		.control_reg = CRF_APB_APLL_TO_LPD_CTRL,
2006 		.status_reg = 0,
2007 		.parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
2008 		.nodes = &generic_domain_crossing_nodes,
2009 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
2010 	},
2011 	[CLK_DPLL_TO_LPD] = {
2012 		.name = "dpll_to_lpd",
2013 		.control_reg = CRF_APB_DPLL_TO_LPD_CTRL,
2014 		.status_reg = 0,
2015 		.parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
2016 		.nodes = &generic_domain_crossing_nodes,
2017 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
2018 	},
2019 	[CLK_VPLL_TO_LPD] = {
2020 		.name = "vpll_to_lpd",
2021 		.control_reg = CRF_APB_VPLL_TO_LPD_CTRL,
2022 		.status_reg = 0,
2023 		.parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
2024 		.nodes = &generic_domain_crossing_nodes,
2025 		.num_nodes = (uint8_t)ARRAY_SIZE(generic_domain_crossing_nodes),
2026 	},
2027 	[CLK_GEM0_TX] = {
2028 		.name = "gem0_tx",
2029 		.control_reg = CRL_APB_GEM0_REF_CTRL,
2030 		.status_reg = 0,
2031 		.parents = &((int32_t []) {
2032 			CLK_GEM0_REF,
2033 			CLK_NA_PARENT
2034 		}),
2035 		.nodes = &gem_tx_nodes,
2036 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
2037 	},
2038 	[CLK_GEM1_TX] = {
2039 		.name = "gem1_tx",
2040 		.control_reg = CRL_APB_GEM1_REF_CTRL,
2041 		.status_reg = 0,
2042 		.parents = &((int32_t []) {
2043 			CLK_GEM1_REF,
2044 			CLK_NA_PARENT
2045 		}),
2046 		.nodes = &gem_tx_nodes,
2047 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
2048 	},
2049 	[CLK_GEM2_TX] = {
2050 		.name = "gem2_tx",
2051 		.control_reg = CRL_APB_GEM2_REF_CTRL,
2052 		.status_reg = 0,
2053 		.parents = &((int32_t []) {
2054 			CLK_GEM2_REF,
2055 			CLK_NA_PARENT
2056 		}),
2057 		.nodes = &gem_tx_nodes,
2058 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
2059 	},
2060 	[CLK_GEM3_TX] = {
2061 		.name = "gem3_tx",
2062 		.control_reg = CRL_APB_GEM3_REF_CTRL,
2063 		.status_reg = 0,
2064 		.parents = &((int32_t []) {
2065 			CLK_GEM3_REF,
2066 			CLK_NA_PARENT
2067 		}),
2068 		.nodes = &gem_tx_nodes,
2069 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tx_nodes),
2070 	},
2071 	[CLK_GEM0_RX] = {
2072 		.name = "gem0_rx",
2073 		.control_reg = CRL_APB_GEM0_REF_CTRL,
2074 		.status_reg = 0,
2075 		.parents = &((int32_t []) {
2076 			EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT,
2077 			CLK_NA_PARENT
2078 		}),
2079 		.nodes = &gem_rx_nodes,
2080 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
2081 	},
2082 	[CLK_GEM1_RX] = {
2083 		.name = "gem1_rx",
2084 		.control_reg = CRL_APB_GEM1_REF_CTRL,
2085 		.status_reg = 0,
2086 		.parents = &((int32_t []) {
2087 			EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT,
2088 			CLK_NA_PARENT
2089 		}),
2090 		.nodes = &gem_rx_nodes,
2091 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
2092 	},
2093 	[CLK_GEM2_RX] = {
2094 		.name = "gem2_rx",
2095 		.control_reg = CRL_APB_GEM2_REF_CTRL,
2096 		.status_reg = 0,
2097 		.parents = &((int32_t []) {
2098 			EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT,
2099 			CLK_NA_PARENT
2100 		}),
2101 		.nodes = &gem_rx_nodes,
2102 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
2103 	},
2104 	[CLK_GEM3_RX] = {
2105 		.name = "gem3_rx",
2106 		.control_reg = CRL_APB_GEM3_REF_CTRL,
2107 		.status_reg = 0,
2108 		.parents = &((int32_t []) {
2109 			EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT,
2110 			CLK_NA_PARENT
2111 		}),
2112 		.nodes = &gem_rx_nodes,
2113 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_rx_nodes),
2114 	},
2115 	[CLK_ACPU_HALF] = {
2116 		.name = "acpu_half",
2117 		.control_reg = CRF_APB_ACPU_CTRL,
2118 		.status_reg = 0,
2119 		.parents = &((int32_t []) {
2120 			(CLK_ACPU | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
2121 			CLK_NA_PARENT
2122 		}),
2123 		.nodes = &acpu_half_nodes,
2124 		.num_nodes = (uint8_t)ARRAY_SIZE(acpu_half_nodes),
2125 	},
2126 	[CLK_FPD_WDT] = {
2127 		.name = "fpd_wdt",
2128 		.control_reg = FPD_SLCR_WDT_CLK_SEL,
2129 		.status_reg = 0,
2130 		.parents = &((int32_t []) {
2131 			CLK_TOPSW_LSBUS,
2132 			EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
2133 			CLK_NA_PARENT
2134 		}),
2135 		.nodes = &wdt_nodes,
2136 		.num_nodes = (uint8_t)ARRAY_SIZE(wdt_nodes),
2137 	},
2138 	[CLK_GPU_PP0_REF] = {
2139 		.name = "gpu_pp0_ref",
2140 		.control_reg = CRF_APB_GPU_REF_CTRL,
2141 		.status_reg = 0,
2142 		.parents = &((int32_t []) {
2143 			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
2144 			CLK_NA_PARENT
2145 		}),
2146 		.nodes = &gpu_pp0_nodes,
2147 		.num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp0_nodes),
2148 	},
2149 	[CLK_GPU_PP1_REF] = {
2150 		.name = "gpu_pp1_ref",
2151 		.control_reg = CRF_APB_GPU_REF_CTRL,
2152 		.status_reg = 0,
2153 		.parents = &((int32_t []) {
2154 			(CLK_GPU_REF | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
2155 			CLK_NA_PARENT
2156 		}),
2157 		.nodes = &gpu_pp1_nodes,
2158 		.num_nodes = (uint8_t)ARRAY_SIZE(gpu_pp1_nodes),
2159 	},
2160 	[CLK_GEM_TSU] = {
2161 		.name = "gem_tsu",
2162 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
2163 		.status_reg = 0,
2164 		.parents = &((int32_t []) {
2165 			CLK_GEM_TSU_REF,
2166 			CLK_GEM_TSU_REF,
2167 			EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
2168 			EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
2169 			CLK_NA_PARENT
2170 		}),
2171 		.nodes = &gem_tsu_nodes,
2172 		.num_nodes = (uint8_t)ARRAY_SIZE(gem_tsu_nodes),
2173 	},
2174 	[CLK_CPU_R5_CORE] = {
2175 		.name = "cpu_r5_core",
2176 		.control_reg = CRL_APB_CPU_R5_CTRL,
2177 		.status_reg = 0,
2178 		.parents = &((int32_t []) {
2179 			(CLK_CPU_R5 | (PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN)),
2180 			CLK_DUMMY_PARENT,
2181 			CLK_NA_PARENT
2182 		}),
2183 		.nodes = &cpu_r5_core_nodes,
2184 		.num_nodes = (uint8_t)ARRAY_SIZE(cpu_r5_core_nodes),
2185 	},
2186 	[CLK_CAN0_MIO] = {
2187 		.name = "can0_mio",
2188 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2189 		.status_reg = 0,
2190 		.parents = &can_mio_parents,
2191 		.nodes = &can0_mio_nodes,
2192 		.num_nodes = ARRAY_SIZE(can0_mio_nodes),
2193 	},
2194 	[CLK_CAN1_MIO] = {
2195 		.name = "can1_mio",
2196 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2197 		.status_reg = 0,
2198 		.parents = &can_mio_parents,
2199 		.nodes = &can1_mio_nodes,
2200 		.num_nodes = ARRAY_SIZE(can1_mio_nodes),
2201 	},
2202 	[CLK_CAN0] = {
2203 		.name = "can0",
2204 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2205 		.status_reg = 0,
2206 		.parents = &((int32_t []) {
2207 			CLK_CAN0_REF,
2208 			CLK_CAN0_MIO,
2209 			CLK_NA_PARENT
2210 		}),
2211 		.nodes = &can0_nodes,
2212 		.num_nodes = (uint8_t)ARRAY_SIZE(can0_nodes),
2213 	},
2214 	[CLK_CAN1] = {
2215 		.name = "can1",
2216 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2217 		.status_reg = 0,
2218 		.parents = &((int32_t []) {
2219 			CLK_CAN1_REF,
2220 			CLK_CAN1_MIO,
2221 			CLK_NA_PARENT
2222 		}),
2223 		.nodes = &can1_nodes,
2224 		.num_nodes = (uint8_t)ARRAY_SIZE(can1_nodes),
2225 	},
2226 	[CLK_LPD_WDT] = {
2227 		.name = "lpd_wdt",
2228 		.control_reg = IOU_SLCR_WDT_CLK_SEL,
2229 		.status_reg = 0,
2230 		.parents = &((int32_t []) {
2231 			CLK_LPD_LSBUS,
2232 			EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
2233 			CLK_NA_PARENT
2234 		}),
2235 		.nodes = &wdt_nodes,
2236 		.num_nodes = ARRAY_SIZE(wdt_nodes),
2237 	},
2238 };
2239 
2240 static struct pm_ext_clock ext_clocks[] = {
2241 	[EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
2242 		.name = "pss_ref_clk",
2243 	},
2244 	[EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
2245 		.name = "video_clk",
2246 	},
2247 	[EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
2248 		.name = "pss_alt_ref_clk",
2249 	},
2250 	[EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
2251 		.name = "aux_ref_clk",
2252 	},
2253 	[EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
2254 		.name = "video_clk",
2255 	},
2256 	[EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
2257 		.name = "swdt0_ext_clk",
2258 	},
2259 	[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
2260 		.name = "swdt1_ext_clk",
2261 	},
2262 	[EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = {
2263 		.name = "gem0_tx_ext",
2264 	},
2265 	[EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = {
2266 		.name = "gem1_tx_ext",
2267 	},
2268 	[EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = {
2269 		.name = "gem2_tx_ext",
2270 	},
2271 	[EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = {
2272 		.name = "gem3_tx_ext",
2273 	},
2274 	[EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = {
2275 		.name = "gem0_rx_ext",
2276 	},
2277 	[EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = {
2278 		.name = "gem1_rx_ext",
2279 	},
2280 	[EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = {
2281 		.name = "gem2_rx_ext",
2282 	},
2283 	[EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = {
2284 		.name = "gem3_rx_ext",
2285 	},
2286 	[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
2287 		.name = "mio_clk_50_51",
2288 	},
2289 	EXT_CLK_MIO_DATA(0),
2290 	EXT_CLK_MIO_DATA(1),
2291 	EXT_CLK_MIO_DATA(2),
2292 	EXT_CLK_MIO_DATA(3),
2293 	EXT_CLK_MIO_DATA(4),
2294 	EXT_CLK_MIO_DATA(5),
2295 	EXT_CLK_MIO_DATA(6),
2296 	EXT_CLK_MIO_DATA(7),
2297 	EXT_CLK_MIO_DATA(8),
2298 	EXT_CLK_MIO_DATA(9),
2299 	EXT_CLK_MIO_DATA(10),
2300 	EXT_CLK_MIO_DATA(11),
2301 	EXT_CLK_MIO_DATA(12),
2302 	EXT_CLK_MIO_DATA(13),
2303 	EXT_CLK_MIO_DATA(14),
2304 	EXT_CLK_MIO_DATA(15),
2305 	EXT_CLK_MIO_DATA(16),
2306 	EXT_CLK_MIO_DATA(17),
2307 	EXT_CLK_MIO_DATA(18),
2308 	EXT_CLK_MIO_DATA(19),
2309 	EXT_CLK_MIO_DATA(20),
2310 	EXT_CLK_MIO_DATA(21),
2311 	EXT_CLK_MIO_DATA(22),
2312 	EXT_CLK_MIO_DATA(23),
2313 	EXT_CLK_MIO_DATA(24),
2314 	EXT_CLK_MIO_DATA(25),
2315 	EXT_CLK_MIO_DATA(26),
2316 	EXT_CLK_MIO_DATA(27),
2317 	EXT_CLK_MIO_DATA(28),
2318 	EXT_CLK_MIO_DATA(29),
2319 	EXT_CLK_MIO_DATA(30),
2320 	EXT_CLK_MIO_DATA(31),
2321 	EXT_CLK_MIO_DATA(32),
2322 	EXT_CLK_MIO_DATA(33),
2323 	EXT_CLK_MIO_DATA(34),
2324 	EXT_CLK_MIO_DATA(35),
2325 	EXT_CLK_MIO_DATA(36),
2326 	EXT_CLK_MIO_DATA(37),
2327 	EXT_CLK_MIO_DATA(38),
2328 	EXT_CLK_MIO_DATA(39),
2329 	EXT_CLK_MIO_DATA(40),
2330 	EXT_CLK_MIO_DATA(41),
2331 	EXT_CLK_MIO_DATA(42),
2332 	EXT_CLK_MIO_DATA(43),
2333 	EXT_CLK_MIO_DATA(44),
2334 	EXT_CLK_MIO_DATA(45),
2335 	EXT_CLK_MIO_DATA(46),
2336 	EXT_CLK_MIO_DATA(47),
2337 	EXT_CLK_MIO_DATA(48),
2338 	EXT_CLK_MIO_DATA(49),
2339 	EXT_CLK_MIO_DATA(50),
2340 	EXT_CLK_MIO_DATA(51),
2341 	EXT_CLK_MIO_DATA(52),
2342 	EXT_CLK_MIO_DATA(53),
2343 	EXT_CLK_MIO_DATA(54),
2344 	EXT_CLK_MIO_DATA(55),
2345 	EXT_CLK_MIO_DATA(56),
2346 	EXT_CLK_MIO_DATA(57),
2347 	EXT_CLK_MIO_DATA(58),
2348 	EXT_CLK_MIO_DATA(59),
2349 	EXT_CLK_MIO_DATA(60),
2350 	EXT_CLK_MIO_DATA(61),
2351 	EXT_CLK_MIO_DATA(62),
2352 	EXT_CLK_MIO_DATA(63),
2353 	EXT_CLK_MIO_DATA(64),
2354 	EXT_CLK_MIO_DATA(65),
2355 	EXT_CLK_MIO_DATA(66),
2356 	EXT_CLK_MIO_DATA(67),
2357 	EXT_CLK_MIO_DATA(68),
2358 	EXT_CLK_MIO_DATA(69),
2359 	EXT_CLK_MIO_DATA(70),
2360 	EXT_CLK_MIO_DATA(71),
2361 	EXT_CLK_MIO_DATA(72),
2362 	EXT_CLK_MIO_DATA(73),
2363 	EXT_CLK_MIO_DATA(74),
2364 	EXT_CLK_MIO_DATA(75),
2365 	EXT_CLK_MIO_DATA(76),
2366 	EXT_CLK_MIO_DATA(77),
2367 };
2368 
2369 /* Array of clock which are invalid for this variant */
2370 static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB,
2371 	CLK_ACPU_FULL,
2372 	CLK_ACPU_HALF,
2373 	CLK_APLL_TO_LPD,
2374 	CLK_DBG_FPD,
2375 	CLK_DBG_LPD,
2376 	CLK_DBG_TRACE,
2377 	CLK_DBG_TSTMP,
2378 	CLK_DDR_REF,
2379 	CLK_TOPSW_MAIN,
2380 	CLK_GTGREF0_REF,
2381 	CLK_LPD_SWITCH,
2382 	CLK_CPU_R5,
2383 	CLK_CPU_R5_CORE,
2384 	CLK_CSU_SPB,
2385 	CLK_CSU_PLL,
2386 	CLK_PCAP,
2387 	CLK_IOU_SWITCH,
2388 	CLK_DLL_REF,
2389 	CLK_TIMESTAMP_REF,
2390 };
2391 
2392 /**
2393  * pm_clock_valid - Check if clock is valid or not.
2394  * @clock_id: Id of the clock to be queried.
2395  *
2396  * This function is used to check if given clock is valid
2397  * or not for the chip variant.
2398  *
2399  * List of invalid clocks are maintained in array list for
2400  * different variants.
2401  *
2402  * Return: Returns 1 if clock is valid else 0.
2403  *
2404  */
2405 static bool pm_clock_valid(uint32_t clock_id)
2406 {
2407 	unsigned int i;
2408 	bool valid = true;
2409 
2410 	for (i = 0U; i < ARRAY_SIZE(pm_clk_invalid_list); i++) {
2411 		if (pm_clk_invalid_list[i] == clock_id) {
2412 			valid = false;
2413 			break;
2414 		}
2415 	}
2416 
2417 	return valid;
2418 }
2419 
2420 /**
2421  * pm_clock_type - Get clock's type.
2422  * @clock_id: Id of the clock to be queried.
2423  *
2424  * This function is used to check type of clock (OUTPUT/EXTERNAL).
2425  *
2426  * Return: Returns type of clock (OUTPUT/EXTERNAL).
2427  *
2428  */
2429 static uint32_t pm_clock_type(uint32_t clock_id)
2430 {
2431 	return (clock_id < CLK_MAX_OUTPUT_CLK) ?
2432 		CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
2433 }
2434 
2435 /**
2436  * pm_api_clock_get_num_clocks() - PM call to request number of clocks.
2437  * @nclocks: Number of clocks.
2438  *
2439  * This function is used by master to get number of clocks.
2440  *
2441  * Return: Returns success.
2442  *
2443  */
2444 enum pm_ret_status pm_api_clock_get_num_clocks(uint32_t *nclocks)
2445 {
2446 	*nclocks = CLK_MAX;
2447 
2448 	return PM_RET_SUCCESS;
2449 }
2450 
2451 /**
2452  * pm_api_clock_get_name() - PM call to request a clock's name.
2453  * @clock_id: Clock ID.
2454  * @name: Name of clock (max 16 bytes).
2455  *
2456  * This function is used by master to get nmae of clock specified
2457  * by given clock ID.
2458  *
2459  */
2460 void pm_api_clock_get_name(uint32_t clock_id, char *name)
2461 {
2462 	uint32_t clock_id_num = clock_id;
2463 
2464 	if (clock_id_num == CLK_MAX) {
2465 		(void)memcpy(name, END_OF_CLK, ((sizeof(END_OF_CLK) > CLK_NAME_LEN) ?
2466 					 CLK_NAME_LEN : sizeof(END_OF_CLK)));
2467 	} else if ((clock_id > CLK_MAX) || (!pm_clock_valid(clock_id))) {
2468 		(void)memset(name, 0, CLK_NAME_LEN);
2469 	} else if (clock_id_num < (uint32_t)CLK_MAX_OUTPUT_CLK) {
2470 		(void)memcpy(name, clocks[clock_id_num].name, CLK_NAME_LEN);
2471 	} else {
2472 		(void)memcpy(name, ext_clocks[clock_id_num - (uint32_t)CLK_MAX_OUTPUT_CLK].name,
2473 		       CLK_NAME_LEN);
2474 	}
2475 }
2476 
2477 /**
2478  * pm_api_clock_get_topology() - PM call to request a clock's topology.
2479  * @clock_id: Clock ID.
2480  * @index: Topology index for next toplogy node.
2481  * @topology: Buffer to store nodes in topology and flags.
2482  *
2483  * This function is used by master to get topology information for the
2484  * clock specified by given clock ID. Each response would return 3
2485  * topology nodes. To get next nodes, caller needs to call this API with
2486  * index of next node. Index starts from 0.
2487  *
2488  * Return: Returns status, either success or error+reason.
2489  *
2490  */
2491 enum pm_ret_status pm_api_clock_get_topology(uint32_t clock_id,
2492 					     uint32_t index,
2493 					     uint32_t *topology)
2494 {
2495 	const struct pm_clock_node *clock_nodes;
2496 	uint8_t num_nodes;
2497 	uint32_t i;
2498 	uint16_t typeflags;
2499 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2500 
2501 	if (!pm_clock_valid(clock_id)) {
2502 		goto exit_label;
2503 	}
2504 
2505 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
2506 		status = PM_RET_ERROR_NOTSUPPORTED;
2507 		goto exit_label;
2508 	}
2509 
2510 	(void)memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
2511 	clock_nodes = *clocks[clock_id].nodes;
2512 	num_nodes = clocks[clock_id].num_nodes;
2513 
2514 	/* Skip parent till index */
2515 	if (index >= num_nodes) {
2516 		status = PM_RET_SUCCESS;
2517 		goto exit_label;
2518 	}
2519 
2520 	for (i = 0; i < 3U; i++) {
2521 		if ((index + i) == num_nodes) {
2522 			break;
2523 		}
2524 
2525 		topology[i] = clock_nodes[index + i].type;
2526 		topology[i] |= ((uint32_t)clock_nodes[index + i].clkflags <<
2527 					CLK_CLKFLAGS_SHIFT);
2528 		typeflags = clock_nodes[index + i].typeflags;
2529 		topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS_BITS_MASK) <<
2530 					CLK_TYPEFLAGS_SHIFT);
2531 		topology[i] |= ((uint32_t)(typeflags & CLK_TYPEFLAGS2_BITS_MASK) >>
2532 				(CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT));
2533 	}
2534 
2535 	status = PM_RET_SUCCESS;
2536 
2537 exit_label:
2538 	return status;
2539 }
2540 
2541 /**
2542  * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
2543  *					   factor parameters for fixed clock.
2544  * @clock_id: Clock ID.
2545  * @mul: Multiplication value.
2546  * @div: Divisor value.
2547  *
2548  * This function is used by master to get fixed factor parameers for the
2549  * fixed clock. This API is application only for the fixed clock.
2550  *
2551  * Return: Returns status, either success or error+reason.
2552  *
2553  */
2554 enum pm_ret_status pm_api_clock_get_fixedfactor_params(uint32_t clock_id,
2555 						       uint32_t *mul,
2556 						       uint32_t *div)
2557 {
2558 	const struct pm_clock_node *clock_nodes;
2559 	uint8_t num_nodes;
2560 	uint32_t type, i;
2561 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2562 
2563 	if (!pm_clock_valid(clock_id)) {
2564 		goto exit_label;
2565 	}
2566 
2567 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
2568 		status = PM_RET_ERROR_NOTSUPPORTED;
2569 		goto exit_label;
2570 	}
2571 
2572 	clock_nodes = *clocks[clock_id].nodes;
2573 	num_nodes = clocks[clock_id].num_nodes;
2574 
2575 	for (i = 0; i < num_nodes; i++) {
2576 		type =  clock_nodes[i].type;
2577 		if (type == TYPE_FIXEDFACTOR) {
2578 			*mul = clock_nodes[i].mult;
2579 			*div = clock_nodes[i].div;
2580 			break;
2581 		}
2582 	}
2583 
2584 	/* Clock is not fixed clock */
2585 	if (i != num_nodes) {
2586 		status = PM_RET_SUCCESS;
2587 	}
2588 
2589 exit_label:
2590 	return status;
2591 }
2592 
2593 /**
2594  * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents.
2595  * @clock_id: Clock ID.
2596  * @index: Index of next parent.
2597  * @parents: Parents of the given clock.
2598  *
2599  * This function is used by master to get clock's parents information.
2600  * This API will return 3 parents with a single response. To get other
2601  * parents, master should call same API in loop with new parent index
2602  * till error is returned.
2603  *
2604  * E.g First call should have index 0 which will return parents 0, 1 and
2605  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
2606  * so on.
2607  *
2608  * Return: Returns status, either success or error+reason.
2609  *
2610  */
2611 enum pm_ret_status pm_api_clock_get_parents(uint32_t clock_id,
2612 					    uint32_t index,
2613 					    uint32_t *parents)
2614 {
2615 	uint32_t i;
2616 	const int32_t *clk_parents;
2617 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2618 
2619 	if (!pm_clock_valid(clock_id)) {
2620 		goto exit_label;
2621 	}
2622 
2623 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
2624 		status = PM_RET_ERROR_NOTSUPPORTED;
2625 		goto exit_label;
2626 	}
2627 
2628 	clk_parents = *clocks[clock_id].parents;
2629 	if (clk_parents == NULL) {
2630 		goto exit_label;
2631 	}
2632 
2633 	(void)memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
2634 
2635 	/* Skip parent till index */
2636 	for (i = 0; i < index; i++) {
2637 		if (clk_parents[i] == CLK_NA_PARENT) {
2638 			status = PM_RET_SUCCESS;
2639 			goto exit_label;
2640 		}
2641 	}
2642 
2643 	for (i = 0; i < 3U; i++) {
2644 		parents[i] = (uint32_t)clk_parents[index + i];
2645 		if (clk_parents[index + i] == CLK_NA_PARENT) {
2646 			break;
2647 		}
2648 	}
2649 
2650 	status = PM_RET_SUCCESS;
2651 
2652 exit_label:
2653 	return status;
2654 }
2655 
2656 /**
2657  * pm_api_clock_get_attributes() - PM call to request a clock's attributes.
2658  * @clock_id: Clock ID.
2659  * @attr: Clock attributes.
2660  *
2661  * This function is used by master to get clock's attributes
2662  * (e.g. valid, clock type, etc).
2663  *
2664  * Return: Returns status, either success or error+reason.
2665  *
2666  */
2667 enum pm_ret_status pm_api_clock_get_attributes(uint32_t clock_id,
2668 					       uint32_t *attr)
2669 {
2670 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2671 
2672 	if (clock_id >= (uint32_t)CLK_MAX) {
2673 		goto exit_label;
2674 	}
2675 
2676 	/* Clock valid bit */
2677 	*attr = pm_clock_valid(clock_id);
2678 
2679 	/* Clock type (Output/External) */
2680 	*attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
2681 
2682 	status = PM_RET_SUCCESS;
2683 
2684 exit_label:
2685 	return status;
2686 }
2687 
2688 /**
2689  * pm_api_clock_get_max_divisor - PM call to get max divisor.
2690  * @clock_id: Clock ID.
2691  * @div_type: Divisor Type (TYPE_DIV1 or TYPE_DIV2).
2692  * @max_div: Maximum supported divisor.
2693  *
2694  * This function is used by master to get maximum supported value.
2695  *
2696  * Return: Returns status, either success or error+reason.
2697  *
2698  */
2699 enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id,
2700 						uint8_t div_type,
2701 						uint32_t *max_div)
2702 {
2703 	uint32_t i;
2704 	const struct pm_clock_node *nodes;
2705 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2706 
2707 	if (clock_id >= CLK_MAX_OUTPUT_CLK) {
2708 		goto exit_label;
2709 	}
2710 
2711 	nodes = *clocks[clock_id].nodes;
2712 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
2713 		if (nodes[i].type == div_type) {
2714 			if ((CLK_DIVIDER_POWER_OF_TWO &
2715 						nodes[i].typeflags) != 0U) {
2716 				*max_div = (((uint32_t)1U <<
2717 						((uint32_t)BIT(nodes[i].width) - (uint32_t)1U)));
2718 			} else {
2719 				*max_div = (uint32_t)BIT(nodes[i].width) - (uint32_t)1U;
2720 			}
2721 			status = PM_RET_SUCCESS;
2722 			break;
2723 		}
2724 	}
2725 
2726 exit_label:
2727 	return status;
2728 }
2729 
2730 /**
2731  * struct pm_pll - PLL related data required to map IOCTL-based PLL control.
2732  * implemented by linux to system-level EEMI APIs.
2733  * @nid: PLL node ID.
2734  * @cid: PLL clock ID.
2735  * @pre_src: Pre-source PLL clock ID.
2736  * @post_src: Post-source PLL clock ID.
2737  * @div2: DIV2 PLL clock ID.
2738  * @bypass: PLL output clock ID that maps to bypass select output.
2739  * @mode: PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE).
2740  *
2741  */
2742 struct pm_pll {
2743 	const enum pm_node_id nid;
2744 	const enum clock_id cid;
2745 	const enum clock_id pre_src;
2746 	const enum clock_id post_src;
2747 	const enum clock_id div2;
2748 	const enum clock_id bypass;
2749 	uint8_t mode;
2750 };
2751 
2752 static struct pm_pll pm_plls[] = {
2753 	{
2754 		.nid = NODE_IOPLL,
2755 		.cid = CLK_IOPLL_INT,
2756 		.pre_src = CLK_IOPLL_PRE_SRC,
2757 		.post_src = CLK_IOPLL_POST_SRC,
2758 		.div2 = CLK_IOPLL_INT_MUX,
2759 		.bypass = CLK_IOPLL,
2760 	}, {
2761 		.nid = NODE_RPLL,
2762 		.cid = CLK_RPLL_INT,
2763 		.pre_src = CLK_RPLL_PRE_SRC,
2764 		.post_src = CLK_RPLL_POST_SRC,
2765 		.div2 = CLK_RPLL_INT_MUX,
2766 		.bypass = CLK_RPLL,
2767 	}, {
2768 		.nid = NODE_APLL,
2769 		.cid = CLK_APLL_INT,
2770 		.pre_src = CLK_APLL_PRE_SRC,
2771 		.post_src = CLK_APLL_POST_SRC,
2772 		.div2 = CLK_APLL_INT_MUX,
2773 		.bypass = CLK_APLL,
2774 	}, {
2775 		.nid = NODE_VPLL,
2776 		.cid = CLK_VPLL_INT,
2777 		.pre_src = CLK_VPLL_PRE_SRC,
2778 		.post_src = CLK_VPLL_POST_SRC,
2779 		.div2 = CLK_VPLL_INT_MUX,
2780 		.bypass = CLK_VPLL,
2781 	}, {
2782 		.nid = NODE_DPLL,
2783 		.cid = CLK_DPLL_INT,
2784 		.pre_src = CLK_DPLL_PRE_SRC,
2785 		.post_src = CLK_DPLL_POST_SRC,
2786 		.div2 = CLK_DPLL_INT_MUX,
2787 		.bypass = CLK_DPLL,
2788 	},
2789 };
2790 
2791 /**
2792  * pm_clock_get_pll() - Get PLL structure by PLL clock ID.
2793  * @clock_id: Clock ID of the target PLL.
2794  *
2795  * Return: Pointer to PLL structure if found, NULL otherwise.
2796  *
2797  */
2798 struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
2799 {
2800 	uint32_t i;
2801 	struct pm_pll *pll = NULL;
2802 
2803 	for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
2804 		if (pm_plls[i].cid == clock_id) {
2805 			pll = &pm_plls[i];
2806 			break;
2807 		}
2808 	}
2809 
2810 	return pll;
2811 }
2812 
2813 /**
2814  * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID.
2815  * @clock_id: Clock ID of the target PLL.
2816  * @node_id: Location to store node ID of the target PLL.
2817  *
2818  * Return: PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise.
2819  *
2820  */
2821 enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
2822 					    enum pm_node_id *node_id)
2823 {
2824 	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
2825 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2826 
2827 	if (pll != NULL) {
2828 		*node_id = pll->nid;
2829 		status = PM_RET_SUCCESS;
2830 	}
2831 
2832 	return status;
2833 }
2834 
2835 /**
2836  * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock
2837  *                                     ID.
2838  * @clock_id: Clock ID.
2839  *
2840  * Return: Pointer to PLL structure if found, NULL otherwise.
2841  *
2842  */
2843 struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
2844 {
2845 	uint32_t i;
2846 	struct pm_pll *pll = NULL;
2847 
2848 	for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
2849 		if ((pm_plls[i].pre_src == clock_id) ||
2850 		    (pm_plls[i].post_src == clock_id) ||
2851 		    (pm_plls[i].div2 == clock_id) ||
2852 		    (pm_plls[i].bypass == clock_id)) {
2853 			pll = &pm_plls[i];
2854 			break;
2855 		}
2856 	}
2857 
2858 	return pll;
2859 }
2860 
2861 /**
2862  * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL).
2863  * @pll: PLL to be locked.
2864  * @flag: 0 - Call from secure source.
2865  *	  1 - Call from non-secure source.
2866  *
2867  * This function is used to map IOCTL/linux-based PLL handling to system-level
2868  * EEMI APIs.
2869  *
2870  * Return: Error if the argument is not valid or status as returned by PMU.
2871  *
2872  */
2873 enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll, uint32_t flag)
2874 {
2875 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2876 
2877 	if (pll != NULL) {
2878 		/* Set the PLL mode according to the buffered mode value */
2879 		if (pll->mode == PLL_FRAC_MODE) {
2880 			status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL, flag);
2881 		} else {
2882 			status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER, flag);
2883 		}
2884 	}
2885 
2886 	return status;
2887 }
2888 
2889 /**
2890  * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL).
2891  * @pll: PLL to be bypassed/reset.
2892  * @flag: 0 - Call from secure source.
2893  *	  1 - Call from non-secure source.
2894  *
2895  * This function is used to map IOCTL/linux-based PLL handling to system-level
2896  * EEMI APIs.
2897  *
2898  * Return: Error if the argument is not valid or status as returned by PMU.
2899  *
2900  */
2901 enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll, uint32_t flag)
2902 {
2903 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2904 
2905 	if (pll != NULL) {
2906 		status = pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET, flag);
2907 	}
2908 
2909 	return status;
2910 }
2911 
2912 /**
2913  * pm_clock_pll_get_state - Get state of the PLL.
2914  * @pll: Pointer to the target PLL structure.
2915  * @state: Location to store the state: 1/0 ("Enabled"/"Disabled").
2916  * @flag: 0 - Call from secure source.
2917  *	  1 - Call from non-secure source.
2918  *
2919  * "Enable" actually means that the PLL is locked and its bypass is deasserted,
2920  * "Disable" means that it is bypassed.
2921  *
2922  * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if
2923  *         returned state value is valid or an error if returned by PMU.
2924  */
2925 enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
2926 					  uint32_t *state,
2927 					  uint32_t flag)
2928 {
2929 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2930 	enum pm_pll_mode mode;
2931 
2932 	if ((pll == NULL) || (state == NULL)) {
2933 		goto exit_label;
2934 	}
2935 
2936 	status = pm_pll_get_mode(pll->nid, &mode, flag);
2937 	if (status != PM_RET_SUCCESS) {
2938 		goto exit_label;
2939 	}
2940 
2941 	if (mode == PM_PLL_MODE_RESET) {
2942 		*state = 0;
2943 	} else {
2944 		*state = 1;
2945 	}
2946 
2947 	status = PM_RET_SUCCESS;
2948 
2949 exit_label:
2950 	return status;
2951 }
2952 
2953 /**
2954  * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id.
2955  * @pll: Target PLL structure.
2956  * @clock_id: Id of the clock.
2957  * @parent_index: parent index (=mux select value).
2958  * @flag: 0 - Call from secure source.
2959  *	  1 - Call from non-secure source.
2960  *
2961  * The whole clock-tree implementation relies on the fact that parent indexes
2962  * match to the multiplexer select values. This function has to rely on that
2963  * assumption as well => parent_index is actually the mux select value.
2964  *
2965  * Return: Returns status, either success or error+reason.
2966  *
2967  */
2968 enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
2969 					   enum clock_id clock_id,
2970 					   uint32_t parent_index,
2971 					   uint32_t flag)
2972 {
2973 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
2974 
2975 	if (pll == NULL) {
2976 		goto exit_label;
2977 	}
2978 	if (pll->pre_src == clock_id) {
2979 		status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
2980 					      parent_index, flag);
2981 		goto exit_label;
2982 	}
2983 	if (pll->post_src == clock_id) {
2984 		status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
2985 					      parent_index, flag);
2986 		goto exit_label;
2987 	}
2988 	if (pll->div2 == clock_id) {
2989 		status = pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
2990 					      parent_index, flag);
2991 	}
2992 
2993 exit_label:
2994 	return status;
2995 }
2996 
2997 /**
2998  * pm_clock_pll_get_parent - Get mux select value of PLL-related clock parent.
2999  * @pll: Target PLL structure.
3000  * @clock_id: Id of the clock.
3001  * @parent_index: parent index (=mux select value).
3002  * @flag: 0 - Call from secure source.
3003  *	  1 - Call from non-secure source.
3004  *
3005  * This function is used by master to get parent index for PLL-related clock.
3006  *
3007  * Return: Returns status, either success or error+reason.
3008  *
3009  */
3010 enum pm_ret_status pm_clock_pll_get_parent(struct pm_pll *pll,
3011 					   enum clock_id clock_id,
3012 					   uint32_t *parent_index,
3013 					   uint32_t flag)
3014 {
3015 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
3016 
3017 	if (pll == NULL) {
3018 		goto exit_label;
3019 	}
3020 	if (pll->pre_src == clock_id) {
3021 		status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
3022 					      parent_index, flag);
3023 		goto exit_label;
3024 	}
3025 	if (pll->post_src == clock_id) {
3026 		status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
3027 					      parent_index, flag);
3028 		goto exit_label;
3029 	}
3030 	if (pll->div2 == clock_id) {
3031 		status = pm_pll_get_parameter(pll->nid, PM_PLL_PARAM_DIV2,
3032 					      parent_index, flag);
3033 		goto exit_label;
3034 	}
3035 	if (pll->bypass == clock_id) {
3036 		*parent_index = 0;
3037 		status = PM_RET_SUCCESS;
3038 	}
3039 
3040 exit_label:
3041 	return status;
3042 }
3043 
3044 /**
3045  * pm_clock_set_pll_mode() -  Set PLL mode.
3046  * @clock_id: PLL clock id.
3047  * @mode: Mode fractional/integer.
3048  *
3049  * This function buffers/saves the PLL mode that is set.
3050  *
3051  * Return: Success if mode is buffered or error if an argument is invalid.
3052  *
3053  */
3054 enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
3055 					 uint32_t mode)
3056 {
3057 	struct pm_pll *pll = pm_clock_get_pll(clock_id);
3058 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
3059 
3060 	if (!((pll == NULL) || ((mode != PLL_FRAC_MODE) && (mode != PLL_INT_MODE)))) {
3061 		pll->mode = (uint8_t)mode;
3062 		status = PM_RET_SUCCESS;
3063 	}
3064 
3065 	return status;
3066 }
3067 
3068 /**
3069  * pm_clock_get_pll_mode() -  Get PLL mode.
3070  * @clock_id: PLL clock id.
3071  * @mode: Location to store the mode (fractional/integer).
3072  *
3073  * This function returns buffered PLL mode.
3074  *
3075  * Return: Success if mode is stored or error if an argument is invalid.
3076  *
3077  */
3078 enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
3079 					 uint32_t *mode)
3080 {
3081 	const struct pm_pll *pll = pm_clock_get_pll(clock_id);
3082 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
3083 
3084 	if ((pll != NULL) && (mode != NULL)) {
3085 		*mode = pll->mode;
3086 		status = PM_RET_SUCCESS;
3087 	}
3088 
3089 	return status;
3090 }
3091 
3092 /**
3093  * pm_clock_id_is_valid() -  Check if given clock ID is valid.
3094  * @clock_id: ID of the clock to be checked.
3095  *
3096  * Return: Returns success if clock_id is valid, otherwise an error.
3097  *
3098  */
3099 enum pm_ret_status pm_clock_id_is_valid(uint32_t clock_id)
3100 {
3101 	enum pm_ret_status status = PM_RET_ERROR_ARGS;
3102 
3103 	if (pm_clock_valid(clock_id)) {
3104 		if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT) {
3105 			status = PM_RET_ERROR_NOTSUPPORTED;
3106 		} else {
3107 			status = PM_RET_SUCCESS;
3108 		}
3109 	}
3110 
3111 	return status;
3112 }
3113 
3114 /**
3115  * pm_clock_has_div() - Check if the clock has divider with given ID.
3116  * @clock_id: Clock ID.
3117  * @div_id: Divider ID.
3118  *
3119  * Return: True(1)=clock has the divider, false(0)=otherwise.
3120  *
3121  */
3122 uint8_t pm_clock_has_div(uint32_t clock_id, enum pm_clock_div_id div_id)
3123 {
3124 	uint32_t i;
3125 	const struct pm_clock_node *nodes;
3126 	uint8_t status = 0U;
3127 
3128 	if (clock_id >= (uint32_t)CLK_MAX_OUTPUT_CLK) {
3129 		goto exit_label;
3130 	}
3131 
3132 	nodes = *clocks[clock_id].nodes;
3133 	for (i = 0; i < clocks[clock_id].num_nodes; i++) {
3134 		if (nodes[i].type == TYPE_DIV1) {
3135 			if (div_id == PM_CLOCK_DIV0_ID) {
3136 				status = 1U;
3137 				break;
3138 			}
3139 		} else if (nodes[i].type == TYPE_DIV2) {
3140 			if (div_id == PM_CLOCK_DIV1_ID) {
3141 				status = 1U;
3142 				break;
3143 			}
3144 		} else {
3145 			/* To fix the misra 15.7 warning */
3146 		}
3147 	}
3148 
3149 exit_label:
3150 	return status;
3151 }
3152