From da3a15e0ac406a14b0117b62a0bc1c46d57d1ebb Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 10 Mar 2023 17:47:18 -0800 Subject: [PATCH 1/2] ASoC: SOF: Intel: hda-dai: Do not perform DMA cleanup during stop In the case of repeated start/stop without involving hw_free, the stream tag needs to be preserved for the subsequent starts. So, skip performing the DMA clean up during stop and handle it only during suspend or hw_free. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/intel/hda-dai.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index fe6ec95e188a38..f4c8d8d28d1d65 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -289,7 +289,6 @@ static int hda_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct switch (cmd) { case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_STOP: ret = hda_link_dma_cleanup(substream, hext_stream, dai); if (ret < 0) { dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); From feb21d4ed65c039cb615cd5497d208abe1aec293 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Fri, 10 Mar 2023 17:54:08 -0800 Subject: [PATCH 2/2] ASoC: SOF: pcm: Make hw_params reset conditional for IPC3 In the case of IPC4, since there is no PCM_PARAMS IPC to send the new stream tag when restarting a stream without a hw_free, the original stream tag needs to be preserved. So, add new a flag as part of struct sof_ipc_pcm_ops, reset_hw_params_during_stop and set it only for IPC3. This will ensure that the host DMA stream tag will not be given up during the STOP trigger for IPC4. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/ipc3-pcm.c | 1 + sound/soc/sof/pcm.c | 3 ++- sound/soc/sof/sof-audio.h | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/ipc3-pcm.c b/sound/soc/sof/ipc3-pcm.c index 31aa3666b1b3b9..304faf6425abc1 100644 --- a/sound/soc/sof/ipc3-pcm.c +++ b/sound/soc/sof/ipc3-pcm.c @@ -380,4 +380,5 @@ const struct sof_ipc_pcm_ops ipc3_pcm_ops = { .hw_free = sof_ipc3_pcm_hw_free, .trigger = sof_ipc3_pcm_trigger, .dai_link_fixup = sof_ipc3_pcm_dai_link_fixup, + .reset_hw_params_during_stop = true, }; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index bcafcb9b0a3cdb..b13c496d13afd2 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -328,7 +328,8 @@ static int sof_pcm_trigger(struct snd_soc_component *component, fallthrough; case SNDRV_PCM_TRIGGER_STOP: ipc_first = true; - reset_hw_params = true; + if (pcm_ops && pcm_ops->reset_hw_params_during_stop) + reset_hw_params = true; break; default: dev_err(component->dev, "Unhandled trigger cmd %d\n", cmd); diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h index d220af5f08fb30..81685e778ad695 100644 --- a/sound/soc/sof/sof-audio.h +++ b/sound/soc/sof/sof-audio.h @@ -104,6 +104,8 @@ struct snd_sof_dai_config_data { * @pcm_free: Function pointer for PCM free that can be used for freeing any * additional memory in the SOF PCM stream structure * @delay: Function pointer for pcm delay calculation + * @reset_hw_params_during_stop: Flag indicating whether the hw_params should be reset during the + * STOP pcm trigger */ struct sof_ipc_pcm_ops { int (*hw_params)(struct snd_soc_component *component, struct snd_pcm_substream *substream, @@ -117,6 +119,7 @@ struct sof_ipc_pcm_ops { void (*pcm_free)(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm); snd_pcm_sframes_t (*delay)(struct snd_soc_component *component, struct snd_pcm_substream *substream); + bool reset_hw_params_during_stop; }; /**