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