]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ALSA: hda: Poll SDxFIFOS after programming SDxFMT
authorCezary Rojewski <cezary.rojewski@intel.com>
Tue, 26 Sep 2023 08:06:20 +0000 (10:06 +0200)
committerTakashi Iwai <tiwai@suse.de>
Fri, 6 Oct 2023 09:11:39 +0000 (11:11 +0200)
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>
include/sound/hda_register.h
include/sound/hdaudio.h
sound/hda/hdac_stream.c

index 9c7872c0ca798eb359815e349c12917c0de8ba60..55958711d6974e87ed08155fef3b47da6d53ba7f 100644 (file)
@@ -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
 
index 32c59053b48edca72dcf57cda55b674c3a9dd5e3..41d725babf53dd665e21ce8ad8840bca5c66872f 100644 (file)
@@ -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)
index 2633a4bb1d85db4db48279ca19b0e82cb6b54715..5382894bebabf59c9fd22b8035baf9d5a88cf492 100644 (file)
@@ -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,