aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-06-27 19:50:34 -0400
committerDave Airlie <airlied@redhat.com>2013-06-27 19:50:34 -0400
commit28419261b09aa3a5118647b1ed93809ca97c5354 (patch)
tree5098381ee695009fce1fa4a25ba34d487eb4f35e /sound/pci
parent4a009085978de90db40f9f38bcfad501f86ca959 (diff)
parent854c94a7854a4fabdd7db451cf1774e6dcba6bab (diff)
Merge tag 'drm-intel-next-2013-06-18' of git://people.freedesktop.org/~danvet/drm-intel into drm-next
Last 3.11 feature pull. I have a few odds bits and pieces and fixes in my queue, I'll sort them out later on to see what's for 3.11-fixes and what's for 3.12. But nothing to hold this here up imo. Highlights: - more hangcheck work from Mika and Chris to prepare for arb robustness - trickle feed fixes from Ville - first parts of the shared pch pll rework, with some basic hw state readout and cross-checking (this shuts up the confused pch pll refcount WARN that Linus just recently forwarded) - Haswell audio power well support from Wang Xingchao (alsa bits acked by Takashi) - some cleanups and asserts sprinkling around the plane/gamma enabling sequence from Ville - more gtt refactoring from Ben - clear up the adjusted->mode vs. pixel clock vs. port clock confusion - 30bpp support, this time for real hopefully * tag 'drm-intel-next-2013-06-18' of git://people.freedesktop.org/~danvet/drm-intel: (97 commits) drm/i915: remove a superflous semi-colon drm/i915: Kill useless "Enable panel fitter" comments drm/i915: Remove extra "ring" from error message drm/i915: simplify the reduced clock handling for pch plls drm/i915: stop killing pfit on i9xx drm/i915: explicitly set up PIPECONF (and gamma table) on haswell drm/i915: set up PIPECONF explicitly for i9xx/vlv platforms drm/i915: set up PIPECONF explicitly on ilk-ivb drm/i915: find guilty batch buffer on ring resets drm/i915: store ring hangcheck action drm/i915: add batch bo to i915_add_request() drm/i915: change i915_add_request to macro drm/i915: add i915_gem_context_get_hang_stats() drm/i915: add struct i915_ctx_hang_stats drm/i915: Try harder to disable trickle feed on VLV drm/i915: fix up pch pll enabling for pixel multipliers drm/i915: hw state readout and cross-checking for shared dplls drm/i915: WARN on lack of shared dpll drm/i915: split up intel_modeset_check_state drm/i915: extract readout_hw_state from setup_hw_state ... Conflicts: drivers/gpu/drm/i915/intel_display.c drivers/gpu/drm/i915/intel_fb.c drivers/gpu/drm/i915/intel_sdvo.c
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/Kconfig10
-rw-r--r--sound/pci/hda/Makefile2
-rw-r--r--sound/pci/hda/hda_i915.c75
-rw-r--r--sound/pci/hda/hda_i915.h35
-rw-r--r--sound/pci/hda/hda_intel.c87
5 files changed, 192 insertions, 17 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 80a7d44bcf81..c5a872ca7703 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -152,6 +152,16 @@ config SND_HDA_CODEC_HDMI
152 snd-hda-codec-hdmi. 152 snd-hda-codec-hdmi.
153 This module is automatically loaded at probing. 153 This module is automatically loaded at probing.
154 154
155config SND_HDA_I915
156 bool "Build Display HD-audio controller/codec power well support for i915 cards"
157 depends on DRM_I915
158 help
159 Say Y here to include full HDMI and DisplayPort HD-audio controller/codec
160 power-well support for Intel Haswell graphics cards based on the i915 driver.
161
162 Note that this option must be enabled for Intel Haswell C+ stepping machines, otherwise
163 the GPU audio controller/codecs will not be initialized or damaged when exit from S3 mode.
164
155config SND_HDA_CODEC_CIRRUS 165config SND_HDA_CODEC_CIRRUS
156 bool "Build Cirrus Logic codec support" 166 bool "Build Cirrus Logic codec support"
157 default y 167 default y
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 24a251497a1f..c091438286a3 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,4 +1,6 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2# for haswell power well
3snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o
2 4
3snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o 5snd-hda-codec-y := hda_codec.o hda_jack.o hda_auto_parser.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 6snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c
new file mode 100644
index 000000000000..76c13d5b3ca0
--- /dev/null
+++ b/sound/pci/hda/hda_i915.c
@@ -0,0 +1,75 @@
1/*
2 * hda_i915.c - routines for Haswell HDA controller power well support
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19#include <linux/init.h>
20#include <linux/module.h>
21#include <sound/core.h>
22#include <drm/i915_powerwell.h>
23#include "hda_i915.h"
24
25static void (*get_power)(void);
26static void (*put_power)(void);
27
28void hda_display_power(bool enable)
29{
30 if (!get_power || !put_power)
31 return;
32
33 snd_printdd("HDA display power %s \n",
34 enable ? "Enable" : "Disable");
35 if (enable)
36 get_power();
37 else
38 put_power();
39}
40
41int hda_i915_init(void)
42{
43 int err = 0;
44
45 get_power = symbol_request(i915_request_power_well);
46 if (!get_power) {
47 snd_printk(KERN_WARNING "hda-i915: get_power symbol get fail\n");
48 return -ENODEV;
49 }
50
51 put_power = symbol_request(i915_release_power_well);
52 if (!put_power) {
53 symbol_put(i915_request_power_well);
54 get_power = NULL;
55 return -ENODEV;
56 }
57
58 snd_printd("HDA driver get symbol successfully from i915 module\n");
59
60 return err;
61}
62
63int hda_i915_exit(void)
64{
65 if (get_power) {
66 symbol_put(i915_request_power_well);
67 get_power = NULL;
68 }
69 if (put_power) {
70 symbol_put(i915_release_power_well);
71 put_power = NULL;
72 }
73
74 return 0;
75}
diff --git a/sound/pci/hda/hda_i915.h b/sound/pci/hda/hda_i915.h
new file mode 100644
index 000000000000..5a63da2c53e5
--- /dev/null
+++ b/sound/pci/hda/hda_i915.h
@@ -0,0 +1,35 @@
1/*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU General Public License as published by the Free
4 * Software Foundation; either version 2 of the License, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful, but WITHOUT
8 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
9 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
10 * more details.
11 *
12 * You should have received a copy of the GNU General Public License along with
13 * this program; if not, write to the Free Software Foundation, Inc., 59
14 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16#ifndef __SOUND_HDA_I915_H
17#define __SOUND_HDA_I915_H
18
19#ifdef CONFIG_SND_HDA_I915
20void hda_display_power(bool enable);
21int hda_i915_init(void);
22int hda_i915_exit(void);
23#else
24static inline void hda_display_power(bool enable) {}
25static inline int hda_i915_init(void)
26{
27 return -ENODEV;
28}
29static inline int hda_i915_exit(void)
30{
31 return 0;
32}
33#endif
34
35#endif
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index de18722c4873..35e9f8b010a7 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -62,6 +62,7 @@
62#include <linux/vga_switcheroo.h> 62#include <linux/vga_switcheroo.h>
63#include <linux/firmware.h> 63#include <linux/firmware.h>
64#include "hda_codec.h" 64#include "hda_codec.h"
65#include "hda_i915.h"
65 66
66 67
67static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 68static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
@@ -541,6 +542,10 @@ struct azx {
541 /* for pending irqs */ 542 /* for pending irqs */
542 struct work_struct irq_pending_work; 543 struct work_struct irq_pending_work;
543 544
545#ifdef CONFIG_SND_HDA_I915
546 struct work_struct probe_work;
547#endif
548
544 /* reboot notifier (for mysterious hangup problem at power-down) */ 549 /* reboot notifier (for mysterious hangup problem at power-down) */
545 struct notifier_block reboot_notifier; 550 struct notifier_block reboot_notifier;
546 551
@@ -594,6 +599,7 @@ enum {
594#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 599#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
595#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */ 600#define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
596#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */ 601#define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
602#define AZX_DCAPS_I915_POWERWELL (1 << 27) /* HSW i915 power well support */
597 603
598/* quirks for Intel PCH */ 604/* quirks for Intel PCH */
599#define AZX_DCAPS_INTEL_PCH_NOPM \ 605#define AZX_DCAPS_INTEL_PCH_NOPM \
@@ -2900,6 +2906,8 @@ static int azx_suspend(struct device *dev)
2900 pci_disable_device(pci); 2906 pci_disable_device(pci);
2901 pci_save_state(pci); 2907 pci_save_state(pci);
2902 pci_set_power_state(pci, PCI_D3hot); 2908 pci_set_power_state(pci, PCI_D3hot);
2909 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2910 hda_display_power(false);
2903 return 0; 2911 return 0;
2904} 2912}
2905 2913
@@ -2912,6 +2920,8 @@ static int azx_resume(struct device *dev)
2912 if (chip->disabled) 2920 if (chip->disabled)
2913 return 0; 2921 return 0;
2914 2922
2923 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2924 hda_display_power(true);
2915 pci_set_power_state(pci, PCI_D0); 2925 pci_set_power_state(pci, PCI_D0);
2916 pci_restore_state(pci); 2926 pci_restore_state(pci);
2917 if (pci_enable_device(pci) < 0) { 2927 if (pci_enable_device(pci) < 0) {
@@ -2944,6 +2954,8 @@ static int azx_runtime_suspend(struct device *dev)
2944 2954
2945 azx_stop_chip(chip); 2955 azx_stop_chip(chip);
2946 azx_clear_irq_pending(chip); 2956 azx_clear_irq_pending(chip);
2957 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2958 hda_display_power(false);
2947 return 0; 2959 return 0;
2948} 2960}
2949 2961
@@ -2952,6 +2964,8 @@ static int azx_runtime_resume(struct device *dev)
2952 struct snd_card *card = dev_get_drvdata(dev); 2964 struct snd_card *card = dev_get_drvdata(dev);
2953 struct azx *chip = card->private_data; 2965 struct azx *chip = card->private_data;
2954 2966
2967 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2968 hda_display_power(true);
2955 azx_init_pci(chip); 2969 azx_init_pci(chip);
2956 azx_init_chip(chip, 1); 2970 azx_init_chip(chip, 1);
2957 return 0; 2971 return 0;
@@ -3006,7 +3020,6 @@ static void azx_notifier_unregister(struct azx *chip)
3006 unregister_reboot_notifier(&chip->reboot_notifier); 3020 unregister_reboot_notifier(&chip->reboot_notifier);
3007} 3021}
3008 3022
3009static int azx_first_init(struct azx *chip);
3010static int azx_probe_continue(struct azx *chip); 3023static int azx_probe_continue(struct azx *chip);
3011 3024
3012#ifdef SUPPORT_VGA_SWITCHEROO 3025#ifdef SUPPORT_VGA_SWITCHEROO
@@ -3033,8 +3046,7 @@ static void azx_vs_set_state(struct pci_dev *pci,
3033 snd_printk(KERN_INFO SFX 3046 snd_printk(KERN_INFO SFX
3034 "%s: Start delayed initialization\n", 3047 "%s: Start delayed initialization\n",
3035 pci_name(chip->pci)); 3048 pci_name(chip->pci));
3036 if (azx_first_init(chip) < 0 || 3049 if (azx_probe_continue(chip) < 0) {
3037 azx_probe_continue(chip) < 0) {
3038 snd_printk(KERN_ERR SFX 3050 snd_printk(KERN_ERR SFX
3039 "%s: initialization error\n", 3051 "%s: initialization error\n",
3040 pci_name(chip->pci)); 3052 pci_name(chip->pci));
@@ -3120,8 +3132,13 @@ static int register_vga_switcheroo(struct azx *chip)
3120 */ 3132 */
3121static int azx_free(struct azx *chip) 3133static int azx_free(struct azx *chip)
3122{ 3134{
3135 struct pci_dev *pci = chip->pci;
3123 int i; 3136 int i;
3124 3137
3138 if ((chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
3139 && chip->running)
3140 pm_runtime_get_noresume(&pci->dev);
3141
3125 azx_del_card_list(chip); 3142 azx_del_card_list(chip);
3126 3143
3127 azx_notifier_unregister(chip); 3144 azx_notifier_unregister(chip);
@@ -3173,6 +3190,10 @@ static int azx_free(struct azx *chip)
3173 if (chip->fw) 3190 if (chip->fw)
3174 release_firmware(chip->fw); 3191 release_firmware(chip->fw);
3175#endif 3192#endif
3193 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3194 hda_display_power(false);
3195 hda_i915_exit();
3196 }
3176 kfree(chip); 3197 kfree(chip);
3177 3198
3178 return 0; 3199 return 0;
@@ -3398,6 +3419,13 @@ static void azx_check_snoop_available(struct azx *chip)
3398 } 3419 }
3399} 3420}
3400 3421
3422#ifdef CONFIG_SND_HDA_I915
3423static void azx_probe_work(struct work_struct *work)
3424{
3425 azx_probe_continue(container_of(work, struct azx, probe_work));
3426}
3427#endif
3428
3401/* 3429/*
3402 * constructor 3430 * constructor
3403 */ 3431 */
@@ -3473,7 +3501,13 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
3473 return err; 3501 return err;
3474 } 3502 }
3475 3503
3504#ifdef CONFIG_SND_HDA_I915
3505 /* continue probing in work context as may trigger request module */
3506 INIT_WORK(&chip->probe_work, azx_probe_work);
3507#endif
3508
3476 *rchip = chip; 3509 *rchip = chip;
3510
3477 return 0; 3511 return 0;
3478} 3512}
3479 3513
@@ -3730,11 +3764,6 @@ static int azx_probe(struct pci_dev *pci,
3730 } 3764 }
3731 3765
3732 probe_now = !chip->disabled; 3766 probe_now = !chip->disabled;
3733 if (probe_now) {
3734 err = azx_first_init(chip);
3735 if (err < 0)
3736 goto out_free;
3737 }
3738 3767
3739#ifdef CONFIG_SND_HDA_PATCH_LOADER 3768#ifdef CONFIG_SND_HDA_PATCH_LOADER
3740 if (patch[dev] && *patch[dev]) { 3769 if (patch[dev] && *patch[dev]) {
@@ -3749,15 +3778,22 @@ static int azx_probe(struct pci_dev *pci,
3749 } 3778 }
3750#endif /* CONFIG_SND_HDA_PATCH_LOADER */ 3779#endif /* CONFIG_SND_HDA_PATCH_LOADER */
3751 3780
3781 /* continue probing in work context, avoid request_module deadlock */
3782 if (probe_now && (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)) {
3783#ifdef CONFIG_SND_HDA_I915
3784 probe_now = false;
3785 schedule_work(&chip->probe_work);
3786#else
3787 snd_printk(KERN_ERR SFX "Haswell must build in CONFIG_SND_HDA_I915\n");
3788#endif
3789 }
3790
3752 if (probe_now) { 3791 if (probe_now) {
3753 err = azx_probe_continue(chip); 3792 err = azx_probe_continue(chip);
3754 if (err < 0) 3793 if (err < 0)
3755 goto out_free; 3794 goto out_free;
3756 } 3795 }
3757 3796
3758 if (pci_dev_run_wake(pci))
3759 pm_runtime_put_noidle(&pci->dev);
3760
3761 dev++; 3797 dev++;
3762 complete_all(&chip->probe_wait); 3798 complete_all(&chip->probe_wait);
3763 return 0; 3799 return 0;
@@ -3770,9 +3806,24 @@ out_free:
3770 3806
3771static int azx_probe_continue(struct azx *chip) 3807static int azx_probe_continue(struct azx *chip)
3772{ 3808{
3809 struct pci_dev *pci = chip->pci;
3773 int dev = chip->dev_index; 3810 int dev = chip->dev_index;
3774 int err; 3811 int err;
3775 3812
3813 /* Request power well for Haswell HDA controller and codec */
3814 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3815 err = hda_i915_init();
3816 if (err < 0) {
3817 snd_printk(KERN_ERR SFX "Error request power-well from i915\n");
3818 goto out_free;
3819 }
3820 hda_display_power(true);
3821 }
3822
3823 err = azx_first_init(chip);
3824 if (err < 0)
3825 goto out_free;
3826
3776#ifdef CONFIG_SND_HDA_INPUT_BEEP 3827#ifdef CONFIG_SND_HDA_INPUT_BEEP
3777 chip->beep_mode = beep_mode[dev]; 3828 chip->beep_mode = beep_mode[dev];
3778#endif 3829#endif
@@ -3817,6 +3868,8 @@ static int azx_probe_continue(struct azx *chip)
3817 power_down_all_codecs(chip); 3868 power_down_all_codecs(chip);
3818 azx_notifier_register(chip); 3869 azx_notifier_register(chip);
3819 azx_add_card_list(chip); 3870 azx_add_card_list(chip);
3871 if (chip->driver_caps & AZX_DCAPS_PM_RUNTIME)
3872 pm_runtime_put_noidle(&pci->dev);
3820 3873
3821 return 0; 3874 return 0;
3822 3875
@@ -3829,9 +3882,6 @@ static void azx_remove(struct pci_dev *pci)
3829{ 3882{
3830 struct snd_card *card = pci_get_drvdata(pci); 3883 struct snd_card *card = pci_get_drvdata(pci);
3831 3884
3832 if (pci_dev_run_wake(pci))
3833 pm_runtime_get_noresume(&pci->dev);
3834
3835 if (card) 3885 if (card)
3836 snd_card_free(card); 3886 snd_card_free(card);
3837 pci_set_drvdata(pci, NULL); 3887 pci_set_drvdata(pci, NULL);
@@ -3864,11 +3914,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3864 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH }, 3914 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH },
3865 /* Haswell */ 3915 /* Haswell */
3866 { PCI_DEVICE(0x8086, 0x0a0c), 3916 { PCI_DEVICE(0x8086, 0x0a0c),
3867 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3917 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3918 AZX_DCAPS_I915_POWERWELL },
3868 { PCI_DEVICE(0x8086, 0x0c0c), 3919 { PCI_DEVICE(0x8086, 0x0c0c),
3869 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3920 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3921 AZX_DCAPS_I915_POWERWELL },
3870 { PCI_DEVICE(0x8086, 0x0d0c), 3922 { PCI_DEVICE(0x8086, 0x0d0c),
3871 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH }, 3923 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH |
3924 AZX_DCAPS_I915_POWERWELL },
3872 /* 5 Series/3400 */ 3925 /* 5 Series/3400 */
3873 { PCI_DEVICE(0x8086, 0x3b56), 3926 { PCI_DEVICE(0x8086, 0x3b56),
3874 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM }, 3927 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM },