/******************************************************************************* * RockChip handler called when a power domain has just been powered on after * being turned off earlier. The target_state encodes the low power state that * each level has woken up from. ******************************************************************************/ void rockchip_pwr_domain_on_finish(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; int ret; assert(RK_CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE); for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { lvl_state = target_state->pwr_domain_state[lvl]; ret = rockchip_soc_hlvl_pwr_dm_on_finish(lvl, lvl_state); if (ret == PSCI_E_NOT_SUPPORTED) break; } rockchip_soc_cores_pwr_dm_on_finish(); /* Perform the common cluster specific operations */ if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { /* Enable coherency if this cluster was off */ plat_cci_enable(); } /* Enable the gic cpu interface */ plat_rockchip_gic_pcpu_init(); /* Program the gic per-cpu distributor or re-distributor interface */ plat_rockchip_gic_cpuif_enable(); }
static int sys_pwr_domain_resume(void) { pmu_sgrf_rst_hld(); mmio_write_32(SGRF_BASE + SGRF_SOC_CON0_1(1), (cpu_warm_boot_addr >> CPU_BOOT_ADDR_ALIGN) | CPU_BOOT_ADDR_WMASK); plls_resume(); mmio_write_32(PMU_BASE + PMU_CCI500_CON, WMSK_BIT(PMU_CLR_PREQ_CCI500_HW) | WMSK_BIT(PMU_CLR_QREQ_CCI500_HW) | WMSK_BIT(PMU_QGATING_CCI500_CFG)); mmio_write_32(PMU_BASE + PMU_ADB400_CON, WMSK_BIT(PMU_CLR_CORE_L_HW) | WMSK_BIT(PMU_CLR_CORE_L_2GIC_HW) | WMSK_BIT(PMU_CLR_GIC2_CORE_L_HW)); mmio_clrbits_32(PMU_BASE + PMU_PWRDN_CON, BIT(PMU_SCU_B_PWRDWN_EN)); mmio_write_32(PMU_BASE + PMU_ADB400_CON, WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_2GIC_SW) | WMSK_BIT(PMU_PWRDWN_REQ_CORE_B_SW) | WMSK_BIT(PMU_PWRDWN_REQ_GIC2_CORE_B_SW)); pmu_scu_b_pwrup(); plat_rockchip_gic_cpuif_enable(); return 0; }
/******************************************************************************* * RockChip handler called when a power domain has just been powered on after * having been suspended earlier. The target_state encodes the low power state * that each level has woken up from. * TODO: At the moment we reuse the on finisher and reinitialize the secure * context. Need to implement a separate suspend finisher. ******************************************************************************/ void rockchip_pwr_domain_suspend_finish(const psci_power_state_t *target_state) { uint32_t lvl; plat_local_state_t lvl_state; /* Nothing to be done on waking up from retention from CPU level */ if (RK_CORE_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) return; /* Perform system domain restore if woken up from system suspend */ if (!rockchip_ops) goto comm_finish; if (RK_SYSTEM_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { if (rockchip_ops->sys_pwr_dm_resume) rockchip_ops->sys_pwr_dm_resume(); goto comm_finish; } if (rockchip_ops->hlvl_pwr_dm_resume) { for (lvl = MPIDR_AFFLVL1; lvl <= PLAT_MAX_PWR_LVL; lvl++) { lvl_state = target_state->pwr_domain_state[lvl]; rockchip_ops->hlvl_pwr_dm_resume(lvl, lvl_state); } } if (rockchip_ops->cores_pwr_dm_resume) rockchip_ops->cores_pwr_dm_resume(); /* * Program the gic per-cpu distributor or re-distributor interface. * For sys power domain operation, resuming of the gic needs to operate * in rockchip_ops->sys_pwr_dm_resume, according to the sys power mode * implements. */ plat_rockchip_gic_cpuif_enable(); comm_finish: /* Perform the common cluster specific operations */ if (RK_CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { /* Enable coherency if this cluster was off */ plat_cci_enable(); } }