diff options
author | Takashi Iwai <tiwai@suse.de> | 2024-03-11 16:18:47 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2024-03-11 16:18:47 +0100 |
commit | f5d9ddf1214bf878ca69c905c2f410c5b51de99c (patch) | |
tree | 3ea7bf6f519a490f72cf5f9023b5c0a6dff0fea0 /sound/soc/sof/intel/hda.c | |
parent | 6719cd5e45111449f4021e08f2e488f17a9b292b (diff) | |
parent | 6c023ad32b192dea51a4f842cc6ecf89bb6238c9 (diff) |
Merge tag 'asoc-v6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v6.9
This has been quite a small release, there's a lot of driver specific
cleanups and minor enhancements but hardly anything on the core and only
one new driver. Highlights include:
- SoundWire support for AMD ACP 6.3 systems.
- Support for reporting version information for AVS firmware.
- Support DSPless mode for Intel Soundwire systems.
- Support for configuring CS35L56 amplifiers using EFI calibration
data.
- Log which component is being operated on as part of power management
trace events.
- Support for Microchip SAM9x7, NXP i.MX95 and Qualcomm WCD939x
Diffstat (limited to 'sound/soc/sof/intel/hda.c')
-rw-r--r-- | sound/soc/sof/intel/hda.c | 80 |
1 files changed, 68 insertions, 12 deletions
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index fe4ae349dad5..7fe72b065451 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -46,44 +46,83 @@ #define EXCEPT_MAX_HDR_SIZE 0x400 #define HDA_EXT_ROM_STATUS_SIZE 8 -static u32 hda_get_interface_mask(struct snd_sof_dev *sdev) +static void hda_get_interfaces(struct snd_sof_dev *sdev, u32 *interface_mask) { const struct sof_intel_dsp_desc *chip; - u32 interface_mask[2] = { 0 }; chip = get_chip_info(sdev->pdata); switch (chip->hw_ip_version) { case SOF_INTEL_TANGIER: case SOF_INTEL_BAYTRAIL: case SOF_INTEL_BROADWELL: - interface_mask[0] = BIT(SOF_DAI_INTEL_SSP); + interface_mask[SOF_DAI_DSP_ACCESS] = BIT(SOF_DAI_INTEL_SSP); break; case SOF_INTEL_CAVS_1_5: case SOF_INTEL_CAVS_1_5_PLUS: - interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | - BIT(SOF_DAI_INTEL_HDA); - interface_mask[1] = BIT(SOF_DAI_INTEL_HDA); + interface_mask[SOF_DAI_DSP_ACCESS] = + BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | BIT(SOF_DAI_INTEL_HDA); + interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA); break; case SOF_INTEL_CAVS_1_8: case SOF_INTEL_CAVS_2_0: case SOF_INTEL_CAVS_2_5: case SOF_INTEL_ACE_1_0: - interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | - BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH); - interface_mask[1] = BIT(SOF_DAI_INTEL_HDA); + interface_mask[SOF_DAI_DSP_ACCESS] = + BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | + BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH); + interface_mask[SOF_DAI_HOST_ACCESS] = BIT(SOF_DAI_INTEL_HDA); break; case SOF_INTEL_ACE_2_0: - interface_mask[0] = BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | - BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH); - interface_mask[1] = interface_mask[0]; /* all interfaces accessible without DSP */ + interface_mask[SOF_DAI_DSP_ACCESS] = + BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC) | + BIT(SOF_DAI_INTEL_HDA) | BIT(SOF_DAI_INTEL_ALH); + /* all interfaces accessible without DSP */ + interface_mask[SOF_DAI_HOST_ACCESS] = + interface_mask[SOF_DAI_DSP_ACCESS]; break; default: break; } +} + +static u32 hda_get_interface_mask(struct snd_sof_dev *sdev) +{ + u32 interface_mask[SOF_DAI_ACCESS_NUM] = { 0 }; + + hda_get_interfaces(sdev, interface_mask); return interface_mask[sdev->dspless_mode_selected]; } +bool hda_is_chain_dma_supported(struct snd_sof_dev *sdev, u32 dai_type) +{ + u32 interface_mask[SOF_DAI_ACCESS_NUM] = { 0 }; + const struct sof_intel_dsp_desc *chip; + + if (sdev->dspless_mode_selected) + return false; + + hda_get_interfaces(sdev, interface_mask); + + if (!(interface_mask[SOF_DAI_DSP_ACCESS] & BIT(dai_type))) + return false; + + if (dai_type == SOF_DAI_INTEL_HDA) + return true; + + switch (dai_type) { + case SOF_DAI_INTEL_SSP: + case SOF_DAI_INTEL_DMIC: + case SOF_DAI_INTEL_ALH: + chip = get_chip_info(sdev->pdata); + if (chip->hw_ip_version < SOF_INTEL_ACE_2_0) + return false; + return true; + default: + return false; + } +} + #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) /* @@ -1192,6 +1231,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) { struct pci_dev *pci = to_pci_dev(sdev->dev); struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip; int ret = 0; hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", @@ -1305,12 +1345,28 @@ skip_dsp_setup: INIT_DELAYED_WORK(&hdev->d0i3_work, hda_dsp_d0i3_work); } + chip = get_chip_info(sdev->pdata); + if (chip && chip->hw_ip_version >= SOF_INTEL_ACE_2_0) { + ret = hda_sdw_startup(sdev); + if (ret < 0) { + dev_err(sdev->dev, "could not startup SoundWire links\n"); + goto disable_pp_cap; + } + + hda_sdw_int_enable(sdev, true); + } + init_waitqueue_head(&hdev->waitq); hdev->nhlt = intel_nhlt_init(sdev->dev); return 0; +disable_pp_cap: + if (!sdev->dspless_mode_selected) { + hda_dsp_ctrl_ppcap_int_enable(sdev, false); + hda_dsp_ctrl_ppcap_enable(sdev, false); + } free_ipc_irq: free_irq(sdev->ipc_irq, sdev); free_irq_vector: |