diff mbox

[3/7] drm/i915: add intel_display_power_enabled

Message ID 1366408498-3791-1-git-send-email-przanoni@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Paulo Zanoni April 19, 2013, 9:54 p.m. UTC
From: Paulo Zanoni <paulo.r.zanoni@intel.com>

This should replace intel_using_power_well. The idea is that we're
adding the requested power domain as an argument, so this might enable
the code to look less platform-specific and also allows us to easily
add new domains in case we need.

v2: Add more domains to enum intel_display_power_domain

Requested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |   14 ++++++++++++++
 drivers/gpu/drm/i915/intel_display.c |   16 +++++++++++-----
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
 drivers/gpu/drm/i915/intel_pm.c      |   27 ++++++++++++++++++++++-----
 4 files changed, 49 insertions(+), 11 deletions(-)

I hope this reflects the discussions both via email and IRC.

Comments

Daniel Vetter April 20, 2013, 1:33 p.m. UTC | #1
On Fri, Apr 19, 2013 at 11:54 PM, Paulo Zanoni <przanoni@gmail.com> wrote:
> From: Paulo Zanoni <paulo.r.zanoni@intel.com>
>
> This should replace intel_using_power_well. The idea is that we're
> adding the requested power domain as an argument, so this might enable
> the code to look less platform-specific and also allows us to easily
> add new domains in case we need.
>
> v2: Add more domains to enum intel_display_power_domain
>
> Requested-by: Daniel Vetter <daniel.vetter@ffwll.ch>
> Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h      |   14 ++++++++++++++
>  drivers/gpu/drm/i915/intel_display.c |   16 +++++++++++-----
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++-
>  drivers/gpu/drm/i915/intel_pm.c      |   27 ++++++++++++++++++++++-----
>  4 files changed, 49 insertions(+), 11 deletions(-)
>
> I hope this reflects the discussions both via email and IRC.
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
> index bd2d7f1..c79622a 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -88,6 +88,20 @@ enum port {
>  };
>  #define port_name(p) ((p) + 'A')
>
> +enum intel_display_power_domain {
> +       POWER_DOMAIN_PIPE_A_PANEL_FITTER,
> +       POWER_DOMAIN_PIPE_A,
> +       POWER_DOMAIN_PIPE_B,
> +       POWER_DOMAIN_PIPE_C,
> +       POWER_DOMAIN_TRANSCODER_A,
> +       POWER_DOMAIN_TRANSCODER_B,
> +       POWER_DOMAIN_TRANSCODER_C,
> +       POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF,
> +};
> +
> +#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
> +#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A)

I think if we go this way we should have a macro (and different
domains) for pfit A/B/C, too. Since now we have imo an ugly middle
ground ....
-Daniel
--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index bd2d7f1..c79622a 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -88,6 +88,20 @@  enum port {
 };
 #define port_name(p) ((p) + 'A')
 
