0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 #include "i915_drv.h"
0059 #include "intel_display_trace.h"
0060 #include "intel_display_types.h"
0061 #include "intel_dp.h"
0062 #include "intel_drrs.h"
0063 #include "intel_fbc.h"
0064 #include "intel_frontbuffer.h"
0065 #include "intel_psr.h"
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 static void frontbuffer_flush(struct drm_i915_private *i915,
0080 unsigned int frontbuffer_bits,
0081 enum fb_op_origin origin)
0082 {
0083
0084 spin_lock(&i915->fb_tracking.lock);
0085 frontbuffer_bits &= ~i915->fb_tracking.busy_bits;
0086 spin_unlock(&i915->fb_tracking.lock);
0087
0088 if (!frontbuffer_bits)
0089 return;
0090
0091 trace_intel_frontbuffer_flush(frontbuffer_bits, origin);
0092
0093 might_sleep();
0094 intel_drrs_flush(i915, frontbuffer_bits);
0095 intel_psr_flush(i915, frontbuffer_bits, origin);
0096 intel_fbc_flush(i915, frontbuffer_bits, origin);
0097 }
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111 void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915,
0112 unsigned frontbuffer_bits)
0113 {
0114 spin_lock(&i915->fb_tracking.lock);
0115 i915->fb_tracking.flip_bits |= frontbuffer_bits;
0116
0117 i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
0118 spin_unlock(&i915->fb_tracking.lock);
0119 }
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 void intel_frontbuffer_flip_complete(struct drm_i915_private *i915,
0132 unsigned frontbuffer_bits)
0133 {
0134 spin_lock(&i915->fb_tracking.lock);
0135
0136 frontbuffer_bits &= i915->fb_tracking.flip_bits;
0137 i915->fb_tracking.flip_bits &= ~frontbuffer_bits;
0138 spin_unlock(&i915->fb_tracking.lock);
0139
0140 if (frontbuffer_bits)
0141 frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
0142 }
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 void intel_frontbuffer_flip(struct drm_i915_private *i915,
0156 unsigned frontbuffer_bits)
0157 {
0158 spin_lock(&i915->fb_tracking.lock);
0159
0160 i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
0161 spin_unlock(&i915->fb_tracking.lock);
0162
0163 frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP);
0164 }
0165
0166 void __intel_fb_invalidate(struct intel_frontbuffer *front,
0167 enum fb_op_origin origin,
0168 unsigned int frontbuffer_bits)
0169 {
0170 struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
0171
0172 if (origin == ORIGIN_CS) {
0173 spin_lock(&i915->fb_tracking.lock);
0174 i915->fb_tracking.busy_bits |= frontbuffer_bits;
0175 i915->fb_tracking.flip_bits &= ~frontbuffer_bits;
0176 spin_unlock(&i915->fb_tracking.lock);
0177 }
0178
0179 trace_intel_frontbuffer_invalidate(frontbuffer_bits, origin);
0180
0181 might_sleep();
0182 intel_psr_invalidate(i915, frontbuffer_bits, origin);
0183 intel_drrs_invalidate(i915, frontbuffer_bits);
0184 intel_fbc_invalidate(i915, frontbuffer_bits, origin);
0185 }
0186
0187 void __intel_fb_flush(struct intel_frontbuffer *front,
0188 enum fb_op_origin origin,
0189 unsigned int frontbuffer_bits)
0190 {
0191 struct drm_i915_private *i915 = to_i915(front->obj->base.dev);
0192
0193 if (origin == ORIGIN_CS) {
0194 spin_lock(&i915->fb_tracking.lock);
0195
0196 frontbuffer_bits &= i915->fb_tracking.busy_bits;
0197 i915->fb_tracking.busy_bits &= ~frontbuffer_bits;
0198 spin_unlock(&i915->fb_tracking.lock);
0199 }
0200
0201 if (frontbuffer_bits)
0202 frontbuffer_flush(i915, frontbuffer_bits, origin);
0203 }
0204
0205 static int frontbuffer_active(struct i915_active *ref)
0206 {
0207 struct intel_frontbuffer *front =
0208 container_of(ref, typeof(*front), write);
0209
0210 kref_get(&front->ref);
0211 return 0;
0212 }
0213
0214 static void frontbuffer_retire(struct i915_active *ref)
0215 {
0216 struct intel_frontbuffer *front =
0217 container_of(ref, typeof(*front), write);
0218
0219 intel_frontbuffer_flush(front, ORIGIN_CS);
0220 intel_frontbuffer_put(front);
0221 }
0222
0223 static void frontbuffer_release(struct kref *ref)
0224 __releases(&to_i915(front->obj->base.dev)->fb_tracking.lock)
0225 {
0226 struct intel_frontbuffer *front =
0227 container_of(ref, typeof(*front), ref);
0228 struct drm_i915_gem_object *obj = front->obj;
0229 struct i915_vma *vma;
0230
0231 drm_WARN_ON(obj->base.dev, atomic_read(&front->bits));
0232
0233 spin_lock(&obj->vma.lock);
0234 for_each_ggtt_vma(vma, obj) {
0235 i915_vma_clear_scanout(vma);
0236 vma->display_alignment = I915_GTT_MIN_ALIGNMENT;
0237 }
0238 spin_unlock(&obj->vma.lock);
0239
0240 RCU_INIT_POINTER(obj->frontbuffer, NULL);
0241 spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock);
0242
0243 i915_active_fini(&front->write);
0244
0245 i915_gem_object_put(obj);
0246 kfree_rcu(front, rcu);
0247 }
0248
0249 struct intel_frontbuffer *
0250 intel_frontbuffer_get(struct drm_i915_gem_object *obj)
0251 {
0252 struct drm_i915_private *i915 = to_i915(obj->base.dev);
0253 struct intel_frontbuffer *front;
0254
0255 front = __intel_frontbuffer_get(obj);
0256 if (front)
0257 return front;
0258
0259 front = kmalloc(sizeof(*front), GFP_KERNEL);
0260 if (!front)
0261 return NULL;
0262
0263 front->obj = obj;
0264 kref_init(&front->ref);
0265 atomic_set(&front->bits, 0);
0266 i915_active_init(&front->write,
0267 frontbuffer_active,
0268 frontbuffer_retire,
0269 I915_ACTIVE_RETIRE_SLEEPS);
0270
0271 spin_lock(&i915->fb_tracking.lock);
0272 if (rcu_access_pointer(obj->frontbuffer)) {
0273 kfree(front);
0274 front = rcu_dereference_protected(obj->frontbuffer, true);
0275 kref_get(&front->ref);
0276 } else {
0277 i915_gem_object_get(obj);
0278 rcu_assign_pointer(obj->frontbuffer, front);
0279 }
0280 spin_unlock(&i915->fb_tracking.lock);
0281
0282 return front;
0283 }
0284
0285 void intel_frontbuffer_put(struct intel_frontbuffer *front)
0286 {
0287 kref_put_lock(&front->ref,
0288 frontbuffer_release,
0289 &to_i915(front->obj->base.dev)->fb_tracking.lock);
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 void intel_frontbuffer_track(struct intel_frontbuffer *old,
0302 struct intel_frontbuffer *new,
0303 unsigned int frontbuffer_bits)
0304 {
0305
0306
0307
0308
0309
0310
0311
0312 BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES >
0313 BITS_PER_TYPE(atomic_t));
0314
0315 if (old) {
0316 drm_WARN_ON(old->obj->base.dev,
0317 !(atomic_read(&old->bits) & frontbuffer_bits));
0318 atomic_andnot(frontbuffer_bits, &old->bits);
0319 }
0320
0321 if (new) {
0322 drm_WARN_ON(new->obj->base.dev,
0323 atomic_read(&new->bits) & frontbuffer_bits);
0324 atomic_or(frontbuffer_bits, &new->bits);
0325 }
0326 }