Skip to content

[dnm] ASoC: SOF: pcm/pm/Intel: Fix VoW during system suspend - #5951

Open
ujfalusi wants to merge 3 commits into
thesofproject:topic/sof-devfrom
ujfalusi:peter/sof/pr/vow-flow-fix-01
Open

ujfalusi wants to merge 3 commits into
thesofproject:topic/sof-devfrom
ujfalusi:peter/sof/pr/vow-flow-fix-01

Conversation

@ujfalusi

Copy link
Copy Markdown
Collaborator

The Wake on Voice flow was broken (supported via IPC3 only atm) because on suspend we attempted to tear down the pipelines
and RESUME was not supported by the PCM:
We had errors on suspend due to failing to free widgets and the user space restarted to capture during resume.

To fix this:
If the target suspend level is SOF_DSP_PM_D0 then we must not tear down the pipelines
we need to set the SNDRV_PCM_INFO_RESUME for the VoW capture PCM, so applications can do the 'resume'
and on RESUME trigger we do nothing as the DSP was left on and everything has been left running as they were before.

Tested on sof-adl-max98357a-rt5682.tplg with:

arecord -Dhw:0,100 -M -N -c 2 -f S16_LE -r 16000 --buffer-size=96000 tmp.wav -d 10 -vvv

and

echo mem > /sys/power/state

then clapping to wake the device up: no errors observed anymore.

Copilot AI lite review requested due to automatic review settings September 23, 2026 11:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Resolve the HDA RESUME handling and restrict or implement resume support for non-retained suspend paths.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Fixes SOF Wake on Voice suspend/resume by retaining pipelines during D0 suspend and enabling ALSA resume support.

Changes:

  • Avoids pipeline teardown when suspending to D0.
  • Handles RESUME for retained streams.
  • Advertises RESUME for compatible HDA capture streams.
File Summary Review status
sound/​soc/​sof/​pm.c Preserves pipelines during D0 suspend. No issue noted.
sound/​soc/​sof/​pcm.c Handles RESUME for suspend-ignored streams. Moderate issue: the HDA DAI path can still return -EINVAL for RESUME.
sound/​soc/​sof/​intel/​hda-pcm.c Advertises resume capability for VoW capture streams. Moderate issue: capability is advertised for paths that do not reliably support RESUME.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread sound/soc/sof/intel/hda-pcm.c
@ujfalusi ujfalusi changed the title ASoC: SOF: pcm/pm/Intel: Fix VoW during system suspend [dnm] ASoC: SOF: pcm/pm/Intel: Fix VoW during system suspend Sep 25, 2026
ujfalusi and others added 3 commits September 28, 2026 17:56
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 <peter.ujfalusi@linux.intel.com>
…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 <peter.ujfalusi@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
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 <peter.ujfalusi@linux.intel.com>
Copilot AI review requested due to automatic review settings September 28, 2026 14:56
@ujfalusi
ujfalusi force-pushed the peter/sof/pr/vow-flow-fix-01 branch from a55afd6 to 2d0141a Compare September 28, 2026 14:56
@ujfalusi

Copy link
Copy Markdown
Collaborator Author

Changes since v1:

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

HDA DAI resume handling is missing and can return -EINVAL on VoW resume.

Review effort: Lite
Findings: 2 Medium severity

Open (2)
Resolved since last review (1)

* 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:
Comment thread sound/soc/sof/pcm.c
* 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:
@lgirdwood

lgirdwood commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

Testing/updates/comments from Gemini. @ujfalusi some may be needed, tested both with ALSA and tinyalsa, depend on how you plan to upstream.

Tested PR #5951 on Intel Panther Lake (PTL / ACE 3.0 DSP) using our Wake-on-Voice test suites (10-run S0 sequence, 10-run S2idle sleep/wake sequence, and audio capture validation suite).

The general direction and cleanup of WoV stream definition in PR #5951 is great, but when tested on IPC4 hardware, several pieces are missing to make IPC4 WoV function across system suspend and wake.

