static int cpus_power_domain_off(uint32_t cpu_id, uint32_t pd_cfg) { uint32_t cpu_pd; uint32_t core_pm_value; cpu_pd = PD_CPUL0 + cpu_id; if (pmu_power_domain_st(cpu_pd) == pmu_pd_off) return 0; if (pd_cfg == core_pwr_pd) { if (check_cpu_wfie(cpu_id, CKECK_WFEI_MSK)) return -EINVAL; /* disable core_pm cfg */ mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg); pmu_power_domain_ctr(cpu_pd, pmu_pd_off); } else { set_cpus_pwr_domain_cfg_info(cpu_id, pd_cfg); core_pm_value = BIT(core_pm_en); if (pd_cfg == core_pwr_wfi_int) core_pm_value |= BIT(core_pm_int_wakeup_en); mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), core_pm_value); dsb(); } return 0; }
static int cpus_power_domain_on(uint32_t cpu_id) { uint32_t cfg_info; uint32_t cpu_pd = PD_CPUL0 + cpu_id; /* * There are two ways to powering on or off on core. * 1) Control it power domain into on or off in PMU_PWRDN_CON reg * 2) Enable the core power manage in PMU_CORE_PM_CON reg, * then, if the core enter into wfi, it power domain will be * powered off automatically. */ cfg_info = get_cpus_pwr_domain_cfg_info(cpu_id); if (cfg_info == core_pwr_pd) { /* disable core_pm cfg */ mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), CORES_PM_DISABLE); /* if the cores have be on, power off it firstly */ if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) { mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), 0); pmu_power_domain_ctr(cpu_pd, pmu_pd_off); } pmu_power_domain_ctr(cpu_pd, pmu_pd_on); } else { if (pmu_power_domain_st(cpu_pd) == pmu_pd_on) { WARN("%s: cpu%d is not in off,!\n", __func__, cpu_id); return -EINVAL; } mmio_write_32(PMU_BASE + PMU_CORE_PM_CON(cpu_id), BIT(core_pm_sft_wakeup_en)); dsb(); } return 0; }
static int cpus_id_power_domain(uint32_t cluster, uint32_t cpu, uint32_t pd_state, uint32_t wfie_msk) { uint32_t pd; uint64_t mpidr; if (cluster) pd = PD_CPUB0 + cpu; else pd = PD_CPUL0 + cpu; if (pmu_power_domain_st(pd) == pd_state) return 0; if (pd_state == pmu_pd_off) { mpidr = (cluster << MPIDR_AFF1_SHIFT) | cpu; if (check_cpu_wfie(mpidr, wfie_msk)) return -EINVAL; } return pmu_power_domain_ctr(pd, pd_state); }