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