aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-12-13 16:19:39 -0500
committerKeith Packard <keithp@keithp.com>2012-01-03 12:31:10 -0500
commit175bd4204e069f8bd855ca3dcf70a78db4410936 (patch)
tree4f172f5f12853ff22d86d66bb3fe3c2ec3405f81 /drivers/gpu
parentb840d907fcf6d5d5ef91af4518b3dab3a5da0f75 (diff)
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 Reviewed-by: Daniel Vetter <daniel@ffwll.ch> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c41
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 a6e2f0d865b1..ed65121989bf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -181,6 +181,7 @@ struct intel_plane {
181 struct drm_plane base; 181 struct drm_plane base;
182 enum pipe pipe; 182 enum pipe pipe;
183 struct drm_i915_gem_object *obj; 183 struct drm_i915_gem_object *obj;
184 bool primary_disabled;
184 int max_downscale; 185 int max_downscale;
185 u32 lut_r[1024], lut_g[1024], lut_b[1024]; 186 u32 lut_r[1024], lut_g[1024], lut_b[1024];
186 void (*update_plane)(struct drm_plane *plane, 187 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 c77717db635b..6994e06f8975 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -256,6 +256,28 @@ snb_disable_plane(struct drm_plane *plane)
256 POSTING_READ(DVSSURF(pipe)); 256 POSTING_READ(DVSSURF(pipe));
257} 257}
258 258
259static void
260intel_enable_primary(struct drm_crtc *crtc)
261{
262 struct drm_device *dev = crtc->dev;
263 struct drm_i915_private *dev_priv = dev->dev_private;
264 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
265 int reg = DSPCNTR(intel_crtc->plane);
266
267 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
268}
269
270static void
271intel_disable_primary(struct drm_crtc *crtc)
272{
273 struct drm_device *dev = crtc->dev;
274 struct drm_i915_private *dev_priv = dev->dev_private;
275 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
276 int reg = DSPCNTR(intel_crtc->plane);
277
278 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
279}
280
259static int 281static int
260intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 282intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
261 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 283 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -342,9 +364,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
342 364
343 intel_plane->obj = obj; 365 intel_plane->obj = obj;
344 366
367 /*
368 * Be sure to re-enable the primary before the sprite is no longer
369 * covering it fully.
370 */
371 if (!disable_primary && intel_plane->primary_disabled) {
372 intel_enable_primary(crtc);
373 intel_plane->primary_disabled = false;
374 }
375
345 intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y, 376 intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
346 crtc_w, crtc_h, x, y, src_w, src_h); 377 crtc_w, crtc_h, x, y, src_w, src_h);
347 378
379 if (disable_primary) {
380 intel_disable_primary(crtc);
381 intel_plane->primary_disabled = true;
382 }
383
348 /* Unpin old obj after new one is active to avoid ugliness */ 384 /* Unpin old obj after new one is active to avoid ugliness */
349 if (old_obj) { 385 if (old_obj) {
350 /* 386 /*
@@ -374,6 +410,11 @@ intel_disable_plane(struct drm_plane *plane)
374 struct intel_plane *intel_plane = to_intel_plane(plane); 410 struct intel_plane *intel_plane = to_intel_plane(plane);
375 int ret = 0; 411 int ret = 0;
376 412
413 if (intel_plane->primary_disabled) {
414 intel_enable_primary(plane->crtc);
415 intel_plane->primary_disabled = false;
416 }
417
377 intel_plane->disable_plane(plane); 418 intel_plane->disable_plane(plane);
378 419
379 if (!intel_plane->obj) 420 if (!intel_plane->obj)