xref: /rk3399_ARM-atf/drivers/renesas/rcar_gen4/pwrc/pwrc.c (revision 52e486f6a6192bd18d36cdcbc35c59092eefc810)
1 /*
2  * Copyright (c) 2015-2025, Renesas Electronics Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <string.h>
9 
10 #include <arch.h>
11 #include <arch_helpers.h>
12 #include <common/debug.h>
13 #include <lib/bakery_lock.h>
14 #include <lib/mmio.h>
15 #include <lib/xlat_tables/xlat_tables_v2.h>
16 #include <plat/common/platform.h>
17 
18 #include "pwrc.h"
19 #include "rcar_def.h"
20 #include "rcar_private.h"
21 
22 #ifndef __ASSEMBLER__
23 IMPORT_SYM(uintptr_t, __system_ram_start__, SYSTEM_RAM_START);
24 IMPORT_SYM(uintptr_t, __system_ram_end__, SYSTEM_RAM_END);
25 IMPORT_SYM(uintptr_t, __SRAM_COPY_START__, SRAM_COPY_START);
26 #endif /*__ASSEMBLER__*/
27 
28 #define	RCAR_CODE_COPY_NONE	0
29 #define	RCAR_CODE_COPY_DONE	1
30 
31 static uint32_t dummy_sdram = 0xAAAAAAAA;
32 static uint32_t rcar_pwrc_code_copy_state;
33 
34 /*
35  * Someday there will be a generic power controller API. At the moment each
36  * platform has its own PWRC so just exporting functions should be acceptable.
37  */
38 static RCAR_INSTANTIATE_LOCK;
39 
40 static u_register_t rcar_boot_mpidr;
41 
42 /* APSREG boot configuration */
43 static uintptr_t apsreg_ap_cluster_aux0(uint32_t n)
44 {
45 	return APSREG_BASE + 0x10UL + ((n & 0x3) * 0x1000UL);
46 }
47 
48 /* APMU */
49 static uintptr_t rcar_apmu_cluster_base(uint32_t n)
50 {
51 	return RCAR_APMU_BASE + 0x400UL + ((n & 0x3) * 0x40UL);
52 }
53 
54 static uintptr_t rcar_apmu_cpu_base(uint32_t n)
55 {
56 	return RCAR_APMU_BASE + 0x800UL + ((n & 0x6) * 0x100UL) +
57 	       ((n & 0x1) * 0x40UL);
58 }
59 
60 static uintptr_t rcar_apmu_pwrctrlcl(uint32_t n)
61 {
62 	return rcar_apmu_cluster_base(n);
63 }
64 
65 static uintptr_t rcar_apmu_pwrctrlc(uint32_t n)
66 {
67 	return rcar_apmu_cpu_base(n);
68 }
69 
70 static uintptr_t rcar_apmu_safectrlc(uint32_t n)
71 {
72 	return rcar_apmu_cpu_base(n) + 0x20UL;
73 }
74 
75 static uintptr_t rcar_apmu_rvbarplc(uint32_t n)
76 {
77 	return rcar_apmu_cpu_base(n) + 0x38UL;
78 }
79 
80 static uintptr_t rcar_apmu_rvbarphc(uint32_t n)
81 {
82 	return rcar_apmu_cpu_base(n) + 0x3cUL;
83 }
84 
85 static uintptr_t rcar_apmu_fsmstsrc(uint32_t n)
86 {
87 	return rcar_apmu_cpu_base(n) + 0x18UL;
88 }
89 
90 /* Product register */
91 static uint32_t prr_caxx_xx_en_cpu(uint32_t n)
92 {
93 	return BIT(n & 0x1);
94 }
95 
96 static void write_cpupwrctlr(u_register_t v)
97 {
98 	__asm__ volatile ("msr S3_0_C15_C2_7, %0" : : "r" (v));
99 }
100 
101 static uint32_t rcar_pwrc_core_pos(u_register_t mpidr)
102 {
103 	int cpu;
104 
105 	cpu = plat_core_pos_by_mpidr(mpidr);
106 	if (cpu < 0) {
107 		ERROR("BL3-1 : The value of passed MPIDR is invalid.");
108 		panic();
109 	}
110 
111 	return (uint32_t)cpu;
112 }
113 
114 static uint64_t rcar_pwrc_saved_cntpct_el0;
115 static uint32_t rcar_pwrc_saved_cntfid;
116 
117 void rcar_pwrc_cpuon(u_register_t mpidr)
118 {
119 	uint32_t cluster, cpu;
120 
121 	rcar_lock_get();
122 
123 	cpu = rcar_pwrc_core_pos(mpidr);
124 
125 	cluster = rcar_pwrc_get_mpidr_cluster(mpidr);
126 
127 	/* clear Cluster OFF bit */
128 	mmio_clrbits_32(rcar_apmu_pwrctrlcl(cluster),
129 			RCAR_APMU_PWRCTRLCL_PCHPDNEN);
130 
131 	/* clear Core OFF bit */
132 	mmio_clrbits_32(rcar_apmu_pwrctrlc(cpu), RCAR_APMU_PWRCTRLC_PCHPDNEN);
133 	while (mmio_read_32(rcar_apmu_pwrctrlc(cpu)) & RCAR_APMU_PWRCTRLC_PCHPDNEN)
134 		;
135 
136 	mmio_setbits_32(rcar_apmu_pwrctrlc(cpu), RCAR_APMU_PWRCTRLC_WUP_REQ);
137 
138 	/* Wait until CAXX wake up sequence finishes */
139 	while ((mmio_read_32(rcar_apmu_pwrctrlc(cpu)) & RCAR_APMU_PWRCTRLC_WUP_REQ) ==
140 	       RCAR_APMU_PWRCTRLC_WUP_REQ)
141 		;
142 
143 	rcar_lock_release();
144 
145 	/*
146 	 * mask should match the kernel's MPIDR_HWID_BITMASK so the core can be
147 	 * identified during cpuhotplug (check the kernel's psci migrate set of
148 	 * functions
149 	 */
150 	rcar_boot_mpidr = read_mpidr_el1() & RCAR_MPIDR_AFFMASK;
151 }
152 
153 int32_t rcar_pwrc_cpu_migrate_info(u_register_t *resident_cpu)
154 {
155 	*resident_cpu = rcar_boot_mpidr;
156 
157 	return PSCI_TOS_NOT_UP_MIG_CAP;
158 }
159 
160 bool rcar_pwrc_mpidr_is_boot_cpu(u_register_t mpidr)
161 {
162 	return (mpidr & RCAR_MPIDR_AFFMASK) == rcar_boot_mpidr;
163 }
164 
165 static void rcar_pwrc_cpuoff_sub(uint32_t cpu)
166 {
167 	/* Clear DBGGEN_PPDN bit for core down to 'OFF' mode */
168 	mmio_clrbits_32(rcar_apmu_safectrlc(cpu), RCAR_APMU_SAFECTRLC_DBGGEN);
169 	/* for Core OFF */
170 	mmio_setbits_32(rcar_apmu_pwrctrlc(cpu), RCAR_APMU_PWRCTRLC_PCHPDNEN);
171 
172 	write_cpupwrctlr(CPUPWRCTLR_PWDN);
173 }
174 
175 void rcar_pwrc_cpuoff(u_register_t mpidr)
176 {
177 	uint32_t cpu;
178 
179 	rcar_lock_get();
180 
181 	cpu = rcar_pwrc_core_pos(mpidr);
182 
183 	rcar_pwrc_cpuoff_sub(cpu);
184 
185 	rcar_lock_release();
186 }
187 
188 void rcar_pwrc_enable_interrupt_wakeup(u_register_t mpidr)
189 {
190 	uint32_t cpu;
191 
192 	rcar_lock_get();
193 
194 	cpu = rcar_pwrc_core_pos(mpidr);
195 
196 	mmio_setbits_32(rcar_apmu_pwrctrlc(cpu), RCAR_APMU_PWRCTRLC_IWUP_EN);
197 
198 	rcar_lock_release();
199 }
200 
201 void rcar_pwrc_disable_interrupt_wakeup(u_register_t mpidr)
202 {
203 	uint32_t cpu;
204 
205 	rcar_lock_get();
206 
207 	cpu = rcar_pwrc_core_pos(mpidr);
208 
209 	mmio_clrbits_32(rcar_apmu_pwrctrlc(cpu), RCAR_APMU_PWRCTRLC_IWUP_EN);
210 
211 	rcar_lock_release();
212 }
213 
214 void rcar_pwrc_clusteroff(u_register_t mpidr)
215 {
216 	uint32_t cluster, cpu;
217 
218 	rcar_lock_get();
219 
220 	cpu = rcar_pwrc_core_pos(mpidr);
221 
222 	cluster = rcar_pwrc_get_mpidr_cluster(mpidr);
223 
224 	/* for Cluster OFF */
225 	mmio_setbits_32(rcar_apmu_pwrctrlcl(cluster),
226 			RCAR_APMU_PWRCTRLCL_PCHPDNEN);
227 
228 	rcar_pwrc_cpuoff_sub(cpu);
229 
230 	rcar_lock_release();
231 }
232 
233 void rcar_pwrc_setup(void)
234 {
235 	uintptr_t rst_barh, rst_barl;
236 	uint32_t cpu, i, j, reg;
237 	uint64_t reset;
238 
239 	reset = (uint64_t)(&plat_secondary_reset) & 0xFFFFFFFFU;
240 	reset &= RCAR_APMU_RVBARPLC_MASK;
241 	reset |= RCAR_APMU_RVBARPL_VLD;
242 
243 	reg = mmio_read_32(RCAR_PRR) >> 17;
244 	for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) {
245 		reg >>= 3;
246 
247 		if ((reg & PRR_CAXX_XX_EN_CLUSTER_MASK) != RCAR_CPU_HAVE_CAXX)
248 			continue;
249 
250 		mmio_setbits_32(apsreg_ap_cluster_aux0(i),
251 			      APSREG_AP_CLUSTER_AUX0_INIT);
252 
253 		for (j = 0; j < PLATFORM_MAX_CPUS_PER_CLUSTER; j++) {
254 			cpu = (i * PLATFORM_MAX_CPUS_PER_CLUSTER) + j;
255 
256 			if ((reg & prr_caxx_xx_en_cpu(cpu)) != RCAR_CPU_HAVE_CAXX)
257 				continue;
258 
259 			rst_barh = rcar_apmu_rvbarphc(cpu);
260 			rst_barl = rcar_apmu_rvbarplc(cpu);
261 			mmio_write_32(rst_barh, 0);
262 			mmio_write_32(rst_barl, (uint32_t)reset);
263 		}
264 	}
265 
266 	mmio_setbits_32(APSREG_CCI500_AUX, APSREG_CCI500_AUX_INIT);
267 	mmio_setbits_32(APSREG_P_CCI500_AUX, APSREG_P_CCI500_AUX_INIT);
268 
269 	rcar_lock_init();
270 }
271 
272 uint32_t rcar_pwrc_get_mpidr_cluster(u_register_t mpidr)
273 {
274 	int32_t cluster = rcar_cluster_pos_by_mpidr(mpidr);
275 
276 	if (cluster < 0) {
277 		ERROR("BL3-1 : The value of passed MPIDR is invalid.");
278 		panic();
279 	}
280 
281 	return (uint32_t)cluster;
282 }
283 
284 uint32_t rcar_pwrc_cpu_on_check(u_register_t mpidr)
285 {
286 	uint32_t core_pos, cpu, i, j, prr, state;
287 	uint32_t count = 0;
288 
289 	core_pos = rcar_pwrc_core_pos(mpidr);
290 	prr = mmio_read_32(RCAR_PRR) >> 17;
291 	for (i = 0; i < PLATFORM_CLUSTER_COUNT; i++) {
292 		prr >>= 3;
293 
294 		/* check the cluster has cores */
295 		if ((prr & PRR_CAXX_XX_EN_CLUSTER_MASK) != RCAR_CPU_HAVE_CAXX)
296 			continue;
297 
298 		for (j = 0; j < PLATFORM_MAX_CPUS_PER_CLUSTER; j++) {
299 			cpu = (i * PLATFORM_MAX_CPUS_PER_CLUSTER) + j;
300 
301 			/* check the core be implemented */
302 			if ((prr & prr_caxx_xx_en_cpu(cpu)) != RCAR_CPU_HAVE_CAXX)
303 				continue;
304 
305 			if (core_pos != cpu) {
306 				state = mmio_read_32(rcar_apmu_fsmstsrc(cpu));
307 				if (state != RCAR_APMU_FSMSTSRC_STATE_OFF)
308 					count++;
309 			}
310 		}
311 	}
312 
313 	return count;
314 }
315 
316 static void rcar_pwrc_save_timer_state(void)
317 {
318 	rcar_pwrc_saved_cntpct_el0 = read_cntpct_el0();
319 
320 	rcar_pwrc_saved_cntfid =
321 		mmio_read_32((uintptr_t)(RCAR_CNTC_BASE + CNTFID_OFF));
322 }
323 
324 void rcar_pwrc_restore_timer_state(void)
325 {
326 	/* Stop timer before restoring counter value */
327 	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + CNTCR_OFF), 0U);
328 
329 	/* restore lower counter value */
330 	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVL_OFF),
331 		(uint32_t)(rcar_pwrc_saved_cntpct_el0 & 0xFFFFFFFFU));
332 	/* restore upper counter value */
333 	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + RCAR_CNTCVU_OFF),
334 		(uint32_t)(rcar_pwrc_saved_cntpct_el0 >> 32U));
335 	/* restore counter frequency setting */
336 	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + CNTFID_OFF),
337 		rcar_pwrc_saved_cntfid);
338 
339 	/* Start generic timer back */
340 	write_cntfrq_el0((u_register_t)plat_get_syscnt_freq2());
341 
342 	mmio_write_32((uintptr_t)(RCAR_CNTC_BASE + CNTCR_OFF),
343 			CNTCR_FCREQ((uint32_t)(0)) | CNTCR_EN);
344 }
345 
346 static void __section(".system_ram") rcar_pwrc_set_self_refresh(void)
347 {
348 	uint64_t base_count, freq, get_count, wait_time;
349 	uint32_t reg;
350 
351 	/* Enable DBSC4 register access */
352 	mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_ENABLE);
353 
354 	/* DFI_PHYMSTR_ACK setting */
355 	mmio_clrbits_32(DBSC4_REG_DBDFIPMSTRCNF, DBSC4_BIT_DBDFIPMSTRCNF_PMSTREN);
356 
357 	/* Set the Self-Refresh mode */
358 
359 	/* Disable access to the SDRAM */
360 	mmio_write_32(DBSC4_REG_DBACEN, 0);
361 
362 	/* Flush the access request in DBSC */
363 	mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
364 
365 	/* Wait succeed to flush */
366 	freq = read_cntfrq_el0();
367 	base_count = read_cntpct_el0();
368 
369 	while ((mmio_read_32(DBSC4_REG_DBCAM0STAT0) & DBSC4_BIT_DBCAM0STAT0)
370 			!= DBSC4_BIT_DBCAM0STAT0) {
371 
372 		get_count = read_cntpct_el0();
373 		wait_time = ((get_count - base_count) * RCAR_CONV_MICROSEC) / freq;
374 
375 		/* Get base counter */
376 		if (wait_time >= RCAR_WAIT_DBCS4_FLUSH) {
377 
378 			/* Stop flushing and enable access to SDRAM */
379 			mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 0);
380 			mmio_write_32(DBSC4_REG_DBACEN, 1);
381 
382 			/* Dummy write to SDRAM */
383 			dummy_sdram = ~dummy_sdram;
384 
385 			/* Re-Disable access and flush */
386 			mmio_write_32(DBSC4_REG_DBACEN, 0);
387 			mmio_write_32(DBSC4_REG_DBCAM0CTRL0, 1);
388 
389 			/* refresh base counter */
390 			base_count = read_cntpct_el0();
391 		}
392 	}
393 
394 	/* Clear the SDRAM calibration configuration register */
395 	mmio_write_32(DBSC4_REG_DBCALCNF, 0);
396 
397 	/* Issue Precharge All (PREA) command */
398 	reg = DBSC4_SET_DBCMD_OPC_PRE | DBSC4_SET_DBCMD_CH_ALL |
399 	      DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ALL;
400 	mmio_write_32(DBSC4_REG_DBCMD, reg);
401 
402 	/* Wait to complete PREA operation */
403 	while (mmio_read_32(DBSC4_REG_DBWAIT) != 0)
404 		;
405 
406 	/* Issue Self-Refresh Entry (SRE) command   */
407 	reg = DBSC4_SET_DBCMD_OPC_SR | DBSC4_SET_DBCMD_CH_ALL |
408 	      DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
409 	mmio_write_32(DBSC4_REG_DBCMD, reg);
410 
411 	/* Wait to complete SRE operation */
412 	while (mmio_read_32(DBSC4_REG_DBWAIT) != 0)
413 		;
414 
415 	/* Issue Mode Register 11 (MR11) write command. (ODT disabled)  */
416 	reg = DBSC4_SET_DBCMD_OPC_MRW | DBSC4_SET_DBCMD_CH_ALL |
417 	      DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_MRW_ODTC;
418 	mmio_write_32(DBSC4_REG_DBCMD, reg);
419 
420 	/* Wait to complete MR11 operation */
421 	while (mmio_read_32(DBSC4_REG_DBWAIT) != 0)
422 		;
423 
424 	/* Issue Power Down (PD) command */
425 	reg = DBSC4_SET_DBCMD_OPC_PD | DBSC4_SET_DBCMD_CH_ALL |
426 	      DBSC4_SET_DBCMD_RANK_ALL | DBSC4_SET_DBCMD_ARG_ENTER;
427 	mmio_write_32(DBSC4_REG_DBCMD, reg);
428 
429 	/* Wait to complete PD operation */
430 	while (mmio_read_32(DBSC4_REG_DBWAIT) != 0)
431 		;
432 
433 	/* Issue set the Auto-Refresh Enable register */
434 	/* to stop the auto-refresh function */
435 	mmio_write_32(DBSC4_REG_DBRFEN, 0);
436 
437 	/* Dummy read DBWAIT register to wait tCKELPD time */
438 	(void)mmio_read_32(DBSC4_REG_DBWAIT);
439 
440 	/* Disable DBSC4 register access */
441 	mmio_write_32(DBSC4_REG_DBSYSCNT0, DBSC4_SET_DBSYSCNT0_WRITE_DISABLE);
442 }
443 
444 static void __section(".system_ram") __attribute__ ((noinline))
445 		rcar_pwrc_go_suspend_to_ram(void)
446 {
447 	rcar_pwrc_set_self_refresh();
448 
449 	wfi();
450 
451 	/* Do not return */
452 	while (true)
453 		;
454 }
455 
456 void rcar_pwrc_suspend_to_ram(void)
457 {
458 	uintptr_t jump = (uintptr_t) rcar_pwrc_go_suspend_to_ram;
459 	uintptr_t stack = (uintptr_t) (DEVICE_SRAM_STACK_BASE +
460 				       DEVICE_SRAM_STACK_SIZE);
461 
462 	rcar_pwrc_save_timer_state();
463 
464 	/* Clear code copy state to execute copy on next boot time */
465 	rcar_pwrc_code_copy_state = RCAR_CODE_COPY_NONE;
466 
467 	/* disable MMU */
468 	disable_mmu_el3();
469 
470 	/* cache flush */
471 	dcsw_op_all(DCCISW);
472 
473 	(void)rcar_pwrc_switch_stack(jump, stack, NULL);
474 }
475 
476 void rcar_pwrc_code_copy_to_system_ram(void)
477 {
478 	int __maybe_unused ret;
479 	uint32_t attr;
480 	struct {
481 		uintptr_t	base;
482 		size_t		len;
483 	} sram = {
484 		.base	= (uintptr_t) DEVICE_SRAM_BASE,
485 		.len	= DEVICE_SRAM_SIZE
486 	}, code = {
487 		.base	= (uintptr_t) SRAM_COPY_START,
488 		.len	= (size_t)(SYSTEM_RAM_END - SYSTEM_RAM_START)
489 	};
490 
491 	/*
492 	 * The copy of the code should only be executed for ColdBoot,
493 	 * and for WarmBoot from SuspendToRAM.
494 	 */
495 	if (rcar_pwrc_code_copy_state == RCAR_CODE_COPY_DONE) {
496 		/* No need to run because it has already been copied */
497 		return;
498 	}
499 
500 	rcar_pwrc_code_copy_state = RCAR_CODE_COPY_DONE;
501 	flush_dcache_range((uintptr_t)(&rcar_pwrc_code_copy_state),
502 			   sizeof(rcar_pwrc_code_copy_state));
503 
504 	attr = MT_MEMORY | MT_RW | MT_SECURE | MT_EXECUTE_NEVER;
505 	ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
506 	assert(ret == 0);
507 
508 	(void)memcpy((void *)sram.base, (void *)code.base, code.len);
509 	flush_dcache_range(sram.base, code.len);
510 
511 	/* Invalidate instruction cache */
512 	plat_invalidate_icache();
513 	dsb();
514 	isb();
515 
516 	attr = MT_MEMORY | MT_RO | MT_SECURE | MT_EXECUTE;
517 	ret = xlat_change_mem_attributes(sram.base, sram.len, attr);
518 	assert(ret == 0);
519 
520 	/* clean up data and stack area in system ram */
521 	(void)memset((void *)DEVICE_SRAM_DATA_BASE, 0x0,
522 		     DEVICE_SRAM_DATA_SIZE + DEVICE_SRAM_STACK_SIZE);
523 	flush_dcache_range((uintptr_t)DEVICE_SRAM_DATA_BASE,
524 			   DEVICE_SRAM_DATA_SIZE + DEVICE_SRAM_STACK_SIZE);
525 }
526