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