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