diff mbox

[34/51] drm/i915: split cursor setting code into prepare/commit/unref parts

Message ID 1351188354-24233-35-git-send-email-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Ville Syrjälä Oct. 25, 2012, 6:05 p.m. UTC
From: Ander Conselvan de Oliveira <conselvan2@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 mbox

Patch

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c59985d..20539c4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5587,10 +5587,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;
@@ -5602,10 +5604,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 */
@@ -5661,17 +5662,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;
@@ -5680,15 +5710,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)