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