1 /*
2 * Copyright 2024-2025 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-regs.h>
11 #include <s32cc-mc-rgm.h>
12 #include <s32cc-clk-utils.h>
13
14 #define S32CC_FXOSC_FREQ (40U * MHZ)
15 #define S32CC_ARM_PLL_VCO_FREQ (2U * GHZ)
16 #define S32CC_ARM_PLL_PHI0_FREQ (1U * GHZ)
17 #define S32CC_A53_FREQ (1U * GHZ)
18 #define S32CC_XBAR_2X_FREQ (800U * MHZ)
19 #define S32CC_PERIPH_PLL_VCO_FREQ (2U * GHZ)
20 #define S32CC_PERIPH_PLL_PHI3_FREQ UART_CLOCK_HZ
21 #define S32CC_DDR_PLL_VCO_FREQ (1600U * MHZ)
22 #define S32CC_DDR_PLL_PHI0_FREQ (800U * MHZ)
23 #define S32CC_PERIPH_DFS_PHI3_FREQ (800U * MHZ)
24 #define S32CC_USDHC_FREQ (200U * MHZ)
25
26 #define S32CC_DDR_RESET_TIMEOUT_US 1000000U
27
setup_fxosc(void)28 static int setup_fxosc(void)
29 {
30 int ret;
31
32 ret = clk_set_rate(S32CC_CLK_FXOSC, S32CC_FXOSC_FREQ, NULL);
33 if (ret != 0) {
34 return ret;
35 }
36
37 return ret;
38 }
39
setup_arm_pll(void)40 static int setup_arm_pll(void)
41 {
42 int ret;
43
44 ret = clk_set_parent(S32CC_CLK_ARM_PLL_MUX, S32CC_CLK_FXOSC);
45 if (ret != 0) {
46 return ret;
47 }
48
49 ret = clk_set_rate(S32CC_CLK_ARM_PLL_VCO, S32CC_ARM_PLL_VCO_FREQ, NULL);
50 if (ret != 0) {
51 return ret;
52 }
53
54 ret = clk_set_rate(S32CC_CLK_ARM_PLL_PHI0, S32CC_ARM_PLL_PHI0_FREQ, NULL);
55 if (ret != 0) {
56 return ret;
57 }
58
59 return ret;
60 }
61
setup_periph_pll(void)62 static int setup_periph_pll(void)
63 {
64 int ret;
65
66 ret = clk_set_parent(S32CC_CLK_PERIPH_PLL_MUX, S32CC_CLK_FXOSC);
67 if (ret != 0) {
68 return ret;
69 }
70
71 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_VCO, S32CC_PERIPH_PLL_VCO_FREQ, NULL);
72 if (ret != 0) {
73 return ret;
74 }
75
76 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_PHI3, S32CC_PERIPH_PLL_PHI3_FREQ, NULL);
77 if (ret != 0) {
78 return ret;
79 }
80
81 return ret;
82 }
83
enable_a53_clk(void)84 static int enable_a53_clk(void)
85 {
86 int ret;
87
88 ret = clk_set_parent(S32CC_CLK_MC_CGM1_MUX0, S32CC_CLK_ARM_PLL_PHI0);
89 if (ret != 0) {
90 return ret;
91 }
92
93 ret = clk_set_rate(S32CC_CLK_A53_CORE, S32CC_A53_FREQ, NULL);
94 if (ret != 0) {
95 return ret;
96 }
97
98 ret = clk_enable(S32CC_CLK_A53_CORE);
99 if (ret != 0) {
100 return ret;
101 }
102
103 return ret;
104 }
105
enable_xbar_clk(void)106 static int enable_xbar_clk(void)
107 {
108 int ret;
109
110 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX0, S32CC_CLK_ARM_PLL_DFS1);
111 if (ret != 0) {
112 return ret;
113 }
114
115 ret = clk_set_rate(S32CC_CLK_XBAR_2X, S32CC_XBAR_2X_FREQ, NULL);
116 if (ret != 0) {
117 return ret;
118 }
119
120 ret = clk_enable(S32CC_CLK_ARM_PLL_DFS1);
121 if (ret != 0) {
122 return ret;
123 }
124
125 ret = clk_enable(S32CC_CLK_XBAR_2X);
126 if (ret != 0) {
127 return ret;
128 }
129
130 return ret;
131 }
132
enable_uart_clk(void)133 static int enable_uart_clk(void)
134 {
135 int ret;
136
137 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX8, S32CC_CLK_PERIPH_PLL_PHI3);
138 if (ret != 0) {
139 return ret;
140 }
141
142 ret = clk_enable(S32CC_CLK_LINFLEX_BAUD);
143 if (ret != 0) {
144 return ret;
145 }
146
147 return ret;
148 }
149
setup_ddr_pll(void)150 static int setup_ddr_pll(void)
151 {
152 int ret;
153
154 ret = clk_set_parent(S32CC_CLK_DDR_PLL_MUX, S32CC_CLK_FXOSC);
155 if (ret != 0) {
156 return ret;
157 }
158
159 ret = clk_set_rate(S32CC_CLK_DDR_PLL_VCO, S32CC_DDR_PLL_VCO_FREQ, NULL);
160 if (ret != 0) {
161 return ret;
162 }
163
164 ret = clk_set_rate(S32CC_CLK_DDR_PLL_PHI0, S32CC_DDR_PLL_PHI0_FREQ, NULL);
165 if (ret != 0) {
166 return ret;
167 }
168
169 return ret;
170 }
171
enable_ddr_clk(void)172 static int enable_ddr_clk(void)
173 {
174 int ret;
175
176 ret = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_DDR_PLL_PHI0);
177 if (ret != 0) {
178 return ret;
179 }
180
181 ret = clk_enable(S32CC_CLK_DDR);
182 if (ret != 0) {
183 return ret;
184 }
185
186 return ret;
187 }
188
enable_usdhc_clk(void)189 static int enable_usdhc_clk(void)
190 {
191 int ret;
192
193 ret = clk_set_parent(S32CC_CLK_MC_CGM0_MUX14,
194 S32CC_CLK_PERIPH_PLL_DFS3);
195 if (ret != 0) {
196 return ret;
197 }
198
199 ret = clk_set_rate(S32CC_CLK_PERIPH_PLL_DFS3,
200 S32CC_PERIPH_DFS_PHI3_FREQ, NULL);
201 if (ret != 0) {
202 return ret;
203 }
204
205 ret = clk_set_rate(S32CC_CLK_USDHC, S32CC_USDHC_FREQ, NULL);
206 if (ret != 0) {
207 return ret;
208 }
209
210 ret = clk_enable(S32CC_CLK_USDHC);
211 if (ret != 0) {
212 return ret;
213 }
214
215 return ret;
216 }
217
plat_deassert_ddr_reset(void)218 int plat_deassert_ddr_reset(void)
219 {
220 int err;
221
222 clk_disable(S32CC_CLK_DDR);
223
224 err = clk_set_parent(S32CC_CLK_MC_CGM5_MUX0, S32CC_CLK_FIRC);
225 if (err != 0) {
226 return err;
227 }
228
229 err = clk_enable(S32CC_CLK_DDR);
230 if (err != 0) {
231 return err;
232 }
233
234 err = mc_rgm_ddr_reset(MC_RGM_BASE_ADDR, S32CC_DDR_RESET_TIMEOUT_US);
235 if (err != 0) {
236 return err;
237 }
238
239 return enable_ddr_clk();
240 }
241
s32cc_init_core_clocks(void)242 int s32cc_init_core_clocks(void)
243 {
244 int ret;
245
246 ret = s32cc_clk_register_drv(false);
247 if (ret != 0) {
248 return ret;
249 }
250
251 ret = setup_fxosc();
252 if (ret != 0) {
253 return ret;
254 }
255
256 ret = setup_arm_pll();
257 if (ret != 0) {
258 return ret;
259 }
260
261 ret = enable_a53_clk();
262 if (ret != 0) {
263 return ret;
264 }
265
266 ret = enable_xbar_clk();
267 if (ret != 0) {
268 return ret;
269 }
270
271 return ret;
272 }
273
s32cc_init_early_clks(void)274 int s32cc_init_early_clks(void)
275 {
276 int ret;
277
278 ret = s32cc_clk_register_drv(true);
279 if (ret != 0) {
280 return ret;
281 }
282
283 ret = setup_periph_pll();
284 if (ret != 0) {
285 return ret;
286 }
287
288 ret = enable_uart_clk();
289 if (ret != 0) {
290 return ret;
291 }
292
293 ret = setup_ddr_pll();
294 if (ret != 0) {
295 return ret;
296 }
297
298 ret = enable_ddr_clk();
299 if (ret != 0) {
300 return ret;
301 }
302
303 ret = enable_usdhc_clk();
304 if (ret != 0) {
305 return ret;
306 }
307
308 return ret;
309 }
310