aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/soc/sof/sof-audio.c
diff options
context:
space:
mode:
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>2023-04-20 14:41:37 +0300
committerMark Brown <broonie@kernel.org>2023-04-20 12:51:59 +0100
commit6d0a21dd95c349bbe3663a4870ff7e70ddc6c9b6 (patch)
tree3c94805ed7b4a43d9ac2a4f636dec96eb602479e /sound/soc/sof/sof-audio.c
parentASoC: SOF: Intel: hda: Do not stop/start DMA during pause/release (diff)
downloadwireguard-linux-6d0a21dd95c349bbe3663a4870ff7e70ddc6c9b6.tar.xz
wireguard-linux-6d0a21dd95c349bbe3663a4870ff7e70ddc6c9b6.zip
ASoC: SOF: pcm: Add an option to skip platform trigger during stop
In the case of IPC4, a pipeline is only paused during STOP/PAUSE/SUSPEND triggers and the FW keeps the host DMA running when a pipeline is paused. The start/stop tests iterate through STOP/START triggers without involving a hw_free. This means that the pipeline state will only toggle between PAUSED (during the STOP trigger) and RUNNING (during the START trigger). So this test should be treated in the same way as a PAUSE_PUSH/PAUSE_RELEASE test and the DMA should be kept running when toggling the pipeline states between PAUSED and RUNNING. Since there is no way to tell if a STOP trigger will be followed by hw_free or not, this patch proposes to always skip DMA stop during the STOP trigger and handle it later during hw_free. Introduce a new flag in struct sof_ipc_pcm_ops, delayed_platform_trigger, that will be used to ensure that the host DMA will not be stopped during the STOP/PAUSE/RELEASE triggers and set it for IPC4. The platform_trigger call to stop the DMA will be invoked during PCM hw_free instead when the pipeline is reset. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Link: https://lore.kernel.org/r/20230420114137.27613-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/sof-audio.c')
-rw-r--r--sound/soc/sof/sof-audio.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 7651644fcd62..1cbda595c518 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -805,16 +805,22 @@ int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *subs
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
int ret;
- /* Send PCM_FREE IPC to reset pipeline */
- if (pcm_ops && pcm_ops->hw_free && spcm->prepared[substream->stream]) {
- ret = pcm_ops->hw_free(sdev->component, substream);
- if (ret < 0)
- return ret;
- }
+ if (spcm->prepared[substream->stream]) {
+ /* stop DMA first if needed */
+ if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
+ snd_sof_pcm_platform_trigger(sdev, substream, SNDRV_PCM_TRIGGER_STOP);
+
+ /* Send PCM_FREE IPC to reset pipeline */
+ if (pcm_ops && pcm_ops->hw_free) {
+ ret = pcm_ops->hw_free(sdev->component, substream);
+ if (ret < 0)
+ return ret;
+ }
- spcm->prepared[substream->stream] = false;
+ spcm->prepared[substream->stream] = false;
+ }
- /* stop the DMA */
+ /* reset the DMA */
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
if (ret < 0)
return ret;