alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping
@ 2021-11-25 10:15 Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget Kai Vehmanen
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

Implement an updated programming sequence to handle DMA stop for Intel
HD-Audio DMA.

The new flow is only used if the firmware is sufficiently new to support
the feature. SOF1.9.2 is the first release with the updated flow. The kernel
changes are backwards compatible with old firmware releases. Likewise new
firmware releases will work with old kernel.

Series reviewed originally at:
https://github.com/thesofproject/linux/pull/3167

Buglink: https://github.com/thesofproject/sof/issues/4779

Ranjani Sridharan (10):
  ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget
  ASoC: SOF: Intel: hda: Add a helper function for stream reset
  ASoC: SOF: Intel: hda: reset stream before coupling host and link
    DMA's
  ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers
  ASoC: SOF: call platform hw_free for paused streams during suspend
  ASoC: SOF: Add a helper for freeing PCM stream
  ASoC: SOF: pcm: move the check for prepared flag
  ASoC: SOF: align the hw_free sequence with stop
  ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags
  ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause

 include/sound/sof/dai.h          | 25 +++++++---
 sound/soc/sof/intel/hda-dai.c    | 53 +++++++++++++++++----
 sound/soc/sof/intel/hda-stream.c | 81 +++++++++++++++++++-------------
 sound/soc/sof/intel/hda.c        | 26 ++++++----
 sound/soc/sof/intel/hda.h        |  6 ++-
 sound/soc/sof/pcm.c              | 36 +++++++-------
 sound/soc/sof/sof-audio.c        | 35 ++++++++++----
 sound/soc/sof/sof-audio.h        |  2 +
 8 files changed, 180 insertions(+), 84 deletions(-)


base-commit: cd2f33e93d578e9e1c47ef8981ec69298da9cb38
-- 
2.33.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 02/10] ASoC: SOF: Intel: hda: Add a helper function for stream reset Kai Vehmanen
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

The DAI_CONFIG IPC that is sent during the STOP trigger is used for
stopping the DMA in the FW. This must be done after the DMA RUN bit is
cleared by the host. So move the call to snd_hdac_ext_link_stream_clear()
before hda_link_dai_widget_update() to follow the correct programming
sequence for DMA stop for HDA DAIs.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/intel/hda-dai.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index 5c9ee6c49473..748e8ed61475 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -329,6 +329,8 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 		break;
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_STOP:
+		snd_hdac_ext_link_stream_clear(link_dev);
+
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			w = dai->playback_widget;
 		else
@@ -347,8 +349,7 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 		}
 
 		link_dev->link_prepared = 0;
-
-		fallthrough;
+		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		snd_hdac_ext_link_stream_clear(link_dev);
 		break;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 02/10] ASoC: SOF: Intel: hda: Add a helper function for stream reset
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 03/10] ASoC: SOF: Intel: hda: reset stream before coupling host and link DMA's Kai Vehmanen
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Add a helper function to perform stream reset.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/intel/hda-stream.c | 76 ++++++++++++++++++--------------
 sound/soc/sof/intel/hda.h        |  2 +
 2 files changed, 46 insertions(+), 32 deletions(-)

diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index b6f037815344..c2895bdd3f07 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -279,6 +279,45 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
 	return 0;
 }
 
