Commit 7e31a015 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Apply clock gate workaround to Skylake, too

Some Skylake machines show the codec probe errors in certain
situations, e.g. HP Z240 desktop fails to probe the onboard Realtek
codec at reloading the snd-hda-intel module like:
  snd_hda_intel 0000:00:1f.3: spurious response 0x200:0x2, last cmd=0x000000
  snd_hda_intel 0000:00:1f.3: azx_get_response timeout, switching to polling mode: lastcmd=0x000f0000
  snd_hda_intel 0000:00:1f.3: No response from codec, disabling MSI: last cmd=0x000f0000
  snd_hda_intel 0000:00:1f.3: Codec #0 probe error; disabling it...
  hdaudio hdaudioC0D2: no AFG or MFG node found
  snd_hda_intel 0000:00:1f.3: no codecs initialized

Also, HP G470 G3 suffers from the similar problem, as reported in
bugzilla below.  On this machine, the codec probe error appears even
at a fresh boot.

As Libin suggested, the same workaround used for Broxton in the commit
[6639484d: ALSA: hda - disable dynamic clock gating on Broxton
 before reset] can be applied for Skylake in order to fix this problem.
The Intel HW team also confirmed that this is needed for SKL.

This patch makes the workaround applied to both SKL and BXT
platforms.  The referred macros are moved and one superfluous macro
(IS_BROXTON()) is another one (IS_BXT()) as well.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112731Suggested-by: default avatarLibin Yang <libin.yang@linux.intel.com>
Cc: <stable@vger.kernel.org> # v4.4+
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 67ec1072
...@@ -363,7 +363,10 @@ enum { ...@@ -363,7 +363,10 @@ enum {
((pci)->device == 0x0d0c) || \ ((pci)->device == 0x0d0c) || \
((pci)->device == 0x160c)) ((pci)->device == 0x160c))
#define IS_BROXTON(pci) ((pci)->device == 0x5a98) #define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
static char *driver_short_names[] = { static char *driver_short_names[] = {
[AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_ICH] = "HDA Intel",
...@@ -540,13 +543,13 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset) ...@@ -540,13 +543,13 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
snd_hdac_set_codec_wakeup(bus, true); snd_hdac_set_codec_wakeup(bus, true);
if (IS_BROXTON(pci)) { if (IS_SKL_PLUS(pci)) {
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val); pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
val = val & ~INTEL_HDA_CGCTL_MISCBDCGE; val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val); pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
} }
azx_init_chip(chip, full_reset); azx_init_chip(chip, full_reset);
if (IS_BROXTON(pci)) { if (IS_SKL_PLUS(pci)) {
pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val); pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
val = val | INTEL_HDA_CGCTL_MISCBDCGE; val = val | INTEL_HDA_CGCTL_MISCBDCGE;
pci_write_config_dword(pci, INTEL_HDA_CGCTL, val); pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
...@@ -555,7 +558,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset) ...@@ -555,7 +558,7 @@ static void hda_intel_init_chip(struct azx *chip, bool full_reset)
snd_hdac_set_codec_wakeup(bus, false); snd_hdac_set_codec_wakeup(bus, false);
/* reduce dma latency to avoid noise */ /* reduce dma latency to avoid noise */
if (IS_BROXTON(pci)) if (IS_BXT(pci))
bxt_reduce_dma_latency(chip); bxt_reduce_dma_latency(chip);
} }
...@@ -977,11 +980,6 @@ static int azx_resume(struct device *dev) ...@@ -977,11 +980,6 @@ static int azx_resume(struct device *dev)
/* put codec down to D3 at hibernation for Intel SKL+; /* put codec down to D3 at hibernation for Intel SKL+;
* otherwise BIOS may still access the codec and screw up the driver * otherwise BIOS may still access the codec and screw up the driver
*/ */
#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
static int azx_freeze_noirq(struct device *dev) static int azx_freeze_noirq(struct device *dev)
{ {
struct pci_dev *pci = to_pci_dev(dev); struct pci_dev *pci = to_pci_dev(dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment