aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2016-08-04 16:38:36 -0400
committerTakashi Iwai <tiwai@suse.de>2016-08-10 09:05:17 -0400
commita52ff34e5ec61749c62c6618b76a9d6dbecee450 (patch)
tree1690217f584b284eb714a7509c3a7f0f9d3bba68 /sound/pci/hda
parent41f5e3bdbf706a9e98194bf0c4b62a875c02f170 (diff)
ALSA: hda - Manage power well properly for resume
For SKL and later Intel chips, we control the power well per codec basis via link_power callback since the commit [03b135cebc47: ALSA: hda - remove dependency on i915 power well for SKL]. However, there are a few exceptional cases where the gfx registers are accessed from the audio driver: namely the wakeup override bit toggling at (both system and runtime) resume. This seems causing a kernel warning when accessed during the power well down (and likely resulting in the bogus register accesses). This patch puts the proper power up / down sequence around the resume code so that the wakeup bit is fiddled properly while the power is up. (The other callback, sync_audio_rate, is used only in the PCM callback, so it's guaranteed in the power-on.) Also, by this proper power up/down, the instantaneous flip of wakeup bit in the resume callback that was introduced by the commit [033ea349a7cd: ALSA: hda - Fix Skylake codec timeout] becomes superfluous, as snd_hdac_display_power() already does it. So we can clean it up together. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96214 Fixes: 03b135cebc47 ('ALSA: hda - remove dependency on i915 power well for SKL') Cc: <stable@vger.kernel.org> # v4.2+ Tested-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_intel.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 89dacf9b4e6c..160c7f713722 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -906,20 +906,23 @@ static int azx_resume(struct device *dev)
906 struct snd_card *card = dev_get_drvdata(dev); 906 struct snd_card *card = dev_get_drvdata(dev);
907 struct azx *chip; 907 struct azx *chip;
908 struct hda_intel *hda; 908 struct hda_intel *hda;
909 struct hdac_bus *bus;
909 910
910 if (!card) 911 if (!card)
911 return 0; 912 return 0;
912 913
913 chip = card->private_data; 914 chip = card->private_data;
914 hda = container_of(chip, struct hda_intel, chip); 915 hda = container_of(chip, struct hda_intel, chip);
916 bus = azx_bus(chip);
915 if (chip->disabled || hda->init_failed || !chip->running) 917 if (chip->disabled || hda->init_failed || !chip->running)
916 return 0; 918 return 0;
917 919
918 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL 920 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
919 && hda->need_i915_power) { 921 snd_hdac_display_power(bus, true);
920 snd_hdac_display_power(azx_bus(chip), true); 922 if (hda->need_i915_power)
921 snd_hdac_i915_set_bclk(azx_bus(chip)); 923 snd_hdac_i915_set_bclk(bus);
922 } 924 }
925
923 if (chip->msi) 926 if (chip->msi)
924 if (pci_enable_msi(pci) < 0) 927 if (pci_enable_msi(pci) < 0)
925 chip->msi = 0; 928 chip->msi = 0;
@@ -929,6 +932,11 @@ static int azx_resume(struct device *dev)
929 932
930 hda_intel_init_chip(chip, true); 933 hda_intel_init_chip(chip, true);
931 934
935 /* power down again for link-controlled chips */
936 if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
937 !hda->need_i915_power)
938 snd_hdac_display_power(bus, false);
939
932 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 940 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
933 941
934 trace_azx_resume(chip); 942 trace_azx_resume(chip);
@@ -1008,6 +1016,7 @@ static int azx_runtime_resume(struct device *dev)
1008 1016
1009 chip = card->private_data; 1017 chip = card->private_data;
1010 hda = container_of(chip, struct hda_intel, chip); 1018 hda = container_of(chip, struct hda_intel, chip);
1019 bus = azx_bus(chip);
1011 if (chip->disabled || hda->init_failed) 1020 if (chip->disabled || hda->init_failed)
1012 return 0; 1021 return 0;
1013 1022
@@ -1015,15 +1024,9 @@ static int azx_runtime_resume(struct device *dev)
1015 return 0; 1024 return 0;
1016 1025
1017 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 1026 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
1018 bus = azx_bus(chip); 1027 snd_hdac_display_power(bus, true);
1019 if (hda->need_i915_power) { 1028 if (hda->need_i915_power)
1020 snd_hdac_display_power(bus, true);
1021 snd_hdac_i915_set_bclk(bus); 1029 snd_hdac_i915_set_bclk(bus);
1022 } else {
1023 /* toggle codec wakeup bit for STATESTS read */
1024 snd_hdac_set_codec_wakeup(bus, true);
1025 snd_hdac_set_codec_wakeup(bus, false);
1026 }
1027 } 1030 }
1028 1031
1029 /* Read STATESTS before controller reset */ 1032 /* Read STATESTS before controller reset */
@@ -1043,6 +1046,11 @@ static int azx_runtime_resume(struct device *dev)
1043 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & 1046 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
1044 ~STATESTS_INT_MASK); 1047 ~STATESTS_INT_MASK);
1045 1048
1049 /* power down again for link-controlled chips */
1050 if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
1051 !hda->need_i915_power)
1052 snd_hdac_display_power(bus, false);
1053
1046 trace_azx_runtime_resume(chip); 1054 trace_azx_runtime_resume(chip);
1047 return 0; 1055 return 0;
1048} 1056}