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