diff mbox

[1/1] HDA: Intel: enable automatic runtime pm for HDMI codecs by default

Message ID 1433837710-5087-1-git-send-email-han.lu@intel.com (mailing list archive)
State Accepted
Delegated to: Takashi Iwai
Headers show

Commit Message

han.lu@intel.com June 9, 2015, 8:15 a.m. UTC
From: "Lu, Han" <han.lu@intel.com>

Enable runtime PM of the HDMI audio codec on the latest Intel platforms.
So the HD-A controller or HDMI codec can suspend when idle timeout by
default and release the GFX power well.
The patch influences HSW/BDW/BYT/BSW/SKL. Eariler platforms and third
party analog codecs will not be influenced.

Signed-off-by: Lu, Han <han.lu@intel.com>

Comments

Takashi Iwai June 9, 2015, 8:35 a.m. UTC | #1
At Tue,  9 Jun 2015 16:15:10 +0800,
han.lu@intel.com wrote:
> 
> From: "Lu, Han" <han.lu@intel.com>
> 
> Enable runtime PM of the HDMI audio codec on the latest Intel platforms.
> So the HD-A controller or HDMI codec can suspend when idle timeout by
> default and release the GFX power well.
> The patch influences HSW/BDW/BYT/BSW/SKL. Eariler platforms and third
> party analog codecs will not be influenced.
> 
> Signed-off-by: Lu, Han <han.lu@intel.com>
> 
> diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
> index 54380ed..804ec24 100644
> --- a/sound/pci/hda/hda_codec.c
> +++ b/sound/pci/hda/hda_codec.c
> @@ -3491,10 +3491,13 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
>  EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
>  
>  #ifdef CONFIG_PM
> -static void codec_set_power_save(struct hda_codec *codec, int delay)
> +static void codec_set_power_save(struct hda_codec *codec, int delay, bool force)
>  {
>  	struct device *dev = hda_codec_dev(codec);
>  
> +	if (force && delay == 0 && codec->auto_runtime_pm)
> +		delay = 3000;
> +

IMO, we can drop the force check.  If a user really wants to disable
runtime PM for the codec, they can adjust directly via codec sysfs
instead of module parameter.


thanks,

Takashi

>  	if (delay > 0) {
>  		pm_runtime_set_autosuspend_delay(dev, delay);
>  		pm_runtime_use_autosuspend(dev);
> @@ -3511,15 +3514,16 @@ static void codec_set_power_save(struct hda_codec *codec, int delay)
>   * snd_hda_set_power_save - reprogram autosuspend for the given delay
>   * @bus: HD-audio bus
>   * @delay: autosuspend delay in msec, 0 = off
> + * @force: force to enable autosuspend
>   *
>   * Synchronize the runtime PM autosuspend state from the power_save option.
>   */
> -void snd_hda_set_power_save(struct hda_bus *bus, int delay)
> +void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force)
>  {
>  	struct hda_codec *c;
>  
>  	list_for_each_codec(c, bus)
> -		codec_set_power_save(c, delay);
> +		codec_set_power_save(c, delay, force);
>  }
>  EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
>  
> diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
> index 6c57258..9f525ba 100644
> --- a/sound/pci/hda/hda_codec.h
> +++ b/sound/pci/hda/hda_codec.h
> @@ -251,6 +251,7 @@ struct hda_codec {
>  	unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
>  	unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
>  	unsigned int power_save_node:1; /* advanced PM for each widget */
> +	unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
>  #ifdef CONFIG_PM
>  	unsigned long power_on_acct;
>  	unsigned long power_off_acct;
> @@ -482,10 +483,11 @@ const char *snd_hda_get_jack_location(u32 cfg);
>  #define snd_hda_power_down(codec)	snd_hdac_power_down(&(codec)->core)
>  #define snd_hda_power_down_pm(codec)	snd_hdac_power_down_pm(&(codec)->core)
>  #ifdef CONFIG_PM
> -void snd_hda_set_power_save(struct hda_bus *bus, int delay);
> +void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force);
>  void snd_hda_update_power_acct(struct hda_codec *codec);
>  #else
> -static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
> +static inline void
> +snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force) {}
>  #endif
>  
>  #ifdef CONFIG_SND_HDA_PATCH_LOADER
> diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
> index 7933fb0..11d52e5 100644
> --- a/sound/pci/hda/hda_intel.c
> +++ b/sound/pci/hda/hda_intel.c
> @@ -797,7 +797,7 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
>  		chip = &hda->chip;
>  		if (!hda->probe_continued || chip->disabled)
>  			continue;
> -		snd_hda_set_power_save(&chip->bus, power_save * 1000);
> +		snd_hda_set_power_save(&chip->bus, power_save * 1000, false);
>  	}
>  	mutex_unlock(&card_list_lock);
>  	return 0;
> @@ -2034,7 +2034,7 @@ static int azx_probe_continue(struct azx *chip)
>  
>  	chip->running = 1;
>  	azx_add_card_list(chip);
> -	snd_hda_set_power_save(&chip->bus, power_save * 1000);
> +	snd_hda_set_power_save(&chip->bus, power_save * 1000, true);
>  	if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
>  		pm_runtime_put_noidle(&pci->dev);
>  
> diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
> index 477742c..bec3a37 100644
> --- a/sound/pci/hda/hda_tegra.c
> +++ b/sound/pci/hda/hda_tegra.c
> @@ -518,7 +518,7 @@ static int hda_tegra_probe(struct platform_device *pdev)
>  		goto out_free;
>  
>  	chip->running = 1;
> -	snd_hda_set_power_save(&chip->bus, power_save * 1000);
> +	snd_hda_set_power_save(&chip->bus, power_save * 1000, false);
>  
>  	return 0;
>  
> diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> index 407978b..7941d81 100644
> --- a/sound/pci/hda/patch_hdmi.c
> +++ b/sound/pci/hda/patch_hdmi.c
> @@ -2356,6 +2356,9 @@ static int patch_generic_hdmi(struct hda_codec *codec)
>  		codec->dp_mst = true;
>  	}
>  
> +	if (is_haswell_plus(codec) || is_valleyview_plus(codec))
> +		codec->auto_runtime_pm = 1;
> +
>  	generic_hdmi_init_per_pins(codec);
>  
>  	init_channel_allocations();
> -- 
> 1.9.1
>
han.lu@intel.com June 9, 2015, 8:53 a.m. UTC | #2
Hi Takashi,

