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