1 /* 2 * Copyright © 2014 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Daniel Vetter <daniel.vetter@ffwll.ch> 25 */ 26 27 /** 28 * DOC: frontbuffer tracking 29 * 30 * Many features require us to track changes to the currently active 31 * frontbuffer, especially rendering targeted at the frontbuffer. 32 * 33 * To be able to do so we track frontbuffers using a bitmask for all possible 34 * frontbuffer slots through intel_frontbuffer_track(). The functions in this 35 * file are then called when the contents of the frontbuffer are invalidated, 36 * when frontbuffer rendering has stopped again to flush out all the changes 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 39 * into the relevant places and filter for the frontbuffer slots that they are 40 * interested int. 41 * 42 * On a high level there are two types of powersaving features. The first one 43 * work like a special cache (FBC and PSR) and are interested when they should 44 * stop caching and when to restart caching. This is done by placing callbacks 45 * into the invalidate and the flush functions: At invalidate the caching must 46 * be stopped and at flush time it can be restarted. And maybe they need to know 47 * when the frontbuffer changes (e.g. when the hw doesn't initiate an invalidate 48 * and flush on its own) which can be achieved with placing callbacks into the 49 * flip functions. 50 * 51 * The other type of display power saving feature only cares about busyness 52 * (e.g. DRRS). In that case all three (invalidate, flush and flip) indicate 53 * busyness. There is no direct way to detect idleness. Instead an idle timer 54 * work delayed work should be started from the flush and flip functions and 55 * cancelled as soon as busyness is detected. 56 */ 57 58 #include <drm/drm_gem.h> 59 #include <drm/drm_print.h> 60 61 #include "intel_display_trace.h" 62 #include "intel_display_types.h" 63 #include "intel_dp.h" 64 #include "intel_drrs.h" 65 #include "intel_fbc.h" 66 #include "intel_frontbuffer.h" 67 #include "intel_parent.h" 68 #include "intel_psr.h" 69 70 /** 71 * frontbuffer_flush - flush frontbuffer 72 * @display: display device 73 * @frontbuffer_bits: frontbuffer plane tracking bits 74 * @origin: which operation caused the flush 75 * 76 * This function gets called every time rendering on the given planes has 77 * completed and frontbuffer caching can be started again. Flushes will get 78 * delayed if they're blocked by some outstanding asynchronous rendering. 79 * 80 * Can be called without any locks held. 81 */ 82 static void frontbuffer_flush(struct intel_display *display, 83 unsigned int frontbuffer_bits, 84 enum fb_op_origin origin) 85 { 86 /* Delay flushing when rings are still busy.*/ 87 spin_lock(&display->fb_tracking.lock); 88 frontbuffer_bits &= ~display->fb_tracking.busy_bits; 89 spin_unlock(&display->fb_tracking.lock); 90 91 if (!frontbuffer_bits) 92 return; 93 94 trace_intel_frontbuffer_flush(display, frontbuffer_bits, origin); 95 96 might_sleep(); 97 intel_parent_transient_data_flush(display); 98 intel_drrs_flush(display, frontbuffer_bits); 99 intel_psr_flush(display, frontbuffer_bits, origin); 100 intel_fbc_flush(display, frontbuffer_bits, origin); 101 } 102 103 /** 104 * intel_frontbuffer_flip - synchronous frontbuffer flip 105 * @display: display device 106 * @frontbuffer_bits: frontbuffer plane tracking bits 107 * 108 * This function gets called after scheduling a flip on @obj. This is for 109 * synchronous plane updates which will happen on the next vblank and which will 110 * not get delayed by pending gpu rendering. 111 * 112 * Can be called without any locks held. 113 */ 114 void intel_frontbuffer_flip(struct intel_display *display, 115 unsigned frontbuffer_bits) 116 { 117 spin_lock(&display->fb_tracking.lock); 118 /* Remove stale busy bits due to the old buffer. */ 119 display->fb_tracking.busy_bits &= ~frontbuffer_bits; 120 spin_unlock(&display->fb_tracking.lock); 121 122 frontbuffer_flush(display, frontbuffer_bits, ORIGIN_FLIP); 123 } 124 125 void __intel_frontbuffer_invalidate(struct intel_frontbuffer *front, 126 enum fb_op_origin origin, 127 unsigned int frontbuffer_bits) 128 { 129 struct intel_display *display = front->display; 130 131 if (origin == ORIGIN_CS) { 132 spin_lock(&display->fb_tracking.lock); 133 display->fb_tracking.busy_bits |= frontbuffer_bits; 134 spin_unlock(&display->fb_tracking.lock); 135 } 136 137 trace_intel_frontbuffer_invalidate(display, frontbuffer_bits, origin); 138 139 might_sleep(); 140 intel_psr_invalidate(display, frontbuffer_bits, origin); 141 intel_drrs_invalidate(display, frontbuffer_bits); 142 intel_fbc_invalidate(display, frontbuffer_bits, origin); 143 } 144 145 void __intel_frontbuffer_flush(struct intel_frontbuffer *front, 146 enum fb_op_origin origin, 147 unsigned int frontbuffer_bits) 148 { 149 struct intel_display *display = front->display; 150 151 if (origin == ORIGIN_DIRTYFB) 152 intel_parent_frontbuffer_flush_for_display(display, front); 153 154 if (origin == ORIGIN_CS) { 155 spin_lock(&display->fb_tracking.lock); 156 /* Filter out new bits since rendering started. */ 157 frontbuffer_bits &= display->fb_tracking.busy_bits; 158 display->fb_tracking.busy_bits &= ~frontbuffer_bits; 159 spin_unlock(&display->fb_tracking.lock); 160 } 161 162 if (frontbuffer_bits) 163 frontbuffer_flush(display, frontbuffer_bits, origin); 164 } 165 166 static void intel_frontbuffer_flush_work(struct work_struct *work) 167 { 168 struct intel_frontbuffer *front = 169 container_of(work, struct intel_frontbuffer, flush_work); 170 171 intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); 172 intel_parent_frontbuffer_put(front->display, front); 173 } 174 175 /** 176 * intel_frontbuffer_queue_flush - queue flushing frontbuffer object 177 * @front: GEM object to flush 178 * 179 * This function is targeted for our dirty callback for queueing flush when 180 * dma fence is signals 181 */ 182 void intel_frontbuffer_queue_flush(struct intel_frontbuffer *front) 183 { 184 if (!front) 185 return; 186 187 intel_parent_frontbuffer_ref(front->display, front); 188 if (!schedule_work(&front->flush_work)) 189 intel_parent_frontbuffer_put(front->display, front); 190 } 191 192 void intel_frontbuffer_init(struct intel_frontbuffer *front, struct drm_device *drm) 193 { 194 front->display = to_intel_display(drm); 195 atomic_set(&front->bits, 0); 196 INIT_WORK(&front->flush_work, intel_frontbuffer_flush_work); 197 } 198 199 void intel_frontbuffer_fini(struct intel_frontbuffer *front) 200 { 201 drm_WARN_ON(front->display->drm, atomic_read(&front->bits)); 202 } 203 204 /** 205 * intel_frontbuffer_track - update frontbuffer tracking 206 * @old: current buffer for the frontbuffer slots 207 * @new: new buffer for the frontbuffer slots 208 * @frontbuffer_bits: bitmask of frontbuffer slots 209 * 210 * This updates the frontbuffer tracking bits @frontbuffer_bits by clearing them 211 * from @old and setting them in @new. Both @old and @new can be NULL. 212 */ 213 void intel_frontbuffer_track(struct intel_frontbuffer *old, 214 struct intel_frontbuffer *new, 215 unsigned int frontbuffer_bits) 216 { 217 /* 218 * Control of individual bits within the mask are guarded by 219 * the owning plane->mutex, i.e. we can never see concurrent 220 * manipulation of individual bits. But since the bitfield as a whole 221 * is updated using RMW, we need to use atomics in order to update 222 * the bits. 223 */ 224 BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > 225 BITS_PER_TYPE(atomic_t)); 226 BUILD_BUG_ON(INTEL_FRONTBUFFER_BITS_PER_PIPE * I915_MAX_PIPES > 32); 227 BUILD_BUG_ON(I915_MAX_PLANES > INTEL_FRONTBUFFER_BITS_PER_PIPE); 228 229 if (old) { 230 drm_WARN_ON(old->display->drm, 231 !(atomic_read(&old->bits) & frontbuffer_bits)); 232 atomic_andnot(frontbuffer_bits, &old->bits); 233 } 234 235 if (new) { 236 drm_WARN_ON(new->display->drm, 237 atomic_read(&new->bits) & frontbuffer_bits); 238 atomic_or(frontbuffer_bits, &new->bits); 239 } 240 } 241