Unfortunately this requires a bit of book-keeping to return the
right values for get_colorkey and to set things up correctly
when re-enabling the plane.

Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/i915/intel_drv.h    |    2 ++
 drivers/gpu/drm/i915/intel_sprite.c |   27 +++++++++++++++++++++++----
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 79f8ed6..e935e75 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -220,6 +220,8 @@ struct intel_plane {
        struct drm_i915_gem_object *obj;
        int max_downscale;
        u32 lut_r[1024], lut_g[1024], lut_b[1024];
+       bool restore_ilk_dest_key; /* for a w/a */
+
        void (*update_plane)(struct drm_plane *plane,
                             struct drm_framebuffer *fb,
                             struct drm_i915_gem_object *obj,
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 7644f31..8bcacd5 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -230,6 +230,13 @@ ilk_update_plane(struct drm_plane *plane, struct 
drm_framebuffer *fb,
 
        dvscntr = I915_READ(DVSCNTR(pipe));
 
+       WARN_ON(!(dvscntr & DVS_ENABLE) && (dvscntr && DVS_DEST_KEY));
+
+       if (intel_plane->restore_ilk_dest_key) {
+               dvscntr |= DVS_DEST_KEY;
+               intel_plane->restore_ilk_dest_key = false;
+       }
+
        /* Mask out pixel format bits in case we change it */
        dvscntr &= ~DVS_PIXFORMAT_MASK;
        dvscntr &= ~DVS_RGB_ORDER_XBGR;
@@ -311,8 +318,16 @@ ilk_disable_plane(struct drm_plane *plane)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_plane *intel_plane = to_intel_plane(plane);
        int pipe = intel_plane->pipe;
+       uint32_t tmp;
 
-       I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
+       /* WaDisableSpriteDestColorKey: We need to disable the dest key when
+        * disabling the sprite. */
+       tmp = I915_READ(DVSCNTR(pipe));
+       if (IS_GEN5(dev) &&(tmp & DVS_DEST_KEY))
+               intel_plane->restore_ilk_dest_key = true;
+       tmp &= ~(DVS_ENABLE | DVS_DEST_KEY);
+
+       I915_WRITE(DVSCNTR(pipe), tmp);
        /* Disable the scaler */
        I915_WRITE(DVSSCALE(pipe), 0);
        /* Flush double buffered register updates */
@@ -365,6 +380,7 @@ ilk_update_colorkey(struct drm_plane *plane,
        int ret = 0;
 
        intel_plane = to_intel_plane(plane);
+       intel_plane->restore_ilk_dest_key = false;
 
        I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
        I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
@@ -372,9 +388,12 @@ ilk_update_colorkey(struct drm_plane *plane,
 
        dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
        dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
-       if (key->flags & I915_SET_COLORKEY_DESTINATION)
-               dvscntr |= DVS_DEST_KEY;
-       else if (key->flags & I915_SET_COLORKEY_SOURCE)
+       if (key->flags & I915_SET_COLORKEY_DESTINATION) {
+               if ((dvscntr & DVS_ENABLE) || !IS_GEN5(dev))
+                       dvscntr |= DVS_DEST_KEY;
+               else
+                       intel_plane->restore_ilk_dest_key = true;
+       } else if (key->flags & I915_SET_COLORKEY_SOURCE)
                dvscntr |= DVS_SOURCE_KEY;
        I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
 
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to