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
|
:Author: Maulik Shah & Wing Li
|
||||||
:Organization: Qualcomm Innovation Center, Inc. & Google LLC
|
:Organization: Qualcomm Innovation Center, Inc. & Google LLC
|
||||||
:Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
|
:Contact: Maulik Shah <quic_mkshah@quicinc.com> & Wing Li <wingers@google.com>
|
||||||
:Status: RFC
|
:Status: Accepted
|
||||||
|
|
||||||
.. contents:: Table of Contents
|
.. 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
|
``psci_validate_state_coordination``. If validation fails, propagate the
|
||||||
error up the call stack.
|
error up the call stack.
|
||||||
|
|
||||||
* Update the return type of the platform specific ``pwr_domain_suspend``
|
* Add a new optional member ``pwr_domain_validate_suspend`` to
|
||||||
handler from ``void`` to ``int``, to allow the platform to optionally perform
|
``plat_psci_ops_t`` to allow the platform to optionally perform validations
|
||||||
validations based on hardware states.
|
based on hardware states.
|
||||||
|
|
||||||
|
* The platform specific ``pwr_domain_suspend`` handler remains unchanged.
|
||||||
|
|
||||||
.. image:: ../resources/diagrams/psci-osi-mode.png
|
.. 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
|
for the higher power domain levels depending on the result of state
|
||||||
coordination. The generic code expects the handler to succeed.
|
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]
|
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
|
data, for example in DRAM. The Distributor can then be powered down using an
|
||||||
implementation-defined sequence.
|
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()
|
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);
|
int (*pwr_domain_on)(u_register_t mpidr);
|
||||||
void (*pwr_domain_off)(const psci_power_state_t *target_state);
|
void (*pwr_domain_off)(const psci_power_state_t *target_state);
|
||||||
int (*pwr_domain_off_early)(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)(
|
void (*pwr_domain_suspend_pwrdown_early)(
|
||||||
const psci_power_state_t *target_state);
|
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);
|
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)(const psci_power_state_t *target_state);
|
||||||
void (*pwr_domain_on_finish_late)(
|
void (*pwr_domain_on_finish_late)(
|
||||||
const psci_power_state_t *target_state);
|
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
|
* enter. This function will be called after coordination of requested power
|
||||||
* states has been done for each power level.
|
* states has been done for each power level.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
static void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
void psci_set_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||||
const psci_power_state_t *target_state)
|
const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
unsigned int parent_idx, lvl;
|
unsigned int parent_idx, lvl;
|
||||||
const plat_local_state_t *pd_state = target_state->pwr_domain_state;
|
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.
|
* 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;
|
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
|
#if PSCI_OS_INIT_MODE
|
||||||
|
@ -684,9 +680,6 @@ exit:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the target state in the power domain nodes */
|
|
||||||
psci_set_target_local_pwr_states(end_pwrlvl, state_info);
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -104,6 +104,9 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
|
||||||
*/
|
*/
|
||||||
psci_do_state_coordination(end_pwrlvl, &state_info);
|
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
|
#if ENABLE_PSCI_STAT
|
||||||
/* Update the last cpu for each level till end_pwrlvl */
|
/* Update the last cpu for each level till end_pwrlvl */
|
||||||
psci_stats_update_pwr_down(end_pwrlvl, &state_info);
|
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
|
#endif
|
||||||
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
void psci_get_target_local_pwr_states(unsigned int end_pwrlvl,
|
||||||
psci_power_state_t *target_state);
|
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,
|
int psci_validate_entry_point(entry_point_info_t *ep,
|
||||||
uintptr_t entrypoint, u_register_t context_id);
|
uintptr_t entrypoint, u_register_t context_id);
|
||||||
void psci_get_parent_pwr_domain_nodes(unsigned int cpu_idx,
|
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
|
#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
|
#if ENABLE_PSCI_STAT
|
||||||
/* Update the last cpu for each level till end_pwrlvl */
|
/* Update the last cpu for each level till end_pwrlvl */
|
||||||
psci_stats_update_pwr_down(end_pwrlvl, state_info);
|
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.
|
* 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);
|
psci_plat_pm_ops->pwr_domain_suspend(state_info);
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLE_PSCI_STAT
|
#if ENABLE_PSCI_STAT
|
||||||
plat_psci_stat_accounting_start(state_info);
|
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
|
* 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.
|
* 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)
|
static void fvp_pwr_domain_suspend(const psci_power_state_t *target_state)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
unsigned long mpidr;
|
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] ==
|
if (target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
||||||
ARM_LOCAL_STATE_RET)
|
ARM_LOCAL_STATE_RET)
|
||||||
#if PSCI_OS_INIT_MODE
|
|
||||||
return PSCI_E_SUCCESS;
|
|
||||||
#else
|
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
|
|
||||||
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
assert(target_state->pwr_domain_state[ARM_PWR_LVL0] ==
|
||||||
ARM_LOCAL_STATE_OFF);
|
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. */
|
/* Program the power controller to power off this cpu. */
|
||||||
fvp_pwrc_write_ppoffr(read_mpidr_el1());
|
fvp_pwrc_write_ppoffr(read_mpidr_el1());
|
||||||
|
|
||||||
#if PSCI_OS_INIT_MODE
|
|
||||||
return PSCI_E_SUCCESS;
|
|
||||||
#else
|
|
||||||
return;
|
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)
|
static void qti_node_suspend(const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
qtiseclib_psci_node_suspend((const uint8_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();
|
qti_set_cpupwrctlr_val();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void qti_node_suspend_finish(const psci_power_state_t *target_state)
|
static void qti_node_suspend_finish(const psci_power_state_t *target_state)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue