1 /* 2 * Copyright 2021-2024 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <stdbool.h> 8 9 #include <arch.h> 10 #include <arch_helpers.h> 11 #include <common/debug.h> 12 #include <drivers/arm/gicv3.h> 13 #include <drivers/delay_timer.h> 14 #include <lib/mmio.h> 15 #include <lib/psci/psci.h> 16 17 #include <plat_imx8.h> 18 #include <upower_api.h> 19 20 extern void cgc1_save(void); 21 extern void cgc1_restore(void); 22 extern void imx_apd_ctx_save(unsigned int cpu); 23 extern void imx_apd_ctx_restore(unsigned int cpu); 24 extern void usb_wakeup_enable(bool enable); 25 extern void upower_wait_resp(void); 26 extern bool is_lpav_owned_by_apd(void); 27 extern void apd_io_pad_off(void); 28 extern int upower_pmic_i2c_read(uint32_t reg_addr, uint32_t *reg_val); 29 extern void imx8ulp_init_scmi_server(void); 30 31 static uintptr_t secure_entrypoint; 32 33 #define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0]) 34 #define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1]) 35 #define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL]) 36 37 #define RVBARADDRx(c) (IMX_SIM1_BASE + 0x5c + 0x4 * (c)) 38 #define WKPUx(c) (IMX_SIM1_BASE + 0x3c + 0x4 * (c)) 39 #define AD_COREx_LPMODE(c) (IMX_CMC1_BASE + 0x50 + 0x4 * (c)) 40 41 #define PMIC_CFG(v, m, msk) \ 42 { \ 43 .volt = (v), \ 44 .mode = (m), \ 45 .mode_msk = (msk), \ 46 } 47 48 #define PAD_CFG(c, r, t) \ 49 { \ 50 .pad_close = (c), \ 51 .pad_reset = (r), \ 52 .pad_tqsleep = (t) \ 53 } 54 55 #define BIAS_CFG(m, n, p, mbias) \ 56 { \ 57 .dombias_cfg = { \ 58 .mode = (m), \ 59 .rbbn = (n), \ 60 .rbbp = (p), \ 61 }, \ 62 .membias_cfg = {mbias}, \ 63 } 64 65 #define SWT_BOARD(swt_on, msk) \ 66 { \ 67 .on = (swt_on), \ 68 .mask = (msk), \ 69 } 70 71 #define SWT_MEM(a, p, m) \ 72 { \ 73 .array = (a), \ 74 .perif = (p), \ 75 .mask = (m), \ 76 } 77 78 static int imx_pwr_set_cpu_entry(unsigned int cpu, unsigned int entry) 79 { 80 mmio_write_32(RVBARADDRx(cpu), entry); 81 82 /* set update bit */ 83 mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(24 + cpu)); 84 /* wait for ack */ 85 while (!(mmio_read_32(IMX_SIM1_BASE + 0x8) & BIT_32(26 + cpu))) { 86 } 87 88 /* clear update bit */ 89 mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) & ~BIT_32(24 + cpu)); 90 /* clear ack bit */ 91 mmio_write_32(IMX_SIM1_BASE + 0x8, mmio_read_32(IMX_SIM1_BASE + 0x8) | BIT_32(26 + cpu)); 92 93 return 0; 94 } 95 96 static volatile uint32_t cgc1_nicclk; 97 int imx_pwr_domain_on(u_register_t mpidr) 98 { 99 unsigned int cpu = MPIDR_AFFLVL0_VAL(mpidr); 100 101 imx_pwr_set_cpu_entry(cpu, secure_entrypoint); 102 103 /* slow down the APD NIC bus clock */ 104 cgc1_nicclk = mmio_read_32(IMX_CGC1_BASE + 0x34); 105 mmio_clrbits_32(IMX_CGC1_BASE + 0x34, GENMASK_32(29, 28)); 106 107 mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f); 108 mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0); 109 110 /* enable wku wakeup for idle */ 111 mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0xffffffff); 112 113 return PSCI_E_SUCCESS; 114 } 115 116 void imx_pwr_domain_on_finish(const psci_power_state_t *target_state) 117 { 118 imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY); 119 plat_gic_pcpu_init(); 120 plat_gic_cpuif_enable(); 121 122 /* set APD NIC back to orignally setting */ 123 mmio_write_32(IMX_CGC1_BASE + 0x34, cgc1_nicclk); 124 } 125 126 int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint) 127 { 128 return PSCI_E_SUCCESS; 129 } 130 131 void imx_pwr_domain_off(const psci_power_state_t *target_state) 132 { 133 unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1()); 134 135 plat_gic_cpuif_disable(); 136 137 /* disable wakeup */ 138 mmio_write_32(WKPUx(cpu), 0); 139 140 /* set core power mode to PD */ 141 mmio_write_32(AD_COREx_LPMODE(cpu), 0x3); 142 } 143 144 /* APD power mode config */ 145 ps_apd_pwr_mode_cfgs_t apd_pwr_mode_cfgs = { 146 [DPD_PWR_MODE] = { 147 .swt_board_offs = 0x180, 148 .swt_mem_offs = 0x188, 149 .pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2), 150 .pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a02), 151 .bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0), 152 }, 153 154 /* PD */ 155 [PD_PWR_MODE] = { 156 .swt_board_offs = 0x170, 157 .swt_mem_offs = 0x178, 158 .pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2), 159 .pad_cfg = PAD_CFG(0x0, 0xc, 0x01e80a00), 160 .bias_cfg = BIAS_CFG(0x0, 0x2, 0x2, 0x0), 161 }, 162 163 [ADMA_PWR_MODE] = { 164 .swt_board_offs = 0x120, 165 .swt_mem_offs = 0x128, 166 .pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2), 167 .pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00), 168 .bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0), 169 }, 170 171 [ACT_PWR_MODE] = { 172 .swt_board_offs = 0x110, 173 .swt_mem_offs = 0x118, 174 .pmic_cfg = PMIC_CFG(0x23, 0x0, 0x2), 175 .pad_cfg = PAD_CFG(0x0, 0x0, 0x0deb7a00), 176 .bias_cfg = BIAS_CFG(0x2, 0x2, 0x2, 0x0), 177 }, 178 }; 179 180 /* APD power switch config */ 181 ps_apd_swt_cfgs_t apd_swt_cfgs = { 182 [DPD_PWR_MODE] = { 183 .swt_board[0] = SWT_BOARD(0x0, 0x1fffc), 184 .swt_mem[0] = SWT_MEM(0x0, 0x0, 0x1ffff), 185 .swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0), 186 }, 187 188 [PD_PWR_MODE] = { 189 .swt_board[0] = SWT_BOARD(0x0, 0x00001fffc), 190 .swt_mem[0] = SWT_MEM(0x00010c00, 0x0, 0x1ffff), 191 .swt_mem[1] = SWT_MEM(0x003fffff, 0x003f0000, 0x0), 192 }, 193 194 [ADMA_PWR_MODE] = { 195 .swt_board[0] = SWT_BOARD(0x15f74, 0x15f74), 196 .swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff), 197 .swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0), 198 }, 199 200 [ACT_PWR_MODE] = { 201 .swt_board[0] = SWT_BOARD(0x15f74, 0x15f74), 202 .swt_mem[0] = SWT_MEM(0x0001fffd, 0x0001fffd, 0x1ffff), 203 .swt_mem[1] = SWT_MEM(0x003fffff, 0x003fffff, 0x0), 204 }, 205 }; 206 207 /* PMIC config for power down, LDO1 should be OFF */ 208 ps_apd_pmic_reg_data_cfgs_t pd_pmic_reg_cfgs = { 209 [0] = { 210 .tag = PMIC_REG_VALID_TAG, 211 .power_mode = PD_PWR_MODE, 212 .i2c_addr = 0x30, 213 .i2c_data = 0x9c, 214 }, 215 [1] = { 216 .tag = PMIC_REG_VALID_TAG, 217 .power_mode = PD_PWR_MODE, 218 .i2c_addr = 0x22, 219 .i2c_data = 0xb, 220 }, 221 [2] = { 222 .tag = PMIC_REG_VALID_TAG, 223 .power_mode = ACT_PWR_MODE, 224 .i2c_addr = 0x30, 225 .i2c_data = 0x9d, 226 }, 227 [3] = { 228 .tag = PMIC_REG_VALID_TAG, 229 .power_mode = ACT_PWR_MODE, 230 .i2c_addr = 0x22, 231 .i2c_data = 0x28, 232 }, 233 }; 234 235 /* PMIC config for deep power down, BUCK3 should be OFF */ 236 ps_apd_pmic_reg_data_cfgs_t dpd_pmic_reg_cfgs = { 237 [0] = { 238 .tag = PMIC_REG_VALID_TAG, 239 .power_mode = DPD_PWR_MODE, 240 .i2c_addr = 0x21, 241 .i2c_data = 0x78, 242 }, 243 [1] = { 244 .tag = PMIC_REG_VALID_TAG, 245 .power_mode = DPD_PWR_MODE, 246 .i2c_addr = 0x30, 247 .i2c_data = 0x9c, 248 }, 249 [2] = { 250 .tag = PMIC_REG_VALID_TAG, 251 .power_mode = ACT_PWR_MODE, 252 .i2c_addr = 0x21, 253 .i2c_data = 0x79, 254 }, 255 [3] = { 256 .tag = PMIC_REG_VALID_TAG, 257 .power_mode = ACT_PWR_MODE, 258 .i2c_addr = 0x30, 259 .i2c_data = 0x9d, 260 }, 261 }; 262 263 struct ps_pwr_mode_cfg_t *pwr_sys_cfg = (struct ps_pwr_mode_cfg_t *)UPWR_DRAM_SHARED_BASE_ADDR; 264 265 void imx_set_pwr_mode_cfg(abs_pwr_mode_t mode) 266 { 267 uint32_t volt; 268 269 if (mode >= NUM_PWR_MODES) { 270 return; 271 } 272 273 /* apd power mode config */ 274 memcpy(&pwr_sys_cfg->ps_apd_pwr_mode_cfg[mode], &apd_pwr_mode_cfgs[mode], 275 sizeof(struct ps_apd_pwr_mode_cfg_t)); 276 277 /* apd power switch config */ 278 memcpy(&pwr_sys_cfg->ps_apd_swt_cfg[mode], &apd_swt_cfgs[mode], sizeof(swt_config_t)); 279 280 /* 281 * BUCK3 & LDO1 can only be shutdown when LPAV is owned by APD side 282 * otherwise RTD side is responsible to control them in low power mode. 283 */ 284 if (is_lpav_owned_by_apd()) { 285 /* power off the BUCK3 in DPD mode */ 286 if (mode == DPD_PWR_MODE) { 287 memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &dpd_pmic_reg_cfgs, 288 sizeof(ps_apd_pmic_reg_data_cfgs_t)); 289 /* LDO1 should be power off in PD mode */ 290 } else if (mode == PD_PWR_MODE) { 291 /* overwrite the buck3 voltage setting in active mode */ 292 upower_pmic_i2c_read(0x22, &volt); 293 pd_pmic_reg_cfgs[3].i2c_data = volt; 294 memcpy(&pwr_sys_cfg->ps_apd_pmic_reg_data_cfg, &pd_pmic_reg_cfgs, 295 sizeof(ps_apd_pmic_reg_data_cfgs_t)); 296 } 297 } 298 } 299 300 void imx_domain_suspend(const psci_power_state_t *target_state) 301 { 302 unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1()); 303 304 if (is_local_state_off(CORE_PWR_STATE(target_state))) { 305 plat_gic_cpuif_disable(); 306 imx_pwr_set_cpu_entry(cpu, secure_entrypoint); 307 /* core put into power down */ 308 mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x3); 309 /* FIXME config wakeup interrupt in WKPU */ 310 mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3); 311 } else { 312 /* for core standby/retention mode */ 313 mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x1); 314 mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x7fffffe3); 315 dsb(); 316 write_scr_el3(read_scr_el3() | SCR_FIQ_BIT); 317 isb(); 318 } 319 320 if (is_local_state_retn(CLUSTER_PWR_STATE(target_state))) { 321 /* 322 * just for sleep mode for now, need to update to 323 * support more modes, same for suspend finish call back. 324 */ 325 mmio_write_32(IMX_CMC1_BASE + 0x10, 0x1); 326 mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1); 327 328 } else if (is_local_state_off(CLUSTER_PWR_STATE(target_state))) { 329 /* 330 * for cluster off state, put cluster into power down mode, 331 * config the cluster clock to be off. 332 */ 333 mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7); 334 mmio_write_32(IMX_CMC1_BASE + 0x20, 0xf); 335 } 336 337 if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) { 338 /* 339 * low power mode config info used by upower 340 * to do low power mode transition. 341 */ 342 imx_set_pwr_mode_cfg(ADMA_PWR_MODE); 343 imx_set_pwr_mode_cfg(ACT_PWR_MODE); 344 imx_set_pwr_mode_cfg(PD_PWR_MODE); 345 346 /* clear the upower wakeup */ 347 upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL); 348 upower_wait_resp(); 349 350 /* enable the USB wakeup */ 351 usb_wakeup_enable(true); 352 353 /* config the WUU to enabled the wakeup source */ 354 mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000); 355 356 /* !!! clear all the pad wakeup pending event */ 357 mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff); 358 359 /* enable upower usb phy wakeup by default */ 360 mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4) | BIT(1) | BIT(0)); 361 362 /* enabled all pad wakeup by default */ 363 mmio_write_32(IMX_WUU1_BASE + 0x8, 0xffffffff); 364 365 /* save the AD domain context before entering PD mode */ 366 imx_apd_ctx_save(cpu); 367 } 368 } 369 370 #define DRAM_LPM_STATUS U(0x2802b004) 371 void imx_domain_suspend_finish(const psci_power_state_t *target_state) 372 { 373 unsigned int cpu = MPIDR_AFFLVL0_VAL(read_mpidr_el1()); 374 375 if (is_local_state_off(SYSTEM_PWR_STATE(target_state))) { 376 /* restore the ap domain context */ 377 imx_apd_ctx_restore(cpu); 378 379 /* clear the upower wakeup */ 380 upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL); 381 upower_wait_resp(); 382 383 /* disable all pad wakeup */ 384 mmio_write_32(IMX_WUU1_BASE + 0x8, 0x0); 385 386 /* clear all the pad wakeup pending event */ 387 mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff); 388 389 /* 390 * disable the usb wakeup after resume to make sure the pending 391 * usb wakeup in WUU can be cleared successfully, otherwise, 392 * APD will resume failed in next PD mode. 393 */ 394 usb_wakeup_enable(false); 395 396 /* re-init the SCMI channel */ 397 imx8ulp_init_scmi_server(); 398 } 399 400 /* 401 * wait for DDR is ready when DDR is under the RTD 402 * side control for power saving 403 */ 404 while (mmio_read_32(DRAM_LPM_STATUS) != 0) { 405 ; 406 } 407 408 /* 409 * when resume from low power mode, need to delay for a while 410 * before access the CMC register. 411 */ 412 udelay(5); 413 414 /* clear cluster's LPM setting. */ 415 mmio_write_32(IMX_CMC1_BASE + 0x20, 0x0); 416 mmio_write_32(IMX_CMC1_BASE + 0x10, 0x0); 417 418 /* clear core's LPM setting */ 419 mmio_write_32(IMX_CMC1_BASE + 0x50 + 0x4 * cpu, 0x0); 420 mmio_write_32(IMX_SIM1_BASE + 0x3c + 0x4 * cpu, 0x0); 421 422 if (is_local_state_off(CORE_PWR_STATE(target_state))) { 423 imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY); 424 plat_gic_cpuif_enable(); 425 } else { 426 dsb(); 427 write_scr_el3(read_scr_el3() & (~SCR_FIQ_BIT)); 428 isb(); 429 } 430 } 431 432 void __dead2 imx8ulp_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) 433 { 434 while (1) { 435 wfi(); 436 } 437 } 438 439 void __dead2 imx8ulp_system_reset(void) 440 { 441 imx_pwr_set_cpu_entry(0, IMX_ROM_ENTRY); 442 443 /* Write invalid command to WDOG CNT to trigger reset */ 444 mmio_write_32(IMX_WDOG3_BASE + 0x4, 0x12345678); 445 446 while (true) { 447 wfi(); 448 } 449 } 450 451 int imx_validate_power_state(unsigned int power_state, 452 psci_power_state_t *req_state) 453 { 454 int pwr_lvl = psci_get_pstate_pwrlvl(power_state); 455 int pwr_type = psci_get_pstate_type(power_state); 456 457 if (pwr_lvl > PLAT_MAX_PWR_LVL) { 458 return PSCI_E_INVALID_PARAMS; 459 } 460 461 if (pwr_type == PSTATE_TYPE_STANDBY) { 462 CORE_PWR_STATE(req_state) = PLAT_MAX_RET_STATE; 463 CLUSTER_PWR_STATE(req_state) = PLAT_MAX_RET_STATE; 464 } 465 466 /* No power down state support */ 467 if (pwr_type == PSTATE_TYPE_POWERDOWN) { 468 return PSCI_E_INVALID_PARAMS; 469 } 470 471 return PSCI_E_SUCCESS; 472 } 473 474 void imx_get_sys_suspend_power_state(psci_power_state_t *req_state) 475 { 476 unsigned int i; 477 478 for (i = IMX_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++) { 479 req_state->pwr_domain_state[i] = PLAT_POWER_DOWN_OFF_STATE; 480 } 481 } 482 483 void __dead2 imx_system_off(void) 484 { 485 unsigned int i; 486 487 /* config the all the core into OFF mode and IRQ masked. */ 488 for (i = 0U; i < PLATFORM_CORE_COUNT; i++) { 489 /* disable wakeup from wkpu */ 490 mmio_write_32(WKPUx(i), 0x0); 491 492 /* reset the core reset entry to 0x1000 */ 493 imx_pwr_set_cpu_entry(i, 0x1000); 494 495 /* config the core power mode to off */ 496 mmio_write_32(AD_COREx_LPMODE(i), 0x3); 497 } 498 499 plat_gic_cpuif_disable(); 500 501 /* power off all the pad */ 502 apd_io_pad_off(); 503 504 /* Config the power mode info for entering DPD mode and ACT mode */ 505 imx_set_pwr_mode_cfg(ADMA_PWR_MODE); 506 imx_set_pwr_mode_cfg(ACT_PWR_MODE); 507 imx_set_pwr_mode_cfg(DPD_PWR_MODE); 508 509 /* Set the APD domain into DPD mode */ 510 mmio_write_32(IMX_CMC1_BASE + 0x10, 0x7); 511 mmio_write_32(IMX_CMC1_BASE + 0x20, 0x1f); 512 513 /* make sure no pending upower wakeup */ 514 upwr_xcp_set_rtd_apd_llwu(APD_DOMAIN, 0, NULL); 515 upower_wait_resp(); 516 517 /* enable the upower wakeup from wuu, act as APD boot up method */ 518 mmio_write_32(IMX_PCC3_BASE + 0x98, 0xc0800000); 519 mmio_setbits_32(IMX_WUU1_BASE + 0x18, BIT(4)); 520 521 /* make sure no pad wakeup event is pending */ 522 mmio_write_32(IMX_WUU1_BASE + 0x20, 0xffffffff); 523 524 wfi(); 525 526 ERROR("power off failed.\n"); 527 panic(); 528 } 529 530 static const plat_psci_ops_t imx_plat_psci_ops = { 531 .pwr_domain_on = imx_pwr_domain_on, 532 .pwr_domain_on_finish = imx_pwr_domain_on_finish, 533 .validate_ns_entrypoint = imx_validate_ns_entrypoint, 534 .system_off = imx_system_off, 535 .system_reset = imx8ulp_system_reset, 536 .pwr_domain_off = imx_pwr_domain_off, 537 .pwr_domain_suspend = imx_domain_suspend, 538 .pwr_domain_suspend_finish = imx_domain_suspend_finish, 539 .get_sys_suspend_power_state = imx_get_sys_suspend_power_state, 540 .validate_power_state = imx_validate_power_state, 541 .pwr_domain_pwr_down_wfi = imx8ulp_pwr_domain_pwr_down_wfi, 542 }; 543 544 int plat_setup_psci_ops(uintptr_t sec_entrypoint, 545 const plat_psci_ops_t **psci_ops) 546 { 547 secure_entrypoint = sec_entrypoint; 548 imx_pwr_set_cpu_entry(0, sec_entrypoint); 549 *psci_ops = &imx_plat_psci_ops; 550 551 mmio_write_32(IMX_CMC1_BASE + 0x18, 0x3f); 552 mmio_write_32(IMX_SIM1_BASE + 0x3c, 0xffffffff); 553 554 return 0; 555 } 556