Conversation
Mark the WOV host-copier stream as D0I3-compatible so the kernel keeps
the capture pipeline active during S0iX system sleep. When the WOV
trigger fires, the firmware sends SOF_IPC4_NOTIFY_PHRASE_DETECTED which
wakes the host from D0I3.
Two placement sites:
- Object.Widget.host-copier.1: parsed by IPC4 kernel (sof_ipc4_widget_setup_pcm
in ipc4-topology.c, see thesofproject/linux#5878)
- Object.PCM.pcm: parsed by IPC3 kernel (topology.c)
Also adds DefineAttribute entries for capture_compatible_d0i3 and
playback_compatible_d0i3 to host-copier.conf so IPC4 alsatplg can
encode the token into the widget TLV tuple set.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
I managed to establish that this indeed works on my PTL-upx. At least if I tag a capture PCM host-copier with 'capture_compatible_d0i3 1' property, and have a capture running when suspending to s2idle, the DSP remains running. And if the DSP sends a SOF_IPC4_NOTIFY_PHRASE_DETECTED to the host, it wakes up. The reason why my first hack test did not work was that the SOF driver pauses the capture before suspending. I assume that is Ok, and the WoV should deal with the pause command correctly. So I think this is ready for review. |
There was a problem hiding this comment.
Pull request overview
This PR extends Sound Open Firmware (SOF) IPC4 topology/PCM handling to support Wake-on-Voice (WoV)-style D0i3 compatibility signaling, aligning IPC4 behavior with the existing IPC3 capability.
Changes:
- Adds new IPC4 token groups to parse per-stream D0i3 compatibility properties from host-copier widget tuples.
- Updates IPC4 host-copier PCM widget setup to set
spcm->stream[dir].d0i3_compatiblebased on the new tokens. - Enables
ipc4_pcm_ops.d0i3_supported_in_s0ixto allow DSP D0i3 during S0iX for IPC4.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| sound/soc/sof/sof-audio.h | Adds new token-group IDs for IPC4 stream D0i3 compatibility parsing. |
| sound/soc/sof/ipc4-topology.c | Defines/installs the new token groups and parses the D0i3 compatibility flag for IPC4 host-copier PCMs. |
| sound/soc/sof/ipc4-pcm.c | Enables d0i3_supported_in_s0ix for IPC4 PCM ops. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| static const struct sof_topology_token ipc4_stream_capture_d0i3_tokens[] = { | ||
| {SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3, SND_SOC_TPLG_TUPLE_TYPE_BOOL, get_token_u32, 0}, | ||
| }; |
There was a problem hiding this comment.
The topology.c have the stream_tokens, which sets the stream[0].d0i3_compatible / stream[1].d0i3_compatible of struct snd_sof_pcm.
I would rather use the existing mechanism if possible than invent another, ipc4 flag.
With that we can simple remove the struct sof_ipc_pcm_ops.d0i3_supported_in_s0ix as both IPC3 and now IPC4 supports this feature.
There was a problem hiding this comment.
The existing mechanism can not be used, the code paths are separate. But you would like to replicate the ipc3 mechanism to ipc4, e.g. put the property to the stream node in the topology?
There was a problem hiding this comment.
we have SOF_TKN_STREAM_PLAYBACK_PAUSE_SUPPORTED / SOF_TKN_STREAM_CAPTURE_PAUSE_SUPPORTED generic tokens, which is applicable to both IPC3 and IPC4, we don't have IPC4 specific duplicates of these either afaik.
Why would the SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3 / SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3 needs duplication for IPC4?
There was a problem hiding this comment.
But there is no duplication. Ipc4 uses the same SOF_TKN_STREAM_PLAYBACK_COMPATIBLE_D0I3 / SOF_TKN_STREAM_CAPTURE_COMPATIBLE_D0I3 tokens as ipc3 does. The rest of the implementation is very different of course, even the node holding the property is different than in ipc3 implementation (AFAIU the ipc3).
There was a problem hiding this comment.
It is all handled in generic code, not IPC3 related. The only thing is the d0i3_compatible flag and the pcm_ops->d0i3_supported_in_s0ix gating IPC4, this flag makes it IPC3 only actually.
Topology2 already have this sort of supported:
tools/topology/topology2/include/common/pcm.conf- DefineAttribute."playback_compatible_d0i3" {
tools/topology/topology2/include/common/pcm.conf- # Token reference and type
tools/topology/topology2/include/common/pcm.conf- token_ref "stream.bool"
tools/topology/topology2/include/common/pcm.conf- }
tools/topology/topology2/include/common/pcm.conf-
tools/topology/topology2/include/common/pcm.conf- DefineAttribute."capture_compatible_d0i3" {
tools/topology/topology2/include/common/pcm.conf- # Token reference and type
tools/topology/topology2/include/common/pcm.conf- token_ref "stream.bool"
tools/topology/topology2/include/common/pcm.conf- }
DeepBuffer flips the flag for playback to allow lower power states during playback:
tools/topology/topology2/platform/intel/deep-buffer-spk.conf: playback_compatible_d0i3 $DEEPBUFFER_D0I3_COMPATIBLE
tools/topology/topology2/platform/intel/deep-buffer.conf: playback_compatible_d0i3 $DEEPBUFFER_D0I3_COMPATIBLE
Oh, and DB dmic capture and WOV also does it:
tools/topology/topology2/platform/intel/dmic-deep-buffer.conf: capture_compatible_d0i3 $DEEPBUFFER_D0I3_COMPATIBLE
tools/topology/topology2/platform/intel/dmic-wov.conf: capture_compatible_d0i3 true
So, the only thing might be needed is to remove the d0i3_supported_in_s0ix from kernel, or set it for IPC4 to true, but then it is always going to be true...
Am I missing something?
There was a problem hiding this comment.
It indeed looks like it. However, I had trouble reading the topo2 pcm node inserted value in the ipc4 topology code. Then I implemented it in the way that I knew would work, and moved on to verifying the feature actully works on PTL HW and latest FW. Then I forgot about the earlier pcm implementation. Maybe this PR should be moved to draft and a new approach should be taken by somebody else, as my time in SOF team is running short.
|
@jsarha Is there a corresponding topology PR available? |
|
@ujfalusi , Ok this patch diminished to almost nothing, but it still works. See the updated description for details. |
There is beauty in simplicity, yes. But now |
@ujfalusi , Ok one more round. This time with d0i3_supported_in_s0ix removed. |
| if (sdev->system_suspend_target == SOF_SUSPEND_S0IX && | ||
| spcm->stream[substream->stream].d0i3_compatible) { | ||
| spcm->stream[substream->stream].suspend_ignored = true; | ||
| return 0; |
There was a problem hiding this comment.
Looking at this again and it is pretty broken imho. With this we ill keep the DSP running even if a DeepBuffer playback is running or if a deepbuffer capture and those will break suspend likely and only that if we are lucky..
this is feature hoarding under one umbrella in it's worst imho...
the pair of _COMPATIBLE_D0I3 token was added in 2019 for IPC3 to tag the WoV PCM - the playback was added as parity.
It was meant to be saying: thsi stream can remain running while the host is suspended, in low power sate (keeping the DSP on).
Fast forward to IPC4:
We added deepbuffer playback and taken the PLAYBACK_COMPATIBLE_D0I3 token to mark it with a slightly different meaning: the playback stream is running we can allow lower power state for the host, but the system should not be suspended, hence the blocking flag for IPC4: d0i3_supported_in_s0ix.
IPC4 has no support for WoV, it should not leave streams enabled on suspend.
Fast forward and the deepbuffer got extended to IPC4 capture as well to mimic the IPC4 DB playback and reuse the CAPTURE_COMPATIBLE_D0I3 from IPC3 WoV - IPC4 does not support WoV, it is not planned.
The flag still guards that streams will be stopped on suspend.
And now today: we need WoV for IPC4, but the _COMPATIBLE_D0I3 is more than what it used to be...
We need to flag WoV specifically without breaking IPC3 legacy...
If we set a rule: streams involved with WoV can be only capture streams, then cannot have DeepBuffer, they must be flagged with _COMPATIBLE_D0I3 and the check here becomes:
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;
}and fix #5951 as well to set the SNDRV_PCM_INFO_RESUME along these rules.
Enable ipc4 D0I3 stream compatibility support for S0ix by removing d0i3_supported_in_s0ix, the feature gating flag in struct sof_ipc_pcm_ops. Since both ipc3 an ipc4 now support the feature, there is no need for the flag anymore. However, since in ipc4 the d0i3_compatible flag is also used with deep-buffer capture support, we need to separate that case from the Wake on Voice support. We do it by checking the streams dsp_max_burst_size_in_ms. After this change the suspend_ignored logic in pcm.c applies also to IPC4 streams, allowing the DSP to remain in D0i3 during S0ix when D0I3-compatible streams are active (e.g. wake-on-voice keyword detection). Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Description rewritten, now that I found the correct place to put capture_compatible_d0i3 1 property in the old implementation.
The example code that I have used to test this code is here:
thesofproject/sof#11232