From 063b2b8b18e916547dfa0cf13ba207c6a27a869e Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Fri, 19 Jan 2024 20:22:08 +0800 Subject: [PATCH] ASoC: SOF: ipc4-pcm: calculate delay with snd_sof_pcm_platform_pointer Currently we use runtime->hw_ptr for host dma position and decrease it with BE dai link position to calculate delay and find runtime->hw_ptr is smaller than BE dai link position for playback. This is incorrect since snd_pcm_delay function is called first and then hw_ptr is updated to latest host dma position, so hw_ptr here is for the last host dma position update. This results to hw_ptr is smaller than latest BE dai link position. Now use snd_sof_pcm_platform_pointer directly to get the latest host dma position and calculate delay with latest BE dai link position. The BE stream position is increased from zero to MAX_UINT and now we compare it with snd_sof_pcm_platform_pointer which is also increased from zero to MAX_UINT and wrapped with runtime->buffer_size, so we need to wrap BE stream position with runtime->buffer_size instead of runtime->boundary which is used for hw_ptr wrapping. Link: https://github.com/thesofproject/linux/issues/4781 https://github.com/thesofproject/linux/issues/4686 Signed-off-by: Rander Wang --- sound/soc/sof/ipc4-pcm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index 85d3f390e4b290..554b2ec35a28bc 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -891,17 +891,17 @@ static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component, tmp_ptr -= time_info->stream_start_offset; /* Calculate the delay taking into account that both pointer can wrap */ - div64_u64_rem(tmp_ptr, substream->runtime->boundary, &tmp_ptr); + div64_u64_rem(tmp_ptr, substream->runtime->buffer_size, &tmp_ptr); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - head_ptr = substream->runtime->status->hw_ptr; + head_ptr = snd_sof_pcm_platform_pointer(sdev, substream); tail_ptr = tmp_ptr; } else { head_ptr = tmp_ptr; - tail_ptr = substream->runtime->status->hw_ptr; + tail_ptr = snd_sof_pcm_platform_pointer(sdev, substream); } if (head_ptr < tail_ptr) - return substream->runtime->boundary - tail_ptr + head_ptr; + return substream->runtime->buffer_size - tail_ptr + head_ptr; return head_ptr - tail_ptr; }