aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorMatt Roper <matthew.d.roper@intel.com>2014-12-01 18:40:12 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-12-05 19:46:22 -0500
commitf4a2cf295d07b1fba9fc3599c1579681132b658a (patch)
tree6dca8f24beefece100f2aec954c88b9eb6b31699 /drivers/gpu/drm/i915/intel_display.c
parent455a68086d1dfb801ad7c867d5ca0ed0e0f758b0 (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.c124
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
12016static int 12016static int
12017intel_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
12052static void
12017intel_commit_cursor_plane(struct drm_plane *plane, 12053intel_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
12106finish:
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;
12118update: 12099update:
@@ -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;
12133fail_unpin:
12134 i915_gem_object_unpin_from_display_plane(obj);
12135fail_locked:
12136 mutex_unlock(&dev->struct_mutex);
12137 return ret;
12138} 12112}
12139 12113
12140static int 12114static 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
12181static const struct drm_plane_funcs intel_cursor_plane_funcs = { 12161static const struct drm_plane_funcs intel_cursor_plane_funcs = {