Thanks. Please review if my patch v2 is OK.

BR,
Han Lu

> -----Original Message-----
> From: Takashi Iwai [mailto:tiwai@suse.de]
> Sent: Tuesday, June 9, 2015 4:36 PM
> To: Lu, Han
> Cc: Vetter, Daniel; alsa-devel@alsa-project.org
> Subject: Re: [PATCH 1/1] HDA: Intel: enable automatic runtime pm for HDMI
> codecs by default
> 
> At Tue,  9 Jun 2015 16:15:10 +0800,
> han.lu@intel.com wrote:
> >
> > From: "Lu, Han" <han.lu@intel.com>
> >
> > Enable runtime PM of the HDMI audio codec on the latest Intel platforms.
> > So the HD-A controller or HDMI codec can suspend when idle timeout by
> > default and release the GFX power well.
> > The patch influences HSW/BDW/BYT/BSW/SKL. Eariler platforms and third
> > party analog codecs will not be influenced.
> >
> > Signed-off-by: Lu, Han <han.lu@intel.com>
> >
> > diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
> > index 54380ed..804ec24 100644
> > --- a/sound/pci/hda/hda_codec.c
> > +++ b/sound/pci/hda/hda_codec.c
> > @@ -3491,10 +3491,13 @@ int snd_hda_add_new_ctls(struct hda_codec
> > *codec,  EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
> >
> >  #ifdef CONFIG_PM
> > -static void codec_set_power_save(struct hda_codec *codec, int delay)
> > +static void codec_set_power_save(struct hda_codec *codec, int delay,
> > +bool force)
> >  {
> >  	struct device *dev = hda_codec_dev(codec);
> >
> > +	if (force && delay == 0 && codec->auto_runtime_pm)
> > +		delay = 3000;
> > +
> 
> IMO, we can drop the force check.  If a user really wants to disable runtime
> PM for the codec, they can adjust directly via codec sysfs instead of module
> parameter.
> 
> 
> thanks,
> 
> Takashi
> 
> >  	if (delay > 0) {
> >  		pm_runtime_set_autosuspend_delay(dev, delay);
> >  		pm_runtime_use_autosuspend(dev);
> > @@ -3511,15 +3514,16 @@ static void codec_set_power_save(struct
> hda_codec *codec, int delay)
> >   * snd_hda_set_power_save - reprogram autosuspend for the given delay
> >   * @bus: HD-audio bus
> >   * @delay: autosuspend delay in msec, 0 = off
> > + * @force: force to enable autosuspend
> >   *
> >   * Synchronize the runtime PM autosuspend state from the power_save
> option.
> >   */
> > -void snd_hda_set_power_save(struct hda_bus *bus, int delay)
> > +void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool
> > +force)
> >  {
> >  	struct hda_codec *c;
> >
> >  	list_for_each_codec(c, bus)
> > -		codec_set_power_save(c, delay);
> > +		codec_set_power_save(c, delay, force);
> >  }
> >  EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
> >
> > diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
> > index 6c57258..9f525ba 100644
> > --- a/sound/pci/hda/hda_codec.h
> > +++ b/sound/pci/hda/hda_codec.h
> > @@ -251,6 +251,7 @@ struct hda_codec {
> >  	unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
> >  	unsigned int dump_coef:1; /* dump processing coefs in codec proc
> file */
> >  	unsigned int power_save_node:1; /* advanced PM for each widget
> */
> > +	unsigned int auto_runtime_pm:1; /* enable automatic codec
> runtime pm
> > +*/
> >  #ifdef CONFIG_PM
> >  	unsigned long power_on_acct;
> >  	unsigned long power_off_acct;
> > @@ -482,10 +483,11 @@ const char *snd_hda_get_jack_location(u32 cfg);
> >  #define snd_hda_power_down(codec)
> 	snd_hdac_power_down(&(codec)->core)
> >  #define snd_hda_power_down_pm(codec)
> 	snd_hdac_power_down_pm(&(codec)->core)
> >  #ifdef CONFIG_PM
> > -void snd_hda_set_power_save(struct hda_bus *bus, int delay);
> > +void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool
> > +force);
> >  void snd_hda_update_power_acct(struct hda_codec *codec);  #else
> > -static inline void snd_hda_set_power_save(struct hda_bus *bus, int
> > delay) {}
> > +static inline void
> > +snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force) {}
> >  #endif
> >
> >  #ifdef CONFIG_SND_HDA_PATCH_LOADER
> > diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
> > index 7933fb0..11d52e5 100644
> > --- a/sound/pci/hda/hda_intel.c
> > +++ b/sound/pci/hda/hda_intel.c
> > @@ -797,7 +797,7 @@ static int param_set_xint(const char *val, const
> struct kernel_param *kp)
> >  		chip = &hda->chip;
> >  		if (!hda->probe_continued || chip->disabled)
> >  			continue;
> > -		snd_hda_set_power_save(&chip->bus, power_save * 1000);
> > +		snd_hda_set_power_save(&chip->bus, power_save * 1000,
> false);
> >  	}
> >  	mutex_unlock(&card_list_lock);
> >  	return 0;
> > @@ -2034,7 +2034,7 @@ static int azx_probe_continue(struct azx *chip)
> >
> >  	chip->running = 1;
> >  	azx_add_card_list(chip);
> > -	snd_hda_set_power_save(&chip->bus, power_save * 1000);
> > +	snd_hda_set_power_save(&chip->bus, power_save * 1000, true);
> >  	if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
> >  		pm_runtime_put_noidle(&pci->dev);
> >
> > diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
> > index 477742c..bec3a37 100644
> > --- a/sound/pci/hda/hda_tegra.c
> > +++ b/sound/pci/hda/hda_tegra.c
> > @@ -518,7 +518,7 @@ static int hda_tegra_probe(struct platform_device
> *pdev)
> >  		goto out_free;
> >
> >  	chip->running = 1;
> > -	snd_hda_set_power_save(&chip->bus, power_save * 1000);
> > +	snd_hda_set_power_save(&chip->bus, power_save * 1000, false);
> >
> >  	return 0;
> >
> > diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
> > index 407978b..7941d81 100644
> > --- a/sound/pci/hda/patch_hdmi.c
> > +++ b/sound/pci/hda/patch_hdmi.c
> > @@ -2356,6 +2356,9 @@ static int patch_generic_hdmi(struct hda_codec
> *codec)
> >  		codec->dp_mst = true;
> >  	}
> >
> > +	if (is_haswell_plus(codec) || is_valleyview_plus(codec))
> > +		codec->auto_runtime_pm = 1;
> > +
> >  	generic_hdmi_init_per_pins(codec);
> >
> >  	init_channel_allocations();
> > --
> > 1.9.1
> >
diff mbox

