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