mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-16 17:44:19 +00:00
Merge changes from topic "psci-osi" into integration
* changes: fix(psci): add optional pwr_domain_validate_suspend to plat_psci_ops_t fix(sc7280): update pwr_domain_suspend fix(fvp): update pwr_domain_suspend
This commit is contained in:
commit
f4d011b0f0
10 changed files with 41 additions and 54 deletions
|
@ -4,7 +4,7 @@ PSCI OS-initiated mode
|
|||
:Author: Maulik Shah & Wing Li
|
||||
:Organization: Qualcomm Innovation Center, Inc. & Google LLC
|
||||
:Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
|
||||
:Status: RFC
|
||||
:Status: Accepted
|
||||
|
||||
.. contents:: Table of Contents
|
||||
|
||||
|
@ -367,9 +367,11 @@ To add support for OS-initiated mode, the following changes are proposed:
|
|||
``psci_validate_state_coordination``. If validation fails, propagate the
|
||||
error up the call stack.
|
||||
|
||||
* Update the return type of the platform specific ``pwr_domain_suspend``
|
||||
handler from ``void`` to ``int``, to allow the platform to optionally perform
|
||||
validations based on hardware states.
|
||||
* Add a new optional member ``pwr_domain_validate_suspend`` to
|
||||
``plat_psci_ops_t`` to allow the platform to optionally perform validations
|
||||
based on hardware states.
|
||||
|
||||
* The platform specific ``pwr_domain_suspend`` handler remains unchanged.
|
||||
|
||||
.. image:: ../resources/diagrams/psci-osi-mode.png
|
||||
|
||||
|
|
|
@ -2818,6 +2818,17 @@ power down state where as it could be either power down, retention or run state
|
|||
for the higher power domain levels depending on the result of state
|
||||
coordination. The generic code expects the handler to succeed.
|
||||
|
||||
plat_psci_ops.pwr_domain_validate_suspend() [optional]
|
||||
......................................................
|
||||
|
||||
This is an optional function that is only compiled into the build if the build
|
||||
option ``PSCI_OS_INIT_MODE`` is enabled.
|
||||
|
||||
If implemented, this function allows the platform to perform platform specific
|
||||
validations based on hardware states. The generic code expects this function to
|
||||
return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
|
||||
PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
|
||||
|
||||
plat_psci_ops.pwr_domain_suspend_pwrdown_early() [optional]
|
||||
...........................................................
|
||||
|
||||
|
@ -2876,10 +2887,6 @@ allocated in a special area if it cannot fit in the platform's global static
|
|||
data, for example in DRAM. The Distributor can then be powered down using an
|
||||
implementation-defined sequence.
|
||||
|
||||
If the build option ``PSCI_OS_INIT_MODE`` is enabled, the generic code expects
|
||||
the platform to return PSCI_E_SUCCESS on success, or either PSCI_E_DENIED or
|
||||
PSCI_E_INVALID_PARAMS as appropriate for any invalid requests.
|
||||
|
||||
plat_psci_ops.pwr_domain_pwr_down_wfi()
|
||||
.......................................
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 197 KiB |
|
@ -319,13 +319,13 @@ typedef struct plat_psci_ops {
|
|||
int (*pwr_domain_on)(u_register_t mpidr);
|
||||
void (*pwr_domain_off)(const psci_power_state_t *target_state);
|
||||
int (*pwr_domain_off_early)(const psci_power_state_t *target_state);
|
||||
#if PSCI_OS_INIT_MODE
|
||||
int (*pwr_domain_validate_suspend)(
|
||||
const psci_power_state_t *target_state);
|
||||
#endif
|
||||
void (*pwr_domain_suspend_pwrdown_early)(
|
||||
const psci_power_state_t *target_state);
|
||||
#if PSCI_OS_INIT_MODE
|
||||
int (*pwr_domain_suspend)(const psci_power_state_t *target_state);
|
||||
#else
|
||||
void (*pwr_domain_suspend)(const psci_power_state_t *target_state);
|
||||
#endif
|
||||
void (*pwr_domain_on_finish)(const psci_power_state_t *target_state);
|
||||
void (*pwr_domain_on_finish_late)(
|
||||
const psci_power_state_t *target_state);
|
||||
|
|
|
@ -451,8 +451,8 @@ void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
|||
* enter. This function will be called after coordination of requested power
|
||||
* states has been done for each power level.
|
||||
*****************************************************************************/
|
||||
static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
const psci_power_state_t *target_state)
|
||||
void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
const psci_power_state_t *target_state)
|
||||
{
|
||||
unsigned int parent_idx, lvl;
|
||||
const plat_local_state_t *pd_state = target_state->pwr_domain_state;
|
||||
|
@ -474,7 +474,6 @@ static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* PSCI helper function to get the parent nodes corresponding to a cpu_index.
|
||||
******************************************************************************/
|
||||
|
@ -595,9 +594,6 @@ void psci_do_state_coordination(unsigned int end_pwrlvl,
|
|||
state_info->pwr_domain_state[lvl] = PSCI_LOCAL_STATE_RUN;
|
||||
|
||||
}
|
||||
|
||||
/* Update the target state in the power domain nodes */
|
||||
psci_set_target_local_pwr_states(end_pwrlvl, state_info);
|
||||
}
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
|
@ -684,9 +680,6 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Update the target state in the power domain nodes */
|
||||
psci_set_target_local_pwr_states(end_pwrlvl, state_info);
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -104,6 +104,9 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
|
|||
*/
|
||||
psci_do_state_coordination(end_pwrlvl, &state_info);
|
||||
|
||||
/* Update the target state in the power domain nodes */
|
||||
psci_set_target_local_pwr_states(end_pwrlvl, &state_info);
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
/* Update the last cpu for each level till end_pwrlvl */
|
||||
psci_stats_update_pwr_down(end_pwrlvl, &state_info);
|
||||
|
|
|
@ -298,6 +298,8 @@ void psci_restore_req_local_pwr_states(unsigned int cpu_idx,
|
|||
#endif
|
||||
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
psci_power_state_t *target_state);
|
||||
void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||
const psci_power_state_t *target_state);
|
||||
int psci_validate_entry_point(entry_point_info_t *ep,
|
||||
uintptr_t entrypoint, u_register_t context_id);
|
||||
void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
|
||||
|
|
|
@ -219,6 +219,19 @@ int psci_cpu_suspend_start(const entry_point_info_t *ep,
|
|||
}
|
||||
#endif
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
if (psci_plat_pm_ops->pwr_domain_validate_suspend != NULL) {
|
||||
rc = psci_plat_pm_ops->pwr_domain_validate_suspend(state_info);
|
||||
if (rc != PSCI_E_SUCCESS) {
|
||||
skip_wfi = true;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Update the target state in the power domain nodes */
|
||||
psci_set_target_local_pwr_states(end_pwrlvl, state_info);
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
/* Update the last cpu for each level till end_pwrlvl */
|
||||
psci_stats_update_pwr_down(end_pwrlvl, state_info);
|
||||
|
@ -234,15 +247,7 @@ int psci_cpu_suspend_start(const entry_point_info_t *ep,
|
|||
* program the power controller etc.
|
||||
*/
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
rc = psci_plat_pm_ops->pwr_domain_suspend(state_info);
|
||||
if (rc != PSCI_E_SUCCESS) {
|
||||
skip_wfi = true;
|
||||
goto exit;
|
||||
}
|
||||
#else
|
||||
psci_plat_pm_ops->pwr_domain_suspend(state_info);
|
||||
#endif
|
||||
|
||||
#if ENABLE_PSCI_STAT
|
||||
plat_psci_stat_accounting_start(state_info);
|
||||
|
|
|
@ -228,11 +228,7 @@ static void fvp_pwr_domain_off(const psci_power_state_t *target_state)
|
|||
* FVP handler called when a power domain is about to be suspended. The
|
||||
* target_state encodes the power state that each level should transition to.
|
||||
******************************************************************************/
|
||||
#if PSCI_OS_INIT_MODE
|
||||
static int fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
#else
|
||||
static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||
#endif
|
||||
{
|
||||
unsigned long mpidr;
|
||||
|
||||
|
@ -242,11 +238,7 @@ static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
*/
|
||||
if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
||||
ARM_LOCAL_STATE_RET)
|
||||
#if PSCI_OS_INIT_MODE
|
||||
return PSCI_E_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
||||
ARM_LOCAL_STATE_OFF);
|
||||
|
@ -279,11 +271,7 @@ static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
|||
/* Program the power controller to power off this cpu. */
|
||||
fvp_pwrc_write_ppoffr(read_mpidr_el1());
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
return PSCI_E_SUCCESS;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -191,18 +191,6 @@ static void qti_node_power_off(const psci_power_state_t *target_state)
|
|||
}
|
||||
}
|
||||
|
||||
#if PSCI_OS_INIT_MODE
|
||||
static int qti_node_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
qtiseclib_psci_node_suspend((const uint8_t *)target_state->
|
||||
pwr_domain_state);
|
||||
if (is_cpu_off(target_state)) {
|
||||
plat_qti_gic_cpuif_disable();
|
||||
qti_set_cpupwrctlr_val();
|
||||
}
|
||||
return PSCI_E_SUCCESS;
|
||||
}
|
||||
#else
|
||||
static void qti_node_suspend(const psci_power_state_t *target_state)
|
||||
{
|
||||
qtiseclib_psci_node_suspend((const uint8_t *)target_state->
|
||||
|
@ -212,7 +200,6 @@ static void qti_node_suspend(const psci_power_state_t *target_state)
|
|||
qti_set_cpupwrctlr_val();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void qti_node_suspend_finish(const psci_power_state_t *target_state)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue