xref: /rk3399_ARM-atf/drivers/nxp/clk/s32cc/s32cc_early_clks.c (revision e01ce1ea61368f169f8f827a05ad9d0c5bb06160)
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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