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