Patch

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 54380ed..804ec24 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -3491,10 +3491,13 @@  int snd_hda_add_new_ctls(struct hda_codec *codec,
 EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
 
 #ifdef CONFIG_PM
-static void codec_set_power_save(struct hda_codec *codec, int delay)
+static void codec_set_power_save(struct hda_codec *codec, int delay, bool force)
 {
 	struct device *dev = hda_codec_dev(codec);
 
+	if (force && delay == 0 && codec->auto_runtime_pm)
+		delay = 3000;
+
 	if (delay > 0) {
 		pm_runtime_set_autosuspend_delay(dev, delay);
 		pm_runtime_use_autosuspend(dev);
@@ -3511,15 +3514,16 @@  static void codec_set_power_save(struct hda_codec *codec, int delay)
  * snd_hda_set_power_save - reprogram autosuspend for the given delay
  * @bus: HD-audio bus
  * @delay: autosuspend delay in msec, 0 = off
+ * @force: force to enable autosuspend
  *
  * Synchronize the runtime PM autosuspend state from the power_save option.
  */
-void snd_hda_set_power_save(struct hda_bus *bus, int delay)
+void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force)
 {
 	struct hda_codec *c;
 
 	list_for_each_codec(c, bus)
-		codec_set_power_save(c, delay);
+		codec_set_power_save(c, delay, force);
 }
 EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
 
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 6c57258..9f525ba 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -251,6 +251,7 @@  struct hda_codec {
 	unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
 	unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
 	unsigned int power_save_node:1; /* advanced PM for each widget */
+	unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
 #ifdef CONFIG_PM
 	unsigned long power_on_acct;
 	unsigned long power_off_acct;
@@ -482,10 +483,11 @@  const char *snd_hda_get_jack_location(u32 cfg);
 #define snd_hda_power_down(codec)	snd_hdac_power_down(&(codec)->core)
 #define snd_hda_power_down_pm(codec)	snd_hdac_power_down_pm(&(codec)->core)
 #ifdef CONFIG_PM
-void snd_hda_set_power_save(struct hda_bus *bus, int delay);
+void snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force);
 void snd_hda_update_power_acct(struct hda_codec *codec);
 #else
-static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
+static inline void
+snd_hda_set_power_save(struct hda_bus *bus, int delay, bool force) {}
 #endif
 
 #ifdef CONFIG_SND_HDA_PATCH_LOADER
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 7933fb0..11d52e5 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -797,7 +797,7 @@  static int param_set_xint(const char *val, const struct kernel_param *kp)
 		chip = &hda->chip;
 		if (!hda->probe_continued || chip->disabled)
 			continue;
-		snd_hda_set_power_save(&chip->bus, power_save * 1000);
+		snd_hda_set_power_save(&chip->bus, power_save * 1000, false);
 	}
 	mutex_unlock(&card_list_lock);
 	return 0;
@@ -2034,7 +2034,7 @@  static int azx_probe_continue(struct azx *chip)
 
 	chip->running = 1;
 	azx_add_card_list(chip);
-	snd_hda_set_power_save(&chip->bus, power_save * 1000);
+	snd_hda_set_power_save(&chip->bus, power_save * 1000, true);
 	if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
 		pm_runtime_put_noidle(&pci->dev);
 
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c
index 477742c..bec3a37 100644
--- a/sound/pci/hda/hda_tegra.c
+++ b/sound/pci/hda/hda_tegra.c
@@ -518,7 +518,7 @@  static int hda_tegra_probe(struct platform_device *pdev)
 		goto out_free;
 
 	chip->running = 1;
-	snd_hda_set_power_save(&chip->bus, power_save * 1000);
+	snd_hda_set_power_save(&chip->bus, power_save * 1000, false);
 
 	return 0;
 
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 407978b..7941d81 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2356,6 +2356,9 @@  static int patch_generic_hdmi(struct hda_codec *codec)
 		codec->dp_mst = true;
 	}
 
+	if (is_haswell_plus(codec) || is_valleyview_plus(codec))
+		codec->auto_runtime_pm = 1;
+
 	generic_hdmi_init_per_pins(codec);
 
 	init_channel_allocations();