diff options
author | Mengdong Lin <mengdong.lin@intel.com> | 2015-05-19 17:29:30 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-05-20 07:16:36 +0300 |
commit | 98d8fc6c5d3652e91c61d78941e0fa6f94771d67 (patch) | |
tree | 31f5d9ce478f828686fb848b66bebc664c51898f /sound/pci/hda/hda_intel.c | |
parent | 4214c5349c20005b7a83916801394eb7270896b2 (diff) | |
download | linux-98d8fc6c5d3652e91c61d78941e0fa6f94771d67.tar.xz |
ALSA: hda - Move hda_i915.c from sound/pci/hda to sound/hda
The file is moved to hda core and renamed to hdac_i915.c, so can be used
by both legacy HDA driver and new Skylake audio driver.
- Add snd_hdac_ prefix to the public APIs.
- The i915 audio component is moved to core bus and dynamically allocated.
- A static pointer hdac_acomp is used to help bind/unbind callbacks to get
this component, because the sound card's private_data is used by the azx
chip pointer, which is a legacy structure. It could be removed if private
_data changes to some core structure which can be extended to find the
bus.
- snd_hdac_get_display_clk() is added to get the display core clock for
HSW/BDW.
- haswell_set_bclk() is moved to hda_intel.c because it needs to write the
controller registers EM4/EM5, and only legacy HD-A needs it for HSW/BDW.
- Move definition of HSW/BDW-specific registers EM4/EM5 to hda_register.h
and rename them to HSW_EM4/HSW_EM5, because other HD-A controllers have
different layout for the extended mode registers.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 82 |
1 files changed, 66 insertions, 16 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5c84d40b7700..391e4f834436 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -57,6 +57,8 @@ #endif #include <sound/core.h> #include <sound/initval.h> +#include <sound/hdaudio.h> +#include <sound/hda_i915.h> #include <linux/vgaarb.h> #include <linux/vga_switcheroo.h> #include <linux/firmware.h> @@ -496,13 +498,13 @@ static void azx_init_pci(struct azx *chip) static void hda_intel_init_chip(struct azx *chip, bool full_reset) { - struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + struct hdac_bus *bus = azx_bus(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) - hda_set_codec_wakeup(hda, true); + snd_hdac_set_codec_wakeup(bus, true); azx_init_chip(chip, full_reset); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) - hda_set_codec_wakeup(hda, false); + snd_hdac_set_codec_wakeup(bus, false); } /* calculate runtime delay from LPIB */ @@ -560,9 +562,9 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev) /* Enable/disable i915 display power for the link */ static int azx_intel_link_power(struct azx *chip, bool enable) { - struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + struct hdac_bus *bus = azx_bus(chip); - return hda_display_power(hda, enable); + return snd_hdac_display_power(bus, enable); } /* @@ -800,6 +802,50 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) #define azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_PM */ +/* Intel HSW/BDW display HDA controller is in GPU. Both its power and link BCLK + * depends on GPU. Two Extended Mode registers EM4 (M value) and EM5 (N Value) + * are used to convert CDClk (Core Display Clock) to 24MHz BCLK: + * BCLK = CDCLK * M / N + * The values will be lost when the display power well is disabled and need to + * be restored to avoid abnormal playback speed. + */ +static void haswell_set_bclk(struct hda_intel *hda) +{ + struct azx *chip = &hda->chip; + int cdclk_freq; + unsigned int bclk_m, bclk_n; + + if (!hda->need_i915_power) + return; + + cdclk_freq = snd_hdac_get_display_clk(azx_bus(chip)); + switch (cdclk_freq) { + case 337500: + bclk_m = 16; + bclk_n = 225; + break; + + case 450000: + default: /* default CDCLK 450MHz */ + bclk_m = 4; + bclk_n = 75; + break; + + case 540000: + bclk_m = 4; + bclk_n = 90; + break; + + case 675000: + bclk_m = 8; + bclk_n = 225; + break; + } + + azx_writew(chip, HSW_EM4, bclk_m); + azx_writew(chip, HSW_EM5, bclk_n); +} + #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) /* * power management @@ -833,7 +879,7 @@ static int azx_suspend(struct device *dev) pci_disable_msi(chip->pci); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && hda->need_i915_power) - hda_display_power(hda, false); + snd_hdac_display_power(bus, false); trace_azx_suspend(chip); return 0; @@ -856,7 +902,7 @@ static int azx_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && hda->need_i915_power) { - hda_display_power(hda, true); + snd_hdac_display_power(azx_bus(chip), true); haswell_set_bclk(hda); } if (chip->msi) @@ -902,7 +948,7 @@ static int azx_runtime_suspend(struct device *dev) azx_clear_irq_pending(chip); if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && hda->need_i915_power) - hda_display_power(hda, false); + snd_hdac_display_power(azx_bus(chip), false); trace_azx_runtime_suspend(chip); return 0; @@ -913,6 +959,7 @@ static int azx_runtime_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; struct hda_intel *hda; + struct hdac_bus *bus; struct hda_codec *codec; int status; @@ -929,11 +976,12 @@ static int azx_runtime_resume(struct device *dev) if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && hda->need_i915_power) { - hda_display_power(hda, true); + bus = azx_bus(chip); + snd_hdac_display_power(bus, true); haswell_set_bclk(hda); /* toggle codec wakeup bit for STATESTS read */ - hda_set_codec_wakeup(hda, true); - hda_set_codec_wakeup(hda, false); + snd_hdac_set_codec_wakeup(bus, true); + snd_hdac_set_codec_wakeup(bus, false); } /* Read STATESTS before controller reset */ @@ -1152,10 +1200,11 @@ static int azx_free(struct azx *chip) #ifdef CONFIG_SND_HDA_PATCH_LOADER release_firmware(chip->fw); #endif + if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { if (hda->need_i915_power) - hda_display_power(hda, false); - hda_i915_exit(hda); + snd_hdac_display_power(bus, false); + snd_hdac_i915_exit(bus); } kfree(hda); @@ -1914,6 +1963,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = { static int azx_probe_continue(struct azx *chip) { struct hda_intel *hda = container_of(chip, struct hda_intel, chip); + struct hdac_bus *bus = azx_bus(chip); struct pci_dev *pci = chip->pci; int dev = chip->dev_index; int err; @@ -1930,11 +1980,11 @@ static int azx_probe_continue(struct azx *chip) if (pci->device != 0x0f04 && pci->device != 0x2284) hda->need_i915_power = 1; - err = hda_i915_init(hda); + err = snd_hdac_i915_init(bus); if (err < 0) goto i915_power_fail; - err = hda_display_power(hda, true); + err = snd_hdac_display_power(bus, true); if (err < 0) { dev_err(chip->card->dev, "Cannot turn on display power on i915\n"); @@ -1986,7 +2036,7 @@ static int azx_probe_continue(struct azx *chip) out_free: if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL && !hda->need_i915_power) - hda_display_power(hda, false); + snd_hdac_display_power(bus, false); i915_power_fail: if (err < 0) |