mirror of
https://github.com/torvalds/linux
synced 2024-09-06 18:01:05 +00:00
ALSA: hda: Poll SDxFIFOS after programming SDxFMT
Software shall read SDxFIFOS calculated by the hardware and notify if invalid value is programmed before continuing the stream preparation. Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com> Link: https://lore.kernel.org/r/20230926080623.43927-2-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
c258bcc289
commit
2ee2c75c58
|
@ -91,6 +91,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
|
|||
#define AZX_REG_SD_BDLPL 0x18
|
||||
#define AZX_REG_SD_BDLPU 0x1c
|
||||
|
||||
#define AZX_SD_FIFOSIZE_MASK GENMASK(15, 0)
|
||||
|
||||
/* GTS registers */
|
||||
#define AZX_REG_LLCH 0x14
|
||||
|
||||
|
|
|
@ -624,6 +624,9 @@ int snd_hdac_stream_set_lpib(struct hdac_stream *azx_dev, u32 value);
|
|||
#define snd_hdac_stream_readb_poll(dev, reg, val, cond, delay_us, timeout_us) \
|
||||
read_poll_timeout_atomic(snd_hdac_reg_readb, val, cond, delay_us, timeout_us, \
|
||||
false, (dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
|
||||
#define snd_hdac_stream_readw_poll(dev, reg, val, cond, delay_us, timeout_us) \
|
||||
read_poll_timeout_atomic(snd_hdac_reg_readw, val, cond, delay_us, timeout_us, \
|
||||
false, (dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
|
||||
#define snd_hdac_stream_readl_poll(dev, reg, val, cond, delay_us, timeout_us) \
|
||||
read_poll_timeout_atomic(snd_hdac_reg_readl, val, cond, delay_us, timeout_us, \
|
||||
false, (dev)->bus, (dev)->sd_addr + AZX_REG_ ## reg)
|
||||
|
|
|
@ -258,6 +258,8 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev)
|
|||
struct hdac_bus *bus = azx_dev->bus;
|
||||
struct snd_pcm_runtime *runtime;
|
||||
unsigned int val;
|
||||
u16 reg;
|
||||
int ret;
|
||||
|
||||
if (azx_dev->substream)
|
||||
runtime = azx_dev->substream->runtime;
|
||||
|
@ -300,6 +302,12 @@ int snd_hdac_stream_setup(struct hdac_stream *azx_dev)
|
|||
/* set the interrupt enable bits in the descriptor control register */
|
||||
snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_INT_MASK);
|
||||
|
||||
/* Once SDxFMT is set, the controller programs SDxFIFOS to non-zero value. */
|
||||
ret = snd_hdac_stream_readw_poll(azx_dev, SD_FIFOSIZE, reg, reg & AZX_SD_FIFOSIZE_MASK,
|
||||
3, 300);
|
||||
if (ret)
|
||||
dev_dbg(bus->dev, "polling SD_FIFOSIZE 0x%04x failed: %d\n",
|
||||
AZX_REG_SD_FIFOSIZE, ret);
|
||||
azx_dev->fifo_size = snd_hdac_stream_readw(azx_dev, SD_FIFOSIZE) + 1;
|
||||
|
||||
/* when LPIB delay correction gives a small negative value,
|
||||
|
|
Loading…
Reference in a new issue