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