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