+static int hda_dsp_stream_reset(struct snd_sof_dev *sdev, struct hdac_stream *hstream)
+{
+	int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
+	int timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
+	u32 val;
+
+	/* enter stream reset */
+	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, SOF_STREAM_SD_OFFSET_CRST,
+				SOF_STREAM_SD_OFFSET_CRST);
+	do {
+		val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, sd_offset);
+		if (val & SOF_STREAM_SD_OFFSET_CRST)
+			break;
+	} while (--timeout);
+	if (timeout == 0) {
+		dev_err(sdev->dev, "timeout waiting for stream reset\n");
+		return -ETIMEDOUT;
+	}
+
+	timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
+
+	/* exit stream reset and wait to read a zero before reading any other register */
+	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, SOF_STREAM_SD_OFFSET_CRST, 0x0);
+
+	/* wait for hardware to report that stream is out of reset */
+	udelay(3);
+	do {
+		val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, sd_offset);
+		if ((val & SOF_STREAM_SD_OFFSET_CRST) == 0)
+			break;
+	} while (--timeout);
+	if (timeout == 0) {
+		dev_err(sdev->dev, "timeout waiting for stream to exit reset\n");
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
 			   struct hdac_ext_stream *stream, int cmd)
 {
@@ -436,9 +475,9 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
 	struct hdac_bus *bus = sof_to_bus(sdev);
 	struct hdac_stream *hstream = &stream->hstream;
 	int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
-	int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
+	int ret;
 	u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
-	u32 val, mask;
+	u32 mask;
 	u32 run;
 
 	if (!stream) {
@@ -483,36 +522,9 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
 				SOF_HDA_CL_DMA_SD_INT_MASK);
 
 	/* stream reset */
-	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
-				0x1);
-	udelay(3);
-	do {
-		val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
-				       sd_offset);
-		if (val & 0x1)
-			break;
-	} while (--timeout);
-	if (timeout == 0) {
-		dev_err(sdev->dev, "error: stream reset failed\n");
-		return -ETIMEDOUT;
-	}
-
-	timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
-	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
-				0x0);
-
-	/* wait for hardware to report that stream is out of reset */
-	udelay(3);
-	do {
-		val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
-				       sd_offset);
-		if ((val & 0x1) == 0)
-			break;
-	} while (--timeout);
-	if (timeout == 0) {
-		dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
-		return -ETIMEDOUT;
-	}
+	ret = hda_dsp_stream_reset(sdev, hstream);
+	if (ret < 0)
+		return ret;
 
 	if (hstream->posbuf)
 		*hstream->posbuf = 0;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 8ed4031ca007..60139ea9b8de 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -487,6 +487,8 @@ struct sof_intel_hda_stream {
 	(SOF_HDA_ADSP_SD_ENTRY_SIZE * ((s)->index) \
 	 + SOF_HDA_ADSP_LOADER_BASE)
 
+#define SOF_STREAM_SD_OFFSET_CRST 0x1
+
 /*
  * DSP Core services.
  */
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 03/10] ASoC: SOF: Intel: hda: reset stream before coupling host and link DMA's
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 02/10] ASoC: SOF: Intel: hda: Add a helper function for stream reset Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 04/10] ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers Kai Vehmanen
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

The recommended programming sequence for HD-Audio DMA is to reset the
stream before coupling the link and host DMA's.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/intel/hda-stream.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index c2895bdd3f07..440827ce390d 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -659,6 +659,11 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
 							hstream);
 	struct hdac_bus *bus = sof_to_bus(sdev);
 	u32 mask = 0x1 << stream->index;
+	int ret;
+
+	ret = hda_dsp_stream_reset(sdev, stream);
+	if (ret < 0)
+		return ret;
 
 	spin_lock_irq(&bus->reg_lock);
 	/* couple host and link DMA if link DMA channel is idle */
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 04/10] ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (2 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 03/10] ASoC: SOF: Intel: hda: reset stream before coupling host and link DMA's Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 05/10] ASoC: SOF: call platform hw_free for paused streams during suspend Kai Vehmanen
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

snd_sof_pcm_platform_hw_params() will be called when the stream is
restarted with a prepare ioctl. This happens in two cases i.e. when a
suspended stream is resumed or when a stream is restarted without
intermediate call to sof_pcm_hw_free(). Make sure to call
snd_sof_pcm_platform_hw_free() in both these cases to keep it balanced.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/pcm.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 1bf7e60be772..1d0d90551e8f 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -470,6 +470,10 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
 		if (ret < 0)
 			return ret;
 
