Skip to content

Commit 67b182b

Browse files
ujfalusibroonie
authored andcommitted
ASoC: SOF: Intel: hda: Implement get_stream_position (Linear Link Position)
When the Linear Link Position is not available in firmware SRAM window we use the host accessible position registers to read it. The address of the PPLCLLPL/U registers depend on the number of streams (playback+capture). At probe time the pplc_addr is calculated for each stream and we can use it to read the LLP without the need of address re-calculation. Set the get_stream_position callback in sof_hda_common_ops for all platforms: The callback is used for IPC4 delay calculations only but the register is a generic HDA register, not tied to any specific IPC version. Cc: stable@vger.kernel.org # 6.8 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://msgid.link/r/20240321130814.4412-5-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent fe76d2e commit 67b182b

File tree

3 files changed

+37
-0
lines changed

3 files changed

+37
-0
lines changed

sound/soc/sof/intel/hda-common-ops.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ struct snd_sof_dsp_ops sof_hda_common_ops = {
5757
.pcm_pointer = hda_dsp_pcm_pointer,
5858
.pcm_ack = hda_dsp_pcm_ack,
5959

60+
.get_stream_position = hda_dsp_get_stream_llp,
61+
6062
/* firmware loading */
6163
.load_firmware = snd_sof_load_firmware_raw,
6264

sound/soc/sof/intel/hda-stream.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,3 +1063,35 @@ snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
10631063

10641064
return pos;
10651065
}
1066+
1067+
/**
1068+
* hda_dsp_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
1069+
* @sdev: SOF device
1070+
* @component: ASoC component
1071+
* @substream: PCM substream
1072+
*
1073+
* Returns the raw Linear Link Position value
1074+
*/
1075+
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1076+
struct snd_soc_component *component,
1077+
struct snd_pcm_substream *substream)
1078+
{
1079+
struct hdac_stream *hstream = substream->runtime->private_data;
1080+
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
1081+
u32 llp_l, llp_u;
1082+
1083+
/*
1084+
* The pplc_addr have been calculated during probe in
1085+
* hda_dsp_stream_init():
1086+
* pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
1087+
* SOF_HDA_PPLC_BASE +
1088+
* SOF_HDA_PPLC_MULTI * total_stream +
1089+
* SOF_HDA_PPLC_INTERVAL * stream_index
1090+
*
1091+
* Use this pre-calculated address to avoid repeated re-calculation.
1092+
*/
1093+
llp_l = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPL);
1094+
llp_u = readl(hext_stream->pplc_addr + AZX_REG_PPLCLLPU);
1095+
1096+
return ((u64)llp_u << 32) | llp_l;
1097+
}

sound/soc/sof/intel/hda.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,9 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);
662662

663663
snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream,
664664
int direction, bool can_sleep);
665+
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
666+
struct snd_soc_component *component,
667+
struct snd_pcm_substream *substream);
665668

666669
struct hdac_ext_stream *
667670
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);

0 commit comments

Comments
 (0)