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