[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