ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information
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>
This commit is contained in:
Родитель
ae81d8fd57
Коммит
288fad2f71
|
@ -202,8 +202,20 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
|
|||
goto found;
|
||||
}
|
||||
|
||||
switch (sof_hda_position_quirk) {
|
||||
case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY:
|
||||
/*
|
||||
* DPIB/posbuf position mode:
|
||||
* 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
|
||||
|
@ -235,6 +247,30 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
|
|||
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));
|
||||
break;
|
||||
case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE:
|
||||
/*
|
||||
* This is the recommended option when VC1 is enabled.
|
||||
* While this isn't needed for SOF platforms it's added for
|
||||
* consistency and debug.
|
||||
*/
|
||||
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)
|
||||
pos = 0;
|
||||
|
|
|
@ -432,6 +432,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.");
|
||||
|
@ -610,6 +614,9 @@ static int hda_init(struct snd_sof_dev *sdev)
|
|||
/* HDA bus init */
|
||||
sof_hda_bus_init(bus, &pci->dev);
|
||||
|
||||
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;
|
||||
|
|
|
@ -740,4 +740,10 @@ struct sof_ipc_dai_config;
|
|||
int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
|
||||
int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
|
||||
|
||||
#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
|
||||
|
|
Загрузка…
Ссылка в новой задаче