diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 10:58:37 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-27 10:58:37 -0700 |
commit | 1c15ca4e4efaddb78f83eed31eeee34c522c3ae2 (patch) | |
tree | a528054028d13fb3361ec72663c7fce7b619564b /sound/soc/sof/intel/hda-stream.c | |
parent | 34b62f186db9614e55d021f8c58d22fc44c57911 (diff) | |
parent | baa6584a24494fbbd2862270d39e61b86987cc91 (diff) |
Merge tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"At this time, it's an interesting mixture of changes for both old and
new stuff. Majority of changes are about ASoC (lots of systematic
changes for converting remove callbacks to void, and cleanups), while
we got the fixes and the enhancements of very old PCI cards, too.
Here are some highlights:
ALSA/ASoC Core:
- Continued effort of more ASoC core cleanups
- Minor improvements for XRUN handling in indirect PCM helpers
- Code refactoring of PCM core code
ASoC:
- Continued feature and simplification work on SOF, including
addition of a no-DSP mode for bringup, HDA MLink and extensions to
the IPC4 protocol
- Hibernation support for CS35L45
- More DT binding conversions
- Support for Cirrus Logic CS35L56, Freescale QMC, Maxim MAX98363,
nVidia systems with MAX9809x and RT5631, Realtek RT712, Renesas
R-Car Gen4, Rockchip RK3588 and TI TAS5733
ALSA:
- Lots of works for legacy emu10k1 and ymfpci PCI drivers
- PCM kselftest fixes and enhancements"
* tag 'sound-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (586 commits)
ALSA: emu10k1: use high-level I/O in set_filterQ()
ALSA: emu10k1: use high-level I/O functions also during init
ALSA: emu10k1: fix error handling in snd_audigy_i2c_volume_put()
ALSA: emu10k1: don't stop DSP in _snd_emu10k1_{,audigy_}init_efx()
ALSA: emu10k1: fix SNDRV_EMU10K1_IOCTL_SINGLE_STEP
ALSA: emu10k1: skip Sound Blaster-specific hacks for E-MU cards
ALSA: emu10k1: fixup DSP defines
ALSA: emu10k1: pull in some register definitions from kX-project
ALSA: emu10k1: remove some bogus defines
ALSA: emu10k1: eliminate some unused defines
ALSA: emu10k1: fix lineup of EMU_HANA_* defines
ALSA: emu10k1: comment updates
ALSA: emu10k1: fix snd_emu1010_fpga_read() input masking for rev2 cards
ALSA: emu10k1: remove unused emu->pcm_playback_efx_substream field
ALSA: emu10k1: remove unused `resume` parameter from snd_emu10k1_init()
ALSA: emu10k1: minor optimizations
ALSA: emu10k1: remove remaining cruft from snd_emu10k1_emu1010_init()
ALSA: emu10k1: remove apparently pointless EMU_HANA_OPTION_CARDS reads
ALSA: emu10k1: remove apparently pointless FPGA reads
ALSA: emu10k1: stop doing weird things with HCFG in snd_emu10k1_emu1010_init()
...
Diffstat (limited to 'sound/soc/sof/intel/hda-stream.c')
-rw-r--r-- | sound/soc/sof/intel/hda-stream.c | 93 |
1 files changed, 59 insertions, 34 deletions
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index 7f0fd05a96e6..8de422604ad5 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -182,6 +182,8 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev, struct hdac_ext_stream * hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) { + const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata); + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct hdac_bus *bus = sof_to_bus(sdev); struct sof_intel_hda_stream *hda_stream; struct hdac_ext_stream *hext_stream = NULL; @@ -220,12 +222,15 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) /* * Prevent DMI Link L1 entry for streams that don't support it. * Workaround to address a known issue with host DMA that results - * in xruns during pause/release in capture scenarios. + * in xruns during pause/release in capture scenarios. This is not needed for the ACE IP. */ - if (!(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) + if (chip_info->hw_ip_version < SOF_INTEL_ACE_1_0 && + !(flags & SOF_HDA_STREAM_DMI_L1_COMPATIBLE)) { snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, HDA_VS_INTEL_EM2_L1SEN, 0); + hda->l1_disabled = true; + } return hext_stream; } @@ -233,6 +238,8 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags) /* free a stream */ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) { + const struct sof_intel_dsp_desc *chip_info = get_chip_info(sdev->pdata); + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct hdac_bus *bus = sof_to_bus(sdev); struct sof_intel_hda_stream *hda_stream; struct hdac_ext_stream *hext_stream; @@ -264,9 +271,11 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag) spin_unlock_irq(&bus->reg_lock); /* Enable DMI L1 if permitted */ - if (dmi_l1_enable) + if (chip_info->hw_ip_version < SOF_INTEL_ACE_1_0 && dmi_l1_enable) { snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2, HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); + hda->l1_disabled = false; + } if (!found) { dev_err(sdev->dev, "%s: stream_tag %d not opened!\n", @@ -328,7 +337,13 @@ int hda_dsp_stream_trigger(struct snd_sof_dev *sdev, /* cmd must be for audio stream */ switch (cmd) { case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!sdev->dspless_mode_selected) + break; + fallthrough; case SNDRV_PCM_TRIGGER_START: + if (hstream->running) + break; + snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, 1 << hstream->index, 1 << hstream->index); @@ -351,8 +366,11 @@ int hda_dsp_stream_trigger(struct snd_sof_dev *sdev, hstream->running = true; break; - case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (!sdev->dspless_mode_selected) + break; + fallthrough; + case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, @@ -476,9 +494,8 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, { const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata); struct hdac_bus *bus = sof_to_bus(sdev); - struct hdac_stream *hstream = &hext_stream->hstream; - int sd_offset = SOF_STREAM_SD_OFFSET(hstream); - int ret; + struct hdac_stream *hstream; + int sd_offset, ret; u32 dma_start = SOF_HDA_SD_CTL_DMA_START; u32 mask; u32 run; @@ -493,10 +510,14 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, return -ENODEV; } - /* decouple host and link DMA */ - mask = 0x1 << hstream->index; - snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, - mask, mask); + hstream = &hext_stream->hstream; + sd_offset = SOF_STREAM_SD_OFFSET(hstream); + mask = BIT(hstream->index); + + /* decouple host and link DMA if the DSP is used */ + if (!sdev->dspless_mode_selected) + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, + mask, mask); /* clear stream status */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, @@ -597,11 +618,10 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, * enable decoupled mode */ - if (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK) { + if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) /* couple host and link DMA, disable DSP features */ snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, mask, 0); - } /* program stream format */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, @@ -609,11 +629,10 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev, SOF_HDA_ADSP_REG_SD_FORMAT, 0xffff, hstream->format_val); - if (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK) { + if (!sdev->dspless_mode_selected && (chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) /* decouple host and link DMA, enable DSP features */ snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, mask, mask); - } /* program last valid index */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, @@ -666,20 +685,23 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream = container_of(hstream, struct hdac_ext_stream, hstream); - struct hdac_bus *bus = sof_to_bus(sdev); - u32 mask = 0x1 << hstream->index; int ret; ret = hda_dsp_stream_reset(sdev, hstream); if (ret < 0) return ret; - spin_lock_irq(&bus->reg_lock); - /* couple host and link DMA if link DMA channel is idle */ - if (!hext_stream->link_locked) - snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, - SOF_HDA_REG_PP_PPCTL, mask, 0); - spin_unlock_irq(&bus->reg_lock); + if (!sdev->dspless_mode_selected) { + struct hdac_bus *bus = sof_to_bus(sdev); + u32 mask = BIT(hstream->index); + + spin_lock_irq(&bus->reg_lock); + /* couple host and link DMA if link DMA channel is idle */ + if (!hext_stream->link_locked) + snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, + SOF_HDA_REG_PP_PPCTL, mask, 0); + spin_unlock_irq(&bus->reg_lock); + } hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0); @@ -861,12 +883,14 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) hext_stream = &hda_stream->hext_stream; - hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + - SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; + if (sdev->bar[HDA_DSP_PP_BAR]) { + hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + + SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; - hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + - SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + - SOF_HDA_PPLC_INTERVAL * i; + hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + + SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + + SOF_HDA_PPLC_INTERVAL * i; + } hstream = &hext_stream->hstream; @@ -917,13 +941,14 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) hext_stream = &hda_stream->hext_stream; - /* we always have DSP support */ - hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + - SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; + if (sdev->bar[HDA_DSP_PP_BAR]) { + hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] + + SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i; - hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + - SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + - SOF_HDA_PPLC_INTERVAL * i; + hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] + + SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total + + SOF_HDA_PPLC_INTERVAL * i; + } hstream = &hext_stream->hstream; |