xref: /rk3399_ARM-atf/plat/xilinx/zynqmp/pm_service/pm_api_clock.c (revision a15f38cf4f9c52870b9ab47aca9f3d4c1f8bfc64)
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 		.type = TYPE_GATE,
337 		.offset = PERIPH_GATE_SHIFT,
338 		.width = PERIPH_GATE_WIDTH,
339 		.clkflags = CLK_SET_RATE_PARENT |
340 			    CLK_IGNORE_UNUSED |
341 			    CLK_IS_BASIC |
342 			    CLK_IS_CRITICAL,
343 		.typeflags = NA_TYPE_FLAGS,
344 		.mult = NA_MULT,
345 		.div = NA_DIV,
346 	},
347 };
348 
349 static struct pm_clock_node generic_mux_div_nodes[] = {
350 	GENERIC_MUX,
351 	GENERIC_DIV(1),
352 };
353 
354 static struct pm_clock_node generic_mux_div_gate_nodes[] = {
355 	GENERIC_MUX,
356 	GENERIC_DIV(1),
357 	GENERIC_GATE,
358 };
359 
360 static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
361 	GENERIC_MUX,
362 	GENERIC_DIV(1),
363 	IGNORE_UNUSED_GATE,
364 };
365 
366 static struct pm_clock_node generic_mux_div_div_gate_nodes[] = {
367 	GENERIC_MUX,
368 	GENERIC_DIV(1),
369 	GENERIC_DIV(2),
370 	GENERIC_GATE,
371 };
372 
373 static struct pm_clock_node dp_audio_video_ref_nodes[] = {
374 	{
375 		.type = TYPE_MUX,
376 		.offset = PERIPH_MUX_SHIFT,
377 		.width = PERIPH_MUX_WIDTH,
378 		.clkflags = CLK_SET_RATE_NO_REPARENT |
379 			    CLK_SET_RATE_PARENT |
380 			    CLK_FRAC | CLK_IS_BASIC,
381 		.typeflags = NA_TYPE_FLAGS,
382 		.mult = NA_MULT,
383 		.div = NA_DIV,
384 	},
385 	{
386 		.type = TYPE_DIV1,
387 		.offset = PERIPH_DIV1_SHIFT,
388 		.width = PERIPH_DIV1_WIDTH,
389 		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
390 			    CLK_FRAC | CLK_IS_BASIC,
391 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
392 		.mult = NA_MULT,
393 		.div = NA_DIV,
394 	},
395 	{
396 		.type = TYPE_DIV2,
397 		.offset = PERIPH_DIV2_SHIFT,
398 		.width = PERIPH_DIV2_WIDTH,
399 		.clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT |
400 			    CLK_FRAC | CLK_IS_BASIC,
401 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
402 		.mult = NA_MULT,
403 		.div = NA_DIV,
404 	},
405 	{
406 		.type = TYPE_GATE,
407 		.offset = PERIPH_GATE_SHIFT,
408 		.width = PERIPH_GATE_WIDTH,
409 		.clkflags = CLK_SET_RATE_PARENT |
410 			    CLK_SET_RATE_GATE |
411 			    CLK_IS_BASIC,
412 		.typeflags = NA_TYPE_FLAGS,
413 		.mult = NA_MULT,
414 		.div = NA_DIV,
415 	},
416 };
417 
418 static struct pm_clock_node usb_nodes[] = {
419 	GENERIC_MUX,
420 	GENERIC_DIV(1),
421 	GENERIC_DIV(2),
422 	{
423 		.type = TYPE_GATE,
424 		.offset = USB_GATE_SHIFT,
425 		.width = PERIPH_GATE_WIDTH,
426 		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC |
427 			    CLK_SET_RATE_GATE,
428 		.typeflags = NA_TYPE_FLAGS,
429 		.mult = NA_MULT,
430 		.div = NA_DIV,
431 	},
432 };
433 
434 static struct pm_clock_node generic_domain_crossing_nodes[] = {
435 	{
436 		.type = TYPE_DIV1,
437 		.offset = 8,
438 		.width = 6,
439 		.clkflags = 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 rpll_to_fpd_nodes[] = {
447 	{
448 		.type = TYPE_DIV1,
449 		.offset = 8,
450 		.width = 6,
451 		.clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC,
452 		.typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
453 		.mult = NA_MULT,
454 		.div = NA_DIV,
455 	},
456 };
457 
458 static struct pm_clock_node acpu_half_nodes[] = {
459 	{
460 		.type = TYPE_FIXEDFACTOR,
461 		.offset = 0,
462 		.width = 1,
463 		.clkflags = 0,
464 		.typeflags = 0,
465 		.mult = 1,
466 		.div = 2,
467 	},
468 	{
469 		.type = TYPE_GATE,
470 		.offset = 25,
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_DBG_TRACE] = {
1211 		.name = "dbg_trace",
1212 		.control_reg = CRF_APB_DBG_TRACE_CTRL,
1213 		.status_reg = 0,
1214 		.parents = &((int32_t []) {
1215 			CLK_IOPLL_TO_FPD,
1216 			CLK_DUMMY_PARENT,
1217 			CLK_DPLL,
1218 			CLK_APLL,
1219 			CLK_NA_PARENT
1220 		}),
1221 		.nodes = &generic_mux_div_gate_nodes,
1222 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1223 	},
1224 	[CLK_DBG_FPD] = {
1225 		.name = "dbg_fpd",
1226 		.control_reg = CRF_APB_DBG_FPD_CTRL,
1227 		.status_reg = 0,
1228 		.parents = &((int32_t []) {
1229 			CLK_IOPLL_TO_FPD,
1230 			CLK_DUMMY_PARENT,
1231 			CLK_DPLL,
1232 			CLK_APLL,
1233 			CLK_NA_PARENT
1234 		}),
1235 		.nodes = &generic_mux_div_gate_nodes,
1236 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1237 	},
1238 	[CLK_DBG_TSTMP] = {
1239 		.name = "dbg_tstmp",
1240 		.control_reg = CRF_APB_DBG_TSTMP_CTRL,
1241 		.status_reg = 0,
1242 		.parents = &((int32_t []) {
1243 			CLK_IOPLL_TO_FPD,
1244 			CLK_DUMMY_PARENT,
1245 			CLK_DPLL,
1246 			CLK_APLL,
1247 			CLK_NA_PARENT
1248 		}),
1249 		.nodes = &generic_mux_div_nodes,
1250 		.num_nodes = ARRAY_SIZE(generic_mux_div_nodes),
1251 	},
1252 	[CLK_DP_VIDEO_REF] = {
1253 		.name = "dp_video_ref",
1254 		.control_reg = CRF_APB_DP_VIDEO_REF_CTRL,
1255 		.status_reg = 0,
1256 		.parents = &((int32_t []) {
1257 			CLK_VPLL,
1258 			CLK_DUMMY_PARENT,
1259 			CLK_DPLL,
1260 			CLK_RPLL_TO_FPD,
1261 			CLK_NA_PARENT
1262 		}),
1263 		.nodes = &dp_audio_video_ref_nodes,
1264 		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
1265 	},
1266 	[CLK_DP_AUDIO_REF] = {
1267 		.name = "dp_audio_ref",
1268 		.control_reg = CRF_APB_DP_AUDIO_REF_CTRL,
1269 		.status_reg = 0,
1270 		.parents = &((int32_t []) {
1271 			CLK_VPLL,
1272 			CLK_DUMMY_PARENT,
1273 			CLK_DPLL,
1274 			CLK_RPLL_TO_FPD,
1275 			CLK_NA_PARENT
1276 		}),
1277 		.nodes = &dp_audio_video_ref_nodes,
1278 		.num_nodes = ARRAY_SIZE(dp_audio_video_ref_nodes),
1279 	},
1280 	[CLK_DP_STC_REF] = {
1281 		.name = "dp_stc_ref",
1282 		.control_reg = CRF_APB_DP_STC_REF_CTRL,
1283 		.status_reg = 0,
1284 		.parents = &((int32_t []) {
1285 			CLK_VPLL,
1286 			CLK_DUMMY_PARENT,
1287 			CLK_DPLL,
1288 			CLK_RPLL_TO_FPD,
1289 			CLK_NA_PARENT
1290 		}),
1291 		.nodes = &generic_mux_div_div_gate_nodes,
1292 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1293 	},
1294 	[CLK_DPDMA_REF] = {
1295 		.name = "dpdma_ref",
1296 		.control_reg = CRF_APB_DPDMA_REF_CTRL,
1297 		.status_reg = 0,
1298 		.parents = &((int32_t []) {
1299 			CLK_APLL,
1300 			CLK_DUMMY_PARENT,
1301 			CLK_VPLL,
1302 			CLK_DPLL,
1303 			CLK_NA_PARENT
1304 		}),
1305 		.nodes = &generic_mux_div_gate_nodes,
1306 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1307 	},
1308 	[CLK_DDR_REF] = {
1309 		.name = "ddr_ref",
1310 		.control_reg = CRF_APB_DDR_CTRL,
1311 		.status_reg = 0,
1312 		.parents = &((int32_t []) {
1313 			CLK_DPLL,
1314 			CLK_VPLL,
1315 			CLK_NA_PARENT
1316 		}),
1317 		.nodes = &ddr_nodes,
1318 		.num_nodes = ARRAY_SIZE(ddr_nodes),
1319 	},
1320 	[CLK_GPU_REF] = {
1321 		.name = "gpu_ref",
1322 		.control_reg = CRF_APB_GPU_REF_CTRL,
1323 		.status_reg = 0,
1324 		.parents = &((int32_t []) {
1325 			CLK_IOPLL_TO_FPD,
1326 			CLK_DUMMY_PARENT,
1327 			CLK_VPLL,
1328 			CLK_DPLL,
1329 			CLK_NA_PARENT
1330 		}),
1331 		.nodes = &generic_mux_div_gate_nodes,
1332 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1333 	},
1334 	[CLK_SATA_REF] = {
1335 		.name = "sata_ref",
1336 		.control_reg = CRF_APB_SATA_REF_CTRL,
1337 		.status_reg = 0,
1338 		.parents = &((int32_t []) {
1339 			CLK_IOPLL_TO_FPD,
1340 			CLK_DUMMY_PARENT,
1341 			CLK_APLL,
1342 			CLK_DPLL,
1343 			CLK_NA_PARENT
1344 		}),
1345 		.nodes = &generic_mux_div_gate_nodes,
1346 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1347 	},
1348 	[CLK_PCIE_REF] = {
1349 		.name = "pcie_ref",
1350 		.control_reg = CRF_APB_PCIE_REF_CTRL,
1351 		.status_reg = 0,
1352 		.parents = &((int32_t []) {
1353 			CLK_IOPLL_TO_FPD,
1354 			CLK_DUMMY_PARENT,
1355 			CLK_RPLL_TO_FPD,
1356 			CLK_DPLL,
1357 			CLK_NA_PARENT
1358 		}),
1359 		.nodes = &generic_mux_div_gate_nodes,
1360 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1361 	},
1362 	[CLK_GDMA_REF] = {
1363 		.name = "gdma_ref",
1364 		.control_reg = CRF_APB_GDMA_REF_CTRL,
1365 		.status_reg = 0,
1366 		.parents = &((int32_t []) {
1367 			CLK_APLL,
1368 			CLK_DUMMY_PARENT,
1369 			CLK_VPLL,
1370 			CLK_DPLL,
1371 			CLK_NA_PARENT
1372 		}),
1373 		.nodes = &generic_mux_div_gate_nodes,
1374 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1375 	},
1376 	[CLK_GTGREF0_REF] = {
1377 		.name = "gtgref0_ref",
1378 		.control_reg = CRF_APB_GTGREF0_REF_CTRL,
1379 		.status_reg = 0,
1380 		.parents = &((int32_t []) {
1381 			CLK_IOPLL_TO_FPD,
1382 			CLK_DUMMY_PARENT,
1383 			CLK_APLL,
1384 			CLK_DPLL,
1385 			CLK_NA_PARENT
1386 		}),
1387 		.nodes = &generic_mux_div_gate_nodes,
1388 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1389 	},
1390 	[CLK_TOPSW_MAIN] = {
1391 		.name = "topsw_main",
1392 		.control_reg = CRF_APB_TOPSW_MAIN_CTRL,
1393 		.status_reg = 0,
1394 		.parents = &((int32_t []) {
1395 			CLK_APLL,
1396 			CLK_DUMMY_PARENT,
1397 			CLK_VPLL,
1398 			CLK_DPLL,
1399 			CLK_NA_PARENT
1400 		}),
1401 		.nodes = &generic_mux_div_unused_gate_nodes,
1402 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1403 	},
1404 	[CLK_TOPSW_LSBUS] = {
1405 		.name = "topsw_lsbus",
1406 		.control_reg = CRF_APB_TOPSW_LSBUS_CTRL,
1407 		.status_reg = 0,
1408 		.parents = &((int32_t []) {
1409 			CLK_APLL,
1410 			CLK_DUMMY_PARENT,
1411 			CLK_IOPLL_TO_FPD,
1412 			CLK_DPLL,
1413 			CLK_NA_PARENT
1414 		}),
1415 		.nodes = &generic_mux_div_unused_gate_nodes,
1416 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1417 	},
1418 	[CLK_IOU_SWITCH] = {
1419 		.name = "iou_switch",
1420 		.control_reg = CRL_APB_IOU_SWITCH_CTRL,
1421 		.status_reg = 0,
1422 		.parents = &((int32_t []) {
1423 			CLK_RPLL,
1424 			CLK_DUMMY_PARENT,
1425 			CLK_IOPLL,
1426 			CLK_DPLL_TO_LPD,
1427 			CLK_NA_PARENT
1428 		}),
1429 		.nodes = &generic_mux_div_unused_gate_nodes,
1430 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1431 	},
1432 	[CLK_GEM0_REF] = {
1433 		.name = "gem0_ref",
1434 		.control_reg = CRL_APB_GEM0_REF_CTRL,
1435 		.status_reg = 0,
1436 		.parents = &((int32_t []) {
1437 			CLK_IOPLL,
1438 			CLK_DUMMY_PARENT,
1439 			CLK_RPLL,
1440 			CLK_DPLL_TO_LPD,
1441 			CLK_NA_PARENT
1442 		}),
1443 		.nodes = &gem_nodes,
1444 		.num_nodes = ARRAY_SIZE(gem_nodes),
1445 	},
1446 	[CLK_GEM1_REF] = {
1447 		.name = "gem1_ref",
1448 		.control_reg = CRL_APB_GEM1_REF_CTRL,
1449 		.status_reg = 0,
1450 		.parents = &((int32_t []) {
1451 			CLK_IOPLL,
1452 			CLK_DUMMY_PARENT,
1453 			CLK_RPLL,
1454 			CLK_DPLL_TO_LPD,
1455 			CLK_NA_PARENT
1456 		}),
1457 		.nodes = &gem_nodes,
1458 		.num_nodes = ARRAY_SIZE(gem_nodes),
1459 	},
1460 	[CLK_GEM2_REF] = {
1461 		.name = "gem2_ref",
1462 		.control_reg = CRL_APB_GEM2_REF_CTRL,
1463 		.status_reg = 0,
1464 		.parents = &((int32_t []) {
1465 			CLK_IOPLL,
1466 			CLK_DUMMY_PARENT,
1467 			CLK_RPLL,
1468 			CLK_DPLL_TO_LPD,
1469 			CLK_NA_PARENT
1470 		}),
1471 		.nodes = &gem_nodes,
1472 		.num_nodes = ARRAY_SIZE(gem_nodes),
1473 	},
1474 	[CLK_GEM3_REF] = {
1475 		.name = "gem3_ref",
1476 		.control_reg = CRL_APB_GEM3_REF_CTRL,
1477 		.status_reg = 0,
1478 		.parents = &((int32_t []) {
1479 			CLK_IOPLL,
1480 			CLK_DUMMY_PARENT,
1481 			CLK_RPLL,
1482 			CLK_DPLL_TO_LPD,
1483 			CLK_NA_PARENT
1484 		}),
1485 		.nodes = &gem_nodes,
1486 		.num_nodes = ARRAY_SIZE(gem_nodes),
1487 	},
1488 	[CLK_USB0_BUS_REF] = {
1489 		.name = "usb0_bus_ref",
1490 		.control_reg = CRL_APB_USB0_BUS_REF_CTRL,
1491 		.status_reg = 0,
1492 		.parents = &((int32_t []) {
1493 			CLK_IOPLL,
1494 			CLK_DUMMY_PARENT,
1495 			CLK_RPLL,
1496 			CLK_DPLL_TO_LPD,
1497 			CLK_NA_PARENT
1498 		}),
1499 		.nodes = &usb_nodes,
1500 		.num_nodes = ARRAY_SIZE(usb_nodes),
1501 	},
1502 	[CLK_USB1_BUS_REF] = {
1503 		.name = "usb1_bus_ref",
1504 		.control_reg = CRL_APB_USB1_BUS_REF_CTRL,
1505 		.status_reg = 0,
1506 		.parents = &((int32_t []) {
1507 			CLK_IOPLL,
1508 			CLK_DUMMY_PARENT,
1509 			CLK_RPLL,
1510 			CLK_DPLL_TO_LPD,
1511 			CLK_NA_PARENT
1512 		}),
1513 		.nodes = &usb_nodes,
1514 		.num_nodes = ARRAY_SIZE(usb_nodes),
1515 	},
1516 	[CLK_USB3_DUAL_REF] = {
1517 		.name = "usb3_dual_ref",
1518 		.control_reg = CRL_APB_USB3_DUAL_REF_CTRL,
1519 		.status_reg = 0,
1520 		.parents = &((int32_t []) {
1521 			CLK_IOPLL,
1522 			CLK_DUMMY_PARENT,
1523 			CLK_RPLL,
1524 			CLK_DPLL_TO_LPD,
1525 			CLK_NA_PARENT
1526 		}),
1527 		.nodes = &usb_nodes,
1528 		.num_nodes = ARRAY_SIZE(usb_nodes),
1529 	},
1530 	[CLK_QSPI_REF] = {
1531 		.name = "qspi_ref",
1532 		.control_reg = CRL_APB_QSPI_REF_CTRL,
1533 		.status_reg = 0,
1534 		.parents = &((int32_t []) {
1535 			CLK_IOPLL,
1536 			CLK_DUMMY_PARENT,
1537 			CLK_RPLL,
1538 			CLK_DPLL_TO_LPD,
1539 			CLK_NA_PARENT
1540 		}),
1541 		.nodes = &generic_mux_div_div_gate_nodes,
1542 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1543 	},
1544 	[CLK_SDIO0_REF] = {
1545 		.name = "sdio0_ref",
1546 		.control_reg = CRL_APB_SDIO0_REF_CTRL,
1547 		.status_reg = 0,
1548 		.parents = &((int32_t []) {
1549 			CLK_IOPLL,
1550 			CLK_DUMMY_PARENT,
1551 			CLK_RPLL,
1552 			CLK_VPLL_TO_LPD,
1553 			CLK_NA_PARENT
1554 		}),
1555 		.nodes = &generic_mux_div_div_gate_nodes,
1556 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1557 	},
1558 	[CLK_SDIO1_REF] = {
1559 		.name = "sdio1_ref",
1560 		.control_reg = CRL_APB_SDIO1_REF_CTRL,
1561 		.status_reg = 0,
1562 		.parents = &((int32_t []) {
1563 			CLK_IOPLL,
1564 			CLK_DUMMY_PARENT,
1565 			CLK_RPLL,
1566 			CLK_VPLL_TO_LPD,
1567 			CLK_NA_PARENT
1568 		}),
1569 		.nodes = &generic_mux_div_div_gate_nodes,
1570 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1571 	},
1572 	[CLK_UART0_REF] = {
1573 		.name = "uart0_ref",
1574 		.control_reg = CRL_APB_UART0_REF_CTRL,
1575 		.status_reg = 0,
1576 		.parents = &((int32_t []) {
1577 			CLK_IOPLL,
1578 			CLK_DUMMY_PARENT,
1579 			CLK_RPLL,
1580 			CLK_DPLL_TO_LPD,
1581 			CLK_NA_PARENT
1582 		}),
1583 		.nodes = &generic_mux_div_div_gate_nodes,
1584 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1585 	},
1586 	[CLK_UART1_REF] = {
1587 		.name = "uart1_ref",
1588 		.control_reg = CRL_APB_UART1_REF_CTRL,
1589 		.status_reg = 0,
1590 		.parents = &((int32_t []) {
1591 			CLK_IOPLL,
1592 			CLK_DUMMY_PARENT,
1593 			CLK_RPLL,
1594 			CLK_DPLL_TO_LPD,
1595 			CLK_NA_PARENT
1596 		}),
1597 		.nodes = &generic_mux_div_div_gate_nodes,
1598 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1599 	},
1600 	[CLK_SPI0_REF] = {
1601 		.name = "spi0_ref",
1602 		.control_reg = CRL_APB_SPI0_REF_CTRL,
1603 		.status_reg = 0,
1604 		.parents = &((int32_t []) {
1605 			CLK_IOPLL,
1606 			CLK_DUMMY_PARENT,
1607 			CLK_RPLL,
1608 			CLK_DPLL_TO_LPD,
1609 			CLK_NA_PARENT
1610 		}),
1611 		.nodes = &generic_mux_div_div_gate_nodes,
1612 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1613 	},
1614 	[CLK_SPI1_REF] = {
1615 		.name = "spi1_ref",
1616 		.control_reg = CRL_APB_SPI1_REF_CTRL,
1617 		.status_reg = 0,
1618 		.parents = &((int32_t []) {
1619 			CLK_IOPLL,
1620 			CLK_DUMMY_PARENT,
1621 			CLK_RPLL,
1622 			CLK_DPLL_TO_LPD,
1623 			CLK_NA_PARENT
1624 		}),
1625 		.nodes = &generic_mux_div_div_gate_nodes,
1626 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1627 	},
1628 	[CLK_CAN0_REF] = {
1629 		.name = "can0_ref",
1630 		.control_reg = CRL_APB_CAN0_REF_CTRL,
1631 		.status_reg = 0,
1632 		.parents = &((int32_t []) {
1633 			CLK_IOPLL,
1634 			CLK_DUMMY_PARENT,
1635 			CLK_RPLL,
1636 			CLK_DPLL_TO_LPD,
1637 			CLK_NA_PARENT
1638 		}),
1639 		.nodes = &generic_mux_div_div_gate_nodes,
1640 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1641 	},
1642 	[CLK_CAN1_REF] = {
1643 		.name = "can1_ref",
1644 		.control_reg = CRL_APB_CAN1_REF_CTRL,
1645 		.status_reg = 0,
1646 		.parents = &((int32_t []) {
1647 			CLK_IOPLL,
1648 			CLK_DUMMY_PARENT,
1649 			CLK_RPLL,
1650 			CLK_DPLL_TO_LPD,
1651 			CLK_NA_PARENT
1652 		}),
1653 		.nodes = &generic_mux_div_div_gate_nodes,
1654 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1655 	},
1656 	[CLK_NAND_REF] = {
1657 		.name = "nand_ref",
1658 		.control_reg = CRL_APB_NAND_REF_CTRL,
1659 		.status_reg = 0,
1660 		.parents = &((int32_t []) {
1661 			CLK_IOPLL,
1662 			CLK_DUMMY_PARENT,
1663 			CLK_RPLL,
1664 			CLK_DPLL_TO_LPD,
1665 			CLK_NA_PARENT
1666 		}),
1667 		.nodes = &generic_mux_div_div_gate_nodes,
1668 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1669 	},
1670 	[CLK_GEM_TSU_REF] = {
1671 		.name = "gem_tsu_ref",
1672 		.control_reg = CRL_APB_GEM_TSU_REF_CTRL,
1673 		.status_reg = 0,
1674 		.parents = &((int32_t []) {
1675 			CLK_IOPLL,
1676 			CLK_DUMMY_PARENT,
1677 			CLK_RPLL,
1678 			CLK_DPLL_TO_LPD,
1679 			CLK_NA_PARENT
1680 		}),
1681 		.nodes = &generic_mux_div_div_gate_nodes,
1682 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1683 	},
1684 	[CLK_DLL_REF] = {
1685 		.name = "dll_ref",
1686 		.control_reg = CRL_APB_DLL_REF_CTRL,
1687 		.status_reg = 0,
1688 		.parents = &((int32_t []) {
1689 			CLK_IOPLL,
1690 			CLK_RPLL,
1691 			CLK_NA_PARENT
1692 		}),
1693 		.nodes = &dll_ref_nodes,
1694 		.num_nodes = ARRAY_SIZE(dll_ref_nodes),
1695 	},
1696 	[CLK_ADMA_REF] = {
1697 		.name = "adma_ref",
1698 		.control_reg = CRL_APB_ADMA_REF_CTRL,
1699 		.status_reg = 0,
1700 		.parents = &((int32_t []) {
1701 			CLK_RPLL,
1702 			CLK_DUMMY_PARENT,
1703 			CLK_IOPLL,
1704 			CLK_DPLL_TO_LPD,
1705 			CLK_NA_PARENT
1706 		}),
1707 		.nodes = &generic_mux_div_gate_nodes,
1708 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1709 	},
1710 	[CLK_DBG_LPD] = {
1711 		.name = "dbg_lpd",
1712 		.control_reg = CRL_APB_DBG_LPD_CTRL,
1713 		.status_reg = 0,
1714 		.parents = &((int32_t []) {
1715 			CLK_RPLL,
1716 			CLK_DUMMY_PARENT,
1717 			CLK_IOPLL,
1718 			CLK_DPLL_TO_LPD,
1719 			CLK_NA_PARENT
1720 		}),
1721 		.nodes = &generic_mux_div_gate_nodes,
1722 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1723 	},
1724 	[CLK_CPU_R5] = {
1725 		.name = "cpu_r5",
1726 		.control_reg = CRL_APB_CPU_R5_CTRL,
1727 		.status_reg = 0,
1728 		.parents = &((int32_t []) {
1729 			CLK_RPLL,
1730 			CLK_DUMMY_PARENT,
1731 			CLK_IOPLL,
1732 			CLK_DPLL_TO_LPD,
1733 			CLK_NA_PARENT
1734 		}),
1735 		.nodes = &generic_mux_div_unused_gate_nodes,
1736 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1737 	},
1738 	[CLK_CSU_PLL] = {
1739 		.name = "csu_pll",
1740 		.control_reg = CRL_APB_CSU_PLL_CTRL,
1741 		.status_reg = 0,
1742 		.parents = &((int32_t []) {
1743 			CLK_IOPLL,
1744 			CLK_DUMMY_PARENT,
1745 			CLK_RPLL,
1746 			CLK_DPLL_TO_LPD,
1747 			CLK_NA_PARENT
1748 		}),
1749 		.nodes = &generic_mux_div_gate_nodes,
1750 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1751 	},
1752 	[CLK_PCAP] = {
1753 		.name = "pcap",
1754 		.control_reg = CRL_APB_PCAP_CTRL,
1755 		.status_reg = 0,
1756 		.parents = &((int32_t []) {
1757 			CLK_IOPLL,
1758 			CLK_DUMMY_PARENT,
1759 			CLK_RPLL,
1760 			CLK_DPLL_TO_LPD,
1761 			CLK_NA_PARENT
1762 		}),
1763 		.nodes = &generic_mux_div_gate_nodes,
1764 		.num_nodes = ARRAY_SIZE(generic_mux_div_gate_nodes),
1765 	},
1766 	[CLK_LPD_LSBUS] = {
1767 		.name = "lpd_lsbus",
1768 		.control_reg = CRL_APB_LPD_LSBUS_CTRL,
1769 		.status_reg = 0,
1770 		.parents = &((int32_t []) {
1771 			CLK_RPLL,
1772 			CLK_DUMMY_PARENT,
1773 			CLK_IOPLL,
1774 			CLK_DPLL_TO_LPD,
1775 			CLK_NA_PARENT
1776 		}),
1777 		.nodes = &generic_mux_div_unused_gate_nodes,
1778 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1779 	},
1780 	[CLK_LPD_SWITCH] = {
1781 		.name = "lpd_switch",
1782 		.control_reg = CRL_APB_LPD_SWITCH_CTRL,
1783 		.status_reg = 0,
1784 		.parents = &((int32_t []) {
1785 			CLK_RPLL,
1786 			CLK_DUMMY_PARENT,
1787 			CLK_IOPLL,
1788 			CLK_DPLL_TO_LPD,
1789 			CLK_NA_PARENT
1790 		}),
1791 		.nodes = &generic_mux_div_unused_gate_nodes,
1792 		.num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes),
1793 	},
1794 	[CLK_I2C0_REF] = {
1795 		.name = "i2c0_ref",
1796 		.control_reg = CRL_APB_I2C0_REF_CTRL,
1797 		.status_reg = 0,
1798 		.parents = &((int32_t []) {
1799 			CLK_IOPLL,
1800 			CLK_DUMMY_PARENT,
1801 			CLK_RPLL,
1802 			CLK_DPLL_TO_LPD,
1803 			CLK_NA_PARENT
1804 		}),
1805 		.nodes = &generic_mux_div_div_gate_nodes,
1806 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1807 	},
1808 	[CLK_I2C1_REF] = {
1809 		.name = "i2c1_ref",
1810 		.control_reg = CRL_APB_I2C1_REF_CTRL,
1811 		.status_reg = 0,
1812 		.parents = &((int32_t []) {
1813 			CLK_IOPLL,
1814 			CLK_DUMMY_PARENT,
1815 			CLK_RPLL,
1816 			CLK_DPLL_TO_LPD,
1817 			CLK_NA_PARENT
1818 		}),
1819 		.nodes = &generic_mux_div_div_gate_nodes,
1820 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1821 	},
1822 	[CLK_TIMESTAMP_REF] = {
1823 		.name = "timestamp_ref",
1824 		.control_reg = CRL_APB_TIMESTAMP_REF_CTRL,
1825 		.status_reg = 0,
1826 		.parents = &((int32_t []) {
1827 			CLK_IOPLL,
1828 			CLK_DUMMY_PARENT,
1829 			CLK_RPLL,
1830 			CLK_DPLL_TO_LPD,
1831 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1832 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1833 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1834 			EXT_CLK_PSS_REF | CLK_EXTERNAL_PARENT,
1835 			CLK_NA_PARENT
1836 		}),
1837 		.nodes = &timestamp_ref_nodes,
1838 		.num_nodes = ARRAY_SIZE(timestamp_ref_nodes),
1839 	},
1840 	[CLK_PL0_REF] = {
1841 		.name = "pl0_ref",
1842 		.control_reg = CRL_APB_PL0_REF_CTRL,
1843 		.status_reg = 0,
1844 		.parents = &((int32_t []) {
1845 			CLK_IOPLL,
1846 			CLK_DUMMY_PARENT,
1847 			CLK_RPLL,
1848 			CLK_DPLL_TO_LPD,
1849 			CLK_NA_PARENT
1850 		}),
1851 		.nodes = &pl_nodes,
1852 		.num_nodes = ARRAY_SIZE(pl_nodes),
1853 	},
1854 	[CLK_PL1_REF] = {
1855 		.name = "pl1_ref",
1856 		.control_reg = CRL_APB_PL1_REF_CTRL,
1857 		.status_reg = 0,
1858 		.parents = &((int32_t []) {
1859 			CLK_IOPLL,
1860 			CLK_DUMMY_PARENT,
1861 			CLK_RPLL,
1862 			CLK_DPLL_TO_LPD,
1863 			CLK_NA_PARENT
1864 		}),
1865 		.nodes = &pl_nodes,
1866 		.num_nodes = ARRAY_SIZE(pl_nodes),
1867 	},
1868 	[CLK_PL2_REF] = {
1869 		.name = "pl2_ref",
1870 		.control_reg = CRL_APB_PL2_REF_CTRL,
1871 		.status_reg = 0,
1872 		.parents = &((int32_t []) {
1873 			CLK_IOPLL,
1874 			CLK_DUMMY_PARENT,
1875 			CLK_RPLL,
1876 			CLK_DPLL_TO_LPD,
1877 			CLK_NA_PARENT
1878 		}),
1879 		.nodes = &pl_nodes,
1880 		.num_nodes = ARRAY_SIZE(pl_nodes),
1881 	},
1882 	[CLK_PL3_REF] = {
1883 		.name = "pl3_ref",
1884 		.control_reg = CRL_APB_PL3_REF_CTRL,
1885 		.status_reg = 0,
1886 		.parents = &((int32_t []) {
1887 			CLK_IOPLL,
1888 			CLK_DUMMY_PARENT,
1889 			CLK_RPLL,
1890 			CLK_DPLL_TO_LPD,
1891 			CLK_NA_PARENT
1892 		}),
1893 		.nodes = &pl_nodes,
1894 		.num_nodes = ARRAY_SIZE(pl_nodes),
1895 	},
1896 	[CLK_AMS_REF] = {
1897 		.name = "ams_ref",
1898 		.control_reg = CRL_APB_AMS_REF_CTRL,
1899 		.status_reg = 0,
1900 		.parents = &((int32_t []) {
1901 			CLK_RPLL,
1902 			CLK_DUMMY_PARENT,
1903 			CLK_IOPLL,
1904 			CLK_DPLL_TO_LPD,
1905 			CLK_NA_PARENT
1906 		}),
1907 		.nodes = &generic_mux_div_div_gate_nodes,
1908 		.num_nodes = ARRAY_SIZE(generic_mux_div_div_gate_nodes),
1909 	},
1910 	[CLK_IOPLL_TO_FPD] = {
1911 		.name = "iopll_to_fpd",
1912 		.control_reg = CRL_APB_IOPLL_TO_FPD_CTRL,
1913 		.status_reg = 0,
1914 		.parents = &((int32_t []) {CLK_IOPLL, CLK_NA_PARENT}),
1915 		.nodes = &generic_domain_crossing_nodes,
1916 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
1917 	},
1918 	[CLK_RPLL_TO_FPD] = {
1919 		.name = "rpll_to_fpd",
1920 		.control_reg = CRL_APB_RPLL_TO_FPD_CTRL,
1921 		.status_reg = 0,
1922 		.parents = &((int32_t []) {CLK_RPLL, CLK_NA_PARENT}),
1923 		.nodes = &rpll_to_fpd_nodes,
1924 		.num_nodes = ARRAY_SIZE(rpll_to_fpd_nodes),
1925 	},
1926 	[CLK_APLL_TO_LPD] = {
1927 		.name = "apll_to_lpd",
1928 		.control_reg = CRF_APB_APLL_TO_LPD_CTRL,
1929 		.status_reg = 0,
1930 		.parents = &((int32_t []) {CLK_APLL, CLK_NA_PARENT}),
1931 		.nodes = &generic_domain_crossing_nodes,
1932 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
1933 	},
1934 	[CLK_DPLL_TO_LPD] = {
1935 		.name = "dpll_to_lpd",
1936 		.control_reg = CRF_APB_DPLL_TO_LPD_CTRL,
1937 		.status_reg = 0,
1938 		.parents = &((int32_t []) {CLK_DPLL, CLK_NA_PARENT}),
1939 		.nodes = &generic_domain_crossing_nodes,
1940 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
1941 	},
1942 	[CLK_VPLL_TO_LPD] = {
1943 		.name = "vpll_to_lpd",
1944 		.control_reg = CRF_APB_VPLL_TO_LPD_CTRL,
1945 		.status_reg = 0,
1946 		.parents = &((int32_t []) {CLK_VPLL, CLK_NA_PARENT}),
1947 		.nodes = &generic_domain_crossing_nodes,
1948 		.num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes),
1949 	},
1950 	/*
1951 	 * This clock control requires different registers for mux and gate.
1952 	 * Use control and status registers for the same.
1953 	 */
1954 	[CLK_GEM0_TX] = {
1955 		.name = "gem0_tx",
1956 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1957 		.status_reg = CRL_APB_GEM0_REF_CTRL,
1958 		.parents = &((int32_t []) {
1959 			CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1960 			EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT,
1961 			CLK_NA_PARENT
1962 		}),
1963 		.nodes = &gem0_tx_nodes,
1964 		.num_nodes = ARRAY_SIZE(gem0_tx_nodes),
1965 	},
1966 	/*
1967 	 * This clock control requires different registers for mux and gate.
1968 	 * Use control and status registers for the same.
1969 	 */
1970 	[CLK_GEM1_TX] = {
1971 		.name = "gem1_tx",
1972 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1973 		.status_reg = CRL_APB_GEM1_REF_CTRL,
1974 		.parents = &((int32_t []) {
1975 			CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1976 			EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT,
1977 			CLK_NA_PARENT
1978 		}),
1979 		.nodes = &gem1_tx_nodes,
1980 		.num_nodes = ARRAY_SIZE(gem1_tx_nodes),
1981 	},
1982 	/*
1983 	 * This clock control requires different registers for mux and gate.
1984 	 * Use control and status registers for the same.
1985 	 */
1986 	[CLK_GEM2_TX] = {
1987 		.name = "gem2_tx",
1988 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
1989 		.status_reg = CRL_APB_GEM2_REF_CTRL,
1990 		.parents = &((int32_t []) {
1991 			CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
1992 			EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT,
1993 			CLK_NA_PARENT
1994 		}),
1995 		.nodes = &gem2_tx_nodes,
1996 		.num_nodes = ARRAY_SIZE(gem2_tx_nodes),
1997 	},
1998 	/*
1999 	 * This clock control requires different registers for mux and gate.
2000 	 * Use control and status registers for the same.
2001 	 */
2002 	[CLK_GEM3_TX] = {
2003 		.name = "gem3_tx",
2004 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
2005 		.status_reg = CRL_APB_GEM3_REF_CTRL,
2006 		.parents = &((int32_t []) {
2007 			CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN),
2008 			EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT,
2009 			CLK_NA_PARENT
2010 		}),
2011 		.nodes = &gem3_tx_nodes,
2012 		.num_nodes = ARRAY_SIZE(gem3_tx_nodes),
2013 	},
2014 	[CLK_ACPU_HALF] = {
2015 		.name = "acpu_half",
2016 		.control_reg = CRF_APB_ACPU_CTRL,
2017 		.status_reg = 0,
2018 		.parents = &((int32_t []) {
2019 			CLK_ACPU | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2020 			CLK_NA_PARENT
2021 		}),
2022 		.nodes = &acpu_half_nodes,
2023 		.num_nodes = ARRAY_SIZE(acpu_half_nodes),
2024 	},
2025 	[CLK_WDT] = {
2026 		.name = "wdt",
2027 		.control_reg = FPD_SLCR_WDT_CLK_SEL,
2028 		.status_reg = 0,
2029 		.parents = &((int32_t []) {
2030 			CLK_TOPSW_LSBUS,
2031 			EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
2032 			CLK_NA_PARENT
2033 		}),
2034 		.nodes = &wdt_nodes,
2035 		.num_nodes = ARRAY_SIZE(wdt_nodes),
2036 	},
2037 	[CLK_GPU_PP0_REF] = {
2038 		.name = "gpu_pp0_ref",
2039 		.control_reg = CRF_APB_GPU_REF_CTRL,
2040 		.status_reg = 0,
2041 		.parents = &((int32_t []) {
2042 			CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2043 			CLK_NA_PARENT
2044 		}),
2045 		.nodes = &gpu_pp0_nodes,
2046 		.num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
2047 	},
2048 	[CLK_GPU_PP1_REF] = {
2049 		.name = "gpu_pp1_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_pp1_nodes,
2057 		.num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
2058 	},
2059 	[CLK_GEM_TSU] = {
2060 		.name = "gem_tsu",
2061 		.control_reg = IOU_SLCR_GEM_CLK_CTRL,
2062 		.status_reg = 0,
2063 		.parents = &((int32_t []) {
2064 			CLK_GEM_TSU_REF,
2065 			CLK_GEM_TSU_REF,
2066 			EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
2067 			EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
2068 			CLK_NA_PARENT
2069 		}),
2070 		.nodes = &gem_tsu_nodes,
2071 		.num_nodes = ARRAY_SIZE(gem_tsu_nodes),
2072 	},
2073 	[CLK_CPU_R5_CORE] = {
2074 		.name = "cpu_r5_core",
2075 		.control_reg = CRL_APB_CPU_R5_CTRL,
2076 		.status_reg = 0,
2077 		.parents = &((int32_t []) {
2078 			CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2079 			CLK_DUMMY_PARENT,
2080 			CLK_NA_PARENT
2081 		}),
2082 		.nodes = &cpu_r5_core_nodes,
2083 		.num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
2084 	},
2085 	[CLK_CAN0_MIO] = {
2086 		.name = "can0_mio",
2087 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2088 		.status_reg = 0,
2089 		.parents = &can_mio_parents,
2090 		.nodes = &can0_mio_nodes,
2091 		.num_nodes = ARRAY_SIZE(can0_mio_nodes),
2092 	},
2093 	[CLK_CAN1_MIO] = {
2094 		.name = "can1_mio",
2095 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2096 		.status_reg = 0,
2097 		.parents = &can_mio_parents,
2098 		.nodes = &can1_mio_nodes,
2099 		.num_nodes = ARRAY_SIZE(can1_mio_nodes),
2100 	},
2101 	[CLK_CAN0] = {
2102 		.name = "can0",
2103 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2104 		.status_reg = 0,
2105 		.parents = &((int32_t []) {
2106 			CLK_CAN0_REF,
2107 			CLK_CAN0_MIO,
2108 			CLK_NA_PARENT
2109 		}),
2110 		.nodes = &can0_nodes,
2111 		.num_nodes = ARRAY_SIZE(can0_nodes),
2112 	},
2113 	[CLK_CAN1] = {
2114 		.name = "can1",
2115 		.control_reg = IOU_SLCR_CAN_MIO_CTRL,
2116 		.status_reg = 0,
2117 		.parents = &((int32_t []) {
2118 			CLK_CAN1_REF,
2119 			CLK_CAN1_MIO,
2120 			CLK_NA_PARENT
2121 		}),
2122 		.nodes = &can1_nodes,
2123 		.num_nodes = ARRAY_SIZE(can1_nodes),
2124 	},
2125 };
2126 
2127 static struct pm_ext_clock ext_clocks[] = {
2128 	[EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
2129 		.name = "pss_ref_clk",
2130 	},
2131 	[EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
2132 		.name = "video_clk",
2133 	},
2134 	[EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
2135 		.name = "pss_alt_ref_clk",
2136 	},
2137 	[EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
2138 		.name = "aux_ref_clk",
2139 	},
2140 	[EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
2141 		.name = "video_clk",
2142 	},
2143 	[EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
2144 		.name = "swdt0_ext_clk",
2145 	},
2146 	[EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
2147 		.name = "swdt1_ext_clk",
2148 	},
2149 	[EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
2150 		.name = "gem0_emio_clk",
2151 	},
2152 	[EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
2153 		.name = "gem1_emio_clk",
2154 	},
2155 	[EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
2156 		.name = "gem2_emio_clk",
2157 	},
2158 	[EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
2159 		.name = "gem3_emio_clk",
2160 	},
2161 	[EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
2162 		.name = "mio_clk_50_51",
2163 	},
2164 	EXT_CLK_MIO_DATA(0),
2165 	EXT_CLK_MIO_DATA(1),
2166 	EXT_CLK_MIO_DATA(2),
2167 	EXT_CLK_MIO_DATA(3),
2168 	EXT_CLK_MIO_DATA(4),
2169 	EXT_CLK_MIO_DATA(5),
2170 	EXT_CLK_MIO_DATA(6),
2171 	EXT_CLK_MIO_DATA(7),
2172 	EXT_CLK_MIO_DATA(8),
2173 	EXT_CLK_MIO_DATA(9),
2174 	EXT_CLK_MIO_DATA(10),
2175 	EXT_CLK_MIO_DATA(11),
2176 	EXT_CLK_MIO_DATA(12),
2177 	EXT_CLK_MIO_DATA(13),
2178 	EXT_CLK_MIO_DATA(14),
2179 	EXT_CLK_MIO_DATA(15),
2180 	EXT_CLK_MIO_DATA(16),
2181 	EXT_CLK_MIO_DATA(17),
2182 	EXT_CLK_MIO_DATA(18),
2183 	EXT_CLK_MIO_DATA(19),
2184 	EXT_CLK_MIO_DATA(20),
2185 	EXT_CLK_MIO_DATA(21),
2186 	EXT_CLK_MIO_DATA(22),
2187 	EXT_CLK_MIO_DATA(23),
2188 	EXT_CLK_MIO_DATA(24),
2189 	EXT_CLK_MIO_DATA(25),
2190 	EXT_CLK_MIO_DATA(26),
2191 	EXT_CLK_MIO_DATA(27),
2192 	EXT_CLK_MIO_DATA(28),
2193 	EXT_CLK_MIO_DATA(29),
2194 	EXT_CLK_MIO_DATA(30),
2195 	EXT_CLK_MIO_DATA(31),
2196 	EXT_CLK_MIO_DATA(32),
2197 	EXT_CLK_MIO_DATA(33),
2198 	EXT_CLK_MIO_DATA(34),
2199 	EXT_CLK_MIO_DATA(35),
2200 	EXT_CLK_MIO_DATA(36),
2201 	EXT_CLK_MIO_DATA(37),
2202 	EXT_CLK_MIO_DATA(38),
2203 	EXT_CLK_MIO_DATA(39),
2204 	EXT_CLK_MIO_DATA(40),
2205 	EXT_CLK_MIO_DATA(41),
2206 	EXT_CLK_MIO_DATA(42),
2207 	EXT_CLK_MIO_DATA(43),
2208 	EXT_CLK_MIO_DATA(44),
2209 	EXT_CLK_MIO_DATA(45),
2210 	EXT_CLK_MIO_DATA(46),
2211 	EXT_CLK_MIO_DATA(47),
2212 	EXT_CLK_MIO_DATA(48),
2213 	EXT_CLK_MIO_DATA(49),
2214 	EXT_CLK_MIO_DATA(50),
2215 	EXT_CLK_MIO_DATA(51),
2216 	EXT_CLK_MIO_DATA(52),
2217 	EXT_CLK_MIO_DATA(53),
2218 	EXT_CLK_MIO_DATA(54),
2219 	EXT_CLK_MIO_DATA(55),
2220 	EXT_CLK_MIO_DATA(56),
2221 	EXT_CLK_MIO_DATA(57),
2222 	EXT_CLK_MIO_DATA(58),
2223 	EXT_CLK_MIO_DATA(59),
2224 	EXT_CLK_MIO_DATA(60),
2225 	EXT_CLK_MIO_DATA(61),
2226 	EXT_CLK_MIO_DATA(62),
2227 	EXT_CLK_MIO_DATA(63),
2228 	EXT_CLK_MIO_DATA(64),
2229 	EXT_CLK_MIO_DATA(65),
2230 	EXT_CLK_MIO_DATA(66),
2231 	EXT_CLK_MIO_DATA(67),
2232 	EXT_CLK_MIO_DATA(68),
2233 	EXT_CLK_MIO_DATA(69),
2234 	EXT_CLK_MIO_DATA(70),
2235 	EXT_CLK_MIO_DATA(71),
2236 	EXT_CLK_MIO_DATA(72),
2237 	EXT_CLK_MIO_DATA(73),
2238 	EXT_CLK_MIO_DATA(74),
2239 	EXT_CLK_MIO_DATA(75),
2240 	EXT_CLK_MIO_DATA(76),
2241 	EXT_CLK_MIO_DATA(77),
2242 };
2243 
2244 /* Array of clock which are invalid for this variant */
2245 static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
2246 
2247 /**
2248  * pm_clock_valid - Check if clock is valid or not
2249  * @clock_id	Id of the clock to be queried
2250  *
2251  * This function is used to check if given clock is valid
2252  * or not for the chip variant.
2253  *
2254  * List of invalid clocks are maintained in array list for
2255  * different variants.
2256  *
2257  * Return: Returns 1 if clock is valid else 0.
2258  */
2259 static bool pm_clock_valid(unsigned int clock_id)
2260 {
2261 	unsigned int i;
2262 
2263 	for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
2264 		if (pm_clk_invalid_list[i] == clock_id)
2265 			return 0;
2266 
2267 	return 1;
2268 }
2269 
2270 /**
2271  * pm_clock_type - Get clock's type
2272  * @clock_id	Id of the clock to be queried
2273  *
2274  * This function is used to check type of clock (OUTPUT/EXTERNAL).
2275  *
2276  * Return: Returns type of clock (OUTPUT/EXTERNAL).
2277  */
2278 static unsigned int pm_clock_type(unsigned int clock_id)
2279 {
2280 	return (clock_id < CLK_MAX_OUTPUT_CLK) ?
2281 		CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
2282 }
2283 
2284 /**
2285  * pm_api_clock_get_num_clocks() - PM call to request number of clocks
2286  * @nclocks	Number of clocks
2287  *
2288  * This function is used by master to get number of clocks.
2289  *
2290  * @return	Returns success.
2291  */
2292 enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
2293 {
2294 	*nclocks = CLK_MAX;
2295 
2296 	return PM_RET_SUCCESS;
2297 }
2298 
2299 /**
2300  * pm_api_clock_get_name() - PM call to request a clock's name
2301  * @clock_id	Clock ID
2302  * @name	Name of clock (max 16 bytes)
2303  *
2304  * This function is used by master to get nmae of clock specified
2305  * by given clock ID.
2306  *
2307  * @return	Returns success. In case of error, name data is 0.
2308  */
2309 enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
2310 {
2311 	if (clock_id == CLK_MAX)
2312 		memcpy(name, END_OF_CLK, CLK_NAME_LEN);
2313 	else if (!pm_clock_valid(clock_id))
2314 		memset(name, 0, CLK_NAME_LEN);
2315 	else if (clock_id < CLK_MAX_OUTPUT_CLK)
2316 		memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
2317 	else
2318 		memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
2319 		       CLK_NAME_LEN);
2320 
2321 	return PM_RET_SUCCESS;
2322 }
2323 
2324 /**
2325  * pm_api_clock_get_topology() - PM call to request a clock's topology
2326  * @clock_id	Clock ID
2327  * @index	Topology index for next toplogy node
2328  * @topology	Buffer to store nodes in topology and flags
2329  *
2330  * This function is used by master to get topology information for the
2331  * clock specified by given clock ID. Each response would return 3
2332  * topology nodes. To get next nodes, caller needs to call this API with
2333  * index of next node. Index starts from 0.
2334  *
2335  * @return	Returns status, either success or error+reason
2336  */
2337 enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
2338 					     unsigned int index,
2339 					     uint32_t *topology)
2340 {
2341 	struct pm_clock_node *clock_nodes;
2342 	uint8_t num_nodes;
2343 	unsigned int i;
2344 
2345 	if (!pm_clock_valid(clock_id))
2346 		return PM_RET_ERROR_ARGS;
2347 
2348 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2349 		return PM_RET_ERROR_NOTSUPPORTED;
2350 
2351 
2352 	memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
2353 	clock_nodes = *clocks[clock_id].nodes;
2354 	num_nodes = clocks[clock_id].num_nodes;
2355 
2356 	/* Skip parent till index */
2357 	if (index >= num_nodes)
2358 		return PM_RET_SUCCESS;
2359 
2360 	for (i = 0; i < 3U; i++) {
2361 		if ((index + i) == num_nodes)
2362 			break;
2363 		topology[i] =  clock_nodes[index + i].type;
2364 		topology[i] |= clock_nodes[index + i].clkflags <<
2365 					CLK_CLKFLAGS_SHIFT;
2366 		topology[i] |= clock_nodes[index + i].typeflags <<
2367 					CLK_TYPEFLAGS_SHIFT;
2368 	}
2369 
2370 	return PM_RET_SUCCESS;
2371 }
2372 
2373 /**
2374  * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
2375  *					   factor parameters for fixed clock
2376  * @clock_id	Clock ID
2377  * @mul		Multiplication value
2378  * @div		Divisor value
2379  *
2380  * This function is used by master to get fixed factor parameers for the
2381  * fixed clock. This API is application only for the fixed clock.
2382  *
2383  * @return	Returns status, either success or error+reason
2384  */
2385 enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
2386 						       uint32_t *mul,
2387 						       uint32_t *div)
2388 {
2389 	struct pm_clock_node *clock_nodes;
2390 	uint8_t num_nodes;
2391 	unsigned int type, i;
2392 
2393 	if (!pm_clock_valid(clock_id))
2394 		return PM_RET_ERROR_ARGS;
2395 
2396 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2397 		return PM_RET_ERROR_NOTSUPPORTED;
2398 
2399 	clock_nodes = *clocks[clock_id].nodes;
2400 	num_nodes = clocks[clock_id].num_nodes;
2401 
2402 	for (i = 0; i < num_nodes; i++) {
2403 		type =  clock_nodes[i].type;
2404 		if (type == TYPE_FIXEDFACTOR) {
2405 			*mul = clock_nodes[i].mult;
2406 			*div = clock_nodes[i].div;
2407 			break;
2408 		}
2409 	}
2410 
2411 	/* Clock is not fixed clock */
2412 	if (i == num_nodes)
2413 		return PM_RET_ERROR_ARGS;
2414 
2415 	return PM_RET_SUCCESS;
2416 }
2417 
2418 /**
2419  * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
2420  * @clock_id	Clock ID
2421  * @index	Index of next parent
2422  * @parents	Parents of the given clock
2423  *
2424  * This function is used by master to get clock's parents information.
2425  * This API will return 3 parents with a single response. To get other
2426  * parents, master should call same API in loop with new parent index
2427  * till error is returned.
2428  *
2429  * E.g First call should have index 0 which will return parents 0, 1 and
2430  * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
2431  * so on.
2432  *
2433  * @return	Returns status, either success or error+reason
2434  */
2435 enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
2436 					    unsigned int index,
2437 					    uint32_t *parents)
2438 {
2439 	unsigned int i;
2440 	int32_t *clk_parents;
2441 
2442 	if (!pm_clock_valid(clock_id))
2443 		return PM_RET_ERROR_ARGS;
2444 
2445 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2446 		return PM_RET_ERROR_NOTSUPPORTED;
2447 
2448 	clk_parents = *clocks[clock_id].parents;
2449 	if (clk_parents == NULL)
2450 		return PM_RET_ERROR_ARGS;
2451 
2452 	memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
2453 
2454 	/* Skip parent till index */
2455 	for (i = 0; i < index; i++)
2456 		if (clk_parents[i] == CLK_NA_PARENT)
2457 			return PM_RET_SUCCESS;
2458 
2459 	for (i = 0; i < 3; i++) {
2460 		parents[i] = clk_parents[index + i];
2461 		if (clk_parents[index + i] == CLK_NA_PARENT)
2462 			break;
2463 	}
2464 
2465 	return PM_RET_SUCCESS;
2466 }
2467 
2468 /**
2469  * pm_api_clock_get_attributes() - PM call to request a clock's attributes
2470  * @clock_id	Clock ID
2471  * @attr	Clock attributes
2472  *
2473  * This function is used by master to get clock's attributes
2474  * (e.g. valid, clock type, etc).
2475  *
2476  * @return	Returns status, either success or error+reason
2477  */
2478 enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
2479 					       uint32_t *attr)
2480 {
2481 	if (clock_id >= CLK_MAX)
2482 		return PM_RET_ERROR_ARGS;
2483 
2484 	/* Clock valid bit */
2485 	*attr = pm_clock_valid(clock_id);
2486 
2487 	/* Clock type (Output/External) */
2488 	*attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
2489 
2490 	return PM_RET_SUCCESS;
2491 }
2492 
2493 /**
2494  * pll_get_lockbit() -  Returns lockbit index for pll id
2495  * @pll_id: Id of the pll
2496  *
2497  * This function return the PLL_LOCKED bit index in
2498  * pll status register accosiated with given pll id.
2499  *
2500  * Return: Returns bit index
2501  */
2502 static int pll_get_lockbit(unsigned int pll_id)
2503 {
2504 	switch (pll_id) {
2505 	case CLK_APLL_INT:
2506 	case CLK_IOPLL_INT:
2507 		return 0;
2508 	case CLK_DPLL_INT:
2509 	case CLK_RPLL_INT:
2510 		return 1;
2511 	case CLK_VPLL_INT:
2512 		return 2;
2513 	default:
2514 		return -1;
2515 	}
2516 }
2517 
2518 /**
2519  * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
2520  * @clock_id: Id of the PLL
2521  *
2522  * This function is to bypass and reset PLL.
2523  */
2524 static inline enum pm_ret_status
2525 pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag)
2526 {
2527 	enum pm_ret_status ret = PM_RET_SUCCESS;
2528 	unsigned int reg, val;
2529 	int lockbit;
2530 
2531 	reg = clocks[clock_id].control_reg;
2532 
2533 	if (flag & CLK_PLL_RESET_ASSERT) {
2534 		ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK);
2535 		if (ret != PM_RET_SUCCESS)
2536 			return ret;
2537 		ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2538 				    PLLCTRL_RESET_MASK);
2539 		if (ret != PM_RET_SUCCESS)
2540 			return ret;
2541 	}
2542 	if (flag & CLK_PLL_RESET_RELEASE) {
2543 		ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2544 				    ~PLLCTRL_RESET_MASK);
2545 		if (ret != PM_RET_SUCCESS)
2546 			return ret;
2547 
2548 		lockbit = pll_get_lockbit(clock_id);
2549 		do {
2550 			ret = pm_mmio_read(clocks[clock_id].status_reg, &val);
2551 			if (ret != PM_RET_SUCCESS)
2552 				return ret;
2553 		} while ((lockbit >= 0) && !(val & (1 << lockbit)));
2554 
2555 		ret = pm_mmio_write(reg, PLLCTRL_BP_MASK,
2556 			      ~(unsigned int)PLLCTRL_BP_MASK);
2557 	}
2558 	return ret;
2559 }
2560 
2561 /**
2562  * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
2563  * @clock_id: Id of the clock to be enabled
2564  * @enable: Enable(1)/Disable(0)
2565  *
2566  * This function is to enable/disable the clock which is not PLL.
2567  *
2568  * Return: Returns status, either success or error+reason.
2569  */
2570 static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id,
2571 						    unsigned int enable)
2572 {
2573 	enum pm_ret_status ret = PM_RET_SUCCESS;
2574 	struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2575 	uint8_t num_nodes = clocks[clock_id].num_nodes;
2576 	unsigned int reg, val;
2577 	uint8_t i = 0;
2578 	uint8_t offset = NA_SHIFT, width = NA_WIDTH;
2579 
2580 	if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX ||
2581 	    clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX)
2582 		reg = clocks[clock_id].status_reg;
2583 	else
2584 		reg = clocks[clock_id].control_reg;
2585 
2586 	for (i = 0; i < num_nodes; i++) {
2587 		if (nodes->type == TYPE_GATE) {
2588 			offset = nodes->offset;
2589 			width = nodes->width;
2590 			break;
2591 		}
2592 		nodes++;
2593 	}
2594 	if (width == NA_WIDTH)
2595 		return PM_RET_ERROR_NOTSUPPORTED;
2596 
2597 	ret = pm_mmio_read(reg, &val);
2598 	if (ret != PM_RET_SUCCESS)
2599 		return ret;
2600 	if ((val & BIT_MASK(offset, width)) == enable)
2601 		return PM_RET_SUCCESS;
2602 
2603 	if (enable == 0)
2604 		val &= ~(BIT_MASK(offset, width));
2605 	else
2606 		val |= BIT_MASK(offset, width);
2607 
2608 	ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
2609 
2610 	return ret;
2611 }
2612 
2613 /**
2614  * pm_api_clock_enable() - Enable the clock for given id
2615  * @clock_id: Id of the clock to be enabled
2616  *
2617  * This function is used by master to enable the clock
2618  * including peripherals and PLL clocks.
2619  *
2620  * Return: Returns status, either success or error+reason.
2621  */
2622 enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
2623 {
2624 	enum pm_ret_status ret = PM_RET_SUCCESS;
2625 
2626 	if (!pm_clock_valid(clock_id))
2627 		return PM_RET_ERROR_ARGS;
2628 
2629 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2630 		return PM_RET_ERROR_NOTSUPPORTED;
2631 
2632 	/*
2633 	 * PLL type clock should not enable explicitly.
2634 	 * It is done by FSBL on boot-up and by PMUFW whenever required.
2635 	 */
2636 	if (!ISPLL(clock_id))
2637 		ret = pm_api_clk_enable_disable(clock_id, 1);
2638 
2639 	return ret;
2640 }
2641 
2642 /**
2643  * pm_api_clock_disable - Disable the clock for given id
2644  * @clock_id	Id of the clock to be disable
2645  *
2646  * This function is used by master to disable the clock
2647  * including peripherals and PLL clocks.
2648  *
2649  * Return: Returns status, either success or error+reason.
2650  */
2651 
2652 enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
2653 {
2654 	enum pm_ret_status ret = PM_RET_SUCCESS;
2655 
2656 	if (!pm_clock_valid(clock_id))
2657 		return PM_RET_ERROR_ARGS;
2658 
2659 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2660 		return PM_RET_ERROR_NOTSUPPORTED;
2661 
2662 	/*
2663 	 * PLL type clock should not be disabled explicitly.
2664 	 * It is done by PMUFW if required.
2665 	 */
2666 	if (!ISPLL(clock_id))
2667 		ret = pm_api_clk_enable_disable(clock_id, 0);
2668 
2669 	return ret;
2670 }
2671 
2672 /**
2673  * pm_api_get_pll_state() - Get state of PLL
2674  * @clock_id	Id of the PLL
2675  * @state	State of PLL(1: Enable, 0: Reset)
2676  *
2677  * This function is to check state of PLL.
2678  */
2679 static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
2680 					unsigned int *state)
2681 {
2682 	enum pm_ret_status ret = PM_RET_SUCCESS;
2683 	unsigned int reg, val;
2684 
2685 	reg = clocks[clock_id].control_reg;
2686 
2687 	ret = pm_mmio_read(reg, &val);
2688 
2689 	/* state:
2690 	 * 1 - PLL is enabled
2691 	 * 0 - PLL is in reset state
2692 	 */
2693 	*state = !(val & PLLCTRL_RESET_MASK);
2694 	return ret;
2695 }
2696 
2697 /**
2698  * pm_api_get_clk_state() - Get the state of clock for given id
2699  * @clock_id: Id of the clock to be enabled
2700  * @state: Enable(1)/Disable(0)
2701  *
2702  * This function is to get state of the clock which is not PLL.
2703  *
2704  * Return: Returns status, either success or error+reason.
2705  */
2706 static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
2707 					       unsigned int *state)
2708 {
2709 	enum pm_ret_status ret = PM_RET_SUCCESS;
2710 	struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2711 	uint8_t num_nodes = clocks[clock_id].num_nodes;
2712 	unsigned int reg, val;
2713 	uint8_t i = 0;
2714 	uint8_t offset = NA_SHIFT, width = NA_WIDTH;
2715 
2716 	reg = clocks[clock_id].control_reg;
2717 
2718 	for (i = 0; i < num_nodes; i++) {
2719 		if (nodes->type == TYPE_GATE) {
2720 			offset = nodes->offset;
2721 			width = nodes->width;
2722 		}
2723 		nodes++;
2724 	}
2725 	if (width == NA_WIDTH)
2726 		return PM_RET_ERROR_NOTSUPPORTED;
2727 
2728 	ret = pm_mmio_read(reg, &val);
2729 	*state = (val & BIT_MASK(offset, width)) >> offset;
2730 
2731 	return ret;
2732 }
2733 
2734 /**
2735  * pm_api_clock_getstate - Get the clock state for given id
2736  * @clock_id	Id of the clock to be queried
2737  * @state	1/0 (Enabled/Disabled)
2738  *
2739  * This function is used by master to get the state of clock
2740  * including peripherals and PLL clocks.
2741  *
2742  * Return: Returns status, either success or error+reason.
2743  */
2744 enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
2745 					 unsigned int *state)
2746 {
2747 	enum pm_ret_status ret = PM_RET_SUCCESS;
2748 
2749 	if (!pm_clock_valid(clock_id))
2750 		return PM_RET_ERROR_ARGS;
2751 
2752 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2753 		return PM_RET_ERROR_NOTSUPPORTED;
2754 
2755 	if (ISPLL(clock_id))
2756 		ret = pm_api_get_pll_state(clock_id, state);
2757 	else
2758 		ret = pm_api_get_clk_state(clock_id, state);
2759 
2760 	return ret;
2761 }
2762 
2763 static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
2764 						 uint32_t divider)
2765 {
2766 	enum pm_ret_status ret = PM_RET_SUCCESS;
2767 	struct pm_clock_node *nodes;
2768 	uint8_t num_nodes;
2769 	uint16_t div1, div2;
2770 	unsigned int reg, mask = 0, val = 0, i;
2771 	uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2772 	uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
2773 
2774 	div1 = (uint16_t)(divider & 0xFFFFU);
2775 	div2 = (uint16_t)((divider >> 16) & 0xFFFFU);
2776 
2777 	reg = clocks[clock_id].control_reg;
2778 
2779 	nodes = *clocks[clock_id].nodes;
2780 	num_nodes = clocks[clock_id].num_nodes;
2781 	for (i = 0; i < num_nodes; i++) {
2782 		if (nodes->type == TYPE_DIV1) {
2783 			div1_offset = nodes->offset;
2784 			div1_width = nodes->width;
2785 		}
2786 		if (nodes->type == TYPE_DIV2) {
2787 			div2_offset = nodes->offset;
2788 			div2_width = nodes->width;
2789 		}
2790 		nodes++;
2791 	}
2792 
2793 	if (div1 != (uint16_t)-1) {
2794 		if (div1_width == NA_WIDTH)
2795 			return PM_RET_ERROR_NOTSUPPORTED;
2796 		val |= div1 << div1_offset;
2797 		mask |= BIT_MASK(div1_offset, div1_width);
2798 	}
2799 	if (div2 != (uint16_t)-1) {
2800 		if (div2_width == NA_WIDTH)
2801 			return PM_RET_ERROR_NOTSUPPORTED;
2802 		val |= div2 << div2_offset;
2803 		mask |= BIT_MASK(div2_offset, div2_width);
2804 	}
2805 	ret = pm_mmio_write(reg, mask, val);
2806 
2807 	return ret;
2808 }
2809 
2810 static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
2811 					  unsigned int divider)
2812 {
2813 	unsigned int reg = clocks[clock_id].control_reg;
2814 	enum pm_ret_status ret;
2815 
2816 	pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_ASSERT);
2817 	ret = pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
2818 	pm_api_pll_bypass_and_reset(clock_id, CLK_PLL_RESET_RELEASE);
2819 
2820 	return ret;
2821 }
2822 
2823 /**
2824  * pm_api_clock_setdivider - Set the clock divider for given id
2825  * @clock_id	Id of the clock
2826  * @divider	Divider value
2827  *
2828  * This function is used by master to set divider for any clock
2829  * to achieve desired rate.
2830  *
2831  * Return: Returns status, either success or error+reason.
2832  */
2833 enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
2834 					   unsigned int divider)
2835 {
2836 	enum pm_ret_status ret;
2837 
2838 	if (!pm_clock_valid(clock_id))
2839 		return PM_RET_ERROR_ARGS;
2840 
2841 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2842 		return PM_RET_ERROR_NOTSUPPORTED;
2843 
2844 	if (ISPLL(clock_id))
2845 		ret = pm_api_pll_set_divider(clock_id, divider);
2846 	else
2847 		ret = pm_api_clk_set_divider(clock_id, divider);
2848 
2849 	return ret;
2850 }
2851 
2852 static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id,
2853 						 uint32_t *divider)
2854 {
2855 	enum pm_ret_status ret = PM_RET_SUCCESS;
2856 	struct pm_clock_node *nodes;
2857 	uint8_t num_nodes;
2858 	unsigned int reg, val, i, div1 = 0, div2 = 0;
2859 	uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2860 	uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
2861 
2862 	reg = clocks[clock_id].control_reg;
2863 
2864 	nodes = *clocks[clock_id].nodes;
2865 	num_nodes = clocks[clock_id].num_nodes;
2866 	for (i = 0; i < num_nodes; i++) {
2867 		if (nodes->type == TYPE_DIV1) {
2868 			div1_offset = nodes->offset;
2869 			div1_width = nodes->width;
2870 		}
2871 		if (nodes->type == TYPE_DIV2) {
2872 			div2_offset = nodes->offset;
2873 			div2_width = nodes->width;
2874 		}
2875 		nodes++;
2876 	}
2877 
2878 	ret = pm_mmio_read(reg, &val);
2879 
2880 	if (div1_width == NA_WIDTH)
2881 		return PM_RET_ERROR_ARGS;
2882 
2883 	div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset;
2884 
2885 	if (div2_width != NA_WIDTH)
2886 		div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset;
2887 
2888 	*divider = div1 | (div2 << 16);
2889 
2890 	return ret;
2891 }
2892 
2893 static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id,
2894 					  unsigned int *divider)
2895 {
2896 	enum pm_ret_status ret = PM_RET_SUCCESS;
2897 	unsigned int reg, val;
2898 
2899 	reg = clocks[clock_id].control_reg;
2900 
2901 	ret = pm_mmio_read(reg, &val);
2902 	*divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
2903 
2904 	return ret;
2905 }
2906 
2907 /**
2908  * pm_api_clock_getdivider - Get the clock divider for given id
2909  * @clock_id	Id of the clock
2910  * @divider	Divider value
2911  *
2912  * This function is used by master to get divider values
2913  * for any clock.
2914  *
2915  * Return: Returns status, either success or error+reason.
2916  */
2917 enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
2918 					   unsigned int *divider)
2919 {
2920 	enum pm_ret_status ret;
2921 
2922 	if (!pm_clock_valid(clock_id))
2923 		return PM_RET_ERROR_ARGS;
2924 
2925 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2926 		return PM_RET_ERROR_NOTSUPPORTED;
2927 
2928 	if (ISPLL(clock_id))
2929 		ret = pm_api_pll_get_divider(clock_id, divider);
2930 	else
2931 		ret = pm_api_clk_get_divider(clock_id, divider);
2932 
2933 	return ret;
2934 }
2935 
2936 /**
2937  * pm_api_clock_setrate - Set the clock rate for given id
2938  * @clock_id	Id of the clock
2939  * @rate	Rate value in hz
2940  *
2941  * This function is used by master to set rate for any clock.
2942  *
2943  * Return: Returns status, either success or error+reason.
2944  */
2945 enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
2946 					uint64_t rate)
2947 {
2948 	return PM_RET_ERROR_NOTSUPPORTED;
2949 }
2950 
2951 /**
2952  * pm_api_clock_getrate - Get the clock rate for given id
2953  * @clock_id	Id of the clock
2954  * @rate	rate value in hz
2955  *
2956  * This function is used by master to get rate
2957  * for any clock.
2958  *
2959  * Return: Returns status, either success or error+reason.
2960  */
2961 enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
2962 					uint64_t *rate)
2963 {
2964 	return PM_RET_ERROR_NOTSUPPORTED;
2965 }
2966 
2967 /**
2968  * pm_api_clock_setparent - Set the clock parent for given id
2969  * @clock_id	Id of the clock
2970  * @parent_idx	parent index
2971  *
2972  * This function is used by master to set parent for any clock.
2973  *
2974  * Return: Returns status, either success or error+reason.
2975  */
2976 enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
2977 					  unsigned int parent_idx)
2978 {
2979 	enum pm_ret_status ret = PM_RET_SUCCESS;
2980 	struct pm_clock_node *nodes;
2981 	uint8_t num_nodes;
2982 	unsigned int reg, val;
2983 	int32_t *clk_parents;
2984 	unsigned int i = 0;
2985 	uint8_t  offset = NA_SHIFT, width = NA_WIDTH;
2986 
2987 	if (!pm_clock_valid(clock_id))
2988 		return PM_RET_ERROR_ARGS;
2989 
2990 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2991 		return PM_RET_ERROR_NOTSUPPORTED;
2992 
2993 	clk_parents = *clocks[clock_id].parents;
2994 
2995 	for (i = 0; i <= parent_idx; i++)
2996 		if (clk_parents[i] == CLK_NA_PARENT)
2997 			return PM_RET_ERROR_ARGS;
2998 
2999 	nodes = *clocks[clock_id].nodes;
3000 	num_nodes = clocks[clock_id].num_nodes;
3001 	for (i = 0; i < num_nodes; i++) {
3002 		if (nodes->type == TYPE_MUX) {
3003 			offset = nodes->offset;
3004 			width = nodes->width;
3005 		}
3006 		nodes++;
3007 	}
3008 	if (width == NA_WIDTH)
3009 		return PM_RET_ERROR_NOTSUPPORTED;
3010 
3011 	reg = clocks[clock_id].control_reg;
3012 	val = parent_idx << offset;
3013 	ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
3014 
3015 	return ret;
3016 }
3017 
3018 /**
3019  * pm_api_clock_getparent - Get the clock parent for given id
3020  * @clock_id	Id of the clock
3021  * @parent_idx	parent index
3022  *
3023  * This function is used by master to get parent index
3024  * for any clock.
3025  *
3026  * Return: Returns status, either success or error+reason.
3027  */
3028 enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
3029 					  unsigned int *parent_idx)
3030 {
3031 	enum pm_ret_status ret = PM_RET_SUCCESS;
3032 	struct pm_clock_node *nodes;
3033 	uint8_t num_nodes;
3034 	unsigned int reg, val;
3035 	uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
3036 
3037 	if (!pm_clock_valid(clock_id))
3038 		return PM_RET_ERROR_ARGS;
3039 
3040 	if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
3041 		return PM_RET_ERROR_NOTSUPPORTED;
3042 
3043 	nodes = *clocks[clock_id].nodes;
3044 	num_nodes = clocks[clock_id].num_nodes;
3045 
3046 	for (i = 0; i < num_nodes; i++) {
3047 		if (nodes->type == TYPE_MUX) {
3048 			offset = nodes->offset;
3049 			width = nodes->width;
3050 		}
3051 		nodes++;
3052 	}
3053 	if (width == NA_WIDTH)
3054 		return PM_RET_ERROR_NOTSUPPORTED;
3055 
3056 	reg = clocks[clock_id].control_reg;
3057 	ret = pm_mmio_read(reg, &val);
3058 	val >>= offset;
3059 	val &= ((1U << width) - 1);
3060 
3061 	*parent_idx = val;
3062 
3063 	return ret;
3064 }
3065 
3066 /**
3067  * pm_api_clk_set_pll_mode() -  Set PLL mode
3068  * @pll     PLL id
3069  * @mode    Mode fraction/integar
3070  *
3071  * This function sets PLL mode.
3072  *
3073  * @return      Returns status, either success or error+reason
3074  */
3075 enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
3076 					   unsigned int mode)
3077 {
3078 	enum pm_ret_status ret = PM_RET_SUCCESS;
3079 	unsigned int reg;
3080 
3081 	if (!pm_clock_valid(pll))
3082 		return PM_RET_ERROR_ARGS;
3083 
3084 	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3085 		return PM_RET_ERROR_NOTSUPPORTED;
3086 
3087 	if (!ISPLL(pll))
3088 		return PM_RET_ERROR_NOTSUPPORTED;
3089 
3090 	if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)
3091 		return PM_RET_ERROR_ARGS;
3092 
3093 	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3094 
3095 	ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK,
3096 			    mode << PLL_FRAC_MODE_SHIFT);
3097 
3098 	return ret;
3099 }
3100 
3101 /**
3102  * pm_ioctl_get_pll_mode() -  Get PLL mode
3103  * @pll     PLL id
3104  * @mode    Mode fraction/integar
3105  *
3106  * This function returns current PLL mode.
3107  *
3108  * @return      Returns status, either success or error+reason
3109  */
3110 enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
3111 					   unsigned int *mode)
3112 {
3113 	enum pm_ret_status ret = PM_RET_SUCCESS;
3114 	unsigned int val, reg;
3115 
3116 	if (!pm_clock_valid(pll))
3117 		return PM_RET_ERROR_ARGS;
3118 
3119 	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3120 		return PM_RET_ERROR_NOTSUPPORTED;
3121 
3122 	if (!ISPLL(pll))
3123 		return PM_RET_ERROR_NOTSUPPORTED;
3124 
3125 	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3126 
3127 	ret = pm_mmio_read(reg, &val);
3128 	val = val & PLL_FRAC_MODE_MASK;
3129 	if (val == 0)
3130 		*mode = PLL_INT_MODE;
3131 	else
3132 		*mode = PLL_FRAC_MODE;
3133 
3134 	return ret;
3135 }
3136 
3137 /**
3138  * pm_api_clk_set_pll_frac_data() -  Set PLL fraction data
3139  * @pll     PLL id
3140  * @data    fraction data
3141  *
3142  * This function sets fraction data. It is valid for fraction
3143  * mode only.
3144  *
3145  * @return      Returns status, either success or error+reason
3146  */
3147 enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
3148 						unsigned int data)
3149 {
3150 	enum pm_ret_status ret = PM_RET_SUCCESS;
3151 	unsigned int val, reg, mode = 0;
3152 
3153 	if (!pm_clock_valid(pll))
3154 		return PM_RET_ERROR_ARGS;
3155 
3156 	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3157 		return PM_RET_ERROR_NOTSUPPORTED;
3158 
3159 	if (!ISPLL(pll))
3160 		return PM_RET_ERROR_NOTSUPPORTED;
3161 
3162 	ret = pm_api_clk_get_pll_mode(pll, &mode);
3163 	if (ret != PM_RET_SUCCESS)
3164 		return ret;
3165 	if (mode == PLL_FRAC_MODE) {
3166 		reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3167 		val = data << PLL_FRAC_DATA_SHIFT;
3168 		ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val);
3169 	} else {
3170 		return PM_RET_ERROR_ARGS;
3171 	}
3172 
3173 	return ret;
3174 }
3175 
3176 /**
3177  * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
3178  * @pll     PLL id
3179  * @data    fraction data
3180  *
3181  * This function returns fraction data value.
3182  *
3183  * @return      Returns status, either success or error+reason
3184  */
3185 enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
3186 						unsigned int *data)
3187 {
3188 	enum pm_ret_status ret = PM_RET_SUCCESS;
3189 	unsigned int val, reg;
3190 
3191 	if (!pm_clock_valid(pll))
3192 		return PM_RET_ERROR_ARGS;
3193 
3194 	if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3195 		return PM_RET_ERROR_NOTSUPPORTED;
3196 
3197 	if (!ISPLL(pll))
3198 		return PM_RET_ERROR_NOTSUPPORTED;
3199 
3200 	reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3201 
3202 	ret = pm_mmio_read(reg, &val);
3203 	*data = (val & PLL_FRAC_DATA_MASK);
3204 
3205 	return ret;
3206 }
3207