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