From: Ander Conselvan de Oliveira <conselvan2@xxxxxxxxx> 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel