From bdd28427b6e84774058fefd7673d86f8ddb09c68 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 23 Sep 2026 14:20:09 +0300 Subject: [PATCH 1/3] ASoC: SOF: pcm/pm: Fix WoV flow during system suspend / resume When a capture stream for WoV is active during suspend, we must not tear down the pipelines as they must remain active while the system is suspended. In order to the WoV to work with system suspend, the PCM must have SNDRV_PCM_INFO_RESUME set so applications will not try to re-start the stream due to not supported resume trigger. However on RESUME trigger there is nothing to do for the VoW PCM as it was left running, but since system RESUME is not supported by default, for other streams which have suspend_ignored=false we need to return error for userspace to restart the stream. Signed-off-by: Peter Ujfalusi --- sound/soc/sof/pcm.c | 7 +++++++ sound/soc/sof/pm.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 42738f12fa3390..6a7acbb69fb4a4 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -428,6 +428,13 @@ static int sof_pcm_trigger(struct snd_soc_component *component, if (pcm_ops && pcm_ops->ipc_first_on_start) ipc_first = true; break; + case SNDRV_PCM_TRIGGER_RESUME: + if (spcm->stream[substream->stream].suspend_ignored) { + spcm->stream[substream->stream].suspend_ignored = false; + return 0; + } + spcm_err(spcm, substream->stream, "RESUME trigger is not supported\n"); + return -EINVAL; case SNDRV_PCM_TRIGGER_SUSPEND: /* * If DSP D0I3 is allowed during S0iX, set the suspend_ignored flag for diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 1d71d483588eb1..b5d239b12e59d2 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -248,7 +248,8 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) * suspended, it is brought back to full power and then * suspended again */ - if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0)) + if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0) && + (target_state != SOF_DSP_PM_D0)) tplg_ops->tear_down_all_pipelines(sdev, false); if (sdev->fw_state != SOF_FW_BOOT_COMPLETE) From e8a10817fba4b16da4cd273bcaa6bff503d62220 Mon Sep 17 00:00:00 2001 From: Jyri Sarha Date: Thu, 13 Aug 2026 22:29:06 +0300 Subject: [PATCH 2/3] ASoC: SOF: Add definition of a WoV stream and drop d0i3_supported_in_s0ix Historically the CAPTURE_COMPATIBLE_D0I3 have been added to mark the WoV stream during IPC3 era. For symmetry the PLAYBACK_COMPATIBLE_D0I3 token was added as well. Later IPC4 declared that WoV is not supported and started to use the playback token to mark Deep Buffer streams (host can enter lower power state) and after that using this example a Deep Buffer support for capture was added - again, keeping the WoV unsupported by IPC4. To lift the WoV block for IPC4 and keeping the IPC3 support intact the definition of WoV stream is: a capture stream, CAPTURE_COMPATIBLE_D0I3 is set for the PCM, it is not a Deep Buffer stream. With this rule we can clearly identify the WoV stream and we can tell it apart from Deep Buffer capture. If Deep Buffer will be needed for WoV then we need bigger changes in firmware, topology (new token) and kernel. Co-Developed by: Peter Ujfalusi Signed-off-by: Peter Ujfalusi Signed-off-by: Jyri Sarha --- sound/soc/sof/ipc3-pcm.c | 1 - sound/soc/sof/pcm.c | 16 ++++++++++------ sound/soc/sof/sof-audio.h | 2 -- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index 42f93e596598fd..b95e888c0adb84 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -431,7 +431,6 @@ const struct sof_ipc_pcm_ops ipc3_pcm_ops = { .trigger = sof_ipc3_pcm_trigger, .dai_link_fixup = sof_ipc3_pcm_dai_link_fixup, .reset_hw_params_during_stop = true, - .d0i3_supported_in_s0ix = true, #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMPRESS) .compress_ops = &sof_ipc3_compressed_ops, #endif diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 6a7acbb69fb4a4..129c698d87beba 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -437,16 +437,20 @@ static int sof_pcm_trigger(struct snd_soc_component *component, return -EINVAL; case SNDRV_PCM_TRIGGER_SUSPEND: /* - * If DSP D0I3 is allowed during S0iX, set the suspend_ignored flag for - * D0I3-compatible streams to keep the firmware pipeline running + * Set the suspend_ignored flag for D0I3-compatible streams used + * for WoV to keep the firmware pipeline running. + * WoV streams can be indetified by: + * They are capture streams and + * They have the d0i3_compatible flag set and + * They don't use Deep Buffer */ - if (pcm_ops && pcm_ops->d0i3_supported_in_s0ix && - sdev->system_suspend_target == SOF_SUSPEND_S0IX && - spcm->stream[substream->stream].d0i3_compatible) { + if (sdev->system_suspend_target == SOF_SUSPEND_S0IX && + substream->stream == SNDRV_PCM_STREAM_CAPTURE && + spcm->stream[substream->stream].d0i3_compatible && + spcm->stream[substream->stream].dsp_max_burst_size_in_ms <= 1) { spcm->stream[substream->stream].suspend_ignored = true; return 0; } - /* On suspend the DMA must be stopped in DSPless mode */ if (sdev->dspless_mode_selected) reset_hw_params = true; diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index b60246fd5869b1..0d3650f7a67002 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -121,7 +121,6 @@ struct snd_sof_dai_config_data { * triggers. The FW keeps the host DMA running in this case and * therefore the host must do the same and should stop the DMA during * hw_free. - * @d0i3_supported_in_s0ix: Allow DSP D0I3 during S0iX * @compress_ops: Pointer to ops for compressed streams */ struct sof_ipc_pcm_ops { @@ -143,7 +142,6 @@ struct sof_ipc_pcm_ops { bool reset_hw_params_during_stop; bool ipc_first_on_start; bool platform_stop_during_hw_free; - bool d0i3_supported_in_s0ix; const struct snd_compress_ops *compress_ops; }; From 2d0141ac4573666e39ba135d6c55ad1408e0b073 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 23 Sep 2026 14:22:20 +0300 Subject: [PATCH 3/3] ASoC: SOF: Intel:hda-pcm: Set SNDRV_PCM_INFO_RESUME for VoW streams VoW streams can be identified by: They are capture streams, the d0i3_compatible flag is set and they are not using Deep Buffer. For the Wake on Voice to work the SNDRV_PCM_INFO_RESUME flag must be set for the PCM. On system suspend the DSP will be left enabled, pipelines running and on resume there will be no action needed to be done. Signed-off-by: Peter Ujfalusi --- sound/soc/sof/intel/hda-pcm.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 83efc9bdf418af..70abff12fef0ee 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -352,6 +352,20 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, spcm->stream[substream->stream].d0i3_compatible) flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE; + /* + * Set the RESUME supported flag for WoV streams. The core will ignore + * the trigger but applications must not try to restart the WoV stream + * due to not supported RESUME. + * WoV streams can be indetified by: + * They are capture streams and + * They have the d0i3_compatible flag set and + * They don't use Deep Buffer + */ + if (direction == SNDRV_PCM_STREAM_CAPTURE && + spcm->stream[substream->stream].d0i3_compatible && + spcm->stream[substream->stream].dsp_max_burst_size_in_ms <= 1) + runtime->hw.info |= SNDRV_PCM_INFO_RESUME; + dsp_stream = hda_dsp_stream_get(sdev, direction, flags); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n");