History

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

Jesse Barnes committed 14 years ago

Commit 175bd421 parent b840d902 files · +42 −0Browse files

Unified · Split

2 files
  1. drivers/gpu/drm/i915/intel_drv.h +1 −0
  2. drivers/gpu/drm/i915/intel_sprite.c +41 −0
drivers/gpu/drm/i915/intel_drv.h+1−0
@@ -181,6 +181,7 @@ struct intel_plane { · 180 unmodified lines
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,
drivers/gpu/drm/i915/intel_sprite.c+41−0
@@ -256,6 +256,28 @@ snb_disable_plane(struct drm_plane *plane) · 255 unmodified lines
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 int281static 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, · 80 unmodified lines
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) · 23 unmodified lines
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)