+		ret = snd_sof_pcm_platform_hw_free(sdev, substream);
+		if (ret < 0)
+			return ret;
+
 		/* free widget list only for SUSPEND trigger */
 		if (free_widget_list)
 			ret = sof_widget_list_free(sdev, spcm, substream->stream);
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 05/10] ASoC: SOF: call platform hw_free for paused streams during suspend
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (3 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 04/10] ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 06/10] ASoC: SOF: Add a helper for freeing PCM stream Kai Vehmanen
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Paused streams must be stopped and platform hw_free should be invoked
during system suspend so they can be restarted properly after system
resume.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/sof-audio.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index e00ce275052f..d81071b39825 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -751,10 +751,17 @@ static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
 				continue;
 
 			if (spcm->stream[dir].list) {
+				/* Free PCM in the DSP */
 				ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
 				if (ret < 0)
 					return ret;
 
+				/* stop DMA */
+				ret = snd_sof_pcm_platform_hw_free(sdev, substream);
+				if (ret < 0)
+					return ret;
+
+				/* free the DAPM widget list */
 				ret = sof_widget_list_free(sdev, spcm, dir);
 				if (ret < 0) {
 					dev_err(sdev->dev, "failed to free widgets during suspend\n");
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 06/10] ASoC: SOF: Add a helper for freeing PCM stream
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (4 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 05/10] ASoC: SOF: call platform hw_free for paused streams during suspend Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 07/10] ASoC: SOF: pcm: move the check for prepared flag Kai Vehmanen
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Add a helper function to free PCM in the FW, stop the DMA and free the
widget list. These actions are performed both during PCM trigger STOP
and when a paused stream is freed during system suspend.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/pcm.c       | 11 ++---------
 sound/soc/sof/sof-audio.c | 40 +++++++++++++++++++++++++--------------
 sound/soc/sof/sof-audio.h |  2 ++
 3 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 1d0d90551e8f..3aa708b1ac26 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -466,17 +466,10 @@ static int sof_pcm_trigger(struct snd_soc_component *component,
 
 	/* free PCM if reset_hw_params is set and the STOP IPC is successful */
 	if (!ret && reset_hw_params) {
-		ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
+		ret = sof_pcm_stream_free(sdev, substream, spcm, substream->stream,
+					  free_widget_list);
 		if (ret < 0)
 			return ret;
-
-		ret = snd_sof_pcm_platform_hw_free(sdev, substream);
-		if (ret < 0)
-			return ret;
-
-		/* free widget list only for SUSPEND trigger */
-		if (free_widget_list)
-			ret = sof_widget_list_free(sdev, spcm, substream->stream);
 	}
 
 	return ret;
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index d81071b39825..a275f7b7c812 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -728,6 +728,31 @@ int sof_set_up_pipelines(struct snd_sof_dev *sdev, bool verify)
 	return 0;
 }
 
+int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
+			struct snd_sof_pcm *spcm, int dir, bool free_widget_list)
+{
+	int ret;
+
+	/* Send PCM_FREE IPC to reset pipeline */
+	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
+	if (ret < 0)
+		return ret;
+
+	/* stop the DMA */
+	ret = snd_sof_pcm_platform_hw_free(sdev, substream);
+	if (ret < 0)
+		return ret;
+
+	/* free widget list */
+	if (free_widget_list) {
+		ret = sof_widget_list_free(sdev, spcm, dir);
+		if (ret < 0)
+			dev_err(sdev->dev, "failed to free widgets during suspend\n");
+	}
+
+	return ret;
+}
+
 /*
  * Free the PCM, its associated widgets and set the prepared flag to false for all PCMs that
  * did not get suspended(ex: paused streams) so the widgets can be set up again during resume.
@@ -751,22 +776,9 @@ static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
 				continue;
 
 			if (spcm->stream[dir].list) {
-				/* Free PCM in the DSP */
-				ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
-				if (ret < 0)
-					return ret;
-
-				/* stop DMA */
-				ret = snd_sof_pcm_platform_hw_free(sdev, substream);
+				ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
 				if (ret < 0)
 					return ret;
-
-				/* free the DAPM widget list */
-				ret = sof_widget_list_free(sdev, spcm, dir);
-				if (ret < 0) {
-					dev_err(sdev->dev, "failed to free widgets during suspend\n");
-					return ret;
-				}
 			}
 		}
 
diff --git a/sound/soc/sof/sof-audio.h b/sound/soc/sof/sof-audio.h
index 1c4f59d34717..e419e7082c28 100644
--- a/sound/soc/sof/sof-audio.h
+++ b/sound/soc/sof/sof-audio.h
@@ -267,4 +267,6 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, in
 int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir);
 int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
 			 struct snd_sof_pcm *spcm);
+int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
+			struct snd_sof_pcm *spcm, int dir, bool free_widget_list);
 #endif
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 07/10] ASoC: SOF: pcm: move the check for prepared flag
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (5 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 06/10] ASoC: SOF: Add a helper for freeing PCM stream Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 08/10] ASoC: SOF: align the hw_free sequence with stop Kai Vehmanen
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Move the check for the prepared flag inside snd_pcm_dsp_pcm_free() to
avoid having to check it before every invocation of the function.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/pcm.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 3aa708b1ac26..c61cd3cc4f02 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -107,6 +107,9 @@ int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev
 	struct sof_ipc_reply reply;
 	int ret;
 
