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