diff options
author | Matt Roper <matthew.d.roper@intel.com> | 2014-12-01 18:40:12 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-12-05 19:46:22 -0500 |
commit | f4a2cf295d07b1fba9fc3599c1579681132b658a (patch) | |
tree | 6dca8f24beefece100f2aec954c88b9eb6b31699 /drivers/gpu/drm/i915/intel_display.c | |
parent | 455a68086d1dfb801ad7c867d5ca0ed0e0f758b0 (diff) |
drm/i915: Introduce intel_prepare_cursor_plane() (v2)
Primary and sprite planes have already been refactored to include a
'prepare' step which handles all the commit-time operations that could
fail (i.e., pinning buffers and such). Refactor the cursor commit in a
similar manner.
For simplicity and consistency with other plane types, we also switch to
using intel_pin_and_fence_fb_obj() to perform our pinning for
non-physical cursors. This will allow us to more easily migrate the
code into the atomic 'begin' handler in a plane-agnostic manner in a
future patchset.
v2:
- Update GEM fb tracking for physical cursors too. (Ander)
- Use intel_unpin_fb_obj() rather than
i915_gem_object_unpin_from_display_plane() and do so while holding
struct_mutex. (Ander)
- Update plane->fb in commit_cursor_plane. This isn't really necessary
since the DRM core does this for us in __setplane_internal(), but
doing it in our driver once we know we're going to succeed helps
avoid confusion. (Ander)
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Ander Conselvan de Oliveira <ander.conselvan.de.oliveira@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 124 |
1 files changed, 52 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 76896e8c09ee..78c0e1c10c44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -12014,20 +12014,55 @@ intel_check_cursor_plane(struct drm_plane *plane, | |||
12014 | } | 12014 | } |
12015 | 12015 | ||
12016 | static int | 12016 | static int |
12017 | intel_prepare_cursor_plane(struct drm_plane *plane, | ||
12018 | struct intel_plane_state *state) | ||
12019 | { | ||
12020 | struct drm_device *dev = plane->dev; | ||
12021 | struct drm_framebuffer *fb = state->fb; | ||
12022 | struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc); | ||
12023 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | ||
12024 | struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb); | ||
12025 | enum pipe pipe = intel_crtc->pipe; | ||
12026 | int ret = 0; | ||
12027 | |||
12028 | if (old_obj != obj) { | ||
12029 | /* we only need to pin inside GTT if cursor is non-phy */ | ||
12030 | mutex_lock(&dev->struct_mutex); | ||
12031 | if (!INTEL_INFO(dev)->cursor_needs_physical) { | ||
12032 | if (obj) | ||
12033 | ret = intel_pin_and_fence_fb_obj(plane, fb, NULL); | ||
12034 | } else { | ||
12035 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
12036 | if (obj) | ||
12037 | ret = i915_gem_object_attach_phys(obj, align); | ||
12038 | if (ret) | ||
12039 | DRM_DEBUG_KMS("failed to attach phys object\n"); | ||
12040 | } | ||
12041 | |||
12042 | if (ret == 0) | ||
12043 | i915_gem_track_fb(intel_crtc->cursor_bo, obj, | ||
12044 | INTEL_FRONTBUFFER_CURSOR(pipe)); | ||
12045 | |||
12046 | mutex_unlock(&dev->struct_mutex); | ||
12047 | } | ||
12048 | |||
12049 | return ret; | ||
12050 | } | ||
12051 | |||
12052 | static void | ||
12017 | intel_commit_cursor_plane(struct drm_plane *plane, | 12053 | intel_commit_cursor_plane(struct drm_plane *plane, |
12018 | struct intel_plane_state *state) | 12054 | struct intel_plane_state *state) |
12019 | { | 12055 | { |
12020 | struct drm_crtc *crtc = state->crtc; | 12056 | struct drm_crtc *crtc = state->crtc; |
12021 | struct drm_device *dev = crtc->dev; | 12057 | struct drm_device *dev = crtc->dev; |
12022 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
12023 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 12058 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
12024 | struct intel_plane *intel_plane = to_intel_plane(plane); | 12059 | struct intel_plane *intel_plane = to_intel_plane(plane); |
12025 | struct drm_i915_gem_object *obj = intel_fb_obj(state->fb); | 12060 | struct drm_i915_gem_object *obj = intel_fb_obj(state->fb); |
12026 | enum pipe pipe = intel_crtc->pipe; | 12061 | enum pipe pipe = intel_crtc->pipe; |
12027 | unsigned old_width; | 12062 | unsigned old_width; |
12028 | uint32_t addr; | 12063 | uint32_t addr; |
12029 | int ret; | ||
12030 | 12064 | ||
12065 | plane->fb = state->fb; | ||
12031 | crtc->cursor_x = state->orig_dst.x1; | 12066 | crtc->cursor_x = state->orig_dst.x1; |
12032 | crtc->cursor_y = state->orig_dst.y1; | 12067 | crtc->cursor_y = state->orig_dst.y1; |
12033 | 12068 | ||
@@ -12044,75 +12079,21 @@ intel_commit_cursor_plane(struct drm_plane *plane, | |||
12044 | if (intel_crtc->cursor_bo == obj) | 12079 | if (intel_crtc->cursor_bo == obj) |
12045 | goto update; | 12080 | goto update; |
12046 | 12081 | ||
12047 | /* if we want to turn off the cursor ignore width and height */ | 12082 | if (!obj) |
12048 | if (!obj) { | ||
12049 | DRM_DEBUG_KMS("cursor off\n"); | ||
12050 | addr = 0; | 12083 | addr = 0; |
12051 | mutex_lock(&dev->struct_mutex); | 12084 | else if (!INTEL_INFO(dev)->cursor_needs_physical) |
12052 | goto finish; | ||
12053 | } | ||
12054 | |||
12055 | /* we only need to pin inside GTT if cursor is non-phy */ | ||
12056 | mutex_lock(&dev->struct_mutex); | ||
12057 | if (!INTEL_INFO(dev)->cursor_needs_physical) { | ||
12058 | unsigned alignment; | ||
12059 | |||
12060 | /* | ||
12061 | * Global gtt pte registers are special registers which actually | ||
12062 | * forward writes to a chunk of system memory. Which means that | ||
12063 | * there is no risk that the register values disappear as soon | ||
12064 | * as we call intel_runtime_pm_put(), so it is correct to wrap | ||
12065 | * only the pin/unpin/fence and not more. | ||
12066 | */ | ||
12067 | intel_runtime_pm_get(dev_priv); | ||
12068 | |||
12069 | /* Note that the w/a also requires 2 PTE of padding following | ||
12070 | * the bo. We currently fill all unused PTE with the shadow | ||
12071 | * page and so we should always have valid PTE following the | ||
12072 | * cursor preventing the VT-d warning. | ||
12073 | */ | ||
12074 | alignment = 0; | ||
12075 | if (need_vtd_wa(dev)) | ||
12076 | alignment = 64*1024; | ||
12077 | |||
12078 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, NULL); | ||
12079 | if (ret) { | ||
12080 | DRM_DEBUG_KMS("failed to move cursor bo into the GTT\n"); | ||
12081 | intel_runtime_pm_put(dev_priv); | ||
12082 | goto fail_locked; | ||
12083 | } | ||
12084 | |||
12085 | ret = i915_gem_object_put_fence(obj); | ||
12086 | if (ret) { | ||
12087 | DRM_DEBUG_KMS("failed to release fence for cursor"); | ||
12088 | intel_runtime_pm_put(dev_priv); | ||
12089 | goto fail_unpin; | ||
12090 | } | ||
12091 | |||
12092 | addr = i915_gem_obj_ggtt_offset(obj); | 12085 | addr = i915_gem_obj_ggtt_offset(obj); |
12093 | 12086 | else | |
12094 | intel_runtime_pm_put(dev_priv); | ||
12095 | |||
12096 | } else { | ||
12097 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
12098 | ret = i915_gem_object_attach_phys(obj, align); | ||
12099 | if (ret) { | ||
12100 | DRM_DEBUG_KMS("failed to attach phys object\n"); | ||
12101 | goto fail_locked; | ||
12102 | } | ||
12103 | addr = obj->phys_handle->busaddr; | 12087 | addr = obj->phys_handle->busaddr; |
12104 | } | ||
12105 | 12088 | ||
12106 | finish: | ||
12107 | if (intel_crtc->cursor_bo) { | 12089 | if (intel_crtc->cursor_bo) { |
12108 | if (!INTEL_INFO(dev)->cursor_needs_physical) | 12090 | if (!INTEL_INFO(dev)->cursor_needs_physical) { |
12109 | i915_gem_object_unpin_from_display_plane(intel_crtc->cursor_bo); | 12091 | mutex_lock(&dev->struct_mutex); |
12092 | intel_unpin_fb_obj(intel_crtc->cursor_bo); | ||
12093 | mutex_unlock(&dev->struct_mutex); | ||
12094 | } | ||
12110 | } | 12095 | } |
12111 | 12096 | ||
12112 | i915_gem_track_fb(intel_crtc->cursor_bo, obj, | ||
12113 | INTEL_FRONTBUFFER_CURSOR(pipe)); | ||
12114 | mutex_unlock(&dev->struct_mutex); | ||
12115 | |||
12116 | intel_crtc->cursor_addr = addr; | 12097 | intel_crtc->cursor_addr = addr; |
12117 | intel_crtc->cursor_bo = obj; | 12098 | intel_crtc->cursor_bo = obj; |
12118 | update: | 12099 | update: |
@@ -12128,13 +12109,6 @@ update: | |||
12128 | 12109 | ||
12129 | intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe)); | 12110 | intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_CURSOR(pipe)); |
12130 | } | 12111 | } |
12131 | |||
12132 | return 0; | ||
12133 | fail_unpin: | ||
12134 | i915_gem_object_unpin_from_display_plane(obj); | ||
12135 | fail_locked: | ||
12136 | mutex_unlock(&dev->struct_mutex); | ||
12137 | return ret; | ||
12138 | } | 12112 | } |
12139 | 12113 | ||
12140 | static int | 12114 | static int |
@@ -12175,7 +12149,13 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
12175 | if (ret) | 12149 | if (ret) |
12176 | return ret; | 12150 | return ret; |
12177 | 12151 | ||
12178 | return intel_commit_cursor_plane(plane, &state); | 12152 | ret = intel_prepare_cursor_plane(plane, &state); |
12153 | if (ret) | ||
12154 | return ret; | ||
12155 | |||
12156 | intel_commit_cursor_plane(plane, &state); | ||
12157 | |||
12158 | return 0; | ||
12179 | } | 12159 | } |
12180 | 12160 | ||
12181 | static const struct drm_plane_funcs intel_cursor_plane_funcs = { | 12161 | static const struct drm_plane_funcs intel_cursor_plane_funcs = { |