Browse Source

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
pull/1999/head
Manish Pandey 1 year ago
committed by TrustedFirmware Code Review
parent
commit
f4d011b0f0
  1. 10
      docs/design_documents/psci_osi_mode.rst
  2. 15
      docs/porting-guide.rst
  3. BIN
      docs/resources/diagrams/psci-osi-mode.png
  4. 8
      include/lib/psci/psci.h
  5. 11
      lib/psci/psci_common.c
  6. 3
      lib/psci/psci_off.c
  7. 2
      lib/psci/psci_private.h
  8. 21
      lib/psci/psci_suspend.c
  9. 12
      plat/arm/board/fvp/fvp_pm.c
  10. 13
      plat/qti/common/src/qti_pm.c

10
docs/design_documents/psci_osi_mode.rst

@ -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

15
docs/porting-guide.rst

@ -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()
.......................................

BIN
docs/resources/diagrams/psci-osi-mode.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 197 KiB

8
include/lib/psci/psci.h

@ -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);

11
lib/psci/psci_common.c

@ -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

3
lib/psci/psci_off.c

@ -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);

2
lib/psci/psci_private.h

@ -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,

21
lib/psci/psci_suspend.c

@ -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);

12
plat/arm/board/fvp/fvp_pm.c

@ -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
}
/*******************************************************************************

13
plat/qti/common/src/qti_pm.c

@ -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…
Cancel
Save