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