ALSA: hda - Fix Skylake codec timeout
authorDavid Henningsson <david.henningsson@canonical.com>
Thu, 16 Jul 2015 08:39:24 +0000 (10:39 +0200)
committerTakashi Iwai <tiwai@suse.de>
Mon, 20 Jul 2015 07:33:24 +0000 (09:33 +0200)
When the controller is powered up but the HDMI codec is powered down
on Skylake, the power well is turned off. When the codec is then
powered up again, we need to poke the codec a little extra to make
sure it wakes up. Otherwise we'll get sad "no response from codec"
messages and broken audio.

This also changes azx_runtime_resume to actually call
snd_hdac_set_codec_wakeup for Skylake (before STATETS read).
(Otherwise it would only have been called for Haswell and Broadwell,
which both do not need it, so this probably was not the author's
intention.)

Signed-off-by: David Henningsson <david.henningsson@canonical.com>
Reviewed-by: Libin Yang <libin.yang@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/hda/hdac_i915.c
sound/pci/hda/hda_intel.c

index 442500e06b7c7b66be05ec254a68e58d009089fe..5676b849379d43468267e8d12fc7367096a2ae4c 100644 (file)
@@ -56,8 +56,11 @@ int snd_hdac_display_power(struct hdac_bus *bus, bool enable)
                enable ? "enable" : "disable");
 
        if (enable) {
-               if (!bus->i915_power_refcount++)
+               if (!bus->i915_power_refcount++) {
                        acomp->ops->get_power(acomp->dev);
+                       snd_hdac_set_codec_wakeup(bus, true);
+                       snd_hdac_set_codec_wakeup(bus, false);
+               }
        } else {
                WARN_ON(!bus->i915_power_refcount);
                if (!--bus->i915_power_refcount)
index ca151b45eeefdf2acf07748d2dde259ccc6b9071..9962237066761fe61fa268a2f21666f6bb5fa25b 100644 (file)
@@ -979,14 +979,16 @@ static int azx_runtime_resume(struct device *dev)
        if (!azx_has_pm_runtime(chip))
                return 0;
 
-       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
-               && hda->need_i915_power) {
-               bus =  azx_bus(chip);
-               snd_hdac_display_power(bus, true);
-               haswell_set_bclk(hda);
-               /* toggle codec wakeup bit for STATESTS read */
-               snd_hdac_set_codec_wakeup(bus, true);
-               snd_hdac_set_codec_wakeup(bus, false);
+       if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
+               bus = azx_bus(chip);
+               if (hda->need_i915_power) {
+                       snd_hdac_display_power(bus, true);
+                       haswell_set_bclk(hda);
+               } else {
+                       /* toggle codec wakeup bit for STATESTS read */
+                       snd_hdac_set_codec_wakeup(bus, true);
+                       snd_hdac_set_codec_wakeup(bus, false);
+               }
        }
 
        /* Read STATESTS before controller reset */