summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel/hda-stream.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>2024-03-21 15:08:14 +0200
committerMark Brown <broonie@kernel.org>2024-03-25 16:36:06 +0000
commit1abc2642588e06f6180b3fbb21968cf5d0ba9e5f (patch)
treef30f3d6e173c7a132522fbfcee6242c9db7326af /sound/soc/sof/intel/hda-stream.c
parentf9eeb6bb13fb5d7af1ea5b74a10b1f8ead962540 (diff)
ASoC: SOF: Intel: hda: Compensate LLP in case it is not reset
During pause/reset or stop/start the LLP counter is not reset, which will result broken delay reporting. Read the LLP value on STOP/PAUSE trigger and use it in LLP reading to normalize the LLP from the register. Cc: stable@vger.kernel.org # 6.8 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://msgid.link/r/20240321130814.4412-18-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sof/intel/hda-stream.c')
-rw-r--r--sound/soc/sof/intel/hda-stream.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index 8504a4f27b60..0c189d3b19c1 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -1064,6 +1064,8 @@ snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
return pos;
}
+#define merge_u64(u32_u, u32_l) (((u64)(u32_u) << 32) | (u32_l))
+
/**
* hda_dsp_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
* @sdev: SOF device
@@ -1093,7 +1095,12 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
llp_l = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL);
llp_u = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU);
- return ((u64)llp_u << 32) | llp_l;
+ /* Compensate the LLP counter with the saved offset */
+ if (hext_stream->pplcllpl || hext_stream->pplcllpu)
+ return merge_u64(llp_u, llp_l) -
+ merge_u64(hext_stream->pplcllpu, hext_stream->pplcllpl);
+
+ return merge_u64(llp_u, llp_l);
}
/**