blob: ca2f452b2228bd192d1f5d4ee52e11119f9abeb2 [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)
Jolly Shah69fb5bf2018-02-07 16:25:41 -080028#define CLK_TYPE_SHIFT U(2)
29#define CLK_CLKFLAGS_SHIFT U(8)
30#define CLK_TYPEFLAGS_SHIFT U(24)
Rajan Vajad98455b2018-01-17 02:39:26 -080031
32#define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
33
Jolly Shah69fb5bf2018-02-07 16:25:41 -080034#define NA_MULT U(0)
35#define NA_DIV U(0)
36#define NA_SHIFT U(0)
37#define NA_WIDTH U(0)
38#define NA_CLK_FLAGS U(0)
39#define NA_TYPE_FLAGS U(0)
Rajan Vajad98455b2018-01-17 02:39:26 -080040
41/* PLL nodes related definitions */
Jolly Shah69fb5bf2018-02-07 16:25:41 -080042#define PLL_PRESRC_MUX_SHIFT U(20)
43#define PLL_PRESRC_MUX_WIDTH U(3)
44#define PLL_POSTSRC_MUX_SHIFT U(24)
45#define PLL_POSTSRC_MUX_WIDTH U(3)
46#define PLL_DIV2_MUX_SHIFT U(16)
47#define PLL_DIV2_MUX_WIDTH U(1)
48#define PLL_BYPASS_MUX_SHIFT U(3)
49#define PLL_BYPASS_MUX_WIDTH U(1)
Rajan Vajad98455b2018-01-17 02:39:26 -080050
51/* Peripheral nodes related definitions */
52/* Peripheral Clocks */
Jolly Shah69fb5bf2018-02-07 16:25:41 -080053#define PERIPH_MUX_SHIFT U(0)
54#define PERIPH_MUX_WIDTH U(3)
55#define PERIPH_DIV1_SHIFT U(8)
56#define PERIPH_DIV1_WIDTH U(6)
57#define PERIPH_DIV2_SHIFT U(16)
58#define PERIPH_DIV2_WIDTH U(6)
59#define PERIPH_GATE_SHIFT U(24)
60#define PERIPH_GATE_WIDTH U(1)
Rajan Vajad98455b2018-01-17 02:39:26 -080061
Jolly Shah69fb5bf2018-02-07 16:25:41 -080062#define USB_GATE_SHIFT U(25)
Rajan Vajad98455b2018-01-17 02:39:26 -080063
64/* External clock related definitions */
65
66#define EXT_CLK_MIO_DATA(mio) \
67 [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \
68 .name = "mio_clk_"#mio, \
69 }
70
71#define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK)
72
73/* Clock control related definitions */
74#define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
75
Jolly Shah69fb5bf2018-02-07 16:25:41 -080076#define ISPLL(id) (id == CLK_APLL_INT || \
77 id == CLK_DPLL_INT || \
78 id == CLK_VPLL_INT || \
79 id == CLK_IOPLL_INT || \
80 id == CLK_RPLL_INT)
81
Rajan Vajad98455b2018-01-17 02:39:26 -080082
83#define PLLCTRL_BP_MASK BIT(3)
Jolly Shah69fb5bf2018-02-07 16:25:41 -080084#define PLLCTRL_RESET_MASK U(1)
85#define PLL_FRAC_OFFSET U(8)
86#define PLL_FRAC_MODE U(1)
87#define PLL_INT_MODE U(0)
88#define PLL_FRAC_MODE_MASK U(0x80000000)
89#define PLL_FRAC_MODE_SHIFT U(31)
90#define PLL_FRAC_DATA_MASK U(0xFFFF)
91#define PLL_FRAC_DATA_SHIFT U(0)
92#define PLL_FBDIV_MASK U(0x7F00)
93#define PLL_FBDIV_WIDTH U(7)
94#define PLL_FBDIV_SHIFT U(8)
Rajan Vajad98455b2018-01-17 02:39:26 -080095
Jolly Shah69fb5bf2018-02-07 16:25:41 -080096#define CLK_PLL_RESET_ASSERT U(1)
97#define CLK_PLL_RESET_RELEASE U(2)
Rajan Vajad98455b2018-01-17 02:39:26 -080098#define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
99
100/* Common topology definitions */
101#define GENERIC_MUX \
102 { \
103 .type = TYPE_MUX, \
104 .offset = PERIPH_MUX_SHIFT, \
105 .width = PERIPH_MUX_WIDTH, \
106 .clkflags = CLK_SET_RATE_NO_REPARENT | \
107 CLK_IS_BASIC, \
108 .typeflags = NA_TYPE_FLAGS, \
109 .mult = NA_MULT, \
110 .div = NA_DIV, \
111 }
112
113#define IGNORE_UNUSED_MUX \
114 { \
115 .type = TYPE_MUX, \
116 .offset = PERIPH_MUX_SHIFT, \
117 .width = PERIPH_MUX_WIDTH, \
118 .clkflags = CLK_IGNORE_UNUSED | \
119 CLK_SET_RATE_NO_REPARENT | \
120 CLK_IS_BASIC, \
121 .typeflags = NA_TYPE_FLAGS, \
122 .mult = NA_MULT, \
123 .div = NA_DIV, \
124 }
125
126#define GENERIC_DIV(id) \
127 { \
128 .type = TYPE_DIV##id, \
129 .offset = PERIPH_DIV##id##_SHIFT, \
130 .width = PERIPH_DIV##id##_WIDTH, \
131 .clkflags = CLK_SET_RATE_NO_REPARENT | \
132 CLK_IS_BASIC, \
133 .typeflags = CLK_DIVIDER_ONE_BASED | \
134 CLK_DIVIDER_ALLOW_ZERO, \
135 .mult = NA_MULT, \
136 .div = NA_DIV, \
137 }
138
139#define IGNORE_UNUSED_DIV(id) \
140 { \
141 .type = TYPE_DIV##id, \
142 .offset = PERIPH_DIV##id##_SHIFT, \
143 .width = PERIPH_DIV##id##_WIDTH, \
144 .clkflags = CLK_IGNORE_UNUSED | \
145 CLK_SET_RATE_NO_REPARENT | \
146 CLK_IS_BASIC, \
147 .typeflags = CLK_DIVIDER_ONE_BASED | \
148 CLK_DIVIDER_ALLOW_ZERO, \
149 .mult = NA_MULT, \
150 .div = NA_DIV, \
151 }
152
153#define GENERIC_GATE \
154 { \
155 .type = TYPE_GATE, \
156 .offset = PERIPH_GATE_SHIFT, \
157 .width = PERIPH_GATE_WIDTH, \
158 .clkflags = CLK_SET_RATE_PARENT | \
159 CLK_SET_RATE_GATE | \
160 CLK_IS_BASIC, \
161 .typeflags = NA_TYPE_FLAGS, \
162 .mult = NA_MULT, \
163 .div = NA_DIV, \
164 }
165
166#define IGNORE_UNUSED_GATE \
167 { \
168 .type = TYPE_GATE, \
169 .offset = PERIPH_GATE_SHIFT, \
170 .width = PERIPH_GATE_WIDTH, \
171 .clkflags = CLK_SET_RATE_PARENT | \
172 CLK_IGNORE_UNUSED | \
173 CLK_IS_BASIC, \
174 .typeflags = NA_TYPE_FLAGS, \
175 .mult = NA_MULT, \
176 .div = NA_DIV, \
177 }
178
Rajan Vaja35116132018-01-17 02:39:25 -0800179/**
180 * struct pm_clock_node - Clock topology node information
181 * @type: Topology type (mux/div1/div2/gate/pll/fixed factor)
182 * @offset: Offset in control register
183 * @width: Width of the specific type in control register
184 * @clkflags: Clk specific flags
185 * @typeflags: Type specific flags
186 * @mult: Multiplier for fixed factor
187 * @div: Divisor for fixed factor
188 */
189struct pm_clock_node {
190 uint16_t clkflags;
191 uint16_t typeflags;
192 uint8_t type;
193 uint8_t offset;
194 uint8_t width;
195 uint8_t mult:4;
196 uint8_t div:4;
197};
198
199/**
200 * struct pm_clock - Clock structure
201 * @name: Clock name
202 * @control_reg: Control register address
203 * @status_reg: Status register address
204 * @parents: Parents for first clock node. Lower byte indicates parent
205 * clock id and upper byte indicate flags for that id.
206 * pm_clock_node: Clock nodes
207 */
208struct pm_clock {
209 char name[CLK_NAME_LEN];
210 uint8_t num_nodes;
211 unsigned int control_reg;
212 unsigned int status_reg;
213 int32_t (*parents)[];
214 struct pm_clock_node(*nodes)[];
215};
216
Rajan Vajad98455b2018-01-17 02:39:26 -0800217/**
218 * struct pm_clock - Clock structure
219 * @name: Clock name
220 */
221struct pm_ext_clock {
222 char name[CLK_NAME_LEN];
223};
224
225/* PLL Clocks */
226static struct pm_clock_node generic_pll_nodes[] = {
227 {
228 .type = TYPE_PLL,
229 .offset = NA_SHIFT,
230 .width = NA_WIDTH,
231 .clkflags = CLK_SET_RATE_NO_REPARENT,
232 .typeflags = NA_TYPE_FLAGS,
233 .mult = NA_MULT,
234 .div = NA_DIV,
235 },
236};
237
238static struct pm_clock_node ignore_unused_pll_nodes[] = {
239 {
240 .type = TYPE_PLL,
241 .offset = NA_SHIFT,
242 .width = NA_WIDTH,
243 .clkflags = CLK_IGNORE_UNUSED | CLK_SET_RATE_NO_REPARENT,
244 .typeflags = NA_TYPE_FLAGS,
245 .mult = NA_MULT,
246 .div = NA_DIV,
247 },
248};
249
250static struct pm_clock_node generic_pll_pre_src_nodes[] = {
251 {
252 .type = TYPE_MUX,
253 .offset = PLL_PRESRC_MUX_SHIFT,
254 .width = PLL_PRESRC_MUX_WIDTH,
255 .clkflags = CLK_IS_BASIC,
256 .typeflags = NA_TYPE_FLAGS,
257 .mult = NA_MULT,
258 .div = NA_DIV,
259 },
260};
261
262static struct pm_clock_node generic_pll_half_nodes[] = {
263 {
264 .type = TYPE_FIXEDFACTOR,
265 .offset = NA_SHIFT,
266 .width = NA_WIDTH,
267 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT,
268 .typeflags = NA_TYPE_FLAGS,
269 .mult = 1,
270 .div = 2,
271 },
272};
273
274static struct pm_clock_node generic_pll_int_nodes[] = {
275 {
276 .type = TYPE_MUX,
277 .offset = PLL_DIV2_MUX_SHIFT,
278 .width = PLL_DIV2_MUX_WIDTH,
279 .clkflags = CLK_SET_RATE_NO_REPARENT |
280 CLK_SET_RATE_PARENT |
281 CLK_IS_BASIC,
282 .typeflags = NA_TYPE_FLAGS,
283 .mult = NA_MULT,
284 .div = NA_DIV,
285 },
286};
287
288static struct pm_clock_node generic_pll_post_src_nodes[] = {
289 {
290 .type = TYPE_MUX,
291 .offset = PLL_POSTSRC_MUX_SHIFT,
292 .width = PLL_POSTSRC_MUX_WIDTH,
293 .clkflags = CLK_IS_BASIC,
294 .typeflags = NA_TYPE_FLAGS,
295 .mult = NA_MULT,
296 .div = NA_DIV,
297 },
298};
299
300static struct pm_clock_node generic_pll_system_nodes[] = {
301 {
302 .type = TYPE_MUX,
303 .offset = PLL_BYPASS_MUX_SHIFT,
304 .width = PLL_BYPASS_MUX_WIDTH,
305 .clkflags = CLK_SET_RATE_NO_REPARENT |
306 CLK_SET_RATE_PARENT |
307 CLK_IS_BASIC,
308 .typeflags = NA_TYPE_FLAGS,
309 .mult = NA_MULT,
310 .div = NA_DIV,
311 },
312};
313
314static struct pm_clock_node acpu_nodes[] = {
315 {
316 .type = TYPE_MUX,
317 .offset = PERIPH_MUX_SHIFT,
318 .width = PERIPH_MUX_WIDTH,
319 .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC,
320 .typeflags = NA_TYPE_FLAGS,
321 .mult = NA_MULT,
322 .div = NA_DIV,
323 },
324 {
325 .type = TYPE_DIV1,
326 .offset = PERIPH_DIV1_SHIFT,
327 .width = PERIPH_DIV1_WIDTH,
328 .clkflags = CLK_IS_BASIC,
329 .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO,
330 .mult = NA_MULT,
331 .div = NA_DIV,
332 },
333 {
334 .type = TYPE_GATE,
335 .offset = PERIPH_GATE_SHIFT,
336 .width = PERIPH_GATE_WIDTH,
337 .clkflags = CLK_SET_RATE_PARENT |
338 CLK_IGNORE_UNUSED |
Siva Durga Prasad Paladugue2aa8272018-09-04 17:37:27 +0530339 CLK_IS_BASIC |
340 CLK_IS_CRITICAL,
Rajan Vajad98455b2018-01-17 02:39:26 -0800341 .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,
Siva Durga Prasad Paladugue2aa8272018-09-04 17:37:27 +0530499 .clkflags = CLK_IS_BASIC | CLK_IS_CRITICAL,
Rajan Vajad98455b2018-01-17 02:39:26 -0800500 .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",
Siva Durga Prasad Paladugu90539cd2018-09-04 17:33:19 +05302025 .control_reg = FPD_SLCR_WDT_CLK_SEL,
Rajan Vajad98455b2018-01-17 02:39:26 -08002026 .status_reg = 0,
2027 .parents = &((int32_t []) {
2028 CLK_TOPSW_LSBUS,
2029 EXT_CLK_SWDT0 | CLK_EXTERNAL_PARENT,
Rajan Vajad98455b2018-01-17 02:39:26 -08002030 CLK_NA_PARENT
2031 }),
2032 .nodes = &wdt_nodes,
2033 .num_nodes = ARRAY_SIZE(wdt_nodes),
2034 },
2035 [CLK_GPU_PP0_REF] = {
2036 .name = "gpu_pp0_ref",
2037 .control_reg = CRF_APB_GPU_REF_CTRL,
2038 .status_reg = 0,
2039 .parents = &((int32_t []) {
2040 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2041 CLK_NA_PARENT
2042 }),
2043 .nodes = &gpu_pp0_nodes,
2044 .num_nodes = ARRAY_SIZE(gpu_pp0_nodes),
2045 },
2046 [CLK_GPU_PP1_REF] = {
2047 .name = "gpu_pp1_ref",
2048 .control_reg = CRF_APB_GPU_REF_CTRL,
2049 .status_reg = 0,
2050 .parents = &((int32_t []) {
2051 CLK_GPU_REF | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2052 CLK_NA_PARENT
2053 }),
2054 .nodes = &gpu_pp1_nodes,
2055 .num_nodes = ARRAY_SIZE(gpu_pp1_nodes),
2056 },
2057 [CLK_GEM_TSU] = {
2058 .name = "gem_tsu",
2059 .control_reg = IOU_SLCR_GEM_CLK_CTRL,
2060 .status_reg = 0,
2061 .parents = &((int32_t []) {
2062 CLK_GEM_TSU_REF,
2063 CLK_GEM_TSU_REF,
2064 EXT_CLK_MIO26 | CLK_EXTERNAL_PARENT,
2065 EXT_CLK_MIO50_OR_MIO51 | CLK_EXTERNAL_PARENT,
2066 CLK_NA_PARENT
2067 }),
2068 .nodes = &gem_tsu_nodes,
2069 .num_nodes = ARRAY_SIZE(gem_tsu_nodes),
2070 },
2071 [CLK_CPU_R5_CORE] = {
2072 .name = "cpu_r5_core",
2073 .control_reg = CRL_APB_CPU_R5_CTRL,
2074 .status_reg = 0,
2075 .parents = &((int32_t []) {
2076 CLK_CPU_R5 | PARENT_CLK_NODE2 << CLK_PARENTS_ID_LEN,
2077 CLK_DUMMY_PARENT,
2078 CLK_NA_PARENT
2079 }),
2080 .nodes = &cpu_r5_core_nodes,
2081 .num_nodes = ARRAY_SIZE(cpu_r5_core_nodes),
2082 },
2083 [CLK_CAN0_MIO] = {
2084 .name = "can0_mio",
2085 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2086 .status_reg = 0,
2087 .parents = &can_mio_parents,
2088 .nodes = &can0_mio_nodes,
2089 .num_nodes = ARRAY_SIZE(can0_mio_nodes),
2090 },
2091 [CLK_CAN1_MIO] = {
2092 .name = "can1_mio",
2093 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2094 .status_reg = 0,
2095 .parents = &can_mio_parents,
2096 .nodes = &can1_mio_nodes,
2097 .num_nodes = ARRAY_SIZE(can1_mio_nodes),
2098 },
2099 [CLK_CAN0] = {
2100 .name = "can0",
2101 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2102 .status_reg = 0,
2103 .parents = &((int32_t []) {
2104 CLK_CAN0_REF,
2105 CLK_CAN0_MIO,
2106 CLK_NA_PARENT
2107 }),
2108 .nodes = &can0_nodes,
2109 .num_nodes = ARRAY_SIZE(can0_nodes),
2110 },
2111 [CLK_CAN1] = {
2112 .name = "can1",
2113 .control_reg = IOU_SLCR_CAN_MIO_CTRL,
2114 .status_reg = 0,
2115 .parents = &((int32_t []) {
2116 CLK_CAN1_REF,
2117 CLK_CAN1_MIO,
2118 CLK_NA_PARENT
2119 }),
2120 .nodes = &can1_nodes,
2121 .num_nodes = ARRAY_SIZE(can1_nodes),
2122 },
2123};
2124
2125static struct pm_ext_clock ext_clocks[] = {
2126 [EXT_CLK_INDEX(EXT_CLK_PSS_REF)] = {
2127 .name = "pss_ref_clk",
2128 },
2129 [EXT_CLK_INDEX(EXT_CLK_VIDEO)] = {
2130 .name = "video_clk",
2131 },
2132 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF)] = {
2133 .name = "pss_alt_ref_clk",
2134 },
2135 [EXT_CLK_INDEX(EXT_CLK_AUX_REF)] = {
2136 .name = "aux_ref_clk",
2137 },
2138 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF)] = {
2139 .name = "video_clk",
2140 },
2141 [EXT_CLK_INDEX(EXT_CLK_SWDT0)] = {
2142 .name = "swdt0_ext_clk",
2143 },
2144 [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = {
2145 .name = "swdt1_ext_clk",
2146 },
2147 [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = {
2148 .name = "gem0_emio_clk",
2149 },
2150 [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = {
2151 .name = "gem1_emio_clk",
2152 },
2153 [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = {
2154 .name = "gem2_emio_clk",
2155 },
2156 [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = {
2157 .name = "gem3_emio_clk",
2158 },
2159 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = {
2160 .name = "mio_clk_50_51",
2161 },
2162 EXT_CLK_MIO_DATA(0),
2163 EXT_CLK_MIO_DATA(1),
2164 EXT_CLK_MIO_DATA(2),
2165 EXT_CLK_MIO_DATA(3),
2166 EXT_CLK_MIO_DATA(4),
2167 EXT_CLK_MIO_DATA(5),
2168 EXT_CLK_MIO_DATA(6),
2169 EXT_CLK_MIO_DATA(7),
2170 EXT_CLK_MIO_DATA(8),
2171 EXT_CLK_MIO_DATA(9),
2172 EXT_CLK_MIO_DATA(10),
2173 EXT_CLK_MIO_DATA(11),
2174 EXT_CLK_MIO_DATA(12),
2175 EXT_CLK_MIO_DATA(13),
2176 EXT_CLK_MIO_DATA(14),
2177 EXT_CLK_MIO_DATA(15),
2178 EXT_CLK_MIO_DATA(16),
2179 EXT_CLK_MIO_DATA(17),
2180 EXT_CLK_MIO_DATA(18),
2181 EXT_CLK_MIO_DATA(19),
2182 EXT_CLK_MIO_DATA(20),
2183 EXT_CLK_MIO_DATA(21),
2184 EXT_CLK_MIO_DATA(22),
2185 EXT_CLK_MIO_DATA(23),
2186 EXT_CLK_MIO_DATA(24),
2187 EXT_CLK_MIO_DATA(25),
2188 EXT_CLK_MIO_DATA(26),
2189 EXT_CLK_MIO_DATA(27),
2190 EXT_CLK_MIO_DATA(28),
2191 EXT_CLK_MIO_DATA(29),
2192 EXT_CLK_MIO_DATA(30),
2193 EXT_CLK_MIO_DATA(31),
2194 EXT_CLK_MIO_DATA(32),
2195 EXT_CLK_MIO_DATA(33),
2196 EXT_CLK_MIO_DATA(34),
2197 EXT_CLK_MIO_DATA(35),
2198 EXT_CLK_MIO_DATA(36),
2199 EXT_CLK_MIO_DATA(37),
2200 EXT_CLK_MIO_DATA(38),
2201 EXT_CLK_MIO_DATA(39),
2202 EXT_CLK_MIO_DATA(40),
2203 EXT_CLK_MIO_DATA(41),
2204 EXT_CLK_MIO_DATA(42),
2205 EXT_CLK_MIO_DATA(43),
2206 EXT_CLK_MIO_DATA(44),
2207 EXT_CLK_MIO_DATA(45),
2208 EXT_CLK_MIO_DATA(46),
2209 EXT_CLK_MIO_DATA(47),
2210 EXT_CLK_MIO_DATA(48),
2211 EXT_CLK_MIO_DATA(49),
2212 EXT_CLK_MIO_DATA(50),
2213 EXT_CLK_MIO_DATA(51),
2214 EXT_CLK_MIO_DATA(52),
2215 EXT_CLK_MIO_DATA(53),
2216 EXT_CLK_MIO_DATA(54),
2217 EXT_CLK_MIO_DATA(55),
2218 EXT_CLK_MIO_DATA(56),
2219 EXT_CLK_MIO_DATA(57),
2220 EXT_CLK_MIO_DATA(58),
2221 EXT_CLK_MIO_DATA(59),
2222 EXT_CLK_MIO_DATA(60),
2223 EXT_CLK_MIO_DATA(61),
2224 EXT_CLK_MIO_DATA(62),
2225 EXT_CLK_MIO_DATA(63),
2226 EXT_CLK_MIO_DATA(64),
2227 EXT_CLK_MIO_DATA(65),
2228 EXT_CLK_MIO_DATA(66),
2229 EXT_CLK_MIO_DATA(67),
2230 EXT_CLK_MIO_DATA(68),
2231 EXT_CLK_MIO_DATA(69),
2232 EXT_CLK_MIO_DATA(70),
2233 EXT_CLK_MIO_DATA(71),
2234 EXT_CLK_MIO_DATA(72),
2235 EXT_CLK_MIO_DATA(73),
2236 EXT_CLK_MIO_DATA(74),
2237 EXT_CLK_MIO_DATA(75),
2238 EXT_CLK_MIO_DATA(76),
2239 EXT_CLK_MIO_DATA(77),
2240};
2241
2242/* Array of clock which are invalid for this variant */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002243static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB};
Rajan Vajad98455b2018-01-17 02:39:26 -08002244
Rajan Vajad98455b2018-01-17 02:39:26 -08002245/**
2246 * pm_clock_valid - Check if clock is valid or not
2247 * @clock_id Id of the clock to be queried
2248 *
2249 * This function is used to check if given clock is valid
2250 * or not for the chip variant.
2251 *
2252 * List of invalid clocks are maintained in array list for
2253 * different variants.
2254 *
2255 * Return: Returns 1 if clock is valid else 0.
2256 */
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002257static bool pm_clock_valid(unsigned int clock_id)
Rajan Vajad98455b2018-01-17 02:39:26 -08002258{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002259 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002260
2261 for (i = 0; i < ARRAY_SIZE(pm_clk_invalid_list); i++)
2262 if (pm_clk_invalid_list[i] == clock_id)
2263 return 0;
2264
2265 return 1;
2266}
2267
2268/**
Rajan Vajad98455b2018-01-17 02:39:26 -08002269 * pm_clock_type - Get clock's type
2270 * @clock_id Id of the clock to be queried
2271 *
2272 * This function is used to check type of clock (OUTPUT/EXTERNAL).
2273 *
2274 * Return: Returns type of clock (OUTPUT/EXTERNAL).
2275 */
2276static unsigned int pm_clock_type(unsigned int clock_id)
2277{
2278 return (clock_id < CLK_MAX_OUTPUT_CLK) ?
2279 CLK_TYPE_OUTPUT : CLK_TYPE_EXTERNAL;
2280}
Rajan Vaja35116132018-01-17 02:39:25 -08002281
2282/**
Rajan Vajada959402018-07-20 03:16:27 -07002283 * pm_api_clock_get_num_clocks() - PM call to request number of clocks
2284 * @nclocks Number of clocks
2285 *
2286 * This function is used by master to get number of clocks.
2287 *
2288 * @return Returns success.
2289 */
2290enum pm_ret_status pm_api_clock_get_num_clocks(unsigned int *nclocks)
2291{
2292 *nclocks = CLK_MAX;
2293
2294 return PM_RET_SUCCESS;
2295}
2296
2297/**
Rajan Vaja35116132018-01-17 02:39:25 -08002298 * pm_api_clock_get_name() - PM call to request a clock's name
2299 * @clock_id Clock ID
2300 * @name Name of clock (max 16 bytes)
2301 *
2302 * This function is used by master to get nmae of clock specified
2303 * by given clock ID.
2304 *
2305 * @return Returns success. In case of error, name data is 0.
2306 */
2307enum pm_ret_status pm_api_clock_get_name(unsigned int clock_id, char *name)
2308{
Rajan Vajad98455b2018-01-17 02:39:26 -08002309 if (clock_id == CLK_MAX)
2310 memcpy(name, END_OF_CLK, CLK_NAME_LEN);
2311 else if (!pm_clock_valid(clock_id))
2312 memset(name, 0, CLK_NAME_LEN);
2313 else if (clock_id < CLK_MAX_OUTPUT_CLK)
2314 memcpy(name, clocks[clock_id].name, CLK_NAME_LEN);
2315 else
2316 memcpy(name, ext_clocks[clock_id - CLK_MAX_OUTPUT_CLK].name,
2317 CLK_NAME_LEN);
2318
2319 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002320}
2321
2322/**
2323 * pm_api_clock_get_topology() - PM call to request a clock's topology
2324 * @clock_id Clock ID
2325 * @index Topology index for next toplogy node
2326 * @topology Buffer to store nodes in topology and flags
2327 *
2328 * This function is used by master to get topology information for the
2329 * clock specified by given clock ID. Each response would return 3
2330 * topology nodes. To get next nodes, caller needs to call this API with
2331 * index of next node. Index starts from 0.
2332 *
2333 * @return Returns status, either success or error+reason
2334 */
2335enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id,
2336 unsigned int index,
2337 uint32_t *topology)
2338{
Rajan Vajad98455b2018-01-17 02:39:26 -08002339 struct pm_clock_node *clock_nodes;
2340 uint8_t num_nodes;
2341 unsigned int i;
2342
2343 if (!pm_clock_valid(clock_id))
2344 return PM_RET_ERROR_ARGS;
2345
2346 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2347 return PM_RET_ERROR_NOTSUPPORTED;
2348
2349
2350 memset(topology, 0, CLK_TOPOLOGY_PAYLOAD_LEN);
2351 clock_nodes = *clocks[clock_id].nodes;
2352 num_nodes = clocks[clock_id].num_nodes;
2353
2354 /* Skip parent till index */
2355 if (index >= num_nodes)
2356 return PM_RET_SUCCESS;
2357
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002358 for (i = 0; i < 3U; i++) {
Rajan Vajad98455b2018-01-17 02:39:26 -08002359 if ((index + i) == num_nodes)
2360 break;
2361 topology[i] = clock_nodes[index + i].type;
2362 topology[i] |= clock_nodes[index + i].clkflags <<
2363 CLK_CLKFLAGS_SHIFT;
2364 topology[i] |= clock_nodes[index + i].typeflags <<
2365 CLK_TYPEFLAGS_SHIFT;
2366 }
2367
2368 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002369}
2370
2371/**
2372 * pm_api_clock_get_fixedfactor_params() - PM call to request a clock's fixed
2373 * factor parameters for fixed clock
2374 * @clock_id Clock ID
2375 * @mul Multiplication value
2376 * @div Divisor value
2377 *
2378 * This function is used by master to get fixed factor parameers for the
2379 * fixed clock. This API is application only for the fixed clock.
2380 *
2381 * @return Returns status, either success or error+reason
2382 */
2383enum pm_ret_status pm_api_clock_get_fixedfactor_params(unsigned int clock_id,
2384 uint32_t *mul,
2385 uint32_t *div)
2386{
Rajan Vajad98455b2018-01-17 02:39:26 -08002387 struct pm_clock_node *clock_nodes;
2388 uint8_t num_nodes;
2389 unsigned int type, i;
2390
2391 if (!pm_clock_valid(clock_id))
2392 return PM_RET_ERROR_ARGS;
2393
2394 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2395 return PM_RET_ERROR_NOTSUPPORTED;
2396
2397 clock_nodes = *clocks[clock_id].nodes;
2398 num_nodes = clocks[clock_id].num_nodes;
2399
2400 for (i = 0; i < num_nodes; i++) {
2401 type = clock_nodes[i].type;
2402 if (type == TYPE_FIXEDFACTOR) {
2403 *mul = clock_nodes[i].mult;
2404 *div = clock_nodes[i].div;
2405 break;
2406 }
2407 }
2408
2409 /* Clock is not fixed clock */
2410 if (i == num_nodes)
2411 return PM_RET_ERROR_ARGS;
2412
2413 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002414}
2415
2416/**
2417 * pm_api_clock_get_parents() - PM call to request a clock's first 3 parents
2418 * @clock_id Clock ID
2419 * @index Index of next parent
2420 * @parents Parents of the given clock
2421 *
2422 * This function is used by master to get clock's parents information.
2423 * This API will return 3 parents with a single response. To get other
2424 * parents, master should call same API in loop with new parent index
2425 * till error is returned.
2426 *
2427 * E.g First call should have index 0 which will return parents 0, 1 and
2428 * 2. Next call, index should be 3 which will return parent 3,4 and 5 and
2429 * so on.
2430 *
2431 * @return Returns status, either success or error+reason
2432 */
2433enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id,
2434 unsigned int index,
2435 uint32_t *parents)
2436{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002437 unsigned int i;
Rajan Vajad98455b2018-01-17 02:39:26 -08002438 int32_t *clk_parents;
2439
2440 if (!pm_clock_valid(clock_id))
2441 return PM_RET_ERROR_ARGS;
2442
2443 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2444 return PM_RET_ERROR_NOTSUPPORTED;
2445
2446 clk_parents = *clocks[clock_id].parents;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002447 if (clk_parents == NULL)
Rajan Vajad98455b2018-01-17 02:39:26 -08002448 return PM_RET_ERROR_ARGS;
2449
2450 memset(parents, 0, CLK_PARENTS_PAYLOAD_LEN);
2451
2452 /* Skip parent till index */
2453 for (i = 0; i < index; i++)
2454 if (clk_parents[i] == CLK_NA_PARENT)
2455 return PM_RET_SUCCESS;
2456
2457 for (i = 0; i < 3; i++) {
2458 parents[i] = clk_parents[index + i];
2459 if (clk_parents[index + i] == CLK_NA_PARENT)
2460 break;
2461 }
2462
2463 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002464}
2465
2466/**
2467 * pm_api_clock_get_attributes() - PM call to request a clock's attributes
2468 * @clock_id Clock ID
2469 * @attr Clock attributes
2470 *
2471 * This function is used by master to get clock's attributes
2472 * (e.g. valid, clock type, etc).
2473 *
2474 * @return Returns status, either success or error+reason
2475 */
2476enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id,
2477 uint32_t *attr)
2478{
Rajan Vajad98455b2018-01-17 02:39:26 -08002479 if (clock_id >= CLK_MAX)
2480 return PM_RET_ERROR_ARGS;
2481
2482 /* Clock valid bit */
2483 *attr = pm_clock_valid(clock_id);
2484
Rajan Vajad98455b2018-01-17 02:39:26 -08002485 /* Clock type (Output/External) */
2486 *attr |= (pm_clock_type(clock_id) << CLK_TYPE_SHIFT);
2487
2488 return PM_RET_SUCCESS;
2489}
2490
2491/**
Jolly Shahb4c99462019-01-02 12:40:17 -08002492 * struct pm_pll - PLL related data required to map IOCTL-based PLL control
2493 * implemented by linux to system-level EEMI APIs
2494 * @nid: PLL node ID
2495 * @cid: PLL clock ID
Jolly Shah407fc0a2019-01-04 11:57:40 -08002496 * @pre_src: Pre-source PLL clock ID
2497 * @post_src: Post-source PLL clock ID
2498 * @div2: DIV2 PLL clock ID
2499 * @bypass: PLL output clock ID that maps to bypass select output
Jolly Shahcb5bc752019-01-02 12:46:46 -08002500 * @mode: PLL mode currently set via IOCTL (PLL_FRAC_MODE/PLL_INT_MODE)
Jolly Shahb4c99462019-01-02 12:40:17 -08002501 */
2502struct pm_pll {
2503 const enum pm_node_id nid;
2504 const enum clock_id cid;
Jolly Shah407fc0a2019-01-04 11:57:40 -08002505 const enum clock_id pre_src;
2506 const enum clock_id post_src;
2507 const enum clock_id div2;
2508 const enum clock_id bypass;
Jolly Shahcb5bc752019-01-02 12:46:46 -08002509 uint8_t mode;
Jolly Shahb4c99462019-01-02 12:40:17 -08002510};
2511
2512static struct pm_pll pm_plls[] = {
2513 {
2514 .nid = NODE_IOPLL,
2515 .cid = CLK_IOPLL_INT,
Jolly Shah407fc0a2019-01-04 11:57:40 -08002516 .pre_src = CLK_IOPLL_PRE_SRC,
2517 .post_src = CLK_IOPLL_POST_SRC,
2518 .div2 = CLK_IOPLL_INT_MUX,
2519 .bypass = CLK_IOPLL,
Jolly Shahb4c99462019-01-02 12:40:17 -08002520 }, {
2521 .nid = NODE_RPLL,
2522 .cid = CLK_RPLL_INT,
Jolly Shah407fc0a2019-01-04 11:57:40 -08002523 .pre_src = CLK_RPLL_PRE_SRC,
2524 .post_src = CLK_RPLL_POST_SRC,
2525 .div2 = CLK_RPLL_INT_MUX,
2526 .bypass = CLK_RPLL,
Jolly Shahb4c99462019-01-02 12:40:17 -08002527 }, {
2528 .nid = NODE_APLL,
2529 .cid = CLK_APLL_INT,
Jolly Shah407fc0a2019-01-04 11:57:40 -08002530 .pre_src = CLK_APLL_PRE_SRC,
2531 .post_src = CLK_APLL_POST_SRC,
2532 .div2 = CLK_APLL_INT_MUX,
2533 .bypass = CLK_APLL,
Jolly Shahb4c99462019-01-02 12:40:17 -08002534 }, {
2535 .nid = NODE_VPLL,
2536 .cid = CLK_VPLL_INT,
Jolly Shah407fc0a2019-01-04 11:57:40 -08002537 .pre_src = CLK_VPLL_PRE_SRC,
2538 .post_src = CLK_VPLL_POST_SRC,
2539 .div2 = CLK_VPLL_INT_MUX,
2540 .bypass = CLK_VPLL,
Jolly Shahb4c99462019-01-02 12:40:17 -08002541 }, {
2542 .nid = NODE_DPLL,
2543 .cid = CLK_DPLL_INT,
Jolly Shah407fc0a2019-01-04 11:57:40 -08002544 .pre_src = CLK_DPLL_PRE_SRC,
2545 .post_src = CLK_DPLL_POST_SRC,
2546 .div2 = CLK_DPLL_INT_MUX,
2547 .bypass = CLK_DPLL,
Jolly Shahb4c99462019-01-02 12:40:17 -08002548 },
2549};
2550
2551/**
2552 * pm_clock_get_pll() - Get PLL structure by PLL clock ID
2553 * @clock_id Clock ID of the target PLL
2554 *
2555 * @return Pointer to PLL structure if found, NULL otherwise
2556 */
Jolly Shaha5209802019-01-04 11:45:59 -08002557struct pm_pll *pm_clock_get_pll(enum clock_id clock_id)
Jolly Shahb4c99462019-01-02 12:40:17 -08002558{
2559 uint32_t i;
2560
2561 for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
2562 if (pm_plls[i].cid == clock_id)
2563 return &pm_plls[i];
2564 }
2565
2566 return NULL;
2567}
2568
2569/**
2570 * pm_clock_get_pll_node_id() - Get PLL node ID by PLL clock ID
2571 * @clock_id Clock ID of the target PLL
2572 * @node_id Location to store node ID of the target PLL
2573 *
2574 * @return PM_RET_SUCCESS if node ID is found, PM_RET_ERROR_ARGS otherwise
2575 */
2576enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id,
2577 enum pm_node_id *node_id)
2578{
2579 struct pm_pll *pll = pm_clock_get_pll(clock_id);
2580
2581 if (pll) {
2582 *node_id = pll->nid;
2583 return PM_RET_SUCCESS;
2584 }
2585
2586 return PM_RET_ERROR_ARGS;
2587}
2588
2589/**
Jolly Shah407fc0a2019-01-04 11:57:40 -08002590 * pm_clock_get_pll_by_related_clk() - Get PLL structure by PLL-related clock ID
2591 * @clock_id Clock ID
2592 *
2593 * @return Pointer to PLL structure if found, NULL otherwise
2594 */
2595struct pm_pll *pm_clock_get_pll_by_related_clk(enum clock_id clock_id)
2596{
2597 uint32_t i;
2598
2599 for (i = 0; i < ARRAY_SIZE(pm_plls); i++) {
2600 if (pm_plls[i].pre_src == clock_id ||
2601 pm_plls[i].post_src == clock_id ||
2602 pm_plls[i].div2 == clock_id ||
2603 pm_plls[i].bypass == clock_id) {
2604 return &pm_plls[i];
2605 }
2606 }
2607
2608 return NULL;
2609}
2610
2611/**
Jolly Shaha5209802019-01-04 11:45:59 -08002612 * pm_clock_pll_enable() - "Enable" the PLL clock (lock the PLL)
2613 * @pll: PLL to be locked
Rajan Vaja35116132018-01-17 02:39:25 -08002614 *
Jolly Shaha5209802019-01-04 11:45:59 -08002615 * This function is used to map IOCTL/linux-based PLL handling to system-level
2616 * EEMI APIs
Rajan Vaja35116132018-01-17 02:39:25 -08002617 *
Jolly Shaha5209802019-01-04 11:45:59 -08002618 * Return: Error if the argument is not valid or status as returned by PMU
Rajan Vaja35116132018-01-17 02:39:25 -08002619 */
Jolly Shaha5209802019-01-04 11:45:59 -08002620enum pm_ret_status pm_clock_pll_enable(struct pm_pll *pll)
Rajan Vaja35116132018-01-17 02:39:25 -08002621{
Jolly Shaha5209802019-01-04 11:45:59 -08002622 if (!pll)
Rajan Vajad98455b2018-01-17 02:39:26 -08002623 return PM_RET_ERROR_ARGS;
2624
Jolly Shaha5209802019-01-04 11:45:59 -08002625 /* Set the PLL mode according to the buffered mode value */
2626 if (pll->mode == PLL_FRAC_MODE)
2627 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_FRACTIONAL);
Rajan Vajad98455b2018-01-17 02:39:26 -08002628
Jolly Shaha5209802019-01-04 11:45:59 -08002629 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_INTEGER);
Rajan Vaja35116132018-01-17 02:39:25 -08002630}
2631
2632/**
Jolly Shaha9057a02019-01-02 12:54:40 -08002633 * pm_clock_pll_disable - "Disable" the PLL clock (bypass/reset the PLL)
2634 * @pll PLL to be bypassed/reset
Rajan Vaja35116132018-01-17 02:39:25 -08002635 *
Jolly Shaha9057a02019-01-02 12:54:40 -08002636 * This function is used to map IOCTL/linux-based PLL handling to system-level
2637 * EEMI APIs
Rajan Vaja35116132018-01-17 02:39:25 -08002638 *
Jolly Shaha9057a02019-01-02 12:54:40 -08002639 * Return: Error if the argument is not valid or status as returned by PMU
Rajan Vaja35116132018-01-17 02:39:25 -08002640 */
Jolly Shaha9057a02019-01-02 12:54:40 -08002641enum pm_ret_status pm_clock_pll_disable(struct pm_pll *pll)
Rajan Vaja35116132018-01-17 02:39:25 -08002642{
Jolly Shaha9057a02019-01-02 12:54:40 -08002643 if (!pll)
Rajan Vajad98455b2018-01-17 02:39:26 -08002644 return PM_RET_ERROR_ARGS;
2645
Jolly Shaha9057a02019-01-02 12:54:40 -08002646 return pm_pll_set_mode(pll->nid, PM_PLL_MODE_RESET);
Rajan Vajad98455b2018-01-17 02:39:26 -08002647}
2648
2649/**
Jolly Shah99e8ac92019-01-02 12:55:41 -08002650 * pm_clock_pll_get_state - Get state of the PLL
2651 * @pll Pointer to the target PLL structure
2652 * @state Location to store the state: 1/0 ("Enabled"/"Disabled")
Rajan Vajad98455b2018-01-17 02:39:26 -08002653 *
Jolly Shah99e8ac92019-01-02 12:55:41 -08002654 * "Enable" actually means that the PLL is locked and its bypass is deasserted,
2655 * "Disable" means that it is bypassed.
Rajan Vaja35116132018-01-17 02:39:25 -08002656 *
Jolly Shah99e8ac92019-01-02 12:55:41 -08002657 * Return: PM_RET_ERROR_ARGS error if the argument is not valid, success if
2658 * returned state value is valid or an error if returned by PMU
Rajan Vaja35116132018-01-17 02:39:25 -08002659 */
Jolly Shah99e8ac92019-01-02 12:55:41 -08002660enum pm_ret_status pm_clock_pll_get_state(struct pm_pll *pll,
2661 unsigned int *state)
Rajan Vaja35116132018-01-17 02:39:25 -08002662{
Jolly Shah99e8ac92019-01-02 12:55:41 -08002663 enum pm_ret_status status;
2664 enum pm_pll_mode mode;
Rajan Vajad98455b2018-01-17 02:39:26 -08002665
Jolly Shah99e8ac92019-01-02 12:55:41 -08002666 if (!pll || !state)
Rajan Vajad98455b2018-01-17 02:39:26 -08002667 return PM_RET_ERROR_ARGS;
2668
Jolly Shah99e8ac92019-01-02 12:55:41 -08002669 status = pm_pll_get_mode(pll->nid, &mode);
2670 if (status != PM_RET_SUCCESS)
2671 return status;
Rajan Vajad98455b2018-01-17 02:39:26 -08002672
Jolly Shah99e8ac92019-01-02 12:55:41 -08002673 if (mode == PM_PLL_MODE_RESET)
2674 *state = 0;
Rajan Vajad98455b2018-01-17 02:39:26 -08002675 else
Jolly Shah99e8ac92019-01-02 12:55:41 -08002676 *state = 1;
Rajan Vajad98455b2018-01-17 02:39:26 -08002677
Jolly Shah99e8ac92019-01-02 12:55:41 -08002678 return PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002679}
2680
Rajan Vaja35116132018-01-17 02:39:25 -08002681/**
Jolly Shah407fc0a2019-01-04 11:57:40 -08002682 * pm_clock_pll_set_parent - Set the clock parent for PLL-related clock id
2683 * @pll Target PLL structure
2684 * @clock_id Id of the clock
2685 * @parent_index parent index (=mux select value)
Rajan Vaja35116132018-01-17 02:39:25 -08002686 *
Jolly Shah407fc0a2019-01-04 11:57:40 -08002687 * The whole clock-tree implementation relies on the fact that parent indexes
2688 * match to the multiplexer select values. This function has to rely on that
2689 * assumption as well => parent_index is actually the mux select value.
Rajan Vaja35116132018-01-17 02:39:25 -08002690 *
2691 * Return: Returns status, either success or error+reason.
2692 */
Jolly Shah407fc0a2019-01-04 11:57:40 -08002693enum pm_ret_status pm_clock_pll_set_parent(struct pm_pll *pll,
2694 enum clock_id clock_id,
2695 unsigned int parent_index)
Rajan Vaja35116132018-01-17 02:39:25 -08002696{
Jolly Shah407fc0a2019-01-04 11:57:40 -08002697 if (!pll)
Rajan Vajad98455b2018-01-17 02:39:26 -08002698 return PM_RET_ERROR_ARGS;
Jolly Shah407fc0a2019-01-04 11:57:40 -08002699 if (pll->pre_src == clock_id)
2700 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_PRE_SRC,
2701 parent_index);
2702 if (pll->post_src == clock_id)
2703 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_POST_SRC,
2704 parent_index);
2705 if (pll->div2 == clock_id)
2706 return pm_pll_set_parameter(pll->nid, PM_PLL_PARAM_DIV2,
2707 parent_index);
Rajan Vajad98455b2018-01-17 02:39:26 -08002708
Jolly Shah407fc0a2019-01-04 11:57:40 -08002709 return PM_RET_ERROR_ARGS;
Rajan Vaja35116132018-01-17 02:39:25 -08002710}
2711
2712/**
2713 * pm_api_clock_getparent - Get the clock parent for given id
2714 * @clock_id Id of the clock
Rajan Vaja914f1cd2018-07-09 00:01:38 -07002715 * @parent_idx parent index
Rajan Vaja35116132018-01-17 02:39:25 -08002716 *
2717 * This function is used by master to get parent index
2718 * for any clock.
2719 *
2720 * Return: Returns status, either success or error+reason.
2721 */
2722enum pm_ret_status pm_api_clock_getparent(unsigned int clock_id,
2723 unsigned int *parent_idx)
2724{
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002725 enum pm_ret_status ret = PM_RET_SUCCESS;
Rajan Vajad98455b2018-01-17 02:39:26 -08002726 struct pm_clock_node *nodes;
2727 uint8_t num_nodes;
2728 unsigned int reg, val;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002729 uint8_t i = 0, offset = NA_SHIFT, width = NA_WIDTH;
Rajan Vajad98455b2018-01-17 02:39:26 -08002730
2731 if (!pm_clock_valid(clock_id))
2732 return PM_RET_ERROR_ARGS;
2733
2734 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2735 return PM_RET_ERROR_NOTSUPPORTED;
2736
2737 nodes = *clocks[clock_id].nodes;
2738 num_nodes = clocks[clock_id].num_nodes;
2739
2740 for (i = 0; i < num_nodes; i++) {
2741 if (nodes->type == TYPE_MUX) {
2742 offset = nodes->offset;
2743 width = nodes->width;
2744 }
2745 nodes++;
2746 }
2747 if (width == NA_WIDTH)
2748 return PM_RET_ERROR_NOTSUPPORTED;
2749
2750 reg = clocks[clock_id].control_reg;
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002751 ret = pm_mmio_read(reg, &val);
Rajan Vajad98455b2018-01-17 02:39:26 -08002752 val >>= offset;
2753 val &= ((1U << width) - 1);
2754
2755 *parent_idx = val;
2756
Jolly Shah69fb5bf2018-02-07 16:25:41 -08002757 return ret;
Rajan Vaja35116132018-01-17 02:39:25 -08002758}
2759
2760/**
Jolly Shahcb5bc752019-01-02 12:46:46 -08002761 * pm_clock_set_pll_mode() - Set PLL mode
2762 * @clock_id PLL clock id
2763 * @mode Mode fractional/integer
Rajan Vaja35116132018-01-17 02:39:25 -08002764 *
Jolly Shahcb5bc752019-01-02 12:46:46 -08002765 * This function buffers/saves the PLL mode that is set.
Rajan Vaja35116132018-01-17 02:39:25 -08002766 *
Jolly Shahcb5bc752019-01-02 12:46:46 -08002767 * @return Success if mode is buffered or error if an argument is invalid
Rajan Vaja35116132018-01-17 02:39:25 -08002768 */
Jolly Shahcb5bc752019-01-02 12:46:46 -08002769enum pm_ret_status pm_clock_set_pll_mode(enum clock_id clock_id,
2770 unsigned int mode)
Rajan Vaja35116132018-01-17 02:39:25 -08002771{
Jolly Shahcb5bc752019-01-02 12:46:46 -08002772 struct pm_pll *pll = pm_clock_get_pll(clock_id);
Rajan Vajad98455b2018-01-17 02:39:26 -08002773
Jolly Shahcb5bc752019-01-02 12:46:46 -08002774 if (!pll || (mode != PLL_FRAC_MODE && mode != PLL_INT_MODE))
Rajan Vajad98455b2018-01-17 02:39:26 -08002775 return PM_RET_ERROR_ARGS;
Jolly Shahcb5bc752019-01-02 12:46:46 -08002776 pll->mode = mode;
Rajan Vajad98455b2018-01-17 02:39:26 -08002777
Jolly Shahcb5bc752019-01-02 12:46:46 -08002778 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002779}
2780
2781/**
Jolly Shah77eb52f2019-01-02 12:49:21 -08002782 * pm_clock_get_pll_mode() - Get PLL mode
2783 * @clock_id PLL clock id
2784 * @mode Location to store the mode (fractional/integer)
Rajan Vaja35116132018-01-17 02:39:25 -08002785 *
Jolly Shah77eb52f2019-01-02 12:49:21 -08002786 * This function returns buffered PLL mode.
Rajan Vaja35116132018-01-17 02:39:25 -08002787 *
Jolly Shah77eb52f2019-01-02 12:49:21 -08002788 * @return Success if mode is stored or error if an argument is invalid
Rajan Vaja35116132018-01-17 02:39:25 -08002789 */
Jolly Shah77eb52f2019-01-02 12:49:21 -08002790enum pm_ret_status pm_clock_get_pll_mode(enum clock_id clock_id,
2791 unsigned int *mode)
Rajan Vaja35116132018-01-17 02:39:25 -08002792{
Jolly Shah77eb52f2019-01-02 12:49:21 -08002793 struct pm_pll *pll = pm_clock_get_pll(clock_id);
Rajan Vajad98455b2018-01-17 02:39:26 -08002794
Jolly Shah77eb52f2019-01-02 12:49:21 -08002795 if (!pll || !mode)
Rajan Vajad98455b2018-01-17 02:39:26 -08002796 return PM_RET_ERROR_ARGS;
Jolly Shah77eb52f2019-01-02 12:49:21 -08002797 *mode = pll->mode;
Rajan Vajad98455b2018-01-17 02:39:26 -08002798
Jolly Shah77eb52f2019-01-02 12:49:21 -08002799 return PM_RET_SUCCESS;
Rajan Vaja35116132018-01-17 02:39:25 -08002800}
Jolly Shaha5209802019-01-04 11:45:59 -08002801
2802/**
2803 * pm_clock_id_is_valid() - Check if given clock ID is valid
2804 * @clock_id ID of the clock to be checked
2805 *
2806 * @return Returns success if clock_id is valid, otherwise an error
2807 */
2808enum pm_ret_status pm_clock_id_is_valid(unsigned int clock_id)
2809{
2810 if (!pm_clock_valid(clock_id))
2811 return PM_RET_ERROR_ARGS;
2812
2813 if (pm_clock_type(clock_id) != CLK_TYPE_OUTPUT)
2814 return PM_RET_ERROR_NOTSUPPORTED;
2815
2816 return PM_RET_SUCCESS;
2817}
Jolly Shah4dd11762019-01-04 11:53:37 -08002818
2819/**
2820 * pm_clock_has_div() - Check if the clock has divider with given ID
2821 * @clock_id Clock ID
2822 * @div_id Divider ID
2823 *
2824 * @return True(1)=clock has the divider, false(0)=otherwise
2825 */
2826uint8_t pm_clock_has_div(unsigned int clock_id, enum pm_clock_div_id div_id)
2827{
2828 uint32_t i;
2829 struct pm_clock_node *nodes;
2830
2831 if (clock_id >= CLK_MAX_OUTPUT_CLK)
2832 return 0;
2833
2834 nodes = *clocks[clock_id].nodes;
2835 for (i = 0; i < clocks[clock_id].num_nodes; i++) {
2836 if (nodes[i].type == TYPE_DIV1) {
2837 if (div_id == PM_CLOCK_DIV0_ID)
2838 return 1;
2839 } else if (nodes[i].type == TYPE_DIV2) {
2840 if (div_id == PM_CLOCK_DIV1_ID)
2841 return 1;
2842 }
2843 }
2844
2845 return 0;
2846}