Issues Identified on IPC4 with PR #5951 Standalone:

  1. Missing IPC4 D0i3 Topology Token Parsing (ipc4-topology.c):
    Commit 2 (036dbd7ff63e) defines a WoV stream as:

    substream->stream == SNDRV_PCM_STREAM_CAPTURE &&
    spcm->stream[substream->stream].d0i3_compatible &&
    spcm->stream[substream->stream].dsp_max_burst_size_in_ms <= 1

    However, on upstream topic/sof-dev, ipc4-topology.c never sets d0i3_compatible (only IPC3 topology.c parses SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3). The topology parsing from PR ASoC: SOF: Bring WoV support to ipc4 #5878 was omitted in PR [dnm] ASoC: SOF: pcm/pm/Intel: Fix VoW during system suspend #5951. Because d0i3_compatible is always false on IPC4:

    • snd_sof_is_vow_stream() always returns false.
    • runtime->hw.info |= SNDRV_PCM_INFO_RESUME is never set on IPC4.
    • spcm->stream[direction].suspend_ignored is never set, so ALSA core suspends the WoV stream into SNDRV_PCM_STATE_SUSPENDED, returning -EBADFD (-86) to userspace on resume.
  2. DAPM DAI Link Suspend Exemption (ignore_suspend):
    While suspend_ignored prevents sof_pcm_trigger() from stopping the stream, generic ASoC DAPM suspend power-down sequencing still attempts to tear down the DAI link widgets while the DSP pipeline remains alive. Setting rtd->dai_link->ignore_suspend = 1 in hda_dsp_pcm_open() (and clearing on close) prevents this host/DSP widget desync and eliminates IPC timeouts on resume.

  3. DSP Power Target Retention in S0ix (pm.c):
    snd_sof_dsp_power_target() in pm.c only retains the DSP in D0 if snd_sof_stream_suspend_ignored(sdev) is true. If userspace has the WoV PCM open but it has not taken a suspend trigger, target_state evaluates to SOF_DSP_PM_D3, causing ctx_save IPC to be sent to a running DSP which returns -EBUSY (-16). Adding snd_sof_dsp_only_d0i3_compatible_stream_active(sdev) ensures the DSP stays in D0 whenever an open WoV stream is active.

  4. Unhandled Phrase Detected Notification (SOF_IPC4_NOTIFY_PHRASE_DETECTED):
    When the DSP detects a wake phrase (or test trigger), firmware emits SOF_IPC4_NOTIFY_PHRASE_DETECTED (0x1b040000). In ipc4.c, this must be handled to call snd_sof_pcm_period_elapsed(), otherwise blocking reads running with NO_PERIOD_WAKEUP (such as tinyalsa and alsa-lib set_period_wakeup(0)) never receive avail wakeups.

  5. Pipeline State Reset on STOP/SUSPEND (hda-dai-ops.c):
    Resetting pipeline->state = SOF_IPC4_PIPE_RESET on STOP/SUSPEND trigger ensures subsequent START cycles cleanly transition through PAUSED to RUNNING.

  6. Multi-Pin Process Module Format Fallback (ipc4-topology.c):
    In multi-pin topologies (e.g. ECNS modules with 1ch out on pin 0 / pin 1), sof_ipc4_init_output_audio_fmt() needs a fallback to Pin 0 format when no reference format matches channel counts, otherwise widget preparation fails with -22 (-EINVAL).


Working Reference Branch:

I have pushed a working branch rebased directly on topic/sof-dev on top of PR #5951 with these additions:
👉 https://github.com/lgirdwood/linux/tree/wov-pr5951-ipc4-reference

With this branch on Panther Lake (PTL):

  • 10 / 10 WoV S0 runs passed (~5.65s elapsed per run)
  • 10 / 10 WoV S2idle sleep/wake cycles passed (all 10 woke the host via DSP IRQ 193 and read 4000 frames)
  • 12 / 12 audio capture validation tests passed (raw DMIC, ECNS, and WoV slots 0/1/2 across arecord, tinycap, and MMAP/NOIRQ)
  • tinyalsa blocking read (wov_blocking_read_tinyalsa) passed

@lgirdwood

Copy link
Copy Markdown
Member

For additional context, here is the empirical pass vs fail breakdown from testing PR #5951 standalone on Panther Lake (PTL / ACE 3.0 DSP) before applying the IPC4 enablement delta:

What Passed with PR #5951 Standalone:

  • Raw DMIC Capture (PCM 10):
    • arecord, tinycap, and tinycap -M (MMAP) all passed 100% (4ch 16kHz audio captured cleanly without any xruns or errors).
  • Initial S0 WoV Capture (Runs 1–5):
    • While the host remained in S0, early runs of wov_blocking_read and wov_blocking_read_tinyalsa (using PCM_MMAP | PCM_NOIRQ) passed, capturing 4,000 frames after ~5.65s and 5.45s upon synthetic wake trigger.
    • NO_PERIOD_WAKEUP was successfully negotiated because sof_hda_common_ops already sets SNDRV_PCM_INFO_NO_PERIOD_WAKEUP in the base kernel.

What Failed with PR #5951 Standalone:

  • WoV S2idle Suspend & Wake (run_10_wov_sleep_wake.sh) — 0 / 10 Passed (100% Failure):
    • On every suspend attempt, wov_blocking_read immediately failed on resume with wait error or timeout: -86 (-EBADFD / stream suspended by the ALSA core) because without d0i3_compatible parsed from IPC4 topology, snd_sof_is_vow_stream() returned false and the stream was not exempted from suspend.
    • The DSP crashed during suspend/resume with a register and stack dump (sof-audio-pci-intel-ptl 0000:00:1f.3: stack dump from 0x00000000).
    • On resumption, DAPM attempted to power down widgets that were supposed to remain active, causing module unbind IPC timeouts (-19 / -ENODEV).
  • S0 WoV Longevity (Runs 6–10):
    • Later S0 runs began timing out after 15s (wait error or timeout: 0).
    • Because SOF_IPC4_NOTIFY_PHRASE_DETECTED (0x1b040000) is ignored by PR [dnm] ASoC: SOF: pcm/pm/Intel: Fix VoW during system suspend #5951, the kernel never calls snd_sof_pcm_period_elapsed(). Without periodic IRQs, userspace snd_pcm_wait() never woke up once the DMA buffer pacing desynced.
  • Topologies with Multi-Pin Process Modules:
    • Topologies containing modules that change channel counts between pins (e.g. ECNS with 1ch out on pin 0 / pin 1 in sof-ptl-dmic-wov-multi-4ch.tplg) failed hw_params with -22 (-EINVAL) in sof_ipc4_init_output_audio_fmt() without the Pin 0 format fallback.

Summary:

In S0 (awake), basic capture and initial WoV reads function. However, actual Wake-on-Voice from system sleep (s2idle) fails 100% on IPC4 under PR #5951 standalone because d0i3_compatible is never set, so the suspend bypass and DAPM retention never take effect.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants