diff options
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 6 |
4 files changed, 33 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e552aa6bc85..8a9fd917786 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1209,7 +1209,8 @@ int __must_check | |||
1209 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, | 1209 | i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, |
1210 | bool write); | 1210 | bool write); |
1211 | int __must_check | 1211 | int __must_check |
1212 | i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, | 1212 | i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, |
1213 | u32 alignment, | ||
1213 | struct intel_ring_buffer *pipelined); | 1214 | struct intel_ring_buffer *pipelined); |
1214 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1215 | int i915_gem_attach_phys_object(struct drm_device *dev, |
1215 | struct drm_i915_gem_object *obj, | 1216 | struct drm_i915_gem_object *obj, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e6915072ba7..8a439f0c21f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -3095,40 +3095,55 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, | |||
3095 | } | 3095 | } |
3096 | 3096 | ||
3097 | /* | 3097 | /* |
3098 | * Prepare buffer for display plane. Use uninterruptible for possible flush | 3098 | * Prepare buffer for display plane (scanout, cursors, etc). |
3099 | * wait, as in modesetting process we're not supposed to be interrupted. | 3099 | * Can be called from an uninterruptible phase (modesetting) and allows |
3100 | * any flushes to be pipelined (for pageflips). | ||
3101 | * | ||
3102 | * For the display plane, we want to be in the GTT but out of any write | ||
3103 | * domains. So in many ways this looks like set_to_gtt_domain() apart from the | ||
3104 | * ability to pipeline the waits, pinning and any additional subtleties | ||
3105 | * that may differentiate the display plane from ordinary buffers. | ||
3100 | */ | 3106 | */ |
3101 | int | 3107 | int |
3102 | i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, | 3108 | i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, |
3109 | u32 alignment, | ||
3103 | struct intel_ring_buffer *pipelined) | 3110 | struct intel_ring_buffer *pipelined) |
3104 | { | 3111 | { |
3105 | uint32_t old_read_domains; | 3112 | u32 old_read_domains, old_write_domain; |
3106 | int ret; | 3113 | int ret; |
3107 | 3114 | ||
3108 | /* Not valid to be called on unbound objects. */ | ||
3109 | if (obj->gtt_space == NULL) | ||
3110 | return -EINVAL; | ||
3111 | |||
3112 | ret = i915_gem_object_flush_gpu_write_domain(obj); | 3115 | ret = i915_gem_object_flush_gpu_write_domain(obj); |
3113 | if (ret) | 3116 | if (ret) |
3114 | return ret; | 3117 | return ret; |
3115 | 3118 | ||
3116 | |||
3117 | /* Currently, we are always called from an non-interruptible context. */ | ||
3118 | if (pipelined != obj->ring) { | 3119 | if (pipelined != obj->ring) { |
3119 | ret = i915_gem_object_wait_rendering(obj); | 3120 | ret = i915_gem_object_wait_rendering(obj); |
3120 | if (ret) | 3121 | if (ret) |
3121 | return ret; | 3122 | return ret; |
3122 | } | 3123 | } |
3123 | 3124 | ||
3125 | /* As the user may map the buffer once pinned in the display plane | ||
3126 | * (e.g. libkms for the bootup splash), we have to ensure that we | ||
3127 | * always use map_and_fenceable for all scanout buffers. | ||
3128 | */ | ||
3129 | ret = i915_gem_object_pin(obj, alignment, true); | ||
3130 | if (ret) | ||
3131 | return ret; | ||
3132 | |||
3124 | i915_gem_object_flush_cpu_write_domain(obj); | 3133 | i915_gem_object_flush_cpu_write_domain(obj); |
3125 | 3134 | ||
3135 | old_write_domain = obj->base.write_domain; | ||
3126 | old_read_domains = obj->base.read_domains; | 3136 | old_read_domains = obj->base.read_domains; |
3137 | |||
3138 | /* It should now be out of any other write domains, and we can update | ||
3139 | * the domain values for our changes. | ||
3140 | */ | ||
3141 | BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); | ||
3127 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; | 3142 | obj->base.read_domains |= I915_GEM_DOMAIN_GTT; |
3128 | 3143 | ||
3129 | trace_i915_gem_object_change_domain(obj, | 3144 | trace_i915_gem_object_change_domain(obj, |
3130 | old_read_domains, | 3145 | old_read_domains, |
3131 | obj->base.write_domain); | 3146 | old_write_domain); |
3132 | 3147 | ||
3133 | return 0; | 3148 | return 0; |
3134 | } | 3149 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f79863a9a69..86a3ec1469b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1812,14 +1812,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, | |||
1812 | } | 1812 | } |
1813 | 1813 | ||
1814 | dev_priv->mm.interruptible = false; | 1814 | dev_priv->mm.interruptible = false; |
1815 | ret = i915_gem_object_pin(obj, alignment, true); | 1815 | ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined); |
1816 | if (ret) | 1816 | if (ret) |
1817 | goto err_interruptible; | 1817 | goto err_interruptible; |
1818 | 1818 | ||
1819 | ret = i915_gem_object_set_to_display_plane(obj, pipelined); | ||
1820 | if (ret) | ||
1821 | goto err_unpin; | ||
1822 | |||
1823 | /* Install a fence for tiled scan-out. Pre-i965 always needs a | 1819 | /* Install a fence for tiled scan-out. Pre-i965 always needs a |
1824 | * fence, whereas 965+ only requires a fence if using | 1820 | * fence, whereas 965+ only requires a fence if using |
1825 | * framebuffer compression. For simplicity, we always install | 1821 | * framebuffer compression. For simplicity, we always install |
@@ -5434,21 +5430,15 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
5434 | goto fail_locked; | 5430 | goto fail_locked; |
5435 | } | 5431 | } |
5436 | 5432 | ||
5437 | ret = i915_gem_object_pin(obj, PAGE_SIZE, true); | 5433 | ret = i915_gem_object_pin_to_display_plane(obj, 0, NULL); |
5438 | if (ret) { | ||
5439 | DRM_ERROR("failed to pin cursor bo\n"); | ||
5440 | goto fail_locked; | ||
5441 | } | ||
5442 | |||
5443 | ret = i915_gem_object_set_to_display_plane(obj, NULL); | ||
5444 | if (ret) { | 5434 | if (ret) { |
5445 | DRM_ERROR("failed to move cursor bo into the GTT\n"); | 5435 | DRM_ERROR("failed to move cursor bo into the GTT\n"); |
5446 | goto fail_unpin; | 5436 | goto fail_locked; |
5447 | } | 5437 | } |
5448 | 5438 | ||
5449 | ret = i915_gem_object_put_fence(obj); | 5439 | ret = i915_gem_object_put_fence(obj); |
5450 | if (ret) { | 5440 | if (ret) { |
5451 | DRM_ERROR("failed to move cursor bo into the GTT\n"); | 5441 | DRM_ERROR("failed to release fence for cursor"); |
5452 | goto fail_unpin; | 5442 | goto fail_unpin; |
5453 | } | 5443 | } |
5454 | 5444 | ||
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index e0903c5f0ca..fcf6fcb0b48 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -773,14 +773,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
773 | if (ret != 0) | 773 | if (ret != 0) |
774 | return ret; | 774 | return ret; |
775 | 775 | ||
776 | ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); | 776 | ret = i915_gem_object_pin_to_display_plane(new_bo, 0, NULL); |
777 | if (ret != 0) | 777 | if (ret != 0) |
778 | return ret; | 778 | return ret; |
779 | 779 | ||
780 | ret = i915_gem_object_set_to_display_plane(new_bo, NULL); | ||
781 | if (ret != 0) | ||
782 | goto out_unpin; | ||
783 | |||
784 | ret = i915_gem_object_put_fence(new_bo); | 780 | ret = i915_gem_object_put_fence(new_bo); |
785 | if (ret) | 781 | if (ret) |
786 | goto out_unpin; | 782 | goto out_unpin; |