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