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 /sound | |
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>
Diffstat (limited to 'sound')
-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; |