Commit 700d1677 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown

ASoC: SOF: pm: Introduce DSP power states

Add a new enum sof_dsp_power_states for all the possible
the DSP device states. The SOF driver currently handles
only the D0 and D3 states and support for other states
will be added later as needed.

Also, add a helper to determine the target DSP power state
based on the system suspend target.
The snd_sof_dsp_d0i3_on_suspend() function is renamed to
snd_sof_stream_suspend_ignored() to be more indicative
of what it does and it used to determine the target
DSP state during system suspend.
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200129220726.31792-5-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 043ae13b
...@@ -12,6 +12,42 @@ ...@@ -12,6 +12,42 @@
#include "sof-priv.h" #include "sof-priv.h"
#include "sof-audio.h" #include "sof-audio.h"
/*
* Helper function to determine the target DSP state during
* system suspend. This function only cares about the device
* D-states. Platform-specific substates, if any, should be
* handled by the platform-specific parts.
*/
static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev)
{
u32 target_dsp_state;
switch (sdev->system_suspend_target) {
case SOF_SUSPEND_S3:
/* DSP should be in D3 if the system is suspending to S3 */
target_dsp_state = SOF_DSP_PM_D3;
break;
case SOF_SUSPEND_S0IX:
/*
* Currently, the only criterion for retaining the DSP in D0
* is that there are streams that ignored the suspend trigger.
* Additional criteria such Soundwire clock-stop mode and
* device suspend latency considerations will be added later.
*/
if (snd_sof_stream_suspend_ignored(sdev))
target_dsp_state = SOF_DSP_PM_D0;
else
target_dsp_state = SOF_DSP_PM_D3;
break;
default:
/* This case would be during runtime suspend */
target_dsp_state = SOF_DSP_PM_D3;
break;
}
return target_dsp_state;
}
static int sof_send_pm_ctx_ipc(struct snd_sof_dev *sdev, int cmd) static int sof_send_pm_ctx_ipc(struct snd_sof_dev *sdev, int cmd)
{ {
struct sof_ipc_pm_ctx pm_ctx; struct sof_ipc_pm_ctx pm_ctx;
...@@ -169,7 +205,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) ...@@ -169,7 +205,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
} }
} }
if (snd_sof_dsp_d0i3_on_suspend(sdev)) { if (snd_sof_dsp_power_target(sdev) == SOF_DSP_PM_D0) {
/* suspend to D0i3 */ /* suspend to D0i3 */
ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3); ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3);
if (ret < 0) { if (ret < 0) {
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
#include "sof-audio.h" #include "sof-audio.h"
#include "ops.h" #include "ops.h"
bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev) bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev)
{ {
struct snd_sof_pcm *spcm; struct snd_sof_pcm *spcm;
......
...@@ -202,7 +202,7 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol, ...@@ -202,7 +202,7 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol,
/* PM */ /* PM */
int sof_restore_pipelines(struct device *dev); int sof_restore_pipelines(struct device *dev);
int sof_set_hw_params_upon_resume(struct device *dev); int sof_set_hw_params_upon_resume(struct device *dev);
bool snd_sof_dsp_d0i3_on_suspend(struct snd_sof_dev *sdev); bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev);
/* Machine driver enumeration */ /* Machine driver enumeration */
int sof_machine_register(struct snd_sof_dev *sdev, void *pdata); int sof_machine_register(struct snd_sof_dev *sdev, void *pdata);
......
...@@ -54,6 +54,16 @@ extern int sof_core_debug; ...@@ -54,6 +54,16 @@ extern int sof_core_debug;
(IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) || \ (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) || \
IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST)) IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST))
/* DSP power state */
enum sof_dsp_power_states {
SOF_DSP_PM_D0,
SOF_DSP_PM_D1,
SOF_DSP_PM_D2,
SOF_DSP_PM_D3_HOT,
SOF_DSP_PM_D3,
SOF_DSP_PM_D3_COLD,
};
/* DSP D0ix sub-state */ /* DSP D0ix sub-state */
enum sof_d0_substate { enum sof_d0_substate {
SOF_DSP_D0I0 = 0, /* DSP default D0 substate */ SOF_DSP_D0I0 = 0, /* DSP default D0 substate */
......
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