diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-16 03:46:35 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2019-08-16 04:51:11 -0400 |
commit | 8e7cb1799b4f8bde3e7d9c80bf689e5408add271 (patch) | |
tree | 16dfa5a166b59520734e411c14ec0f403bd35c26 | |
parent | e5dadff4b09376e8ed92ecc0c12f1b9b3b1fbd19 (diff) |
drm/i915: Extract intel_frontbuffer active tracking
Move the active tracking for the frontbuffer operations out of the
i915_gem_object and into its own first class (refcounted) object. In the
process of detangling, we switch from low level request tracking to the
easier i915_active -- with the plan that this avoids any potential
atomic callbacks as the frontbuffer tracking wishes to sleep as it
flushes.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190816074635.26062-1-chris@chris-wilson.co.uk
-rw-r--r-- | Documentation/gpu/i915.rst | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display.c | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_display_types.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_fbdev.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_frontbuffer.c | 255 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_frontbuffer.h | 70 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_overlay.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_clflush.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_domain.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_mman.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_object.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/gem/i915_gem_object_types.h | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_vma.c | 6 |
17 files changed, 306 insertions, 260 deletions
diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst index 0e322688be5c..3415255ad3dc 100644 --- a/Documentation/gpu/i915.rst +++ b/Documentation/gpu/i915.rst | |||
@@ -91,9 +91,6 @@ Frontbuffer Tracking | |||
91 | .. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.c | 91 | .. kernel-doc:: drivers/gpu/drm/i915/display/intel_frontbuffer.c |
92 | :internal: | 92 | :internal: |
93 | 93 | ||
94 | .. kernel-doc:: drivers/gpu/drm/i915/i915_gem.c | ||
95 | :functions: i915_gem_track_fb | ||
96 | |||
97 | Display FIFO Underrun Reporting | 94 | Display FIFO Underrun Reporting |
98 | ------------------------------- | 95 | ------------------------------- |
99 | 96 | ||
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 3916c697ffab..59e1988dd362 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c | |||
@@ -3049,12 +3049,13 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, | |||
3049 | { | 3049 | { |
3050 | struct drm_device *dev = crtc->base.dev; | 3050 | struct drm_device *dev = crtc->base.dev; |
3051 | struct drm_i915_private *dev_priv = to_i915(dev); | 3051 | struct drm_i915_private *dev_priv = to_i915(dev); |
3052 | struct drm_i915_gem_object *obj = NULL; | ||
3053 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; | 3052 | struct drm_mode_fb_cmd2 mode_cmd = { 0 }; |
3054 | struct drm_framebuffer *fb = &plane_config->fb->base; | 3053 | struct drm_framebuffer *fb = &plane_config->fb->base; |
3055 | u32 base_aligned = round_down(plane_config->base, PAGE_SIZE); | 3054 | u32 base_aligned = round_down(plane_config->base, PAGE_SIZE); |
3056 | u32 size_aligned = round_up(plane_config->base + plane_config->size, | 3055 | u32 size_aligned = round_up(plane_config->base + plane_config->size, |
3057 | PAGE_SIZE); | 3056 | PAGE_SIZE); |
3057 | struct drm_i915_gem_object *obj; | ||
3058 | bool ret = false; | ||
3058 | 3059 | ||
3059 | size_aligned -= base_aligned; | 3060 | size_aligned -= base_aligned; |
3060 | 3061 | ||
@@ -3096,7 +3097,7 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, | |||
3096 | break; | 3097 | break; |
3097 | default: | 3098 | default: |
3098 | MISSING_CASE(plane_config->tiling); | 3099 | MISSING_CASE(plane_config->tiling); |
3099 | return false; | 3100 | goto out; |
3100 | } | 3101 | } |
3101 | 3102 | ||
3102 | mode_cmd.pixel_format = fb->format->format; | 3103 | mode_cmd.pixel_format = fb->format->format; |
@@ -3108,16 +3109,15 @@ intel_alloc_initial_plane_obj(struct intel_crtc *crtc, | |||
3108 | 3109 | ||
3109 | if (intel_framebuffer_init(to_intel_framebuffer(fb), obj, &mode_cmd)) { | 3110 | if (intel_framebuffer_init(to_intel_framebuffer(fb), obj, &mode_cmd)) { |
3110 | DRM_DEBUG_KMS("intel fb init failed\n"); | 3111 | DRM_DEBUG_KMS("intel fb init failed\n"); |
3111 | goto out_unref_obj; | 3112 | goto out; |
3112 | } | 3113 | } |
3113 | 3114 | ||
3114 | 3115 | ||
3115 | DRM_DEBUG_KMS("initial plane fb obj %p\n", obj); | 3116 | DRM_DEBUG_KMS("initial plane fb obj %p\n", obj); |
3116 | return true; | 3117 | ret = true; |
3117 | 3118 | out: | |
3118 | out_unref_obj: | ||
3119 | i915_gem_object_put(obj); | 3119 | i915_gem_object_put(obj); |
3120 | return false; | 3120 | return ret; |
3121 | } | 3121 | } |
3122 | 3122 | ||
3123 | static void | 3123 | static void |
@@ -3174,6 +3174,12 @@ static void intel_plane_disable_noatomic(struct intel_crtc *crtc, | |||
3174 | intel_disable_plane(plane, crtc_state); | 3174 | intel_disable_plane(plane, crtc_state); |
3175 | } | 3175 | } |
3176 | 3176 | ||
3177 | static struct intel_frontbuffer * | ||
3178 | to_intel_frontbuffer(struct drm_framebuffer *fb) | ||
3179 | { | ||
3180 | return fb ? to_intel_framebuffer(fb)->frontbuffer : NULL; | ||
3181 | } | ||
3182 | |||
3177 | static void | 3183 | static void |
3178 | intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, | 3184 | intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, |
3179 | struct intel_initial_plane_config *plane_config) | 3185 | struct intel_initial_plane_config *plane_config) |
@@ -3181,7 +3187,6 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc, | |||
3181 | struct drm_device *dev = intel_crtc->base.dev; | 3187 | struct drm_device *dev = intel_crtc->base.dev; |
3182 | struct drm_i915_private *dev_priv = to_i915(dev); | 3188 | struct drm_i915_private *dev_priv = to_i915(dev); |
3183 | struct drm_crtc *c; | 3189 | struct drm_crtc *c; |
3184 | struct drm_i915_gem_object *obj; | ||
3185 | struct drm_plane *primary = intel_crtc->base.primary; | 3190 | struct drm_plane *primary = intel_crtc->base.primary; |
3186 | struct drm_plane_state *plane_state = primary->state; | 3191 | struct drm_plane_state *plane_state = primary->state; |
3187 | struct intel_plane *intel_plane = to_intel_plane(primary); | 3192 | struct intel_plane *intel_plane = to_intel_plane(primary); |
@@ -3257,8 +3262,7 @@ valid_fb: | |||
3257 | return; | 3262 | return; |
3258 | } | 3263 | } |
3259 | 3264 | ||
3260 | obj = intel_fb_obj(fb); | 3265 | intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB); |
3261 | intel_fb_obj_flush(obj, ORIGIN_DIRTYFB); | ||
3262 | 3266 | ||
3263 | plane_state->src_x = 0; | 3267 | plane_state->src_x = 0; |
3264 | plane_state->src_y = 0; | 3268 | plane_state->src_y = 0; |
@@ -3273,14 +3277,14 @@ valid_fb: | |||
3273 | intel_state->base.src = drm_plane_state_src(plane_state); | 3277 | intel_state->base.src = drm_plane_state_src(plane_state); |
3274 | intel_state->base.dst = drm_plane_state_dest(plane_state); | 3278 | intel_state->base.dst = drm_plane_state_dest(plane_state); |
3275 | 3279 | ||
3276 | if (i915_gem_object_is_tiled(obj)) | 3280 | if (plane_config->tiling) |
3277 | dev_priv->preserve_bios_swizzle = true; | 3281 | dev_priv->preserve_bios_swizzle = true; |
3278 | 3282 | ||
3279 | plane_state->fb = fb; | 3283 | plane_state->fb = fb; |
3280 | plane_state->crtc = &intel_crtc->base; | 3284 | plane_state->crtc = &intel_crtc->base; |
3281 | 3285 | ||
3282 | atomic_or(to_intel_plane(primary)->frontbuffer_bit, | 3286 | atomic_or(to_intel_plane(primary)->frontbuffer_bit, |
3283 | &obj->frontbuffer_bits); | 3287 | &to_intel_frontbuffer(fb)->bits); |
3284 | } | 3288 | } |
3285 | 3289 | ||
3286 | static int skl_max_plane_width(const struct drm_framebuffer *fb, | 3290 | static int skl_max_plane_width(const struct drm_framebuffer *fb, |
@@ -14132,9 +14136,9 @@ static void intel_atomic_track_fbs(struct intel_atomic_state *state) | |||
14132 | 14136 | ||
14133 | for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, | 14137 | for_each_oldnew_intel_plane_in_state(state, plane, old_plane_state, |
14134 | new_plane_state, i) | 14138 | new_plane_state, i) |
14135 | i915_gem_track_fb(intel_fb_obj(old_plane_state->base.fb), | 14139 | intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->base.fb), |
14136 | intel_fb_obj(new_plane_state->base.fb), | 14140 | to_intel_frontbuffer(new_plane_state->base.fb), |
14137 | plane->frontbuffer_bit); | 14141 | plane->frontbuffer_bit); |
14138 | } | 14142 | } |
14139 | 14143 | ||
14140 | static int intel_atomic_commit(struct drm_device *dev, | 14144 | static int intel_atomic_commit(struct drm_device *dev, |
@@ -14418,7 +14422,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, | |||
14418 | return ret; | 14422 | return ret; |
14419 | 14423 | ||
14420 | fb_obj_bump_render_priority(obj); | 14424 | fb_obj_bump_render_priority(obj); |
14421 | intel_fb_obj_flush(obj, ORIGIN_DIRTYFB); | 14425 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_DIRTYFB); |
14422 | 14426 | ||
14423 | if (!new_state->fence) { /* implicit fencing */ | 14427 | if (!new_state->fence) { /* implicit fencing */ |
14424 | struct dma_fence *fence; | 14428 | struct dma_fence *fence; |
@@ -14681,13 +14685,12 @@ intel_legacy_cursor_update(struct drm_plane *plane, | |||
14681 | struct drm_modeset_acquire_ctx *ctx) | 14685 | struct drm_modeset_acquire_ctx *ctx) |
14682 | { | 14686 | { |
14683 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); | 14687 | struct drm_i915_private *dev_priv = to_i915(crtc->dev); |
14684 | int ret; | ||
14685 | struct drm_plane_state *old_plane_state, *new_plane_state; | 14688 | struct drm_plane_state *old_plane_state, *new_plane_state; |
14686 | struct intel_plane *intel_plane = to_intel_plane(plane); | 14689 | struct intel_plane *intel_plane = to_intel_plane(plane); |
14687 | struct drm_framebuffer *old_fb; | ||
14688 | struct intel_crtc_state *crtc_state = | 14690 | struct intel_crtc_state *crtc_state = |
14689 | to_intel_crtc_state(crtc->state); | 14691 | to_intel_crtc_state(crtc->state); |
14690 | struct intel_crtc_state *new_crtc_state; | 14692 | struct intel_crtc_state *new_crtc_state; |
14693 | int ret; | ||
14691 | 14694 | ||
14692 | /* | 14695 | /* |
14693 | * When crtc is inactive or there is a modeset pending, | 14696 | * When crtc is inactive or there is a modeset pending, |
@@ -14755,11 +14758,10 @@ intel_legacy_cursor_update(struct drm_plane *plane, | |||
14755 | if (ret) | 14758 | if (ret) |
14756 | goto out_unlock; | 14759 | goto out_unlock; |
14757 | 14760 | ||
14758 | intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_FLIP); | 14761 | intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_FLIP); |
14759 | 14762 | intel_frontbuffer_track(to_intel_frontbuffer(old_plane_state->fb), | |
14760 | old_fb = old_plane_state->fb; | 14763 | to_intel_frontbuffer(fb), |
14761 | i915_gem_track_fb(intel_fb_obj(old_fb), intel_fb_obj(fb), | 14764 | intel_plane->frontbuffer_bit); |
14762 | intel_plane->frontbuffer_bit); | ||
14763 | 14765 | ||
14764 | /* Swap plane state */ | 14766 | /* Swap plane state */ |
14765 | plane->state = new_plane_state; | 14767 | plane->state = new_plane_state; |
@@ -15540,15 +15542,9 @@ static void intel_setup_outputs(struct drm_i915_private *dev_priv) | |||
15540 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | 15542 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) |
15541 | { | 15543 | { |
15542 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | 15544 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
15543 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | ||
15544 | 15545 | ||
15545 | drm_framebuffer_cleanup(fb); | 15546 | drm_framebuffer_cleanup(fb); |
15546 | 15547 | intel_frontbuffer_put(intel_fb->frontbuffer); | |
15547 | i915_gem_object_lock(obj); | ||
15548 | WARN_ON(!obj->framebuffer_references--); | ||
15549 | i915_gem_object_unlock(obj); | ||
15550 | |||
15551 | i915_gem_object_put(obj); | ||
15552 | 15548 | ||
15553 | kfree(intel_fb); | 15549 | kfree(intel_fb); |
15554 | } | 15550 | } |
@@ -15576,7 +15572,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, | |||
15576 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 15572 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
15577 | 15573 | ||
15578 | i915_gem_object_flush_if_display(obj); | 15574 | i915_gem_object_flush_if_display(obj); |
15579 | intel_fb_obj_flush(obj, ORIGIN_DIRTYFB); | 15575 | intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB); |
15580 | 15576 | ||
15581 | return 0; | 15577 | return 0; |
15582 | } | 15578 | } |
@@ -15598,8 +15594,11 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, | |||
15598 | int ret = -EINVAL; | 15594 | int ret = -EINVAL; |
15599 | int i; | 15595 | int i; |
15600 | 15596 | ||
15597 | intel_fb->frontbuffer = intel_frontbuffer_get(obj); | ||
15598 | if (!intel_fb->frontbuffer) | ||
15599 | return -ENOMEM; | ||
15600 | |||
15601 | i915_gem_object_lock(obj); | 15601 | i915_gem_object_lock(obj); |
15602 | obj->framebuffer_references++; | ||
15603 | tiling = i915_gem_object_get_tiling(obj); | 15602 | tiling = i915_gem_object_get_tiling(obj); |
15604 | stride = i915_gem_object_get_stride(obj); | 15603 | stride = i915_gem_object_get_stride(obj); |
15605 | i915_gem_object_unlock(obj); | 15604 | i915_gem_object_unlock(obj); |
@@ -15716,9 +15715,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb, | |||
15716 | return 0; | 15715 | return 0; |
15717 | 15716 | ||
15718 | err: | 15717 | err: |
15719 | i915_gem_object_lock(obj); | 15718 | intel_frontbuffer_put(intel_fb->frontbuffer); |
15720 | obj->framebuffer_references--; | ||
15721 | i915_gem_object_unlock(obj); | ||
15722 | return ret; | 15719 | return ret; |
15723 | } | 15720 | } |
15724 | 15721 | ||
@@ -15736,8 +15733,7 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
15736 | return ERR_PTR(-ENOENT); | 15733 | return ERR_PTR(-ENOENT); |
15737 | 15734 | ||
15738 | fb = intel_framebuffer_create(obj, &mode_cmd); | 15735 | fb = intel_framebuffer_create(obj, &mode_cmd); |
15739 | if (IS_ERR(fb)) | 15736 | i915_gem_object_put(obj); |
15740 | i915_gem_object_put(obj); | ||
15741 | 15737 | ||
15742 | return fb; | 15738 | return fb; |
15743 | } | 15739 | } |
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h index a88ec9aa9ca0..3c1a5f3e1d22 100644 --- a/drivers/gpu/drm/i915/display/intel_display_types.h +++ b/drivers/gpu/drm/i915/display/intel_display_types.h | |||
@@ -84,6 +84,7 @@ enum intel_broadcast_rgb { | |||
84 | 84 | ||
85 | struct intel_framebuffer { | 85 | struct intel_framebuffer { |
86 | struct drm_framebuffer base; | 86 | struct drm_framebuffer base; |
87 | struct intel_frontbuffer *frontbuffer; | ||
87 | struct intel_rotation_info rot_info; | 88 | struct intel_rotation_info rot_info; |
88 | 89 | ||
89 | /* for each plane in the normal GTT view */ | 90 | /* for each plane in the normal GTT view */ |
diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c index 2d74c33a504d..d59eee5c5d9c 100644 --- a/drivers/gpu/drm/i915/display/intel_fbdev.c +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c | |||
@@ -47,13 +47,14 @@ | |||
47 | #include "intel_fbdev.h" | 47 | #include "intel_fbdev.h" |
48 | #include "intel_frontbuffer.h" | 48 | #include "intel_frontbuffer.h" |
49 | 49 | ||
50 | static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) | 50 | static struct intel_frontbuffer *to_frontbuffer(struct intel_fbdev *ifbdev) |
51 | { | 51 | { |
52 | struct drm_i915_gem_object *obj = intel_fb_obj(&ifbdev->fb->base); | 52 | return ifbdev->fb->frontbuffer; |
53 | unsigned int origin = | 53 | } |
54 | ifbdev->vma_flags & PLANE_HAS_FENCE ? ORIGIN_GTT : ORIGIN_CPU; | ||
55 | 54 | ||
56 | intel_fb_obj_invalidate(obj, origin); | 55 | static void intel_fbdev_invalidate(struct intel_fbdev *ifbdev) |
56 | { | ||
57 | intel_frontbuffer_invalidate(to_frontbuffer(ifbdev), ORIGIN_CPU); | ||
57 | } | 58 | } |
58 | 59 | ||
59 | static int intel_fbdev_set_par(struct fb_info *info) | 60 | static int intel_fbdev_set_par(struct fb_info *info) |
@@ -120,7 +121,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper, | |||
120 | struct drm_i915_private *dev_priv = to_i915(dev); | 121 | struct drm_i915_private *dev_priv = to_i915(dev); |
121 | struct drm_mode_fb_cmd2 mode_cmd = {}; | 122 | struct drm_mode_fb_cmd2 mode_cmd = {}; |
122 | struct drm_i915_gem_object *obj; | 123 | struct drm_i915_gem_object *obj; |
123 | int size, ret; | 124 | int size; |
124 | 125 | ||
125 | /* we don't do packed 24bpp */ | 126 | /* we don't do packed 24bpp */ |
126 | if (sizes->surface_bpp == 24) | 127 | if (sizes->surface_bpp == 24) |
@@ -147,24 +148,16 @@ static int intelfb_alloc(struct drm_fb_helper *helper, | |||
147 | obj = i915_gem_object_create_shmem(dev_priv, size); | 148 | obj = i915_gem_object_create_shmem(dev_priv, size); |
148 | if (IS_ERR(obj)) { | 149 | if (IS_ERR(obj)) { |
149 | DRM_ERROR("failed to allocate framebuffer\n"); | 150 | DRM_ERROR("failed to allocate framebuffer\n"); |
150 | ret = PTR_ERR(obj); | 151 | return PTR_ERR(obj); |
151 | goto err; | ||
152 | } | 152 | } |
153 | 153 | ||
154 | fb = intel_framebuffer_create(obj, &mode_cmd); | 154 | fb = intel_framebuffer_create(obj, &mode_cmd); |
155 | if (IS_ERR(fb)) { | 155 | i915_gem_object_put(obj); |
156 | ret = PTR_ERR(fb); | 156 | if (IS_ERR(fb)) |
157 | goto err_obj; | 157 | return PTR_ERR(fb); |
158 | } | ||
159 | 158 | ||
160 | ifbdev->fb = to_intel_framebuffer(fb); | 159 | ifbdev->fb = to_intel_framebuffer(fb); |
161 | |||
162 | return 0; | 160 | return 0; |
163 | |||
164 | err_obj: | ||
165 | i915_gem_object_put(obj); | ||
166 | err: | ||
167 | return ret; | ||
168 | } | 161 | } |
169 | 162 | ||
170 | static int intelfb_create(struct drm_fb_helper *helper, | 163 | static int intelfb_create(struct drm_fb_helper *helper, |
@@ -180,7 +173,6 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
180 | const struct i915_ggtt_view view = { | 173 | const struct i915_ggtt_view view = { |
181 | .type = I915_GGTT_VIEW_NORMAL, | 174 | .type = I915_GGTT_VIEW_NORMAL, |
182 | }; | 175 | }; |
183 | struct drm_framebuffer *fb; | ||
184 | intel_wakeref_t wakeref; | 176 | intel_wakeref_t wakeref; |
185 | struct fb_info *info; | 177 | struct fb_info *info; |
186 | struct i915_vma *vma; | 178 | struct i915_vma *vma; |
@@ -226,8 +218,7 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
226 | goto out_unlock; | 218 | goto out_unlock; |
227 | } | 219 | } |
228 | 220 | ||
229 | fb = &ifbdev->fb->base; | 221 | intel_frontbuffer_flush(to_frontbuffer(ifbdev), ORIGIN_DIRTYFB); |
230 | intel_fb_obj_flush(intel_fb_obj(fb), ORIGIN_DIRTYFB); | ||
231 | 222 | ||
232 | info = drm_fb_helper_alloc_fbi(helper); | 223 | info = drm_fb_helper_alloc_fbi(helper); |
233 | if (IS_ERR(info)) { | 224 | if (IS_ERR(info)) { |
@@ -236,7 +227,7 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
236 | goto out_unpin; | 227 | goto out_unpin; |
237 | } | 228 | } |
238 | 229 | ||
239 | ifbdev->helper.fb = fb; | 230 | ifbdev->helper.fb = &ifbdev->fb->base; |
240 | 231 | ||
241 | info->fbops = &intelfb_ops; | 232 | info->fbops = &intelfb_ops; |
242 | 233 | ||
@@ -263,13 +254,14 @@ static int intelfb_create(struct drm_fb_helper *helper, | |||
263 | * If the object is stolen however, it will be full of whatever | 254 | * If the object is stolen however, it will be full of whatever |
264 | * garbage was left in there. | 255 | * garbage was left in there. |
265 | */ | 256 | */ |
266 | if (intel_fb_obj(fb)->stolen && !prealloc) | 257 | if (vma->obj->stolen && !prealloc) |
267 | memset_io(info->screen_base, 0, info->screen_size); | 258 | memset_io(info->screen_base, 0, info->screen_size); |
268 | 259 | ||
269 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ | 260 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
270 | 261 | ||
271 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n", | 262 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x\n", |
272 | fb->width, fb->height, i915_ggtt_offset(vma)); | 263 | ifbdev->fb->base.width, ifbdev->fb->base.height, |
264 | i915_ggtt_offset(vma)); | ||
273 | ifbdev->vma = vma; | 265 | ifbdev->vma = vma; |
274 | ifbdev->vma_flags = flags; | 266 | ifbdev->vma_flags = flags; |
275 | 267 | ||
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.c b/drivers/gpu/drm/i915/display/intel_frontbuffer.c index 9cda88e41d29..719379774fa5 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.c +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.c | |||
@@ -30,11 +30,11 @@ | |||
30 | * Many features require us to track changes to the currently active | 30 | * Many features require us to track changes to the currently active |
31 | * frontbuffer, especially rendering targeted at the frontbuffer. | 31 | * frontbuffer, especially rendering targeted at the frontbuffer. |
32 | * | 32 | * |
33 | * To be able to do so GEM tracks frontbuffers using a bitmask for all possible | 33 | * To be able to do so we track frontbuffers using a bitmask for all possible |
34 | * frontbuffer slots through i915_gem_track_fb(). The function in this file are | 34 | * frontbuffer slots through intel_frontbuffer_track(). The functions in this |
35 | * then called when the contents of the frontbuffer are invalidated, when | 35 | * file are then called when the contents of the frontbuffer are invalidated, |
36 | * frontbuffer rendering has stopped again to flush out all the changes and when | 36 | * when frontbuffer rendering has stopped again to flush out all the changes |
37 | * the frontbuffer is exchanged with a flip. Subsystems interested in | 37 | * and when the frontbuffer is exchanged with a flip. Subsystems interested in |
38 | * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks | 38 | * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks |
39 | * into the relevant places and filter for the frontbuffer slots that they are | 39 | * into the relevant places and filter for the frontbuffer slots that they are |
40 | * interested int. | 40 | * interested int. |
@@ -63,28 +63,9 @@ | |||
63 | #include "intel_frontbuffer.h" | 63 | #include "intel_frontbuffer.h" |
64 | #include "intel_psr.h" | 64 | #include "intel_psr.h" |
65 | 65 | ||
66 | void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, | ||
67 | enum fb_op_origin origin, | ||
68 | unsigned int frontbuffer_bits) | ||
69 | { | ||
70 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | ||
71 | |||
72 | if (origin == ORIGIN_CS) { | ||
73 | spin_lock(&dev_priv->fb_tracking.lock); | ||
74 | dev_priv->fb_tracking.busy_bits |= frontbuffer_bits; | ||
75 | dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; | ||
76 | spin_unlock(&dev_priv->fb_tracking.lock); | ||
77 | } | ||
78 | |||
79 | might_sleep(); | ||
80 | intel_psr_invalidate(dev_priv, frontbuffer_bits, origin); | ||
81 | intel_edp_drrs_invalidate(dev_priv, frontbuffer_bits); | ||
82 | intel_fbc_invalidate(dev_priv, frontbuffer_bits, origin); | ||
83 | } | ||
84 | |||
85 | /** | 66 | /** |
86 | * intel_frontbuffer_flush - flush frontbuffer | 67 | * frontbuffer_flush - flush frontbuffer |
87 | * @dev_priv: i915 device | 68 | * @i915: i915 device |
88 | * @frontbuffer_bits: frontbuffer plane tracking bits | 69 | * @frontbuffer_bits: frontbuffer plane tracking bits |
89 | * @origin: which operation caused the flush | 70 | * @origin: which operation caused the flush |
90 | * | 71 | * |
@@ -94,45 +75,27 @@ void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, | |||
94 | * | 75 | * |
95 | * Can be called without any locks held. | 76 | * Can be called without any locks held. |
96 | */ | 77 | */ |
97 | static void intel_frontbuffer_flush(struct drm_i915_private *dev_priv, | 78 | static void frontbuffer_flush(struct drm_i915_private *i915, |
98 | unsigned frontbuffer_bits, | 79 | unsigned int frontbuffer_bits, |
99 | enum fb_op_origin origin) | 80 | enum fb_op_origin origin) |
100 | { | 81 | { |
101 | /* Delay flushing when rings are still busy.*/ | 82 | /* Delay flushing when rings are still busy.*/ |
102 | spin_lock(&dev_priv->fb_tracking.lock); | 83 | spin_lock(&i915->fb_tracking.lock); |
103 | frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; | 84 | frontbuffer_bits &= ~i915->fb_tracking.busy_bits; |
104 | spin_unlock(&dev_priv->fb_tracking.lock); | 85 | spin_unlock(&i915->fb_tracking.lock); |
105 | 86 | ||
106 | if (!frontbuffer_bits) | 87 | if (!frontbuffer_bits) |
107 | return; | 88 | return; |
108 | 89 | ||
109 | might_sleep(); | 90 | might_sleep(); |
110 | intel_edp_drrs_flush(dev_priv, frontbuffer_bits); | 91 | intel_edp_drrs_flush(i915, frontbuffer_bits); |
111 | intel_psr_flush(dev_priv, frontbuffer_bits, origin); | 92 | intel_psr_flush(i915, frontbuffer_bits, origin); |
112 | intel_fbc_flush(dev_priv, frontbuffer_bits, origin); | 93 | intel_fbc_flush(i915, frontbuffer_bits, origin); |
113 | } | ||
114 | |||
115 | void __intel_fb_obj_flush(struct drm_i915_gem_object *obj, | ||
116 | enum fb_op_origin origin, | ||
117 | unsigned int frontbuffer_bits) | ||
118 | { | ||
119 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | ||
120 | |||
121 | if (origin == ORIGIN_CS) { | ||
122 | spin_lock(&dev_priv->fb_tracking.lock); | ||
123 | /* Filter out new bits since rendering started. */ | ||
124 | frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; | ||
125 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; | ||
126 | spin_unlock(&dev_priv->fb_tracking.lock); | ||
127 | } | ||
128 | |||
129 | if (frontbuffer_bits) | ||
130 | intel_frontbuffer_flush(dev_priv, frontbuffer_bits, origin); | ||
131 | } | 94 | } |
132 | 95 | ||
133 | /** | 96 | /** |
134 | * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip | 97 | * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip |
135 | * @dev_priv: i915 device | 98 | * @i915: i915 device |
136 | * @frontbuffer_bits: frontbuffer plane tracking bits | 99 | * @frontbuffer_bits: frontbuffer plane tracking bits |
137 | * | 100 | * |
138 | * This function gets called after scheduling a flip on @obj. The actual | 101 | * This function gets called after scheduling a flip on @obj. The actual |
@@ -142,19 +105,19 @@ void __intel_fb_obj_flush(struct drm_i915_gem_object *obj, | |||
142 | * | 105 | * |
143 | * Can be called without any locks held. | 106 | * Can be called without any locks held. |
144 | */ | 107 | */ |
145 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *dev_priv, | 108 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, |
146 | unsigned frontbuffer_bits) | 109 | unsigned frontbuffer_bits) |
147 | { | 110 | { |
148 | spin_lock(&dev_priv->fb_tracking.lock); | 111 | spin_lock(&i915->fb_tracking.lock); |
149 | dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; | 112 | i915->fb_tracking.flip_bits |= frontbuffer_bits; |
150 | /* Remove stale busy bits due to the old buffer. */ | 113 | /* Remove stale busy bits due to the old buffer. */ |
151 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; | 114 | i915->fb_tracking.busy_bits &= ~frontbuffer_bits; |
152 | spin_unlock(&dev_priv->fb_tracking.lock); | 115 | spin_unlock(&i915->fb_tracking.lock); |
153 | } | 116 | } |
154 | 117 | ||
155 | /** | 118 | /** |
156 | * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip | 119 | * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip |
157 | * @dev_priv: i915 device | 120 | * @i915: i915 device |
158 | * @frontbuffer_bits: frontbuffer plane tracking bits | 121 | * @frontbuffer_bits: frontbuffer plane tracking bits |
159 | * | 122 | * |
160 | * This function gets called after the flip has been latched and will complete | 123 | * This function gets called after the flip has been latched and will complete |
@@ -162,23 +125,22 @@ void intel_frontbuffer_flip_prepare(struct drm_i915_private *dev_priv, | |||
162 | * | 125 | * |
163 | * Can be called without any locks held. | 126 | * Can be called without any locks held. |
164 | */ | 127 | */ |
165 | void intel_frontbuffer_flip_complete(struct drm_i915_private *dev_priv, | 128 | void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, |
166 | unsigned frontbuffer_bits) | 129 | unsigned frontbuffer_bits) |
167 | { | 130 | { |
168 | spin_lock(&dev_priv->fb_tracking.lock); | 131 | spin_lock(&i915->fb_tracking.lock); |
169 | /* Mask any cancelled flips. */ | 132 | /* Mask any cancelled flips. */ |
170 | frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; | 133 | frontbuffer_bits &= i915->fb_tracking.flip_bits; |
171 | dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; | 134 | i915->fb_tracking.flip_bits &= ~frontbuffer_bits; |
172 | spin_unlock(&dev_priv->fb_tracking.lock); | 135 | spin_unlock(&i915->fb_tracking.lock); |
173 | 136 | ||
174 | if (frontbuffer_bits) | 137 | if (frontbuffer_bits) |
175 | intel_frontbuffer_flush(dev_priv, | 138 | frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); |
176 | frontbuffer_bits, ORIGIN_FLIP); | ||
177 | } | 139 | } |
178 | 140 | ||
179 | /** | 141 | /** |
180 | * intel_frontbuffer_flip - synchronous frontbuffer flip | 142 | * intel_frontbuffer_flip - synchronous frontbuffer flip |
181 | * @dev_priv: i915 device | 143 | * @i915: i915 device |
182 | * @frontbuffer_bits: frontbuffer plane tracking bits | 144 | * @frontbuffer_bits: frontbuffer plane tracking bits |
183 | * | 145 | * |
184 | * This function gets called after scheduling a flip on @obj. This is for | 146 | * This function gets called after scheduling a flip on @obj. This is for |
@@ -187,13 +149,160 @@ void intel_frontbuffer_flip_complete(struct drm_i915_private *dev_priv, | |||
187 | * | 149 | * |
188 | * Can be called without any locks held. | 150 | * Can be called without any locks held. |
189 | */ | 151 | */ |
190 | void intel_frontbuffer_flip(struct drm_i915_private *dev_priv, | 152 | void intel_frontbuffer_flip(struct drm_i915_private *i915, |
191 | unsigned frontbuffer_bits) | 153 | unsigned frontbuffer_bits) |
192 | { | 154 | { |
193 | spin_lock(&dev_priv->fb_tracking.lock); | 155 | spin_lock(&i915->fb_tracking.lock); |
194 | /* Remove stale busy bits due to the old buffer. */ | 156 | /* Remove stale busy bits due to the old buffer. */ |
195 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; | 157 | i915->fb_tracking.busy_bits &= ~frontbuffer_bits; |
196 | spin_unlock(&dev_priv->fb_tracking.lock); | 158 | spin_unlock(&i915->fb_tracking.lock); |
197 | 159 | ||
198 | intel_frontbuffer_flush(dev_priv, frontbuffer_bits, ORIGIN_FLIP); | 160 | frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); |
161 | } | ||
162 | |||
163 | void __intel_fb_invalidate(struct intel_frontbuffer *front, | ||
164 | enum fb_op_origin origin, | ||
165 | unsigned int frontbuffer_bits) | ||
166 | { | ||
167 | struct drm_i915_private *i915 = to_i915(front->obj->base.dev); | ||
168 | |||
169 | if (origin == ORIGIN_CS) { | ||
170 | spin_lock(&i915->fb_tracking.lock); | ||
171 | i915->fb_tracking.busy_bits |= frontbuffer_bits; | ||
172 | i915->fb_tracking.flip_bits &= ~frontbuffer_bits; | ||
173 | spin_unlock(&i915->fb_tracking.lock); | ||
174 | } | ||
175 | |||
176 | might_sleep(); | ||
177 | intel_psr_invalidate(i915, frontbuffer_bits, origin); | ||
178 | intel_edp_drrs_invalidate(i915, frontbuffer_bits); | ||
179 | intel_fbc_invalidate(i915, frontbuffer_bits, origin); | ||
180 | } | ||
181 | |||
182 | void __intel_fb_flush(struct intel_frontbuffer *front, | ||
183 | enum fb_op_origin origin, | ||
184 | unsigned int frontbuffer_bits) | ||
185 | { | ||
186 | struct drm_i915_private *i915 = to_i915(front->obj->base.dev); | ||
187 | |||
188 | if (origin == ORIGIN_CS) { | ||
189 | spin_lock(&i915->fb_tracking.lock); | ||
190 | /* Filter out new bits since rendering started. */ | ||
191 | frontbuffer_bits &= i915->fb_tracking.busy_bits; | ||
192 | i915->fb_tracking.busy_bits &= ~frontbuffer_bits; | ||
193 | spin_unlock(&i915->fb_tracking.lock); | ||
194 | } | ||
195 | |||
196 | if (frontbuffer_bits) | ||
197 | frontbuffer_flush(i915, frontbuffer_bits, origin); | ||
198 | } | ||
199 | |||
200 | static int frontbuffer_active(struct i915_active *ref) | ||
201 | { | ||
202 | struct intel_frontbuffer *front = | ||
203 | container_of(ref, typeof(*front), write); | ||
204 | |||
205 | kref_get(&front->ref); | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static void frontbuffer_retire(struct i915_active *ref) | ||
210 | { | ||
211 | struct intel_frontbuffer *front = | ||
212 | container_of(ref, typeof(*front), write); | ||
213 | |||
214 | intel_frontbuffer_flush(front, ORIGIN_CS); | ||
215 | intel_frontbuffer_put(front); | ||
216 | } | ||
217 | |||
218 | static void frontbuffer_release(struct kref *ref) | ||
219 | __releases(&to_i915(front->obj->base.dev)->fb_tracking.lock) | ||
220 | { | ||
221 | struct intel_frontbuffer *front = | ||
222 | container_of(ref, typeof(*front), ref); | ||
223 | |||
224 | front->obj->frontbuffer = NULL; | ||
225 | spin_unlock(&to_i915(front->obj->base.dev)->fb_tracking.lock); | ||
226 | |||
227 | i915_gem_object_put(front->obj); | ||
228 | kfree(front); | ||
229 | } | ||
230 | |||
231 | struct intel_frontbuffer * | ||
232 | intel_frontbuffer_get(struct drm_i915_gem_object *obj) | ||
233 | { | ||
234 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | ||
235 | struct intel_frontbuffer *front; | ||
236 | |||
237 | spin_lock(&i915->fb_tracking.lock); | ||
238 | front = obj->frontbuffer; | ||
239 | if (front) | ||
240 | kref_get(&front->ref); | ||
241 | spin_unlock(&i915->fb_tracking.lock); | ||
242 | if (front) | ||
243 | return front; | ||
244 | |||
245 | front = kmalloc(sizeof(*front), GFP_KERNEL); | ||
246 | if (!front) | ||
247 | return NULL; | ||
248 | |||
249 | front->obj = obj; | ||
250 | kref_init(&front->ref); | ||
251 | atomic_set(&front->bits, 0); | ||
252 | i915_active_init(i915, &front->write, | ||
253 | frontbuffer_active, frontbuffer_retire); | ||
254 | |||
255 | spin_lock(&i915->fb_tracking.lock); | ||
256 | if (obj->frontbuffer) { | ||
257 | kfree(front); | ||
258 | front = obj->frontbuffer; | ||
259 | kref_get(&front->ref); | ||
260 | } else { | ||
261 | i915_gem_object_get(obj); | ||
262 | obj->frontbuffer = front; | ||
263 | } | ||
264 | spin_unlock(&i915->fb_tracking.lock); | ||
265 | |||
266 | return front; | ||
267 | } | ||
268 | |||
269 | void intel_frontbuffer_put(struct intel_frontbuffer *front) | ||
270 | { | ||
271 | kref_put_lock(&front->ref, | ||
272 | frontbuffer_release, | ||
273 | &to_i915(front->obj->base.dev)->fb_tracking.lock); | ||
274 | } | ||
275 | |||
276 | /** | ||
277 | * intel_frontbuffer_track - update frontbuffer tracking | ||
278 | * @old: current buffer for the frontbuffer slots | ||
279 | * @new: new buffer for the frontbuffer slots | ||
280 | * @frontbuffer_bits: bitmask of frontbuffer slots | ||
281 | * | ||
282 | * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them | ||
283 | * from @old and setting them in @new. Both @old and @new can be NULL. | ||
284 | */ | ||
285 | void intel_frontbuffer_track(struct intel_frontbuffer *old, | ||
286 | struct intel_frontbuffer *new, | ||
287 | unsigned int frontbuffer_bits) | ||
288 | { | ||
289 | /* | ||
290 | * Control of individual bits within the mask are guarded by | ||
291 | * the owning plane->mutex, i.e. we can never see concurrent | ||
292 | * manipulation of individual bits. But since the bitfield as a whole | ||
293 | * is updated using RMW, we need to use atomics in order to update | ||
294 | * the bits. | ||
295 | */ | ||
296 | BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > | ||
297 | BITS_PER_TYPE(atomic_t)); | ||
298 | |||
299 | if (old) { | ||
300 | WARN_ON(!(atomic_read(&old->bits) & frontbuffer_bits)); | ||
301 | atomic_andnot(frontbuffer_bits, &old->bits); | ||
302 | } | ||
303 | |||
304 | if (new) { | ||
305 | WARN_ON(atomic_read(&new->bits) & frontbuffer_bits); | ||
306 | atomic_or(frontbuffer_bits, &new->bits); | ||
307 | } | ||
199 | } | 308 | } |
diff --git a/drivers/gpu/drm/i915/display/intel_frontbuffer.h b/drivers/gpu/drm/i915/display/intel_frontbuffer.h index 5727320c8084..adc64d61a4a5 100644 --- a/drivers/gpu/drm/i915/display/intel_frontbuffer.h +++ b/drivers/gpu/drm/i915/display/intel_frontbuffer.h | |||
@@ -24,7 +24,10 @@ | |||
24 | #ifndef __INTEL_FRONTBUFFER_H__ | 24 | #ifndef __INTEL_FRONTBUFFER_H__ |
25 | #define __INTEL_FRONTBUFFER_H__ | 25 | #define __INTEL_FRONTBUFFER_H__ |
26 | 26 | ||
27 | #include "gem/i915_gem_object.h" | 27 | #include <linux/atomic.h> |
28 | #include <linux/kref.h> | ||
29 | |||
30 | #include "i915_active.h" | ||
28 | 31 | ||
29 | struct drm_i915_private; | 32 | struct drm_i915_private; |
30 | struct drm_i915_gem_object; | 33 | struct drm_i915_gem_object; |
@@ -37,23 +40,30 @@ enum fb_op_origin { | |||
37 | ORIGIN_DIRTYFB, | 40 | ORIGIN_DIRTYFB, |
38 | }; | 41 | }; |
39 | 42 | ||
40 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *dev_priv, | 43 | struct intel_frontbuffer { |
44 | struct kref ref; | ||
45 | atomic_t bits; | ||
46 | struct i915_active write; | ||
47 | struct drm_i915_gem_object *obj; | ||
48 | }; | ||
49 | |||
50 | void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, | ||
41 | unsigned frontbuffer_bits); | 51 | unsigned frontbuffer_bits); |
42 | void intel_frontbuffer_flip_complete(struct drm_i915_private *dev_priv, | 52 | void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, |
43 | unsigned frontbuffer_bits); | 53 | unsigned frontbuffer_bits); |
44 | void intel_frontbuffer_flip(struct drm_i915_private *dev_priv, | 54 | void intel_frontbuffer_flip(struct drm_i915_private *i915, |
45 | unsigned frontbuffer_bits); | 55 | unsigned frontbuffer_bits); |
46 | 56 | ||
47 | void __intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, | 57 | struct intel_frontbuffer * |
48 | enum fb_op_origin origin, | 58 | intel_frontbuffer_get(struct drm_i915_gem_object *obj); |
49 | unsigned int frontbuffer_bits); | 59 | |
50 | void __intel_fb_obj_flush(struct drm_i915_gem_object *obj, | 60 | void __intel_fb_invalidate(struct intel_frontbuffer *front, |
51 | enum fb_op_origin origin, | 61 | enum fb_op_origin origin, |
52 | unsigned int frontbuffer_bits); | 62 | unsigned int frontbuffer_bits); |
53 | 63 | ||
54 | /** | 64 | /** |
55 | * intel_fb_obj_invalidate - invalidate frontbuffer object | 65 | * intel_frontbuffer_invalidate - invalidate frontbuffer object |
56 | * @obj: GEM object to invalidate | 66 | * @front: GEM object to invalidate |
57 | * @origin: which operation caused the invalidation | 67 | * @origin: which operation caused the invalidation |
58 | * | 68 | * |
59 | * This function gets called every time rendering on the given object starts and | 69 | * This function gets called every time rendering on the given object starts and |
@@ -62,37 +72,53 @@ void __intel_fb_obj_flush(struct drm_i915_gem_object *obj, | |||
62 | * until the rendering completes or a flip on this frontbuffer plane is | 72 | * until the rendering completes or a flip on this frontbuffer plane is |
63 | * scheduled. | 73 | * scheduled. |
64 | */ | 74 | */ |
65 | static inline bool intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, | 75 | static inline bool intel_frontbuffer_invalidate(struct intel_frontbuffer *front, |
66 | enum fb_op_origin origin) | 76 | enum fb_op_origin origin) |
67 | { | 77 | { |
68 | unsigned int frontbuffer_bits; | 78 | unsigned int frontbuffer_bits; |
69 | 79 | ||
70 | frontbuffer_bits = atomic_read(&obj->frontbuffer_bits); | 80 | if (!front) |
81 | return false; | ||
82 | |||
83 | frontbuffer_bits = atomic_read(&front->bits); | ||
71 | if (!frontbuffer_bits) | 84 | if (!frontbuffer_bits) |
72 | return false; | 85 | return false; |
73 | 86 | ||
74 | __intel_fb_obj_invalidate(obj, origin, frontbuffer_bits); | 87 | __intel_fb_invalidate(front, origin, frontbuffer_bits); |
75 | return true; | 88 | return true; |
76 | } | 89 | } |
77 | 90 | ||
91 | void __intel_fb_flush(struct intel_frontbuffer *front, | ||
92 | enum fb_op_origin origin, | ||
93 | unsigned int frontbuffer_bits); | ||
94 | |||
78 | /** | 95 | /** |
79 | * intel_fb_obj_flush - flush frontbuffer object | 96 | * intel_frontbuffer_flush - flush frontbuffer object |
80 | * @obj: GEM object to flush | 97 | * @front: GEM object to flush |
81 | * @origin: which operation caused the flush | 98 | * @origin: which operation caused the flush |
82 | * | 99 | * |
83 | * This function gets called every time rendering on the given object has | 100 | * This function gets called every time rendering on the given object has |
84 | * completed and frontbuffer caching can be started again. | 101 | * completed and frontbuffer caching can be started again. |
85 | */ | 102 | */ |
86 | static inline void intel_fb_obj_flush(struct drm_i915_gem_object *obj, | 103 | static inline void intel_frontbuffer_flush(struct intel_frontbuffer *front, |
87 | enum fb_op_origin origin) | 104 | enum fb_op_origin origin) |
88 | { | 105 | { |
89 | unsigned int frontbuffer_bits; | 106 | unsigned int frontbuffer_bits; |
90 | 107 | ||
91 | frontbuffer_bits = atomic_read(&obj->frontbuffer_bits); | 108 | if (!front) |
109 | return; | ||
110 | |||
111 | frontbuffer_bits = atomic_read(&front->bits); | ||
92 | if (!frontbuffer_bits) | 112 | if (!frontbuffer_bits) |
93 | return; | 113 | return; |
94 | 114 | ||
95 | __intel_fb_obj_flush(obj, origin, frontbuffer_bits); | 115 | __intel_fb_flush(front, origin, frontbuffer_bits); |
96 | } | 116 | } |
97 | 117 | ||
118 | void intel_frontbuffer_track(struct intel_frontbuffer *old, | ||
119 | struct intel_frontbuffer *new, | ||
120 | unsigned int frontbuffer_bits); | ||
121 | |||
122 | void intel_frontbuffer_put(struct intel_frontbuffer *front); | ||
123 | |||
98 | #endif /* __INTEL_FRONTBUFFER_H__ */ | 124 | #endif /* __INTEL_FRONTBUFFER_H__ */ |
diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 4f78586ee05e..e1248eace0e1 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c | |||
@@ -281,9 +281,9 @@ static void intel_overlay_flip_prepare(struct intel_overlay *overlay, | |||
281 | 281 | ||
282 | WARN_ON(overlay->old_vma); | 282 | WARN_ON(overlay->old_vma); |
283 | 283 | ||
284 | i915_gem_track_fb(overlay->vma ? overlay->vma->obj : NULL, | 284 | intel_frontbuffer_track(overlay->vma ? overlay->vma->obj->frontbuffer : NULL, |
285 | vma ? vma->obj : NULL, | 285 | vma ? vma->obj->frontbuffer : NULL, |
286 | INTEL_FRONTBUFFER_OVERLAY(pipe)); | 286 | INTEL_FRONTBUFFER_OVERLAY(pipe)); |
287 | 287 | ||
288 | intel_frontbuffer_flip_prepare(overlay->i915, | 288 | intel_frontbuffer_flip_prepare(overlay->i915, |
289 | INTEL_FRONTBUFFER_OVERLAY(pipe)); | 289 | INTEL_FRONTBUFFER_OVERLAY(pipe)); |
@@ -768,7 +768,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, | |||
768 | ret = PTR_ERR(vma); | 768 | ret = PTR_ERR(vma); |
769 | goto out_pin_section; | 769 | goto out_pin_section; |
770 | } | 770 | } |
771 | intel_fb_obj_flush(new_bo, ORIGIN_DIRTYFB); | 771 | intel_frontbuffer_flush(new_bo->frontbuffer, ORIGIN_DIRTYFB); |
772 | 772 | ||
773 | ret = i915_vma_put_fence(vma); | 773 | ret = i915_vma_put_fence(vma); |
774 | if (ret) | 774 | if (ret) |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c index c31684682eaa..77944950d4c9 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c | |||
@@ -49,7 +49,7 @@ static void __i915_do_clflush(struct drm_i915_gem_object *obj) | |||
49 | { | 49 | { |
50 | GEM_BUG_ON(!i915_gem_object_has_pages(obj)); | 50 | GEM_BUG_ON(!i915_gem_object_has_pages(obj)); |
51 | drm_clflush_sg(obj->mm.pages); | 51 | drm_clflush_sg(obj->mm.pages); |
52 | intel_fb_obj_flush(obj, ORIGIN_CPU); | 52 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); |
53 | } | 53 | } |
54 | 54 | ||
55 | static void i915_clflush_work(struct work_struct *work) | 55 | static void i915_clflush_work(struct work_struct *work) |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 2e3ce2a69653..a1afc2690e9e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c | |||
@@ -551,13 +551,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) | |||
551 | return 0; | 551 | return 0; |
552 | } | 552 | } |
553 | 553 | ||
554 | static inline enum fb_op_origin | ||
555 | fb_write_origin(struct drm_i915_gem_object *obj, unsigned int domain) | ||
556 | { | ||
557 | return (domain == I915_GEM_DOMAIN_GTT ? | ||
558 | obj->frontbuffer_ggtt_origin : ORIGIN_CPU); | ||
559 | } | ||
560 | |||
561 | /** | 554 | /** |
562 | * Called when user space prepares to use an object with the CPU, either | 555 | * Called when user space prepares to use an object with the CPU, either |
563 | * through the mmap ioctl's mapping or a GTT mapping. | 556 | * through the mmap ioctl's mapping or a GTT mapping. |
@@ -661,9 +654,8 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
661 | 654 | ||
662 | i915_gem_object_unlock(obj); | 655 | i915_gem_object_unlock(obj); |
663 | 656 | ||
664 | if (write_domain != 0) | 657 | if (write_domain) |
665 | intel_fb_obj_invalidate(obj, | 658 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); |
666 | fb_write_origin(obj, write_domain)); | ||
667 | 659 | ||
668 | out_unpin: | 660 | out_unpin: |
669 | i915_gem_object_unpin_pages(obj); | 661 | i915_gem_object_unpin_pages(obj); |
@@ -783,7 +775,7 @@ int i915_gem_object_prepare_write(struct drm_i915_gem_object *obj, | |||
783 | } | 775 | } |
784 | 776 | ||
785 | out: | 777 | out: |
786 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 778 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); |
787 | obj->mm.dirty = true; | 779 | obj->mm.dirty = true; |
788 | /* return with the pages pinned */ | 780 | /* return with the pages pinned */ |
789 | return 0; | 781 | return 0; |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index cfaedb4b70bd..501ab55f1280 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c | |||
@@ -101,9 +101,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, | |||
101 | up_write(&mm->mmap_sem); | 101 | up_write(&mm->mmap_sem); |
102 | if (IS_ERR_VALUE(addr)) | 102 | if (IS_ERR_VALUE(addr)) |
103 | goto err; | 103 | goto err; |
104 | |||
105 | /* This may race, but that's ok, it only gets set */ | ||
106 | WRITE_ONCE(obj->frontbuffer_ggtt_origin, ORIGIN_CPU); | ||
107 | } | 104 | } |
108 | i915_gem_object_put(obj); | 105 | i915_gem_object_put(obj); |
109 | 106 | ||
@@ -283,7 +280,6 @@ vm_fault_t i915_gem_fault(struct vm_fault *vmf) | |||
283 | * Userspace is now writing through an untracked VMA, abandon | 280 | * Userspace is now writing through an untracked VMA, abandon |
284 | * all hope that the hardware is able to track future writes. | 281 | * all hope that the hardware is able to track future writes. |
285 | */ | 282 | */ |
286 | obj->frontbuffer_ggtt_origin = ORIGIN_CPU; | ||
287 | 283 | ||
288 | vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, flags); | 284 | vma = i915_gem_object_ggtt_pin(obj, &view, 0, 0, flags); |
289 | if (IS_ERR(vma) && !view.type) { | 285 | if (IS_ERR(vma) && !view.type) { |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.c b/drivers/gpu/drm/i915/gem/i915_gem_object.c index 3929c3a6b281..0807bb5464cf 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.c | |||
@@ -46,16 +46,6 @@ void i915_gem_object_free(struct drm_i915_gem_object *obj) | |||
46 | return kmem_cache_free(global.slab_objects, obj); | 46 | return kmem_cache_free(global.slab_objects, obj); |
47 | } | 47 | } |
48 | 48 | ||
49 | static void | ||
50 | frontbuffer_retire(struct i915_active_request *active, | ||
51 | struct i915_request *request) | ||
52 | { | ||
53 | struct drm_i915_gem_object *obj = | ||
54 | container_of(active, typeof(*obj), frontbuffer_write); | ||
55 | |||
56 | intel_fb_obj_flush(obj, ORIGIN_CS); | ||
57 | } | ||
58 | |||
59 | void i915_gem_object_init(struct drm_i915_gem_object *obj, | 49 | void i915_gem_object_init(struct drm_i915_gem_object *obj, |
60 | const struct drm_i915_gem_object_ops *ops) | 50 | const struct drm_i915_gem_object_ops *ops) |
61 | { | 51 | { |
@@ -72,10 +62,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, | |||
72 | 62 | ||
73 | obj->ops = ops; | 63 | obj->ops = ops; |
74 | 64 | ||
75 | obj->frontbuffer_ggtt_origin = ORIGIN_GTT; | ||
76 | i915_active_request_init(&obj->frontbuffer_write, | ||
77 | NULL, frontbuffer_retire); | ||
78 | |||
79 | obj->mm.madv = I915_MADV_WILLNEED; | 65 | obj->mm.madv = I915_MADV_WILLNEED; |
80 | INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN); | 66 | INIT_RADIX_TREE(&obj->mm.get_page.radix, GFP_KERNEL | __GFP_NOWARN); |
81 | mutex_init(&obj->mm.get_page.lock); | 67 | mutex_init(&obj->mm.get_page.lock); |
@@ -187,7 +173,6 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, | |||
187 | 173 | ||
188 | GEM_BUG_ON(atomic_read(&obj->bind_count)); | 174 | GEM_BUG_ON(atomic_read(&obj->bind_count)); |
189 | GEM_BUG_ON(obj->userfault_count); | 175 | GEM_BUG_ON(obj->userfault_count); |
190 | GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits)); | ||
191 | GEM_BUG_ON(!list_empty(&obj->lut_list)); | 176 | GEM_BUG_ON(!list_empty(&obj->lut_list)); |
192 | 177 | ||
193 | atomic_set(&obj->mm.pages_pin_count, 0); | 178 | atomic_set(&obj->mm.pages_pin_count, 0); |
@@ -230,6 +215,8 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
230 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); | 215 | struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); |
231 | struct drm_i915_private *i915 = to_i915(obj->base.dev); | 216 | struct drm_i915_private *i915 = to_i915(obj->base.dev); |
232 | 217 | ||
218 | GEM_BUG_ON(i915_gem_object_is_framebuffer(obj)); | ||
219 | |||
233 | /* | 220 | /* |
234 | * Before we free the object, make sure any pure RCU-only | 221 | * Before we free the object, make sure any pure RCU-only |
235 | * read-side critical sections are complete, e.g. | 222 | * read-side critical sections are complete, e.g. |
@@ -261,13 +248,6 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj) | |||
261 | queue_work(i915->wq, &i915->mm.free_work); | 248 | queue_work(i915->wq, &i915->mm.free_work); |
262 | } | 249 | } |
263 | 250 | ||
264 | static inline enum fb_op_origin | ||
265 | fb_write_origin(struct drm_i915_gem_object *obj, unsigned int domain) | ||
266 | { | ||
267 | return (domain == I915_GEM_DOMAIN_GTT ? | ||
268 | obj->frontbuffer_ggtt_origin : ORIGIN_CPU); | ||
269 | } | ||
270 | |||
271 | static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) | 251 | static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj) |
272 | { | 252 | { |
273 | return !(obj->cache_level == I915_CACHE_NONE || | 253 | return !(obj->cache_level == I915_CACHE_NONE || |
@@ -290,8 +270,7 @@ i915_gem_object_flush_write_domain(struct drm_i915_gem_object *obj, | |||
290 | for_each_ggtt_vma(vma, obj) | 270 | for_each_ggtt_vma(vma, obj) |
291 | intel_gt_flush_ggtt_writes(vma->vm->gt); | 271 | intel_gt_flush_ggtt_writes(vma->vm->gt); |
292 | 272 | ||
293 | intel_fb_obj_flush(obj, | 273 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); |
294 | fb_write_origin(obj, I915_GEM_DOMAIN_GTT)); | ||
295 | 274 | ||
296 | for_each_ggtt_vma(vma, obj) { | 275 | for_each_ggtt_vma(vma, obj) { |
297 | if (vma->iomap) | 276 | if (vma->iomap) |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h index 3714cf234d64..abc23e7e13a7 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h | |||
@@ -161,7 +161,7 @@ i915_gem_object_needs_async_cancel(const struct drm_i915_gem_object *obj) | |||
161 | static inline bool | 161 | static inline bool |
162 | i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj) | 162 | i915_gem_object_is_framebuffer(const struct drm_i915_gem_object *obj) |
163 | { | 163 | { |
164 | return READ_ONCE(obj->framebuffer_references); | 164 | return READ_ONCE(obj->frontbuffer); |
165 | } | 165 | } |
166 | 166 | ||
167 | static inline unsigned int | 167 | static inline unsigned int |
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h index d474c6ac4100..ede0eb4218a8 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_types.h +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_types.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include "i915_selftest.h" | 13 | #include "i915_selftest.h" |
14 | 14 | ||
15 | struct drm_i915_gem_object; | 15 | struct drm_i915_gem_object; |
16 | struct intel_fronbuffer; | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * struct i915_lut_handle tracks the fast lookups from handle to vma used | 19 | * struct i915_lut_handle tracks the fast lookups from handle to vma used |
@@ -141,9 +142,7 @@ struct drm_i915_gem_object { | |||
141 | */ | 142 | */ |
142 | u16 write_domain; | 143 | u16 write_domain; |
143 | 144 | ||
144 | atomic_t frontbuffer_bits; | 145 | struct intel_frontbuffer *frontbuffer; |
145 | unsigned int frontbuffer_ggtt_origin; /* write once */ | ||
146 | struct i915_active_request frontbuffer_write; | ||
147 | 146 | ||
148 | /** Current tiling stride for the object, if it's tiled. */ | 147 | /** Current tiling stride for the object, if it's tiled. */ |
149 | unsigned int tiling_and_stride; | 148 | unsigned int tiling_and_stride; |
@@ -224,9 +223,6 @@ struct drm_i915_gem_object { | |||
224 | bool quirked:1; | 223 | bool quirked:1; |
225 | } mm; | 224 | } mm; |
226 | 225 | ||
227 | /** References from framebuffers, locks out tiling changes. */ | ||
228 | unsigned int framebuffer_references; | ||
229 | |||
230 | /** Record of address bit 17 of each page at last unbind. */ | 226 | /** Record of address bit 17 of each page at last unbind. */ |
231 | unsigned long *bit_17; | 227 | unsigned long *bit_17; |
232 | 228 | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ef4f84e060ee..e7ce739fe545 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -138,7 +138,6 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
138 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); | 138 | struct drm_i915_private *dev_priv = to_i915(obj->base.dev); |
139 | struct intel_engine_cs *engine; | 139 | struct intel_engine_cs *engine; |
140 | struct i915_vma *vma; | 140 | struct i915_vma *vma; |
141 | unsigned int frontbuffer_bits; | ||
142 | int pin_count = 0; | 141 | int pin_count = 0; |
143 | 142 | ||
144 | seq_printf(m, "%pK: %c%c%c%c %8zdKiB %02x %02x %s%s%s", | 143 | seq_printf(m, "%pK: %c%c%c%c %8zdKiB %02x %02x %s%s%s", |
@@ -228,10 +227,6 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) | |||
228 | engine = i915_gem_object_last_write_engine(obj); | 227 | engine = i915_gem_object_last_write_engine(obj); |
229 | if (engine) | 228 | if (engine) |
230 | seq_printf(m, " (%s)", engine->name); | 229 | seq_printf(m, " (%s)", engine->name); |
231 | |||
232 | frontbuffer_bits = atomic_read(&obj->frontbuffer_bits); | ||
233 | if (frontbuffer_bits) | ||
234 | seq_printf(m, " (frontbuffer: 0x%03x)", frontbuffer_bits); | ||
235 | } | 230 | } |
236 | 231 | ||
237 | struct file_stats { | 232 | struct file_stats { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 50effdccc76c..b6beae12cd21 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -2355,10 +2355,6 @@ int i915_gem_mmap_gtt(struct drm_file *file_priv, struct drm_device *dev, | |||
2355 | u32 handle, u64 *offset); | 2355 | u32 handle, u64 *offset); |
2356 | int i915_gem_mmap_gtt_version(void); | 2356 | int i915_gem_mmap_gtt_version(void); |
2357 | 2357 | ||
2358 | void i915_gem_track_fb(struct drm_i915_gem_object *old, | ||
2359 | struct drm_i915_gem_object *new, | ||
2360 | unsigned frontbuffer_bits); | ||
2361 | |||
2362 | int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno); | 2358 | int __must_check i915_gem_set_global_seqno(struct drm_device *dev, u32 seqno); |
2363 | 2359 | ||
2364 | static inline u32 i915_reset_count(struct i915_gpu_error *error) | 2360 | static inline u32 i915_reset_count(struct i915_gpu_error *error) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 29be25a7aade..71ee4c710252 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -139,17 +139,19 @@ i915_gem_phys_pwrite(struct drm_i915_gem_object *obj, | |||
139 | void *vaddr = obj->phys_handle->vaddr + args->offset; | 139 | void *vaddr = obj->phys_handle->vaddr + args->offset; |
140 | char __user *user_data = u64_to_user_ptr(args->data_ptr); | 140 | char __user *user_data = u64_to_user_ptr(args->data_ptr); |
141 | 141 | ||
142 | /* We manually control the domain here and pretend that it | 142 | /* |
143 | * We manually control the domain here and pretend that it | ||
143 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. | 144 | * remains coherent i.e. in the GTT domain, like shmem_pwrite. |
144 | */ | 145 | */ |
145 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 146 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); |
147 | |||
146 | if (copy_from_user(vaddr, user_data, args->size)) | 148 | if (copy_from_user(vaddr, user_data, args->size)) |
147 | return -EFAULT; | 149 | return -EFAULT; |
148 | 150 | ||
149 | drm_clflush_virt_range(vaddr, args->size); | 151 | drm_clflush_virt_range(vaddr, args->size); |
150 | intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); | 152 | intel_gt_chipset_flush(&to_i915(obj->base.dev)->gt); |
151 | 153 | ||
152 | intel_fb_obj_flush(obj, ORIGIN_CPU); | 154 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); |
153 | return 0; | 155 | return 0; |
154 | } | 156 | } |
155 | 157 | ||
@@ -594,7 +596,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, | |||
594 | goto out_unpin; | 596 | goto out_unpin; |
595 | } | 597 | } |
596 | 598 | ||
597 | intel_fb_obj_invalidate(obj, ORIGIN_CPU); | 599 | intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CPU); |
598 | 600 | ||
599 | user_data = u64_to_user_ptr(args->data_ptr); | 601 | user_data = u64_to_user_ptr(args->data_ptr); |
600 | offset = args->offset; | 602 | offset = args->offset; |
@@ -636,7 +638,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_gem_object *obj, | |||
636 | user_data += page_length; | 638 | user_data += page_length; |
637 | offset += page_length; | 639 | offset += page_length; |
638 | } | 640 | } |
639 | intel_fb_obj_flush(obj, ORIGIN_CPU); | 641 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); |
640 | 642 | ||
641 | i915_gem_object_unlock_fence(obj, fence); | 643 | i915_gem_object_unlock_fence(obj, fence); |
642 | out_unpin: | 644 | out_unpin: |
@@ -729,7 +731,7 @@ i915_gem_shmem_pwrite(struct drm_i915_gem_object *obj, | |||
729 | offset = 0; | 731 | offset = 0; |
730 | } | 732 | } |
731 | 733 | ||
732 | intel_fb_obj_flush(obj, ORIGIN_CPU); | 734 | intel_frontbuffer_flush(obj->frontbuffer, ORIGIN_CPU); |
733 | i915_gem_object_unlock_fence(obj, fence); | 735 | i915_gem_object_unlock_fence(obj, fence); |
734 | 736 | ||
735 | return ret; | 737 | return ret; |
@@ -1763,39 +1765,6 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file) | |||
1763 | return ret; | 1765 | return ret; |
1764 | } | 1766 | } |
1765 | 1767 | ||
1766 | /** | ||
1767 | * i915_gem_track_fb - update frontbuffer tracking | ||
1768 | * @old: current GEM buffer for the frontbuffer slots | ||
1769 | * @new: new GEM buffer for the frontbuffer slots | ||
1770 | * @frontbuffer_bits: bitmask of frontbuffer slots | ||
1771 | * | ||
1772 | * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them | ||
1773 | * from @old and setting them in @new. Both @old and @new can be NULL. | ||
1774 | */ | ||
1775 | void i915_gem_track_fb(struct drm_i915_gem_object *old, | ||
1776 | struct drm_i915_gem_object *new, | ||
1777 | unsigned frontbuffer_bits) | ||
1778 | { | ||
1779 | /* Control of individual bits within the mask are guarded by | ||
1780 | * the owning plane->mutex, i.e. we can never see concurrent | ||
1781 | * manipulation of individual bits. But since the bitfield as a whole | ||
1782 | * is updated using RMW, we need to use atomics in order to update | ||
1783 | * the bits. | ||
1784 | */ | ||
1785 | BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > | ||
1786 | BITS_PER_TYPE(atomic_t)); | ||
1787 | |||
1788 | if (old) { | ||
1789 | WARN_ON(!(atomic_read(&old->frontbuffer_bits) & frontbuffer_bits)); | ||
1790 | atomic_andnot(frontbuffer_bits, &old->frontbuffer_bits); | ||
1791 | } | ||
1792 | |||
1793 | if (new) { | ||
1794 | WARN_ON(atomic_read(&new->frontbuffer_bits) & frontbuffer_bits); | ||
1795 | atomic_or(frontbuffer_bits, &new->frontbuffer_bits); | ||
1796 | } | ||
1797 | } | ||
1798 | |||
1799 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) | 1768 | #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) |
1800 | #include "selftests/mock_gem_device.c" | 1769 | #include "selftests/mock_gem_device.c" |
1801 | #include "selftests/i915_gem.c" | 1770 | #include "selftests/i915_gem.c" |
diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 8be1bbef40e5..d38ef2ef3ce4 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c | |||
@@ -908,8 +908,10 @@ int i915_vma_move_to_active(struct i915_vma *vma, | |||
908 | return err; | 908 | return err; |
909 | 909 | ||
910 | if (flags & EXEC_OBJECT_WRITE) { | 910 | if (flags & EXEC_OBJECT_WRITE) { |
911 | if (intel_fb_obj_invalidate(obj, ORIGIN_CS)) | 911 | if (intel_frontbuffer_invalidate(obj->frontbuffer, ORIGIN_CS)) |
912 | __i915_active_request_set(&obj->frontbuffer_write, rq); | 912 | i915_active_ref(&obj->frontbuffer->write, |
913 | rq->fence.context, | ||
914 | rq); | ||
913 | 915 | ||
914 | reservation_object_add_excl_fence(vma->resv, &rq->fence); | 916 | reservation_object_add_excl_fence(vma->resv, &rq->fence); |
915 | obj->write_domain = I915_GEM_DOMAIN_RENDER; | 917 | obj->write_domain = I915_GEM_DOMAIN_RENDER; |