summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/sof/pm.c38
-rw-r--r--sound/soc/sof/sof-audio.c2
-rw-r--r--sound/soc/sof/sof-audio.h2
-rw-r--r--sound/soc/sof/sof-priv.h10
4 files changed, 49 insertions, 3 deletions
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index c86ac1e84bd7..bec25cb6beec 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -12,6 +12,42 @@
#include "sof-priv.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)
{
struct sof_ipc_pm_ctx pm_ctx;
@@ -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 */
ret = snd_sof_set_d0_substate(sdev, SOF_DSP_D0I3);
if (ret < 0) {
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 345e42ee4783..d16571ca129c 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -11,7 +11,7 @@
#include "sof-audio.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;
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index a62fb2da6a6e..a2702afbd9a1 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -202,7 +202,7 @@ int snd_sof_ipc_set_get_comp_data(struct snd_sof_control *scontrol,
/* PM */
int sof_restore_pipelines(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 */
int sof_machine_register(struct snd_sof_dev *sdev, void *pdata);
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 1839cc51957d..a7c6109acd98 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -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_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 */
enum sof_d0_substate {
SOF_DSP_D0I0 = 0, /* DSP default D0 substate */