diff options
| author | Mengdong Lin <mengdong.lin@intel.com> | 2014-06-26 06:45:16 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-06-26 09:47:42 -0400 |
| commit | a07187c992be945ab561b370cbb49cfd72064c3c (patch) | |
| tree | 2db9f7483d06befd0b159f3b08450eba06e712ab | |
| parent | 92a586bdc06de6629dae1b357dac221253f55ff8 (diff) | |
ALSA: hda - restore BCLK M/N values when resuming HSW/BDW display controller
For Intel Haswell/Broadwell display HD-A controller, the 24MHz HD-A link BCLK
is converted from Core Display Clock (CDCLK): BCLK = CDCLK * M / N
And there are two registers EM4 and EM5 to program M, N value respectively.
The EM4/EM5 values will be lost and when the display power well is disabled.
BIOS programs CDCLK selected by OEM and EM4/EM5, but BIOS has no idea about
display power well on/off at runtime. So the M/N can be wrong if non-default
CDCLK is used when the audio controller resumes, which results in an invalid
BCLK and abnormal audio playback rate. So this patch saves and restores valid
M/N values on controller suspend/resume.
And 'struct hda_intel' is defined to contain standard HD-A 'struct azx' and
Intel specific fields, as Takashi suggested.
Signed-off-by: Mengdong Lin <mengdong.lin@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/pci/hda/hda_intel.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 23fd6b9aecca..25753db97071 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -288,6 +288,24 @@ static char *driver_short_names[] = { | |||
| 288 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", | 288 | [AZX_DRIVER_GENERIC] = "HD-Audio Generic", |
| 289 | }; | 289 | }; |
| 290 | 290 | ||
| 291 | |||
| 292 | /* Intel HSW/BDW display HDA controller Extended Mode registers. | ||
| 293 | * EM4 (M value) and EM5 (N Value) are used to convert CDClk (Core Display | ||
| 294 | * Clock) to 24MHz BCLK: BCLK = CDCLK * M / N | ||
| 295 | * The values will be lost when the display power well is disabled. | ||
| 296 | */ | ||
| 297 | #define ICH6_REG_EM4 0x100c | ||
| 298 | #define ICH6_REG_EM5 0x1010 | ||
| 299 | |||
| 300 | struct hda_intel { | ||
| 301 | struct azx chip; | ||
| 302 | |||
| 303 | /* HSW/BDW display HDA controller to restore BCLK from CDCLK */ | ||
| 304 | unsigned int bclk_m; | ||
| 305 | unsigned int bclk_n; | ||
| 306 | }; | ||
| 307 | |||
| 308 | |||
| 291 | #ifdef CONFIG_X86 | 309 | #ifdef CONFIG_X86 |
| 292 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) | 310 | static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on) |
| 293 | { | 311 | { |
| @@ -580,6 +598,22 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) | |||
| 580 | #define azx_del_card_list(chip) /* NOP */ | 598 | #define azx_del_card_list(chip) /* NOP */ |
| 581 | #endif /* CONFIG_PM */ | 599 | #endif /* CONFIG_PM */ |
| 582 | 600 | ||
| 601 | static void haswell_save_bclk(struct azx *chip) | ||
| 602 | { | ||
| 603 | struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | ||
| 604 | |||
| 605 | hda->bclk_m = azx_readw(chip, EM4); | ||
| 606 | hda->bclk_n = azx_readw(chip, EM5); | ||
| 607 | } | ||
| 608 | |||
| 609 | static void haswell_restore_bclk(struct azx *chip) | ||
| 610 | { | ||
| 611 | struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | ||
| 612 | |||
| 613 | azx_writew(chip, EM4, hda->bclk_m); | ||
| 614 | azx_writew(chip, EM5, hda->bclk_n); | ||
| 615 | } | ||
| 616 | |||
| 583 | #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) | 617 | #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) |
| 584 | /* | 618 | /* |
| 585 | * power management | 619 | * power management |
| @@ -606,6 +640,13 @@ static int azx_suspend(struct device *dev) | |||
| 606 | free_irq(chip->irq, chip); | 640 | free_irq(chip->irq, chip); |
| 607 | chip->irq = -1; | 641 | chip->irq = -1; |
| 608 | } | 642 | } |
| 643 | |||
| 644 | /* Save BCLK M/N values before they become invalid in D3. | ||
| 645 | * Will test if display power well can be released now. | ||
| 646 | */ | ||
| 647 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | ||
| 648 | haswell_save_bclk(chip); | ||
| 649 | |||
| 609 | if (chip->msi) | 650 | if (chip->msi) |
| 610 | pci_disable_msi(chip->pci); | 651 | pci_disable_msi(chip->pci); |
| 611 | pci_disable_device(pci); | 652 | pci_disable_device(pci); |
| @@ -625,8 +666,10 @@ static int azx_resume(struct device *dev) | |||
| 625 | if (chip->disabled) | 666 | if (chip->disabled) |
| 626 | return 0; | 667 | return 0; |
| 627 | 668 | ||
| 628 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 669 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
| 629 | hda_display_power(true); | 670 | hda_display_power(true); |
| 671 | haswell_restore_bclk(chip); | ||
| 672 | } | ||
| 630 | pci_set_power_state(pci, PCI_D0); | 673 | pci_set_power_state(pci, PCI_D0); |
| 631 | pci_restore_state(pci); | 674 | pci_restore_state(pci); |
| 632 | if (pci_enable_device(pci) < 0) { | 675 | if (pci_enable_device(pci) < 0) { |
| @@ -670,8 +713,10 @@ static int azx_runtime_suspend(struct device *dev) | |||
| 670 | azx_stop_chip(chip); | 713 | azx_stop_chip(chip); |
| 671 | azx_enter_link_reset(chip); | 714 | azx_enter_link_reset(chip); |
| 672 | azx_clear_irq_pending(chip); | 715 | azx_clear_irq_pending(chip); |
| 673 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 716 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
| 717 | haswell_save_bclk(chip); | ||
| 674 | hda_display_power(false); | 718 | hda_display_power(false); |
| 719 | } | ||
| 675 | return 0; | 720 | return 0; |
| 676 | } | 721 | } |
| 677 | 722 | ||
| @@ -689,8 +734,10 @@ static int azx_runtime_resume(struct device *dev) | |||
| 689 | if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) | 734 | if (!(chip->driver_caps & AZX_DCAPS_PM_RUNTIME)) |
| 690 | return 0; | 735 | return 0; |
| 691 | 736 | ||
| 692 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) | 737 | if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { |
| 693 | hda_display_power(true); | 738 | hda_display_power(true); |
| 739 | haswell_restore_bclk(chip); | ||
| 740 | } | ||
| 694 | 741 | ||
| 695 | /* Read STATESTS before controller reset */ | 742 | /* Read STATESTS before controller reset */ |
| 696 | status = azx_readw(chip, STATESTS); | 743 | status = azx_readw(chip, STATESTS); |
| @@ -883,6 +930,8 @@ static int register_vga_switcheroo(struct azx *chip) | |||
| 883 | static int azx_free(struct azx *chip) | 930 | static int azx_free(struct azx *chip) |
| 884 | { | 931 | { |
| 885 | struct pci_dev *pci = chip->pci; | 932 | struct pci_dev *pci = chip->pci; |
| 933 | struct hda_intel *hda = container_of(chip, struct hda_intel, chip); | ||
| 934 | |||
| 886 | int i; | 935 | int i; |
| 887 | 936 | ||
| 888 | if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) | 937 | if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME) |
| @@ -930,7 +979,7 @@ static int azx_free(struct azx *chip) | |||
| 930 | hda_display_power(false); | 979 | hda_display_power(false); |
| 931 | hda_i915_exit(); | 980 | hda_i915_exit(); |
| 932 | } | 981 | } |
| 933 | kfree(chip); | 982 | kfree(hda); |
| 934 | 983 | ||
| 935 | return 0; | 984 | return 0; |
| 936 | } | 985 | } |
| @@ -1174,6 +1223,7 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1174 | static struct snd_device_ops ops = { | 1223 | static struct snd_device_ops ops = { |
| 1175 | .dev_free = azx_dev_free, | 1224 | .dev_free = azx_dev_free, |
| 1176 | }; | 1225 | }; |
| 1226 | struct hda_intel *hda; | ||
| 1177 | struct azx *chip; | 1227 | struct azx *chip; |
| 1178 | int err; | 1228 | int err; |
| 1179 | 1229 | ||
| @@ -1183,13 +1233,14 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1183 | if (err < 0) | 1233 | if (err < 0) |
| 1184 | return err; | 1234 | return err; |
| 1185 | 1235 | ||
| 1186 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1236 | hda = kzalloc(sizeof(*hda), GFP_KERNEL); |
| 1187 | if (!chip) { | 1237 | if (!hda) { |
| 1188 | dev_err(card->dev, "Cannot allocate chip\n"); | 1238 | dev_err(card->dev, "Cannot allocate hda\n"); |
| 1189 | pci_disable_device(pci); | 1239 | pci_disable_device(pci); |
| 1190 | return -ENOMEM; | 1240 | return -ENOMEM; |
| 1191 | } | 1241 | } |
| 1192 | 1242 | ||
| 1243 | chip = &hda->chip; | ||
| 1193 | spin_lock_init(&chip->reg_lock); | 1244 | spin_lock_init(&chip->reg_lock); |
| 1194 | mutex_init(&chip->open_mutex); | 1245 | mutex_init(&chip->open_mutex); |
| 1195 | chip->card = card; | 1246 | chip->card = card; |
