[Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
To save power when the sprite is full screen, we can disable the primary plane on the same pipe. Track the sprite status and enable/disable the primary opportunistically. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_drv.h|3 ++ drivers/gpu/drm/i915/intel_sprite.c | 67 +++ 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 68ef060..4ea3f68 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -180,6 +180,7 @@ struct intel_plane { struct drm_plane base; enum pipe pipe; struct drm_i915_gem_object *obj; + bool primary_disabled; int max_downscale; u32 lut_r[1024], lut_g[1024], lut_b[1024]; void (*update_plane)(struct drm_plane *plane, @@ -192,6 +193,8 @@ struct intel_plane { void (*disable_plane)(struct drm_plane *plane); int (*update_destkey)(struct drm_plane *plane, u32 value); u32 (*get_destkey)(struct drm_plane *plane); + void (*enable_primary)(struct drm_crtc *crtc); + void (*disable_primary)(struct drm_crtc *crtc); }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b470e9b..f63e2a3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -49,6 +49,28 @@ */ static void +ivb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +ivb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -181,6 +203,28 @@ ivb_get_destkey(struct drm_plane *plane) } static void +snb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +snb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -394,9 +438,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_plane->obj = obj; + /* +* Be sure to re-enable the primary before the sprite is no longer +* covering it fully. +*/ + if (!disable_primary && intel_plane->primary_disabled) { + intel_plane->enable_primary(crtc); + intel_plane->primary_disabled = false; + } + intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, x, y, src_w, src_h); + if (disable_primary) { + intel_plane->disable_primary(crtc); + intel_plane->primary_disabled = true; + } + /* Unpin old obj after new one is active to avoid ugliness */ if (old_obj) { /* @@ -427,6 +485,11 @@ intel_disable_plane(struct drm_plane *plane) struct intel_plane *intel_plane = to_intel_plane(plane); int ret = 0; + if (intel_plane->primary_disabled) { + intel_plane->enable_primary(plane->crtc); + intel_plane->primary_disabled = false; + } + intel_plane->disable_plane(plane); if (!intel_plane->obj) @@ -550,12 +613,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) intel_plane->disable_plane = snb_disable_plane; intel_plane->update_destkey = snb_update_destkey; intel_plane->get_destkey = snb_get_destkey; + intel_plane->enable_primary = ivb_enable_primary; + intel_plane->disable_primary = iv
[Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
To save power when the sprite is full screen, we can disable the primary plane on the same pipe. Track the sprite status and enable/disable the primary opportunistically. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_drv.h|3 ++ drivers/gpu/drm/i915/intel_sprite.c | 67 +++ 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 68ef060..4ea3f68 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -180,6 +180,7 @@ struct intel_plane { struct drm_plane base; enum pipe pipe; struct drm_i915_gem_object *obj; + bool primary_disabled; int max_downscale; u32 lut_r[1024], lut_g[1024], lut_b[1024]; void (*update_plane)(struct drm_plane *plane, @@ -192,6 +193,8 @@ struct intel_plane { void (*disable_plane)(struct drm_plane *plane); int (*update_destkey)(struct drm_plane *plane, u32 value); u32 (*get_destkey)(struct drm_plane *plane); + void (*enable_primary)(struct drm_crtc *crtc); + void (*disable_primary)(struct drm_crtc *crtc); }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index b470e9b..f63e2a3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -49,6 +49,28 @@ */ static void +ivb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +ivb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -181,6 +203,28 @@ ivb_get_destkey(struct drm_plane *plane) } static void +snb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +snb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, struct drm_i915_gem_object *obj, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -394,9 +438,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_plane->obj = obj; + /* +* Be sure to re-enable the primary before the sprite is no longer +* covering it fully. +*/ + if (!disable_primary && intel_plane->primary_disabled) { + intel_plane->enable_primary(crtc); + intel_plane->primary_disabled = false; + } + intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, x, y, src_w, src_h); + if (disable_primary) { + intel_plane->disable_primary(crtc); + intel_plane->primary_disabled = true; + } + /* Unpin old obj after new one is active to avoid ugliness */ if (old_obj) { /* @@ -427,6 +485,11 @@ intel_disable_plane(struct drm_plane *plane) struct intel_plane *intel_plane = to_intel_plane(plane); int ret = 0; + if (intel_plane->primary_disabled) { + intel_plane->enable_primary(plane->crtc); + intel_plane->primary_disabled = false; + } + intel_plane->disable_plane(plane); if (!intel_plane->obj) @@ -550,12 +613,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) intel_plane->disable_plane = snb_disable_plane; intel_plane->update_destkey = snb_update_destkey; intel_plane->get_destkey = snb_get_destkey; + intel_plane->enable_primary = ivb_enable_primary; + intel_plane->disable_primary = iv
[Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
To save power when the sprite is full screen, we can disable the primary plane on the same pipe. Track the sprite status and enable/disable the primary opportunistically. v2: remove primary plane enable/disable hooks; they're identical Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_drv.h|1 + drivers/gpu/drm/i915/intel_sprite.c | 41 +++ 2 files changed, 42 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e0407cd..0340b4c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -180,6 +180,7 @@ struct intel_plane { struct drm_plane base; enum pipe pipe; struct drm_i915_gem_object *obj; + bool primary_disabled; int max_downscale; u32 lut_r[1024], lut_g[1024], lut_b[1024]; void (*update_plane)(struct drm_plane *plane, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index a51edc9..976eee3 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -329,6 +329,28 @@ snb_get_destkey(struct drm_plane *plane) return value; } +static void +intel_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +intel_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + static int intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, @@ -415,9 +437,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_plane->obj = obj; + /* +* Be sure to re-enable the primary before the sprite is no longer +* covering it fully. +*/ + if (!disable_primary && intel_plane->primary_disabled) { + intel_enable_primary(crtc); + intel_plane->primary_disabled = false; + } + intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, crtc_w, crtc_h, x, y, src_w, src_h); + if (disable_primary) { + intel_disable_primary(crtc); + intel_plane->primary_disabled = true; + } + /* Unpin old obj after new one is active to avoid ugliness */ if (old_obj) { /* @@ -447,6 +483,11 @@ intel_disable_plane(struct drm_plane *plane) struct intel_plane *intel_plane = to_intel_plane(plane); int ret = 0; + if (intel_plane->primary_disabled) { + intel_enable_primary(plane->crtc); + intel_plane->primary_disabled = false; + } + intel_plane->disable_plane(plane); if (!intel_plane->obj) -- 1.7.4.1 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
[Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
To save power when the sprite is full screen, we can disable the primary plane on the same pipe. Track the sprite status and enable/disable the primary opportunistically. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_drv.h|3 ++ drivers/gpu/drm/i915/intel_sprite.c | 67 +++ 2 files changed, 70 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b0081d2..d534e1e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -180,6 +180,7 @@ struct intel_plane { struct drm_plane base; enum pipe pipe; struct drm_i915_gem_object *obj; + bool primary_disabled; int max_downscale; u32 lut_r[1024], lut_g[1024], lut_b[1024]; void (*update_plane)(struct drm_plane *plane, @@ -191,6 +192,8 @@ struct intel_plane { void (*disable_plane)(struct drm_plane *plane); int (*update_destkey)(struct drm_plane *plane, u32 value); u32 (*get_destkey)(struct drm_plane *plane); + void (*enable_primary)(struct drm_crtc *crtc); + void (*disable_primary)(struct drm_crtc *crtc); }; #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 7c6c6c7..384a4a7 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -48,6 +48,28 @@ */ static void +ivb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +ivb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void ivb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, unsigned long start, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -180,6 +202,28 @@ ivb_get_destkey(struct drm_plane *plane) } static void +snb_enable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE); +} + +static void +snb_disable_primary(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); + int reg = DSPCNTR(intel_crtc->plane); + + I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE); +} + +static void snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, unsigned long start, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -395,9 +439,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, start = obj->gtt_offset; + /* +* Be sure to re-enable the primary before the sprite is no longer +* covering it fully. +*/ + if (!disable_primary && intel_plane->primary_disabled) { + intel_plane->enable_primary(crtc); + intel_plane->primary_disabled = false; + } + intel_plane->update_plane(plane, fb, start, crtc_x, crtc_y, crtc_w, crtc_h, x, y, src_w, src_h); + if (disable_primary) { + intel_plane->disable_primary(crtc); + intel_plane->primary_disabled = true; + } + /* Unpin old obj after new one is active to avoid ugliness */ if (old_obj) { /* @@ -427,6 +485,11 @@ intel_disable_plane(struct drm_plane *plane) mutex_lock(&dev->struct_mutex); + if (intel_plane->primary_disabled) { + intel_plane->enable_primary(plane->crtc); + intel_plane->primary_disabled = false; + } + intel_plane->disable_plane(plane); if (!intel_plane->obj) @@ -556,12 +619,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe) intel_plane->disable_plane = snb_disable_plane; intel_plane->update_destkey = snb_update_destkey; intel_plane->get_destkey = snb_get_destkey; + intel_plane->enable_primary = ivb_enable_primary; + intel_plane->disable_primary = ivb_disable_primary; } else if (IS_GEN7(dev)) {
Re: [Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
On Mon, Nov 14, 2011 at 21:22, Jesse Barnes wrote: > To save power when the sprite is full screen, we can disable the primary > plane on the same pipe. Track the sprite status and enable/disable the > primary opportunistically. > > Signed-off-by: Jesse Barnes Imo the indirection is overkill because afaics there's no difference. And in my experience this will only get in the way when later hw _really_ needs some abstraction (*cough* intel_ringbuffer.c *cough*. Can we just kill it? -Daniel -- Daniel Vetter daniel.vet...@ffwll.ch - +41 (0) 79 364 57 48 - http://blog.ffwll.ch ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
On Wed, 16 Nov 2011 17:05:50 +0100 Daniel Vetter wrote: > On Mon, Nov 14, 2011 at 21:22, Jesse Barnes wrote: > > To save power when the sprite is full screen, we can disable the primary > > plane on the same pipe. Track the sprite status and enable/disable the > > primary opportunistically. > > > > Signed-off-by: Jesse Barnes > > Imo the indirection is overkill because afaics there's no difference. > And in my experience this will only get in the way when later hw > _really_ needs some abstraction (*cough* intel_ringbuffer.c *cough*. > Can we just kill it? Yeah I can make ivb and snb share at least (and probably ilk), but I *do* have code coming that needs the separation. (At least I'm pretty sure; I'll remove the abstraction if it turns out I don't need it.) Thanks, -- Jesse Barnes, Intel Open Source Technology Center ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx
Re: [Intel-gfx] [PATCH 3/3] drm/i915: track sprite coverage and disable primary plane if possible
On Wed, Dec 07, 2011 at 12:29:23PM -0800, Jesse Barnes wrote: > To save power when the sprite is full screen, we can disable the primary > plane on the same pipe. Track the sprite status and enable/disable the > primary opportunistically. > > v2: remove primary plane enable/disable hooks; they're identical > > Signed-off-by: Jesse Barnes Minor nitpick on patch-splitting: You've left the disable_primary calculations in the 1st patch. But since I didn't notice it there, I can't be that bad ;-) Reviewed-by: Daniel Vetter -- Daniel Vetter Mail: dan...@ffwll.ch Mobile: +41 (0)79 365 57 48 ___ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx