Commit 175bd420 authored by Jesse Barnes's avatar Jesse Barnes Committed by Keith Packard

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: default avatarDaniel Vetter <daniel@ffwll.ch>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
parent b840d907
...@@ -181,6 +181,7 @@ struct intel_plane { ...@@ -181,6 +181,7 @@ struct intel_plane {
struct drm_plane base; struct drm_plane base;
enum pipe pipe; enum pipe pipe;
struct drm_i915_gem_object *obj; struct drm_i915_gem_object *obj;
bool primary_disabled;
int max_downscale; int max_downscale;
u32 lut_r[1024], lut_g[1024], lut_b[1024]; u32 lut_r[1024], lut_g[1024], lut_b[1024];
void (*update_plane)(struct drm_plane *plane, void (*update_plane)(struct drm_plane *plane,
......
...@@ -256,6 +256,28 @@ snb_disable_plane(struct drm_plane *plane) ...@@ -256,6 +256,28 @@ snb_disable_plane(struct drm_plane *plane)
POSTING_READ(DVSSURF(pipe)); POSTING_READ(DVSSURF(pipe));
} }
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 static int
intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y, 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,9 +364,23 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
intel_plane->obj = obj; 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, intel_plane->update_plane(plane, fb, obj, crtc_x, crtc_y,
crtc_w, crtc_h, x, y, src_w, src_h); 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 */ /* Unpin old obj after new one is active to avoid ugliness */
if (old_obj) { if (old_obj) {
/* /*
...@@ -374,6 +410,11 @@ intel_disable_plane(struct drm_plane *plane) ...@@ -374,6 +410,11 @@ intel_disable_plane(struct drm_plane *plane)
struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_plane *intel_plane = to_intel_plane(plane);
int ret = 0; int ret = 0;
if (intel_plane->primary_disabled) {
intel_enable_primary(plane->crtc);
intel_plane->primary_disabled = false;
}
intel_plane->disable_plane(plane); intel_plane->disable_plane(plane);
if (!intel_plane->obj) if (!intel_plane->obj)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment