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