From 3f8bc370ac679a5fe5c098f30d3cf8e80f62a9f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= <krh@redhat.com>
Date: Wed, 17 Dec 2008 22:14:59 -0500
Subject: [PATCH] drm/i915: Pin cursor bo and unpin old bo when setting cursor.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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 | 29 ++++++++++++++++++++--------
 drivers/gpu/drm/i915/intel_drv.h     |  1 +
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e5c1c80d1f9051..1204d26b50db53 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -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;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 407edd5bf5822e..94981ee7b8bd9c 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -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;
-- 
GitLab