1 /*
2  * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <lib/mmio.h>
9 
10 #include "cpg_registers.h"
11 #include "rcar_def.h"
12 #include "rcar_private.h"
13 
14 static void bl2_secure_cpg_init(void);
15 
16 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || \
17 	(RCAR_LSI == RCAR_H3N) || (RCAR_LSI == RZ_G2H)
18 static void bl2_realtime_cpg_init_h3(void);
19 static void bl2_system_cpg_init_h3(void);
20 #endif
21 
22 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
23 static void bl2_realtime_cpg_init_m3(void);
24 static void bl2_system_cpg_init_m3(void);
25 #endif
26 
27 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N) || (RCAR_LSI == RZ_G2N)
28 static void bl2_realtime_cpg_init_m3n(void);
29 static void bl2_system_cpg_init_m3n(void);
30 #endif
31 
32 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M)
33 static void bl2_realtime_cpg_init_v3m(void);
34 static void bl2_system_cpg_init_v3m(void);
35 #endif
36 
37 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
38 static void bl2_realtime_cpg_init_e3(void);
39 static void bl2_system_cpg_init_e3(void);
40 #endif
41 
42 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
43 static void bl2_system_cpg_init_d3(void);
44 #endif
45 
46 typedef struct {
47 	uintptr_t adr;
48 	uint32_t val;
49 } reg_setting_t;
50 
bl2_secure_cpg_init(void)51 static void bl2_secure_cpg_init(void)
52 {
53 	uint32_t stop_cr2, reset_cr2;
54 	uint32_t stop_cr4, reset_cr4;
55 	uint32_t stop_cr5, reset_cr5;
56 
57 #if (RCAR_LSI == RCAR_D3)
58 	reset_cr2 = 0x00000000U;
59 	stop_cr2 = 0xFFFFFFFFU;
60 #elif (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
61 	reset_cr2 = 0x10000000U;
62 	stop_cr2 = 0xEFFFFFFFU;
63 #else
64 	reset_cr2 = 0x14000000U;
65 	stop_cr2 = 0xEBFFFFFFU;
66 #endif
67 
68 #if (RCAR_LSI == RCAR_D3)
69 	reset_cr4 = 0x00000000U;
70 	stop_cr4 = 0xFFFFFFFFU;
71 	reset_cr5 = 0x00000000U;
72 	stop_cr5 = 0xFFFFFFFFU;
73 #else
74 	reset_cr4 = 0x80000003U;
75 	stop_cr4 = 0x7FFFFFFFU;
76 	reset_cr5 = 0x40000000U;
77 	stop_cr5 = 0xBFFFFFFFU;
78 #endif
79 
80 	/* Secure Module Stop Control Registers */
81 	cpg_write(SCMSTPCR0, 0xFFFFFFFFU);
82 	cpg_write(SCMSTPCR1, 0xFFFFFFFFU);
83 	cpg_write(SCMSTPCR2, stop_cr2);
84 	cpg_write(SCMSTPCR3, 0xFFFFFFFFU);
85 	cpg_write(SCMSTPCR4, stop_cr4);
86 	cpg_write(SCMSTPCR5, stop_cr5);
87 	cpg_write(SCMSTPCR6, 0xFFFFFFFFU);
88 	cpg_write(SCMSTPCR7, 0xFFFFFFFFU);
89 	cpg_write(SCMSTPCR8, 0xFFFFFFFFU);
90 	cpg_write(SCMSTPCR9, 0xFFFDFFFFU);
91 	cpg_write(SCMSTPCR10, 0xFFFFFFFFU);
92 	cpg_write(SCMSTPCR11, 0xFFFFFFFFU);
93 
94 	/* Secure Software Reset Access Enable Control Registers */
95 	cpg_write(SCSRSTECR0, 0x00000000U);
96 	cpg_write(SCSRSTECR1, 0x00000000U);
97 	cpg_write(SCSRSTECR2, reset_cr2);
98 	cpg_write(SCSRSTECR3, 0x00000000U);
99 	cpg_write(SCSRSTECR4, reset_cr4);
100 	cpg_write(SCSRSTECR5, reset_cr5);
101 	cpg_write(SCSRSTECR6, 0x00000000U);
102 	cpg_write(SCSRSTECR7, 0x00000000U);
103 	cpg_write(SCSRSTECR8, 0x00000000U);
104 	cpg_write(SCSRSTECR9, 0x00020000U);
105 	cpg_write(SCSRSTECR10, 0x00000000U);
106 	cpg_write(SCSRSTECR11, 0x00000000U);
107 }
108 
109 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || \
110 	(RCAR_LSI == RCAR_H3N) || (RCAR_LSI == RZ_G2H)
bl2_realtime_cpg_init_h3(void)111 static void bl2_realtime_cpg_init_h3(void)
112 {
113 	uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK;
114 	uint32_t cr0, cr8;
115 
116 	cr0 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ?
117 	    0x00200000U : 0x00210000U;
118 	cr8 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ?
119 	    0x01F1FFF4U : 0x01F1FFF7U;
120 
121 	cpg_write(RMSTPCR0, cr0);
122 	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
123 	cpg_write(RMSTPCR2, 0x040E0FDCU);
124 	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
125 	cpg_write(RMSTPCR4, 0x80000004U);
126 	cpg_write(RMSTPCR5, 0xC3FFFFFFU);
127 	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
128 	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
129 	cpg_write(RMSTPCR8, cr8);
130 	cpg_write(RMSTPCR9, 0xFFFFFFFEU);
131 	cpg_write(RMSTPCR10, 0xFFFEFFE0U);
132 	cpg_write(RMSTPCR11, 0x000000B7U);
133 }
134 
bl2_system_cpg_init_h3(void)135 static void bl2_system_cpg_init_h3(void)
136 {
137 	/** System Module Stop Control Registers */
138 	cpg_write(SMSTPCR0, 0x00210000U);
139 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
140 	cpg_write(SMSTPCR2, 0x040E2FDCU);
141 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
142 	cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
143 	cpg_write(SMSTPCR5, 0xC3FFFFFFU);
144 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
145 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
146 	cpg_write(SMSTPCR8, 0x01F1FFF5U);
147 	cpg_write(SMSTPCR9, 0xFFFFFFFFU);
148 	cpg_write(SMSTPCR10, 0xFFFEFFE0U);
149 	cpg_write(SMSTPCR11, 0x000000B7U);
150 }
151 #endif
152 
153 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
bl2_realtime_cpg_init_m3(void)154 static void bl2_realtime_cpg_init_m3(void)
155 {
156 	/* Realtime Module Stop Control Registers */
157 	cpg_write(RMSTPCR0, 0x00200000U);
158 	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
159 	cpg_write(RMSTPCR2, 0x040E0FDCU);
160 	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
161 	cpg_write(RMSTPCR4, 0x80000004U);
162 	cpg_write(RMSTPCR5, 0xC3FFFFFFU);
163 	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
164 	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
165 	cpg_write(RMSTPCR8, 0x01F1FFF7U);
166 	cpg_write(RMSTPCR9, 0xFFFFFFFEU);
167 	cpg_write(RMSTPCR10, 0xFFFEFFE0U);
168 	cpg_write(RMSTPCR11, 0x000000B7U);
169 }
170 
bl2_system_cpg_init_m3(void)171 static void bl2_system_cpg_init_m3(void)
172 {
173 	/* System Module Stop Control Registers */
174 	cpg_write(SMSTPCR0, 0x00200000U);
175 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
176 	cpg_write(SMSTPCR2, 0x040E2FDCU);
177 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
178 	cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
179 	cpg_write(SMSTPCR5, 0xC3FFFFFFU);
180 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
181 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
182 	cpg_write(SMSTPCR8, 0x01F1FFF7U);
183 	cpg_write(SMSTPCR9, 0xFFFFFFFFU);
184 	cpg_write(SMSTPCR10, 0xFFFEFFE0U);
185 	cpg_write(SMSTPCR11, 0x000000B7U);
186 }
187 #endif
188 
189 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_M3N)  || (RCAR_LSI == RZ_G2N)
bl2_realtime_cpg_init_m3n(void)190 static void bl2_realtime_cpg_init_m3n(void)
191 {
192 	/* Realtime Module Stop Control Registers */
193 	cpg_write(RMSTPCR0, 0x00210000U);
194 	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
195 	cpg_write(RMSTPCR2, 0x040E0FDCU);
196 	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
197 	cpg_write(RMSTPCR4, 0x80000004U);
198 	cpg_write(RMSTPCR5, 0xC3FFFFFFU);
199 	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
200 	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
201 	cpg_write(RMSTPCR8, 0x00F1FFF7U);
202 	cpg_write(RMSTPCR9, 0xFFFFFFFFU);
203 	cpg_write(RMSTPCR10, 0xFFFFFFE0U);
204 	cpg_write(RMSTPCR11, 0x000000B7U);
205 }
206 
bl2_system_cpg_init_m3n(void)207 static void bl2_system_cpg_init_m3n(void)
208 {
209 	/* System Module Stop Control Registers */
210 	cpg_write(SMSTPCR0, 0x00210000U);
211 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
212 	cpg_write(SMSTPCR2, 0x040E2FDCU);
213 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
214 	cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
215 	cpg_write(SMSTPCR5, 0xC3FFFFFFU);
216 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
217 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
218 	cpg_write(SMSTPCR8, 0x00F1FFF7U);
219 	cpg_write(SMSTPCR9, 0xFFFFFFFFU);
220 	cpg_write(SMSTPCR10, 0xFFFFFFE0U);
221 	cpg_write(SMSTPCR11, 0x000000B7U);
222 }
223 #endif
224 
225 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_V3M)
bl2_realtime_cpg_init_v3m(void)226 static void bl2_realtime_cpg_init_v3m(void)
227 {
228 	/* Realtime Module Stop Control Registers */
229 	cpg_write(RMSTPCR0, 0x00230000U);
230 	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
231 	cpg_write(RMSTPCR2, 0x14062FD8U);
232 	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
233 	cpg_write(RMSTPCR4, 0x80000184U);
234 	cpg_write(RMSTPCR5, 0x83FFFFFFU);
235 	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
236 	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
237 	cpg_write(RMSTPCR8, 0x7FF3FFF4U);
238 	cpg_write(RMSTPCR9, 0xFFFFFFFEU);
239 }
240 
bl2_system_cpg_init_v3m(void)241 static void bl2_system_cpg_init_v3m(void)
242 {
243 	/* System Module Stop Control Registers */
244 	cpg_write(SMSTPCR0, 0x00210000U);
245 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
246 	cpg_write(SMSTPCR2, 0x340E2FDCU);
247 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
248 	cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
249 	cpg_write(SMSTPCR5, 0xC3FFFFFFU);
250 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
251 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
252 	cpg_write(SMSTPCR8, 0x01F1FFF5U);
253 	cpg_write(SMSTPCR9, 0xFFFFFFFEU);
254 }
255 #endif
256 
257 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RZ_G2E)
bl2_realtime_cpg_init_e3(void)258 static void bl2_realtime_cpg_init_e3(void)
259 {
260 	/* Realtime Module Stop Control Registers */
261 	cpg_write(RMSTPCR0, 0x00210000U);
262 	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
263 	cpg_write(RMSTPCR2, 0x000E0FDCU);
264 	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
265 	cpg_write(RMSTPCR4, 0x80000004U);
266 	cpg_write(RMSTPCR5, 0xC3FFFFFFU);
267 	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
268 	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
269 	cpg_write(RMSTPCR8, 0x00F1FFF7U);
270 	cpg_write(RMSTPCR9, 0xFFFFFFDFU);
271 	cpg_write(RMSTPCR10, 0xFFFFFFE8U);
272 	cpg_write(RMSTPCR11, 0x000000B7U);
273 }
274 
bl2_system_cpg_init_e3(void)275 static void bl2_system_cpg_init_e3(void)
276 {
277 	/* System Module Stop Control Registers */
278 	cpg_write(SMSTPCR0, 0x00210000U);
279 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
280 	cpg_write(SMSTPCR2, 0x000E2FDCU);
281 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
282 	cpg_write(SMSTPCR4, 0x80000000U | (mmio_read_32(SMSTPCR4) & 0x4));
283 	cpg_write(SMSTPCR5, 0xC3FFFFFFU);
284 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
285 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
286 	cpg_write(SMSTPCR8, 0x00F1FFF7U);
287 	cpg_write(SMSTPCR9, 0xFFFFFFDFU);
288 	cpg_write(SMSTPCR10, 0xFFFFFFE8U);
289 	cpg_write(SMSTPCR11, 0x000000B7U);
290 }
291 #endif
292 
293 #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
bl2_system_cpg_init_d3(void)294 static void bl2_system_cpg_init_d3(void)
295 {
296 	/* System Module Stop Control Registers */
297 	cpg_write(SMSTPCR0, 0x00010000U);
298 	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
299 	cpg_write(SMSTPCR2, 0x00060FDCU);
300 	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
301 	cpg_write(SMSTPCR4, 0x00000080U | (mmio_read_32(SMSTPCR4) & 0x4));
302 	cpg_write(SMSTPCR5, 0x83FFFFFFU);
303 	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
304 	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
305 	cpg_write(SMSTPCR8, 0x00F1FFF7U);
306 	cpg_write(SMSTPCR9, 0xF3F5E016U);
307 	cpg_write(SMSTPCR10, 0xFFFEFFE0U);
308 	cpg_write(SMSTPCR11, 0x000000B7U);
309 }
310 #endif
311 
bl2_cpg_init(void)312 void bl2_cpg_init(void)
313 {
314 	uint32_t boot_cpu = mmio_read_32(RCAR_MODEMR) & MODEMR_BOOT_CPU_MASK;
315 #if RCAR_LSI == RCAR_AUTO
316 	uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
317 #endif
318 	bl2_secure_cpg_init();
319 
320 	if (boot_cpu == MODEMR_BOOT_CPU_CA57 ||
321 	    boot_cpu == MODEMR_BOOT_CPU_CA53) {
322 #if RCAR_LSI == RCAR_AUTO
323 
324 		switch (product) {
325 		case PRR_PRODUCT_H3:
326 			bl2_realtime_cpg_init_h3();
327 			break;
328 		case PRR_PRODUCT_M3:
329 			bl2_realtime_cpg_init_m3();
330 			break;
331 		case PRR_PRODUCT_M3N:
332 			bl2_realtime_cpg_init_m3n();
333 			break;
334 		case PRR_PRODUCT_V3M:
335 			bl2_realtime_cpg_init_v3m();
336 			break;
337 		case PRR_PRODUCT_E3:
338 			bl2_realtime_cpg_init_e3();
339 			break;
340 		case PRR_PRODUCT_D3:
341 			/* no need */
342 			break;
343 		default:
344 			panic();
345 			break;
346 		}
347 #elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) || (RCAR_LSI == RZ_G2H)
348 		bl2_realtime_cpg_init_h3();
349 #elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
350 		bl2_realtime_cpg_init_m3();
351 #elif RCAR_LSI == RCAR_M3N || (RCAR_LSI == RZ_G2N)
352 		bl2_realtime_cpg_init_m3n();
353 #elif RCAR_LSI == RCAR_V3M
354 		bl2_realtime_cpg_init_v3m();
355 #elif RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2E
356 		bl2_realtime_cpg_init_e3();
357 #elif RCAR_LSI == RCAR_D3
358 		/* no need */
359 #else
360 #error "Don't have CPG initialize routine(unknown)."
361 #endif
362 	}
363 }
364 
bl2_system_cpg_init(void)365 void bl2_system_cpg_init(void)
366 {
367 #if RCAR_LSI == RCAR_AUTO
368 	uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
369 
370 	switch (product) {
371 	case PRR_PRODUCT_H3:
372 		bl2_system_cpg_init_h3();
373 		break;
374 	case PRR_PRODUCT_M3:
375 		bl2_system_cpg_init_m3();
376 		break;
377 	case PRR_PRODUCT_M3N:
378 		bl2_system_cpg_init_m3n();
379 		break;
380 	case PRR_PRODUCT_V3M:
381 		bl2_system_cpg_init_v3m();
382 		break;
383 	case PRR_PRODUCT_E3:
384 		bl2_system_cpg_init_e3();
385 		break;
386 	case PRR_PRODUCT_D3:
387 		bl2_system_cpg_init_d3();
388 		break;
389 	default:
390 		panic();
391 		break;
392 	}
393 #elif (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) || (RCAR_LSI == RZ_G2H)
394 	bl2_system_cpg_init_h3();
395 #elif (RCAR_LSI == RCAR_M3) || (RCAR_LSI == RZ_G2M)
396 	bl2_system_cpg_init_m3();
397 #elif RCAR_LSI == RCAR_M3N  || (RCAR_LSI == RZ_G2N)
398 	bl2_system_cpg_init_m3n();
399 #elif RCAR_LSI == RCAR_V3M
400 	bl2_system_cpg_init_v3m();
401 #elif RCAR_LSI == RCAR_E3 || RCAR_LSI == RZ_G2E
402 	bl2_system_cpg_init_e3();
403 #elif RCAR_LSI == RCAR_D3
404 	bl2_system_cpg_init_d3();
405 #else
406 #error "Don't have CPG initialize routine(unknown)."
407 #endif
408 }
409