+	if (!spcm->prepared[substream->stream])
+		return 0;
+
 	stream.hdr.size = sizeof(stream);
 	stream.hdr.cmd = SOF_IPC_GLB_STREAM_MSG | SOF_IPC_STREAM_PCM_FREE;
 	stream.comp_id = spcm->stream[substream->stream].comp_id;
@@ -178,11 +181,9 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
 	 * Handle repeated calls to hw_params() without free_pcm() in
 	 * between. At least ALSA OSS emulation depends on this.
 	 */
-	if (spcm->prepared[substream->stream]) {
-		ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
-		if (ret < 0)
-			return ret;
-	}
+	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
+	if (ret < 0)
+		return ret;
 
 	dev_dbg(component->dev, "pcm: hw params stream %d dir %d\n",
 		spcm->pcm.pcm_id, substream->stream);
@@ -298,11 +299,9 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
 	dev_dbg(component->dev, "pcm: free stream %d dir %d\n",
 		spcm->pcm.pcm_id, substream->stream);
 
-	if (spcm->prepared[substream->stream]) {
-		ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
-		if (ret < 0)
-			err = ret;
-	}
+	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
+	if (ret < 0)
+		err = ret;
 
 	ret = sof_widget_list_free(sdev, spcm, substream->stream);
 	if (ret < 0)
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 08/10] ASoC: SOF: align the hw_free sequence with stop
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (6 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 07/10] ASoC: SOF: pcm: move the check for prepared flag Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 09/10] ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags Kai Vehmanen
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Even though the order of stopping the DMA and freeing the widget list is
not important, align the sequence to match with the stop trigger to
avoid confusion.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/pcm.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index c61cd3cc4f02..e4446defe51e 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -299,22 +299,26 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
 	dev_dbg(component->dev, "pcm: free stream %d dir %d\n",
 		spcm->pcm.pcm_id, substream->stream);
 
+	/* free PCM in the DSP */
 	ret = sof_pcm_dsp_pcm_free(substream, sdev, spcm);
 	if (ret < 0)
 		err = ret;
 
-	ret = sof_widget_list_free(sdev, spcm, substream->stream);
-	if (ret < 0)
-		err = ret;
-
-	cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);
 
+	/* stop DMA */
 	ret = snd_sof_pcm_platform_hw_free(sdev, substream);
 	if (ret < 0) {
 		dev_err(component->dev, "error: platform hw free failed\n");
 		err = ret;
 	}
 
+	/* free the DAPM widget list */
+	ret = sof_widget_list_free(sdev, spcm, substream->stream);
+	if (ret < 0)
+		err = ret;
+
+	cancel_work_sync(&spcm->stream[substream->stream].period_elapsed_work);
+
 	return err;
 }
 
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 09/10] ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (7 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 08/10] ASoC: SOF: align the hw_free sequence with stop Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-25 10:15 ` [PATCH 10/10] ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause Kai Vehmanen
  2021-11-27  1:29 ` [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Mark Brown
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

Some DAI components, such as HDaudio, need to be stopped in two steps
a) stop the DAI component
b) stop the DAI DMA

This patch enables this two-step stop by expanding the DAI_CONFIG
IPC flags and split them into 2 parts.

The 4 LSB bits indicate when the DAI_CONFIG IPC is sent, ex: hw_params,
hw_free or pause. The 4 MSB bits are used as the quirk flags to be used
along with the command flags. The quirk flag called
SOF_DAI_CONFIG_FLAGS_2_STEP_STOP shall be set along with the HW_PARAMS
command flag, i.e. before the pipeline is started so that the stop/pause
trigger op in the FW can take the appropriate action to either
perform/skip the DMA stop. If set, the DMA stop will be executed when
the DAI_CONFIG IPC is sent during hw_free. In the case of pause, DMA
pause will be handled when the DAI_CONFIG IPC is sent with the PAUSE
command flag.

Along with this, modify the signature for the hda_ctrl_dai_widget_setup/
hda_ctrl_dai_widget_free() functions to take additional flags as an
argument and modify all users to pass the appropriate quirk flags. Only
the HDA DAI's need to pass the SOF_DAI_CONFIG_FLAGS_2_STEP_STOP quirk
flag during hw_params to indicate that it supports two-step stop and
pause.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 include/sound/sof/dai.h       | 25 +++++++++++++++++++------
 sound/soc/sof/intel/hda-dai.c |  8 ++++----
 sound/soc/sof/intel/hda.c     | 26 ++++++++++++++++++--------
 sound/soc/sof/intel/hda.h     |  4 ++--
 sound/soc/sof/sof-audio.c     |  2 +-
 5 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h
