diff --git a/sound/hda/ext/hdac_ext_controller.c b/sound/hda/ext/hdac_ext_controller.c index a684f0520b4b98..4d060d5b1db6dc 100644 --- a/sound/hda/ext/hdac_ext_controller.c +++ b/sound/hda/ext/hdac_ext_controller.c @@ -254,6 +254,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_link_power_down_all); int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, struct hdac_ext_link *link) { + unsigned long codec_mask; int ret = 0; mutex_lock(&bus->lock); @@ -280,9 +281,11 @@ int snd_hdac_ext_bus_link_get(struct hdac_bus *bus, * HDA spec section 4.3 - Codec Discovery */ udelay(521); - bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS); - dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask); - snd_hdac_chip_writew(bus, STATESTS, bus->codec_mask); + codec_mask = snd_hdac_chip_readw(bus, STATESTS); + dev_dbg(bus->dev, "codec_mask = 0x%lx\n", codec_mask); + snd_hdac_chip_writew(bus, STATESTS, codec_mask); + if (!bus->codec_mask) + bus->codec_mask = codec_mask; } mutex_unlock(&bus->lock); diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 9106ab8dac6f62..ff45075ef72038 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -174,8 +174,10 @@ void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable) { struct hdac_bus *bus = sof_to_bus(sdev); - dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable); - snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable); + if (HDA_IDISP_CODEC(bus->codec_mask)) { + dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable); + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable); + } } EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); @@ -189,7 +191,8 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev) if (ret < 0) return ret; - hda_codec_i915_display_power(sdev, true); + /* codec_mask not yet known, power up for probe */ + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true); return 0; } @@ -200,7 +203,8 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev) struct hdac_bus *bus = sof_to_bus(sdev); int ret; - hda_codec_i915_display_power(sdev, false); + /* power down unconditionally */ + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); ret = snd_hdac_i915_exit(bus); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index dfccbcbf769e7e..46d7b55a158383 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -595,11 +595,8 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) return ret; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) /* display codec can powered off after link reset */ - if (HDA_IDISP_CODEC(bus->codec_mask)) - hda_codec_i915_display_power(sdev, false); -#endif + hda_codec_i915_display_power(sdev, false); return 0; } @@ -612,11 +609,8 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) #endif int ret; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) /* display codec must be powered before link reset */ - if (HDA_IDISP_CODEC(bus->codec_mask)) - hda_codec_i915_display_power(sdev, true); -#endif + hda_codec_i915_display_power(sdev, true); /* * clear TCSEL to clear playback on some HD Audio @@ -675,6 +669,8 @@ int hda_dsp_resume(struct snd_sof_dev *sdev) return ret; } + hda_codec_i915_display_power(sdev, true); + /* restore L1SEN bit */ if (hda->l1_support_changed) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, @@ -763,6 +759,9 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) return ret; } + /* we can't keep a wakeref to display driver at suspend */ + hda_codec_i915_display_power(sdev, false); + /* enable L1SEN to make sure the system can enter S0Ix */ hda->l1_support_changed = snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index f225152c21d78d..cdb418edd66451 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -519,14 +519,12 @@ static int hda_init(struct snd_sof_dev *sdev) /* HDA base */ sdev->bar[HDA_DSP_HDA_BAR] = bus->remap_addr; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) /* init i915 and HDMI codecs */ ret = hda_codec_i915_init(sdev); if (ret < 0) { dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n"); return ret; } -#endif /* get controller capabilities */ ret = hda_dsp_ctrl_get_caps(sdev); @@ -645,7 +643,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev) hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi); if (!HDA_IDISP_CODEC(bus->codec_mask)) - hda_codec_i915_display_power(sdev, false); + hda_codec_i915_exit(sdev); /* * we are done probing so decrement link counts @@ -884,6 +882,7 @@ int hda_dsp_probe(struct snd_sof_dev *sdev) iounmap(sdev->bar[HDA_DSP_BAR]); hdac_bus_unmap: iounmap(bus->remap_addr); + hda_codec_i915_exit(sdev); err: return ret; }