From 1fd8976409705fb0931eb055e0b515000c27de3f Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Tue, 6 Aug 2024 12:11:12 +0300 Subject: [PATCH 1/3] ASOC: SOF: Intel: hda-loader: do not wait for HDaudio IOC Commit 9ee3f0d8c999 (" ASOC: SOF: Intel: hda-loader: only wait for HDaudio IOC for IPC4 devices") removed DMA wait for IPC3 case. Proceed and remove the wait for IPC4 devices as well. There is no dependency to IPC version in the load logic and checking the firmware status is a sufficient check in case of errors. The removed code also had a bug in that -ETIMEDOUT is returned without stopping the DMA transfer. Link: https://github.com/thesofproject/linux/issues/5135 Suggested-by: Peter Ujfalusi Signed-off-by: Kai Vehmanen --- sound/soc/sof/intel/hda-loader.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 75f6240cf3e1d3..9d8ebb7c6a1060 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -294,14 +294,9 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; - struct sof_intel_hda_stream *hda_stream; - unsigned long time_left; unsigned int reg; int ret, status; - hda_stream = container_of(hext_stream, struct sof_intel_hda_stream, - hext_stream); - dev_dbg(sdev->dev, "Code loader DMA starting\n"); ret = hda_cl_trigger(sdev->dev, hext_stream, SNDRV_PCM_TRIGGER_START); @@ -310,18 +305,6 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream return ret; } - if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { - /* Wait for completion of transfer */ - time_left = wait_for_completion_timeout(&hda_stream->ioc, - msecs_to_jiffies(HDA_CL_DMA_IOC_TIMEOUT_MS)); - - if (!time_left) { - dev_err(sdev->dev, "Code loader DMA did not complete\n"); - return -ETIMEDOUT; - } - dev_dbg(sdev->dev, "Code loader DMA done\n"); - } - dev_dbg(sdev->dev, "waiting for FW_ENTERED status\n"); status = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, From ddbb29b818a956c0462e4fa37b2b68037e06169e Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 7 Aug 2024 16:08:12 +0300 Subject: [PATCH 2/3] ASOC: SOF: Intel: hda-stream: do not filter position==bufsize When a single-shot DMA is complete, hda_dsp_stream_get_position() will point to hstream->bufsize. Current code zeros out the returned position in this case as ALSA core does not expect to get such values in its pointer callback. While valid in the ALSA case, this is no helpful when debugging other DMA usages, e.g. firmware loading. Allow valid value of hstream->bufsize to be returned as a position. Signed-off-by: Kai Vehmanen --- sound/soc/sof/intel/hda-stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 3ac63ce67ab1ce..9f446ce6882e48 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -1082,7 +1082,7 @@ snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, break; } - if (pos >= hstream->bufsize) + if (pos > hstream->bufsize) pos = 0; return pos; From 67550c807a90515ea8070377849a38befeb8939b Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Wed, 7 Aug 2024 16:11:44 +0300 Subject: [PATCH 3/3] ASOC: SOF: Intel: hda-stream: report DMA position if FW load fails To help debugging FW load failures, print out the last position of the DMA used to load the firmware image. This allows to see whether DMA transfer has started and whether it completed. Signed-off-by: Kai Vehmanen --- sound/soc/sof/intel/hda-loader.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 9d8ebb7c6a1060..c93c83f04ecf16 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -319,9 +319,11 @@ int hda_cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream */ if (status < 0) { + struct hdac_stream *hstream = &hext_stream->hstream; + snd_pcm_uframes_t pos = hda_dsp_stream_get_position(hstream, SNDRV_PCM_STREAM_PLAYBACK, 0); dev_err(sdev->dev, - "%s: timeout with rom_status_reg (%#x) read\n", - __func__, chip->rom_status_reg); + "%s: timeout with rom_status_reg (%#x) read, DMA pos %lu/%lu\n", + __func__, chip->rom_status_reg, pos, hstream->bufsize); } else { dev_dbg(sdev->dev, "Code loader FW_ENTERED status\n"); }