blob: fefd9ea8fea96b8b37101c0d425702d4610e1ce2 [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/**
Rajan Vajada959402018-07-20 03:16:27 -07002310 * pm_api_clock_get_num_clocks() - PM call to request number of clocks
2311 * @nclocks Number of clocks
2312 *
2313 * This function is used by master to get number of clocks.
2314 *
2315 * @return Returns success.
2316 */
2317enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
2318{
2319 *nclocks = CLK_MAX;
2320
2321 return PM_RET_SUCCESS;
2322}
2323
2324/**
Rajan Vaja35116132018-01-17 02:39:25 -08002325 * pm_api_clock_get_name() - PM call to request a clock's name
2326 * @clock_id Clock ID
2327 * @name Name of clock (max 16 bytes)
2328 *
2329 * This function is used by master to get nmae of clock specified
2330 * by given clock ID.
2331 *
2332 * @return Returns success. In case of error, name data is 0.
2333 */
2334enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
2335{
Rajan Vajad98455b2018-01-17 02:39:26 -08002336 if (clock_id == CLK_MAX)
2337 memcpy(name, END_OF_CLK, CLK_NAME_LEN);
2338 else if (!pm_clock_valid(clock_id))
2339 memset(name, 0, CLK_NAME_LEN);
2340 else if (clock_id < CLK_MAX_OUTPUT_CLK)
2341 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
2342 else
2343 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
2344 CLK_NAME_LEN);
2345
2346 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002347}
2348
2349/**
2350 * pm_api_clock_get_topology() - PM call to request a clock's topology
2351 * @clock_id Clock ID
2352 * @index Topology index for next toplogy node
2353 * @topology Buffer to store nodes in topology and flags
2354 *
2355 * This function is used by master to get topology information for the
2356 * clock specified by given clock ID. Each response would return 3
2357 * topology nodes. To get next nodes, caller needs to call this API with
2358 * index of next node. Index starts from 0.
2359 *
2360 * @return Returns status, either success or error+reason
2361 */
2362enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
2363 unsigned int index,
2364 uint32_t *topology)
2365{
Rajan Vajad98455b2018-01-17 02:39:26 -08002366 struct pm_clock_node *clock_nodes;
2367 uint8_t num_nodes;
2368 unsigned int i;
2369
2370 if (!pm_clock_valid(clock_id))
2371 return PM_RET_ERROR_ARGS;
2372
2373 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2374 return PM_RET_ERROR_NOTSUPPORTED;
2375
2376
2377 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
2378 clock_nodes = *clocks[clock_id].nodes;
2379 num_nodes = clocks[clock_id].num_nodes;
2380
2381 /* Skip parent till index */
2382 if (index >= num_nodes)
2383 return PM_RET_SUCCESS;
2384
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002385 for (i = 0; i < 3U; i++) {
Rajan Vajad98455b2018-01-17 02:39:26 -08002386 if ((index + i) == num_nodes)
2387 break;
2388 topology[i] = clock_nodes[index + i].type;
2389 topology[i] |= clock_nodes[index + i].clkflags <<
2390 CLK_CLKFLAGS_SHIFT;
2391 topology[i] |= clock_nodes[index + i].typeflags <<
2392 CLK_TYPEFLAGS_SHIFT;
2393 }
2394
2395 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002396}
2397
2398/**
2399 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
2400 * factor parameters for fixed clock
2401 * @clock_id Clock ID
2402 * @mul Multiplication value
2403 * @div Divisor value
2404 *
2405 * This function is used by master to get fixed factor parameers for the
2406 * fixed clock. This API is application only for the fixed clock.
2407 *
2408 * @return Returns status, either success or error+reason
2409 */
2410enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
2411 uint32_t *mul,
2412 uint32_t *div)
2413{
Rajan Vajad98455b2018-01-17 02:39:26 -08002414 struct pm_clock_node *clock_nodes;
2415 uint8_t num_nodes;
2416 unsigned int type, i;
2417
2418 if (!pm_clock_valid(clock_id))
2419 return PM_RET_ERROR_ARGS;
2420
2421 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2422 return PM_RET_ERROR_NOTSUPPORTED;
2423
2424 clock_nodes = *clocks[clock_id].nodes;
2425 num_nodes = clocks[clock_id].num_nodes;
2426
2427 for (i = 0; i < num_nodes; i++) {
2428 type = clock_nodes[i].type;
2429 if (type == TYPE_FIXEDFACTOR) {
2430 *mul = clock_nodes[i].mult;
2431 *div = clock_nodes[i].div;
2432 break;
2433 }
2434 }
2435
2436 /* Clock is not fixed clock */
2437 if (i == num_nodes)
2438 return PM_RET_ERROR_ARGS;
2439
2440 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002441}
2442
2443/**
2444 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
2445 * @clock_id Clock ID
2446 * @index Index of next parent
2447 * @parents Parents of the given clock
2448 *
2449 * This function is used by master to get clock's parents information.
2450 * This API will return 3 parents with a single response. To get other
2451 * parents, master should call same API in loop with new parent index
2452 * till error is returned.
2453 *
2454 * E.g First call should have index 0 which will return parents 0, 1 and
2455 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
2456 * so on.
2457 *
2458 * @return Returns status, either success or error+reason
2459 */
2460enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
2461 unsigned int index,
2462 uint32_t *parents)
2463{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002464 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002465 int32_t *clk_parents;
2466
2467 if (!pm_clock_valid(clock_id))
2468 return PM_RET_ERROR_ARGS;
2469
2470 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2471 return PM_RET_ERROR_NOTSUPPORTED;
2472
2473 clk_parents = *clocks[clock_id].parents;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002474 if (clk_parents == NULL)
Rajan Vajad98455b2018-01-17 02:39:26 -08002475 return PM_RET_ERROR_ARGS;
2476
2477 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
2478
2479 /* Skip parent till index */
2480 for (i = 0; i < index; i++)
2481 if (clk_parents[i] == CLK_NA_PARENT)
2482 return PM_RET_SUCCESS;
2483
2484 for (i = 0; i < 3; i++) {
2485 parents[i] = clk_parents[index + i];
2486 if (clk_parents[index + i] == CLK_NA_PARENT)
2487 break;
2488 }
2489
2490 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002491}
2492
2493/**
2494 * pm_api_clock_get_attributes() - PM call to request a clock's attributes
2495 * @clock_id Clock ID
2496 * @attr Clock attributes
2497 *
2498 * This function is used by master to get clock's attributes
2499 * (e.g. valid, clock type, etc).
2500 *
2501 * @return Returns status, either success or error+reason
2502 */
2503enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
2504 uint32_t *attr)
2505{
Rajan Vajad98455b2018-01-17 02:39:26 -08002506 if (clock_id >= CLK_MAX)
2507 return PM_RET_ERROR_ARGS;
2508
2509 /* Clock valid bit */
2510 *attr = pm_clock_valid(clock_id);
2511
2512 /* If clock needs to be enabled during init */
2513 *attr |= (pm_clock_init_enable(clock_id) << CLK_INIT_ENABLE_SHIFT);
2514
2515 /* Clock type (Output/External) */
2516 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
2517
2518 return PM_RET_SUCCESS;
2519}
2520
2521/**
2522 * pll_get_lockbit() - Returns lockbit index for pll id
2523 * @pll_id: Id of the pll
2524 *
2525 * This function return the PLL_LOCKED bit index in
2526 * pll status register accosiated with given pll id.
2527 *
2528 * Return: Returns bit index
2529 */
2530static int pll_get_lockbit(unsigned int pll_id)
2531{
2532 switch (pll_id) {
2533 case CLK_APLL_INT:
2534 case CLK_IOPLL_INT:
2535 return 0;
2536 case CLK_DPLL_INT:
2537 case CLK_RPLL_INT:
2538 return 1;
2539 case CLK_VPLL_INT:
2540 return 2;
2541 default:
2542 return -1;
2543 }
2544}
2545
2546/**
2547 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
2548 * @clock_id: Id of the PLL
2549 *
2550 * This function is to bypass and reset PLL.
2551 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002552static inline enum pm_ret_status
2553pm_api_pll_bypass_and_reset(unsigned int clock_id, unsigned int flag)
Rajan Vajad98455b2018-01-17 02:39:26 -08002554{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002555 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002556 unsigned int reg, val;
2557 int lockbit;
2558
2559 reg = clocks[clock_id].control_reg;
2560
2561 if (flag & CLK_PLL_RESET_ASSERT) {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002562 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK, PLLCTRL_BP_MASK);
2563 if (ret != PM_RET_SUCCESS)
2564 return ret;
2565 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2566 PLLCTRL_RESET_MASK);
2567 if (ret != PM_RET_SUCCESS)
2568 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002569 }
2570 if (flag & CLK_PLL_RESET_RELEASE) {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002571 ret = pm_mmio_write(reg, PLLCTRL_RESET_MASK,
2572 ~PLLCTRL_RESET_MASK);
2573 if (ret != PM_RET_SUCCESS)
2574 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002575
2576 lockbit = pll_get_lockbit(clock_id);
2577 do {
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002578 ret = pm_mmio_read(clocks[clock_id].status_reg, &val);
2579 if (ret != PM_RET_SUCCESS)
2580 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002581 } while ((lockbit >= 0) && !(val & (1 << lockbit)));
2582
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002583 ret = pm_mmio_write(reg, PLLCTRL_BP_MASK,
Rajan Vajad98455b2018-01-17 02:39:26 -08002584 ~(unsigned int)PLLCTRL_BP_MASK);
2585 }
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002586 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002587}
2588
2589/**
2590 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
2591 * @clock_id: Id of the clock to be enabled
2592 * @enable: Enable(1)/Disable(0)
2593 *
2594 * This function is to enable/disable the clock which is not PLL.
2595 *
2596 * Return: Returns status, either success or error+reason.
2597 */
2598static enum pm_ret_status pm_api_clk_enable_disable(unsigned int clock_id,
2599 unsigned int enable)
2600{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002601 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002602 struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2603 uint8_t num_nodes = clocks[clock_id].num_nodes;
2604 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002605 uint8_t i = 0;
2606 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002607
2608 if (clock_id == CLK_GEM0_TX || clock_id == CLK_GEM1_TX ||
2609 clock_id == CLK_GEM2_TX || clock_id == CLK_GEM3_TX)
2610 reg = clocks[clock_id].status_reg;
2611 else
2612 reg = clocks[clock_id].control_reg;
2613
2614 for (i = 0; i < num_nodes; i++) {
2615 if (nodes->type == TYPE_GATE) {
2616 offset = nodes->offset;
2617 width = nodes->width;
2618 break;
2619 }
2620 nodes++;
2621 }
2622 if (width == NA_WIDTH)
2623 return PM_RET_ERROR_NOTSUPPORTED;
2624
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002625 ret = pm_mmio_read(reg, &val);
2626 if (ret != PM_RET_SUCCESS)
2627 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002628 if ((val & BIT_MASK(offset, width)) == enable)
2629 return PM_RET_SUCCESS;
2630
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002631 if (enable == 0)
Rajan Vajad98455b2018-01-17 02:39:26 -08002632 val &= ~(BIT_MASK(offset, width));
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002633 else
2634 val |= BIT_MASK(offset, width);
Rajan Vajad98455b2018-01-17 02:39:26 -08002635
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002636 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002637
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002638 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002639}
2640
2641/**
2642 * pm_api_clock_enable() - Enable the clock for given id
2643 * @clock_id: Id of the clock to be enabled
2644 *
2645 * This function is used by master to enable the clock
2646 * including peripherals and PLL clocks.
2647 *
2648 * Return: Returns status, either success or error+reason.
2649 */
2650enum pm_ret_status pm_api_clock_enable(unsigned int clock_id)
2651{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002652 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002653
2654 if (!pm_clock_valid(clock_id))
2655 return PM_RET_ERROR_ARGS;
2656
2657 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2658 return PM_RET_ERROR_NOTSUPPORTED;
2659
2660 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002661 ret = pm_api_pll_bypass_and_reset(clock_id,
2662 CLK_PLL_RESET_PULSE);
Rajan Vajad98455b2018-01-17 02:39:26 -08002663 else
2664 ret = pm_api_clk_enable_disable(clock_id, 1);
2665
2666 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002667}
2668
2669/**
2670 * pm_api_clock_disable - Disable the clock for given id
2671 * @clock_id Id of the clock to be disable
2672 *
2673 * This function is used by master to disable the clock
2674 * including peripherals and PLL clocks.
2675 *
2676 * Return: Returns status, either success or error+reason.
2677 */
2678
2679enum pm_ret_status pm_api_clock_disable(unsigned int clock_id)
2680{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002681 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002682
2683 if (!pm_clock_valid(clock_id))
2684 return PM_RET_ERROR_ARGS;
2685
2686 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2687 return PM_RET_ERROR_NOTSUPPORTED;
2688
2689 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002690 ret = pm_api_pll_bypass_and_reset(clock_id,
2691 CLK_PLL_RESET_ASSERT);
Rajan Vajad98455b2018-01-17 02:39:26 -08002692 else
2693 ret = pm_api_clk_enable_disable(clock_id, 0);
2694
2695 return ret;
2696}
2697
2698/**
2699 * pm_api_get_pll_state() - Get state of PLL
2700 * @clock_id Id of the PLL
2701 * @state State of PLL(1: Enable, 0: Reset)
2702 *
2703 * This function is to check state of PLL.
2704 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002705static inline enum pm_ret_status pm_api_get_pll_state(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002706 unsigned int *state)
2707{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002708 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002709 unsigned int reg, val;
2710
2711 reg = clocks[clock_id].control_reg;
2712
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002713 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002714
2715 /* state:
2716 * 1 - PLL is enabled
2717 * 0 - PLL is in reset state
2718 */
2719 *state = !(val & PLLCTRL_RESET_MASK);
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002720 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002721}
2722
2723/**
2724 * pm_api_get_clk_state() - Get the state of clock for given id
2725 * @clock_id: Id of the clock to be enabled
2726 * @state: Enable(1)/Disable(0)
2727 *
2728 * This function is to get state of the clock which is not PLL.
2729 *
2730 * Return: Returns status, either success or error+reason.
2731 */
2732static enum pm_ret_status pm_api_get_clk_state(unsigned int clock_id,
2733 unsigned int *state)
2734{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002735 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002736 struct pm_clock_node *nodes = *clocks[clock_id].nodes;
2737 uint8_t num_nodes = clocks[clock_id].num_nodes;
2738 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002739 uint8_t i = 0;
2740 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002741
2742 reg = clocks[clock_id].control_reg;
2743
2744 for (i = 0; i < num_nodes; i++) {
2745 if (nodes->type == TYPE_GATE) {
2746 offset = nodes->offset;
2747 width = nodes->width;
2748 }
2749 nodes++;
2750 }
2751 if (width == NA_WIDTH)
2752 return PM_RET_ERROR_NOTSUPPORTED;
2753
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002754 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002755 *state = (val & BIT_MASK(offset, width)) >> offset;
2756
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002757 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002758}
2759
2760/**
2761 * pm_api_clock_getstate - Get the clock state for given id
2762 * @clock_id Id of the clock to be queried
2763 * @state 1/0 (Enabled/Disabled)
2764 *
2765 * This function is used by master to get the state of clock
2766 * including peripherals and PLL clocks.
2767 *
2768 * Return: Returns status, either success or error+reason.
2769 */
2770enum pm_ret_status pm_api_clock_getstate(unsigned int clock_id,
2771 unsigned int *state)
2772{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002773 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002774
2775 if (!pm_clock_valid(clock_id))
2776 return PM_RET_ERROR_ARGS;
2777
2778 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2779 return PM_RET_ERROR_NOTSUPPORTED;
2780
2781 if (ISPLL(clock_id))
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002782 ret = pm_api_get_pll_state(clock_id, state);
Rajan Vajad98455b2018-01-17 02:39:26 -08002783 else
2784 ret = pm_api_get_clk_state(clock_id, state);
2785
2786 return ret;
2787}
2788
2789static enum pm_ret_status pm_api_clk_set_divider(unsigned int clock_id,
2790 uint32_t divider)
2791{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002792 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002793 struct pm_clock_node *nodes;
2794 uint8_t num_nodes;
2795 uint16_t div1, div2;
2796 unsigned int reg, mask = 0, val = 0, i;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002797 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2798 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
Rajan Vajad98455b2018-01-17 02:39:26 -08002799
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002800 div1 = (uint16_t)(divider & 0xFFFFU);
2801 div2 = (uint16_t)((divider >> 16) & 0xFFFFU);
Rajan Vajad98455b2018-01-17 02:39:26 -08002802
2803 reg = clocks[clock_id].control_reg;
2804
2805 nodes = *clocks[clock_id].nodes;
2806 num_nodes = clocks[clock_id].num_nodes;
2807 for (i = 0; i < num_nodes; i++) {
2808 if (nodes->type == TYPE_DIV1) {
2809 div1_offset = nodes->offset;
2810 div1_width = nodes->width;
2811 }
2812 if (nodes->type == TYPE_DIV2) {
2813 div2_offset = nodes->offset;
2814 div2_width = nodes->width;
2815 }
2816 nodes++;
2817 }
2818
2819 if (div1 != (uint16_t)-1) {
2820 if (div1_width == NA_WIDTH)
2821 return PM_RET_ERROR_NOTSUPPORTED;
2822 val |= div1 << div1_offset;
2823 mask |= BIT_MASK(div1_offset, div1_width);
2824 }
2825 if (div2 != (uint16_t)-1) {
2826 if (div2_width == NA_WIDTH)
2827 return PM_RET_ERROR_NOTSUPPORTED;
2828 val |= div2 << div2_offset;
2829 mask |= BIT_MASK(div2_offset, div2_width);
2830 }
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002831 ret = pm_mmio_write(reg, mask, val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002832
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002833 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002834}
2835
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002836static enum pm_ret_status pm_api_pll_set_divider(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002837 unsigned int divider)
2838{
2839 unsigned int reg = clocks[clock_id].control_reg;
2840
2841 return pm_mmio_write(reg, PLL_FBDIV_MASK, divider << PLL_FBDIV_SHIFT);
Rajan Vaja35116132018-01-17 02:39:25 -08002842}
2843
2844/**
2845 * pm_api_clock_setdivider - Set the clock divider for given id
2846 * @clock_id Id of the clock
2847 * @divider Divider value
2848 *
2849 * This function is used by master to set divider for any clock
2850 * to achieve desired rate.
2851 *
2852 * Return: Returns status, either success or error+reason.
2853 */
2854enum pm_ret_status pm_api_clock_setdivider(unsigned int clock_id,
2855 unsigned int divider)
2856{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002857 enum pm_ret_status ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002858
2859 if (!pm_clock_valid(clock_id))
2860 return PM_RET_ERROR_ARGS;
2861
2862 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2863 return PM_RET_ERROR_NOTSUPPORTED;
2864
2865 if (ISPLL(clock_id))
2866 ret = pm_api_pll_set_divider(clock_id, divider);
2867 else
2868 ret = pm_api_clk_set_divider(clock_id, divider);
2869
2870 return ret;
2871}
2872
2873static enum pm_ret_status pm_api_clk_get_divider(unsigned int clock_id,
2874 uint32_t *divider)
2875{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002876 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002877 struct pm_clock_node *nodes;
2878 uint8_t num_nodes;
2879 unsigned int reg, val, i, div1 = 0, div2 = 0;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002880 uint8_t div1_width = NA_WIDTH, div1_offset = NA_SHIFT;
2881 uint8_t div2_width = NA_WIDTH, div2_offset = NA_SHIFT;
Rajan Vajad98455b2018-01-17 02:39:26 -08002882
2883 reg = clocks[clock_id].control_reg;
2884
2885 nodes = *clocks[clock_id].nodes;
2886 num_nodes = clocks[clock_id].num_nodes;
2887 for (i = 0; i < num_nodes; i++) {
2888 if (nodes->type == TYPE_DIV1) {
2889 div1_offset = nodes->offset;
2890 div1_width = nodes->width;
2891 }
2892 if (nodes->type == TYPE_DIV2) {
2893 div2_offset = nodes->offset;
2894 div2_width = nodes->width;
2895 }
2896 nodes++;
2897 }
2898
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002899 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002900
2901 if (div1_width == NA_WIDTH)
2902 return PM_RET_ERROR_ARGS;
2903
2904 div1 = (val & BIT_MASK(div1_offset, div1_width)) >> div1_offset;
2905
2906 if (div2_width != NA_WIDTH)
2907 div2 = (val & BIT_MASK(div2_offset, div2_width)) >> div2_offset;
2908
2909 *divider = div1 | (div2 << 16);
2910
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002911 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002912}
2913
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002914static enum pm_ret_status pm_api_pll_get_divider(unsigned int clock_id,
Rajan Vajad98455b2018-01-17 02:39:26 -08002915 unsigned int *divider)
2916{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002917 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002918 unsigned int reg, val;
2919
2920 reg = clocks[clock_id].control_reg;
2921
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002922 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002923 *divider = (val & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;
2924
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002925 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002926}
2927
2928/**
2929 * pm_api_clock_getdivider - Get the clock divider for given id
2930 * @clock_id Id of the clock
2931 * @divider Divider value
2932 *
2933 * This function is used by master to get divider values
2934 * for any clock.
2935 *
2936 * Return: Returns status, either success or error+reason.
2937 */
2938enum pm_ret_status pm_api_clock_getdivider(unsigned int clock_id,
2939 unsigned int *divider)
2940{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002941 enum pm_ret_status ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08002942
2943 if (!pm_clock_valid(clock_id))
2944 return PM_RET_ERROR_ARGS;
2945
2946 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2947 return PM_RET_ERROR_NOTSUPPORTED;
2948
2949 if (ISPLL(clock_id))
2950 ret = pm_api_pll_get_divider(clock_id, divider);
2951 else
2952 ret = pm_api_clk_get_divider(clock_id, divider);
2953
2954 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002955}
2956
2957/**
2958 * pm_api_clock_setrate - Set 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 set rate for any clock.
2963 *
2964 * Return: Returns status, either success or error+reason.
2965 */
2966enum pm_ret_status pm_api_clock_setrate(unsigned int clock_id,
2967 uint64_t rate)
2968{
2969 return PM_RET_ERROR_NOTSUPPORTED;
2970}
2971
2972/**
2973 * pm_api_clock_getrate - Get the clock rate for given id
2974 * @clock_id Id of the clock
2975 * @rate rate value in hz
2976 *
2977 * This function is used by master to get rate
2978 * for any clock.
2979 *
2980 * Return: Returns status, either success or error+reason.
2981 */
2982enum pm_ret_status pm_api_clock_getrate(unsigned int clock_id,
2983 uint64_t *rate)
2984{
2985 return PM_RET_ERROR_NOTSUPPORTED;
2986}
2987
2988/**
2989 * pm_api_clock_setparent - Set the clock parent for given id
2990 * @clock_id Id of the clock
2991 * @parent_id parent id
2992 *
2993 * This function is used by master to set parent for any clock.
2994 *
2995 * Return: Returns status, either success or error+reason.
2996 */
2997enum pm_ret_status pm_api_clock_setparent(unsigned int clock_id,
2998 unsigned int parent_idx)
2999{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003000 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003001 struct pm_clock_node *nodes;
3002 uint8_t num_nodes;
3003 unsigned int reg, val;
3004 int32_t *clk_parents;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003005 unsigned int i = 0;
3006 uint8_t offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08003007
3008 if (!pm_clock_valid(clock_id))
3009 return PM_RET_ERROR_ARGS;
3010
3011 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
3012 return PM_RET_ERROR_NOTSUPPORTED;
3013
3014 clk_parents = *clocks[clock_id].parents;
3015
3016 for (i = 0; i <= parent_idx; i++)
3017 if (clk_parents[i] == CLK_NA_PARENT)
3018 return PM_RET_ERROR_ARGS;
3019
3020 nodes = *clocks[clock_id].nodes;
3021 num_nodes = clocks[clock_id].num_nodes;
3022 for (i = 0; i < num_nodes; i++) {
3023 if (nodes->type == TYPE_MUX) {
3024 offset = nodes->offset;
3025 width = nodes->width;
3026 }
3027 nodes++;
3028 }
3029 if (width == NA_WIDTH)
3030 return PM_RET_ERROR_NOTSUPPORTED;
3031
3032 reg = clocks[clock_id].control_reg;
3033 val = parent_idx << offset;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003034 ret = pm_mmio_write(reg, BIT_MASK(offset, width), val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003035
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003036 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003037}
3038
3039/**
3040 * pm_api_clock_getparent - Get the clock parent for given id
3041 * @clock_id Id of the clock
3042 * @parent_id parent id
3043 *
3044 * This function is used by master to get parent index
3045 * for any clock.
3046 *
3047 * Return: Returns status, either success or error+reason.
3048 */
3049enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
3050 unsigned int *parent_idx)
3051{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003052 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003053 struct pm_clock_node *nodes;
3054 uint8_t num_nodes;
3055 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003056 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08003057
3058 if (!pm_clock_valid(clock_id))
3059 return PM_RET_ERROR_ARGS;
3060
3061 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
3062 return PM_RET_ERROR_NOTSUPPORTED;
3063
3064 nodes = *clocks[clock_id].nodes;
3065 num_nodes = clocks[clock_id].num_nodes;
3066
3067 for (i = 0; i < num_nodes; i++) {
3068 if (nodes->type == TYPE_MUX) {
3069 offset = nodes->offset;
3070 width = nodes->width;
3071 }
3072 nodes++;
3073 }
3074 if (width == NA_WIDTH)
3075 return PM_RET_ERROR_NOTSUPPORTED;
3076
3077 reg = clocks[clock_id].control_reg;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003078 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003079 val >>= offset;
3080 val &= ((1U << width) - 1);
3081
3082 *parent_idx = val;
3083
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003084 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003085}
3086
3087/**
3088 * pm_api_clk_set_pll_mode() - Set PLL mode
3089 * @pll PLL id
3090 * @mode Mode fraction/integar
3091 *
3092 * This function sets PLL mode.
3093 *
3094 * @return Returns status, either success or error+reason
3095 */
3096enum pm_ret_status pm_api_clk_set_pll_mode(unsigned int pll,
3097 unsigned int mode)
3098{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003099 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003100 unsigned int reg;
3101
3102 if (!pm_clock_valid(pll))
3103 return PM_RET_ERROR_ARGS;
3104
3105 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3106 return PM_RET_ERROR_NOTSUPPORTED;
3107
3108 if (!ISPLL(pll))
3109 return PM_RET_ERROR_NOTSUPPORTED;
3110
3111 if (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE)
3112 return PM_RET_ERROR_ARGS;
3113
3114 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3115
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003116 ret = pm_mmio_write(reg, PLL_FRAC_MODE_MASK,
3117 mode << PLL_FRAC_MODE_SHIFT);
Rajan Vajad98455b2018-01-17 02:39:26 -08003118
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003119 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003120}
3121
3122/**
3123 * pm_ioctl_get_pll_mode() - Get PLL mode
3124 * @pll PLL id
3125 * @mode Mode fraction/integar
3126 *
3127 * This function returns current PLL mode.
3128 *
3129 * @return Returns status, either success or error+reason
3130 */
3131enum pm_ret_status pm_api_clk_get_pll_mode(unsigned int pll,
3132 unsigned int *mode)
3133{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003134 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003135 unsigned int val, reg;
3136
3137 if (!pm_clock_valid(pll))
3138 return PM_RET_ERROR_ARGS;
3139
3140 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3141 return PM_RET_ERROR_NOTSUPPORTED;
3142
3143 if (!ISPLL(pll))
3144 return PM_RET_ERROR_NOTSUPPORTED;
3145
3146 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3147
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003148 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003149 val = val & PLL_FRAC_MODE_MASK;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003150 if (val == 0)
Rajan Vajad98455b2018-01-17 02:39:26 -08003151 *mode = PLL_INT_MODE;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003152 else
3153 *mode = PLL_FRAC_MODE;
Rajan Vajad98455b2018-01-17 02:39:26 -08003154
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003155 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003156}
3157
3158/**
3159 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data
3160 * @pll PLL id
3161 * @data fraction data
3162 *
3163 * This function sets fraction data. It is valid for fraction
3164 * mode only.
3165 *
3166 * @return Returns status, either success or error+reason
3167 */
3168enum pm_ret_status pm_api_clk_set_pll_frac_data(unsigned int pll,
3169 unsigned int data)
3170{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003171 enum pm_ret_status ret = PM_RET_SUCCESS;
3172 unsigned int val, reg, mode = 0;
Rajan Vajad98455b2018-01-17 02:39:26 -08003173
3174 if (!pm_clock_valid(pll))
3175 return PM_RET_ERROR_ARGS;
3176
3177 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3178 return PM_RET_ERROR_NOTSUPPORTED;
3179
3180 if (!ISPLL(pll))
3181 return PM_RET_ERROR_NOTSUPPORTED;
3182
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003183 ret = pm_api_clk_get_pll_mode(pll, &mode);
3184 if (ret != PM_RET_SUCCESS)
3185 return ret;
Rajan Vajad98455b2018-01-17 02:39:26 -08003186 if (mode == PLL_FRAC_MODE) {
3187 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3188 val = data << PLL_FRAC_DATA_SHIFT;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003189 ret = pm_mmio_write(reg, PLL_FRAC_DATA_MASK, val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003190 } else {
3191 return PM_RET_ERROR_ARGS;
3192 }
3193
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003194 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003195}
3196
3197/**
3198 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
3199 * @pll PLL id
3200 * @data fraction data
3201 *
3202 * This function returns fraction data value.
3203 *
3204 * @return Returns status, either success or error+reason
3205 */
3206enum pm_ret_status pm_api_clk_get_pll_frac_data(unsigned int pll,
3207 unsigned int *data)
3208{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003209 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08003210 unsigned int val, reg;
3211
3212 if (!pm_clock_valid(pll))
3213 return PM_RET_ERROR_ARGS;
3214
3215 if (pm_clock_type(pll) != CLK_TYPE_OUTPUT)
3216 return PM_RET_ERROR_NOTSUPPORTED;
3217
3218 if (!ISPLL(pll))
3219 return PM_RET_ERROR_NOTSUPPORTED;
3220
3221 reg = clocks[pll].control_reg + PLL_FRAC_OFFSET;
3222
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003223 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08003224 *data = (val & PLL_FRAC_DATA_MASK);
3225
Jolly Shah69fb5bf2018-02-07 16:25:41 -08003226 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08003227}