index 5132bc60f54b..59ee50ac7705 100644
--- a/include/sound/sof/dai.h
+++ b/include/sound/sof/dai.h
@@ -52,12 +52,25 @@
 #define SOF_DAI_FMT_INV_MASK		0x0f00
 #define SOF_DAI_FMT_CLOCK_PROVIDER_MASK	0xf000
 
-/* DAI_CONFIG flags */
-#define SOF_DAI_CONFIG_FLAGS_MASK	0x3
-#define SOF_DAI_CONFIG_FLAGS_NONE	(0 << 0) /**< DAI_CONFIG sent without stage information */
-#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS	(1 << 0) /**< DAI_CONFIG sent during hw_params stage */
-#define SOF_DAI_CONFIG_FLAGS_HW_FREE	(2 << 0) /**< DAI_CONFIG sent during hw_free stage */
-#define SOF_DAI_CONFIG_FLAGS_RFU	(3 << 0) /**< not used, reserved for future use */
+/*
+ * DAI_CONFIG flags. The 4 LSB bits are used for the commands, HW_PARAMS, HW_FREE and PAUSE
+ * representing when the IPC is sent. The 4 MSB bits are used to add quirks along with the above
+ * commands.
+ */
+#define SOF_DAI_CONFIG_FLAGS_CMD_MASK	0xF
+#define SOF_DAI_CONFIG_FLAGS_NONE	0 /**< DAI_CONFIG sent without stage information */
+#define SOF_DAI_CONFIG_FLAGS_HW_PARAMS	BIT(0) /**< DAI_CONFIG sent during hw_params stage */
+#define SOF_DAI_CONFIG_FLAGS_HW_FREE	BIT(1) /**< DAI_CONFIG sent during hw_free stage */
+/**< DAI_CONFIG sent during pause trigger. Only available ABI 3.20 onwards */
+#define SOF_DAI_CONFIG_FLAGS_PAUSE	BIT(2)
+#define SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT 4
+#define SOF_DAI_CONFIG_FLAGS_QUIRK_MASK  (0xF << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT)
+/*
+ * This should be used along with the SOF_DAI_CONFIG_FLAGS_HW_PARAMS to indicate that pipeline
+ * stop/pause and DAI DMA stop/pause should happen in two steps. This change is only available
+ * ABI 3.20 onwards.
+ */
+#define SOF_DAI_CONFIG_FLAGS_2_STEP_STOP BIT(0)
 
 /** \brief Types of DAI */
 enum sof_ipc_dai_type {
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index 748e8ed61475..bce5366cf913 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -197,9 +197,9 @@ static int hda_link_dai_widget_update(struct sof_intel_hda_stream *hda_stream,
 
 	/* set up/free DAI widget and send DAI_CONFIG IPC */
 	if (widget_setup)
-		return hda_ctrl_dai_widget_setup(w);
+		return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP);
 
-	return hda_ctrl_dai_widget_free(w);
+	return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
 }
 
 static int hda_link_hw_params(struct snd_pcm_substream *substream,
@@ -452,9 +452,9 @@ static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd
 		return 0;
 
 	if (setup)
-		return hda_ctrl_dai_widget_setup(w);
+		return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE);
 
-	return hda_ctrl_dai_widget_free(w);
+	return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
 }
 
 static int ssp_dai_startup(struct snd_pcm_substream *substream,
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 1e1e9659ea86..cfe026dbf124 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -41,7 +41,7 @@
 #define EXCEPT_MAX_HDR_SIZE	0x400
 #define HDA_EXT_ROM_STATUS_SIZE 8
 
-int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w)
+int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags)
 {
 	struct snd_sof_widget *swidget = w->dobj.private;
 	struct snd_soc_component *component = swidget->scomp;
@@ -58,6 +58,13 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w)
 		return -EINVAL;
 	}
 
+	/* DAI already configured, reset it before reconfiguring it */
+	if (sof_dai->configured) {
+		ret = hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
+		if (ret < 0)
+			return ret;
+	}
+
 	config = &sof_dai->dai_config[sof_dai->current_config];
 
 	/*
@@ -71,8 +78,10 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w)
 		return ret;
 	}
 
-	/* set HW_PARAMS flag */
-	config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_HW_PARAMS);
+	/* set HW_PARAMS flag along with quirks */
+	config->flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS |
+		       quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
+
 
 	/* send DAI_CONFIG IPC */
 	ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
@@ -87,7 +96,7 @@ int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w)
 	return 0;
 }
 
-int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w)
+int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags)
 {
 	struct snd_sof_widget *swidget = w->dobj.private;
 	struct snd_soc_component *component = swidget->scomp;
@@ -110,8 +119,9 @@ int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w)
 
 	config = &sof_dai->dai_config[sof_dai->current_config];
 
-	/* set HW_FREE flag */
-	config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_HW_FREE);
+	/* set HW_FREE flag along with any quirks */
+	config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE |
+		       quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
 
 	ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
 				 &reply, sizeof(reply));
@@ -166,9 +176,9 @@ static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
 	config->alh.stream_id = alh_stream_id;
 
 	if (setup)
-		return hda_ctrl_dai_widget_setup(w);
+		return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE);
 
-	return hda_ctrl_dai_widget_free(w);
+	return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
 }
 
 static int sdw_params_stream(struct device *dev,
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 60139ea9b8de..72e78c449aa8 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -739,7 +739,7 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
 
 struct snd_sof_dai;
 struct sof_ipc_dai_config;
-int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w);
-int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w);
+int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
+int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
 
 #endif
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index a275f7b7c812..58a62bfb16ab 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -57,7 +57,7 @@ static int sof_dai_config_setup(struct snd_sof_dev *sdev, struct snd_sof_dai *da
 	}
 
 	/* set NONE flag to clear all previous settings */
-	config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_MASK, SOF_DAI_CONFIG_FLAGS_NONE);
+	config->flags = SOF_DAI_CONFIG_FLAGS_NONE;
 
 	ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
 				 &reply, sizeof(reply));
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 10/10] ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (8 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 09/10] ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags Kai Vehmanen
@ 2021-11-25 10:15 ` Kai Vehmanen
  2021-11-27  1:29 ` [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Mark Brown
  10 siblings, 0 replies; 12+ messages in thread
From: Kai Vehmanen @ 2021-11-25 10:15 UTC (permalink / raw)
  To: alsa-devel, broonie
  Cc: kai.vehmanen, yung-chuan.liao, lgirdwood, pierre-louis.bossart,
	ranjani.sridharan, daniel.baluta

From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>

For HDA DAI's the DMA must be paused after the RUN bit is cleared by the
host. So, send the DAI_CONFIG IPC with just the SOF_DAI_CONFIG_FLAGS_PAUSE
flag set to indicate this to the firmware.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
---
 sound/soc/sof/intel/hda-dai.c | 42 ++++++++++++++++++++++++++++++-----
 1 file changed, 37 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index bce5366cf913..8c1d7ddb00e2 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -287,6 +287,36 @@ static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
 				  dai);
 }
 
+static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)
+{
+	struct snd_sof_widget *swidget = w->dobj.private;
+	struct snd_soc_component *component = swidget->scomp;
+	struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
+	struct sof_ipc_dai_config *config;
+	struct snd_sof_dai *sof_dai;
+	struct sof_ipc_reply reply;
+	int ret;
+
+	sof_dai = swidget->private;
+
+	if (!sof_dai || !sof_dai->dai_config) {
+		dev_err(sdev->dev, "No config for DAI %s\n", w->name);
+		return -EINVAL;
+	}
+
+	config = &sof_dai->dai_config[sof_dai->current_config];
+
+	/* set PAUSE command flag */
+	config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_CMD_MASK, SOF_DAI_CONFIG_FLAGS_PAUSE);
+
+	ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
+				 &reply, sizeof(reply));
+	if (ret < 0)
+		dev_err(sdev->dev, "DAI config for %s failed during pause push\n", w->name);
+
+	return ret;
+}
+
 static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 				int cmd, struct snd_soc_dai *dai)
 {
@@ -312,6 +342,9 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 	hda_stream = hstream_to_sof_hda_stream(link_dev);
 
 	dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
+
+	w = snd_soc_dai_get_widget(dai, substream->stream);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_RESUME:
 		/* set up hw_params */
@@ -331,11 +364,6 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_STOP:
 		snd_hdac_ext_link_stream_clear(link_dev);
 
-		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-			w = dai->playback_widget;
-		else
-			w = dai->capture_widget;
-
 		/*
 		 * free DAI widget during stop/suspend to keep widget use_count's balanced.
 		 */
@@ -352,6 +380,10 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
 		break;
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		snd_hdac_ext_link_stream_clear(link_dev);
+
+		ret = hda_link_dai_config_pause_push_ipc(w);
+		if (ret < 0)
+			return ret;
 		break;
 	default:
 		return -EINVAL;
-- 
2.33.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping
  2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
                   ` (9 preceding siblings ...)
  2021-11-25 10:15 ` [PATCH 10/10] ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause Kai Vehmanen
@ 2021-11-27  1:29 ` Mark Brown
  10 siblings, 0 replies; 12+ messages in thread
From: Mark Brown @ 2021-11-27  1:29 UTC (permalink / raw)
  To: alsa-devel, Kai Vehmanen
  Cc: daniel.baluta, lgirdwood, yung-chuan.liao, ranjani.sridharan,
	pierre-louis.bossart

On Thu, 25 Nov 2021 12:15:10 +0200, Kai Vehmanen wrote:
> Implement an updated programming sequence to handle DMA stop for Intel
> HD-Audio DMA.
> 
> The new flow is only used if the firmware is sufficiently new to support
> the feature. SOF1.9.2 is the first release with the updated flow. The kernel
> changes are backwards compatible with old firmware releases. Likewise new
> firmware releases will work with old kernel.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget
        commit: e14cddc5888418cc9f2ba66c01a04cdbab3b5b25
[02/10] ASoC: SOF: Intel: hda: Add a helper function for stream reset
        commit: 2b1acedccf36434924ae530410e008e7eb427cd3
[03/10] ASoC: SOF: Intel: hda: reset stream before coupling host and link DMA's
        commit: 4794601a52d40a425542be1b88f8f5614fcf45b4
[04/10] ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers
        commit: 0dd71a3340b92b503278af4565156f086ccbca3f
[05/10] ASoC: SOF: call platform hw_free for paused streams during suspend
        commit: 47934e0fcbbe2bf488bcae2d68431b9ea5972488
[06/10] ASoC: SOF: Add a helper for freeing PCM stream
        commit: d9a7246534753efa383ad8d05ab3691df846c4b4
[07/10] ASoC: SOF: pcm: move the check for prepared flag
        commit: 85d7acd0ef18725b1d3a7980eee8b84d46296b91
[08/10] ASoC: SOF: align the hw_free sequence with stop
        commit: 0b639dcd457b1d3fc660e5a77b02cf65acde3b5a
[09/10] ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags
        commit: a0f84dfb3f6d9f78f862cbe885036d3e4449fc6f
[10/10] ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause
        commit: 69acac569031426e2ab9b5244593b60d0c9abd04

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-11-27  1:31 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-25 10:15 [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Kai Vehmanen
2021-11-25 10:15 ` [PATCH 01/10] ASoC: SOF: Intel: hda: clear stream before freeing the DAI widget Kai Vehmanen
2021-11-25 10:15 ` [PATCH 02/10] ASoC: SOF: Intel: hda: Add a helper function for stream reset Kai Vehmanen
2021-11-25 10:15 ` [PATCH 03/10] ASoC: SOF: Intel: hda: reset stream before coupling host and link DMA's Kai Vehmanen
2021-11-25 10:15 ` [PATCH 04/10] ASoC: SOF: pcm: invoke platform hw_free for STOP/SUSPEND triggers Kai Vehmanen
2021-11-25 10:15 ` [PATCH 05/10] ASoC: SOF: call platform hw_free for paused streams during suspend Kai Vehmanen
2021-11-25 10:15 ` [PATCH 06/10] ASoC: SOF: Add a helper for freeing PCM stream Kai Vehmanen
2021-11-25 10:15 ` [PATCH 07/10] ASoC: SOF: pcm: move the check for prepared flag Kai Vehmanen
2021-11-25 10:15 ` [PATCH 08/10] ASoC: SOF: align the hw_free sequence with stop Kai Vehmanen
2021-11-25 10:15 ` [PATCH 09/10] ASoC: SOF: IPC: dai: Expand DAI_CONFIG IPC flags Kai Vehmanen
2021-11-25 10:15 ` [PATCH 10/10] ASoC: SOF: Intel: hda: send DAI_CONFIG IPC during pause Kai Vehmanen
2021-11-27  1:29 ` [PATCH 00/10] ASoC: SOF: Fixes for Intel HD-Audio DMA stopping Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).