1 /*
2 * Copyright 2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6 #include <drivers/clk.h>
7 #include <platform_def.h>
8 #include <s32cc-clk-drv.h>
9 #include <s32cc-clk-ids.h>
10 #include <s32cc-clk-utils.h>
11
12 #define S32CC_FXOSC_FREQ (40U * MHZ)
13 #define S32CC_ARM_PLL_VCO_FREQ (2U * GHZ)
14 #define S32CC_ARM_PLL_PHI0_FREQ (1U * GHZ)
15 #define S32CC_A53_FREQ (1U * GHZ)
16 #define S32CC_XBAR_2X_FREQ (800U * MHZ)
17 #define S32CC_PERIPH_PLL_VCO_FREQ (2U * GHZ)
18 #define S32CC_PERIPH_PLL_PHI3_FREQ UART_CLOCK_HZ
19 #define S32CC_DDR_PLL_VCO_FREQ (1600U * MHZ)
20 #define S32CC_DDR_PLL_PHI0_FREQ (800U * MHZ)
21
setup_fxosc(void)22 static int setup_fxosc(void)
23 {
24 int ret;
25
26 ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
27 if (ret != 0) {
28 return ret;
29 }
30
31 return ret;
32 }
33
setup_arm_pll(void)34 static int setup_arm_pll(void)
35 {
36 int ret;
37
38 ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
39 if (ret != 0) {
40 return ret;
41 }
42
43 ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
44 if (ret != 0) {
45 return ret;
46 }
47
48 ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
49 if (ret != 0) {
50 return ret;
51 }
52
53 return ret;
54 }
55
setup_periph_pll(void)56 static int setup_periph_pll(void)
57 {
58 int ret;
59
60 ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
61 if (ret != 0) {
62 return ret;
63 }
64
65 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
66 if (ret != 0) {
67 return ret;
68 }
69
70 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
71 if (ret != 0) {
72 return ret;
73 }
74
75 return ret;
76 }
77
enable_a53_clk(void)78 static int enable_a53_clk(void)
79 {
80 int ret;
81
82 ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
83 if (ret != 0) {
84 return ret;
85 }
86
87 ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
88 if (ret != 0) {
89 return ret;
90 }
91
92 ret = clk_enable(S32CC_CLK_A53_CORE);
93 if (ret != 0) {
94 return ret;
95 }
96
97 return ret;
98 }
99
enable_xbar_clk(void)100 static int enable_xbar_clk(void)
101 {
102 int ret;
103
104 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
105 if (ret != 0) {
106 return ret;
107 }
108
109 ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
110 if (ret != 0) {
111 return ret;
112 }
113
114 ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
115 if (ret != 0) {
116 return ret;
117 }
118
119 ret = clk_enable(S32CC_CLK_XBAR_2X);
120 if (ret != 0) {
121 return ret;
122 }
123
124 return ret;
125 }
126
enable_uart_clk(void)127 static int enable_uart_clk(void)
128 {
129 int ret;
130
131 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
132 if (ret != 0) {
133 return ret;
134 }
135
136 ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
137 if (ret != 0) {
138 return ret;
139 }
140
141 return ret;
142 }
143
setup_ddr_pll(void)144 static int setup_ddr_pll(void)
145 {
146 int ret;
147
148 ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
149 if (ret != 0) {
150 return ret;
151 }
152
153 ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
154 if (ret != 0) {
155 return ret;
156 }
157
158 ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
159 if (ret != 0) {
160 return ret;
161 }
162
163 return ret;
164 }
165
enable_ddr_clk(void)166 static int enable_ddr_clk(void)
167 {
168 int ret;
169
170 ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
171 if (ret != 0) {
172 return ret;
173 }
174
175 ret = clk_enable(S32CC_CLK_DDR);
176 if (ret != 0) {
177 return ret;
178 }
179
180 return ret;
181 }
182
s32cc_init_early_clks(void)183 int s32cc_init_early_clks(void)
184 {
185 int ret;
186
187 s32cc_clk_register_drv();
188
189 ret = setup_fxosc();
190 if (ret != 0) {
191 return ret;
192 }
193
194 ret = setup_arm_pll();
195 if (ret != 0) {
196 return ret;
197 }
198
199 ret = enable_a53_clk();
200 if (ret != 0) {
201 return ret;
202 }
203
204 ret = enable_xbar_clk();
205 if (ret != 0) {
206 return ret;
207 }
208
209 ret = setup_periph_pll();
210 if (ret != 0) {
211 return ret;
212 }
213
214 ret = enable_uart_clk();
215 if (ret != 0) {
216 return ret;
217 }
218
219 ret = setup_ddr_pll();
220 if (ret != 0) {
221 return ret;
222 }
223
224 ret = enable_ddr_clk();
225 if (ret != 0) {
226 return ret;
227 }
228
229 return ret;
230 }
231