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