diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-13 11:27:26 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-13 11:27:26 -0800 |
commit | 102f9d3d455870844c47b82322c2dfc0a35eb745 (patch) | |
tree | 31e2c500794f0827d1319fa28c71a0616c598971 /sound/soc/sof/intel/hda.c | |
parent | 8715c6d3100fc7c6edddf29af4a399a1c12d028c (diff) | |
parent | 8ec2d95f50c06f5cf2a2b94bcdf47f494f91ad55 (diff) | |
download | lwn-102f9d3d455870844c47b82322c2dfc0a35eb745.tar.gz lwn-102f9d3d455870844c47b82322c2dfc0a35eb745.zip |
Merge tag 'sound-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"This looks like a relatively calm development cycle; there have been
only few changes in ALSA and ASoC core sides while we get lots of
device-specific fixes and updates as usual. Most of commits are about
ASoC, including Intel SOF/AVS and many device tree updates.
Below are some highlights:
Core:
- Improvement in memalloc helper for fallback allocations
- More cleanups of ASoC DAPM code
ASoC:
- Factoring out of mapping hw_params onto SoundWire configuration
- The ever ongoing overhauls of the Intel DSP code continue,
including support for loading libraries and probes with IPC4 on
SOF.
- Support for more sample formats on JZ4740
- Lots of device tree conversions and fixups
- Support for Allwinner D1, a range of AMD and Intel systems,
Mediatek systems with multiple DMICs, Nuvoton NAU8318, NXP
fsl_rpmsg and i.MX93, Qualcomm AudioReach Enable, MFC and SAL,
RealTek RT1318 and Rockchip RK3588
ALSA:
- Addition of PCM kselftest; still minimalistic but can be extended
in future
- Fixes for corner-case XRUNs with USB-audio implicit feedback mode
- Usual device-specific quirk updates for USB- and HD-audio
- FireWire DICE updates
This also contains a few cross-tree updates:
- Some OMAP board file updates for removal of relevant OMAP platforms
- A new I2C API update for I2C probe API adaption
- A DRM update for the further hdmi-codec updates"
* tag 'sound-6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (417 commits)
ALSA: mts64: fix possible null-ptr-defer in snd_mts64_interrupt
ALSA: patch_realtek: Fix Dell Inspiron Plus 16
ALSA: hda/cirrus: Add extra 10 ms delay to allow PLL settle and lock.
ASoC: dt-bindings: Correct Alexandre Belloni email
ASoC: dt-bindings: maxim,max98504: Convert to DT schema
ASoC: dt-bindings: maxim,max98357a: Convert to DT schema
ASoC: dt-bindings: Reference common DAI properties
ASoC: dt-bindings: Extend name-prefix.yaml into common DAI properties
ASoC: rt715: Make read-only arrays capture_reg_H and capture_reg_L static const
ASoC: uniphier: aio-core: Make some read-only arrays static const
ASoC: wcd938x: Make read-only array minCode_param static const
ASoC: qcom: lpass-sc7280: Add maybe_unused tag for system PM ops
ASoC : SOF: amd: Add support for IPC and DSP dumps
ASoC: SOF: amd: Use poll function instead to read ACP_SHA_DSP_FW_QUALIFIER
ALSA: usb-audio: Workaround for XRUN at prepare
ALSA: pcm: Handle XRUN at trigger START
ALSA: pcm: Set missing stop_operating flag at undoing trigger start
drm: tda99x: Don't advertise non-existent capture support
ASoC: hdmi-codec: Allow playback and capture to be disabled
kselftest/alsa: Add more coverage of sample rates and channel counts
...
Diffstat (limited to 'sound/soc/sof/intel/hda.c')
-rw-r--r-- | sound/soc/sof/intel/hda.c | 139 |
1 files changed, 86 insertions, 53 deletions
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 1188ec51816b..14a2f8701350 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -155,9 +155,27 @@ struct sdw_intel_ops sdw_callback = { .free_stream = sdw_free_stream, }; +void hda_common_enable_sdw_irq(struct snd_sof_dev *sdev, bool enable) +{ + struct sof_intel_hda_dev *hdev; + + hdev = sdev->pdata->hw_pdata; + + if (!hdev->sdw) + return; + + snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC2, + HDA_DSP_REG_ADSPIC2_SNDW, + enable ? HDA_DSP_REG_ADSPIC2_SNDW : 0); +} + void hda_sdw_int_enable(struct snd_sof_dev *sdev, bool enable) { - sdw_intel_enable_irq(sdev->bar[HDA_DSP_BAR], enable); + const struct sof_intel_dsp_desc *chip; + + chip = get_chip_info(sdev->pdata); + if (chip && chip->enable_sdw_irq) + chip->enable_sdw_irq(sdev, enable); } static int hda_sdw_acpi_scan(struct snd_sof_dev *sdev) @@ -220,10 +238,45 @@ static int hda_sdw_probe(struct snd_sof_dev *sdev) return 0; } +int hda_sdw_check_lcount_common(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hdev; + struct sdw_intel_ctx *ctx; + u32 caps; + + hdev = sdev->pdata->hw_pdata; + ctx = hdev->sdw; + + caps = snd_sof_dsp_read(sdev, HDA_DSP_BAR, ctx->shim_base + SDW_SHIM_LCAP); + caps &= SDW_SHIM_LCAP_LCOUNT_MASK; + + /* Check HW supported vs property value */ + if (caps < ctx->count) { + dev_err(sdev->dev, + "BIOS master count %d is larger than hardware capabilities %d\n", + ctx->count, caps); + return -EINVAL; + } + + return 0; +} + +static int hda_sdw_check_lcount(struct snd_sof_dev *sdev) +{ + const struct sof_intel_dsp_desc *chip; + + chip = get_chip_info(sdev->pdata); + if (chip && chip->read_sdw_lcount) + return chip->read_sdw_lcount(sdev); + + return 0; +} + int hda_sdw_startup(struct snd_sof_dev *sdev) { struct sof_intel_hda_dev *hdev; struct snd_sof_pdata *pdata = sdev->pdata; + int ret; hdev = sdev->pdata->hw_pdata; @@ -233,6 +286,10 @@ int hda_sdw_startup(struct snd_sof_dev *sdev) if (pdata->machine && !pdata->machine->mach_params.link_mask) return 0; + ret = hda_sdw_check_lcount(sdev); + if (ret < 0) + return ret; + return sdw_intel_startup(hdev->sdw); } @@ -383,12 +440,6 @@ static int mclk_id_override = -1; module_param_named(mclk_id, mclk_id_override, int, 0444); MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id"); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) -static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI); -module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); -MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); -#endif - static const struct hda_dsp_msg_code hda_dsp_rom_fw_error_texts[] = { {HDA_DSP_ROM_CSE_ERROR, "error: cse error"}, {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"}, @@ -625,7 +676,6 @@ static bool hda_check_ipc_irq(struct snd_sof_dev *sdev) void hda_ipc_irq_dump(struct snd_sof_dev *sdev) { - struct hdac_bus *bus = sof_to_bus(sdev); u32 adspis; u32 intsts; u32 intctl; @@ -637,7 +687,7 @@ void hda_ipc_irq_dump(struct snd_sof_dev *sdev) intsts = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS); intctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL); ppsts = snd_sof_dsp_read(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPSTS); - rirbsts = snd_hdac_chip_readb(bus, RIRBSTS); + rirbsts = snd_sof_dsp_read8(sdev, HDA_DSP_HDA_BAR, AZX_REG_RIRBSTS); dev_err(sdev->dev, "hda irq intsts 0x%8.8x intlctl 0x%8.8x rirb %2.2x\n", intsts, intctl, rirbsts); @@ -681,6 +731,17 @@ void hda_ipc4_dump(struct snd_sof_dev *sdev) hipci, hipcie, hipct, hipcte, hipcctl); } +bool hda_ipc4_tx_is_busy(struct snd_sof_dev *sdev) +{ + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; + u32 val; + + val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, chip->ipc_req); + + return !!(val & chip->ipc_req_mask); +} + static int hda_init(struct snd_sof_dev *sdev) { struct hda_bus *hbus; @@ -692,7 +753,7 @@ static int hda_init(struct snd_sof_dev *sdev) bus = sof_to_bus(sdev); /* HDA bus init */ - sof_hda_bus_init(bus, &pci->dev); + sof_hda_bus_init(sdev, &pci->dev); if (sof_hda_position_quirk == SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS) bus->use_posbuf = 0; @@ -787,7 +848,7 @@ static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num) return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *sof_tplg_filename, @@ -867,9 +928,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); struct snd_sof_pdata *pdata = sdev->pdata; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_ext_link *hlink; -#endif struct sof_intel_hda_dev *hdev = pdata->hw_pdata; u32 link_mask; int ret = 0; @@ -879,13 +937,15 @@ static int hda_init_caps(struct snd_sof_dev *sdev) dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n"); /* Init HDA controller after i915 init */ - ret = hda_dsp_ctrl_init_chip(sdev, true); + ret = hda_dsp_ctrl_init_chip(sdev); if (ret < 0) { dev_err(bus->dev, "error: init chip failed with ret: %d\n", ret); return ret; } + hda_bus_ml_get_capabilities(bus); + /* scan SoundWire capabilities exposed by DSDT */ ret = hda_sdw_acpi_scan(sdev); if (ret < 0) { @@ -914,37 +974,15 @@ static int hda_init_caps(struct snd_sof_dev *sdev) skip_soundwire: -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - if (bus->mlcap) - snd_hdac_ext_bus_get_ml_capabilities(bus); - /* create codec instances */ - hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi); + hda_codec_probe_bus(sdev); if (!HDA_IDISP_CODEC(bus->codec_mask)) hda_codec_i915_display_power(sdev, false); - /* - * we are done probing so decrement link counts - */ - list_for_each_entry(hlink, &bus->hlink_list, list) - snd_hdac_ext_bus_link_put(bus, hlink); -#endif - return 0; -} + hda_bus_ml_put_all(bus); -static void hda_check_for_state_change(struct snd_sof_dev *sdev) -{ -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_bus *bus = sof_to_bus(sdev); - unsigned int codec_mask; - - codec_mask = snd_hdac_chip_readw(bus, STATESTS); - if (codec_mask) { - hda_codec_jack_check(sdev); - snd_hdac_chip_writew(bus, STATESTS, codec_mask); - } -#endif + return 0; } static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context) @@ -996,7 +1034,7 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) hda_sdw_process_wakeen(sdev); } - hda_check_for_state_change(sdev); + hda_codec_check_for_state_change(sdev); /* enable GIE interrupt */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, @@ -1192,10 +1230,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) /* cancel any attempt for DSP D0I3 */ cancel_delayed_work_sync(&hda->d0i3_work); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* codec removal, invoke bus_device_remove */ - snd_hdac_ext_bus_device_remove(bus); -#endif + hda_codec_device_remove(sdev); hda_sdw_exit(sdev); @@ -1223,16 +1258,14 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) pci_free_irq_vectors(pci); hda_dsp_stream_free(sdev); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_link_free_all(bus); -#endif + + hda_bus_ml_free(sof_to_bus(sdev)); iounmap(sdev->bar[HDA_DSP_BAR]); iounmap(bus->remap_addr); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_ext_bus_exit(bus); -#endif + sof_hda_bus_exit(sdev); + hda_codec_i915_exit(sdev); return 0; @@ -1246,7 +1279,7 @@ int hda_power_down_dsp(struct snd_sof_dev *sdev) return hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) static void hda_generic_machine_select(struct snd_sof_dev *sdev, struct snd_soc_acpi_mach **mach) { @@ -1325,7 +1358,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, if (*mach) { mach_params = &(*mach)->mach_params; mach_params->codec_mask = bus->codec_mask; - mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi; + mach_params->common_hdmi_codec_drv = true; } } #else |