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
181181 struct drm_plane base;
182182 enum pipe pipe;
183183 struct drm_i915_gem_object *obj;
184+ bool primary_disabled;
184185 int max_downscale;
185186 u32 lut_r[1024], lut_g[1024], lut_b[1024];
186187 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
256256 POSTING_READ(DVSSURF(pipe));
257257 }
258258
259+static void
260+intel_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+
270+static void
271+intel_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+
259281 static int
260282 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
261283 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
342364
343365 intel_plane->obj = obj;
344366
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+
345376 intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
346377 crtc_w, crtc_h, x, y, src_w, src_h);
347378
379+ if (disable_primary) {
380+ intel_disable_primary(crtc);
381+ intel_plane->primary_disabled = true;
382+ }
383+
348384 /* Unpin old obj after new one is active to avoid ugliness */
349385 if (old_obj) {
350386 /*
@@ -374,6 +410,11 @@ intel_disable_plane(struct drm_plane *plane) · 23 unmodified lines
374410 struct intel_plane *intel_plane = to_intel_plane(plane);
375411 int ret = 0;
376412
413+ if (intel_plane->primary_disabled) {
414+ intel_enable_primary(plane->crtc);
415+ intel_plane->primary_disabled = false;
416+ }
417+
377418 intel_plane->disable_plane(plane);
378419
379420 if (!intel_plane->obj)