1 1.3 riastrad /* $NetBSD: intel_frontbuffer.c,v 1.3 2021/12/19 12:09:43 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2014 Intel Corporation 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 1.1 riastrad * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 1.1 riastrad * DEALINGS IN THE SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Daniel Vetter <daniel.vetter (at) ffwll.ch> 27 1.1 riastrad */ 28 1.1 riastrad 29 1.1 riastrad /** 30 1.1 riastrad * DOC: frontbuffer tracking 31 1.1 riastrad * 32 1.1 riastrad * Many features require us to track changes to the currently active 33 1.1 riastrad * frontbuffer, especially rendering targeted at the frontbuffer. 34 1.1 riastrad * 35 1.1 riastrad * To be able to do so we track frontbuffers using a bitmask for all possible 36 1.1 riastrad * frontbuffer slots through intel_frontbuffer_track(). The functions in this 37 1.1 riastrad * file are then called when the contents of the frontbuffer are invalidated, 38 1.1 riastrad * when frontbuffer rendering has stopped again to flush out all the changes 39 1.1 riastrad * and when the frontbuffer is exchanged with a flip. Subsystems interested in 40 1.1 riastrad * frontbuffer changes (e.g. PSR, FBC, DRRS) should directly put their callbacks 41 1.1 riastrad * into the relevant places and filter for the frontbuffer slots that they are 42 1.1 riastrad * interested int. 43 1.1 riastrad * 44 1.1 riastrad * On a high level there are two types of powersaving features. The first one 45 1.1 riastrad * work like a special cache (FBC and PSR) and are interested when they should 46 1.1 riastrad * stop caching and when to restart caching. This is done by placing callbacks 47 1.1 riastrad * into the invalidate and the flush functions: At invalidate the caching must 48 1.1 riastrad * be stopped and at flush time it can be restarted. And maybe they need to know 49 1.1 riastrad * when the frontbuffer changes (e.g. when the hw doesn't initiate an invalidate 50 1.1 riastrad * and flush on its own) which can be achieved with placing callbacks into the 51 1.1 riastrad * flip functions. 52 1.1 riastrad * 53 1.1 riastrad * The other type of display power saving feature only cares about busyness 54 1.1 riastrad * (e.g. DRRS). In that case all three (invalidate, flush and flip) indicate 55 1.1 riastrad * busyness. There is no direct way to detect idleness. Instead an idle timer 56 1.1 riastrad * work delayed work should be started from the flush and flip functions and 57 1.1 riastrad * cancelled as soon as busyness is detected. 58 1.1 riastrad */ 59 1.1 riastrad 60 1.1 riastrad #include <sys/cdefs.h> 61 1.3 riastrad __KERNEL_RCSID(0, "$NetBSD: intel_frontbuffer.c,v 1.3 2021/12/19 12:09:43 riastradh Exp $"); 62 1.1 riastrad 63 1.1 riastrad #include "display/intel_dp.h" 64 1.1 riastrad 65 1.1 riastrad #include "i915_drv.h" 66 1.1 riastrad #include "intel_display_types.h" 67 1.1 riastrad #include "intel_fbc.h" 68 1.1 riastrad #include "intel_frontbuffer.h" 69 1.1 riastrad #include "intel_psr.h" 70 1.1 riastrad 71 1.1 riastrad /** 72 1.1 riastrad * frontbuffer_flush - flush frontbuffer 73 1.1 riastrad * @i915: i915 device 74 1.1 riastrad * @frontbuffer_bits: frontbuffer plane tracking bits 75 1.1 riastrad * @origin: which operation caused the flush 76 1.1 riastrad * 77 1.1 riastrad * This function gets called every time rendering on the given planes has 78 1.1 riastrad * completed and frontbuffer caching can be started again. Flushes will get 79 1.1 riastrad * delayed if they're blocked by some outstanding asynchronous rendering. 80 1.1 riastrad * 81 1.1 riastrad * Can be called without any locks held. 82 1.1 riastrad */ 83 1.1 riastrad static void frontbuffer_flush(struct drm_i915_private *i915, 84 1.1 riastrad unsigned int frontbuffer_bits, 85 1.1 riastrad enum fb_op_origin origin) 86 1.1 riastrad { 87 1.1 riastrad /* Delay flushing when rings are still busy.*/ 88 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 89 1.1 riastrad frontbuffer_bits &= ~i915->fb_tracking.busy_bits; 90 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 91 1.1 riastrad 92 1.1 riastrad if (!frontbuffer_bits) 93 1.1 riastrad return; 94 1.1 riastrad 95 1.1 riastrad might_sleep(); 96 1.1 riastrad intel_edp_drrs_flush(i915, frontbuffer_bits); 97 1.1 riastrad intel_psr_flush(i915, frontbuffer_bits, origin); 98 1.1 riastrad intel_fbc_flush(i915, frontbuffer_bits, origin); 99 1.1 riastrad } 100 1.1 riastrad 101 1.1 riastrad /** 102 1.1 riastrad * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip 103 1.1 riastrad * @i915: i915 device 104 1.1 riastrad * @frontbuffer_bits: frontbuffer plane tracking bits 105 1.1 riastrad * 106 1.1 riastrad * This function gets called after scheduling a flip on @obj. The actual 107 1.1 riastrad * frontbuffer flushing will be delayed until completion is signalled with 108 1.1 riastrad * intel_frontbuffer_flip_complete. If an invalidate happens in between this 109 1.1 riastrad * flush will be cancelled. 110 1.1 riastrad * 111 1.1 riastrad * Can be called without any locks held. 112 1.1 riastrad */ 113 1.1 riastrad void intel_frontbuffer_flip_prepare(struct drm_i915_private *i915, 114 1.1 riastrad unsigned frontbuffer_bits) 115 1.1 riastrad { 116 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 117 1.1 riastrad i915->fb_tracking.flip_bits |= frontbuffer_bits; 118 1.1 riastrad /* Remove stale busy bits due to the old buffer. */ 119 1.1 riastrad i915->fb_tracking.busy_bits &= ~frontbuffer_bits; 120 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 121 1.1 riastrad } 122 1.1 riastrad 123 1.1 riastrad /** 124 1.1 riastrad * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip 125 1.1 riastrad * @i915: i915 device 126 1.1 riastrad * @frontbuffer_bits: frontbuffer plane tracking bits 127 1.1 riastrad * 128 1.1 riastrad * This function gets called after the flip has been latched and will complete 129 1.1 riastrad * on the next vblank. It will execute the flush if it hasn't been cancelled yet. 130 1.1 riastrad * 131 1.1 riastrad * Can be called without any locks held. 132 1.1 riastrad */ 133 1.1 riastrad void intel_frontbuffer_flip_complete(struct drm_i915_private *i915, 134 1.1 riastrad unsigned frontbuffer_bits) 135 1.1 riastrad { 136 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 137 1.1 riastrad /* Mask any cancelled flips. */ 138 1.1 riastrad frontbuffer_bits &= i915->fb_tracking.flip_bits; 139 1.1 riastrad i915->fb_tracking.flip_bits &= ~frontbuffer_bits; 140 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 141 1.1 riastrad 142 1.1 riastrad if (frontbuffer_bits) 143 1.1 riastrad frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); 144 1.1 riastrad } 145 1.1 riastrad 146 1.1 riastrad /** 147 1.1 riastrad * intel_frontbuffer_flip - synchronous frontbuffer flip 148 1.1 riastrad * @i915: i915 device 149 1.1 riastrad * @frontbuffer_bits: frontbuffer plane tracking bits 150 1.1 riastrad * 151 1.1 riastrad * This function gets called after scheduling a flip on @obj. This is for 152 1.1 riastrad * synchronous plane updates which will happen on the next vblank and which will 153 1.1 riastrad * not get delayed by pending gpu rendering. 154 1.1 riastrad * 155 1.1 riastrad * Can be called without any locks held. 156 1.1 riastrad */ 157 1.1 riastrad void intel_frontbuffer_flip(struct drm_i915_private *i915, 158 1.1 riastrad unsigned frontbuffer_bits) 159 1.1 riastrad { 160 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 161 1.1 riastrad /* Remove stale busy bits due to the old buffer. */ 162 1.1 riastrad i915->fb_tracking.busy_bits &= ~frontbuffer_bits; 163 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 164 1.1 riastrad 165 1.1 riastrad frontbuffer_flush(i915, frontbuffer_bits, ORIGIN_FLIP); 166 1.1 riastrad } 167 1.1 riastrad 168 1.1 riastrad void __intel_fb_invalidate(struct intel_frontbuffer *front, 169 1.1 riastrad enum fb_op_origin origin, 170 1.1 riastrad unsigned int frontbuffer_bits) 171 1.1 riastrad { 172 1.1 riastrad struct drm_i915_private *i915 = to_i915(front->obj->base.dev); 173 1.1 riastrad 174 1.1 riastrad if (origin == ORIGIN_CS) { 175 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 176 1.1 riastrad i915->fb_tracking.busy_bits |= frontbuffer_bits; 177 1.1 riastrad i915->fb_tracking.flip_bits &= ~frontbuffer_bits; 178 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 179 1.1 riastrad } 180 1.1 riastrad 181 1.1 riastrad might_sleep(); 182 1.1 riastrad intel_psr_invalidate(i915, frontbuffer_bits, origin); 183 1.1 riastrad intel_edp_drrs_invalidate(i915, frontbuffer_bits); 184 1.1 riastrad intel_fbc_invalidate(i915, frontbuffer_bits, origin); 185 1.1 riastrad } 186 1.1 riastrad 187 1.1 riastrad void __intel_fb_flush(struct intel_frontbuffer *front, 188 1.1 riastrad enum fb_op_origin origin, 189 1.1 riastrad unsigned int frontbuffer_bits) 190 1.1 riastrad { 191 1.1 riastrad struct drm_i915_private *i915 = to_i915(front->obj->base.dev); 192 1.1 riastrad 193 1.1 riastrad if (origin == ORIGIN_CS) { 194 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 195 1.1 riastrad /* Filter out new bits since rendering started. */ 196 1.1 riastrad frontbuffer_bits &= i915->fb_tracking.busy_bits; 197 1.1 riastrad i915->fb_tracking.busy_bits &= ~frontbuffer_bits; 198 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 199 1.1 riastrad } 200 1.1 riastrad 201 1.1 riastrad if (frontbuffer_bits) 202 1.1 riastrad frontbuffer_flush(i915, frontbuffer_bits, origin); 203 1.1 riastrad } 204 1.1 riastrad 205 1.1 riastrad static int frontbuffer_active(struct i915_active *ref) 206 1.1 riastrad { 207 1.1 riastrad struct intel_frontbuffer *front = 208 1.1 riastrad container_of(ref, typeof(*front), write); 209 1.1 riastrad 210 1.1 riastrad kref_get(&front->ref); 211 1.1 riastrad return 0; 212 1.1 riastrad } 213 1.1 riastrad 214 1.1 riastrad __i915_active_call 215 1.1 riastrad static void frontbuffer_retire(struct i915_active *ref) 216 1.1 riastrad { 217 1.1 riastrad struct intel_frontbuffer *front = 218 1.1 riastrad container_of(ref, typeof(*front), write); 219 1.1 riastrad 220 1.1 riastrad intel_frontbuffer_flush(front, ORIGIN_CS); 221 1.1 riastrad intel_frontbuffer_put(front); 222 1.1 riastrad } 223 1.1 riastrad 224 1.1 riastrad static void frontbuffer_release(struct kref *ref) 225 1.1 riastrad __releases(&to_i915(front->obj->base.dev)->fb_tracking.lock) 226 1.1 riastrad { 227 1.1 riastrad struct intel_frontbuffer *front = 228 1.1 riastrad container_of(ref, typeof(*front), ref); 229 1.1 riastrad struct drm_i915_gem_object *obj = front->obj; 230 1.1 riastrad struct i915_vma *vma; 231 1.1 riastrad 232 1.1 riastrad spin_lock(&obj->vma.lock); 233 1.1 riastrad for_each_ggtt_vma(vma, obj) 234 1.1 riastrad vma->display_alignment = I915_GTT_MIN_ALIGNMENT; 235 1.1 riastrad spin_unlock(&obj->vma.lock); 236 1.1 riastrad 237 1.1 riastrad RCU_INIT_POINTER(obj->frontbuffer, NULL); 238 1.1 riastrad spin_unlock(&to_i915(obj->base.dev)->fb_tracking.lock); 239 1.1 riastrad 240 1.1 riastrad i915_gem_object_put(obj); 241 1.3 riastrad i915_active_fini(&front->write); 242 1.1 riastrad kfree_rcu(front, rcu); 243 1.1 riastrad } 244 1.1 riastrad 245 1.1 riastrad struct intel_frontbuffer * 246 1.1 riastrad intel_frontbuffer_get(struct drm_i915_gem_object *obj) 247 1.1 riastrad { 248 1.1 riastrad struct drm_i915_private *i915 = to_i915(obj->base.dev); 249 1.1 riastrad struct intel_frontbuffer *front; 250 1.1 riastrad 251 1.1 riastrad front = __intel_frontbuffer_get(obj); 252 1.1 riastrad if (front) 253 1.1 riastrad return front; 254 1.1 riastrad 255 1.1 riastrad front = kmalloc(sizeof(*front), GFP_KERNEL); 256 1.1 riastrad if (!front) 257 1.1 riastrad return NULL; 258 1.1 riastrad 259 1.1 riastrad front->obj = obj; 260 1.1 riastrad kref_init(&front->ref); 261 1.1 riastrad atomic_set(&front->bits, 0); 262 1.1 riastrad i915_active_init(&front->write, 263 1.1 riastrad frontbuffer_active, 264 1.1 riastrad i915_active_may_sleep(frontbuffer_retire)); 265 1.1 riastrad 266 1.1 riastrad spin_lock(&i915->fb_tracking.lock); 267 1.1 riastrad if (rcu_access_pointer(obj->frontbuffer)) { 268 1.1 riastrad kfree(front); 269 1.1 riastrad front = rcu_dereference_protected(obj->frontbuffer, true); 270 1.1 riastrad kref_get(&front->ref); 271 1.1 riastrad } else { 272 1.1 riastrad i915_gem_object_get(obj); 273 1.1 riastrad rcu_assign_pointer(obj->frontbuffer, front); 274 1.1 riastrad } 275 1.1 riastrad spin_unlock(&i915->fb_tracking.lock); 276 1.1 riastrad 277 1.1 riastrad return front; 278 1.1 riastrad } 279 1.1 riastrad 280 1.1 riastrad void intel_frontbuffer_put(struct intel_frontbuffer *front) 281 1.1 riastrad { 282 1.1 riastrad kref_put_lock(&front->ref, 283 1.1 riastrad frontbuffer_release, 284 1.1 riastrad &to_i915(front->obj->base.dev)->fb_tracking.lock); 285 1.1 riastrad } 286 1.1 riastrad 287 1.1 riastrad /** 288 1.1 riastrad * intel_frontbuffer_track - update frontbuffer tracking 289 1.1 riastrad * @old: current buffer for the frontbuffer slots 290 1.1 riastrad * @new: new buffer for the frontbuffer slots 291 1.1 riastrad * @frontbuffer_bits: bitmask of frontbuffer slots 292 1.1 riastrad * 293 1.1 riastrad * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them 294 1.1 riastrad * from @old and setting them in @new. Both @old and @new can be NULL. 295 1.1 riastrad */ 296 1.1 riastrad void intel_frontbuffer_track(struct intel_frontbuffer *old, 297 1.1 riastrad struct intel_frontbuffer *new, 298 1.1 riastrad unsigned int frontbuffer_bits) 299 1.1 riastrad { 300 1.1 riastrad /* 301 1.1 riastrad * Control of individual bits within the mask are guarded by 302 1.1 riastrad * the owning plane->mutex, i.e. we can never see concurrent 303 1.1 riastrad * manipulation of individual bits. But since the bitfield as a whole 304 1.1 riastrad * is updated using RMW, we need to use atomics in order to update 305 1.1 riastrad * the bits. 306 1.1 riastrad */ 307 1.1 riastrad BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > 308 1.1 riastrad BITS_PER_TYPE(atomic_t)); 309 1.1 riastrad 310 1.1 riastrad if (old) { 311 1.1 riastrad WARN_ON(!(atomic_read(&old->bits) & frontbuffer_bits)); 312 1.1 riastrad atomic_andnot(frontbuffer_bits, &old->bits); 313 1.1 riastrad } 314 1.1 riastrad 315 1.1 riastrad if (new) { 316 1.1 riastrad WARN_ON(atomic_read(&new->bits) & frontbuffer_bits); 317 1.1 riastrad atomic_or(frontbuffer_bits, &new->bits); 318 1.1 riastrad } 319 1.1 riastrad } 320