summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-04-29 06:28:52 -0400
committerTakashi Iwai <tiwai@suse.de>2015-04-29 06:28:52 -0400
commit85abf3ec5fa663c9638ef2d10d9623880a26458e (patch)
treece1cc6166cd34b4a49299ccf4aefaac657a34fcf
parent49c4a4c5244d2c1a25ec1e01dbb4fba3813d237d (diff)
parent2bd1f73f4242ee19d8c610bcffe6e7a813451ce0 (diff)
Merge branch 'topic/hda' into for-next
-rw-r--r--include/sound/hdaudio.h4
-rw-r--r--sound/hda/hdac_device.c15
-rw-r--r--sound/pci/hda/hda_codec.c4
-rw-r--r--sound/pci/hda/hda_controller.c11
-rw-r--r--sound/pci/hda/hda_controller.h2
-rw-r--r--sound/pci/hda/hda_i915.c18
-rw-r--r--sound/pci/hda/hda_intel.c46
-rw-r--r--sound/pci/hda/hda_intel.h2
-rw-r--r--sound/pci/hda/patch_hdmi.c9
9 files changed, 99 insertions, 12 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 6a2e030c836c..b97c59eab7ab 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -74,6 +74,7 @@ struct hdac_device {
74 74
75 /* misc flags */ 75 /* misc flags */
76 atomic_t in_pm; /* suspend/resume being performed */ 76 atomic_t in_pm; /* suspend/resume being performed */
77 bool link_power_control:1;
77 78
78 /* sysfs */ 79 /* sysfs */
79 struct hdac_widget_tree *widgets; 80 struct hdac_widget_tree *widgets;
@@ -184,6 +185,8 @@ struct hdac_bus_ops {
184 /* get a response from the last command */ 185 /* get a response from the last command */
185 int (*get_response)(struct hdac_bus *bus, unsigned int addr, 186 int (*get_response)(struct hdac_bus *bus, unsigned int addr,
186 unsigned int *res); 187 unsigned int *res);
188 /* control the link power */
189 int (*link_power)(struct hdac_bus *bus, bool enable);
187}; 190};
188 191
189/* 192/*
@@ -311,6 +314,7 @@ static inline void snd_hdac_codec_link_down(struct hdac_device *codec)
311int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val); 314int snd_hdac_bus_send_cmd(struct hdac_bus *bus, unsigned int val);
312int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr, 315int snd_hdac_bus_get_response(struct hdac_bus *bus, unsigned int addr,
313 unsigned int *res); 316 unsigned int *res);
317int snd_hdac_link_power(struct hdac_device *codec, bool enable);
314 318
315bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset); 319bool snd_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset);
316void snd_hdac_bus_stop_chip(struct hdac_bus *bus); 320void snd_hdac_bus_stop_chip(struct hdac_bus *bus);
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index 55c7d086b9dd..cdee7103f649 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -552,6 +552,21 @@ void snd_hdac_power_down_pm(struct hdac_device *codec)
552EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm); 552EXPORT_SYMBOL_GPL(snd_hdac_power_down_pm);
553#endif 553#endif
554 554
555/*
556 * Enable/disable the link power for a codec.
557 */
558int snd_hdac_link_power(struct hdac_device *codec, bool enable)
559{
560 if (!codec->link_power_control)
561 return 0;
562
563 if (codec->bus->ops->link_power)
564 return codec->bus->ops->link_power(codec->bus, enable);
565 else
566 return -EINVAL;
567}
568EXPORT_SYMBOL_GPL(snd_hdac_link_power);
569
555/* codec vendor labels */ 570/* codec vendor labels */
556struct hda_vendor_id { 571struct hda_vendor_id {
557 unsigned int id; 572 unsigned int id;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index d65173a62ae9..54380ed03697 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -858,6 +858,7 @@ void snd_hda_codec_register(struct hda_codec *codec)
858 return; 858 return;
859 if (device_is_registered(hda_codec_dev(codec))) { 859 if (device_is_registered(hda_codec_dev(codec))) {
860 snd_hda_register_beep_device(codec); 860 snd_hda_register_beep_device(codec);
861 snd_hdac_link_power(&codec->core, true);
861 pm_runtime_enable(hda_codec_dev(codec)); 862 pm_runtime_enable(hda_codec_dev(codec));
862 /* it was powered up in snd_hda_codec_new(), now all done */ 863 /* it was powered up in snd_hda_codec_new(), now all done */
863 snd_hda_power_down(codec); 864 snd_hda_power_down(codec);
@@ -884,6 +885,7 @@ static int snd_hda_codec_dev_free(struct snd_device *device)
884 struct hda_codec *codec = device->device_data; 885 struct hda_codec *codec = device->device_data;
885 886
886 codec->in_freeing = 1; 887 codec->in_freeing = 1;
888 snd_hdac_link_power(&codec->core, false);
887 snd_hdac_device_unregister(&codec->core); 889 snd_hdac_device_unregister(&codec->core);
888 put_device(hda_codec_dev(codec)); 890 put_device(hda_codec_dev(codec));
889 return 0; 891 return 0;
@@ -3106,6 +3108,7 @@ static int hda_codec_runtime_suspend(struct device *dev)
3106 if (codec_has_clkstop(codec) && codec_has_epss(codec) && 3108 if (codec_has_clkstop(codec) && codec_has_epss(codec) &&
3107 (state & AC_PWRST_CLK_STOP_OK)) 3109 (state & AC_PWRST_CLK_STOP_OK))
3108 snd_hdac_codec_link_down(&codec->core); 3110 snd_hdac_codec_link_down(&codec->core);
3111 snd_hdac_link_power(&codec->core, false);
3109 return 0; 3112 return 0;
3110} 3113}
3111 3114
@@ -3113,6 +3116,7 @@ static int hda_codec_runtime_resume(struct device *dev)
3113{ 3116{
3114 struct hda_codec *codec = dev_to_hda_codec(dev); 3117 struct hda_codec *codec = dev_to_hda_codec(dev);
3115 3118
3119 snd_hdac_link_power(&codec->core, true);
3116 snd_hdac_codec_link_up(&codec->core); 3120 snd_hdac_codec_link_up(&codec->core);
3117 hda_call_codec_resume(codec); 3121 hda_call_codec_resume(codec);
3118 pm_runtime_mark_last_busy(dev); 3122 pm_runtime_mark_last_busy(dev);
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index e0bb6231ff0c..120854ebd054 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -775,9 +775,20 @@ static int azx_get_response(struct hdac_bus *bus, unsigned int addr,
775 return azx_rirb_get_response(bus, addr, res); 775 return azx_rirb_get_response(bus, addr, res);
776} 776}
777 777
778static int azx_link_power(struct hdac_bus *bus, bool enable)
779{
780 struct azx *chip = bus_to_azx(bus);
781
782 if (chip->ops->link_power)
783 return chip->ops->link_power(chip, enable);
784 else
785 return -EINVAL;
786}
787
778static const struct hdac_bus_ops bus_core_ops = { 788static const struct hdac_bus_ops bus_core_ops = {
779 .command = azx_send_cmd, 789 .command = azx_send_cmd,
780 .get_response = azx_get_response, 790 .get_response = azx_get_response,
791 .link_power = azx_link_power,
781}; 792};
782 793
783#ifdef CONFIG_SND_HDA_DSP_LOADER 794#ifdef CONFIG_SND_HDA_DSP_LOADER
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h
index 3c6ebaf033a5..314105cd5061 100644
--- a/sound/pci/hda/hda_controller.h
+++ b/sound/pci/hda/hda_controller.h
@@ -89,6 +89,8 @@ struct hda_controller_ops {
89 struct vm_area_struct *area); 89 struct vm_area_struct *area);
90 /* Check if current position is acceptable */ 90 /* Check if current position is acceptable */
91 int (*position_check)(struct azx *chip, struct azx_dev *azx_dev); 91 int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
92 /* enable/disable the link power */
93 int (*link_power)(struct azx *chip, bool enable);
92}; 94};
93 95
94struct azx_pcm { 96struct azx_pcm {
diff --git a/sound/pci/hda/hda_i915.c b/sound/pci/hda/hda_i915.c
index 3052a2b095f7..d9d079330e55 100644
--- a/sound/pci/hda/hda_i915.c
+++ b/sound/pci/hda/hda_i915.c
@@ -42,10 +42,15 @@ int hda_display_power(struct hda_intel *hda, bool enable)
42 42
43 dev_dbg(&hda->chip.pci->dev, "display power %s\n", 43 dev_dbg(&hda->chip.pci->dev, "display power %s\n",
44 enable ? "enable" : "disable"); 44 enable ? "enable" : "disable");
45 if (enable) 45
46 acomp->ops->get_power(acomp->dev); 46 if (enable) {
47 else 47 if (!hda->i915_power_refcount++)
48 acomp->ops->put_power(acomp->dev); 48 acomp->ops->get_power(acomp->dev);
49 } else {
50 WARN_ON(!hda->i915_power_refcount);
51 if (!--hda->i915_power_refcount)
52 acomp->ops->put_power(acomp->dev);
53 }
49 54
50 return 0; 55 return 0;
51} 56}
@@ -189,6 +194,11 @@ out_err:
189int hda_i915_exit(struct hda_intel *hda) 194int hda_i915_exit(struct hda_intel *hda)
190{ 195{
191 struct device *dev = &hda->chip.pci->dev; 196 struct device *dev = &hda->chip.pci->dev;
197 struct i915_audio_component *acomp = &hda->audio_component;
198
199 WARN_ON(hda->i915_power_refcount);
200 if (hda->i915_power_refcount > 0 && acomp->ops)
201 acomp->ops->put_power(acomp->dev);
192 202
193 component_master_del(dev, &hda_component_master_ops); 203 component_master_del(dev, &hda_component_master_ops);
194 204
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c212f13e1721..5aa5cfa517aa 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -543,6 +543,14 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
543 return 0; 543 return 0;
544} 544}
545 545
546/* Enable/disable i915 display power for the link */
547static int azx_intel_link_power(struct azx *chip, bool enable)
548{
549 struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
550
551 return hda_display_power(hda, enable);
552}
553
546/* 554/*
547 * Check whether the current DMA position is acceptable for updating 555 * Check whether the current DMA position is acceptable for updating
548 * periods. Returns non-zero if it's OK. 556 * periods. Returns non-zero if it's OK.
@@ -809,7 +817,8 @@ static int azx_suspend(struct device *dev)
809 817
810 if (chip->msi) 818 if (chip->msi)
811 pci_disable_msi(chip->pci); 819 pci_disable_msi(chip->pci);
812 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 820 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
821 && hda->need_i915_power)
813 hda_display_power(hda, false); 822 hda_display_power(hda, false);
814 return 0; 823 return 0;
815} 824}
@@ -829,7 +838,8 @@ static int azx_resume(struct device *dev)
829 if (chip->disabled || hda->init_failed) 838 if (chip->disabled || hda->init_failed)
830 return 0; 839 return 0;
831 840
832 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 841 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
842 && hda->need_i915_power) {
833 hda_display_power(hda, true); 843 hda_display_power(hda, true);
834 haswell_set_bclk(hda); 844 haswell_set_bclk(hda);
835 } 845 }
@@ -872,7 +882,8 @@ static int azx_runtime_suspend(struct device *dev)
872 azx_stop_chip(chip); 882 azx_stop_chip(chip);
873 azx_enter_link_reset(chip); 883 azx_enter_link_reset(chip);
874 azx_clear_irq_pending(chip); 884 azx_clear_irq_pending(chip);
875 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 885 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
886 && hda->need_i915_power)
876 hda_display_power(hda, false); 887 hda_display_power(hda, false);
877 888
878 return 0; 889 return 0;
@@ -897,7 +908,8 @@ static int azx_runtime_resume(struct device *dev)
897 if (!azx_has_pm_runtime(chip)) 908 if (!azx_has_pm_runtime(chip))
898 return 0; 909 return 0;
899 910
900 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 911 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
912 && hda->need_i915_power) {
901 hda_display_power(hda, true); 913 hda_display_power(hda, true);
902 haswell_set_bclk(hda); 914 haswell_set_bclk(hda);
903 } 915 }
@@ -1118,7 +1130,8 @@ static int azx_free(struct azx *chip)
1118 release_firmware(chip->fw); 1130 release_firmware(chip->fw);
1119#endif 1131#endif
1120 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 1132 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
1121 hda_display_power(hda, false); 1133 if (hda->need_i915_power)
1134 hda_display_power(hda, false);
1122 hda_i915_exit(hda); 1135 hda_i915_exit(hda);
1123 } 1136 }
1124 kfree(hda); 1137 kfree(hda);
@@ -1789,6 +1802,7 @@ static const struct hda_controller_ops pci_hda_ops = {
1789 .substream_free_pages = substream_free_pages, 1802 .substream_free_pages = substream_free_pages,
1790 .pcm_mmap_prepare = pcm_mmap_prepare, 1803 .pcm_mmap_prepare = pcm_mmap_prepare,
1791 .position_check = azx_position_check, 1804 .position_check = azx_position_check,
1805 .link_power = azx_intel_link_power,
1792}; 1806};
1793 1807
1794static int azx_probe(struct pci_dev *pci, 1808static int azx_probe(struct pci_dev *pci,
@@ -1882,17 +1896,28 @@ static int azx_probe_continue(struct azx *chip)
1882 int err; 1896 int err;
1883 1897
1884 hda->probe_continued = 1; 1898 hda->probe_continued = 1;
1885 /* Request power well for Haswell HDA controller and codec */ 1899
1900 /* Request display power well for the HDA controller or codec. For
1901 * Haswell/Broadwell, both the display HDA controller and codec need
1902 * this power. For other platforms, like Baytrail/Braswell, only the
1903 * display codec needs the power and it can be released after probe.
1904 */
1886 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 1905 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
1906 /* Baytral/Braswell controllers don't need this power */
1907 if (pci->device != 0x0f04 && pci->device != 0x2284)
1908 hda->need_i915_power = 1;
1909
1910
1887#ifdef CONFIG_SND_HDA_I915 1911#ifdef CONFIG_SND_HDA_I915
1888 err = hda_i915_init(hda); 1912 err = hda_i915_init(hda);
1889 if (err < 0) 1913 if (err < 0)
1890 goto out_free; 1914 goto i915_power_fail;
1915
1891 err = hda_display_power(hda, true); 1916 err = hda_display_power(hda, true);
1892 if (err < 0) { 1917 if (err < 0) {
1893 dev_err(chip->card->dev, 1918 dev_err(chip->card->dev,
1894 "Cannot turn on display power on i915\n"); 1919 "Cannot turn on display power on i915\n");
1895 goto out_free; 1920 goto i915_power_fail;
1896 } 1921 }
1897#endif 1922#endif
1898 } 1923 }
@@ -1939,6 +1964,11 @@ static int azx_probe_continue(struct azx *chip)
1939 pm_runtime_put_noidle(&pci->dev); 1964 pm_runtime_put_noidle(&pci->dev);
1940 1965
1941out_free: 1966out_free:
1967 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL
1968 && !hda->need_i915_power)
1969 hda_display_power(hda, false);
1970
1971i915_power_fail:
1942 if (err < 0) 1972 if (err < 0)
1943 hda->init_failed = 1; 1973 hda->init_failed = 1;
1944 complete_all(&hda->probe_wait); 1974 complete_all(&hda->probe_wait);
diff --git a/sound/pci/hda/hda_intel.h b/sound/pci/hda/hda_intel.h
index 206989878bc6..505f987eb4a2 100644
--- a/sound/pci/hda/hda_intel.h
+++ b/sound/pci/hda/hda_intel.h
@@ -45,7 +45,9 @@ struct hda_intel {
45 struct dev_pm_domain hdmi_pm_domain; 45 struct dev_pm_domain hdmi_pm_domain;
46 46
47 /* i915 component interface */ 47 /* i915 component interface */
48 bool need_i915_power:1; /* the hda controller needs i915 power */
48 struct i915_audio_component audio_component; 49 struct i915_audio_component audio_component;
50 int i915_power_refcount;
49}; 51};
50 52
51#ifdef CONFIG_SND_HDA_I915 53#ifdef CONFIG_SND_HDA_I915
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d925742624ee..e8d847819d71 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2335,6 +2335,15 @@ static int patch_generic_hdmi(struct hda_codec *codec)
2335 intel_haswell_fixup_enable_dp12(codec); 2335 intel_haswell_fixup_enable_dp12(codec);
2336 } 2336 }
2337 2337
2338 /* For Valleyview/Cherryview, only the display codec is in the display
2339 * power well and can use link_power ops to request/release the power.
2340 * For Haswell/Broadwell, the controller is also in the power well and
2341 * can cover the codec power request, and so need not set this flag.
2342 * For previous platforms, there is no such power well feature.
2343 */
2344 if (is_valleyview_plus(codec))
2345 codec->core.link_power_control = 1;
2346
2338 if (is_haswell_plus(codec) || is_valleyview_plus(codec)) 2347 if (is_haswell_plus(codec) || is_valleyview_plus(codec))
2339 codec->depop_delay = 0; 2348 codec->depop_delay = 0;
2340 2349