Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: hda: Add code_loading parameter to stream setup

AudioDSP firmware is the one who kicks SDxFIFOS calculation when a
stream is decoupled mode. During firmware bring up procedure, there is
no firmware running and the code-loading stream is always a decoupled
one. So, there is none to trigger the calculation and we end up with
false-positive timeout (-110) messages.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20231006102857.749143-4-cezary.rojewski@intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Cezary Rojewski and committed by
Takashi Iwai
5eb4ff88 956b610c

+26 -21
+1 -1
include/sound/hdaudio.h
··· 573 573 struct hdac_stream *snd_hdac_get_stream(struct hdac_bus *bus, 574 574 int dir, int stream_tag); 575 575 576 - int snd_hdac_stream_setup(struct hdac_stream *azx_dev); 576 + int snd_hdac_stream_setup(struct hdac_stream *azx_dev, bool code_loading); 577 577 void snd_hdac_stream_cleanup(struct hdac_stream *azx_dev); 578 578 int snd_hdac_stream_setup_periods(struct hdac_stream *azx_dev); 579 579 int snd_hdac_stream_set_params(struct hdac_stream *azx_dev,
+2 -2
include/sound/hdaudio_ext.h
··· 60 60 bool link_locked:1; 61 61 bool link_prepared; 62 62 63 - int (*host_setup)(struct hdac_stream *); 63 + int (*host_setup)(struct hdac_stream *, bool); 64 64 65 65 struct snd_pcm_substream *link_substream; 66 66 }; ··· 88 88 void snd_hdac_ext_stream_clear(struct hdac_ext_stream *hext_stream); 89 89 void snd_hdac_ext_stream_reset(struct hdac_ext_stream *hext_stream); 90 90 int snd_hdac_ext_stream_setup(struct hdac_ext_stream *hext_stream, int fmt); 91 - int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream); 91 + int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream, bool code_loading); 92 92 93 93 struct hdac_ext_link { 94 94 struct hdac_bus *bus;
+7 -5
sound/hda/ext/hdac_ext_stream.c
··· 21 21 /** 22 22 * snd_hdac_ext_host_stream_setup - Setup a HOST stream. 23 23 * @hext_stream: HDAudio stream to set up. 24 + * @code_loading: Whether the stream is for PCM or code-loading. 24 25 * 25 26 * Return: Zero on success or negative error code. 26 27 */ 27 - int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream) 28 + int snd_hdac_ext_host_stream_setup(struct hdac_ext_stream *hext_stream, bool code_loading) 28 29 { 29 - return hext_stream->host_setup(hdac_stream(hext_stream)); 30 + return hext_stream->host_setup(hdac_stream(hext_stream), code_loading); 30 31 } 31 32 EXPORT_SYMBOL_GPL(snd_hdac_ext_host_stream_setup); 32 33 ··· 35 34 * snd_hdac_apl_host_stream_setup - Setup a HOST stream following procedure 36 35 * recommended for ApolloLake devices. 37 36 * @hstream: HDAudio stream to set up. 37 + * @code_loading: Whether the stream is for PCM or code-loading. 38 38 * 39 39 * Return: Zero on success or negative error code. 40 40 */ 41 - static int snd_hdac_apl_host_stream_setup(struct hdac_stream *hstream) 41 + static int snd_hdac_apl_host_stream_setup(struct hdac_stream *hstream, bool code_loading) 42 42 { 43 43 struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream); 44 44 int ret; 45 45 46 46 snd_hdac_ext_stream_decouple(hstream->bus, hext_stream, false); 47 - ret = snd_hdac_stream_setup(hstream); 47 + ret = snd_hdac_stream_setup(hstream, code_loading); 48 48 snd_hdac_ext_stream_decouple(hstream->bus, hext_stream, true); 49 49 50 50 return ret; ··· 91 89 int num_stream, int dir) 92 90 { 93 91 struct pci_dev *pci = to_pci_dev(bus->dev); 94 - int (*setup_op)(struct hdac_stream *); 92 + int (*setup_op)(struct hdac_stream *, bool); 95 93 int stream_tag = 0; 96 94 int i, tag, idx = start_idx; 97 95
+12 -9
sound/hda/hdac_stream.c
··· 252 252 /** 253 253 * snd_hdac_stream_setup - set up the SD for streaming 254 254 * @azx_dev: HD-audio core stream to set up 255 + * @code_loading: Whether the stream is for PCM or code-loading. 255 256 */ 256 - int snd_hdac_stream_setup(struct hdac_stream *azx_dev) 257 + int snd_hdac_stream_setup(struct hdac_stream *azx_dev, bool code_loading) 257 258 { 258 259 struct hdac_bus *bus = azx_dev->bus; 259 260 struct snd_pcm_runtime *runtime; ··· 303 302 /* set the interrupt enable bits in the descriptor control register */ 304 303 snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_INT_MASK); 305 304 306 - /* Once SDxFMT is set, the controller programs SDxFIFOS to non-zero value. */ 307 - ret = snd_hdac_stream_readw_poll(azx_dev, SD_FIFOSIZE, reg, reg & AZX_SD_FIFOSIZE_MASK, 308 - 3, 300); 309 - if (ret) 310 - dev_dbg(bus->dev, "polling SD_FIFOSIZE 0x%04x failed: %d\n", 311 - AZX_REG_SD_FIFOSIZE, ret); 312 - azx_dev->fifo_size = snd_hdac_stream_readw(azx_dev, SD_FIFOSIZE); 305 + if (!code_loading) { 306 + /* Once SDxFMT is set, the controller programs SDxFIFOS to non-zero value. */ 307 + ret = snd_hdac_stream_readw_poll(azx_dev, SD_FIFOSIZE, reg, 308 + reg & AZX_SD_FIFOSIZE_MASK, 3, 300); 309 + if (ret) 310 + dev_dbg(bus->dev, "polling SD_FIFOSIZE 0x%04x failed: %d\n", 311 + AZX_REG_SD_FIFOSIZE, ret); 312 + azx_dev->fifo_size = reg; 313 + } 313 314 314 315 /* when LPIB delay correction gives a small negative value, 315 316 * we ignore it; currently set the threshold statically to ··· 956 953 if (err < 0) 957 954 goto error; 958 955 959 - snd_hdac_stream_setup(azx_dev); 956 + snd_hdac_stream_setup(azx_dev, true); 960 957 snd_hdac_dsp_unlock(azx_dev); 961 958 return azx_dev->stream_tag; 962 959
+1 -1
sound/pci/hda/hda_controller.c
··· 182 182 if (err < 0) 183 183 goto unlock; 184 184 185 - snd_hdac_stream_setup(azx_stream(azx_dev)); 185 + snd_hdac_stream_setup(azx_stream(azx_dev), false); 186 186 187 187 stream_tag = azx_dev->core.stream_tag; 188 188 /* CA-IBG chips need the playback stream starting from 1 */
+1 -1
sound/soc/intel/avs/pcm.c
··· 625 625 if (ret < 0) 626 626 return ret; 627 627 628 - ret = snd_hdac_ext_host_stream_setup(host_stream); 628 + ret = snd_hdac_ext_host_stream_setup(host_stream, false); 629 629 if (ret < 0) 630 630 return ret; 631 631
+1 -1
sound/soc/intel/avs/probes.c
··· 145 145 ret = snd_hdac_stream_set_params(hdac_stream(host_stream), format_val); 146 146 if (ret < 0) 147 147 return ret; 148 - ret = snd_hdac_stream_setup(hdac_stream(host_stream)); 148 + ret = snd_hdac_stream_setup(hdac_stream(host_stream), false); 149 149 if (ret < 0) 150 150 return ret; 151 151
+1 -1
sound/soc/intel/skylake/skl-pcm.c
··· 148 148 if (err < 0) 149 149 return err; 150 150 151 - err = snd_hdac_ext_host_stream_setup(stream); 151 + err = snd_hdac_ext_host_stream_setup(stream, false); 152 152 if (err < 0) 153 153 return err; 154 154