2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
8 * ZynqMP system level PM-API functions for clock control.
11 #include <arch_helpers.h>
16 #include "pm_api_clock.h"
17 #include "pm_api_sys.h"
18 #include "pm_client.h"
19 #include "pm_common.h"
22 #define CLK_NODE_MAX U(6)
24 #define CLK_PARENTS_ID_LEN U(16)
25 #define CLK_TOPOLOGY_NODE_OFFSET U(16)
26 #define CLK_TOPOLOGY_PAYLOAD_LEN U(12)
27 #define CLK_PARENTS_PAYLOAD_LEN U(12)
28 #define CLK_TYPE_SHIFT U(2)
29 #define CLK_CLKFLAGS_SHIFT U(8)
30 #define CLK_TYPEFLAGS_SHIFT U(24)
32 #define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN)
38 #define NA_CLK_FLAGS U(0)
39 #define NA_TYPE_FLAGS U(0)
41 /* PLL nodes related definitions */
42 #define PLL_PRESRC_MUX_SHIFT U(20)
43 #define PLL_PRESRC_MUX_WIDTH U(3)
44 #define PLL_POSTSRC_MUX_SHIFT U(24)
45 #define PLL_POSTSRC_MUX_WIDTH U(3)
46 #define PLL_DIV2_MUX_SHIFT U(16)
47 #define PLL_DIV2_MUX_WIDTH U(1)
48 #define PLL_BYPASS_MUX_SHIFT U(3)
49 #define PLL_BYPASS_MUX_WIDTH U(1)
51 /* Peripheral nodes related definitions */
52 /* Peripheral Clocks */
53 #define PERIPH_MUX_SHIFT U(0)
54 #define PERIPH_MUX_WIDTH U(3)
55 #define PERIPH_DIV1_SHIFT U(8)
56 #define PERIPH_DIV1_WIDTH U(6)
57 #define PERIPH_DIV2_SHIFT U(16)
58 #define PERIPH_DIV2_WIDTH U(6)
59 #define PERIPH_GATE_SHIFT U(24)
60 #define PERIPH_GATE_WIDTH U(1)
62 #define USB_GATE_SHIFT U(25)
64 /* External clock related definitions */
66 #define EXT_CLK_MIO_DATA(mio) \
67 [EXT_CLK_INDEX(EXT_CLK_MIO##mio)] = { \
68 .name = "mio_clk_"#mio, \
71 #define EXT_CLK_INDEX(n) (n - CLK_MAX_OUTPUT_CLK)
73 /* Clock control related definitions */
74 #define BIT_MASK(x, y) (((1U << (y)) - 1) << (x))
76 #define ISPLL(id) (id == CLK_APLL_INT || \
77 id == CLK_DPLL_INT || \
78 id == CLK_VPLL_INT || \
79 id == CLK_IOPLL_INT || \
83 #define PLLCTRL_BP_MASK BIT(3)
84 #define PLLCTRL_RESET_MASK U(1)
85 #define PLL_FRAC_OFFSET U(8)
86 #define PLL_FRAC_MODE U(1)
87 #define PLL_INT_MODE U(0)
88 #define PLL_FRAC_MODE_MASK U(0x80000000)
89 #define PLL_FRAC_MODE_SHIFT U(31)
90 #define PLL_FRAC_DATA_MASK U(0xFFFF)
91 #define PLL_FRAC_DATA_SHIFT U(0)
92 #define PLL_FBDIV_MASK U(0x7F00)
93 #define PLL_FBDIV_WIDTH U(7)
94 #define PLL_FBDIV_SHIFT U(8)
96 #define CLK_PLL_RESET_ASSERT U(1)
97 #define CLK_PLL_RESET_RELEASE U(2)
98 #define CLK_PLL_RESET_PULSE (CLK_PLL_RESET_ASSERT | CLK_PLL_RESET_RELEASE)
100 /* Common topology definitions */
101 #define GENERIC_MUX \
104 .offset = PERIPH_MUX_SHIFT, \
105 .width = PERIPH_MUX_WIDTH, \
106 .clkflags = CLK_SET_RATE_NO_REPARENT | \
108 .typeflags = NA_TYPE_FLAGS, \
113 #define IGNORE_UNUSED_MUX \
116 .offset = PERIPH_MUX_SHIFT, \
117 .width = PERIPH_MUX_WIDTH, \
118 .clkflags = CLK_IGNORE_UNUSED | \
119 CLK_SET_RATE_NO_REPARENT | \
121 .typeflags = NA_TYPE_FLAGS, \
126 #define GENERIC_DIV(id) \
128 .type = TYPE_DIV##id, \
129 .offset = PERIPH_DIV##id##_SHIFT, \
130 .width = PERIPH_DIV##id##_WIDTH, \
131 .clkflags = CLK_SET_RATE_NO_REPARENT | \
133 .typeflags = CLK_DIVIDER_ONE_BASED | \
134 CLK_DIVIDER_ALLOW_ZERO, \
139 #define IGNORE_UNUSED_DIV(id) \
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 | \
147 .typeflags = CLK_DIVIDER_ONE_BASED | \
148 CLK_DIVIDER_ALLOW_ZERO, \
153 #define GENERIC_GATE \
156 .offset = PERIPH_GATE_SHIFT, \
157 .width = PERIPH_GATE_WIDTH, \
158 .clkflags = CLK_SET_RATE_PARENT | \
159 CLK_SET_RATE_GATE | \
161 .typeflags = NA_TYPE_FLAGS, \
166 #define IGNORE_UNUSED_GATE \
169 .offset = PERIPH_GATE_SHIFT, \
170 .width = PERIPH_GATE_WIDTH, \
171 .clkflags = CLK_SET_RATE_PARENT | \
172 CLK_IGNORE_UNUSED | \
174 .typeflags = NA_TYPE_FLAGS, \
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
189 struct pm_clock_node
{
200 * struct pm_clock - Clock structure
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
209 char name
[CLK_NAME_LEN
];
211 unsigned int control_reg
;
212 unsigned int status_reg
;
213 int32_t (*parents
)[];
214 struct pm_clock_node(*nodes
)[];
218 * struct pm_clock - Clock structure
221 struct pm_ext_clock
{
222 char name
[CLK_NAME_LEN
];
226 static struct pm_clock_node generic_pll_nodes
[] = {
231 .clkflags
= CLK_SET_RATE_NO_REPARENT
,
232 .typeflags
= NA_TYPE_FLAGS
,
238 static struct pm_clock_node ignore_unused_pll_nodes
[] = {
243 .clkflags
= CLK_IGNORE_UNUSED
| CLK_SET_RATE_NO_REPARENT
,
244 .typeflags
= NA_TYPE_FLAGS
,
250 static struct pm_clock_node generic_pll_pre_src_nodes
[] = {
253 .offset
= PLL_PRESRC_MUX_SHIFT
,
254 .width
= PLL_PRESRC_MUX_WIDTH
,
255 .clkflags
= CLK_IS_BASIC
,
256 .typeflags
= NA_TYPE_FLAGS
,
262 static struct pm_clock_node generic_pll_half_nodes
[] = {
264 .type
= TYPE_FIXEDFACTOR
,
267 .clkflags
= CLK_SET_RATE_NO_REPARENT
| CLK_SET_RATE_PARENT
,
268 .typeflags
= NA_TYPE_FLAGS
,
274 static struct pm_clock_node generic_pll_int_nodes
[] = {
277 .offset
= PLL_DIV2_MUX_SHIFT
,
278 .width
= PLL_DIV2_MUX_WIDTH
,
279 .clkflags
= CLK_SET_RATE_NO_REPARENT
|
280 CLK_SET_RATE_PARENT
|
282 .typeflags
= NA_TYPE_FLAGS
,
288 static struct pm_clock_node generic_pll_post_src_nodes
[] = {
291 .offset
= PLL_POSTSRC_MUX_SHIFT
,
292 .width
= PLL_POSTSRC_MUX_WIDTH
,
293 .clkflags
= CLK_IS_BASIC
,
294 .typeflags
= NA_TYPE_FLAGS
,
300 static struct pm_clock_node generic_pll_system_nodes
[] = {
303 .offset
= PLL_BYPASS_MUX_SHIFT
,
304 .width
= PLL_BYPASS_MUX_WIDTH
,
305 .clkflags
= CLK_SET_RATE_NO_REPARENT
|
306 CLK_SET_RATE_PARENT
|
308 .typeflags
= NA_TYPE_FLAGS
,
314 static struct pm_clock_node acpu_nodes
[] = {
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
,
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
,
335 .offset
= PERIPH_GATE_SHIFT
,
336 .width
= PERIPH_GATE_WIDTH
,
337 .clkflags
= CLK_SET_RATE_PARENT
|
341 .typeflags
= NA_TYPE_FLAGS
,
347 static struct pm_clock_node generic_mux_div_nodes
[] = {
352 static struct pm_clock_node generic_mux_div_gate_nodes
[] = {
358 static struct pm_clock_node generic_mux_div_unused_gate_nodes
[] = {
364 static struct pm_clock_node generic_mux_div_div_gate_nodes
[] = {
371 static struct pm_clock_node dp_audio_video_ref_nodes
[] = {
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
,
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
,
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
,
405 .offset
= PERIPH_GATE_SHIFT
,
406 .width
= PERIPH_GATE_WIDTH
,
407 .clkflags
= CLK_SET_RATE_PARENT
|
410 .typeflags
= NA_TYPE_FLAGS
,
416 static struct pm_clock_node usb_nodes
[] = {
422 .offset
= USB_GATE_SHIFT
,
423 .width
= PERIPH_GATE_WIDTH
,
424 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
|
426 .typeflags
= NA_TYPE_FLAGS
,
432 static struct pm_clock_node generic_domain_crossing_nodes
[] = {
437 .clkflags
= CLK_IS_BASIC
,
438 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
444 static struct pm_clock_node rpll_to_fpd_nodes
[] = {
449 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
450 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
456 static struct pm_clock_node acpu_half_nodes
[] = {
458 .type
= TYPE_FIXEDFACTOR
,
469 .width
= PERIPH_GATE_WIDTH
,
470 .clkflags
= CLK_IGNORE_UNUSED
|
471 CLK_SET_RATE_PARENT
|
473 .typeflags
= NA_TYPE_FLAGS
,
479 static struct pm_clock_node wdt_nodes
[] = {
484 .clkflags
= CLK_SET_RATE_PARENT
|
485 CLK_SET_RATE_NO_REPARENT
|
487 .typeflags
= NA_TYPE_FLAGS
,
493 static struct pm_clock_node ddr_nodes
[] = {
499 .clkflags
= CLK_IS_BASIC
| CLK_IS_CRITICAL
,
500 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
506 static struct pm_clock_node pl_nodes
[] = {
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
,
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
,
528 .offset
= PERIPH_GATE_SHIFT
,
529 .width
= PERIPH_GATE_WIDTH
,
530 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
531 .typeflags
= NA_TYPE_FLAGS
,
537 static struct pm_clock_node gpu_pp0_nodes
[] = {
541 .width
= PERIPH_GATE_WIDTH
,
542 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
543 .typeflags
= NA_TYPE_FLAGS
,
549 static struct pm_clock_node gpu_pp1_nodes
[] = {
553 .width
= PERIPH_GATE_WIDTH
,
554 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
555 .typeflags
= NA_TYPE_FLAGS
,
561 static struct pm_clock_node gem_nodes
[] = {
567 .clkflags
= CLK_IS_BASIC
,
568 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
576 .clkflags
= CLK_IS_BASIC
,
577 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
584 .width
= PERIPH_GATE_WIDTH
,
585 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
586 .typeflags
= NA_TYPE_FLAGS
,
592 static struct pm_clock_node gem0_tx_nodes
[] = {
597 .clkflags
= CLK_SET_RATE_NO_REPARENT
| CLK_IS_BASIC
,
598 .typeflags
= NA_TYPE_FLAGS
,
605 .width
= PERIPH_GATE_WIDTH
,
606 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
607 .typeflags
= NA_TYPE_FLAGS
,
613 static struct pm_clock_node gem1_tx_nodes
[] = {
618 .clkflags
= CLK_SET_RATE_NO_REPARENT
| CLK_IS_BASIC
,
619 .typeflags
= NA_TYPE_FLAGS
,
626 .width
= PERIPH_GATE_WIDTH
,
627 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
628 .typeflags
= NA_TYPE_FLAGS
,
634 static struct pm_clock_node gem2_tx_nodes
[] = {
639 .clkflags
= CLK_SET_RATE_NO_REPARENT
| CLK_IS_BASIC
,
640 .typeflags
= NA_TYPE_FLAGS
,
647 .width
= PERIPH_GATE_WIDTH
,
648 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
649 .typeflags
= NA_TYPE_FLAGS
,
655 static struct pm_clock_node gem3_tx_nodes
[] = {
660 .clkflags
= CLK_SET_RATE_NO_REPARENT
| CLK_IS_BASIC
,
661 .typeflags
= NA_TYPE_FLAGS
,
668 .width
= PERIPH_GATE_WIDTH
,
669 .clkflags
= CLK_SET_RATE_PARENT
| CLK_IS_BASIC
,
670 .typeflags
= NA_TYPE_FLAGS
,
676 static struct pm_clock_node gem_tsu_nodes
[] = {
681 .clkflags
= CLK_SET_RATE_PARENT
|
682 CLK_SET_RATE_NO_REPARENT
|
684 .typeflags
= NA_TYPE_FLAGS
,
690 static struct pm_clock_node can0_mio_nodes
[] = {
695 .clkflags
= CLK_SET_RATE_PARENT
|
696 CLK_SET_RATE_NO_REPARENT
|
698 .typeflags
= NA_TYPE_FLAGS
,
704 static struct pm_clock_node can1_mio_nodes
[] = {
709 .clkflags
= CLK_SET_RATE_PARENT
|
710 CLK_SET_RATE_NO_REPARENT
|
712 .typeflags
= NA_TYPE_FLAGS
,
718 static struct pm_clock_node can0_nodes
[] = {
723 .clkflags
= CLK_SET_RATE_PARENT
|
724 CLK_SET_RATE_NO_REPARENT
|
726 .typeflags
= NA_TYPE_FLAGS
,
732 static struct pm_clock_node can1_nodes
[] = {
737 .clkflags
= CLK_SET_RATE_PARENT
|
738 CLK_SET_RATE_NO_REPARENT
|
740 .typeflags
= NA_TYPE_FLAGS
,
746 static struct pm_clock_node cpu_r5_core_nodes
[] = {
750 .width
= PERIPH_GATE_WIDTH
,
751 .clkflags
= CLK_IGNORE_UNUSED
|
753 .typeflags
= NA_TYPE_FLAGS
,
759 static struct pm_clock_node dll_ref_nodes
[] = {
764 .clkflags
= CLK_SET_RATE_PARENT
|
765 CLK_SET_RATE_NO_REPARENT
|
767 .typeflags
= NA_TYPE_FLAGS
,
773 static struct pm_clock_node timestamp_ref_nodes
[] = {
779 .clkflags
= CLK_IS_BASIC
,
780 .typeflags
= CLK_DIVIDER_ONE_BASED
| CLK_DIVIDER_ALLOW_ZERO
,
787 static int32_t can_mio_parents
[] = {
788 EXT_CLK_MIO0
, EXT_CLK_MIO1
, EXT_CLK_MIO2
, EXT_CLK_MIO3
,
789 EXT_CLK_MIO4
, EXT_CLK_MIO5
, EXT_CLK_MIO6
, EXT_CLK_MIO7
,
790 EXT_CLK_MIO8
, EXT_CLK_MIO9
, EXT_CLK_MIO10
, EXT_CLK_MIO11
,
791 EXT_CLK_MIO12
, EXT_CLK_MIO13
, EXT_CLK_MIO14
, EXT_CLK_MIO15
,
792 EXT_CLK_MIO16
, EXT_CLK_MIO17
, EXT_CLK_MIO18
, EXT_CLK_MIO19
,
793 EXT_CLK_MIO20
, EXT_CLK_MIO21
, EXT_CLK_MIO22
, EXT_CLK_MIO23
,
794 EXT_CLK_MIO24
, EXT_CLK_MIO25
, EXT_CLK_MIO26
, EXT_CLK_MIO27
,
795 EXT_CLK_MIO28
, EXT_CLK_MIO29
, EXT_CLK_MIO30
, EXT_CLK_MIO31
,
796 EXT_CLK_MIO32
, EXT_CLK_MIO33
, EXT_CLK_MIO34
, EXT_CLK_MIO35
,
797 EXT_CLK_MIO36
, EXT_CLK_MIO37
, EXT_CLK_MIO38
, EXT_CLK_MIO39
,
798 EXT_CLK_MIO40
, EXT_CLK_MIO41
, EXT_CLK_MIO42
, EXT_CLK_MIO43
,
799 EXT_CLK_MIO44
, EXT_CLK_MIO45
, EXT_CLK_MIO46
, EXT_CLK_MIO47
,
800 EXT_CLK_MIO48
, EXT_CLK_MIO49
, EXT_CLK_MIO50
, EXT_CLK_MIO51
,
801 EXT_CLK_MIO52
, EXT_CLK_MIO53
, EXT_CLK_MIO54
, EXT_CLK_MIO55
,
802 EXT_CLK_MIO56
, EXT_CLK_MIO57
, EXT_CLK_MIO58
, EXT_CLK_MIO59
,
803 EXT_CLK_MIO60
, EXT_CLK_MIO61
, EXT_CLK_MIO62
, EXT_CLK_MIO63
,
804 EXT_CLK_MIO64
, EXT_CLK_MIO65
, EXT_CLK_MIO66
, EXT_CLK_MIO67
,
805 EXT_CLK_MIO68
, EXT_CLK_MIO69
, EXT_CLK_MIO70
, EXT_CLK_MIO71
,
806 EXT_CLK_MIO72
, EXT_CLK_MIO73
, EXT_CLK_MIO74
, EXT_CLK_MIO75
,
807 EXT_CLK_MIO76
, EXT_CLK_MIO77
, CLK_NA_PARENT
810 /* Clock array containing clock informaton */
811 static struct pm_clock clocks
[] = {
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
),
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
,
835 .nodes
= &generic_pll_pre_src_nodes
,
836 .num_nodes
= ARRAY_SIZE(generic_pll_pre_src_nodes
),
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
),
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 []) {
855 .nodes
= &generic_pll_int_nodes
,
856 .num_nodes
= ARRAY_SIZE(generic_pll_int_nodes
),
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
,
873 .nodes
= &generic_pll_post_src_nodes
,
874 .num_nodes
= ARRAY_SIZE(generic_pll_post_src_nodes
),
878 .control_reg
= CRF_APB_APLL_CTRL
,
879 .status_reg
= CRF_APB_PLL_STATUS
,
880 .parents
= &((int32_t []) {
885 .nodes
= &generic_pll_system_nodes
,
886 .num_nodes
= ARRAY_SIZE(generic_pll_system_nodes
),
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
),
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
,
911 .nodes
= &generic_pll_pre_src_nodes
,
912 .num_nodes
= ARRAY_SIZE(generic_pll_pre_src_nodes
),
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
),
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 []) {
931 .nodes
= &generic_pll_int_nodes
,
932 .num_nodes
= ARRAY_SIZE(generic_pll_int_nodes
),
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
,
949 .nodes
= &generic_pll_post_src_nodes
,
950 .num_nodes
= ARRAY_SIZE(generic_pll_post_src_nodes
),
954 .control_reg
= CRF_APB_DPLL_CTRL
,
955 .status_reg
= CRF_APB_PLL_STATUS
,
956 .parents
= &((int32_t []) {
961 .nodes
= &generic_pll_system_nodes
,
962 .num_nodes
= ARRAY_SIZE(generic_pll_system_nodes
),
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
),
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
,
987 .nodes
= &generic_pll_pre_src_nodes
,
988 .num_nodes
= ARRAY_SIZE(generic_pll_pre_src_nodes
),
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
),
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 []) {
1007 .nodes
= &generic_pll_int_nodes
,
1008 .num_nodes
= ARRAY_SIZE(generic_pll_int_nodes
),
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
,
1025 .nodes
= &generic_pll_post_src_nodes
,
1026 .num_nodes
= ARRAY_SIZE(generic_pll_post_src_nodes
),
1030 .control_reg
= CRF_APB_VPLL_CTRL
,
1031 .status_reg
= CRF_APB_PLL_STATUS
,
1032 .parents
= &((int32_t []) {
1037 .nodes
= &generic_pll_system_nodes
,
1038 .num_nodes
= ARRAY_SIZE(generic_pll_system_nodes
),
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
),
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
,
1063 .nodes
= &generic_pll_pre_src_nodes
,
1064 .num_nodes
= ARRAY_SIZE(generic_pll_pre_src_nodes
),
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
),
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 []) {
1083 .nodes
= &generic_pll_int_nodes
,
1084 .num_nodes
= ARRAY_SIZE(generic_pll_int_nodes
),
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
,
1101 .nodes
= &generic_pll_post_src_nodes
,
1102 .num_nodes
= ARRAY_SIZE(generic_pll_post_src_nodes
),
1106 .control_reg
= CRL_APB_IOPLL_CTRL
,
1107 .status_reg
= CRF_APB_PLL_STATUS
,
1108 .parents
= &((int32_t []) {
1113 .nodes
= &generic_pll_system_nodes
,
1114 .num_nodes
= ARRAY_SIZE(generic_pll_system_nodes
),
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
),
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
,
1140 .nodes
= &generic_pll_pre_src_nodes
,
1141 .num_nodes
= ARRAY_SIZE(generic_pll_pre_src_nodes
),
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
),
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 []) {
1160 .nodes
= &generic_pll_int_nodes
,
1161 .num_nodes
= ARRAY_SIZE(generic_pll_int_nodes
),
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
,
1178 .nodes
= &generic_pll_post_src_nodes
,
1179 .num_nodes
= ARRAY_SIZE(generic_pll_post_src_nodes
),
1183 .control_reg
= CRL_APB_RPLL_CTRL
,
1184 .status_reg
= CRL_APB_PLL_STATUS
,
1185 .parents
= &((int32_t []) {
1190 .nodes
= &generic_pll_system_nodes
,
1191 .num_nodes
= ARRAY_SIZE(generic_pll_system_nodes
),
1193 /* Peripheral Clocks */
1196 .control_reg
= CRF_APB_ACPU_CTRL
,
1198 .parents
= &((int32_t []) {
1205 .nodes
= &acpu_nodes
,
1206 .num_nodes
= ARRAY_SIZE(acpu_nodes
),
1209 .name
= "dbg_trace",
1210 .control_reg
= CRF_APB_DBG_TRACE_CTRL
,
1212 .parents
= &((int32_t []) {
1219 .nodes
= &generic_mux_div_gate_nodes
,
1220 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1224 .control_reg
= CRF_APB_DBG_FPD_CTRL
,
1226 .parents
= &((int32_t []) {
1233 .nodes
= &generic_mux_div_gate_nodes
,
1234 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1237 .name
= "dbg_tstmp",
1238 .control_reg
= CRF_APB_DBG_TSTMP_CTRL
,
1240 .parents
= &((int32_t []) {
1247 .nodes
= &generic_mux_div_nodes
,
1248 .num_nodes
= ARRAY_SIZE(generic_mux_div_nodes
),
1250 [CLK_DP_VIDEO_REF
] = {
1251 .name
= "dp_video_ref",
1252 .control_reg
= CRF_APB_DP_VIDEO_REF_CTRL
,
1254 .parents
= &((int32_t []) {
1261 .nodes
= &dp_audio_video_ref_nodes
,
1262 .num_nodes
= ARRAY_SIZE(dp_audio_video_ref_nodes
),
1264 [CLK_DP_AUDIO_REF
] = {
1265 .name
= "dp_audio_ref",
1266 .control_reg
= CRF_APB_DP_AUDIO_REF_CTRL
,
1268 .parents
= &((int32_t []) {
1275 .nodes
= &dp_audio_video_ref_nodes
,
1276 .num_nodes
= ARRAY_SIZE(dp_audio_video_ref_nodes
),
1278 [CLK_DP_STC_REF
] = {
1279 .name
= "dp_stc_ref",
1280 .control_reg
= CRF_APB_DP_STC_REF_CTRL
,
1282 .parents
= &((int32_t []) {
1289 .nodes
= &generic_mux_div_div_gate_nodes
,
1290 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1293 .name
= "dpdma_ref",
1294 .control_reg
= CRF_APB_DPDMA_REF_CTRL
,
1296 .parents
= &((int32_t []) {
1303 .nodes
= &generic_mux_div_gate_nodes
,
1304 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1308 .control_reg
= CRF_APB_DDR_CTRL
,
1310 .parents
= &((int32_t []) {
1315 .nodes
= &ddr_nodes
,
1316 .num_nodes
= ARRAY_SIZE(ddr_nodes
),
1320 .control_reg
= CRF_APB_GPU_REF_CTRL
,
1322 .parents
= &((int32_t []) {
1329 .nodes
= &generic_mux_div_gate_nodes
,
1330 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1334 .control_reg
= CRF_APB_SATA_REF_CTRL
,
1336 .parents
= &((int32_t []) {
1343 .nodes
= &generic_mux_div_gate_nodes
,
1344 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1348 .control_reg
= CRF_APB_PCIE_REF_CTRL
,
1350 .parents
= &((int32_t []) {
1357 .nodes
= &generic_mux_div_gate_nodes
,
1358 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1362 .control_reg
= CRF_APB_GDMA_REF_CTRL
,
1364 .parents
= &((int32_t []) {
1371 .nodes
= &generic_mux_div_gate_nodes
,
1372 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1374 [CLK_GTGREF0_REF
] = {
1375 .name
= "gtgref0_ref",
1376 .control_reg
= CRF_APB_GTGREF0_REF_CTRL
,
1378 .parents
= &((int32_t []) {
1385 .nodes
= &generic_mux_div_gate_nodes
,
1386 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1388 [CLK_TOPSW_MAIN
] = {
1389 .name
= "topsw_main",
1390 .control_reg
= CRF_APB_TOPSW_MAIN_CTRL
,
1392 .parents
= &((int32_t []) {
1399 .nodes
= &generic_mux_div_unused_gate_nodes
,
1400 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1402 [CLK_TOPSW_LSBUS
] = {
1403 .name
= "topsw_lsbus",
1404 .control_reg
= CRF_APB_TOPSW_LSBUS_CTRL
,
1406 .parents
= &((int32_t []) {
1413 .nodes
= &generic_mux_div_unused_gate_nodes
,
1414 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1416 [CLK_IOU_SWITCH
] = {
1417 .name
= "iou_switch",
1418 .control_reg
= CRL_APB_IOU_SWITCH_CTRL
,
1420 .parents
= &((int32_t []) {
1427 .nodes
= &generic_mux_div_unused_gate_nodes
,
1428 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1432 .control_reg
= CRL_APB_GEM0_REF_CTRL
,
1434 .parents
= &((int32_t []) {
1441 .nodes
= &gem_nodes
,
1442 .num_nodes
= ARRAY_SIZE(gem_nodes
),
1446 .control_reg
= CRL_APB_GEM1_REF_CTRL
,
1448 .parents
= &((int32_t []) {
1455 .nodes
= &gem_nodes
,
1456 .num_nodes
= ARRAY_SIZE(gem_nodes
),
1460 .control_reg
= CRL_APB_GEM2_REF_CTRL
,
1462 .parents
= &((int32_t []) {
1469 .nodes
= &gem_nodes
,
1470 .num_nodes
= ARRAY_SIZE(gem_nodes
),
1474 .control_reg
= CRL_APB_GEM3_REF_CTRL
,
1476 .parents
= &((int32_t []) {
1483 .nodes
= &gem_nodes
,
1484 .num_nodes
= ARRAY_SIZE(gem_nodes
),
1486 [CLK_USB0_BUS_REF
] = {
1487 .name
= "usb0_bus_ref",
1488 .control_reg
= CRL_APB_USB0_BUS_REF_CTRL
,
1490 .parents
= &((int32_t []) {
1497 .nodes
= &usb_nodes
,
1498 .num_nodes
= ARRAY_SIZE(usb_nodes
),
1500 [CLK_USB1_BUS_REF
] = {
1501 .name
= "usb1_bus_ref",
1502 .control_reg
= CRL_APB_USB1_BUS_REF_CTRL
,
1504 .parents
= &((int32_t []) {
1511 .nodes
= &usb_nodes
,
1512 .num_nodes
= ARRAY_SIZE(usb_nodes
),
1514 [CLK_USB3_DUAL_REF
] = {
1515 .name
= "usb3_dual_ref",
1516 .control_reg
= CRL_APB_USB3_DUAL_REF_CTRL
,
1518 .parents
= &((int32_t []) {
1525 .nodes
= &usb_nodes
,
1526 .num_nodes
= ARRAY_SIZE(usb_nodes
),
1530 .control_reg
= CRL_APB_QSPI_REF_CTRL
,
1532 .parents
= &((int32_t []) {
1539 .nodes
= &generic_mux_div_div_gate_nodes
,
1540 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1543 .name
= "sdio0_ref",
1544 .control_reg
= CRL_APB_SDIO0_REF_CTRL
,
1546 .parents
= &((int32_t []) {
1553 .nodes
= &generic_mux_div_div_gate_nodes
,
1554 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1557 .name
= "sdio1_ref",
1558 .control_reg
= CRL_APB_SDIO1_REF_CTRL
,
1560 .parents
= &((int32_t []) {
1567 .nodes
= &generic_mux_div_div_gate_nodes
,
1568 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1571 .name
= "uart0_ref",
1572 .control_reg
= CRL_APB_UART0_REF_CTRL
,
1574 .parents
= &((int32_t []) {
1581 .nodes
= &generic_mux_div_div_gate_nodes
,
1582 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1585 .name
= "uart1_ref",
1586 .control_reg
= CRL_APB_UART1_REF_CTRL
,
1588 .parents
= &((int32_t []) {
1595 .nodes
= &generic_mux_div_div_gate_nodes
,
1596 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1600 .control_reg
= CRL_APB_SPI0_REF_CTRL
,
1602 .parents
= &((int32_t []) {
1609 .nodes
= &generic_mux_div_div_gate_nodes
,
1610 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1614 .control_reg
= CRL_APB_SPI1_REF_CTRL
,
1616 .parents
= &((int32_t []) {
1623 .nodes
= &generic_mux_div_div_gate_nodes
,
1624 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1628 .control_reg
= CRL_APB_CAN0_REF_CTRL
,
1630 .parents
= &((int32_t []) {
1637 .nodes
= &generic_mux_div_div_gate_nodes
,
1638 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1642 .control_reg
= CRL_APB_CAN1_REF_CTRL
,
1644 .parents
= &((int32_t []) {
1651 .nodes
= &generic_mux_div_div_gate_nodes
,
1652 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1656 .control_reg
= CRL_APB_NAND_REF_CTRL
,
1658 .parents
= &((int32_t []) {
1665 .nodes
= &generic_mux_div_div_gate_nodes
,
1666 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1668 [CLK_GEM_TSU_REF
] = {
1669 .name
= "gem_tsu_ref",
1670 .control_reg
= CRL_APB_GEM_TSU_REF_CTRL
,
1672 .parents
= &((int32_t []) {
1679 .nodes
= &generic_mux_div_div_gate_nodes
,
1680 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1684 .control_reg
= CRL_APB_DLL_REF_CTRL
,
1686 .parents
= &((int32_t []) {
1691 .nodes
= &dll_ref_nodes
,
1692 .num_nodes
= ARRAY_SIZE(dll_ref_nodes
),
1696 .control_reg
= CRL_APB_ADMA_REF_CTRL
,
1698 .parents
= &((int32_t []) {
1705 .nodes
= &generic_mux_div_gate_nodes
,
1706 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1710 .control_reg
= CRL_APB_DBG_LPD_CTRL
,
1712 .parents
= &((int32_t []) {
1719 .nodes
= &generic_mux_div_gate_nodes
,
1720 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1724 .control_reg
= CRL_APB_CPU_R5_CTRL
,
1726 .parents
= &((int32_t []) {
1733 .nodes
= &generic_mux_div_unused_gate_nodes
,
1734 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1738 .control_reg
= CRL_APB_CSU_PLL_CTRL
,
1740 .parents
= &((int32_t []) {
1747 .nodes
= &generic_mux_div_gate_nodes
,
1748 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1752 .control_reg
= CRL_APB_PCAP_CTRL
,
1754 .parents
= &((int32_t []) {
1761 .nodes
= &generic_mux_div_gate_nodes
,
1762 .num_nodes
= ARRAY_SIZE(generic_mux_div_gate_nodes
),
1765 .name
= "lpd_lsbus",
1766 .control_reg
= CRL_APB_LPD_LSBUS_CTRL
,
1768 .parents
= &((int32_t []) {
1775 .nodes
= &generic_mux_div_unused_gate_nodes
,
1776 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1778 [CLK_LPD_SWITCH
] = {
1779 .name
= "lpd_switch",
1780 .control_reg
= CRL_APB_LPD_SWITCH_CTRL
,
1782 .parents
= &((int32_t []) {
1789 .nodes
= &generic_mux_div_unused_gate_nodes
,
1790 .num_nodes
= ARRAY_SIZE(generic_mux_div_unused_gate_nodes
),
1794 .control_reg
= CRL_APB_I2C0_REF_CTRL
,
1796 .parents
= &((int32_t []) {
1803 .nodes
= &generic_mux_div_div_gate_nodes
,
1804 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1808 .control_reg
= CRL_APB_I2C1_REF_CTRL
,
1810 .parents
= &((int32_t []) {
1817 .nodes
= &generic_mux_div_div_gate_nodes
,
1818 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1820 [CLK_TIMESTAMP_REF
] = {
1821 .name
= "timestamp_ref",
1822 .control_reg
= CRL_APB_TIMESTAMP_REF_CTRL
,
1824 .parents
= &((int32_t []) {
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
,
1835 .nodes
= ×tamp_ref_nodes
,
1836 .num_nodes
= ARRAY_SIZE(timestamp_ref_nodes
),
1840 .control_reg
= CRL_APB_PL0_REF_CTRL
,
1842 .parents
= &((int32_t []) {
1850 .num_nodes
= ARRAY_SIZE(pl_nodes
),
1854 .control_reg
= CRL_APB_PL1_REF_CTRL
,
1856 .parents
= &((int32_t []) {
1864 .num_nodes
= ARRAY_SIZE(pl_nodes
),
1868 .control_reg
= CRL_APB_PL2_REF_CTRL
,
1870 .parents
= &((int32_t []) {
1878 .num_nodes
= ARRAY_SIZE(pl_nodes
),
1882 .control_reg
= CRL_APB_PL3_REF_CTRL
,
1884 .parents
= &((int32_t []) {
1892 .num_nodes
= ARRAY_SIZE(pl_nodes
),
1896 .control_reg
= CRL_APB_AMS_REF_CTRL
,
1898 .parents
= &((int32_t []) {
1905 .nodes
= &generic_mux_div_div_gate_nodes
,
1906 .num_nodes
= ARRAY_SIZE(generic_mux_div_div_gate_nodes
),
1908 [CLK_IOPLL_TO_FPD
] = {
1909 .name
= "iopll_to_fpd",
1910 .control_reg
= CRL_APB_IOPLL_TO_FPD_CTRL
,
1912 .parents
= &((int32_t []) {CLK_IOPLL
, CLK_NA_PARENT
}),
1913 .nodes
= &generic_domain_crossing_nodes
,
1914 .num_nodes
= ARRAY_SIZE(generic_domain_crossing_nodes
),
1916 [CLK_RPLL_TO_FPD
] = {
1917 .name
= "rpll_to_fpd",
1918 .control_reg
= CRL_APB_RPLL_TO_FPD_CTRL
,
1920 .parents
= &((int32_t []) {CLK_RPLL
, CLK_NA_PARENT
}),
1921 .nodes
= &rpll_to_fpd_nodes
,
1922 .num_nodes
= ARRAY_SIZE(rpll_to_fpd_nodes
),
1924 [CLK_APLL_TO_LPD
] = {
1925 .name
= "apll_to_lpd",
1926 .control_reg
= CRF_APB_APLL_TO_LPD_CTRL
,
1928 .parents
= &((int32_t []) {CLK_APLL
, CLK_NA_PARENT
}),
1929 .nodes
= &generic_domain_crossing_nodes
,
1930 .num_nodes
= ARRAY_SIZE(generic_domain_crossing_nodes
),
1932 [CLK_DPLL_TO_LPD
] = {
1933 .name
= "dpll_to_lpd",
1934 .control_reg
= CRF_APB_DPLL_TO_LPD_CTRL
,
1936 .parents
= &((int32_t []) {CLK_DPLL
, CLK_NA_PARENT
}),
1937 .nodes
= &generic_domain_crossing_nodes
,
1938 .num_nodes
= ARRAY_SIZE(generic_domain_crossing_nodes
),
1940 [CLK_VPLL_TO_LPD
] = {
1941 .name
= "vpll_to_lpd",
1942 .control_reg
= CRF_APB_VPLL_TO_LPD_CTRL
,
1944 .parents
= &((int32_t []) {CLK_VPLL
, CLK_NA_PARENT
}),
1945 .nodes
= &generic_domain_crossing_nodes
,
1946 .num_nodes
= ARRAY_SIZE(generic_domain_crossing_nodes
),
1949 * This clock control requires different registers for mux and gate.
1950 * Use control and status registers for the same.
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
,
1961 .nodes
= &gem0_tx_nodes
,
1962 .num_nodes
= ARRAY_SIZE(gem0_tx_nodes
),
1965 * This clock control requires different registers for mux and gate.
1966 * Use control and status registers for the same.
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
,
1977 .nodes
= &gem1_tx_nodes
,
1978 .num_nodes
= ARRAY_SIZE(gem1_tx_nodes
),
1981 * This clock control requires different registers for mux and gate.
1982 * Use control and status registers for the same.
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
,
1993 .nodes
= &gem2_tx_nodes
,
1994 .num_nodes
= ARRAY_SIZE(gem2_tx_nodes
),
1997 * This clock control requires different registers for mux and gate.
1998 * Use control and status registers for the same.
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
,
2009 .nodes
= &gem3_tx_nodes
,
2010 .num_nodes
= ARRAY_SIZE(gem3_tx_nodes
),
2013 .name
= "acpu_half",
2014 .control_reg
= CRF_APB_ACPU_CTRL
,
2016 .parents
= &((int32_t []) {
2017 CLK_ACPU
| PARENT_CLK_NODE2
<< CLK_PARENTS_ID_LEN
,
2020 .nodes
= &acpu_half_nodes
,
2021 .num_nodes
= ARRAY_SIZE(acpu_half_nodes
),
2025 .control_reg
= FPD_SLCR_WDT_CLK_SEL
,
2027 .parents
= &((int32_t []) {
2029 EXT_CLK_SWDT0
| CLK_EXTERNAL_PARENT
,
2032 .nodes
= &wdt_nodes
,
2033 .num_nodes
= ARRAY_SIZE(wdt_nodes
),
2035 [CLK_GPU_PP0_REF
] = {
2036 .name
= "gpu_pp0_ref",
2037 .control_reg
= CRF_APB_GPU_REF_CTRL
,
2039 .parents
= &((int32_t []) {
2040 CLK_GPU_REF
| PARENT_CLK_NODE2
<< CLK_PARENTS_ID_LEN
,
2043 .nodes
= &gpu_pp0_nodes
,
2044 .num_nodes
= ARRAY_SIZE(gpu_pp0_nodes
),
2046 [CLK_GPU_PP1_REF
] = {
2047 .name
= "gpu_pp1_ref",
2048 .control_reg
= CRF_APB_GPU_REF_CTRL
,
2050 .parents
= &((int32_t []) {
2051 CLK_GPU_REF
| PARENT_CLK_NODE2
<< CLK_PARENTS_ID_LEN
,
2054 .nodes
= &gpu_pp1_nodes
,
2055 .num_nodes
= ARRAY_SIZE(gpu_pp1_nodes
),
2059 .control_reg
= IOU_SLCR_GEM_CLK_CTRL
,
2061 .parents
= &((int32_t []) {
2064 EXT_CLK_MIO26
| CLK_EXTERNAL_PARENT
,
2065 EXT_CLK_MIO50_OR_MIO51
| CLK_EXTERNAL_PARENT
,
2068 .nodes
= &gem_tsu_nodes
,
2069 .num_nodes
= ARRAY_SIZE(gem_tsu_nodes
),
2071 [CLK_CPU_R5_CORE
] = {
2072 .name
= "cpu_r5_core",
2073 .control_reg
= CRL_APB_CPU_R5_CTRL
,
2075 .parents
= &((int32_t []) {
2076 CLK_CPU_R5
| PARENT_CLK_NODE2
<< CLK_PARENTS_ID_LEN
,
2080 .nodes
= &cpu_r5_core_nodes
,
2081 .num_nodes
= ARRAY_SIZE(cpu_r5_core_nodes
),
2085 .control_reg
= IOU_SLCR_CAN_MIO_CTRL
,
2087 .parents
= &can_mio_parents
,
2088 .nodes
= &can0_mio_nodes
,
2089 .num_nodes
= ARRAY_SIZE(can0_mio_nodes
),
2093 .control_reg
= IOU_SLCR_CAN_MIO_CTRL
,
2095 .parents
= &can_mio_parents
,
2096 .nodes
= &can1_mio_nodes
,
2097 .num_nodes
= ARRAY_SIZE(can1_mio_nodes
),
2101 .control_reg
= IOU_SLCR_CAN_MIO_CTRL
,
2103 .parents
= &((int32_t []) {
2108 .nodes
= &can0_nodes
,
2109 .num_nodes
= ARRAY_SIZE(can0_nodes
),
2113 .control_reg
= IOU_SLCR_CAN_MIO_CTRL
,
2115 .parents
= &((int32_t []) {
2120 .nodes
= &can1_nodes
,
2121 .num_nodes
= ARRAY_SIZE(can1_nodes
),
2125 static struct pm_ext_clock ext_clocks
[] = {
2126 [EXT_CLK_INDEX(EXT_CLK_PSS_REF
)] = {
2127 .name
= "pss_ref_clk",
2129 [EXT_CLK_INDEX(EXT_CLK_VIDEO
)] = {
2130 .name
= "video_clk",
2132 [EXT_CLK_INDEX(EXT_CLK_PSS_ALT_REF
)] = {
2133 .name
= "pss_alt_ref_clk",
2135 [EXT_CLK_INDEX(EXT_CLK_AUX_REF
)] = {
2136 .name
= "aux_ref_clk",
2138 [EXT_CLK_INDEX(EXT_CLK_GT_CRX_REF
)] = {
2139 .name
= "video_clk",
2141 [EXT_CLK_INDEX(EXT_CLK_SWDT0
)] = {
2142 .name
= "swdt0_ext_clk",
2144 [EXT_CLK_INDEX(EXT_CLK_SWDT1
)] = {
2145 .name
= "swdt1_ext_clk",
2147 [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO
)] = {
2148 .name
= "gem0_emio_clk",
2150 [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO
)] = {
2151 .name
= "gem1_emio_clk",
2153 [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO
)] = {
2154 .name
= "gem2_emio_clk",
2156 [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO
)] = {
2157 .name
= "gem3_emio_clk",
2159 [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51
)] = {
2160 .name
= "mio_clk_50_51",
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),
2242 /* Array of clock which are invalid for this variant */
2243 static uint32_t pm_clk_invalid_list
[] = {CLK_USB0
, CLK_USB1
, CLK_CSU_SPB
};
2246 * pm_clock_valid - Check if clock is valid or not
2247 * @clock_id Id of the clock to be queried
2249 * This function is used to check if given clock is valid
2250 * or not for the chip variant.
2252 * List of invalid clocks are maintained in array list for
2253 * different variants.
2255 * Return: Returns 1 if clock is valid else 0.
2257 static bool pm_clock_valid(unsigned int clock_id
)
2261 for (i
= 0; i
< ARRAY_SIZE(pm_clk_invalid_list
); i
++)
2262 if (pm_clk_invalid_list
[i
] == clock_id
)
2269 * pm_clock_type - Get clock's type
2270 * @clock_id Id of the clock to be queried
2272 * This function is used to check type of clock (OUTPUT/EXTERNAL).
2274 * Return: Returns type of clock (OUTPUT/EXTERNAL).
2276 static unsigned int pm_clock_type(unsigned int clock_id
)
2278 return (clock_id
< CLK_MAX_OUTPUT_CLK
) ?
2279 CLK_TYPE_OUTPUT
: CLK_TYPE_EXTERNAL
;
2283 * pm_api_clock_get_num_clocks() - PM call to request number of clocks
2284 * @nclocks Number of clocks
2286 * This function is used by master to get number of clocks.
2288 * @return Returns success.
2290 enum pm_ret_status
pm_api_clock_get_num_clocks(unsigned int *nclocks
)
2294 return PM_RET_SUCCESS
;
2298 * pm_api_clock_get_name() - PM call to request a clock's name
2299 * @clock_id Clock ID
2300 * @name Name of clock (max 16 bytes)
2302 * This function is used by master to get nmae of clock specified
2303 * by given clock ID.
2305 * @return Returns success. In case of error, name data is 0.
2307 enum pm_ret_status
pm_api_clock_get_name(unsigned int clock_id
, char *name
)
2309 if (clock_id
== CLK_MAX
)
2310 memcpy(name
, END_OF_CLK
, CLK_NAME_LEN
);
2311 else if (!pm_clock_valid(clock_id
))
2312 memset(name
, 0, CLK_NAME_LEN
);
2313 else if (clock_id
< CLK_MAX_OUTPUT_CLK
)
2314 memcpy(name
, clocks
[clock_id
].name
, CLK_NAME_LEN
);
2316 memcpy(name
, ext_clocks
[clock_id
- CLK_MAX_OUTPUT_CLK
].name
,
2319 return PM_RET_SUCCESS
;
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
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.
2333 * @return Returns status, either success or error+reason
2335 enum pm_ret_status
pm_api_clock_get_topology(unsigned int clock_id
,
2339 struct pm_clock_node
*clock_nodes
;
2343 if (!pm_clock_valid(clock_id
))
2344 return PM_RET_ERROR_ARGS
;
2346 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2347 return PM_RET_ERROR_NOTSUPPORTED
;
2350 memset(topology
, 0, CLK_TOPOLOGY_PAYLOAD_LEN
);
2351 clock_nodes
= *clocks
[clock_id
].nodes
;
2352 num_nodes
= clocks
[clock_id
].num_nodes
;
2354 /* Skip parent till index */
2355 if (index
>= num_nodes
)
2356 return PM_RET_SUCCESS
;
2358 for (i
= 0; i
< 3U; i
++) {
2359 if ((index
+ i
) == num_nodes
)
2361 topology
[i
] = clock_nodes
[index
+ i
].type
;
2362 topology
[i
] |= clock_nodes
[index
+ i
].clkflags
<<
2364 topology
[i
] |= clock_nodes
[index
+ i
].typeflags
<<
2365 CLK_TYPEFLAGS_SHIFT
;
2368 return PM_RET_SUCCESS
;
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
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.
2381 * @return Returns status, either success or error+reason
2383 enum pm_ret_status
pm_api_clock_get_fixedfactor_params(unsigned int clock_id
,
2387 struct pm_clock_node
*clock_nodes
;
2389 unsigned int type
, i
;
2391 if (!pm_clock_valid(clock_id
))
2392 return PM_RET_ERROR_ARGS
;
2394 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2395 return PM_RET_ERROR_NOTSUPPORTED
;
2397 clock_nodes
= *clocks
[clock_id
].nodes
;
2398 num_nodes
= clocks
[clock_id
].num_nodes
;
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
;
2409 /* Clock is not fixed clock */
2411 return PM_RET_ERROR_ARGS
;
2413 return PM_RET_SUCCESS
;
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
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.
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
2431 * @return Returns status, either success or error+reason
2433 enum pm_ret_status
pm_api_clock_get_parents(unsigned int clock_id
,
2438 int32_t *clk_parents
;
2440 if (!pm_clock_valid(clock_id
))
2441 return PM_RET_ERROR_ARGS
;
2443 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2444 return PM_RET_ERROR_NOTSUPPORTED
;
2446 clk_parents
= *clocks
[clock_id
].parents
;
2447 if (clk_parents
== NULL
)
2448 return PM_RET_ERROR_ARGS
;
2450 memset(parents
, 0, CLK_PARENTS_PAYLOAD_LEN
);
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
;
2457 for (i
= 0; i
< 3; i
++) {
2458 parents
[i
] = clk_parents
[index
+ i
];
2459 if (clk_parents
[index
+ i
] == CLK_NA_PARENT
)
2463 return PM_RET_SUCCESS
;
2467 * pm_api_clock_get_attributes() - PM call to request a clock's attributes
2468 * @clock_id Clock ID
2469 * @attr Clock attributes
2471 * This function is used by master to get clock's attributes
2472 * (e.g. valid, clock type, etc).
2474 * @return Returns status, either success or error+reason
2476 enum pm_ret_status
pm_api_clock_get_attributes(unsigned int clock_id
,
2479 if (clock_id
>= CLK_MAX
)
2480 return PM_RET_ERROR_ARGS
;
2482 /* Clock valid bit */
2483 *attr
= pm_clock_valid(clock_id
);
2485 /* Clock type (Output/External) */
2486 *attr
|= (pm_clock_type(clock_id
) << CLK_TYPE_SHIFT
);
2488 return PM_RET_SUCCESS
;
2492 * pll_get_lockbit() - Returns lockbit index for pll id
2493 * @pll_id: Id of the pll
2495 * This function return the PLL_LOCKED bit index in
2496 * pll status register accosiated with given pll id.
2498 * Return: Returns bit index
2500 static int pll_get_lockbit(unsigned int pll_id
)
2517 * pm_api_pll_bypass_and_reset() - Bypass and reset PLL
2518 * @clock_id: Id of the PLL
2520 * This function is to bypass and reset PLL.
2522 static inline enum pm_ret_status
2523 pm_api_pll_bypass_and_reset(unsigned int clock_id
, unsigned int flag
)
2525 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2526 unsigned int reg
, val
;
2529 reg
= clocks
[clock_id
].control_reg
;
2531 if (flag
& CLK_PLL_RESET_ASSERT
) {
2532 ret
= pm_mmio_write(reg
, PLLCTRL_BP_MASK
, PLLCTRL_BP_MASK
);
2533 if (ret
!= PM_RET_SUCCESS
)
2535 ret
= pm_mmio_write(reg
, PLLCTRL_RESET_MASK
,
2536 PLLCTRL_RESET_MASK
);
2537 if (ret
!= PM_RET_SUCCESS
)
2540 if (flag
& CLK_PLL_RESET_RELEASE
) {
2541 ret
= pm_mmio_write(reg
, PLLCTRL_RESET_MASK
,
2542 ~PLLCTRL_RESET_MASK
);
2543 if (ret
!= PM_RET_SUCCESS
)
2546 lockbit
= pll_get_lockbit(clock_id
);
2548 ret
= pm_mmio_read(clocks
[clock_id
].status_reg
, &val
);
2549 if (ret
!= PM_RET_SUCCESS
)
2551 } while ((lockbit
>= 0) && !(val
& (1 << lockbit
)));
2553 ret
= pm_mmio_write(reg
, PLLCTRL_BP_MASK
,
2554 ~(unsigned int)PLLCTRL_BP_MASK
);
2560 * pm_api_clk_enable_disable() - Enable/Disable the clock for given id
2561 * @clock_id: Id of the clock to be enabled
2562 * @enable: Enable(1)/Disable(0)
2564 * This function is to enable/disable the clock which is not PLL.
2566 * Return: Returns status, either success or error+reason.
2568 static enum pm_ret_status
pm_api_clk_enable_disable(unsigned int clock_id
,
2569 unsigned int enable
)
2571 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2572 struct pm_clock_node
*nodes
= *clocks
[clock_id
].nodes
;
2573 uint8_t num_nodes
= clocks
[clock_id
].num_nodes
;
2574 unsigned int reg
, val
;
2576 uint8_t offset
= NA_SHIFT
, width
= NA_WIDTH
;
2578 if (clock_id
== CLK_GEM0_TX
|| clock_id
== CLK_GEM1_TX
||
2579 clock_id
== CLK_GEM2_TX
|| clock_id
== CLK_GEM3_TX
)
2580 reg
= clocks
[clock_id
].status_reg
;
2582 reg
= clocks
[clock_id
].control_reg
;
2584 for (i
= 0; i
< num_nodes
; i
++) {
2585 if (nodes
->type
== TYPE_GATE
) {
2586 offset
= nodes
->offset
;
2587 width
= nodes
->width
;
2592 if (width
== NA_WIDTH
)
2593 return PM_RET_ERROR_NOTSUPPORTED
;
2595 ret
= pm_mmio_read(reg
, &val
);
2596 if (ret
!= PM_RET_SUCCESS
)
2598 if ((val
& BIT_MASK(offset
, width
)) == enable
)
2599 return PM_RET_SUCCESS
;
2602 val
&= ~(BIT_MASK(offset
, width
));
2604 val
|= BIT_MASK(offset
, width
);
2606 ret
= pm_mmio_write(reg
, BIT_MASK(offset
, width
), val
);
2612 * pm_api_clock_enable() - Enable the clock for given id
2613 * @clock_id: Id of the clock to be enabled
2615 * This function is used by master to enable the clock
2616 * including peripherals and PLL clocks.
2618 * Return: Returns status, either success or error+reason.
2620 enum pm_ret_status
pm_api_clock_enable(unsigned int clock_id
)
2622 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2624 if (!pm_clock_valid(clock_id
))
2625 return PM_RET_ERROR_ARGS
;
2627 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2628 return PM_RET_ERROR_NOTSUPPORTED
;
2631 * PLL type clock should not enable explicitly.
2632 * It is done by FSBL on boot-up and by PMUFW whenever required.
2634 if (!ISPLL(clock_id
))
2635 ret
= pm_api_clk_enable_disable(clock_id
, 1);
2641 * pm_api_clock_disable - Disable the clock for given id
2642 * @clock_id Id of the clock to be disable
2644 * This function is used by master to disable the clock
2645 * including peripherals and PLL clocks.
2647 * Return: Returns status, either success or error+reason.
2650 enum pm_ret_status
pm_api_clock_disable(unsigned int clock_id
)
2652 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2654 if (!pm_clock_valid(clock_id
))
2655 return PM_RET_ERROR_ARGS
;
2657 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2658 return PM_RET_ERROR_NOTSUPPORTED
;
2661 * PLL type clock should not be disabled explicitly.
2662 * It is done by PMUFW if required.
2664 if (!ISPLL(clock_id
))
2665 ret
= pm_api_clk_enable_disable(clock_id
, 0);
2671 * pm_api_get_pll_state() - Get state of PLL
2672 * @clock_id Id of the PLL
2673 * @state State of PLL(1: Enable, 0: Reset)
2675 * This function is to check state of PLL.
2677 static inline enum pm_ret_status
pm_api_get_pll_state(unsigned int clock_id
,
2678 unsigned int *state
)
2680 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2681 unsigned int reg
, val
;
2683 reg
= clocks
[clock_id
].control_reg
;
2685 ret
= pm_mmio_read(reg
, &val
);
2688 * 1 - PLL is enabled
2689 * 0 - PLL is in reset state
2691 *state
= !(val
& PLLCTRL_RESET_MASK
);
2696 * pm_api_get_clk_state() - Get the state of clock for given id
2697 * @clock_id: Id of the clock to be enabled
2698 * @state: Enable(1)/Disable(0)
2700 * This function is to get state of the clock which is not PLL.
2702 * Return: Returns status, either success or error+reason.
2704 static enum pm_ret_status
pm_api_get_clk_state(unsigned int clock_id
,
2705 unsigned int *state
)
2707 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2708 struct pm_clock_node
*nodes
= *clocks
[clock_id
].nodes
;
2709 uint8_t num_nodes
= clocks
[clock_id
].num_nodes
;
2710 unsigned int reg
, val
;
2712 uint8_t offset
= NA_SHIFT
, width
= NA_WIDTH
;
2714 reg
= clocks
[clock_id
].control_reg
;
2716 for (i
= 0; i
< num_nodes
; i
++) {
2717 if (nodes
->type
== TYPE_GATE
) {
2718 offset
= nodes
->offset
;
2719 width
= nodes
->width
;
2723 if (width
== NA_WIDTH
)
2724 return PM_RET_ERROR_NOTSUPPORTED
;
2726 ret
= pm_mmio_read(reg
, &val
);
2727 *state
= (val
& BIT_MASK(offset
, width
)) >> offset
;
2733 * pm_api_clock_getstate - Get the clock state for given id
2734 * @clock_id Id of the clock to be queried
2735 * @state 1/0 (Enabled/Disabled)
2737 * This function is used by master to get the state of clock
2738 * including peripherals and PLL clocks.
2740 * Return: Returns status, either success or error+reason.
2742 enum pm_ret_status
pm_api_clock_getstate(unsigned int clock_id
,
2743 unsigned int *state
)
2745 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2747 if (!pm_clock_valid(clock_id
))
2748 return PM_RET_ERROR_ARGS
;
2750 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2751 return PM_RET_ERROR_NOTSUPPORTED
;
2753 if (ISPLL(clock_id
))
2754 ret
= pm_api_get_pll_state(clock_id
, state
);
2756 ret
= pm_api_get_clk_state(clock_id
, state
);
2761 static enum pm_ret_status
pm_api_clk_set_divider(unsigned int clock_id
,
2764 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2765 struct pm_clock_node
*nodes
;
2767 uint16_t div1
, div2
;
2768 unsigned int reg
, mask
= 0, val
= 0, i
;
2769 uint8_t div1_width
= NA_WIDTH
, div1_offset
= NA_SHIFT
;
2770 uint8_t div2_width
= NA_WIDTH
, div2_offset
= NA_SHIFT
;
2772 div1
= (uint16_t)(divider
& 0xFFFFU
);
2773 div2
= (uint16_t)((divider
>> 16) & 0xFFFFU
);
2775 reg
= clocks
[clock_id
].control_reg
;
2777 nodes
= *clocks
[clock_id
].nodes
;
2778 num_nodes
= clocks
[clock_id
].num_nodes
;
2779 for (i
= 0; i
< num_nodes
; i
++) {
2780 if (nodes
->type
== TYPE_DIV1
) {
2781 div1_offset
= nodes
->offset
;
2782 div1_width
= nodes
->width
;
2784 if (nodes
->type
== TYPE_DIV2
) {
2785 div2_offset
= nodes
->offset
;
2786 div2_width
= nodes
->width
;
2791 if (div1
!= (uint16_t)-1) {
2792 if (div1_width
== NA_WIDTH
)
2793 return PM_RET_ERROR_NOTSUPPORTED
;
2794 val
|= div1
<< div1_offset
;
2795 mask
|= BIT_MASK(div1_offset
, div1_width
);
2797 if (div2
!= (uint16_t)-1) {
2798 if (div2_width
== NA_WIDTH
)
2799 return PM_RET_ERROR_NOTSUPPORTED
;
2800 val
|= div2
<< div2_offset
;
2801 mask
|= BIT_MASK(div2_offset
, div2_width
);
2803 ret
= pm_mmio_write(reg
, mask
, val
);
2808 static enum pm_ret_status
pm_api_pll_set_divider(unsigned int clock_id
,
2809 unsigned int divider
)
2811 unsigned int reg
= clocks
[clock_id
].control_reg
;
2812 enum pm_ret_status ret
;
2814 pm_api_pll_bypass_and_reset(clock_id
, CLK_PLL_RESET_ASSERT
);
2815 ret
= pm_mmio_write(reg
, PLL_FBDIV_MASK
, divider
<< PLL_FBDIV_SHIFT
);
2816 pm_api_pll_bypass_and_reset(clock_id
, CLK_PLL_RESET_RELEASE
);
2822 * pm_api_clock_setdivider - Set the clock divider for given id
2823 * @clock_id Id of the clock
2824 * @divider Divider value
2826 * This function is used by master to set divider for any clock
2827 * to achieve desired rate.
2829 * Return: Returns status, either success or error+reason.
2831 enum pm_ret_status
pm_api_clock_setdivider(unsigned int clock_id
,
2832 unsigned int divider
)
2834 enum pm_ret_status ret
;
2836 if (!pm_clock_valid(clock_id
))
2837 return PM_RET_ERROR_ARGS
;
2839 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2840 return PM_RET_ERROR_NOTSUPPORTED
;
2842 if (ISPLL(clock_id
))
2843 ret
= pm_api_pll_set_divider(clock_id
, divider
);
2845 ret
= pm_api_clk_set_divider(clock_id
, divider
);
2850 static enum pm_ret_status
pm_api_clk_get_divider(unsigned int clock_id
,
2853 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2854 struct pm_clock_node
*nodes
;
2856 unsigned int reg
, val
, i
, div1
= 0, div2
= 0;
2857 uint8_t div1_width
= NA_WIDTH
, div1_offset
= NA_SHIFT
;
2858 uint8_t div2_width
= NA_WIDTH
, div2_offset
= NA_SHIFT
;
2860 reg
= clocks
[clock_id
].control_reg
;
2862 nodes
= *clocks
[clock_id
].nodes
;
2863 num_nodes
= clocks
[clock_id
].num_nodes
;
2864 for (i
= 0; i
< num_nodes
; i
++) {
2865 if (nodes
->type
== TYPE_DIV1
) {
2866 div1_offset
= nodes
->offset
;
2867 div1_width
= nodes
->width
;
2869 if (nodes
->type
== TYPE_DIV2
) {
2870 div2_offset
= nodes
->offset
;
2871 div2_width
= nodes
->width
;
2876 ret
= pm_mmio_read(reg
, &val
);
2878 if (div1_width
== NA_WIDTH
)
2879 return PM_RET_ERROR_ARGS
;
2881 div1
= (val
& BIT_MASK(div1_offset
, div1_width
)) >> div1_offset
;
2883 if (div2_width
!= NA_WIDTH
)
2884 div2
= (val
& BIT_MASK(div2_offset
, div2_width
)) >> div2_offset
;
2886 *divider
= div1
| (div2
<< 16);
2891 static enum pm_ret_status
pm_api_pll_get_divider(unsigned int clock_id
,
2892 unsigned int *divider
)
2894 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2895 unsigned int reg
, val
;
2897 reg
= clocks
[clock_id
].control_reg
;
2899 ret
= pm_mmio_read(reg
, &val
);
2900 *divider
= (val
& PLL_FBDIV_MASK
) >> PLL_FBDIV_SHIFT
;
2906 * pm_api_clock_getdivider - Get the clock divider for given id
2907 * @clock_id Id of the clock
2908 * @divider Divider value
2910 * This function is used by master to get divider values
2913 * Return: Returns status, either success or error+reason.
2915 enum pm_ret_status
pm_api_clock_getdivider(unsigned int clock_id
,
2916 unsigned int *divider
)
2918 enum pm_ret_status ret
;
2920 if (!pm_clock_valid(clock_id
))
2921 return PM_RET_ERROR_ARGS
;
2923 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2924 return PM_RET_ERROR_NOTSUPPORTED
;
2926 if (ISPLL(clock_id
))
2927 ret
= pm_api_pll_get_divider(clock_id
, divider
);
2929 ret
= pm_api_clk_get_divider(clock_id
, divider
);
2935 * pm_api_clock_setrate - Set the clock rate for given id
2936 * @clock_id Id of the clock
2937 * @rate Rate value in hz
2939 * This function is used by master to set rate for any clock.
2941 * Return: Returns status, either success or error+reason.
2943 enum pm_ret_status
pm_api_clock_setrate(unsigned int clock_id
,
2946 return PM_RET_ERROR_NOTSUPPORTED
;
2950 * pm_api_clock_getrate - Get the clock rate for given id
2951 * @clock_id Id of the clock
2952 * @rate rate value in hz
2954 * This function is used by master to get rate
2957 * Return: Returns status, either success or error+reason.
2959 enum pm_ret_status
pm_api_clock_getrate(unsigned int clock_id
,
2962 return PM_RET_ERROR_NOTSUPPORTED
;
2966 * pm_api_clock_setparent - Set the clock parent for given id
2967 * @clock_id Id of the clock
2968 * @parent_idx parent index
2970 * This function is used by master to set parent for any clock.
2972 * Return: Returns status, either success or error+reason.
2974 enum pm_ret_status
pm_api_clock_setparent(unsigned int clock_id
,
2975 unsigned int parent_idx
)
2977 enum pm_ret_status ret
= PM_RET_SUCCESS
;
2978 struct pm_clock_node
*nodes
;
2980 unsigned int reg
, val
;
2981 int32_t *clk_parents
;
2983 uint8_t offset
= NA_SHIFT
, width
= NA_WIDTH
;
2985 if (!pm_clock_valid(clock_id
))
2986 return PM_RET_ERROR_ARGS
;
2988 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
2989 return PM_RET_ERROR_NOTSUPPORTED
;
2991 clk_parents
= *clocks
[clock_id
].parents
;
2993 for (i
= 0; i
<= parent_idx
; i
++)
2994 if (clk_parents
[i
] == CLK_NA_PARENT
)
2995 return PM_RET_ERROR_ARGS
;
2997 nodes
= *clocks
[clock_id
].nodes
;
2998 num_nodes
= clocks
[clock_id
].num_nodes
;
2999 for (i
= 0; i
< num_nodes
; i
++) {
3000 if (nodes
->type
== TYPE_MUX
) {
3001 offset
= nodes
->offset
;
3002 width
= nodes
->width
;
3006 if (width
== NA_WIDTH
)
3007 return PM_RET_ERROR_NOTSUPPORTED
;
3009 reg
= clocks
[clock_id
].control_reg
;
3010 val
= parent_idx
<< offset
;
3011 ret
= pm_mmio_write(reg
, BIT_MASK(offset
, width
), val
);
3017 * pm_api_clock_getparent - Get the clock parent for given id
3018 * @clock_id Id of the clock
3019 * @parent_idx parent index
3021 * This function is used by master to get parent index
3024 * Return: Returns status, either success or error+reason.
3026 enum pm_ret_status
pm_api_clock_getparent(unsigned int clock_id
,
3027 unsigned int *parent_idx
)
3029 enum pm_ret_status ret
= PM_RET_SUCCESS
;
3030 struct pm_clock_node
*nodes
;
3032 unsigned int reg
, val
;
3033 uint8_t i
= 0, offset
= NA_SHIFT
, width
= NA_WIDTH
;
3035 if (!pm_clock_valid(clock_id
))
3036 return PM_RET_ERROR_ARGS
;
3038 if (pm_clock_type(clock_id
) != CLK_TYPE_OUTPUT
)
3039 return PM_RET_ERROR_NOTSUPPORTED
;
3041 nodes
= *clocks
[clock_id
].nodes
;
3042 num_nodes
= clocks
[clock_id
].num_nodes
;
3044 for (i
= 0; i
< num_nodes
; i
++) {
3045 if (nodes
->type
== TYPE_MUX
) {
3046 offset
= nodes
->offset
;
3047 width
= nodes
->width
;
3051 if (width
== NA_WIDTH
)
3052 return PM_RET_ERROR_NOTSUPPORTED
;
3054 reg
= clocks
[clock_id
].control_reg
;
3055 ret
= pm_mmio_read(reg
, &val
);
3057 val
&= ((1U << width
) - 1);
3065 * pm_api_clk_set_pll_mode() - Set PLL mode
3067 * @mode Mode fraction/integar
3069 * This function sets PLL mode.
3071 * @return Returns status, either success or error+reason
3073 enum pm_ret_status
pm_api_clk_set_pll_mode(unsigned int pll
,
3076 enum pm_ret_status ret
= PM_RET_SUCCESS
;
3079 if (!pm_clock_valid(pll
))
3080 return PM_RET_ERROR_ARGS
;
3082 if (pm_clock_type(pll
) != CLK_TYPE_OUTPUT
)
3083 return PM_RET_ERROR_NOTSUPPORTED
;
3086 return PM_RET_ERROR_NOTSUPPORTED
;
3088 if (mode
!= PLL_FRAC_MODE
&& mode
!= PLL_INT_MODE
)
3089 return PM_RET_ERROR_ARGS
;
3091 reg
= clocks
[pll
].control_reg
+ PLL_FRAC_OFFSET
;
3093 ret
= pm_mmio_write(reg
, PLL_FRAC_MODE_MASK
,
3094 mode
<< PLL_FRAC_MODE_SHIFT
);
3100 * pm_ioctl_get_pll_mode() - Get PLL mode
3102 * @mode Mode fraction/integar
3104 * This function returns current PLL mode.
3106 * @return Returns status, either success or error+reason
3108 enum pm_ret_status
pm_api_clk_get_pll_mode(unsigned int pll
,
3111 enum pm_ret_status ret
= PM_RET_SUCCESS
;
3112 unsigned int val
, reg
;
3114 if (!pm_clock_valid(pll
))
3115 return PM_RET_ERROR_ARGS
;
3117 if (pm_clock_type(pll
) != CLK_TYPE_OUTPUT
)
3118 return PM_RET_ERROR_NOTSUPPORTED
;
3121 return PM_RET_ERROR_NOTSUPPORTED
;
3123 reg
= clocks
[pll
].control_reg
+ PLL_FRAC_OFFSET
;
3125 ret
= pm_mmio_read(reg
, &val
);
3126 val
= val
& PLL_FRAC_MODE_MASK
;
3128 *mode
= PLL_INT_MODE
;
3130 *mode
= PLL_FRAC_MODE
;
3136 * pm_api_clk_set_pll_frac_data() - Set PLL fraction data
3138 * @data fraction data
3140 * This function sets fraction data. It is valid for fraction
3143 * @return Returns status, either success or error+reason
3145 enum pm_ret_status
pm_api_clk_set_pll_frac_data(unsigned int pll
,
3148 enum pm_ret_status ret
= PM_RET_SUCCESS
;
3149 unsigned int val
, reg
, mode
= 0;
3151 if (!pm_clock_valid(pll
))
3152 return PM_RET_ERROR_ARGS
;
3154 if (pm_clock_type(pll
) != CLK_TYPE_OUTPUT
)
3155 return PM_RET_ERROR_NOTSUPPORTED
;
3158 return PM_RET_ERROR_NOTSUPPORTED
;
3160 ret
= pm_api_clk_get_pll_mode(pll
, &mode
);
3161 if (ret
!= PM_RET_SUCCESS
)
3163 if (mode
== PLL_FRAC_MODE
) {
3164 reg
= clocks
[pll
].control_reg
+ PLL_FRAC_OFFSET
;
3165 val
= data
<< PLL_FRAC_DATA_SHIFT
;
3166 ret
= pm_mmio_write(reg
, PLL_FRAC_DATA_MASK
, val
);
3168 return PM_RET_ERROR_ARGS
;
3175 * pm_api_clk_get_pll_frac_data() - Get PLL fraction data
3177 * @data fraction data
3179 * This function returns fraction data value.
3181 * @return Returns status, either success or error+reason
3183 enum pm_ret_status
pm_api_clk_get_pll_frac_data(unsigned int pll
,
3186 enum pm_ret_status ret
= PM_RET_SUCCESS
;
3187 unsigned int val
, reg
;
3189 if (!pm_clock_valid(pll
))
3190 return PM_RET_ERROR_ARGS
;
3192 if (pm_clock_type(pll
) != CLK_TYPE_OUTPUT
)
3193 return PM_RET_ERROR_NOTSUPPORTED
;
3196 return PM_RET_ERROR_NOTSUPPORTED
;
3198 reg
= clocks
[pll
].control_reg
+ PLL_FRAC_OFFSET
;
3200 ret
= pm_mmio_read(reg
, &val
);
3201 *data
= (val
& PLL_FRAC_DATA_MASK
);