[PATCH 24/81] drm/i915: split cursor setting code into prepare/commit/unref parts

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Dec 12 08:15:51 PST 2012


From: Ander Conselvan de Oliveira <conselvan2 at gmail.com>

The atomic mode setting API will need to pin the cursor bo without
making changes to the current setup. Only on a later stage the cursor
registers can be written and the previous bo released.

This patch splits intel_crtc_cursor_set() into three parts: prepare,
commit and unref. intel_crtc_cursor_prepare() will pin the cursor bo
and return a gem object and the address to be written to the cursor
registers. intel_crtc_cursor_commit() takes that object and address
and actually changes the cursor. intel_crtc_cursor_unref() is used to
release the previous cursor bo.
---
 drivers/gpu/drm/i915/intel_display.c |   90 +++++++++++++++++++++++++--------
 1 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 2a32cb0..0f25a07 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6173,10 +6173,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 	}
 }
 
-static int intel_crtc_cursor_set(struct drm_crtc *crtc,
+static int intel_crtc_cursor_prepare(struct drm_crtc *crtc,
 				 struct drm_file *file,
 				 uint32_t handle,
-				 uint32_t width, uint32_t height)
+				 uint32_t width, uint32_t height,
+				 struct drm_i915_gem_object **obj_ret,
+				 uint32_t *addr_ret)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -6188,10 +6190,9 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	/* if we want to turn off the cursor ignore width and height */
 	if (!handle) {
 		DRM_DEBUG_KMS("cursor off\n");
-		addr = 0;
-		obj = NULL;
-		mutex_lock(&dev->struct_mutex);
-		goto finish;
+		*addr_ret = 0;
+		*obj_ret = NULL;
+		return 0;
 	}
 
 	/* Currently we only support 64x64 cursors */
@@ -6247,17 +6248,46 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	if (IS_GEN2(dev))
 		I915_WRITE(CURSIZE, (height << 12) | width);
 
- finish:
-	if (intel_crtc->cursor_bo) {
-		if (dev_priv->info->cursor_needs_physical) {
-			if (intel_crtc->cursor_bo != obj)
-				i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo);
-		} else
-			i915_gem_object_unpin(intel_crtc->cursor_bo);
-		drm_gem_object_unreference(&intel_crtc->cursor_bo->base);
-	}
+	mutex_unlock(&dev->struct_mutex);
+
+	*obj_ret = obj;
+	*addr_ret = addr;
+
+	return 0;
+fail_unpin:
+	i915_gem_object_unpin(obj);
+fail_locked:
+	mutex_unlock(&dev->struct_mutex);
+fail:
+	drm_gem_object_unreference_unlocked(&obj->base);
+	return ret;
+}
+
+static void intel_crtc_cursor_bo_unref(struct drm_crtc *crtc,
+				       struct drm_i915_gem_object *obj)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+
+	mutex_lock(&dev->struct_mutex);
+
+	if (dev_priv->info->cursor_needs_physical) {
+		if (obj != intel_crtc->cursor_bo)
+			i915_gem_detach_phys_object(dev, obj);
+	} else
+		i915_gem_object_unpin(obj);
+	drm_gem_object_unreference(&obj->base);
 
 	mutex_unlock(&dev->struct_mutex);
+}
+
+static void intel_crtc_cursor_commit(struct drm_crtc *crtc, uint32_t handle,
+				     uint32_t width, uint32_t height,
+				     struct drm_i915_gem_object *obj,
+				     uint32_t addr)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 
 	intel_crtc->cursor_addr = addr;
 	intel_crtc->cursor_handle = handle;
@@ -6266,15 +6296,31 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc,
 	intel_crtc->cursor_height = height;
 
 	intel_crtc_update_cursor(crtc, true);
+}
+
+static int intel_crtc_cursor_set(struct drm_crtc *crtc,
+				 struct drm_file *file,
+				 uint32_t handle,
+				 uint32_t width, uint32_t height)
+{
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int ret;
+	struct drm_i915_gem_object *obj, *old_obj;
+	uint32_t addr;
+
+	ret = intel_crtc_cursor_prepare(crtc, file, handle, width, height,
+					&obj, &addr);
+	if (ret)
+		return ret;
+
+	old_obj = intel_crtc->cursor_bo;
+
+	intel_crtc_cursor_commit(crtc, handle, width, height, obj, addr);
+
+	if (old_obj)
+		intel_crtc_cursor_bo_unref(crtc, old_obj);
 
 	return 0;
-fail_unpin:
-	i915_gem_object_unpin(obj);
-fail_locked:
-	mutex_unlock(&dev->struct_mutex);
-fail:
-	drm_gem_object_unreference_unlocked(&obj->base);
-	return ret;
 }
 
 static int intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
-- 
1.7.8.6



More information about the dri-devel mailing list