Rev 5354 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5354 | Rev 6084 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright © 2014 Intel Corporation |
2 | * Copyright © 2014 Intel Corporation |
3 | * |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), |
5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation |
6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
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 |
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: |
9 | * Software is furnished to do so, subject to the following conditions: |
10 | * |
10 | * |
11 | * The above copyright notice and this permission notice (including the next |
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 |
12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. |
13 | * Software. |
14 | * |
14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
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, |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
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 |
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 |
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 |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | * DEALINGS IN THE SOFTWARE. |
21 | * DEALINGS IN THE SOFTWARE. |
22 | * |
22 | * |
23 | * Authors: |
23 | * Authors: |
24 | * Daniel Vetter |
24 | * Daniel Vetter |
25 | */ |
25 | */ |
26 | 26 | ||
27 | /** |
27 | /** |
28 | * DOC: frontbuffer tracking |
28 | * DOC: frontbuffer tracking |
29 | * |
29 | * |
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 GEM tracks 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 i915_gem_track_fb(). The function in this file are |
35 | * then called when the contents of the frontbuffer are invalidated, when |
35 | * then called when the contents of the frontbuffer are invalidated, when |
36 | * frontbuffer rendering has stopped again to flush out all the changes and when |
36 | * frontbuffer rendering has stopped again to flush out all the changes and when |
37 | * the frontbuffer is exchanged with a flip. Subsystems interested in |
37 | * 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. |
41 | * |
41 | * |
42 | * On a high level there are two types of powersaving features. The first one |
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 |
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 |
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 |
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 |
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 |
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 |
48 | * and flush on its own) which can be achieved with placing callbacks into the |
49 | * flip functions. |
49 | * flip functions. |
50 | * |
50 | * |
51 | * The other type of display power saving feature only cares about busyness |
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 |
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 |
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 |
54 | * work delayed work should be started from the flush and flip functions and |
55 | * cancelled as soon as busyness is detected. |
55 | * cancelled as soon as busyness is detected. |
56 | * |
56 | * |
57 | * Note that there's also an older frontbuffer activity tracking scheme which |
57 | * Note that there's also an older frontbuffer activity tracking scheme which |
58 | * just tracks general activity. This is done by the various mark_busy and |
58 | * just tracks general activity. This is done by the various mark_busy and |
59 | * mark_idle functions. For display power management features using these |
59 | * mark_idle functions. For display power management features using these |
60 | * functions is deprecated and should be avoided. |
60 | * functions is deprecated and should be avoided. |
61 | */ |
61 | */ |
62 | 62 | ||
63 | #include |
63 | #include |
64 | 64 | ||
65 | #include "intel_drv.h" |
65 | #include "intel_drv.h" |
66 | #include "i915_drv.h" |
66 | #include "i915_drv.h" |
67 | - | ||
68 | static void intel_increase_pllclock(struct drm_device *dev, |
- | |
69 | enum pipe pipe) |
- | |
70 | { |
- | |
71 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
72 | int dpll_reg = DPLL(pipe); |
- | |
73 | int dpll; |
- | |
74 | - | ||
75 | if (!HAS_GMCH_DISPLAY(dev)) |
- | |
76 | return; |
- | |
77 | - | ||
78 | if (!dev_priv->lvds_downclock_avail) |
- | |
79 | return; |
- | |
80 | - | ||
81 | dpll = I915_READ(dpll_reg); |
- | |
82 | if (!HAS_PIPE_CXSR(dev) && (dpll & DISPLAY_RATE_SELECT_FPA1)) { |
- | |
83 | DRM_DEBUG_DRIVER("upclocking LVDS\n"); |
- | |
84 | - | ||
85 | assert_panel_unlocked(dev_priv, pipe); |
- | |
86 | - | ||
87 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
- | |
88 | I915_WRITE(dpll_reg, dpll); |
- | |
89 | intel_wait_for_vblank(dev, pipe); |
- | |
90 | - | ||
91 | dpll = I915_READ(dpll_reg); |
- | |
92 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
- | |
93 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
- | |
94 | } |
- | |
95 | } |
- | |
96 | - | ||
97 | /** |
- | |
98 | * intel_mark_fb_busy - mark given planes as busy |
- | |
99 | * @dev: DRM device |
- | |
100 | * @frontbuffer_bits: bits for the affected planes |
- | |
101 | * @ring: optional ring for asynchronous commands |
- | |
102 | * |
- | |
103 | * This function gets called every time the screen contents change. It can be |
- | |
104 | * used to keep e.g. the update rate at the nominal refresh rate with DRRS. |
- | |
105 | */ |
- | |
106 | static void intel_mark_fb_busy(struct drm_device *dev, |
- | |
107 | unsigned frontbuffer_bits, |
- | |
108 | struct intel_engine_cs *ring) |
- | |
109 | { |
- | |
110 | struct drm_i915_private *dev_priv = dev->dev_private; |
- | |
111 | enum pipe pipe; |
- | |
112 | - | ||
113 | if (!i915.powersave) |
- | |
114 | return; |
- | |
115 | - | ||
116 | for_each_pipe(dev_priv, pipe) { |
- | |
117 | if (!(frontbuffer_bits & INTEL_FRONTBUFFER_ALL_MASK(pipe))) |
- | |
118 | continue; |
- | |
119 | - | ||
120 | intel_increase_pllclock(dev, pipe); |
- | |
121 | if (ring && intel_fbc_enabled(dev)) |
- | |
122 | ring->fbc_dirty = true; |
- | |
123 | } |
- | |
124 | } |
- | |
125 | 67 | ||
126 | /** |
68 | /** |
127 | * intel_fb_obj_invalidate - invalidate frontbuffer object |
69 | * intel_fb_obj_invalidate - invalidate frontbuffer object |
128 | * @obj: GEM object to invalidate |
70 | * @obj: GEM object to invalidate |
129 | * @ring: set for asynchronous rendering |
71 | * @origin: which operation caused the invalidation |
130 | * |
72 | * |
131 | * This function gets called every time rendering on the given object starts and |
73 | * This function gets called every time rendering on the given object starts and |
132 | * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must |
74 | * frontbuffer caching (fbc, low refresh rate for DRRS, panel self refresh) must |
133 | * be invalidated. If @ring is non-NULL any subsequent invalidation will be delayed |
75 | * be invalidated. For ORIGIN_CS any subsequent invalidation will be delayed |
134 | * until the rendering completes or a flip on this frontbuffer plane is |
76 | * until the rendering completes or a flip on this frontbuffer plane is |
135 | * scheduled. |
77 | * scheduled. |
136 | */ |
78 | */ |
137 | void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, |
79 | void intel_fb_obj_invalidate(struct drm_i915_gem_object *obj, |
138 | struct intel_engine_cs *ring) |
80 | enum fb_op_origin origin) |
139 | { |
81 | { |
140 | struct drm_device *dev = obj->base.dev; |
82 | struct drm_device *dev = obj->base.dev; |
141 | struct drm_i915_private *dev_priv = dev->dev_private; |
83 | struct drm_i915_private *dev_priv = to_i915(dev); |
142 | 84 | ||
143 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
85 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
144 | 86 | ||
145 | if (!obj->frontbuffer_bits) |
87 | if (!obj->frontbuffer_bits) |
146 | return; |
88 | return; |
147 | 89 | ||
148 | if (ring) { |
90 | if (origin == ORIGIN_CS) { |
149 | mutex_lock(&dev_priv->fb_tracking.lock); |
91 | mutex_lock(&dev_priv->fb_tracking.lock); |
150 | dev_priv->fb_tracking.busy_bits |
92 | dev_priv->fb_tracking.busy_bits |
151 | |= obj->frontbuffer_bits; |
93 | |= obj->frontbuffer_bits; |
152 | dev_priv->fb_tracking.flip_bits |
94 | dev_priv->fb_tracking.flip_bits |
153 | &= ~obj->frontbuffer_bits; |
95 | &= ~obj->frontbuffer_bits; |
154 | mutex_unlock(&dev_priv->fb_tracking.lock); |
96 | mutex_unlock(&dev_priv->fb_tracking.lock); |
155 | } |
97 | } |
156 | - | ||
157 | intel_mark_fb_busy(dev, obj->frontbuffer_bits, ring); |
- | |
158 | 98 | ||
- | 99 | intel_psr_invalidate(dev, obj->frontbuffer_bits); |
|
- | 100 | intel_edp_drrs_invalidate(dev, obj->frontbuffer_bits); |
|
159 | intel_psr_invalidate(dev, obj->frontbuffer_bits); |
101 | intel_fbc_invalidate(dev_priv, obj->frontbuffer_bits, origin); |
160 | } |
102 | } |
161 | 103 | ||
162 | /** |
104 | /** |
163 | * intel_frontbuffer_flush - flush frontbuffer |
105 | * intel_frontbuffer_flush - flush frontbuffer |
164 | * @dev: DRM device |
106 | * @dev: DRM device |
165 | * @frontbuffer_bits: frontbuffer plane tracking bits |
107 | * @frontbuffer_bits: frontbuffer plane tracking bits |
- | 108 | * @origin: which operation caused the flush |
|
166 | * |
109 | * |
167 | * This function gets called every time rendering on the given planes has |
110 | * This function gets called every time rendering on the given planes has |
168 | * completed and frontbuffer caching can be started again. Flushes will get |
111 | * completed and frontbuffer caching can be started again. Flushes will get |
169 | * delayed if they're blocked by some outstanding asynchronous rendering. |
112 | * delayed if they're blocked by some outstanding asynchronous rendering. |
170 | * |
113 | * |
171 | * Can be called without any locks held. |
114 | * Can be called without any locks held. |
172 | */ |
115 | */ |
173 | void intel_frontbuffer_flush(struct drm_device *dev, |
116 | static void intel_frontbuffer_flush(struct drm_device *dev, |
174 | unsigned frontbuffer_bits) |
117 | unsigned frontbuffer_bits, |
- | 118 | enum fb_op_origin origin) |
|
175 | { |
119 | { |
176 | struct drm_i915_private *dev_priv = dev->dev_private; |
120 | struct drm_i915_private *dev_priv = to_i915(dev); |
177 | 121 | ||
178 | /* Delay flushing when rings are still busy.*/ |
122 | /* Delay flushing when rings are still busy.*/ |
179 | mutex_lock(&dev_priv->fb_tracking.lock); |
123 | mutex_lock(&dev_priv->fb_tracking.lock); |
180 | frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; |
124 | frontbuffer_bits &= ~dev_priv->fb_tracking.busy_bits; |
181 | mutex_unlock(&dev_priv->fb_tracking.lock); |
125 | mutex_unlock(&dev_priv->fb_tracking.lock); |
182 | 126 | ||
183 | intel_mark_fb_busy(dev, frontbuffer_bits, NULL); |
- | |
184 | 127 | if (!frontbuffer_bits) |
|
185 | intel_psr_flush(dev, frontbuffer_bits); |
- | |
186 | - | ||
187 | /* |
- | |
188 | * FIXME: Unconditional fbc flushing here is a rather gross hack and |
- | |
189 | * needs to be reworked into a proper frontbuffer tracking scheme like |
- | |
190 | * psr employs. |
128 | return; |
191 | */ |
129 | |
192 | if (dev_priv->fbc.need_sw_cache_clean) { |
130 | intel_edp_drrs_flush(dev, frontbuffer_bits); |
193 | dev_priv->fbc.need_sw_cache_clean = false; |
- | |
194 | bdw_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN); |
131 | intel_psr_flush(dev, frontbuffer_bits, origin); |
195 | } |
132 | intel_fbc_flush(dev_priv, frontbuffer_bits, origin); |
196 | } |
133 | } |
197 | 134 | ||
198 | /** |
135 | /** |
199 | * intel_fb_obj_flush - flush frontbuffer object |
136 | * intel_fb_obj_flush - flush frontbuffer object |
200 | * @obj: GEM object to flush |
137 | * @obj: GEM object to flush |
201 | * @retire: set when retiring asynchronous rendering |
138 | * @retire: set when retiring asynchronous rendering |
- | 139 | * @origin: which operation caused the flush |
|
202 | * |
140 | * |
203 | * This function gets called every time rendering on the given object has |
141 | * This function gets called every time rendering on the given object has |
204 | * completed and frontbuffer caching can be started again. If @retire is true |
142 | * completed and frontbuffer caching can be started again. If @retire is true |
205 | * then any delayed flushes will be unblocked. |
143 | * then any delayed flushes will be unblocked. |
206 | */ |
144 | */ |
207 | void intel_fb_obj_flush(struct drm_i915_gem_object *obj, |
145 | void intel_fb_obj_flush(struct drm_i915_gem_object *obj, |
208 | bool retire) |
146 | bool retire, enum fb_op_origin origin) |
209 | { |
147 | { |
210 | struct drm_device *dev = obj->base.dev; |
148 | struct drm_device *dev = obj->base.dev; |
211 | struct drm_i915_private *dev_priv = dev->dev_private; |
149 | struct drm_i915_private *dev_priv = to_i915(dev); |
212 | unsigned frontbuffer_bits; |
150 | unsigned frontbuffer_bits; |
213 | 151 | ||
214 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
152 | WARN_ON(!mutex_is_locked(&dev->struct_mutex)); |
215 | 153 | ||
216 | if (!obj->frontbuffer_bits) |
154 | if (!obj->frontbuffer_bits) |
217 | return; |
155 | return; |
218 | 156 | ||
219 | frontbuffer_bits = obj->frontbuffer_bits; |
157 | frontbuffer_bits = obj->frontbuffer_bits; |
220 | 158 | ||
221 | if (retire) { |
159 | if (retire) { |
222 | mutex_lock(&dev_priv->fb_tracking.lock); |
160 | mutex_lock(&dev_priv->fb_tracking.lock); |
223 | /* Filter out new bits since rendering started. */ |
161 | /* Filter out new bits since rendering started. */ |
224 | frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; |
162 | frontbuffer_bits &= dev_priv->fb_tracking.busy_bits; |
225 | 163 | ||
226 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; |
164 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; |
227 | mutex_unlock(&dev_priv->fb_tracking.lock); |
165 | mutex_unlock(&dev_priv->fb_tracking.lock); |
228 | } |
166 | } |
229 | 167 | ||
230 | intel_frontbuffer_flush(dev, frontbuffer_bits); |
168 | intel_frontbuffer_flush(dev, frontbuffer_bits, origin); |
231 | } |
169 | } |
232 | 170 | ||
233 | /** |
171 | /** |
234 | * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip |
172 | * intel_frontbuffer_flip_prepare - prepare asynchronous frontbuffer flip |
235 | * @dev: DRM device |
173 | * @dev: DRM device |
236 | * @frontbuffer_bits: frontbuffer plane tracking bits |
174 | * @frontbuffer_bits: frontbuffer plane tracking bits |
237 | * |
175 | * |
238 | * This function gets called after scheduling a flip on @obj. The actual |
176 | * This function gets called after scheduling a flip on @obj. The actual |
239 | * frontbuffer flushing will be delayed until completion is signalled with |
177 | * frontbuffer flushing will be delayed until completion is signalled with |
240 | * intel_frontbuffer_flip_complete. If an invalidate happens in between this |
178 | * intel_frontbuffer_flip_complete. If an invalidate happens in between this |
241 | * flush will be cancelled. |
179 | * flush will be cancelled. |
242 | * |
180 | * |
243 | * Can be called without any locks held. |
181 | * Can be called without any locks held. |
244 | */ |
182 | */ |
245 | void intel_frontbuffer_flip_prepare(struct drm_device *dev, |
183 | void intel_frontbuffer_flip_prepare(struct drm_device *dev, |
246 | unsigned frontbuffer_bits) |
184 | unsigned frontbuffer_bits) |
247 | { |
185 | { |
248 | struct drm_i915_private *dev_priv = dev->dev_private; |
186 | struct drm_i915_private *dev_priv = to_i915(dev); |
249 | 187 | ||
250 | mutex_lock(&dev_priv->fb_tracking.lock); |
188 | mutex_lock(&dev_priv->fb_tracking.lock); |
251 | dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; |
189 | dev_priv->fb_tracking.flip_bits |= frontbuffer_bits; |
252 | /* Remove stale busy bits due to the old buffer. */ |
190 | /* Remove stale busy bits due to the old buffer. */ |
253 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; |
191 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; |
254 | mutex_unlock(&dev_priv->fb_tracking.lock); |
192 | mutex_unlock(&dev_priv->fb_tracking.lock); |
- | 193 | ||
- | 194 | intel_psr_single_frame_update(dev, frontbuffer_bits); |
|
255 | } |
195 | } |
256 | 196 | ||
257 | /** |
197 | /** |
258 | * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip |
198 | * intel_frontbuffer_flip_complete - complete asynchronous frontbuffer flip |
259 | * @dev: DRM device |
199 | * @dev: DRM device |
260 | * @frontbuffer_bits: frontbuffer plane tracking bits |
200 | * @frontbuffer_bits: frontbuffer plane tracking bits |
261 | * |
201 | * |
262 | * This function gets called after the flip has been latched and will complete |
202 | * This function gets called after the flip has been latched and will complete |
263 | * on the next vblank. It will execute the flush if it hasn't been cancelled yet. |
203 | * on the next vblank. It will execute the flush if it hasn't been cancelled yet. |
264 | * |
204 | * |
265 | * Can be called without any locks held. |
205 | * Can be called without any locks held. |
266 | */ |
206 | */ |
267 | void intel_frontbuffer_flip_complete(struct drm_device *dev, |
207 | void intel_frontbuffer_flip_complete(struct drm_device *dev, |
268 | unsigned frontbuffer_bits) |
208 | unsigned frontbuffer_bits) |
269 | { |
209 | { |
270 | struct drm_i915_private *dev_priv = dev->dev_private; |
210 | struct drm_i915_private *dev_priv = to_i915(dev); |
271 | 211 | ||
272 | mutex_lock(&dev_priv->fb_tracking.lock); |
212 | mutex_lock(&dev_priv->fb_tracking.lock); |
273 | /* Mask any cancelled flips. */ |
213 | /* Mask any cancelled flips. */ |
274 | frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; |
214 | frontbuffer_bits &= dev_priv->fb_tracking.flip_bits; |
275 | dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; |
215 | dev_priv->fb_tracking.flip_bits &= ~frontbuffer_bits; |
276 | mutex_unlock(&dev_priv->fb_tracking.lock); |
216 | mutex_unlock(&dev_priv->fb_tracking.lock); |
277 | 217 | ||
- | 218 | intel_frontbuffer_flush(dev, frontbuffer_bits, ORIGIN_FLIP); |
|
- | 219 | } |
|
- | 220 | ||
- | 221 | /** |
|
- | 222 | * intel_frontbuffer_flip - synchronous frontbuffer flip |
|
- | 223 | * @dev: DRM device |
|
- | 224 | * @frontbuffer_bits: frontbuffer plane tracking bits |
|
- | 225 | * |
|
- | 226 | * This function gets called after scheduling a flip on @obj. This is for |
|
- | 227 | * synchronous plane updates which will happen on the next vblank and which will |
|
- | 228 | * not get delayed by pending gpu rendering. |
|
- | 229 | * |
|
- | 230 | * Can be called without any locks held. |
|
- | 231 | */ |
|
- | 232 | void intel_frontbuffer_flip(struct drm_device *dev, |
|
- | 233 | unsigned frontbuffer_bits) |
|
- | 234 | { |
|
- | 235 | struct drm_i915_private *dev_priv = to_i915(dev); |
|
- | 236 | ||
- | 237 | mutex_lock(&dev_priv->fb_tracking.lock); |
|
- | 238 | /* Remove stale busy bits due to the old buffer. */ |
|
- | 239 | dev_priv->fb_tracking.busy_bits &= ~frontbuffer_bits; |
|
- | 240 | mutex_unlock(&dev_priv->fb_tracking.lock); |
|
- | 241 | ||
278 | intel_frontbuffer_flush(dev, frontbuffer_bits); |
242 | intel_frontbuffer_flush(dev, frontbuffer_bits, ORIGIN_FLIP); |
279 | } |
243 | } |