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