Commit d118f9f8 authored by Vikram Kanigiri's avatar Vikram Kanigiri Committed by Dan Handley
Browse files

Add standby state support in PSCI cpu_suspend api

This patch adds support in the generic PSCI implementation to call a
platform specific function to enter a standby state using an example
implementation in ARM FVP port

Fixes ARM-software/tf-issues#94
Change-Id: Ic1263fcf25f28e09162ad29dca954125f9aa8cc9
parent 886278e5
...@@ -74,6 +74,9 @@ ...@@ -74,6 +74,9 @@
#define PSTATE_TYPE_MASK 0x1 #define PSTATE_TYPE_MASK 0x1
#define PSTATE_AFF_LVL_MASK 0x3 #define PSTATE_AFF_LVL_MASK 0x3
#define PSTATE_TYPE_STANDBY 0x0
#define PSTATE_TYPE_POWERDOWN 0x1
#define psci_get_pstate_id(pstate) (pstate >> PSTATE_ID_SHIFT) & \ #define psci_get_pstate_id(pstate) (pstate >> PSTATE_ID_SHIFT) & \
PSTATE_ID_MASK PSTATE_ID_MASK
#define psci_get_pstate_type(pstate) (pstate >> PSTATE_TYPE_SHIFT) & \ #define psci_get_pstate_type(pstate) (pstate >> PSTATE_TYPE_SHIFT) & \
......
...@@ -43,6 +43,29 @@ ...@@ -43,6 +43,29 @@
/* Only included for error codes */ /* Only included for error codes */
#include <psci.h> #include <psci.h>
/*******************************************************************************
* FVP handler called when an affinity instance is about to enter standby.
******************************************************************************/
int fvp_affinst_standby(unsigned int power_state)
{
unsigned int target_afflvl;
/* Sanity check the requested state */
target_afflvl = psci_get_pstate_afflvl(power_state);
/*
* It's possible to enter standby only on affinity level 0 i.e. a cpu
* on the FVP. Ignore any other affinity level.
*/
if (target_afflvl != MPIDR_AFFLVL0)
return PSCI_E_INVALID_PARAMS;
/* Enter standby state */
wfi();
return PSCI_E_SUCCESS;
}
/******************************************************************************* /*******************************************************************************
* FVP handler called when an affinity instance is about to be turned on. The * FVP handler called when an affinity instance is about to be turned on. The
* level and mpidr determine the affinity instance. * level and mpidr determine the affinity instance.
...@@ -372,7 +395,7 @@ int fvp_affinst_suspend_finish(unsigned long mpidr, ...@@ -372,7 +395,7 @@ int fvp_affinst_suspend_finish(unsigned long mpidr,
* Export the platform handlers to enable psci to invoke them * Export the platform handlers to enable psci to invoke them
******************************************************************************/ ******************************************************************************/
static plat_pm_ops fvp_plat_pm_ops = { static plat_pm_ops fvp_plat_pm_ops = {
0, fvp_affinst_standby,
fvp_affinst_on, fvp_affinst_on,
fvp_affinst_off, fvp_affinst_off,
fvp_affinst_suspend, fvp_affinst_suspend,
......
...@@ -85,31 +85,28 @@ int psci_cpu_suspend(unsigned int power_state, ...@@ -85,31 +85,28 @@ int psci_cpu_suspend(unsigned int power_state,
unsigned long mpidr; unsigned long mpidr;
unsigned int target_afflvl, pstate_type; unsigned int target_afflvl, pstate_type;
/* TODO: Standby states are not supported at the moment */
pstate_type = psci_get_pstate_type(power_state);
if (pstate_type == 0) {
rc = PSCI_E_INVALID_PARAMS;
goto exit;
}
/* Sanity check the requested state */ /* Sanity check the requested state */
target_afflvl = psci_get_pstate_afflvl(power_state); target_afflvl = psci_get_pstate_afflvl(power_state);
if (target_afflvl > MPIDR_MAX_AFFLVL) { if (target_afflvl > MPIDR_MAX_AFFLVL)
rc = PSCI_E_INVALID_PARAMS; return PSCI_E_INVALID_PARAMS;
goto exit;
}
mpidr = read_mpidr(); pstate_type = psci_get_pstate_type(power_state);
rc = psci_afflvl_suspend(mpidr, if (pstate_type == PSTATE_TYPE_STANDBY) {
entrypoint, if (psci_plat_pm_ops->affinst_standby)
context_id, rc = psci_plat_pm_ops->affinst_standby(power_state);
power_state, else
MPIDR_AFFLVL0, return PSCI_E_INVALID_PARAMS;
target_afflvl); } else {
mpidr = read_mpidr();
rc = psci_afflvl_suspend(mpidr,
entrypoint,
context_id,
power_state,
MPIDR_AFFLVL0,
target_afflvl);
}
exit: assert(rc == PSCI_E_INVALID_PARAMS || rc == PSCI_E_SUCCESS);
if (rc != PSCI_E_SUCCESS)
assert(rc == PSCI_E_INVALID_PARAMS);
return rc; return rc;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment