All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, broonie@kernel.org,
	Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>,
	Kai Vehmanen <kai.vehmanen@linux.intel.com>
Subject: [PATCH 02/21] ASoC: SOF: reset DMA state in prepare
Date: Mon, 22 Jul 2019 09:13:43 -0500	[thread overview]
Message-ID: <20190722141402.7194-3-pierre-louis.bossart@linux.intel.com> (raw)
In-Reply-To: <20190722141402.7194-1-pierre-louis.bossart@linux.intel.com>

From: Kai Vehmanen <kai.vehmanen@linux.intel.com>

When application goes through SUSPEND/STOP->PREPARE->START
cycle, we should always reprogram the SOF device to start
DMA from a known state so that hw_ptr/appl_ptrs remain valid.
This is expected by ALSA core as it resets the buffer
state as part of prepare (see snd_pcm_do_prepare()).

Fix the issue by forcing reconfiguration of the FW with
STREAM_PCM_PARAMS in prepare(). Use combined logic to handle
prepare and the existing flow to reprogram hw-params after
system suspend.

Without the fix, first call to pcm pointer() will return
an invalid hw_ptr and application may immediately observe XRUN
status, unless "start_threshold" SW parameter is set to maximum
value by the application.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/sof/pcm.c      | 27 +++++++++++++++------------
 sound/soc/sof/pm.c       |  2 +-
 sound/soc/sof/sof-priv.h |  2 +-
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 334e9d59b1ba..3b8955e755b2 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -208,12 +208,11 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream,
 	if (ret < 0)
 		return ret;
 
+	spcm->prepared[substream->stream] = true;
+
 	/* save pcm hw_params */
 	memcpy(&spcm->params[substream->stream], params, sizeof(*params));
 
-	/* clear hw_params_upon_resume flag */
-	spcm->hw_params_upon_resume[substream->stream] = 0;
-
 	return ret;
 }
 
@@ -236,6 +235,9 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
 	if (!spcm)
 		return -EINVAL;
 
+	if (!spcm->prepared[substream->stream])
+		return 0;
+
 	dev_dbg(sdev->dev, "pcm: free stream %d dir %d\n", spcm->pcm.pcm_id,
 		substream->stream);
 
@@ -258,6 +260,8 @@ static int sof_pcm_hw_free(struct snd_pcm_substream *substream)
 	if (ret < 0)
 		dev_err(sdev->dev, "error: platform hw free failed\n");
 
+	spcm->prepared[substream->stream] = false;
+
 	return ret;
 }
 
@@ -278,11 +282,7 @@ static int sof_pcm_prepare(struct snd_pcm_substream *substream)
 	if (!spcm)
 		return -EINVAL;
 
-	/*
-	 * check if hw_params needs to be set-up again.
-	 * This is only needed when resuming from system sleep.
-	 */
-	if (!spcm->hw_params_upon_resume[substream->stream])
+	if (spcm->prepared[substream->stream])
 		return 0;
 
 	dev_dbg(sdev->dev, "pcm: prepare stream %d dir %d\n", spcm->pcm.pcm_id,
@@ -311,6 +311,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	struct snd_sof_pcm *spcm;
 	struct sof_ipc_stream stream;
 	struct sof_ipc_reply reply;
+	bool reset_hw_params = false;
 	int ret;
 
 	/* nothing to do for BE */
@@ -351,6 +352,7 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_STOP:
 		stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP;
+		reset_hw_params = true;
 		break;
 	default:
 		dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd);
@@ -363,17 +365,17 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 	ret = sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
 				 sizeof(stream), &reply, sizeof(reply));
 
-	if (ret < 0 || cmd != SNDRV_PCM_TRIGGER_SUSPEND)
+	if (ret < 0 || !reset_hw_params)
 		return ret;
 
 	/*
-	 * The hw_free op is usually called when the pcm stream is closed.
-	 * Since the stream is not closed during suspend, the DSP needs to be
-	 * notified explicitly to free pcm to prevent errors upon resume.
+	 * In case of stream is stopped, DSP must be reprogrammed upon
+	 * restart, so free PCM here.
 	 */
 	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;
+	spcm->prepared[substream->stream] = false;
 
 	/* send IPC to the DSP */
 	return sof_ipc_tx_message(sdev->ipc, stream.hdr.cmd, &stream,
@@ -481,6 +483,7 @@ static int sof_pcm_open(struct snd_pcm_substream *substream)
 	spcm->stream[substream->stream].posn.host_posn = 0;
 	spcm->stream[substream->stream].posn.dai_posn = 0;
 	spcm->stream[substream->stream].substream = substream;
+	spcm->prepared[substream->stream] = false;
 
 	ret = snd_sof_pcm_platform_open(sdev, substream);
 	if (ret < 0)
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index 278abfd10490..48c6d78d72e2 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -233,7 +233,7 @@ static int sof_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
 
 			state = substream->runtime->status->state;
 			if (state == SNDRV_PCM_STATE_SUSPENDED)
-				spcm->hw_params_upon_resume[dir] = 1;
+				spcm->prepared[dir] = false;
 		}
 	}
 
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index b8c0b2a22684..fa5cb7d2a660 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -297,7 +297,7 @@ struct snd_sof_pcm {
 	struct snd_sof_pcm_stream stream[2];
 	struct list_head list;	/* list in sdev pcm list */
 	struct snd_pcm_hw_params params[2];
-	int hw_params_upon_resume[2]; /* set up hw_params upon resume */
+	bool prepared[2]; /* PCM_PARAMS set successfully */
 };
 
 /* ALSA SOF Kcontrol device */
-- 
2.20.1

  parent reply	other threads:[~2019-07-22 14:14 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-22 14:13 [PATCH 00/21] ASoC: SOF: updates for 5.4 Pierre-Louis Bossart
2019-07-22 14:13 ` [PATCH 01/21] ASoC: SOF: pci: mark last_busy value at runtime PM init Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: pci: mark last_busy value at runtime PM init" to the asoc tree Mark Brown
2019-07-22 14:13 ` Pierre-Louis Bossart [this message]
2019-07-23 11:29   ` Applied "ASoC: SOF: reset DMA state in prepare" " Mark Brown
2019-07-22 14:13 ` [PATCH 03/21] ASoC: SOF: use common code to send PCM_FREE IPC Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: use common code to send PCM_FREE IPC" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 04/21] ASoC: SOF: ipc: use timeout configured at probe Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: ipc: use timeout configured at probe" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 05/21] ASoC: SOF: core: increase default IPC timeouts Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: core: increase default IPC timeouts" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 06/21] ASoC: SOF: Introduce snd_sof_dsp_get_bar_index ops Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Introduce snd_sof_dsp_get_bar_index ops" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 07/21] ASoC: SOF: loader: Use the BAR provided by FW Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: loader: Use the BAR provided by FW" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 08/21] ASoC: SOF: loader: Don't ignore SRAM block types Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: loader: Don't ignore SRAM block types" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 09/21] ASoC: SOF: remove unused state variable in suspend function Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: remove unused state variable in suspend function" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 10/21] ASoC: SOF: Intel: hda: correct ROM state mask Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: correct ROM state mask" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 11/21] ASoC: SOF: Intel: hda: reduce ifdef usage for hda Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: reduce ifdef usage for hda" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 12/21] ASoC: SOF: Intel: hda: Enable jack detection Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: Enable jack detection" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 13/21] ASoC: SOF: Intel: hda: set position buffer in init chip Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: set position buffer in init chip" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 14/21] ASoC: SOF: Intel: hda: use SOF defined init chip in resume Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: use SOF defined init chip in resume" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 15/21] ASoC: SOF: Intel: hda: remove duplicated clear WAKESTS Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: remove duplicated clear WAKESTS" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 16/21] ASoC: SOF: Intel: hda: add a parameter to disable MSI Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: add a parameter to disable MSI" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 17/21] ASoC: SOF: Intel: hda: reset link DMA state in prepare Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: reset link DMA state in prepare" to the asoc tree Mark Brown
2019-07-22 14:13 ` [PATCH 18/21] ASoC: SOF: Intel: hda: fix link DMA config Pierre-Louis Bossart
2019-07-23 11:15   ` Mark Brown
2019-07-23 14:37     ` Pierre-Louis Bossart
2019-07-23 16:30       ` Mark Brown
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: fix link DMA config" to the asoc tree Mark Brown
2019-07-22 14:14 ` [PATCH 19/21] ASoC: SOF: Intel: hda: fix stream id setting Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: fix stream id setting" to the asoc tree Mark Brown
2019-07-22 14:14 ` [PATCH 20/21] ASoC: SOF: Intel: hda: remove misleading error trace from IRQ thread Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: hda: remove misleading error trace from IRQ thread" to the asoc tree Mark Brown
2019-07-22 14:14 ` [PATCH 21/21] ASoC: SOF: Intel: ssp: BCLK delay parameter Pierre-Louis Bossart
2019-07-23 11:29   ` Applied "ASoC: SOF: Intel: ssp: BCLK delay parameter" to the asoc tree Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190722141402.7194-3-pierre-louis.bossart@linux.intel.com \
    --to=pierre-louis.bossart@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=kai.vehmanen@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.