diff options
author | Takashi Iwai <tiwai@suse.de> | 2022-12-22 09:11:48 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-12-22 09:11:48 +0100 |
commit | 2d78eb0342dd2c9c5cde9ae9ada1d33f189a858b (patch) | |
tree | f711bc9cab45f4963e4883ef15ff4c54a6cbc12e /sound/soc/sof/intel/hda.c | |
parent | b47068b4aa53a57552398e3f60d0ed1918700c2b (diff) | |
parent | ee0b089d660021792e4ab4dda191b097ce1e964f (diff) |
Merge branch 'for-next' into for-linus
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 |