diff mbox

[2/2] drm/i915: runtime PM support for DPMS

Message ID 1400856685-3158-3-git-send-email-przanoni@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paulo Zanoni May 23, 2014, 2:51 p.m. UTC
From: Daniel Vetter <daniel.vetter@ffwll.ch>

Keeping track of the power domains is a bit messy since crtc->active
is currently updated by the platform hooks, but we need to be aware of
which state transition exactly is going on. Maybe we simply need to
shovel all the power domain handling down into platform code to
simplify this. But doing that requires some more auditing since
currently the ->mode_set callbacks still read some random registers
(to e.g. figure out the reference clocks).

Also note that intel_crtc_update_dpms is always call first/last even
for encoders which have their own dpms functions. Hence we really only
need to update this place here.

Being a quick "does it blow up?" run not really tested yet.

v2, made by Paulo:
  - IVB and older are not ready yet for this.

Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

Comments

Daniel Vetter May 25, 2014, 9:07 p.m. UTC | #1
On Fri, May 23, 2014 at 4:51 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Daniel Vetter <daniel.vetter@ffwll.ch>
>
> Keeping track of the power domains is a bit messy since crtc->active
> is currently updated by the platform hooks, but we need to be aware of
> which state transition exactly is going on. Maybe we simply need to
> shovel all the power domain handling down into platform code to
> simplify this. But doing that requires some more auditing since
> currently the ->mode_set callbacks still read some random registers
> (to e.g. figure out the reference clocks).
>
> Also note that intel_crtc_update_dpms is always call first/last even
> for encoders which have their own dpms functions. Hence we really only
> need to update this place here.
>
> Being a quick "does it blow up?" run not really tested yet.
>
> v2, made by Paulo:
>   - IVB and older are not ready yet for this.

I've actually tested this on snb. Not yet tested on byt (due to lack
of hw on my side), but it should also work (as long as the normal
runtime pm works).

So if you want to unblock runtime pm support for dpms I think this
patch is good, but instead we should disallow runtime pm for HAS_DDI
until the wrpll code can cope.
-Daniel

>
> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c | 35 +++++++++++++++++++++++++++++++----
>  1 file changed, 31 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 1ea4fbe..79b4f5f 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -4845,16 +4845,43 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc)
>  {
>         struct drm_device *dev = crtc->dev;
>         struct drm_i915_private *dev_priv = dev->dev_private;
> +       struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>         struct intel_encoder *intel_encoder;
> +       enum intel_display_power_domain domain;
> +       unsigned long domains;
>         bool enable = false;
>
>         for_each_encoder_on_crtc(dev, crtc, intel_encoder)
>                 enable |= intel_encoder->connectors_active;
>
> -       if (enable)
> -               dev_priv->display.crtc_enable(crtc);
> -       else
> -               dev_priv->display.crtc_disable(crtc);
> +       if (enable) {
> +               if (!intel_crtc->active) {
> +
> +                       /* IVB and older still don't support RPM on DPMS. */
> +                       if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) {
> +                               domains = get_crtc_power_domains(crtc);
> +                               for_each_power_domain(domain, domains)
> +                                       intel_display_power_get(dev_priv,
> +                                                               domain);
> +                               intel_crtc->enabled_power_domains = domains;
> +                       }
> +
> +                       dev_priv->display.crtc_enable(crtc);
> +               }
> +       } else {
> +               if (intel_crtc->active) {
> +                       dev_priv->display.crtc_disable(crtc);
> +
> +                       /* IVB and older still don't support RPM on DPMS. */
> +                       if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) {
> +                               domains = intel_crtc->enabled_power_domains;
> +                               for_each_power_domain(domain, domains)
> +                                       intel_display_power_put(dev_priv,
> +                                                               domain);
> +                               intel_crtc->enabled_power_domains = 0;
> +                       }
> +               }
> +       }
>
>         intel_crtc_update_sarea(crtc, enable);
>  }
> --
> 1.9.0
>
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 1ea4fbe..79b4f5f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4845,16 +4845,43 @@  void intel_crtc_update_dpms(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_encoder *intel_encoder;
+	enum intel_display_power_domain domain;
+	unsigned long domains;
 	bool enable = false;
 
 	for_each_encoder_on_crtc(dev, crtc, intel_encoder)
 		enable |= intel_encoder->connectors_active;
 
-	if (enable)
-		dev_priv->display.crtc_enable(crtc);
-	else
-		dev_priv->display.crtc_disable(crtc);
+	if (enable) {
+		if (!intel_crtc->active) {
+
+			/* IVB and older still don't support RPM on DPMS. */
+			if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) {
+				domains = get_crtc_power_domains(crtc);
+				for_each_power_domain(domain, domains)
+					intel_display_power_get(dev_priv,
+								domain);
+				intel_crtc->enabled_power_domains = domains;
+			}
+
+			dev_priv->display.crtc_enable(crtc);
+		}
+	} else {
+		if (intel_crtc->active) {
+			dev_priv->display.crtc_disable(crtc);
+
+			/* IVB and older still don't support RPM on DPMS. */
+			if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) {
+				domains = intel_crtc->enabled_power_domains;
+				for_each_power_domain(domain, domains)
+					intel_display_power_put(dev_priv,
+								domain);
+				intel_crtc->enabled_power_domains = 0;
+			}
+		}
+	}
 
 	intel_crtc_update_sarea(crtc, enable);
 }