Skip to content

Commit

Permalink
ASoC: SOF: ipc4-pcm: Correct delay reporting
Browse files Browse the repository at this point in the history
The link start offset and link position is in frames from the hardware,
there is no need for conversion.

At the start of the stream the link position can be lower than the start
offset as the firmware provides a calculated estimate of it by taking the
link DMA position and adding a calculated latency through the audio
processing.

Fixes: 3937a76 ("ASoC: SOF: ipc4-pcm: add delay function support")
Link: thesofproject#4781
Reported-by: Kai Vehmanen <[email protected]>
Signed-off-by: Peter Ujfalusi <[email protected]>
  • Loading branch information
ujfalusi committed Jan 17, 2024
1 parent da4523f commit 7413ce2
Showing 1 changed file with 6 additions and 11 deletions.
17 changes: 6 additions & 11 deletions sound/soc/sof/ipc4-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -818,9 +818,7 @@ static int sof_ipc4_get_stream_start_offset(struct snd_sof_dev *sdev,
struct sof_ipc4_copier *host_copier = time_info->host_copier;
struct sof_ipc4_copier *dai_copier = time_info->dai_copier;
struct sof_ipc4_pipeline_registers ppl_reg;
u64 stream_start_position;
u32 dai_sample_size;
u32 ch, node_index;
u32 node_index;
u32 offset;

if (!host_copier || !dai_copier)
Expand All @@ -835,13 +833,7 @@ static int sof_ipc4_get_stream_start_offset(struct snd_sof_dev *sdev,
if (ppl_reg.stream_start_offset == SOF_IPC4_INVALID_STREAM_POSITION)
return -EINVAL;

stream_start_position = ppl_reg.stream_start_offset;
ch = dai_copier->data.out_format.fmt_cfg;
ch = SOF_IPC4_AUDIO_FORMAT_CFG_CHANNELS_COUNT(ch);
dai_sample_size = (dai_copier->data.out_format.bit_depth >> 3) * ch;
/* convert offset to sample count */
do_div(stream_start_position, dai_sample_size);
time_info->stream_start_offset = stream_start_position;
time_info->stream_start_offset = ppl_reg.stream_start_offset;

return 0;
}
Expand Down Expand Up @@ -899,7 +891,10 @@ static snd_pcm_sframes_t sof_ipc4_pcm_delay(struct snd_soc_component *component,
* Firmware calculates correct stream_start_offset for all cases including above two.
* Driver subtracts stream_start_offset from dai dma position to get accurate one
*/
tmp_ptr -= time_info->stream_start_offset;
if (tmp_ptr > time_info->stream_start_offset)
tmp_ptr -= time_info->stream_start_offset;
else
tmp_ptr = 0;

/* Calculate the delay taking into account that both pointer can wrap */
div64_u64_rem(tmp_ptr, substream->runtime->boundary, &tmp_ptr);
Expand Down

0 comments on commit 7413ce2

Please sign in to comment.