From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: "Sasha Levin" <sashal@kernel.org>,
guennadi.liakhovetski@linux.intel.com,
alsa-devel@alsa-project.org, kai.vehmanen@linux.intel.com,
daniel.baluta@nxp.com, tiwai@suse.com, lgirdwood@gmail.com,
"Pierre-Louis Bossart" <pierre-louis.bossart@linux.intel.com>,
"Mark Brown" <broonie@kernel.org>,
yung-chuan.liao@linux.intel.com,
"Ranjani Sridharan" <ranjani.sridharan@linux.intel.com>,
cujomalainey@chromium.org,
"Péter Ujfalusi" <peter.ujfalusi@linux.intel.com>,
sound-open-firmware@alsa-project.org
Subject: [PATCH AUTOSEL 5.16 31/52] ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information
Date: Mon, 17 Jan 2022 11:58:32 -0500 [thread overview]
Message-ID: <20220117165853.1470420-31-sashal@kernel.org> (raw)
In-Reply-To: <20220117165853.1470420-1-sashal@kernel.org>
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
[ Upstream commit 288fad2f71fa0b989c075d4984879c26d47cfb06 ]
The code inherited from the Skylake driver does not seem to follow any
known hardware recommendations.
The only two recommended options are
a) use DPIB registers if VC1 traffic is not allowed
b) use DPIB DDR update if VC1 traffic is used
In all of SOF-based updated, VC1 is not supported so we can 'safely'
move to using DPIB registers only.
This patch keeps the legacy code, in case there was an undocumented
issue lost to history, and adds the DPIB DDR update for additional
debug.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20211207193947.71080-6-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/sof/intel/hda-pcm.c | 86 +++++++++++++++++++++++++----------
sound/soc/sof/intel/hda.c | 9 +++-
sound/soc/sof/intel/hda.h | 6 +++
3 files changed, 75 insertions(+), 26 deletions(-)
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index cc8ddef37f37b..41cb60955f5c1 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -172,38 +172,74 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
goto found;
}
- /*
- * DPIB/posbuf position mode:
- * For Playback, Use DPIB register from HDA space which
- * reflects the actual data transferred.
- * For Capture, Use the position buffer for pointer, as DPIB
- * is not accurate enough, its update may be completed
- * earlier than the data written to DDR.
- */
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ switch (sof_hda_position_quirk) {
+ case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
+ /*
+ * This legacy code, inherited from the Skylake driver,
+ * mixes DPIB registers and DPIB DDR updates and
+ * does not seem to follow any known hardware recommendations.
+ * It's not clear e.g. why there is a different flow
+ * for capture and playback, the only information that matters is
+ * what traffic class is used, and on all SOF-enabled platforms
+ * only VC0 is supported so the work-around was likely not necessary
+ * and quite possibly wrong.
+ */
+
+ /* DPIB/posbuf position mode:
+ * For Playback, Use DPIB register from HDA space which
+ * reflects the actual data transferred.
+ * For Capture, Use the position buffer for pointer, as DPIB
+ * is not accurate enough, its update may be completed
+ * earlier than the data written to DDR.
+ */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+ AZX_REG_VS_SDXDPIB_XBASE +
+ (AZX_REG_VS_SDXDPIB_XINTERVAL *
+ hstream->index));
+ } else {
+ /*
+ * For capture stream, we need more workaround to fix the
+ * position incorrect issue:
+ *
+ * 1. Wait at least 20us before reading position buffer after
+ * the interrupt generated(IOC), to make sure position update
+ * happens on frame boundary i.e. 20.833uSec for 48KHz.
+ * 2. Perform a dummy Read to DPIB register to flush DMA
+ * position value.
+ * 3. Read the DMA Position from posbuf. Now the readback
+ * value should be >= period boundary.
+ */
+ usleep_range(20, 21);
+ snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
+ AZX_REG_VS_SDXDPIB_XBASE +
+ (AZX_REG_VS_SDXDPIB_XINTERVAL *
+ hstream->index));
+ pos = snd_hdac_stream_get_pos_posbuf(hstream);
+ }
+ break;
+ case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS:
+ /*
+ * In case VC1 traffic is disabled this is the recommended option
+ */
pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
AZX_REG_VS_SDXDPIB_XBASE +
(AZX_REG_VS_SDXDPIB_XINTERVAL *
hstream->index));
- } else {
+ break;
+ case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
/*
- * For capture stream, we need more workaround to fix the
- * position incorrect issue:
- *
- * 1. Wait at least 20us before reading position buffer after
- * the interrupt generated(IOC), to make sure position update
- * happens on frame boundary i.e. 20.833uSec for 48KHz.
- * 2. Perform a dummy Read to DPIB register to flush DMA
- * position value.
- * 3. Read the DMA Position from posbuf. Now the readback
- * value should be >= period boundary.
+ * This is the recommended option when VC1 is enabled.
+ * While this isn't needed for SOF platforms it's added for
+ * consistency and debug.
*/
- usleep_range(20, 21);
- snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
- AZX_REG_VS_SDXDPIB_XBASE +
- (AZX_REG_VS_SDXDPIB_XINTERVAL *
- hstream->index));
pos = snd_hdac_stream_get_pos_posbuf(hstream);
+ break;
+ default:
+ dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n",
+ sof_hda_position_quirk);
+ pos = 0;
+ break;
}
if (pos >= hstream->bufsize)
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 2c0d4d06ab364..25200a0e1dc9d 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -440,6 +440,10 @@ MODULE_PARM_DESC(use_msi, "SOF HDA use PCI MSI mode");
#define hda_use_msi (1)
#endif
+int sof_hda_position_quirk = SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS;
+module_param_named(position_quirk, sof_hda_position_quirk, int, 0444);
+MODULE_PARM_DESC(position_quirk, "SOF HDaudio position quirk");
+
static char *hda_model;
module_param(hda_model, charp, 0444);
MODULE_PARM_DESC(hda_model, "Use the given HDA board model.");
@@ -618,7 +622,10 @@ static int hda_init(struct snd_sof_dev *sdev)
/* HDA bus init */
sof_hda_bus_init(bus, &pci->dev);
- bus->use_posbuf = 1;
+ if (sof_hda_position_quirk == SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS)
+ bus->use_posbuf = 0;
+ else
+ bus->use_posbuf = 1;
bus->bdl_pos_adj = 0;
bus->sync_write = 1;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 1195018a1f4f5..dba4733ccf9ae 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -738,4 +738,10 @@ struct sof_ipc_dai_config;
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w);
int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w);
+#define SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY (0) /* previous implementation */
+#define SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS (1) /* recommended if VC0 only */
+#define SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE (2) /* recommended with VC0 or VC1 */
+
+extern int sof_hda_position_quirk;
+
#endif
--
2.34.1
next prev parent reply other threads:[~2022-01-17 17:01 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20220117165853.1470420-1-sashal@kernel.org>
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 08/52] ASoC: imx-hdmi: add put_device() after of_find_device_by_node() Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 20/52] ASoC: test-component: fix null pointer dereference Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 25/52] ALSA: seq: Set upper limit of processed events Sasha Levin
2022-01-17 16:58 ` Sasha Levin [this message]
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 38/52] ASoC: SOF: ipc: Add null pointer check for substream->runtime Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 43/52] ASoC: mediatek: mt8192-mt6359: fix device_node leak Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 45/52] ASoC: mediatek: mt8173: " Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 46/52] ASoC: mediatek: mt8183: " Sasha Levin
2022-01-17 16:58 ` [PATCH AUTOSEL 5.16 50/52] ASoC: amd: acp: acp-mach: Change default RT1019 amp dev id Sasha Levin
2022-01-18 16:18 ` Mark Brown
2022-01-22 18:43 ` Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220117165853.1470420-31-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=alsa-devel@alsa-project.org \
--cc=broonie@kernel.org \
--cc=cujomalainey@chromium.org \
--cc=daniel.baluta@nxp.com \
--cc=guennadi.liakhovetski@linux.intel.com \
--cc=kai.vehmanen@linux.intel.com \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=peter.ujfalusi@linux.intel.com \
--cc=pierre-louis.bossart@linux.intel.com \
--cc=ranjani.sridharan@linux.intel.com \
--cc=sound-open-firmware@alsa-project.org \
--cc=stable@vger.kernel.org \
--cc=tiwai@suse.com \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox