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