1 /* 2 * Copyright (c) 2023-2025, ARM Limited and Contributors. All rights reserved. 3 * 4 * The power management unit (PMU) is designed for controlling power resources. 5 * The PMU is dedicated for managing the power of the whole chip. 6 * 7 * SPDX-License-Identifier: BSD-3-Clause 8 */ 9 10 #include <assert.h> 11 #include <errno.h> 12 13 #include <bakery_lock.h> 14 #include <cortex_a55.h> 15 #include <dsu_def.h> 16 #include <mmio.h> 17 #include <platform.h> 18 #include <platform_def.h> 19 #include <pmu.h> 20 21 #include <cpus_on_fixed_addr.h> 22 #include <plat_private.h> 23 #include <rk3568_clk.h> 24 #include <soc.h> 25 26 /* 27 * Use this macro to instantiate lock before it is used in below 28 * rockchip_pd_lock_xxx() macros 29 */ 30 DECLARE_BAKERY_LOCK(rockchip_pd_lock); 31 32 static uint32_t grf_ddr_con3; 33 static struct psram_data_t *psram_sleep_cfg = 34 (struct psram_data_t *)&sys_sleep_flag_sram; 35 36 /* 37 * These are wrapper macros to the powe domain Bakery Lock API. 38 */ 39 #define rockchip_pd_lock_init() bakery_lock_init(&rockchip_pd_lock) 40 #define rockchip_pd_lock_get() bakery_lock_get(&rockchip_pd_lock) 41 #define rockchip_pd_lock_rls() bakery_lock_release(&rockchip_pd_lock) 42 43 void __dead2 rockchip_soc_sys_pd_pwr_dn_wfi(void) 44 { 45 uint64_t ctrl; 46 47 __asm__ volatile ("mrs %0, " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) : "=r" (ctrl)); 48 ctrl |= 0x01; 49 __asm__ volatile ("msr " __XSTRING(CORTEX_A55_CPUPWRCTLR_EL1) ", %0" : : "r" (ctrl)); 50 isb(); 51 52 while (1) 53 wfi(); 54 } 55 56 static void pmu_pmic_sleep_mode_config(void) 57 { 58 /* pmic sleep function selection 59 * 1'b0: From reset pulse generator, can reset external PMIC 60 * 1'b1: From pmu block, only support sleep function for external PMIC 61 */ 62 mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), WRITE_MASK_SET(BIT(7))); 63 mmio_write_32(PMUGRF_BASE + PMU_GRF_GPIO0A_IOMUX_L, PMIC_SLEEP_FUN); 64 } 65 66 static void pmu_wakeup_source_config(void) 67 { 68 /* config wakeup source */ 69 mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, WRITE_MASK_SET(BIT(WAKEUP_GPIO0_INT_EN))); 70 71 INFO("WAKEUP: PMU_WAKEUP_INT_CON:0x%x, reg: 0x%x\n", 72 mmio_read_32(PMU_BASE + PMU_WAKEUP_INT_CON), PMU_WAKEUP_INT_CON); 73 } 74 75 static void pmu_pll_powerdown_config(void) 76 { 77 uint32_t pll_id; 78 79 /* PLL power down by PMU */ 80 pll_id = BIT(APLL_PD_ENA) | 81 BIT(CPLL_PD_ENA) | 82 BIT(GPLL_PD_ENA) | 83 BIT(MPLL_PD_ENA) | 84 BIT(NPLL_PD_ENA) | 85 BIT(HPLL_PD_ENA) | 86 BIT(PPLL_PD_ENA) | 87 BIT(VPLL_PD_ENA); 88 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(pll_id)); 89 INFO("PLL: PMU_PLLPD_CON(0x%x):0x%x\n", 90 PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON)); 91 } 92 93 static void pmu_stable_count_config(void) 94 { 95 mmio_write_32(PMU_BASE + PMU_DSU_STABLE_CNT, 0x180); 96 mmio_write_32(PMU_BASE + PMU_PMIC_STABLE_CNT, 0x180); 97 mmio_write_32(PMU_BASE + PMU_OSC_STABLE_CNT, 0x180); 98 mmio_write_32(PMU_BASE + PMU_WAKEUP_RSTCLR_CNT, 0x180); 99 mmio_write_32(PMU_BASE + PMU_PLL_LOCK_CNT, 0x180); 100 mmio_write_32(PMU_BASE + PMU_DSU_PWRUP_CNT, 0x180); 101 mmio_write_32(PMU_BASE + PMU_DSU_PWRDN_CNT, 0x180); 102 mmio_write_32(PMU_BASE + PMU_GPU_VOLUP_CNT, 0x180); 103 mmio_write_32(PMU_BASE + PMU_GPU_VOLDN_CNT, 0x180); 104 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x180); 105 mmio_write_32(PMU_BASE + PMU_PWM_SWITCH_CNT, 0x180); 106 mmio_write_32(PMU_BASE + PMU_DBG_RST_CNT, 0x180); 107 } 108 109 static void pmu_pd_powerdown_config(void) 110 { 111 uint32_t pwr_gate_con, pwr_dwn_st, pmu_bus_idle_con0 = 0; 112 uint32_t pmu_bus_idle_con1; 113 114 /* Pd power down by PMU */ 115 pwr_dwn_st = mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST); 116 pwr_gate_con = ~pwr_dwn_st & 0x3ff; 117 118 if (pwr_gate_con & BIT(PD_GPU_DWN_ENA)) { 119 pmu_bus_idle_con0 |= BIT(IDLE_REQ_GPU); 120 } 121 122 if (pwr_gate_con & BIT(PD_NPU_DWN_ENA)) { 123 pmu_bus_idle_con0 |= BIT(IDLE_REQ_NPU); 124 } 125 126 if (pwr_gate_con & BIT(PD_RKVENC_DWN_ENA)) { 127 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVENC); 128 } 129 130 if (pwr_gate_con & BIT(PD_RKVDEC_DWN_ENA)) { 131 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RKVDEC); 132 } 133 134 if (pwr_gate_con & BIT(PD_RGA_DWN_ENA)) { 135 pmu_bus_idle_con0 |= BIT(IDLE_REQ_RGA); 136 } 137 138 if (pwr_gate_con & BIT(PD_VI_DWN_ENA)) { 139 pmu_bus_idle_con0 |= BIT(IDLE_REQ_VI); 140 } 141 142 if (pwr_gate_con & BIT(PD_VO_DWN_ENA)) { 143 pmu_bus_idle_con0 |= BIT(IDLE_REQ_VO); 144 } 145 146 if (pwr_gate_con & BIT(PD_PIPE_DWN_ENA)) { 147 pmu_bus_idle_con0 |= BIT(IDLE_REQ_PIPE); 148 } 149 150 pmu_bus_idle_con0 |= BIT(IDLE_REQ_GIC_AUDIO) | 151 BIT(IDLE_REQ_MSCH) | 152 BIT(IDLE_REQ_PHP) | 153 BIT(IDLE_REQ_SECURE_FLASH) | 154 BIT(IDLE_REQ_PERIMID) | 155 BIT(IDLE_REQ_USB) | 156 BIT(IDLE_REQ_BUS); 157 158 /* Enable power down PD by PMU automatically */ 159 pwr_gate_con |= (BIT(PD_GPU_DWN_ENA) | 160 BIT(PD_NPU_DWN_ENA) | 161 BIT(PD_VPU_DWN_ENA) | 162 BIT(PD_RKVENC_DWN_ENA) | 163 BIT(PD_RKVDEC_DWN_ENA) | 164 BIT(PD_RGA_DWN_ENA) | 165 BIT(PD_VI_DWN_ENA) | 166 BIT(PD_VO_DWN_ENA) | 167 BIT(PD_PIPE_DWN_ENA)) << 16; 168 169 pmu_bus_idle_con1 = 0; 170 171 mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, pwr_gate_con); 172 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, WRITE_MASK_SET(pmu_bus_idle_con0)); 173 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, WRITE_MASK_SET(pmu_bus_idle_con1)); 174 175 /* When perform idle operation, 176 * corresponding clock can be opened or gated automatically 177 */ 178 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff); 179 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007); 180 181 mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, WRITE_MASK_SET(BIT(VD_NPU_ENA))); 182 183 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(PWRDN_BYPASS))); 184 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(BUS_BYPASS))); 185 186 INFO("PD & BUS:PMU_PWR_DWN_ST(0x%x):0x%x\n", 187 PMU_PWR_DWN_ST, mmio_read_32(PMU_BASE + PMU_PWR_DWN_ST)); 188 INFO("PD & BUS:PMU_PWR_GATE_CON(0x%x):0x%x\n", 189 PMU_PWR_GATE_CON, mmio_read_32(PMU_BASE + PMU_PWR_GATE_CON)); 190 INFO("PD & BUS:PMU_BUS_IDLE_CON0(0x%x):0x%x\n", 191 PMU_BUS_IDLE_CON0, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON0)); 192 INFO("PD & BUS:PMU_BUS_IDLE_CON1(0x%x):0x%x\n", 193 PMU_BUS_IDLE_CON1, mmio_read_32(PMU_BASE + PMU_BUS_IDLE_CON1)); 194 INFO("PD & BUS:PMU_PWR_CON(0x%x):0x%x\n", 195 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON)); 196 } 197 198 static void pmu_ddr_suspend_config(void) 199 { 200 uint32_t pmu_ddr_pwr_con; 201 202 pmu_ddr_pwr_con = BIT(DDR_SREF_ENA) | 203 BIT(DDRIO_RET_ENTER_ENA) | 204 BIT(DDRIO_RET_EXIT_ENA) | 205 BIT(DDRPHY_AUTO_GATING_ENA); 206 207 mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, WRITE_MASK_SET(pmu_ddr_pwr_con)); 208 /* DPLL power down by PMU */ 209 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, WRITE_MASK_SET(BIT(DPLL_PD_ENA))); 210 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DDR_BYPASS))); 211 212 grf_ddr_con3 = mmio_read_32(DDRGRF_BASE + GRF_DDR_CON3); 213 214 mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, 0x00600020); 215 216 pmu_ddr_pwr_con = mmio_read_32(PMU_BASE + PMU_DDR_PWR_CON); 217 218 INFO("DDR: PMU_PLLPD_CON(0x%x):0x%x\n", 219 PMU_PLLPD_CON, mmio_read_32(PMU_BASE + PMU_PLLPD_CON)); 220 INFO("DDR: PMU_DDR_PWR_CON(0x%x):\t0x%x\n", 221 PMU_DDR_PWR_CON, pmu_ddr_pwr_con); 222 223 if (pmu_ddr_pwr_con & BIT(DDR_SREF_ENA)) { 224 INFO("\t DDR_SREF_ENA\n"); 225 } 226 227 if (pmu_ddr_pwr_con & BIT(DDRIO_RET_ENTER_ENA)) { 228 INFO("\t DDRIO_RET_ENTER_ENA\n"); 229 } 230 231 if (pmu_ddr_pwr_con & BIT(DDRIO_RET_EXIT_ENA)) { 232 INFO("\t DDRIO_RET_EXIT_ENA\n"); 233 } 234 235 if (pmu_ddr_pwr_con & BIT(DDRPHY_AUTO_GATING_ENA)) { 236 INFO("\t DDRPHY_AUTO_GATING_ENA\n"); 237 } 238 } 239 240 static void pmu_dsu_suspend_config(void) 241 { 242 uint32_t pmu_dsu_pwr_con; 243 244 pmu_dsu_pwr_con = BIT(DSU_PWRDN_ENA); 245 246 mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0x000f000f); 247 mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, WRITE_MASK_SET(pmu_dsu_pwr_con)); 248 mmio_write_32(PMU_BASE + PMU_PWR_CON, WRITE_MASK_CLR(BIT(DSU_BYPASS))); 249 dsu_pwr_dwn(); 250 251 INFO("DSU: PMU_DSU_PWR_CON(0x%x): 0x%x\n", 252 PMU_DSU_PWR_CON, mmio_read_32(PMU_BASE + PMU_DSU_PWR_CON)); 253 INFO("DSU: PMU_CLUSTER_IDLE_CON(0x%x),: 0x%x\n", 254 PMU_CLUSTER_IDLE_CON, mmio_read_32(PMU_BASE + PMU_CLUSTER_IDLE_CON)); 255 INFO("DSU: PMU_PWR_CON(0x%x),: 0x%x\n", 256 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON)); 257 } 258 259 static void pmu_cpu_powerdown_config(void) 260 { 261 uint32_t pmu_cluster_pwr_st, cpus_state, cpus_bypass; 262 263 pmu_cluster_pwr_st = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST); 264 cpus_state = pmu_cluster_pwr_st & 0x0f; 265 266 cpus_bypass = cpus_state << CPU0_BYPASS; 267 268 INFO("CPU: PMU_CLUSTER_PWR_ST(0x%x):0x%x\n", 269 PMU_CLUSTER_PWR_ST, mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST)); 270 mmio_write_32(PMU_BASE + PMU_PWR_CON, (0xf << (16 + CPU0_BYPASS)) | cpus_bypass); 271 272 INFO("CPU: PMU_PWR_CON(0x%x), 0x%x\n", 273 PMU_PWR_CON, mmio_read_32(PMU_BASE + PMU_PWR_CON)); 274 } 275 276 static void pvtm_32k_config(void) 277 { 278 uint32_t pmu_cru_pwr_con; 279 uint32_t pvtm_freq_khz, pvtm_div; 280 281 mmio_write_32(PMUCRU_BASE + PMUCRU_PMUGATE_CON01, 0x38000000); 282 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00020002); 283 dsb(); 284 285 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x001c0000); 286 287 mmio_write_32(PMUPVTM_BASE + PVTM_CON1, PVTM_CALC_CNT); 288 dsb(); 289 290 mmio_write_32(PMUPVTM_BASE + PVTM_CON0, 0x00010001); 291 dsb(); 292 293 while (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) < 30) { 294 ; 295 } 296 297 dsb(); 298 while (!(mmio_read_32(PMUPVTM_BASE + PVTM_STATUS0) & 0x1)) { 299 ; 300 } 301 302 pvtm_freq_khz = (mmio_read_32(PMUPVTM_BASE + PVTM_STATUS1) * 24000 + 303 PVTM_CALC_CNT / 2) / PVTM_CALC_CNT; 304 pvtm_div = (pvtm_freq_khz + 16) / 32; 305 306 mmio_write_32(PMUGRF_BASE + PMU_GRF_DLL_CON0, pvtm_div); 307 308 mmio_write_32(PMUCRU_BASE + PMUCRU_PMUCLKSEL_CON00, 0x00c00000); 309 310 pmu_cru_pwr_con = BIT(ALIVE_32K_ENA) | BIT(OSC_DIS_ENA); 311 312 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 32000 * 10); 313 314 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con)); 315 INFO("PVTM: PMU_CRU_PWR_CON(0x0%x): 0x%x\n", 316 PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON)); 317 } 318 319 static void pmu_cru_suspendmode_config(void) 320 { 321 uint32_t pmu_cru_pwr_con; 322 323 pmu_cru_pwr_con = BIT(ALIVE_OSC_ENA); 324 325 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(pmu_cru_pwr_con)); 326 INFO("CRU: PMU_CRU_PWR_CON(0x0%x): 0x%x\n", 327 PMU_CRU_PWR_CON, mmio_read_32(PMU_BASE + PMU_CRU_PWR_CON)); 328 } 329 330 static void pmu_suspend_cru_fsm(void) 331 { 332 pmu_pmic_sleep_mode_config(); 333 334 /* Global interrupt disable */ 335 mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, CLB_INT_DISABLE); 336 mmio_write_32(PMU_BASE + PMU_PWR_CON, CPUS_BYPASS); 337 338 pmu_stable_count_config(); 339 pmu_wakeup_source_config(); 340 mmio_write_32(PMU_BASE + PMU_WAKEUP_TIMEOUT_CNT, 0x5dc0 * 20000); 341 /* default cru config */ 342 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, WRITE_MASK_SET(BIT(ALIVE_OSC_ENA))); 343 344 pmu_cru_suspendmode_config(); 345 pmu_cpu_powerdown_config(); 346 pmu_pll_powerdown_config(); 347 pmu_pd_powerdown_config(); 348 pmu_ddr_suspend_config(); 349 pmu_dsu_suspend_config(); 350 pvtm_32k_config(); 351 mmio_write_32(PMU_BASE + PMU_PWR_CON, 0x00010001); 352 } 353 354 static void pmu_reinit(void) 355 { 356 mmio_write_32(DDRGRF_BASE + GRF_DDR_CON3, grf_ddr_con3 | 0xffff0000); 357 mmio_write_32(PMU_BASE + PMU_PWR_CON, 0xffff0000); 358 mmio_write_32(PMU_BASE + PMU_INT_MASK_CON, 0xffff0000); 359 mmio_write_32(PMU_BASE + PMU_WAKEUP_INT_CON, 0xffff0000); 360 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON0, 0xffff0000); 361 mmio_write_32(PMU_BASE + PMU_DDR_PWR_CON, 0xffff0000); 362 mmio_write_32(PMU_BASE + PMU_BUS_IDLE_CON1, 0xffff0000); 363 364 mmio_write_32(PMU_BASE + PMU_PWR_GATE_CON, 0xffff0000); 365 mmio_write_32(PMU_BASE + PMU_VOL_GATE_SFTCON, 0xffff0000); 366 mmio_write_32(PMU_BASE + PMU_CRU_PWR_CON, 0xffff0000); 367 368 mmio_write_32(PMU_BASE + PMU_PLLPD_CON, 0xffff0000); 369 mmio_write_32(PMU_BASE + PMU_INFO_TX_CON, 0xffff0000); 370 mmio_write_32(PMU_BASE + PMU_DSU_PWR_CON, 0xffff0000); 371 mmio_write_32(PMU_BASE + PMU_CLUSTER_IDLE_CON, 0xffff0000); 372 } 373 374 void rockchip_plat_mmu_el3(void) 375 { 376 } 377 378 int rockchip_soc_cores_pwr_dm_suspend(void) 379 { 380 return 0; 381 } 382 383 int rockchip_soc_cores_pwr_dm_resume(void) 384 { 385 return 0; 386 } 387 388 int rockchip_soc_sys_pwr_dm_suspend(void) 389 { 390 pvtplls_suspend(); 391 psram_sleep_cfg->pm_flag = 0; 392 flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag), 393 sizeof(uint32_t)); 394 pmu_suspend_cru_fsm(); 395 396 return 0; 397 } 398 399 int rockchip_soc_sys_pwr_dm_resume(void) 400 { 401 pvtplls_resume(); 402 pmu_reinit(); 403 plat_rockchip_gic_cpuif_enable(); 404 psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT; 405 flush_dcache_range((uintptr_t)&(psram_sleep_cfg->pm_flag), 406 sizeof(uint32_t)); 407 408 return 0; 409 } 410 411 static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg) 412 { 413 uint32_t apm_value, offset, idx; 414 415 apm_value = BIT(core_pm_en) | BIT(core_pm_int_wakeup_glb_msk); 416 417 if (pd_cfg == core_pwr_wfi_int) { 418 apm_value |= BIT(core_pm_int_wakeup_en); 419 } 420 421 idx = cpu_id / 2; 422 offset = (cpu_id % 2) << 3; 423 424 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx), 425 BITS_WITH_WMASK(apm_value, 0xf, offset)); 426 dsb(); 427 428 return 0; 429 } 430 431 static int cpus_power_domain_on(uint32_t cpu_id) 432 { 433 uint32_t offset, idx; 434 435 idx = cpu_id / 2; 436 offset = (cpu_id % 2) << 3; 437 438 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx), 439 WMSK_BIT(core_pm_en + offset)); 440 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx), 441 BIT_WITH_WMSK(core_pm_sft_wakeup_en + offset)); 442 dsb(); 443 444 return 0; 445 } 446 447 int rockchip_soc_cores_pwr_dm_on(unsigned long mpidr, uint64_t entrypoint) 448 { 449 uint32_t cpu_id = plat_core_pos_by_mpidr(mpidr); 450 451 assert(cpu_id < PLATFORM_CORE_COUNT); 452 453 cpuson_flags[cpu_id] = PMU_CPU_HOTPLUG; 454 cpuson_entry_point[cpu_id] = entrypoint; 455 flush_dcache_range((uintptr_t)cpuson_flags, sizeof(cpuson_flags)); 456 flush_dcache_range((uintptr_t)cpuson_entry_point, 457 sizeof(cpuson_entry_point)); 458 459 cpus_power_domain_on(cpu_id); 460 return 0; 461 } 462 463 int rockchip_soc_cores_pwr_dm_off(void) 464 { 465 uint32_t cpu_id = plat_my_core_pos(); 466 467 cpus_power_domain_off(cpu_id, 468 core_pwr_wfi); 469 return 0; 470 } 471 472 int rockchip_soc_cores_pwr_dm_on_finish(void) 473 { 474 uint32_t cpu_id = plat_my_core_pos(); 475 uint32_t offset, idx; 476 477 /* Disable core_pm */ 478 idx = cpu_id / 2; 479 offset = (cpu_id % 2) << 3; 480 mmio_write_32(PMU_BASE + PMU_CPUAPM_CON(idx), 481 BITS_WITH_WMASK(0, 0xf, offset)); 482 483 return 0; 484 } 485 486 static void nonboot_cpus_off(void) 487 { 488 uint32_t tmp; 489 490 cpus_power_domain_off(1, 0); 491 cpus_power_domain_off(2, 0); 492 cpus_power_domain_off(3, 0); 493 494 mmio_write_32(SYSSRAM_BASE + 0x04, 0xdeadbeaf); 495 mmio_write_32(SYSSRAM_BASE + 0x08, (uintptr_t)&rockchip_soc_sys_pd_pwr_dn_wfi); 496 sev(); 497 498 do { 499 tmp = mmio_read_32(PMU_BASE + PMU_CLUSTER_PWR_ST); 500 } while ((tmp & 0xe) != 0xe); 501 } 502 503 void plat_rockchip_pmu_init(void) 504 { 505 uint32_t cpu; 506 507 rockchip_pd_lock_init(); 508 nonboot_cpus_off(); 509 for (cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu++) 510 cpuson_flags[cpu] = PMU_CPU_HOTPLUG; 511 512 psram_sleep_cfg->ddr_data = (uint64_t)0; 513 psram_sleep_cfg->sp = PSRAM_SP_TOP; 514 psram_sleep_cfg->ddr_flag = 0x00; 515 psram_sleep_cfg->boot_mpidr = read_mpidr_el1() & 0xffff; 516 psram_sleep_cfg->pm_flag = PM_WARM_BOOT_BIT; 517 518 /* 519 * When perform idle operation, corresponding clock can be 520 * opened or gated automatically. 521 */ 522 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON0, 0xffffffff); 523 mmio_write_32(PMU_BASE + PMU_NOC_AUTO_CON1, 0x00070007); 524 525 /* grf_con_pmic_sleep_sel 526 * pmic sleep function selection 527 * 1'b0: From reset pulse generator, can reset external PMIC 528 * 1'b1: From pmu block, only support sleep function for external PMIC 529 */ 530 mmio_write_32(PMUGRF_BASE + PMU_GRF_SOC_CON(0), 0x00800080); 531 532 /* 533 * force jtag control 534 * 1'b0: CPU debug port IO mux is controlled by sdmmc_detect_en status 535 * 1'b0: CPU debug port IO mux IS controlled by GRF 536 */ 537 mmio_write_32(SGRF_BASE + 0x008, 0x00100000); 538 539 /* 540 * remap 541 * 2'b00: Boot from boot-rom. 542 * 2'b01: Boot from pmu mem. 543 * 2'b10: Boot from sys mem. 544 */ 545 mmio_write_32(PMUSGRF_BASE + PMU_SGRF_SOC_CON1, 0x18000800); 546 } 547