/******************************************************************************* * PSCI Compatibility helper function to return the state id of the current * cpu encoded in the 'power_state' parameter. Returns PSCI_INVALID_DATA * if not invoked within CPU_SUSPEND for the current CPU. ******************************************************************************/ int psci_get_suspend_stateid(void) { unsigned int power_state; power_state = psci_get_suspend_powerstate(); if (power_state != PSCI_INVALID_DATA) return psci_get_pstate_id(power_state); return PSCI_INVALID_DATA; }
/******************************************************************************* * This function gets the state id of the current cpu from the power state * parameter saved in the per-cpu data array. Returns PSCI_INVALID_DATA if the * power state saved is invalid. ******************************************************************************/ int psci_get_suspend_stateid() { unsigned int power_state; power_state = get_cpu_data(psci_svc_cpu_data.power_state); return ((power_state == PSCI_INVALID_DATA) ? power_state : psci_get_pstate_id(power_state)); }
/******************************************************************************* * This function gets the state id of the cpu specified by the 'mpidr' parameter * from the power state parameter saved in the per-cpu data array. Returns * PSCI_INVALID_DATA if the power state saved is invalid. ******************************************************************************/ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr) { unsigned int power_state; power_state = get_cpu_data_by_mpidr(mpidr, psci_svc_cpu_data.power_state); return ((power_state == PSCI_INVALID_DATA) ? power_state : psci_get_pstate_id(power_state)); }
/******************************************************************************* * PSCI Compatibility helper function to return the state id encoded in the * 'power_state' parameter of the CPU specified by 'mpidr'. Returns * PSCI_INVALID_DATA if the CPU is not in CPU_SUSPEND. ******************************************************************************/ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr) { int cpu_idx = plat_core_pos_by_mpidr(mpidr); if (cpu_idx == -1) return PSCI_INVALID_DATA; /* Sanity check to verify that the CPU is in CPU_SUSPEND */ if (psci_get_aff_info_state_by_idx(cpu_idx) == AFF_STATE_ON && !is_local_state_run(psci_get_cpu_local_state_by_idx(cpu_idx))) return psci_get_pstate_id(psci_power_state_compat[cpu_idx]); return PSCI_INVALID_DATA; }
static int32_t poplar_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { VERBOSE("%s: power_state: 0x%x\n", __func__, power_state); int pstate = psci_get_pstate_type(power_state); assert(req_state); /* Sanity check the requested state */ if (pstate == PSTATE_TYPE_STANDBY) req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; else req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE; /* We expect the 'state id' to be zero */ if (psci_get_pstate_id(power_state)) return PSCI_E_INVALID_PARAMS; return PSCI_E_SUCCESS; }
/******************************************************************************* * Rockchip standard platform handler called to check the validity of the power * state parameter. ******************************************************************************/ int rockchip_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { int pstate = psci_get_pstate_type(power_state); int pwr_lvl = psci_get_pstate_pwrlvl(power_state); int i; assert(req_state); if (pwr_lvl > PLAT_MAX_PWR_LVL) return PSCI_E_INVALID_PARAMS; /* Sanity check the requested state */ if (pstate == PSTATE_TYPE_STANDBY) { /* * It's probably to enter standby only on power level 0 * ignore any other power level. */ if (pwr_lvl != MPIDR_AFFLVL0) return PSCI_E_INVALID_PARAMS; req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; } else { for (i = MPIDR_AFFLVL0; i <= pwr_lvl; i++) req_state->pwr_domain_state[i] = PLAT_MAX_OFF_STATE; for (i = (pwr_lvl + 1); i <= PLAT_MAX_PWR_LVL; i++) req_state->pwr_domain_state[i] = PLAT_MAX_RET_STATE; } /* We expect the 'state id' to be zero */ if (psci_get_pstate_id(power_state)) return PSCI_E_INVALID_PARAMS; return PSCI_E_SUCCESS; }
static int stm32_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { int pstate = psci_get_pstate_type(power_state); if (pstate != 0) { return PSCI_E_INVALID_PARAMS; } if (psci_get_pstate_pwrlvl(power_state)) { return PSCI_E_INVALID_PARAMS; } if (psci_get_pstate_id(power_state)) { return PSCI_E_INVALID_PARAMS; } req_state->pwr_domain_state[0] = ARM_LOCAL_STATE_RET; req_state->pwr_domain_state[1] = ARM_LOCAL_STATE_RUN; return PSCI_E_SUCCESS; }
int32_t tegra_soc_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { int state_id = psci_get_pstate_id(power_state) & TEGRA186_STATE_ID_MASK; int cpu = plat_my_core_pos(); /* save the core wake time (in TSC ticks)*/ percpu_data[cpu].wake_time = (power_state & TEGRA186_WAKE_TIME_MASK) << TEGRA186_WAKE_TIME_SHIFT; /* * Clean percpu_data[cpu] to DRAM. This needs to be done to ensure that * the correct value is read in tegra_soc_pwr_domain_suspend(), which * is called with caches disabled. It is possible to read a stale value * from DRAM in that function, because the L2 cache is not flushed * unless the cluster is entering CC6/CC7. */ clean_dcache_range((uint64_t)&percpu_data[cpu], sizeof(percpu_data[cpu])); /* Sanity check the requested state id */ switch (state_id) { case PSTATE_ID_CORE_IDLE: case PSTATE_ID_CORE_POWERDN: /* Core powerdown request */ req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; break; default: ERROR("%s: unsupported state id (%d)\n", __func__, state_id); return PSCI_E_INVALID_PARAMS; } return PSCI_E_SUCCESS; }
/******************************************************************************* * Platform handler called to check the validity of the power state * parameter. The power state parameter has to be a composite power state. ******************************************************************************/ static int rpi3_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { unsigned int state_id; int i; assert(req_state != 0); /* * Currently we are using a linear search for finding the matching * entry in the idle power state array. This can be made a binary * search if the number of entries justify the additional complexity. */ for (i = 0; rpi3_pm_idle_states[i] != 0; i++) { if (power_state == rpi3_pm_idle_states[i]) { break; } } /* Return error if entry not found in the idle state array */ if (!rpi3_pm_idle_states[i]) { return PSCI_E_INVALID_PARAMS; } i = 0; state_id = psci_get_pstate_id(power_state); /* Parse the State ID and populate the state info parameter */ while (state_id) { req_state->pwr_domain_state[i++] = state_id & PLAT_LOCAL_PSTATE_MASK; state_id >>= PLAT_LOCAL_PSTATE_WIDTH; } return PSCI_E_SUCCESS; }