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