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