drm/i915: Pin cursor bo and unpin old bo when setting cursor.
authorKristian Høgsberg <krh@redhat.com>
Thu, 18 Dec 2008 03:14:59 +0000 (22:14 -0500)
committerDave Airlie <airlied@linux.ie>
Wed, 7 Jan 2009 01:49:43 +0000 (11:49 +1000)
We also didn't track the cursor bo before and would leak a reference
when the cursor image was change.

Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@linux.ie>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h

index e5c1c80..1204d26 100644 (file)
@@ -986,19 +986,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
        uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
        uint32_t temp;
        size_t addr;
+       int ret;
 
        DRM_DEBUG("\n");
 
        /* if we want to turn off the cursor ignore width and height */
        if (!handle) {
                DRM_DEBUG("cursor off\n");
-               /* turn of the cursor */
-               temp = 0;
-               temp |= CURSOR_MODE_DISABLE;
-
-               I915_WRITE(control, temp);
-               I915_WRITE(base, 0);
-               return 0;
+               temp = CURSOR_MODE_DISABLE;
+               addr = 0;
+               bo = NULL;
+               goto finish;
        }
 
        /* Currently we only support 64x64 cursors */
@@ -1025,15 +1023,30 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
                addr = obj_priv->gtt_offset;
        }
 
-       intel_crtc->cursor_addr = addr;
+       ret = i915_gem_object_pin(bo, PAGE_SIZE);
+       if (ret) {
+               DRM_ERROR("failed to pin cursor bo\n");
+               drm_gem_object_unreference(bo);
+               return ret;
+       }
+
        temp = 0;
        /* set the pipe for the cursor */
        temp |= (pipe << 28);
        temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 
+ finish:
        I915_WRITE(control, temp);
        I915_WRITE(base, addr);
 
+       if (intel_crtc->cursor_bo) {
+               i915_gem_object_unpin(intel_crtc->cursor_bo);
+               drm_gem_object_unreference(intel_crtc->cursor_bo);
+       }
+
+       intel_crtc->cursor_addr = addr;
+       intel_crtc->cursor_bo = bo;
+
        return 0;
 }
 
index 407edd5..94981ee 100644 (file)
@@ -88,6 +88,7 @@ struct intel_crtc {
        struct drm_crtc base;
        int pipe;
        int plane;
+       struct drm_gem_object *cursor_bo;
        uint32_t cursor_addr;
        u8 lut_r[256], lut_g[256], lut_b[256];
        int dpms_mode;