blob: a41eebbc065ae64807bf6c92aea2438f9d02631d [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>
Jolly Shah69fb5bf2018-02-07 16:25:41 -080014#include <stdbool.h>
Rajan Vaja35116132018-01-17 02:39:25 -080015#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
Jolly Shah69fb5bf2018-02-07 16:25:41 -080022#define CLK_NODE_MAX U(6)
Rajan Vaja35116132018-01-17 02:39:25 -080023
Jolly Shah69fb5bf2018-02-07 16:25:41 -080024#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_INIT_ENABLE_SHIFT U(1)
29#define CLK_TYPE_SHIFT U(2)
30#define CLK_CLKFLAGS_SHIFT U(8)
31#define CLK_TYPEFLAGS_SHIFT U(24)
Rajan Vajad98455b2018-01-17 02:39:26 -080032
33#define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
34
Jolly Shah69fb5bf2018-02-07 16:25:41 -080035#define NA_MULT U(0)
36#define NA_DIV U(0)
37#define NA_SHIFT U(0)
38#define NA_WIDTH U(0)
39#define NA_CLK_FLAGS U(0)
40#define NA_TYPE_FLAGS U(0)
Rajan Vajad98455b2018-01-17 02:39:26 -080041
42/* PLL nodes related definitions */
Jolly Shah69fb5bf2018-02-07 16:25:41 -080043#define PLL_PRESRC_MUX_SHIFT U(20)
44#define PLL_PRESRC_MUX_WIDTH U(3)
45#define PLL_POSTSRC_MUX_SHIFT U(24)
46#define PLL_POSTSRC_MUX_WIDTH U(3)
47#define PLL_DIV2_MUX_SHIFT U(16)
48#define PLL_DIV2_MUX_WIDTH U(1)
49#define PLL_BYPASS_MUX_SHIFT U(3)
50#define PLL_BYPASS_MUX_WIDTH U(1)
Rajan Vajad98455b2018-01-17 02:39:26 -080051
52/* Peripheral nodes related definitions */
53/* Peripheral Clocks */
Jolly Shah69fb5bf2018-02-07 16:25:41 -080054#define PERIPH_MUX_SHIFT U(0)
55#define PERIPH_MUX_WIDTH U(3)
56#define PERIPH_DIV1_SHIFT U(8)
57#define PERIPH_DIV1_WIDTH U(6)
58#define PERIPH_DIV2_SHIFT U(16)
59#define PERIPH_DIV2_WIDTH U(6)
60#define PERIPH_GATE_SHIFT U(24)
61#define PERIPH_GATE_WIDTH U(1)
Rajan Vajad98455b2018-01-17 02:39:26 -080062
Jolly Shah69fb5bf2018-02-07 16:25:41 -080063#define USB_GATE_SHIFT U(25)
Rajan Vajad98455b2018-01-17 02:39:26 -080064
65/* External clock related definitions */
66
67#define EXT_CLK_MIO_DATA(mio) \
68 [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \
69 .name = "mio_clk_"#mio, \
70 }
71
72#define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK)
73
74/* Clock control related definitions */
75#define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
76
Jolly Shah69fb5bf2018-02-07 16:25:41 -080077#define ISPLL(id) (id == CLK_APLL_INT || \
78 id == CLK_DPLL_INT || \
79 id == CLK_VPLL_INT || \
80 id == CLK_IOPLL_INT || \
81 id == CLK_RPLL_INT)
82
Rajan Vajad98455b2018-01-17 02:39:26 -080083
84#define PLLCTRL_BP_MASK BIT(3)
Jolly Shah69fb5bf2018-02-07 16:25:41 -080085#define PLLCTRL_RESET_MASK U(1)
86#define PLL_FRAC_OFFSET U(8)
87#define PLL_FRAC_MODE U(1)
88#define PLL_INT_MODE U(0)
89#define PLL_FRAC_MODE_MASK U(0x80000000)
90#define PLL_FRAC_MODE_SHIFT U(31)
91#define PLL_FRAC_DATA_MASK U(0xFFFF)
92#define PLL_FRAC_DATA_SHIFT U(0)
93#define PLL_FBDIV_MASK U(0x7F00)
94#define PLL_FBDIV_WIDTH U(7)
95#define PLL_FBDIV_SHIFT U(8)
Rajan Vajad98455b2018-01-17 02:39:26 -080096
Jolly Shah69fb5bf2018-02-07 16:25:41 -080097#define CLK_PLL_RESET_ASSERT U(1)
98#define CLK_PLL_RESET_RELEASE U(2)
Rajan Vajad98455b2018-01-17 02:39:26 -080099#define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
100
101/* Common topology definitions */
102#define GENERIC_MUX \
103 { \
104 .type = TYPE_MUX, \
105 .offset = PERIPH_MUX_SHIFT, \
106 .width = PERIPH_MUX_WIDTH, \
107 .clkflags = CLK_SET_RATE_NO_REPARENT | \
108 CLK_IS_BASIC, \
109 .typeflags = NA_TYPE_FLAGS, \
110 .mult = NA_MULT, \
111 .div = NA_DIV, \
112 }
113
114#define IGNORE_UNUSED_MUX \
115 { \
116 .type = TYPE_MUX, \
117 .offset = PERIPH_MUX_SHIFT, \
118 .width = PERIPH_MUX_WIDTH, \
119 .clkflags = CLK_IGNORE_UNUSED | \
120 CLK_SET_RATE_NO_REPARENT | \
121 CLK_IS_BASIC, \
122 .typeflags = NA_TYPE_FLAGS, \
123 .mult = NA_MULT, \
124 .div = NA_DIV, \
125 }
126
127#define GENERIC_DIV(id) \
128 { \
129 .type = TYPE_DIV##id, \
130 .offset = PERIPH_DIV##id##_SHIFT, \
131 .width = PERIPH_DIV##id##_WIDTH, \
132 .clkflags = CLK_SET_RATE_NO_REPARENT | \
133 CLK_IS_BASIC, \
134 .typeflags = CLK_DIVIDER_ONE_BASED | \
135 CLK_DIVIDER_ALLOW_ZERO, \
136 .mult = NA_MULT, \
137 .div = NA_DIV, \
138 }
139
140#define IGNORE_UNUSED_DIV(id) \
141 { \
142 .type = TYPE_DIV##id, \
143 .offset = PERIPH_DIV##id##_SHIFT, \
144 .width = PERIPH_DIV##id##_WIDTH, \
145 .clkflags = CLK_IGNORE_UNUSED | \
146 CLK_SET_RATE_NO_REPARENT | \
147 CLK_IS_BASIC, \
148 .typeflags = CLK_DIVIDER_ONE_BASED | \
149 CLK_DIVIDER_ALLOW_ZERO, \
150 .mult = NA_MULT, \
151 .div = NA_DIV, \
152 }
153
154#define GENERIC_GATE \
155 { \
156 .type = TYPE_GATE, \
157 .offset = PERIPH_GATE_SHIFT, \
158 .width = PERIPH_GATE_WIDTH, \
159 .clkflags = CLK_SET_RATE_PARENT | \
160 CLK_SET_RATE_GATE | \
161 CLK_IS_BASIC, \
162 .typeflags = NA_TYPE_FLAGS, \
163 .mult = NA_MULT, \
164 .div = NA_DIV, \
165 }
166
167#define IGNORE_UNUSED_GATE \
168 { \
169 .type = TYPE_GATE, \
170 .offset = PERIPH_GATE_SHIFT, \
171 .width = PERIPH_GATE_WIDTH, \
172 .clkflags = CLK_SET_RATE_PARENT | \
173 CLK_IGNORE_UNUSED | \
174 CLK_IS_BASIC, \
175 .typeflags = NA_TYPE_FLAGS, \
176 .mult = NA_MULT, \
177 .div = NA_DIV, \
178 }
179
Rajan Vaja35116132018-01-17 02:39:25 -0800180/**
181 * struct pm_clock_node - Clock topology node information
182 * @type: Topology type (mux/div1/div2/gate/pll/fixed factor)
183 * @offset: Offset in control register
184 * @width: Width of the specific type in control register
185 * @clkflags: Clk specific flags
186 * @typeflags: Type specific flags
187 * @mult: Multiplier for fixed factor
188 * @div: Divisor for fixed factor
189 */
190struct pm_clock_node {
191 uint16_t clkflags;
192 uint16_t typeflags;
193 uint8_t type;
194 uint8_t offset;
195 uint8_t width;
196 uint8_t mult:4;
197 uint8_t div:4;
198};
199
200/**
201 * struct pm_clock - Clock structure
202 * @name: Clock name
203 * @control_reg: Control register address
204 * @status_reg: Status register address
205 * @parents: Parents for first clock node. Lower byte indicates parent
206 * clock id and upper byte indicate flags for that id.
207 * pm_clock_node: Clock nodes
208 */
209struct pm_clock {
210 char name[CLK_NAME_LEN];
211 uint8_t num_nodes;
212 unsigned int control_reg;
213 unsigned int status_reg;
214 int32_t (*parents)[];
215 struct pm_clock_node(*nodes)[];
216};
217
Rajan Vajad98455b2018-01-17 02:39:26 -0800218/**
219 * struct pm_clock - Clock structure
220 * @name: Clock name
221 */
222struct pm_ext_clock {
223 char name[CLK_NAME_LEN];
224};
225
226/* PLL Clocks */
227static struct pm_clock_node generic_pll_nodes[] = {
228 {
229 .type = TYPE_PLL,
230 .offset = NA_SHIFT,
231 .width = NA_WIDTH,
232 .clkflags = CLK_SET_RATE_NO_REPARENT,
233 .typeflags = NA_TYPE_FLAGS,
234 .mult = NA_MULT,
235 .div = NA_DIV,
236 },
237};
238
239static struct pm_clock_node ignore_unused_pll_nodes[] = {
240 {
241 .type = TYPE_PLL,
242 .offset = NA_SHIFT,
243 .width = NA_WIDTH,
244 .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
245 .typeflags = NA_TYPE_FLAGS,
246 .mult = NA_MULT,
247 .div = NA_DIV,
248 },
249};
250
251static struct pm_clock_node generic_pll_pre_src_nodes[] = {
252 {
253 .type = TYPE_MUX,
254 .offset = PLL_PRESRC_MUX_SHIFT,
255 .width = PLL_PRESRC_MUX_WIDTH,
256 .clkflags = CLK_IS_BASIC,
257 .typeflags = NA_TYPE_FLAGS,
258 .mult = NA_MULT,
259 .div = NA_DIV,
260 },
261};
262
263static struct pm_clock_node generic_pll_half_nodes[] = {
264 {
265 .type = TYPE_FIXEDFACTOR,
266 .offset = NA_SHIFT,
267 .width = NA_WIDTH,
268 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
269 .typeflags = NA_TYPE_FLAGS,
270 .mult = 1,
271 .div = 2,
272 },
273};
274
275static struct pm_clock_node generic_pll_int_nodes[] = {
276 {
277 .type = TYPE_MUX,
278 .offset = PLL_DIV2_MUX_SHIFT,
279 .width = PLL_DIV2_MUX_WIDTH,
280 .clkflags = CLK_SET_RATE_NO_REPARENT |
281 CLK_SET_RATE_PARENT |
282 CLK_IS_BASIC,
283 .typeflags = NA_TYPE_FLAGS,
284 .mult = NA_MULT,
285 .div = NA_DIV,
286 },
287};
288
289static struct pm_clock_node generic_pll_post_src_nodes[] = {
290 {
291 .type = TYPE_MUX,
292 .offset = PLL_POSTSRC_MUX_SHIFT,
293 .width = PLL_POSTSRC_MUX_WIDTH,
294 .clkflags = CLK_IS_BASIC,
295 .typeflags = NA_TYPE_FLAGS,
296 .mult = NA_MULT,
297 .div = NA_DIV,
298 },
299};
300
301static struct pm_clock_node generic_pll_system_nodes[] = {
302 {
303 .type = TYPE_MUX,
304 .offset = PLL_BYPASS_MUX_SHIFT,
305 .width = PLL_BYPASS_MUX_WIDTH,
306 .clkflags = CLK_SET_RATE_NO_REPARENT |
307 CLK_SET_RATE_PARENT |
308 CLK_IS_BASIC,
309 .typeflags = NA_TYPE_FLAGS,
310 .mult = NA_MULT,
311 .div = NA_DIV,
312 },
313};
314
315static struct pm_clock_node acpu_nodes[] = {
316 {
317 .type = TYPE_MUX,
318 .offset = PERIPH_MUX_SHIFT,
319 .width = PERIPH_MUX_WIDTH,
320 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
321 .typeflags = NA_TYPE_FLAGS,
322 .mult = NA_MULT,
323 .div = NA_DIV,
324 },
325 {
326 .type = TYPE_DIV1,
327 .offset = PERIPH_DIV1_SHIFT,
328 .width = PERIPH_DIV1_WIDTH,
329 .clkflags = CLK_IS_BASIC,
330 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
331 .mult = NA_MULT,
332 .div = NA_DIV,
333 },
334 {
335 .type = TYPE_GATE,
336 .offset = PERIPH_GATE_SHIFT,
337 .width = PERIPH_GATE_WIDTH,
338 .clkflags = CLK_SET_RATE_PARENT |
339 CLK_IGNORE_UNUSED |
340 CLK_IS_BASIC,
341 .typeflags = NA_TYPE_FLAGS,
342 .mult = NA_MULT,
343 .div = NA_DIV,
344 },
345};
346
347static struct pm_clock_node generic_mux_div_nodes[] = {
348 GENERIC_MUX,
349 GENERIC_DIV(1),
350};
351
352static struct pm_clock_node generic_mux_div_gate_nodes[] = {
353 GENERIC_MUX,
354 GENERIC_DIV(1),
355 GENERIC_GATE,
356};
357
358static struct pm_clock_node generic_mux_div_unused_gate_nodes[] = {
359 GENERIC_MUX,
360 GENERIC_DIV(1),
361 IGNORE_UNUSED_GATE,
362};
363
364static 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
371static 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
416static 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
432static 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
444static 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
456static 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
479static 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
493static 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,
500 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
501 .mult = NA_MULT,
502 .div = NA_DIV,
503 },
504};
505
506static 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
537static 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
549static 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
561static 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
592static 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
613static 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
634static 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
655static 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
676static 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
690static 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
704static 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
718static 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
732static 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
746static 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
759static 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
773static 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
787static 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
Rajan Vaja35116132018-01-17 02:39:25 -0800810/* Clock array containing clock informaton */
Rajan Vajad98455b2018-01-17 02:39:26 -0800811static 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 = IOU_SLCR_WDT_CLK_SEL,
2026 .status_reg = 0,
2027 .parents = &((int32_t []) {
2028 CLK_TOPSW_LSBUS,
2029 EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
2030 EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT,
2031 CLK_NA_PARENT
2032 }),
2033 .nodes = &wdt_nodes,
2034 .num_nodes = ARRAY_SIZE(wdt_nodes),
2035 },
2036 [CLK_GPU_PP0_REF] = {
2037 .name = "gpu_pp0_ref",
2038 .control_reg = CRF_APB_GPU_REF_CTRL,
2039 .status_reg = 0,
2040 .parents = &((int32_t []) {
2041 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2042 CLK_NA_PARENT
2043 }),
2044 .nodes = &gpu_pp0_nodes,
2045 .num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
2046 },
2047 [CLK_GPU_PP1_REF] = {
2048 .name = "gpu_pp1_ref",
2049 .control_reg = CRF_APB_GPU_REF_CTRL,
2050 .status_reg = 0,
2051 .parents = &((int32_t []) {
2052 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2053 CLK_NA_PARENT
2054 }),
2055 .nodes = &gpu_pp1_nodes,
2056 .num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
2057 },
2058 [CLK_GEM_TSU] = {
2059 .name = "gem_tsu",
2060 .control_reg = IOU_SLCR_GEM_CLK_CTRL,
2061 .status_reg = 0,
2062 .parents = &((int32_t []) {
2063 CLK_GEM_TSU_REF,
2064 CLK_GEM_TSU_REF,
2065 EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
2066 EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
2067 CLK_NA_PARENT
2068 }),
2069 .nodes = &gem_tsu_nodes,
2070 .num_nodes = ARRAY_SIZE(gem_tsu_nodes),
2071 },
2072 [CLK_CPU_R5_CORE] = {
2073 .name = "cpu_r5_core",
2074 .control_reg = CRL_APB_CPU_R5_CTRL,
2075 .status_reg = 0,
2076 .parents = &((int32_t []) {
2077 CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2078 CLK_DUMMY_PARENT,
2079 CLK_NA_PARENT
2080 }),
2081 .nodes = &cpu_r5_core_nodes,
2082 .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
2083 },
2084 [CLK_CAN0_MIO] = {
2085 .name = "can0_mio",
2086 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2087 .status_reg = 0,
2088 .parents = &can_mio_parents,
2089 .nodes = &can0_mio_nodes,
2090 .num_nodes = ARRAY_SIZE(can0_mio_nodes),
2091 },
2092 [CLK_CAN1_MIO] = {
2093 .name = "can1_mio",
2094 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2095 .status_reg = 0,
2096 .parents = &can_mio_parents,
2097 .nodes = &can1_mio_nodes,
2098 .num_nodes = ARRAY_SIZE(can1_mio_nodes),
2099 },
2100 [CLK_CAN0] = {
2101 .name = "can0",
2102 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2103 .status_reg = 0,
2104 .parents = &((int32_t []) {
2105 CLK_CAN0_REF,
2106 CLK_CAN0_MIO,
2107 CLK_NA_PARENT
2108 }),
2109 .nodes = &can0_nodes,
2110 .num_nodes = ARRAY_SIZE(can0_nodes),
2111 },
2112 [CLK_CAN1] = {
2113 .name = "can1",
2114 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2115 .status_reg = 0,
2116 .parents = &((int32_t []) {
2117 CLK_CAN1_REF,
2118 CLK_CAN1_MIO,
2119 CLK_NA_PARENT
2120 }),
2121 .nodes = &can1_nodes,
2122 .num_nodes = ARRAY_SIZE(can1_nodes),
2123 },
2124};
2125
2126static struct pm_ext_clock ext_clocks[] = {
2127 [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
2128 .name = "pss_ref_clk",
2129 },
2130 [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
2131 .name = "video_clk",
2132 },
2133 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
2134 .name = "pss_alt_ref_clk",
2135 },
2136 [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
2137 .name = "aux_ref_clk",
2138 },
2139 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
2140 .name = "video_clk",
2141 },
2142 [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
2143 .name = "swdt0_ext_clk",
2144 },
2145 [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
2146 .name = "swdt1_ext_clk",
2147 },
2148 [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
2149 .name = "gem0_emio_clk",
2150 },
2151 [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
2152 .name = "gem1_emio_clk",
2153 },
2154 [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
2155 .name = "gem2_emio_clk",
2156 },
2157 [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
2158 .name = "gem3_emio_clk",
2159 },
2160 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
2161 .name = "mio_clk_50_51",
2162 },
2163 EXT_CLK_MIO_DATA(0),
2164 EXT_CLK_MIO_DATA(1),
2165 EXT_CLK_MIO_DATA(2),
2166 EXT_CLK_MIO_DATA(3),
2167 EXT_CLK_MIO_DATA(4),
2168 EXT_CLK_MIO_DATA(5),
2169 EXT_CLK_MIO_DATA(6),
2170 EXT_CLK_MIO_DATA(7),
2171 EXT_CLK_MIO_DATA(8),
2172 EXT_CLK_MIO_DATA(9),
2173 EXT_CLK_MIO_DATA(10),
2174 EXT_CLK_MIO_DATA(11),
2175 EXT_CLK_MIO_DATA(12),
2176 EXT_CLK_MIO_DATA(13),
2177 EXT_CLK_MIO_DATA(14),
2178 EXT_CLK_MIO_DATA(15),
2179 EXT_CLK_MIO_DATA(16),
2180 EXT_CLK_MIO_DATA(17),
2181 EXT_CLK_MIO_DATA(18),
2182 EXT_CLK_MIO_DATA(19),
2183 EXT_CLK_MIO_DATA(20),
2184 EXT_CLK_MIO_DATA(21),
2185 EXT_CLK_MIO_DATA(22),
2186 EXT_CLK_MIO_DATA(23),
2187 EXT_CLK_MIO_DATA(24),
2188 EXT_CLK_MIO_DATA(25),
2189 EXT_CLK_MIO_DATA(26),
2190 EXT_CLK_MIO_DATA(27),
2191 EXT_CLK_MIO_DATA(28),
2192 EXT_CLK_MIO_DATA(29),
2193 EXT_CLK_MIO_DATA(30),
2194 EXT_CLK_MIO_DATA(31),
2195 EXT_CLK_MIO_DATA(32),
2196 EXT_CLK_MIO_DATA(33),
2197 EXT_CLK_MIO_DATA(34),
2198 EXT_CLK_MIO_DATA(35),
2199 EXT_CLK_MIO_DATA(36),
2200 EXT_CLK_MIO_DATA(37),
2201 EXT_CLK_MIO_DATA(38),
2202 EXT_CLK_MIO_DATA(39),
2203 EXT_CLK_MIO_DATA(40),
2204 EXT_CLK_MIO_DATA(41),
2205 EXT_CLK_MIO_DATA(42),
2206 EXT_CLK_MIO_DATA(43),
2207 EXT_CLK_MIO_DATA(44),
2208 EXT_CLK_MIO_DATA(45),
2209 EXT_CLK_MIO_DATA(46),
2210 EXT_CLK_MIO_DATA(47),
2211 EXT_CLK_MIO_DATA(48),
2212 EXT_CLK_MIO_DATA(49),
2213 EXT_CLK_MIO_DATA(50),
2214 EXT_CLK_MIO_DATA(51),
2215 EXT_CLK_MIO_DATA(52),
2216 EXT_CLK_MIO_DATA(53),
2217 EXT_CLK_MIO_DATA(54),
2218 EXT_CLK_MIO_DATA(55),
2219 EXT_CLK_MIO_DATA(56),
2220 EXT_CLK_MIO_DATA(57),
2221 EXT_CLK_MIO_DATA(58),
2222 EXT_CLK_MIO_DATA(59),
2223 EXT_CLK_MIO_DATA(60),
2224 EXT_CLK_MIO_DATA(61),
2225 EXT_CLK_MIO_DATA(62),
2226 EXT_CLK_MIO_DATA(63),
2227 EXT_CLK_MIO_DATA(64),
2228 EXT_CLK_MIO_DATA(65),
2229 EXT_CLK_MIO_DATA(66),
2230 EXT_CLK_MIO_DATA(67),
2231 EXT_CLK_MIO_DATA(68),
2232 EXT_CLK_MIO_DATA(69),
2233 EXT_CLK_MIO_DATA(70),
2234 EXT_CLK_MIO_DATA(71),
2235 EXT_CLK_MIO_DATA(72),
2236 EXT_CLK_MIO_DATA(73),
2237 EXT_CLK_MIO_DATA(74),
2238 EXT_CLK_MIO_DATA(75),
2239 EXT_CLK_MIO_DATA(76),
2240 EXT_CLK_MIO_DATA(77),
2241};
2242
2243/* Array of clock which are invalid for this variant */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002244static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
Rajan Vajad98455b2018-01-17 02:39:26 -08002245
2246/* Array of clocks which needs to be enabled at init */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002247static uint32_t pm_clk_init_enable_list[] = {
Rajan Vajad98455b2018-01-17 02:39:26 -08002248 CLK_ACPU,
2249 CLK_DDR_REF,
2250};
2251
2252/**
2253 * pm_clock_valid - Check if clock is valid or not
2254 * @clock_id Id of the clock to be queried
2255 *
2256 * This function is used to check if given clock is valid
2257 * or not for the chip variant.
2258 *
2259 * List of invalid clocks are maintained in array list for
2260 * different variants.
2261 *
2262 * Return: Returns 1 if clock is valid else 0.
2263 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002264static bool pm_clock_valid(unsigned int clock_id)
Rajan Vajad98455b2018-01-17 02:39:26 -08002265{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002266 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002267
2268 for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
2269 if (pm_clk_invalid_list[i] == clock_id)
2270 return 0;
2271
2272 return 1;
2273}
2274
2275/**
2276 * pm_clock_init_enable - Check if clock needs to be enabled at init
2277 * @clock_id Id of the clock to be queried
2278 *
2279 * This function is used to check if given clock needs to be enabled
2280 * at boot up or not. Some clocks needs to be enabled at init.
2281 *
2282 * Return: Returns 1 if clock needs to be enabled at boot up else 0.
2283 */
2284static unsigned int pm_clock_init_enable(unsigned int clock_id)
2285{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002286 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002287
2288 for (i = 0; i < ARRAY_SIZE(pm_clk_init_enable_list); i++)
2289 if (pm_clk_init_enable_list[i] == clock_id)
2290 return 1;
2291
2292 return 0;
2293}
2294
2295/**
2296 * pm_clock_type - Get clock's type
2297 * @clock_id Id of the clock to be queried
2298 *
2299 * This function is used to check type of clock (OUTPUT/EXTERNAL).
2300 *
2301 * Return: Returns type of clock (OUTPUT/EXTERNAL).
2302 */
2303static unsigned int pm_clock_type(unsigned int clock_id)
2304{
2305 return (clock_id < CLK_MAX_OUTPUT_CLK) ?
2306 CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
2307}
Rajan Vaja35116132018-01-17 02:39:25 -08002308
2309/**
2310 * pm_api_clock_get_name() - PM call to request a clock's name
2311 * @clock_id Clock ID
2312 * @name Name of clock (max 16 bytes)
2313 *
2314 * This function is used by master to get nmae of clock specified
2315 * by given clock ID.
2316 *
2317 * @return Returns success. In case of error, name data is 0.
2318 */
2319enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
2320{
Rajan Vajad98455b2018-01-17 02:39:26 -08002321 if (clock_id == CLK_MAX)
2322 memcpy(name, END_OF_CLK, CLK_NAME_LEN);
2323 else if (!pm_clock_valid(clock_id))
2324 memset(name, 0, CLK_NAME_LEN);
2325 else if (clock_id < CLK_MAX_OUTPUT_CLK)
2326 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
2327 else
2328 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
2329 CLK_NAME_LEN);
2330
2331 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002332}
2333
2334/**
2335 * pm_api_clock_get_topology() - PM call to request a clock's topology
2336 * @clock_id Clock ID
2337 * @index Topology index for next toplogy node
2338 * @topology Buffer to store nodes in topology and flags
2339 *
2340 * This function is used by master to get topology information for the
2341 * clock specified by given clock ID. Each response would return 3
2342 * topology nodes. To get next nodes, caller needs to call this API with
2343 * index of next node. Index starts from 0.
2344 *
2345 * @return Returns status, either success or error+reason
2346 */
2347enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
2348 unsigned int index,
2349 uint32_t *topology)
2350{
Rajan Vajad98455b2018-01-17 02:39:26 -08002351 struct pm_clock_node *clock_nodes;
2352 uint8_t num_nodes;
2353 unsigned int i;
2354
2355 if (!pm_clock_valid(clock_id))
2356 return PM_RET_ERROR_ARGS;
2357
2358 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2359 return PM_RET_ERROR_NOTSUPPORTED;
2360
2361
2362 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
2363 clock_nodes = *clocks[clock_id].nodes;
2364 num_nodes = clocks[clock_id].num_nodes;
2365
2366 /* Skip parent till index */
2367 if (index >= num_nodes)
2368 return PM_RET_SUCCESS;
2369
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002370 for (i = 0; i < 3U; i++) {
Rajan Vajad98455b2018-01-17 02:39:26 -08002371 if ((index + i) == num_nodes)
2372 break;
2373 topology[i] = clock_nodes[index + i].type;
2374 topology[i] |= clock_nodes[index + i].clkflags <<
2375 CLK_CLKFLAGS_SHIFT;
2376 topology[i] |= clock_nodes[index + i].typeflags <<
2377 CLK_TYPEFLAGS_SHIFT;
2378 }
2379
2380 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002381}
2382
2383/**
2384 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
2385 * factor parameters for fixed clock
2386 * @clock_id Clock ID
2387 * @mul Multiplication value
2388 * @div Divisor value
2389 *
2390 * This function is used by master to get fixed factor parameers for the
2391 * fixed clock. This API is application only for the fixed clock.
2392 *
2393 * @return Returns status, either success or error+reason
2394 */
2395enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
2396 uint32_t *mul,
2397 uint32_t *div)
2398{
Rajan Vajad98455b2018-01-17 02:39:26 -08002399 struct pm_clock_node *clock_nodes;
2400 uint8_t num_nodes;
2401 unsigned int type, i;
2402
2403 if (!pm_clock_valid(clock_id))
2404 return PM_RET_ERROR_ARGS;
2405
2406 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2407 return PM_RET_ERROR_NOTSUPPORTED;
2408
2409 clock_nodes = *clocks[clock_id].nodes;
2410 num_nodes = clocks[clock_id].num_nodes;
2411
2412 for (i = 0; i < num_nodes; i++) {
2413 type = clock_nodes[i].type;
2414 if (type == TYPE_FIXEDFACTOR) {
2415 *mul = clock_nodes[i].mult;
2416 *div = clock_nodes[i].div;
2417 break;
2418 }
2419 }
2420
2421 /* Clock is not fixed clock */
2422 if (i == num_nodes)
2423 return PM_RET_ERROR_ARGS;
2424
2425 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002426}
2427
2428/**
2429 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
2430 * @clock_id Clock ID
2431 * @index Index of next parent
2432 * @parents Parents of the given clock
2433 *
2434 * This function is used by master to get clock's parents information.
2435 * This API will return 3 parents with a single response. To get other
2436 * parents, master should call same API in loop with new parent index
2437 * till error is returned.
2438 *
2439 * E.g First call should have index 0 which will return parents 0, 1 and
2440 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
2441 * so on.
2442 *
2443 * @return Returns status, either success or error+reason
2444 */
2445enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
2446 unsigned int index,
2447 uint32_t *parents)
2448{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002449 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002450 int32_t *clk_parents;
2451
2452 if (!pm_clock_valid(clock_id))
2453 return PM_RET_ERROR_ARGS;
2454
2455 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2456 return PM_RET_ERROR_NOTSUPPORTED;
2457
2458 clk_parents = *clocks[clock_id].parents;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002459 if (clk_parents == NULL)
Rajan Vajad98455b2018-01-17 02:39:26 -08002460 return PM_RET_ERROR_ARGS;
2461
2462 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
2463
2464 /* Skip parent till index */
2465 for (i = 0; i < index; i++)
2466 if (clk_parents[i] == CLK_NA_PARENT)
2467 return PM_RET_SUCCESS;
2468
2469 for (i = 0; i < 3; i++) {
2470 parents[i] = clk_parents[index + i];
2471 if (clk_parents[index + i] == CLK_NA_PARENT)
2472 break;
2473 }
2474
2475 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002476}
2477
2478/**
2479 * pm_api_clock_get_attributes() - PM call to request a clock's attributes
2480 * @clock_id Clock ID
2481 * @attr Clock attributes
2482 *
2483 * This function is used by master to get clock's attributes
2484 * (e.g. valid, clock type, etc).
2485 *
2486 * @return Returns status, either success or error+reason
2487 */
2488enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
2489 uint32_t *attr)
2490{
Rajan Vajad98455b2018-01-17 02:39:26 -08002491 if (clock_id >= CLK_MAX)
2492 return PM_RET_ERROR_ARGS;
2493
2494 /* Clock valid bit */
2495 *attr = pm_clock_valid(clock_id);
2496
2497 /* If clock needs to be enabled during init */
2498 *attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT);
2499
2500 /* Clock type (Output/External) */
2501 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
2502
2503 return PM_RET_SUCCESS;
2504}
2505
2506/**
2507 * pll_get_lockbit() - Returns lockbit index for pll id
2508 * @pll_id: Id of the pll
2509 *
2510 * This function return the PLL_LOCKED bit index in
2511 * pll status register accosiated with given pll id.
2512 *
2513 * Return: Returns bit index
2514 */
2515static int pll_get_lockbit(unsigned int pll_id)
2516{
2517 switch (pll_id) {
2518 case CLK_APLL_INT:
2519 case CLK_IOPLL_INT:
2520 return 0;
2521 case CLK_DPLL_INT:
2522 case CLK_RPLL_INT:
2523 return 1;
2524 case CLK_VPLL_INT:
2525 return 2;
2526 default:
2527 return -1;
2528 }
2529}
2530
2531/**
2532 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
2533 * @clock_id: Id of the PLL
2534 *
2535 * This function is to bypass and reset PLL.
2536 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002537static inline enum pm_ret_status
2538pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag)
Rajan Vajad98455b2018-01-17 02:39:26 -08002539{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002540 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002541 unsigned int reg, val;
2542 int lockbit;
2543
2544 reg = clocks[clock_id].control_reg;
2545
2546 if (flag & CLK_PLL_RESET_ASSERT) {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002547 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK);
2548 if (ret != PM_RET_SUCCESS)
2549 return ret;
2550 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2551 PLLCTRL_RESET_MASK);
2552 if (ret != PM_RET_SUCCESS)
2553 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002554 }
2555 if (flag & CLK_PLL_RESET_RELEASE) {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002556 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2557 ~PLLCTRL_RESET_MASK);
2558 if (ret != PM_RET_SUCCESS)
2559 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002560
2561 lockbit = pll_get_lockbit(clock_id);
2562 do {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002563 ret = pm_mmio_read(clocks[clock_id].status_reg, &val);
2564 if (ret != PM_RET_SUCCESS)
2565 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002566 } while ((lockbit >= 0) && !(val & (1 << lockbit)));
2567
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002568 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK,
Rajan Vajad98455b2018-01-17 02:39:26 -08002569 ~(unsigned int)PLLCTRL_BP_MASK);
2570 }
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002571 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002572}
2573
2574/**
2575 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
2576 * @clock_id: Id of the clock to be enabled
2577 * @enable: Enable(1)/Disable(0)
2578 *
2579 * This function is to enable/disable the clock which is not PLL.
2580 *
2581 * Return: Returns status, either success or error+reason.
2582 */
2583static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id,
2584 unsigned int enable)
2585{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002586 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002587 struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2588 uint8_t num_nodes = clocks[clock_id].num_nodes;
2589 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002590 uint8_t i = 0;
2591 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002592
2593 if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX ||
2594 clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX)
2595 reg = clocks[clock_id].status_reg;
2596 else
2597 reg = clocks[clock_id].control_reg;
2598
2599 for (i = 0; i < num_nodes; i++) {
2600 if (nodes->type == TYPE_GATE) {
2601 offset = nodes->offset;
2602 width = nodes->width;
2603 break;
2604 }
2605 nodes++;
2606 }
2607 if (width == NA_WIDTH)
2608 return PM_RET_ERROR_NOTSUPPORTED;
2609
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002610 ret = pm_mmio_read(reg, &val);
2611 if (ret != PM_RET_SUCCESS)
2612 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002613 if ((val & BIT_MASK(offset, width)) == enable)
2614 return PM_RET_SUCCESS;
2615
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002616 if (enable == 0)
Rajan Vajad98455b2018-01-17 02:39:26 -08002617 val &= ~(BIT_MASK(offset, width));
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002618 else
2619 val |= BIT_MASK(offset, width);
Rajan Vajad98455b2018-01-17 02:39:26 -08002620
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002621 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002622
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002623 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002624}
2625
2626/**
2627 * pm_api_clock_enable() - Enable the clock for given id
2628 * @clock_id: Id of the clock to be enabled
2629 *
2630 * This function is used by master to enable the clock
2631 * including peripherals and PLL clocks.
2632 *
2633 * Return: Returns status, either success or error+reason.
2634 */
2635enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
2636{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002637 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002638
2639 if (!pm_clock_valid(clock_id))
2640 return PM_RET_ERROR_ARGS;
2641
2642 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2643 return PM_RET_ERROR_NOTSUPPORTED;
2644
2645 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002646 ret = pm_api_pll_bypass_and_reset(clock_id,
2647 CLK_PLL_RESET_PULSE);
Rajan Vajad98455b2018-01-17 02:39:26 -08002648 else
2649 ret = pm_api_clk_enable_disable(clock_id, 1);
2650
2651 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002652}
2653
2654/**
2655 * pm_api_clock_disable - Disable the clock for given id
2656 * @clock_id Id of the clock to be disable
2657 *
2658 * This function is used by master to disable the clock
2659 * including peripherals and PLL clocks.
2660 *
2661 * Return: Returns status, either success or error+reason.
2662 */
2663
2664enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
2665{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002666 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002667
2668 if (!pm_clock_valid(clock_id))
2669 return PM_RET_ERROR_ARGS;
2670
2671 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2672 return PM_RET_ERROR_NOTSUPPORTED;
2673
2674 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002675 ret = pm_api_pll_bypass_and_reset(clock_id,
2676 CLK_PLL_RESET_ASSERT);
Rajan Vajad98455b2018-01-17 02:39:26 -08002677 else
2678 ret = pm_api_clk_enable_disable(clock_id, 0);
2679
2680 return ret;
2681}
2682
2683/**
2684 * pm_api_get_pll_state() - Get state of PLL
2685 * @clock_id Id of the PLL
2686 * @state State of PLL(1: Enable, 0: Reset)
2687 *
2688 * This function is to check state of PLL.
2689 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002690static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002691 unsigned int *state)
2692{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002693 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002694 unsigned int reg, val;
2695
2696 reg = clocks[clock_id].control_reg;
2697
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002698 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002699
2700 /* state:
2701 * 1 - PLL is enabled
2702 * 0 - PLL is in reset state
2703 */
2704 *state = !(val & PLLCTRL_RESET_MASK);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002705 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002706}
2707
2708/**
2709 * pm_api_get_clk_state() - Get the state of clock for given id
2710 * @clock_id: Id of the clock to be enabled
2711 * @state: Enable(1)/Disable(0)
2712 *
2713 * This function is to get state of the clock which is not PLL.
2714 *
2715 * Return: Returns status, either success or error+reason.
2716 */
2717static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
2718 unsigned int *state)
2719{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002720 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002721 struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2722 uint8_t num_nodes = clocks[clock_id].num_nodes;
2723 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002724 uint8_t i = 0;
2725 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002726
2727 reg = clocks[clock_id].control_reg;
2728
2729 for (i = 0; i < num_nodes; i++) {
2730 if (nodes->type == TYPE_GATE) {
2731 offset = nodes->offset;
2732 width = nodes->width;
2733 }
2734 nodes++;
2735 }
2736 if (width == NA_WIDTH)
2737 return PM_RET_ERROR_NOTSUPPORTED;
2738
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002739 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002740 *state = (val & BIT_MASK(offset, width)) >> offset;
2741
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002742 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002743}
2744
2745/**
2746 * pm_api_clock_getstate - Get the clock state for given id
2747 * @clock_id Id of the clock to be queried
2748 * @state 1/0 (Enabled/Disabled)
2749 *
2750 * This function is used by master to get the state of clock
2751 * including peripherals and PLL clocks.
2752 *
2753 * Return: Returns status, either success or error+reason.
2754 */
2755enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
2756 unsigned int *state)
2757{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002758 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002759
2760 if (!pm_clock_valid(clock_id))
2761 return PM_RET_ERROR_ARGS;
2762
2763 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2764 return PM_RET_ERROR_NOTSUPPORTED;
2765
2766 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002767 ret = pm_api_get_pll_state(clock_id, state);
Rajan Vajad98455b2018-01-17 02:39:26 -08002768 else
2769 ret = pm_api_get_clk_state(clock_id, state);
2770
2771 return ret;
2772}
2773
2774static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
2775 uint32_t divider)
2776{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002777 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002778 struct pm_clock_node *nodes;
2779 uint8_t num_nodes;
2780 uint16_t div1, div2;
2781 unsigned int reg, mask = 0, val = 0, i;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002782 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2783 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
Rajan Vajad98455b2018-01-17 02:39:26 -08002784
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002785 div1 = (uint16_t)(divider & 0xFFFFU);
2786 div2 = (uint16_t)((divider >> 16) & 0xFFFFU);
Rajan Vajad98455b2018-01-17 02:39:26 -08002787
2788 reg = clocks[clock_id].control_reg;
2789
2790 nodes = *clocks[clock_id].nodes;
2791 num_nodes = clocks[clock_id].num_nodes;
2792 for (i = 0; i < num_nodes; i++) {
2793 if (nodes->type == TYPE_DIV1) {
2794 div1_offset = nodes->offset;
2795 div1_width = nodes->width;
2796 }
2797 if (nodes->type == TYPE_DIV2) {
2798 div2_offset = nodes->offset;
2799 div2_width = nodes->width;
2800 }
2801 nodes++;
2802 }
2803
2804 if (div1 != (uint16_t)-1) {
2805 if (div1_width == NA_WIDTH)
2806 return PM_RET_ERROR_NOTSUPPORTED;
2807 val |= div1 << div1_offset;
2808 mask |= BIT_MASK(div1_offset, div1_width);
2809 }
2810 if (div2 != (uint16_t)-1) {
2811 if (div2_width == NA_WIDTH)
2812 return PM_RET_ERROR_NOTSUPPORTED;
2813 val |= div2 << div2_offset;
2814 mask |= BIT_MASK(div2_offset, div2_width);
2815 }
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002816 ret = pm_mmio_write(reg, mask, val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002817
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002818 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002819}
2820
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002821static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002822 unsigned int divider)
2823{
2824 unsigned int reg = clocks[clock_id].control_reg;
2825
2826 return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
Rajan Vaja35116132018-01-17 02:39:25 -08002827}
2828
2829/**
2830 * pm_api_clock_setdivider - Set the clock divider for given id
2831 * @clock_id Id of the clock
2832 * @divider Divider value
2833 *
2834 * This function is used by master to set divider for any clock
2835 * to achieve desired rate.
2836 *
2837 * Return: Returns status, either success or error+reason.
2838 */
2839enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
2840 unsigned int divider)
2841{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002842 enum pm_ret_status ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002843
2844 if (!pm_clock_valid(clock_id))
2845 return PM_RET_ERROR_ARGS;
2846
2847 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2848 return PM_RET_ERROR_NOTSUPPORTED;
2849
2850 if (ISPLL(clock_id))
2851 ret = pm_api_pll_set_divider(clock_id, divider);
2852 else
2853 ret = pm_api_clk_set_divider(clock_id, divider);
2854
2855 return ret;
2856}
2857
2858static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id,
2859 uint32_t *divider)
2860{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002861 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002862 struct pm_clock_node *nodes;
2863 uint8_t num_nodes;
2864 unsigned int reg, val, i, div1 = 0, div2 = 0;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002865 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2866 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
Rajan Vajad98455b2018-01-17 02:39:26 -08002867
2868 reg = clocks[clock_id].control_reg;
2869
2870 nodes = *clocks[clock_id].nodes;
2871 num_nodes = clocks[clock_id].num_nodes;
2872 for (i = 0; i < num_nodes; i++) {
2873 if (nodes->type == TYPE_DIV1) {
2874 div1_offset = nodes->offset;
2875 div1_width = nodes->width;
2876 }
2877 if (nodes->type == TYPE_DIV2) {
2878 div2_offset = nodes->offset;
2879 div2_width = nodes->width;
2880 }
2881 nodes++;
2882 }
2883
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002884 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002885
2886 if (div1_width == NA_WIDTH)
2887 return PM_RET_ERROR_ARGS;
2888
2889 div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset;
2890
2891 if (div2_width != NA_WIDTH)
2892 div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset;
2893
2894 *divider = div1 | (div2 << 16);
2895
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002896 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002897}
2898
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002899static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002900 unsigned int *divider)
2901{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002902 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002903 unsigned int reg, val;
2904
2905 reg = clocks[clock_id].control_reg;
2906
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002907 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002908 *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
2909
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002910 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002911}
2912
2913/**
2914 * pm_api_clock_getdivider - Get the clock divider for given id
2915 * @clock_id Id of the clock
2916 * @divider Divider value
2917 *
2918 * This function is used by master to get divider values
2919 * for any clock.
2920 *
2921 * Return: Returns status, either success or error+reason.
2922 */
2923enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
2924 unsigned int *divider)
2925{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002926 enum pm_ret_status ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002927
2928 if (!pm_clock_valid(clock_id))
2929 return PM_RET_ERROR_ARGS;
2930
2931 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2932 return PM_RET_ERROR_NOTSUPPORTED;
2933
2934 if (ISPLL(clock_id))
2935 ret = pm_api_pll_get_divider(clock_id, divider);
2936 else
2937 ret = pm_api_clk_get_divider(clock_id, divider);
2938
2939 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002940}
2941
2942/**
2943 * pm_api_clock_setrate - Set the clock rate for given id
2944 * @clock_id Id of the clock
2945 * @rate Rate value in hz
2946 *
2947 * This function is used by master to set rate for any clock.
2948 *
2949 * Return: Returns status, either success or error+reason.
2950 */
2951enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
2952 uint64_t rate)
2953{
2954 return PM_RET_ERROR_NOTSUPPORTED;
2955}
2956
2957/**
2958 * pm_api_clock_getrate - Get the clock rate for given id
2959 * @clock_id Id of the clock
2960 * @rate rate value in hz
2961 *
2962 * This function is used by master to get rate
2963 * for any clock.
2964 *
2965 * Return: Returns status, either success or error+reason.
2966 */
2967enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
2968 uint64_t *rate)
2969{
2970 return PM_RET_ERROR_NOTSUPPORTED;
2971}
2972
2973/**
2974 * pm_api_clock_setparent - Set the clock parent for given id
2975 * @clock_id Id of the clock
2976 * @parent_id parent id
2977 *
2978 * This function is used by master to set parent for any clock.
2979 *
2980 * Return: Returns status, either success or error+reason.
2981 */
2982enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
2983 unsigned int parent_idx)
2984{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002985 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002986 struct pm_clock_node *nodes;
2987 uint8_t num_nodes;
2988 unsigned int reg, val;
2989 int32_t *clk_parents;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002990 unsigned int i = 0;
2991 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002992
2993 if (!pm_clock_valid(clock_id))
2994 return PM_RET_ERROR_ARGS;
2995
2996 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2997 return PM_RET_ERROR_NOTSUPPORTED;
2998
2999 clk_parents = *clocks[clock_id].parents;
3000
3001 for (i = 0; i <= parent_idx; i++)
3002 if (clk_parents[i] == CLK_NA_PARENT)
3003 return PM_RET_ERROR_ARGS;
3004
3005 nodes = *clocks[clock_id].nodes;
3006 num_nodes = clocks[clock_id].num_nodes;
3007 for (i = 0; i < num_nodes; i++) {
3008 if (nodes->type == TYPE_MUX) {
3009 offset = nodes->offset;
3010 width = nodes->width;
3011 }
3012 nodes++;
3013 }
3014 if (width == NA_WIDTH)
3015 return PM_RET_ERROR_NOTSUPPORTED;
3016
3017 reg = clocks[clock_id].control_reg;
3018 val = parent_idx << offset;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003019 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003020
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003021 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003022}
3023
3024/**
3025 * pm_api_clock_getparent - Get the clock parent for given id
3026 * @clock_id Id of the clock
3027 * @parent_id parent id
3028 *
3029 * This function is used by master to get parent index
3030 * for any clock.
3031 *
3032 * Return: Returns status, either success or error+reason.
3033 */
3034enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
3035 unsigned int *parent_idx)
3036{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003037 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003038 struct pm_clock_node *nodes;
3039 uint8_t num_nodes;
3040 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003041 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08003042
3043 if (!pm_clock_valid(clock_id))
3044 return PM_RET_ERROR_ARGS;
3045
3046 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
3047 return PM_RET_ERROR_NOTSUPPORTED;
3048
3049 nodes = *clocks[clock_id].nodes;
3050 num_nodes = clocks[clock_id].num_nodes;
3051
3052 for (i = 0; i < num_nodes; i++) {
3053 if (nodes->type == TYPE_MUX) {
3054 offset = nodes->offset;
3055 width = nodes->width;
3056 }
3057 nodes++;
3058 }
3059 if (width == NA_WIDTH)
3060 return PM_RET_ERROR_NOTSUPPORTED;
3061
3062 reg = clocks[clock_id].control_reg;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003063 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003064 val >>= offset;
3065 val &= ((1U << width) - 1);
3066
3067 *parent_idx = val;
3068
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003069 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003070}
3071
3072/**
3073 * pm_api_clk_set_pll_mode() - Set PLL mode
3074 * @pll PLL id
3075 * @mode Mode fraction/integar
3076 *
3077 * This function sets PLL mode.
3078 *
3079 * @return Returns status, either success or error+reason
3080 */
3081enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
3082 unsigned int mode)
3083{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003084 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003085 unsigned int reg;
3086
3087 if (!pm_clock_valid(pll))
3088 return PM_RET_ERROR_ARGS;
3089
3090 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3091 return PM_RET_ERROR_NOTSUPPORTED;
3092
3093 if (!ISPLL(pll))
3094 return PM_RET_ERROR_NOTSUPPORTED;
3095
3096 if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)
3097 return PM_RET_ERROR_ARGS;
3098
3099 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3100
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003101 ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK,
3102 mode << PLL_FRAC_MODE_SHIFT);
Rajan Vajad98455b2018-01-17 02:39:26 -08003103
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003104 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003105}
3106
3107/**
3108 * pm_ioctl_get_pll_mode() - Get PLL mode
3109 * @pll PLL id
3110 * @mode Mode fraction/integar
3111 *
3112 * This function returns current PLL mode.
3113 *
3114 * @return Returns status, either success or error+reason
3115 */
3116enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
3117 unsigned int *mode)
3118{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003119 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003120 unsigned int val, reg;
3121
3122 if (!pm_clock_valid(pll))
3123 return PM_RET_ERROR_ARGS;
3124
3125 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3126 return PM_RET_ERROR_NOTSUPPORTED;
3127
3128 if (!ISPLL(pll))
3129 return PM_RET_ERROR_NOTSUPPORTED;
3130
3131 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3132
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003133 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003134 val = val & PLL_FRAC_MODE_MASK;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003135 if (val == 0)
Rajan Vajad98455b2018-01-17 02:39:26 -08003136 *mode = PLL_INT_MODE;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003137 else
3138 *mode = PLL_FRAC_MODE;
Rajan Vajad98455b2018-01-17 02:39:26 -08003139
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003140 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003141}
3142
3143/**
3144 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data
3145 * @pll PLL id
3146 * @data fraction data
3147 *
3148 * This function sets fraction data. It is valid for fraction
3149 * mode only.
3150 *
3151 * @return Returns status, either success or error+reason
3152 */
3153enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
3154 unsigned int data)
3155{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003156 enum pm_ret_status ret = PM_RET_SUCCESS;
3157 unsigned int val, reg, mode = 0;
Rajan Vajad98455b2018-01-17 02:39:26 -08003158
3159 if (!pm_clock_valid(pll))
3160 return PM_RET_ERROR_ARGS;
3161
3162 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3163 return PM_RET_ERROR_NOTSUPPORTED;
3164
3165 if (!ISPLL(pll))
3166 return PM_RET_ERROR_NOTSUPPORTED;
3167
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003168 ret = pm_api_clk_get_pll_mode(pll, &mode);
3169 if (ret != PM_RET_SUCCESS)
3170 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08003171 if (mode == PLL_FRAC_MODE) {
3172 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3173 val = data << PLL_FRAC_DATA_SHIFT;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003174 ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003175 } else {
3176 return PM_RET_ERROR_ARGS;
3177 }
3178
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003179 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003180}
3181
3182/**
3183 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
3184 * @pll PLL id
3185 * @data fraction data
3186 *
3187 * This function returns fraction data value.
3188 *
3189 * @return Returns status, either success or error+reason
3190 */
3191enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
3192 unsigned int *data)
3193{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003194 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003195 unsigned int val, reg;
3196
3197 if (!pm_clock_valid(pll))
3198 return PM_RET_ERROR_ARGS;
3199
3200 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3201 return PM_RET_ERROR_NOTSUPPORTED;
3202
3203 if (!ISPLL(pll))
3204 return PM_RET_ERROR_NOTSUPPORTED;
3205
3206 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3207
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003208 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003209 *data = (val & PLL_FRAC_DATA_MASK);
3210
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003211 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003212}