diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 89dacf9b4e6c..c3469f756ec2 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -54,6 +54,7 @@ /* for snoop control */ #include <asm/pgtable.h> #include <asm/cacheflush.h> +#include <asm/cpufeature.h> #endif #include <sound/core.h> #include <sound/initval.h> @@ -906,20 +907,23 @@ static int azx_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; struct hda_intel *hda; + struct hdac_bus *bus; if (!card) return 0; chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); + bus = azx_bus(chip); if (chip->disabled || hda->init_failed || !chip->running) return 0; - if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL - && hda->need_i915_power) { - snd_hdac_display_power(azx_bus(chip), true); - snd_hdac_i915_set_bclk(azx_bus(chip)); + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { + snd_hdac_display_power(bus, true); + if (hda->need_i915_power) + snd_hdac_i915_set_bclk(bus); } + if (chip->msi) if (pci_enable_msi(pci) < 0) chip->msi = 0; @@ -929,6 +933,11 @@ static int azx_resume(struct device *dev) hda_intel_init_chip(chip, true); + /* power down again for link-controlled chips */ + if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) && + !hda->need_i915_power) + snd_hdac_display_power(bus, false); + snd_power_change_state(card, SNDRV_CTL_POWER_D0); trace_azx_resume(chip); @@ -1008,6 +1017,7 @@ static int azx_runtime_resume(struct device *dev) chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); + bus = azx_bus(chip); if (chip->disabled || hda->init_failed) return 0; @@ -1015,15 +1025,9 @@ static int azx_runtime_resume(struct device *dev) return 0; if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { - bus = azx_bus(chip); - if (hda->need_i915_power) { - snd_hdac_display_power(bus, true); + snd_hdac_display_power(bus, true); + if (hda->need_i915_power) snd_hdac_i915_set_bclk(bus); - } 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 */ @@ -1043,6 +1047,11 @@ static int azx_runtime_resume(struct device *dev) azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & ~STATESTS_INT_MASK); + /* power down again for link-controlled chips */ + if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) && + !hda->need_i915_power) + snd_hdac_display_power(bus, false); + trace_azx_runtime_resume(chip); return 0; } @@ -1655,6 +1664,22 @@ static int azx_first_init(struct azx *chip) return -ENXIO; } + if (IS_SKL_PLUS(pci)) + snd_hdac_bus_parse_capabilities(bus); + + /* + * Some Intel CPUs has always running timer (ART) feature and + * controller may have Global time sync reporting capability, so + * check both of these before declaring synchronized time reporting + * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME + */ + chip->gts_present = false; + +#ifdef CONFIG_X86 + if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART)) + chip->gts_present = true; +#endif + if (chip->msi) { if (chip->driver_caps & AZX_DCAPS_NO_MSI64) { dev_dbg(card->dev, "Disabling 64bit MSI\n"); |