+enum intel_display_power_domain {
+	POWER_DOMAIN_PIPE_A_PANEL_FITTER,
+	POWER_DOMAIN_PIPE_A,
+	POWER_DOMAIN_PIPE_B,
+	POWER_DOMAIN_PIPE_C,
+	POWER_DOMAIN_TRANSCODER_A,
+	POWER_DOMAIN_TRANSCODER_B,
+	POWER_DOMAIN_TRANSCODER_C,
+	POWER_DOMAIN_TRANSCODER_EDP = POWER_DOMAIN_TRANSCODER_A + 0xF,
+};
+
+#define POWER_DOMAIN_PIPE(pipe) ((pipe) + POWER_DOMAIN_PIPE_A)
+#define POWER_DOMAIN_TRANSCODER(tran) ((tran) + POWER_DOMAIN_TRANSCODER_A)
+
 enum hpd_pin {
 	HPD_NONE = 0,
 	HPD_PORT_A = HPD_NONE, /* PORT_A is internal */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3c90605..bf80942 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1215,8 +1215,8 @@  void assert_pipe(struct drm_i915_private *dev_priv,
 	if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
 		state = true;
 
-	if (!intel_using_power_well(dev_priv->dev) &&
-	    cpu_transcoder != TRANSCODER_EDP) {
+	if (!intel_display_power_enabled(dev_priv->dev,
+				POWER_DOMAIN_TRANSCODER(cpu_transcoder))) {
 		cur_state = false;
 	} else {
 		reg = PIPECONF(cpu_transcoder);
@@ -3597,6 +3597,7 @@  static void haswell_crtc_disable(struct drm_crtc *crtc)
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
 	enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
+	enum intel_display_power_domain domain;
 
 	if (!intel_crtc->active)
 		return;
@@ -3622,7 +3623,12 @@  static void haswell_crtc_disable(struct drm_crtc *crtc)
 	/* XXX: Once we have proper panel fitter state tracking implemented with
 	 * hardware state read/check support we should switch to only disable
 	 * the panel fitter when we know it's used. */
-	if (intel_using_power_well(dev)) {
+	if (pipe == PIPE_A)
+		domain = POWER_DOMAIN_PIPE_A_PANEL_FITTER;
+	else
+		domain = POWER_DOMAIN_PIPE(pipe);
+
+	if (intel_display_power_enabled(dev, domain)) {
 		I915_WRITE(PF_CTL(pipe), 0);
 		I915_WRITE(PF_WIN_SZ(pipe), 0);
 	}
@@ -5981,8 +5987,8 @@  static bool haswell_get_pipe_config(struct intel_crtc *crtc,
 	enum transcoder cpu_transcoder = crtc->config.cpu_transcoder;
 	uint32_t tmp;
 
-	if (!intel_using_power_well(dev_priv->dev) &&
-	    cpu_transcoder != TRANSCODER_EDP)
+	if (!intel_display_power_enabled(dev,
+			POWER_DOMAIN_TRANSCODER(cpu_transcoder)))
 		return false;
 
 	tmp = I915_READ(PIPECONF(cpu_transcoder));
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c20201d..d82cef8 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -721,7 +721,8 @@  extern void intel_update_fbc(struct drm_device *dev);
 extern void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
 extern void intel_gpu_ips_teardown(void);
 
-extern bool intel_using_power_well(struct drm_device *dev);
+extern bool intel_display_power_enabled(struct drm_device *dev,
+					enum intel_display_power_domain domain);
 extern void intel_init_power_well(struct drm_device *dev);
 extern void intel_set_power_well(struct drm_device *dev, bool enable);
 extern void intel_enable_gt_powersave(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 2557926..4e20ba7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4287,15 +4287,32 @@  void intel_init_clock_gating(struct drm_device *dev)
  * enable it, so check if it's enabled and also check if we've requested it to
  * be enabled.
  */
-bool intel_using_power_well(struct drm_device *dev)
+bool intel_display_power_enabled(struct drm_device *dev,
+				 enum intel_display_power_domain domain)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool power_well_enabled;
 
-	if (IS_HASWELL(dev))
-		return I915_READ(HSW_PWR_WELL_DRIVER) ==
-		       (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE);
-	else
+	if (!HAS_POWER_WELL(dev))
+		return true;
+
+	power_well_enabled = I915_READ(HSW_PWR_WELL_DRIVER) ==
+			     (HSW_PWR_WELL_ENABLE | HSW_PWR_WELL_STATE);
+
+	switch (domain) {
+	case POWER_DOMAIN_PIPE_A:
+	case POWER_DOMAIN_TRANSCODER_EDP:
 		return true;
+	case POWER_DOMAIN_PIPE_A_PANEL_FITTER:
+	case POWER_DOMAIN_PIPE_B:
+	case POWER_DOMAIN_PIPE_C:
+	case POWER_DOMAIN_TRANSCODER_A:
+	case POWER_DOMAIN_TRANSCODER_B:
+	case POWER_DOMAIN_TRANSCODER_C:
+		return power_well_enabled;
+	default:
+		BUG();
+	}
 }
 
 void intel_set_power_well(struct drm_device *dev, bool enable)