Commit | Line | Data |
---|---|---|
cc4ceb48 DV |
1 | /* |
2 | * Copyright (C) 2014 Red Hat | |
3 | * Copyright (C) 2014 Intel Corp. | |
4 | * | |
5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
6 | * copy of this software and associated documentation files (the "Software"), | |
7 | * to deal in the Software without restriction, including without limitation | |
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
9 | * and/or sell copies of the Software, and to permit persons to whom the | |
10 | * Software is furnished to do so, subject to the following conditions: | |
11 | * | |
12 | * The above copyright notice and this permission notice shall be included in | |
13 | * all copies or substantial portions of the 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
19 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
20 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
21 | * OTHER DEALINGS IN THE SOFTWARE. | |
22 | * | |
23 | * Authors: | |
24 | * Rob Clark <robdclark@gmail.com> | |
25 | * Daniel Vetter <daniel.vetter@ffwll.ch> | |
26 | */ | |
27 | ||
28 | #ifndef DRM_ATOMIC_H_ | |
29 | #define DRM_ATOMIC_H_ | |
30 | ||
37cc0148 | 31 | #include <drm/drm_crtc.h> |
d78aa650 | 32 | #include <drm/drm_util.h> |
37cc0148 | 33 | |
43968d7b DV |
34 | /** |
35 | * struct drm_crtc_commit - track modeset commits on a CRTC | |
36 | * | |
37 | * This structure is used to track pending modeset changes and atomic commit on | |
dbe2d2bf | 38 | * a per-CRTC basis. Since updating the list should never block, this structure |
43968d7b DV |
39 | * is reference counted to allow waiters to safely wait on an event to complete, |
40 | * without holding any locks. | |
41 | * | |
42 | * It has 3 different events in total to allow a fine-grained synchronization | |
43 | * between outstanding updates:: | |
44 | * | |
45 | * atomic commit thread hardware | |
46 | * | |
47 | * write new state into hardware ----> ... | |
48 | * signal hw_done | |
49 | * switch to new state on next | |
50 | * ... v/hblank | |
51 | * | |
52 | * wait for buffers to show up ... | |
53 | * | |
54 | * ... send completion irq | |
55 | * irq handler signals flip_done | |
56 | * cleanup old buffers | |
57 | * | |
58 | * signal cleanup_done | |
59 | * | |
60 | * wait for flip_done <---- | |
61 | * clean up atomic state | |
62 | * | |
0380c684 DV |
63 | * The important bit to know is that &cleanup_done is the terminal event, but the |
64 | * ordering between &flip_done and &hw_done is entirely up to the specific driver | |
43968d7b DV |
65 | * and modeset state change. |
66 | * | |
67 | * For an implementation of how to use this look at | |
68 | * drm_atomic_helper_setup_commit() from the atomic helper library. | |
b99c2c95 MR |
69 | * |
70 | * See also drm_crtc_commit_wait(). | |
43968d7b DV |
71 | */ |
72 | struct drm_crtc_commit { | |
73 | /** | |
74 | * @crtc: | |
75 | * | |
76 | * DRM CRTC for this commit. | |
77 | */ | |
78 | struct drm_crtc *crtc; | |
79 | ||
80 | /** | |
81 | * @ref: | |
82 | * | |
83 | * Reference count for this structure. Needed to allow blocking on | |
84 | * completions without the risk of the completion disappearing | |
85 | * meanwhile. | |
86 | */ | |
87 | struct kref ref; | |
88 | ||
89 | /** | |
90 | * @flip_done: | |
91 | * | |
92 | * Will be signaled when the hardware has flipped to the new set of | |
93 | * buffers. Signals at the same time as when the drm event for this | |
94 | * commit is sent to userspace, or when an out-fence is singalled. Note | |
95 | * that for most hardware, in most cases this happens after @hw_done is | |
96 | * signalled. | |
0380c684 DV |
97 | * |
98 | * Completion of this stage is signalled implicitly by calling | |
99 | * drm_crtc_send_vblank_event() on &drm_crtc_state.event. | |
43968d7b DV |
100 | */ |
101 | struct completion flip_done; | |
102 | ||
103 | /** | |
104 | * @hw_done: | |
105 | * | |
106 | * Will be signalled when all hw register changes for this commit have | |
107 | * been written out. Especially when disabling a pipe this can be much | |
09f3344a | 108 | * later than @flip_done, since that can signal already when the |
43968d7b DV |
109 | * screen goes black, whereas to fully shut down a pipe more register |
110 | * I/O is required. | |
111 | * | |
112 | * Note that this does not need to include separately reference-counted | |
113 | * resources like backing storage buffer pinning, or runtime pm | |
114 | * management. | |
0380c684 DV |
115 | * |
116 | * Drivers should call drm_atomic_helper_commit_hw_done() to signal | |
117 | * completion of this stage. | |
43968d7b DV |
118 | */ |
119 | struct completion hw_done; | |
120 | ||
121 | /** | |
122 | * @cleanup_done: | |
123 | * | |
124 | * Will be signalled after old buffers have been cleaned up by calling | |
125 | * drm_atomic_helper_cleanup_planes(). Since this can only happen after | |
126 | * a vblank wait completed it might be a bit later. This completion is | |
127 | * useful to throttle updates and avoid hardware updates getting ahead | |
128 | * of the buffer cleanup too much. | |
0380c684 DV |
129 | * |
130 | * Drivers should call drm_atomic_helper_commit_cleanup_done() to signal | |
131 | * completion of this stage. | |
43968d7b DV |
132 | */ |
133 | struct completion cleanup_done; | |
134 | ||
135 | /** | |
136 | * @commit_entry: | |
137 | * | |
d574528a DV |
138 | * Entry on the per-CRTC &drm_crtc.commit_list. Protected by |
139 | * $drm_crtc.commit_lock. | |
43968d7b DV |
140 | */ |
141 | struct list_head commit_entry; | |
142 | ||
143 | /** | |
144 | * @event: | |
145 | * | |
146 | * &drm_pending_vblank_event pointer to clean up private events. | |
147 | */ | |
148 | struct drm_pending_vblank_event *event; | |
1c6ceeee LSL |
149 | |
150 | /** | |
151 | * @abort_completion: | |
152 | * | |
7d0250ed DV |
153 | * A flag that's set after drm_atomic_helper_setup_commit() takes a |
154 | * second reference for the completion of $drm_crtc_state.event. It's | |
155 | * used by the free code to remove the second reference if commit fails. | |
1c6ceeee LSL |
156 | */ |
157 | bool abort_completion; | |
43968d7b DV |
158 | }; |
159 | ||
160 | struct __drm_planes_state { | |
161 | struct drm_plane *ptr; | |
581e49fe | 162 | struct drm_plane_state *state, *old_state, *new_state; |
43968d7b DV |
163 | }; |
164 | ||
165 | struct __drm_crtcs_state { | |
166 | struct drm_crtc *ptr; | |
581e49fe | 167 | struct drm_crtc_state *state, *old_state, *new_state; |
4364bcb2 LL |
168 | |
169 | /** | |
170 | * @commit: | |
171 | * | |
172 | * A reference to the CRTC commit object that is kept for use by | |
173 | * drm_atomic_helper_wait_for_flip_done() after | |
174 | * drm_atomic_helper_commit_hw_done() is called. This ensures that a | |
175 | * concurrent commit won't free a commit object that is still in use. | |
176 | */ | |
177 | struct drm_crtc_commit *commit; | |
178 | ||
7e9081c5 | 179 | s32 __user *out_fence_ptr; |
f4c0468e | 180 | u64 last_vblank_count; |
43968d7b DV |
181 | }; |
182 | ||
183 | struct __drm_connnectors_state { | |
184 | struct drm_connector *ptr; | |
581e49fe | 185 | struct drm_connector_state *state, *old_state, *new_state; |
b13cc8dd BS |
186 | /** |
187 | * @out_fence_ptr: | |
188 | * | |
189 | * User-provided pointer which the kernel uses to return a sync_file | |
190 | * file descriptor. Used by writeback connectors to signal completion of | |
191 | * the writeback. | |
192 | */ | |
193 | s32 __user *out_fence_ptr; | |
43968d7b DV |
194 | }; |
195 | ||
a4370c77 VS |
196 | struct drm_private_obj; |
197 | struct drm_private_state; | |
198 | ||
b430c27a PD |
199 | /** |
200 | * struct drm_private_state_funcs - atomic state functions for private objects | |
201 | * | |
202 | * These hooks are used by atomic helpers to create, swap and destroy states of | |
203 | * private objects. The structure itself is used as a vtable to identify the | |
204 | * associated private object type. Each private object type that needs to be | |
205 | * added to the atomic states is expected to have an implementation of these | |
1e55a53a | 206 | * hooks and pass a pointer to its drm_private_state_funcs struct to |
b430c27a PD |
207 | * drm_atomic_get_private_obj_state(). |
208 | */ | |
209 | struct drm_private_state_funcs { | |
210 | /** | |
a4370c77 | 211 | * @atomic_duplicate_state: |
b430c27a PD |
212 | * |
213 | * Duplicate the current state of the private object and return it. It | |
214 | * is an error to call this before obj->state has been initialized. | |
215 | * | |
216 | * RETURNS: | |
217 | * | |
218 | * Duplicated atomic state or NULL when obj->state is not | |
219 | * initialized or allocation failed. | |
220 | */ | |
a4370c77 | 221 | struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj); |
b430c27a PD |
222 | |
223 | /** | |
a4370c77 | 224 | * @atomic_destroy_state: |
b430c27a | 225 | * |
a4370c77 | 226 | * Frees the private object state created with @atomic_duplicate_state. |
b430c27a | 227 | */ |
a4370c77 VS |
228 | void (*atomic_destroy_state)(struct drm_private_obj *obj, |
229 | struct drm_private_state *state); | |
97a1f01b MR |
230 | |
231 | /** | |
232 | * @atomic_print_state: | |
233 | * | |
234 | * If driver subclasses &struct drm_private_state, it should implement | |
235 | * this optional hook for printing additional driver specific state. | |
236 | * | |
237 | * Do not call this directly, use drm_atomic_private_obj_print_state() | |
238 | * instead. | |
239 | */ | |
240 | void (*atomic_print_state)(struct drm_printer *p, | |
241 | const struct drm_private_state *state); | |
a4370c77 | 242 | }; |
b430c27a | 243 | |
da6c0596 DV |
244 | /** |
245 | * struct drm_private_obj - base struct for driver private atomic object | |
246 | * | |
247 | * A driver private object is initialized by calling | |
248 | * drm_atomic_private_obj_init() and cleaned up by calling | |
249 | * drm_atomic_private_obj_fini(). | |
250 | * | |
251 | * Currently only tracks the state update functions and the opaque driver | |
252 | * private state itself, but in the future might also track which | |
253 | * &drm_modeset_lock is required to duplicate and update this object's state. | |
b962a120 RC |
254 | * |
255 | * All private objects must be initialized before the DRM device they are | |
256 | * attached to is registered to the DRM subsystem (call to drm_dev_register()) | |
257 | * and should stay around until this DRM device is unregistered (call to | |
258 | * drm_dev_unregister()). In other words, private objects lifetime is tied | |
259 | * to the DRM device lifetime. This implies that: | |
260 | * | |
261 | * 1/ all calls to drm_atomic_private_obj_init() must be done before calling | |
262 | * drm_dev_register() | |
263 | * 2/ all calls to drm_atomic_private_obj_fini() must be done after calling | |
264 | * drm_dev_unregister() | |
27125e86 MR |
265 | * |
266 | * If that private object is used to store a state shared by multiple | |
267 | * CRTCs, proper care must be taken to ensure that non-blocking commits are | |
268 | * properly ordered to avoid a use-after-free issue. | |
269 | * | |
270 | * Indeed, assuming a sequence of two non-blocking &drm_atomic_commit on two | |
271 | * different &drm_crtc using different &drm_plane and &drm_connector, so with no | |
272 | * resources shared, there's no guarantee on which commit is going to happen | |
273 | * first. However, the second &drm_atomic_commit will consider the first | |
274 | * &drm_private_obj its old state, and will be in charge of freeing it whenever | |
275 | * the second &drm_atomic_commit is done. | |
276 | * | |
277 | * If the first &drm_atomic_commit happens after it, it will consider its | |
278 | * &drm_private_obj the new state and will be likely to access it, resulting in | |
279 | * an access to a freed memory region. Drivers should store (and get a reference | |
280 | * to) the &drm_crtc_commit structure in our private state in | |
281 | * &drm_mode_config_helper_funcs.atomic_commit_setup, and then wait for that | |
282 | * commit to complete as the first step of | |
283 | * &drm_mode_config_helper_funcs.atomic_commit_tail, similar to | |
284 | * drm_atomic_helper_wait_for_dependencies(). | |
da6c0596 | 285 | */ |
a4370c77 | 286 | struct drm_private_obj { |
b962a120 RC |
287 | /** |
288 | * @head: List entry used to attach a private object to a &drm_device | |
289 | * (queued to &drm_mode_config.privobj_list). | |
290 | */ | |
291 | struct list_head head; | |
292 | ||
293 | /** | |
294 | * @lock: Modeset lock to protect the state object. | |
295 | */ | |
296 | struct drm_modeset_lock lock; | |
297 | ||
da6c0596 DV |
298 | /** |
299 | * @state: Current atomic state for this driver private object. | |
300 | */ | |
a4370c77 VS |
301 | struct drm_private_state *state; |
302 | ||
da6c0596 DV |
303 | /** |
304 | * @funcs: | |
305 | * | |
306 | * Functions to manipulate the state of this driver private object, see | |
307 | * &drm_private_state_funcs. | |
308 | */ | |
a4370c77 VS |
309 | const struct drm_private_state_funcs *funcs; |
310 | }; | |
311 | ||
b962a120 RC |
312 | /** |
313 | * drm_for_each_privobj() - private object iterator | |
314 | * | |
315 | * @privobj: pointer to the current private object. Updated after each | |
316 | * iteration | |
317 | * @dev: the DRM device we want get private objects from | |
318 | * | |
319 | * Allows one to iterate over all private objects attached to @dev | |
320 | */ | |
321 | #define drm_for_each_privobj(privobj, dev) \ | |
322 | list_for_each_entry(privobj, &(dev)->mode_config.privobj_list, head) | |
323 | ||
da6c0596 DV |
324 | /** |
325 | * struct drm_private_state - base struct for driver private object state | |
da6c0596 | 326 | * |
97a1f01b MR |
327 | * Currently only contains a backpointer to the overall atomic update, |
328 | * and the relevant private object but in the future also might hold | |
329 | * synchronization information similar to e.g. &drm_crtc.commit. | |
da6c0596 | 330 | */ |
a4370c77 | 331 | struct drm_private_state { |
97a1f01b MR |
332 | /** |
333 | * @state: backpointer to global drm_atomic_state | |
334 | */ | |
a4370c77 | 335 | struct drm_atomic_state *state; |
97a1f01b MR |
336 | |
337 | /** | |
338 | * @obj: backpointer to the private object | |
339 | */ | |
340 | struct drm_private_obj *obj; | |
b430c27a PD |
341 | }; |
342 | ||
343 | struct __drm_private_objs_state { | |
a4370c77 VS |
344 | struct drm_private_obj *ptr; |
345 | struct drm_private_state *state, *old_state, *new_state; | |
b430c27a PD |
346 | }; |
347 | ||
43968d7b DV |
348 | /** |
349 | * struct drm_atomic_state - the global state object for atomic updates | |
0853695c | 350 | * @ref: count of all references to this state (will not be freed until zero) |
43968d7b | 351 | * @dev: parent DRM device |
fef9df8b | 352 | * @async_update: hint for asynchronous plane update |
43968d7b DV |
353 | * @planes: pointer to array of structures with per-plane data |
354 | * @crtcs: pointer to array of CRTC pointers | |
355 | * @num_connector: size of the @connectors and @connector_states arrays | |
356 | * @connectors: pointer to array of structures with per-connector data | |
b430c27a PD |
357 | * @num_private_objs: size of the @private_objs array |
358 | * @private_objs: pointer to array of private object pointers | |
43968d7b | 359 | * @acquire_ctx: acquire context for this atomic modeset state update |
5fca5ece DV |
360 | * |
361 | * States are added to an atomic update by calling drm_atomic_get_crtc_state(), | |
362 | * drm_atomic_get_plane_state(), drm_atomic_get_connector_state(), or for | |
363 | * private state structures, drm_atomic_get_private_obj_state(). | |
43968d7b DV |
364 | */ |
365 | struct drm_atomic_state { | |
0853695c CW |
366 | struct kref ref; |
367 | ||
43968d7b | 368 | struct drm_device *dev; |
ec9b0a9e DV |
369 | |
370 | /** | |
371 | * @allow_modeset: | |
372 | * | |
373 | * Allow full modeset. This is used by the ATOMIC IOCTL handler to | |
374 | * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should | |
375 | * never consult this flag, instead looking at the output of | |
376 | * drm_atomic_crtc_needs_modeset(). | |
377 | */ | |
43968d7b | 378 | bool allow_modeset : 1; |
7d18e2f3 DV |
379 | /** |
380 | * @legacy_cursor_update: | |
381 | * | |
382 | * Hint to enforce legacy cursor IOCTL semantics. | |
383 | * | |
384 | * WARNING: This is thoroughly broken and pretty much impossible to | |
385 | * implement correctly. Drivers must ignore this and should instead | |
386 | * implement &drm_plane_helper_funcs.atomic_async_check and | |
387 | * &drm_plane_helper_funcs.atomic_async_commit hooks. New users of this | |
388 | * flag are not allowed. | |
389 | */ | |
43968d7b | 390 | bool legacy_cursor_update : 1; |
fef9df8b | 391 | bool async_update : 1; |
022debad LP |
392 | /** |
393 | * @duplicated: | |
394 | * | |
395 | * Indicates whether or not this atomic state was duplicated using | |
396 | * drm_atomic_helper_duplicate_state(). Drivers and atomic helpers | |
397 | * should use this to fixup normal inconsistencies in duplicated | |
398 | * states. | |
399 | */ | |
400 | bool duplicated : 1; | |
43968d7b DV |
401 | struct __drm_planes_state *planes; |
402 | struct __drm_crtcs_state *crtcs; | |
403 | int num_connector; | |
404 | struct __drm_connnectors_state *connectors; | |
b430c27a PD |
405 | int num_private_objs; |
406 | struct __drm_private_objs_state *private_objs; | |
43968d7b DV |
407 | |
408 | struct drm_modeset_acquire_ctx *acquire_ctx; | |
409 | ||
21a01abb ML |
410 | /** |
411 | * @fake_commit: | |
412 | * | |
413 | * Used for signaling unbound planes/connectors. | |
414 | * When a connector or plane is not bound to any CRTC, it's still important | |
415 | * to preserve linearity to prevent the atomic states from being freed to early. | |
416 | * | |
42240c90 | 417 | * This commit (if set) is not bound to any CRTC, but will be completed when |
21a01abb ML |
418 | * drm_atomic_helper_commit_hw_done() is called. |
419 | */ | |
420 | struct drm_crtc_commit *fake_commit; | |
421 | ||
43968d7b DV |
422 | /** |
423 | * @commit_work: | |
424 | * | |
425 | * Work item which can be used by the driver or helpers to execute the | |
426 | * commit without blocking. | |
427 | */ | |
428 | struct work_struct commit_work; | |
429 | }; | |
430 | ||
b3ba3f6f DV |
431 | void __drm_crtc_commit_free(struct kref *kref); |
432 | ||
433 | /** | |
434 | * drm_crtc_commit_get - acquire a reference to the CRTC commit | |
435 | * @commit: CRTC commit | |
436 | * | |
437 | * Increases the reference of @commit. | |
f46640b9 ML |
438 | * |
439 | * Returns: | |
440 | * The pointer to @commit, with reference increased. | |
b3ba3f6f | 441 | */ |
f46640b9 | 442 | static inline struct drm_crtc_commit *drm_crtc_commit_get(struct drm_crtc_commit *commit) |
3b24f7d6 DV |
443 | { |
444 | kref_get(&commit->ref); | |
f46640b9 | 445 | return commit; |
3b24f7d6 DV |
446 | } |
447 | ||
b3ba3f6f DV |
448 | /** |
449 | * drm_crtc_commit_put - release a reference to the CRTC commmit | |
450 | * @commit: CRTC commit | |
451 | * | |
452 | * This releases a reference to @commit which is freed after removing the | |
453 | * final reference. No locking required and callable from any context. | |
454 | */ | |
455 | static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit) | |
456 | { | |
457 | kref_put(&commit->ref, __drm_crtc_commit_free); | |
458 | } | |
459 | ||
b99c2c95 MR |
460 | int drm_crtc_commit_wait(struct drm_crtc_commit *commit); |
461 | ||
cc4ceb48 DV |
462 | struct drm_atomic_state * __must_check |
463 | drm_atomic_state_alloc(struct drm_device *dev); | |
464 | void drm_atomic_state_clear(struct drm_atomic_state *state); | |
0853695c CW |
465 | |
466 | /** | |
467 | * drm_atomic_state_get - acquire a reference to the atomic state | |
468 | * @state: The atomic state | |
469 | * | |
470 | * Returns a new reference to the @state | |
471 | */ | |
472 | static inline struct drm_atomic_state * | |
473 | drm_atomic_state_get(struct drm_atomic_state *state) | |
474 | { | |
475 | kref_get(&state->ref); | |
476 | return state; | |
477 | } | |
478 | ||
479 | void __drm_atomic_state_free(struct kref *ref); | |
480 | ||
481 | /** | |
482 | * drm_atomic_state_put - release a reference to the atomic state | |
483 | * @state: The atomic state | |
484 | * | |
485 | * This releases a reference to @state which is freed after removing the | |
486 | * final reference. No locking required and callable from any context. | |
487 | */ | |
488 | static inline void drm_atomic_state_put(struct drm_atomic_state *state) | |
489 | { | |
490 | kref_put(&state->ref, __drm_atomic_state_free); | |
491 | } | |
036ef573 ML |
492 | |
493 | int __must_check | |
494 | drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); | |
495 | void drm_atomic_state_default_clear(struct drm_atomic_state *state); | |
496 | void drm_atomic_state_default_release(struct drm_atomic_state *state); | |
cc4ceb48 DV |
497 | |
498 | struct drm_crtc_state * __must_check | |
499 | drm_atomic_get_crtc_state(struct drm_atomic_state *state, | |
500 | struct drm_crtc *crtc); | |
501 | struct drm_plane_state * __must_check | |
502 | drm_atomic_get_plane_state(struct drm_atomic_state *state, | |
503 | struct drm_plane *plane); | |
504 | struct drm_connector_state * __must_check | |
505 | drm_atomic_get_connector_state(struct drm_atomic_state *state, | |
506 | struct drm_connector *connector); | |
88a48e29 | 507 | |
b962a120 RC |
508 | void drm_atomic_private_obj_init(struct drm_device *dev, |
509 | struct drm_private_obj *obj, | |
a4370c77 VS |
510 | struct drm_private_state *state, |
511 | const struct drm_private_state_funcs *funcs); | |
512 | void drm_atomic_private_obj_fini(struct drm_private_obj *obj); | |
513 | ||
514 | struct drm_private_state * __must_check | |
b430c27a | 515 | drm_atomic_get_private_obj_state(struct drm_atomic_state *state, |
a4370c77 | 516 | struct drm_private_obj *obj); |
9801a7ea | 517 | struct drm_private_state * |
2081bd89 | 518 | drm_atomic_get_old_private_obj_state(const struct drm_atomic_state *state, |
9801a7ea ATC |
519 | struct drm_private_obj *obj); |
520 | struct drm_private_state * | |
2081bd89 | 521 | drm_atomic_get_new_private_obj_state(const struct drm_atomic_state *state, |
9801a7ea | 522 | struct drm_private_obj *obj); |
b430c27a | 523 | |
1b27fbdd | 524 | struct drm_connector * |
2081bd89 | 525 | drm_atomic_get_old_connector_for_encoder(const struct drm_atomic_state *state, |
1b27fbdd LP |
526 | struct drm_encoder *encoder); |
527 | struct drm_connector * | |
2081bd89 | 528 | drm_atomic_get_new_connector_for_encoder(const struct drm_atomic_state *state, |
1b27fbdd LP |
529 | struct drm_encoder *encoder); |
530 | ||
7b9a9e35 VP |
531 | struct drm_crtc * |
532 | drm_atomic_get_old_crtc_for_encoder(struct drm_atomic_state *state, | |
533 | struct drm_encoder *encoder); | |
534 | struct drm_crtc * | |
535 | drm_atomic_get_new_crtc_for_encoder(struct drm_atomic_state *state, | |
536 | struct drm_encoder *encoder); | |
537 | ||
1b26a5e1 | 538 | /** |
42240c90 | 539 | * drm_atomic_get_existing_crtc_state - get CRTC state, if it exists |
1b26a5e1 | 540 | * @state: global atomic state object |
42240c90 | 541 | * @crtc: CRTC to grab |
1b26a5e1 | 542 | * |
42240c90 TR |
543 | * This function returns the CRTC state for the given CRTC, or NULL |
544 | * if the CRTC is not part of the global atomic state. | |
2107777c ML |
545 | * |
546 | * This function is deprecated, @drm_atomic_get_old_crtc_state or | |
547 | * @drm_atomic_get_new_crtc_state should be used instead. | |
1b26a5e1 ML |
548 | */ |
549 | static inline struct drm_crtc_state * | |
2081bd89 | 550 | drm_atomic_get_existing_crtc_state(const struct drm_atomic_state *state, |
1b26a5e1 ML |
551 | struct drm_crtc *crtc) |
552 | { | |
5d943aa6 | 553 | return state->crtcs[drm_crtc_index(crtc)].state; |
1b26a5e1 ML |
554 | } |
555 | ||
2107777c | 556 | /** |
42240c90 | 557 | * drm_atomic_get_old_crtc_state - get old CRTC state, if it exists |
2107777c | 558 | * @state: global atomic state object |
42240c90 | 559 | * @crtc: CRTC to grab |
2107777c | 560 | * |
42240c90 TR |
561 | * This function returns the old CRTC state for the given CRTC, or |
562 | * NULL if the CRTC is not part of the global atomic state. | |
2107777c ML |
563 | */ |
564 | static inline struct drm_crtc_state * | |
2081bd89 | 565 | drm_atomic_get_old_crtc_state(const struct drm_atomic_state *state, |
2107777c ML |
566 | struct drm_crtc *crtc) |
567 | { | |
568 | return state->crtcs[drm_crtc_index(crtc)].old_state; | |
569 | } | |
570 | /** | |
42240c90 | 571 | * drm_atomic_get_new_crtc_state - get new CRTC state, if it exists |
2107777c | 572 | * @state: global atomic state object |
42240c90 | 573 | * @crtc: CRTC to grab |
2107777c | 574 | * |
42240c90 TR |
575 | * This function returns the new CRTC state for the given CRTC, or |
576 | * NULL if the CRTC is not part of the global atomic state. | |
2107777c ML |
577 | */ |
578 | static inline struct drm_crtc_state * | |
2081bd89 | 579 | drm_atomic_get_new_crtc_state(const struct drm_atomic_state *state, |
2107777c ML |
580 | struct drm_crtc *crtc) |
581 | { | |
582 | return state->crtcs[drm_crtc_index(crtc)].new_state; | |
583 | } | |
584 | ||
1b26a5e1 ML |
585 | /** |
586 | * drm_atomic_get_existing_plane_state - get plane state, if it exists | |
587 | * @state: global atomic state object | |
588 | * @plane: plane to grab | |
589 | * | |
590 | * This function returns the plane state for the given plane, or NULL | |
591 | * if the plane is not part of the global atomic state. | |
2107777c ML |
592 | * |
593 | * This function is deprecated, @drm_atomic_get_old_plane_state or | |
594 | * @drm_atomic_get_new_plane_state should be used instead. | |
1b26a5e1 ML |
595 | */ |
596 | static inline struct drm_plane_state * | |
2081bd89 | 597 | drm_atomic_get_existing_plane_state(const struct drm_atomic_state *state, |
1b26a5e1 ML |
598 | struct drm_plane *plane) |
599 | { | |
b8b5342b | 600 | return state->planes[drm_plane_index(plane)].state; |
1b26a5e1 ML |
601 | } |
602 | ||
2107777c ML |
603 | /** |
604 | * drm_atomic_get_old_plane_state - get plane state, if it exists | |
605 | * @state: global atomic state object | |
606 | * @plane: plane to grab | |
607 | * | |
608 | * This function returns the old plane state for the given plane, or | |
609 | * NULL if the plane is not part of the global atomic state. | |
610 | */ | |
611 | static inline struct drm_plane_state * | |
2081bd89 | 612 | drm_atomic_get_old_plane_state(const struct drm_atomic_state *state, |
2107777c ML |
613 | struct drm_plane *plane) |
614 | { | |
615 | return state->planes[drm_plane_index(plane)].old_state; | |
616 | } | |
617 | ||
618 | /** | |
619 | * drm_atomic_get_new_plane_state - get plane state, if it exists | |
620 | * @state: global atomic state object | |
621 | * @plane: plane to grab | |
622 | * | |
623 | * This function returns the new plane state for the given plane, or | |
624 | * NULL if the plane is not part of the global atomic state. | |
625 | */ | |
626 | static inline struct drm_plane_state * | |
2081bd89 | 627 | drm_atomic_get_new_plane_state(const struct drm_atomic_state *state, |
2107777c ML |
628 | struct drm_plane *plane) |
629 | { | |
630 | return state->planes[drm_plane_index(plane)].new_state; | |
631 | } | |
632 | ||
1b26a5e1 ML |
633 | /** |
634 | * drm_atomic_get_existing_connector_state - get connector state, if it exists | |
635 | * @state: global atomic state object | |
636 | * @connector: connector to grab | |
637 | * | |
638 | * This function returns the connector state for the given connector, | |
639 | * or NULL if the connector is not part of the global atomic state. | |
2107777c ML |
640 | * |
641 | * This function is deprecated, @drm_atomic_get_old_connector_state or | |
642 | * @drm_atomic_get_new_connector_state should be used instead. | |
1b26a5e1 ML |
643 | */ |
644 | static inline struct drm_connector_state * | |
2081bd89 | 645 | drm_atomic_get_existing_connector_state(const struct drm_atomic_state *state, |
1b26a5e1 ML |
646 | struct drm_connector *connector) |
647 | { | |
648 | int index = drm_connector_index(connector); | |
649 | ||
650 | if (index >= state->num_connector) | |
651 | return NULL; | |
652 | ||
63e83c1d | 653 | return state->connectors[index].state; |
1b26a5e1 ML |
654 | } |
655 | ||
2107777c ML |
656 | /** |
657 | * drm_atomic_get_old_connector_state - get connector state, if it exists | |
658 | * @state: global atomic state object | |
659 | * @connector: connector to grab | |
660 | * | |
661 | * This function returns the old connector state for the given connector, | |
662 | * or NULL if the connector is not part of the global atomic state. | |
663 | */ | |
664 | static inline struct drm_connector_state * | |
2081bd89 | 665 | drm_atomic_get_old_connector_state(const struct drm_atomic_state *state, |
2107777c ML |
666 | struct drm_connector *connector) |
667 | { | |
668 | int index = drm_connector_index(connector); | |
669 | ||
670 | if (index >= state->num_connector) | |
671 | return NULL; | |
672 | ||
673 | return state->connectors[index].old_state; | |
674 | } | |
675 | ||
676 | /** | |
677 | * drm_atomic_get_new_connector_state - get connector state, if it exists | |
678 | * @state: global atomic state object | |
679 | * @connector: connector to grab | |
680 | * | |
681 | * This function returns the new connector state for the given connector, | |
682 | * or NULL if the connector is not part of the global atomic state. | |
683 | */ | |
684 | static inline struct drm_connector_state * | |
2081bd89 | 685 | drm_atomic_get_new_connector_state(const struct drm_atomic_state *state, |
2107777c ML |
686 | struct drm_connector *connector) |
687 | { | |
688 | int index = drm_connector_index(connector); | |
689 | ||
690 | if (index >= state->num_connector) | |
691 | return NULL; | |
692 | ||
693 | return state->connectors[index].new_state; | |
694 | } | |
695 | ||
2f196b7c DV |
696 | /** |
697 | * __drm_atomic_get_current_plane_state - get current plane state | |
698 | * @state: global atomic state object | |
699 | * @plane: plane to grab | |
700 | * | |
701 | * This function returns the plane state for the given plane, either from | |
702 | * @state, or if the plane isn't part of the atomic state update, from @plane. | |
703 | * This is useful in atomic check callbacks, when drivers need to peek at, but | |
704 | * not change, state of other planes, since it avoids threading an error code | |
705 | * back up the call chain. | |
706 | * | |
707 | * WARNING: | |
708 | * | |
709 | * Note that this function is in general unsafe since it doesn't check for the | |
710 | * required locking for access state structures. Drivers must ensure that it is | |
60c9e190 | 711 | * safe to access the returned state structure through other means. One common |
2f196b7c | 712 | * example is when planes are fixed to a single CRTC, and the driver knows that |
60c9e190 | 713 | * the CRTC lock is held already. In that case holding the CRTC lock gives a |
2f196b7c DV |
714 | * read-lock on all planes connected to that CRTC. But if planes can be |
715 | * reassigned things get more tricky. In that case it's better to use | |
716 | * drm_atomic_get_plane_state and wire up full error handling. | |
717 | * | |
718 | * Returns: | |
719 | * | |
720 | * Read-only pointer to the current plane state. | |
721 | */ | |
722 | static inline const struct drm_plane_state * | |
2081bd89 | 723 | __drm_atomic_get_current_plane_state(const struct drm_atomic_state *state, |
2f196b7c DV |
724 | struct drm_plane *plane) |
725 | { | |
b8b5342b DV |
726 | if (state->planes[drm_plane_index(plane)].state) |
727 | return state->planes[drm_plane_index(plane)].state; | |
2f196b7c DV |
728 | |
729 | return plane->state; | |
730 | } | |
731 | ||
75146591 BB |
732 | int __must_check |
733 | drm_atomic_add_encoder_bridges(struct drm_atomic_state *state, | |
734 | struct drm_encoder *encoder); | |
cc4ceb48 DV |
735 | int __must_check |
736 | drm_atomic_add_affected_connectors(struct drm_atomic_state *state, | |
737 | struct drm_crtc *crtc); | |
e01e9f75 ML |
738 | int __must_check |
739 | drm_atomic_add_affected_planes(struct drm_atomic_state *state, | |
740 | struct drm_crtc *crtc); | |
741 | ||
cc4ceb48 DV |
742 | int __must_check drm_atomic_check_only(struct drm_atomic_state *state); |
743 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); | |
b837ba0a | 744 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); |
cc4ceb48 | 745 | |
6559c901 RC |
746 | void drm_state_dump(struct drm_device *dev, struct drm_printer *p); |
747 | ||
f9a76955 DV |
748 | /** |
749 | * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update | |
750 | * @__state: &struct drm_atomic_state pointer | |
751 | * @connector: &struct drm_connector iteration cursor | |
752 | * @old_connector_state: &struct drm_connector_state iteration cursor for the | |
753 | * old state | |
754 | * @new_connector_state: &struct drm_connector_state iteration cursor for the | |
755 | * new state | |
756 | * @__i: int iteration cursor, for macro-internal use | |
757 | * | |
758 | * This iterates over all connectors in an atomic update, tracking both old and | |
759 | * new state. This is useful in places where the state delta needs to be | |
760 | * considered, for example in atomic check functions. | |
761 | */ | |
581e49fe ML |
762 | #define for_each_oldnew_connector_in_state(__state, connector, old_connector_state, new_connector_state, __i) \ |
763 | for ((__i) = 0; \ | |
331494eb ML |
764 | (__i) < (__state)->num_connector; \ |
765 | (__i)++) \ | |
766 | for_each_if ((__state)->connectors[__i].ptr && \ | |
767 | ((connector) = (__state)->connectors[__i].ptr, \ | |
bf5d837a | 768 | (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ |
331494eb ML |
769 | (old_connector_state) = (__state)->connectors[__i].old_state, \ |
770 | (new_connector_state) = (__state)->connectors[__i].new_state, 1)) | |
581e49fe | 771 | |
f9a76955 DV |
772 | /** |
773 | * for_each_old_connector_in_state - iterate over all connectors in an atomic update | |
774 | * @__state: &struct drm_atomic_state pointer | |
775 | * @connector: &struct drm_connector iteration cursor | |
776 | * @old_connector_state: &struct drm_connector_state iteration cursor for the | |
777 | * old state | |
778 | * @__i: int iteration cursor, for macro-internal use | |
779 | * | |
780 | * This iterates over all connectors in an atomic update, tracking only the old | |
781 | * state. This is useful in disable functions, where we need the old state the | |
782 | * hardware is still in. | |
783 | */ | |
581e49fe ML |
784 | #define for_each_old_connector_in_state(__state, connector, old_connector_state, __i) \ |
785 | for ((__i) = 0; \ | |
331494eb ML |
786 | (__i) < (__state)->num_connector; \ |
787 | (__i)++) \ | |
788 | for_each_if ((__state)->connectors[__i].ptr && \ | |
789 | ((connector) = (__state)->connectors[__i].ptr, \ | |
bf5d837a | 790 | (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ |
331494eb | 791 | (old_connector_state) = (__state)->connectors[__i].old_state, 1)) |
581e49fe | 792 | |
f9a76955 DV |
793 | /** |
794 | * for_each_new_connector_in_state - iterate over all connectors in an atomic update | |
795 | * @__state: &struct drm_atomic_state pointer | |
796 | * @connector: &struct drm_connector iteration cursor | |
797 | * @new_connector_state: &struct drm_connector_state iteration cursor for the | |
798 | * new state | |
799 | * @__i: int iteration cursor, for macro-internal use | |
800 | * | |
801 | * This iterates over all connectors in an atomic update, tracking only the new | |
802 | * state. This is useful in enable functions, where we need the new state the | |
803 | * hardware should be in when the atomic commit operation has completed. | |
804 | */ | |
581e49fe ML |
805 | #define for_each_new_connector_in_state(__state, connector, new_connector_state, __i) \ |
806 | for ((__i) = 0; \ | |
331494eb ML |
807 | (__i) < (__state)->num_connector; \ |
808 | (__i)++) \ | |
809 | for_each_if ((__state)->connectors[__i].ptr && \ | |
810 | ((connector) = (__state)->connectors[__i].ptr, \ | |
bf5d837a BG |
811 | (void)(connector) /* Only to avoid unused-but-set-variable warning */, \ |
812 | (new_connector_state) = (__state)->connectors[__i].new_state, \ | |
813 | (void)(new_connector_state) /* Only to avoid unused-but-set-variable warning */, 1)) | |
581e49fe | 814 | |
f9a76955 DV |
815 | /** |
816 | * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update | |
817 | * @__state: &struct drm_atomic_state pointer | |
818 | * @crtc: &struct drm_crtc iteration cursor | |
819 | * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state | |
820 | * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state | |
821 | * @__i: int iteration cursor, for macro-internal use | |
822 | * | |
823 | * This iterates over all CRTCs in an atomic update, tracking both old and | |
824 | * new state. This is useful in places where the state delta needs to be | |
825 | * considered, for example in atomic check functions. | |
826 | */ | |
581e49fe ML |
827 | #define for_each_oldnew_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ |
828 | for ((__i) = 0; \ | |
331494eb | 829 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
581e49fe | 830 | (__i)++) \ |
331494eb ML |
831 | for_each_if ((__state)->crtcs[__i].ptr && \ |
832 | ((crtc) = (__state)->crtcs[__i].ptr, \ | |
bf5d837a | 833 | (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ |
331494eb | 834 | (old_crtc_state) = (__state)->crtcs[__i].old_state, \ |
bf5d837a | 835 | (void)(old_crtc_state) /* Only to avoid unused-but-set-variable warning */, \ |
94ffd9b8 LJ |
836 | (new_crtc_state) = (__state)->crtcs[__i].new_state, \ |
837 | (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) | |
581e49fe | 838 | |
f9a76955 DV |
839 | /** |
840 | * for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update | |
841 | * @__state: &struct drm_atomic_state pointer | |
842 | * @crtc: &struct drm_crtc iteration cursor | |
843 | * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state | |
844 | * @__i: int iteration cursor, for macro-internal use | |
845 | * | |
846 | * This iterates over all CRTCs in an atomic update, tracking only the old | |
847 | * state. This is useful in disable functions, where we need the old state the | |
848 | * hardware is still in. | |
849 | */ | |
581e49fe ML |
850 | #define for_each_old_crtc_in_state(__state, crtc, old_crtc_state, __i) \ |
851 | for ((__i) = 0; \ | |
331494eb | 852 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
581e49fe | 853 | (__i)++) \ |
331494eb ML |
854 | for_each_if ((__state)->crtcs[__i].ptr && \ |
855 | ((crtc) = (__state)->crtcs[__i].ptr, \ | |
e232e3d4 | 856 | (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ |
331494eb | 857 | (old_crtc_state) = (__state)->crtcs[__i].old_state, 1)) |
581e49fe | 858 | |
f9a76955 DV |
859 | /** |
860 | * for_each_new_crtc_in_state - iterate over all CRTCs in an atomic update | |
861 | * @__state: &struct drm_atomic_state pointer | |
862 | * @crtc: &struct drm_crtc iteration cursor | |
863 | * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state | |
864 | * @__i: int iteration cursor, for macro-internal use | |
865 | * | |
866 | * This iterates over all CRTCs in an atomic update, tracking only the new | |
867 | * state. This is useful in enable functions, where we need the new state the | |
868 | * hardware should be in when the atomic commit operation has completed. | |
869 | */ | |
581e49fe ML |
870 | #define for_each_new_crtc_in_state(__state, crtc, new_crtc_state, __i) \ |
871 | for ((__i) = 0; \ | |
331494eb | 872 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
581e49fe | 873 | (__i)++) \ |
331494eb ML |
874 | for_each_if ((__state)->crtcs[__i].ptr && \ |
875 | ((crtc) = (__state)->crtcs[__i].ptr, \ | |
bf5d837a BG |
876 | (void)(crtc) /* Only to avoid unused-but-set-variable warning */, \ |
877 | (new_crtc_state) = (__state)->crtcs[__i].new_state, \ | |
878 | (void)(new_crtc_state) /* Only to avoid unused-but-set-variable warning */, 1)) | |
581e49fe | 879 | |
f9a76955 DV |
880 | /** |
881 | * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update | |
882 | * @__state: &struct drm_atomic_state pointer | |
883 | * @plane: &struct drm_plane iteration cursor | |
884 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state | |
885 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state | |
886 | * @__i: int iteration cursor, for macro-internal use | |
887 | * | |
888 | * This iterates over all planes in an atomic update, tracking both old and | |
889 | * new state. This is useful in places where the state delta needs to be | |
890 | * considered, for example in atomic check functions. | |
891 | */ | |
581e49fe ML |
892 | #define for_each_oldnew_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ |
893 | for ((__i) = 0; \ | |
331494eb | 894 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
581e49fe | 895 | (__i)++) \ |
331494eb ML |
896 | for_each_if ((__state)->planes[__i].ptr && \ |
897 | ((plane) = (__state)->planes[__i].ptr, \ | |
bf5d837a | 898 | (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ |
331494eb ML |
899 | (old_plane_state) = (__state)->planes[__i].old_state,\ |
900 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) | |
581e49fe | 901 | |
55de2923 S |
902 | /** |
903 | * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic | |
904 | * update in reverse order | |
905 | * @__state: &struct drm_atomic_state pointer | |
906 | * @plane: &struct drm_plane iteration cursor | |
907 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state | |
908 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state | |
909 | * @__i: int iteration cursor, for macro-internal use | |
910 | * | |
911 | * This iterates over all planes in an atomic update in reverse order, | |
912 | * tracking both old and new state. This is useful in places where the | |
913 | * state delta needs to be considered, for example in atomic check functions. | |
914 | */ | |
915 | #define for_each_oldnew_plane_in_state_reverse(__state, plane, old_plane_state, new_plane_state, __i) \ | |
916 | for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \ | |
917 | (__i) >= 0; \ | |
918 | (__i)--) \ | |
919 | for_each_if ((__state)->planes[__i].ptr && \ | |
920 | ((plane) = (__state)->planes[__i].ptr, \ | |
921 | (old_plane_state) = (__state)->planes[__i].old_state,\ | |
922 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) | |
923 | ||
a6c3c37b YK |
924 | /** |
925 | * for_each_new_plane_in_state_reverse - other than only tracking new state, | |
926 | * it's the same as for_each_oldnew_plane_in_state_reverse | |
c45d9400 YK |
927 | * @__state: &struct drm_atomic_state pointer |
928 | * @plane: &struct drm_plane iteration cursor | |
929 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state | |
930 | * @__i: int iteration cursor, for macro-internal use | |
a6c3c37b YK |
931 | */ |
932 | #define for_each_new_plane_in_state_reverse(__state, plane, new_plane_state, __i) \ | |
933 | for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \ | |
934 | (__i) >= 0; \ | |
935 | (__i)--) \ | |
936 | for_each_if ((__state)->planes[__i].ptr && \ | |
937 | ((plane) = (__state)->planes[__i].ptr, \ | |
938 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) | |
939 | ||
f9a76955 DV |
940 | /** |
941 | * for_each_old_plane_in_state - iterate over all planes in an atomic update | |
942 | * @__state: &struct drm_atomic_state pointer | |
943 | * @plane: &struct drm_plane iteration cursor | |
944 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state | |
945 | * @__i: int iteration cursor, for macro-internal use | |
946 | * | |
947 | * This iterates over all planes in an atomic update, tracking only the old | |
948 | * state. This is useful in disable functions, where we need the old state the | |
949 | * hardware is still in. | |
950 | */ | |
581e49fe ML |
951 | #define for_each_old_plane_in_state(__state, plane, old_plane_state, __i) \ |
952 | for ((__i) = 0; \ | |
331494eb | 953 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
581e49fe | 954 | (__i)++) \ |
331494eb ML |
955 | for_each_if ((__state)->planes[__i].ptr && \ |
956 | ((plane) = (__state)->planes[__i].ptr, \ | |
957 | (old_plane_state) = (__state)->planes[__i].old_state, 1)) | |
f9a76955 DV |
958 | /** |
959 | * for_each_new_plane_in_state - iterate over all planes in an atomic update | |
960 | * @__state: &struct drm_atomic_state pointer | |
961 | * @plane: &struct drm_plane iteration cursor | |
962 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state | |
963 | * @__i: int iteration cursor, for macro-internal use | |
964 | * | |
965 | * This iterates over all planes in an atomic update, tracking only the new | |
966 | * state. This is useful in enable functions, where we need the new state the | |
967 | * hardware should be in when the atomic commit operation has completed. | |
968 | */ | |
581e49fe ML |
969 | #define for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \ |
970 | for ((__i) = 0; \ | |
331494eb | 971 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
581e49fe | 972 | (__i)++) \ |
331494eb ML |
973 | for_each_if ((__state)->planes[__i].ptr && \ |
974 | ((plane) = (__state)->planes[__i].ptr, \ | |
bf5d837a BG |
975 | (void)(plane) /* Only to avoid unused-but-set-variable warning */, \ |
976 | (new_plane_state) = (__state)->planes[__i].new_state, \ | |
977 | (void)(new_plane_state) /* Only to avoid unused-but-set-variable warning */, 1)) | |
581e49fe | 978 | |
b430c27a | 979 | /** |
a4370c77 | 980 | * for_each_oldnew_private_obj_in_state - iterate over all private objects in an atomic update |
b430c27a | 981 | * @__state: &struct drm_atomic_state pointer |
a4370c77 VS |
982 | * @obj: &struct drm_private_obj iteration cursor |
983 | * @old_obj_state: &struct drm_private_state iteration cursor for the old state | |
984 | * @new_obj_state: &struct drm_private_state iteration cursor for the new state | |
b430c27a | 985 | * @__i: int iteration cursor, for macro-internal use |
b430c27a | 986 | * |
a4370c77 VS |
987 | * This iterates over all private objects in an atomic update, tracking both |
988 | * old and new state. This is useful in places where the state delta needs | |
989 | * to be considered, for example in atomic check functions. | |
b430c27a | 990 | */ |
a4370c77 VS |
991 | #define for_each_oldnew_private_obj_in_state(__state, obj, old_obj_state, new_obj_state, __i) \ |
992 | for ((__i) = 0; \ | |
993 | (__i) < (__state)->num_private_objs && \ | |
994 | ((obj) = (__state)->private_objs[__i].ptr, \ | |
995 | (old_obj_state) = (__state)->private_objs[__i].old_state, \ | |
996 | (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ | |
f0d2e86c | 997 | (__i)++) |
a4370c77 VS |
998 | |
999 | /** | |
1000 | * for_each_old_private_obj_in_state - iterate over all private objects in an atomic update | |
1001 | * @__state: &struct drm_atomic_state pointer | |
1002 | * @obj: &struct drm_private_obj iteration cursor | |
1003 | * @old_obj_state: &struct drm_private_state iteration cursor for the old state | |
1004 | * @__i: int iteration cursor, for macro-internal use | |
1005 | * | |
1006 | * This iterates over all private objects in an atomic update, tracking only | |
1007 | * the old state. This is useful in disable functions, where we need the old | |
1008 | * state the hardware is still in. | |
1009 | */ | |
1010 | #define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i) \ | |
1011 | for ((__i) = 0; \ | |
1012 | (__i) < (__state)->num_private_objs && \ | |
1013 | ((obj) = (__state)->private_objs[__i].ptr, \ | |
1014 | (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \ | |
f0d2e86c | 1015 | (__i)++) |
b430c27a PD |
1016 | |
1017 | /** | |
a4370c77 | 1018 | * for_each_new_private_obj_in_state - iterate over all private objects in an atomic update |
b430c27a | 1019 | * @__state: &struct drm_atomic_state pointer |
a4370c77 VS |
1020 | * @obj: &struct drm_private_obj iteration cursor |
1021 | * @new_obj_state: &struct drm_private_state iteration cursor for the new state | |
b430c27a | 1022 | * @__i: int iteration cursor, for macro-internal use |
b430c27a | 1023 | * |
a4370c77 VS |
1024 | * This iterates over all private objects in an atomic update, tracking only |
1025 | * the new state. This is useful in enable functions, where we need the new state the | |
1026 | * hardware should be in when the atomic commit operation has completed. | |
b430c27a | 1027 | */ |
a4370c77 VS |
1028 | #define for_each_new_private_obj_in_state(__state, obj, new_obj_state, __i) \ |
1029 | for ((__i) = 0; \ | |
1030 | (__i) < (__state)->num_private_objs && \ | |
1031 | ((obj) = (__state)->private_objs[__i].ptr, \ | |
4527d47b | 1032 | (void)(obj) /* Only to avoid unused-but-set-variable warning */, \ |
a4370c77 | 1033 | (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ |
f0d2e86c | 1034 | (__i)++) |
b430c27a | 1035 | |
081e9c0f DV |
1036 | /** |
1037 | * drm_atomic_crtc_needs_modeset - compute combined modeset need | |
1038 | * @state: &drm_crtc_state for the CRTC | |
1039 | * | |
ea0dd85a | 1040 | * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track |
081e9c0f | 1041 | * whether the state CRTC changed enough to need a full modeset cycle: |
96bf51df | 1042 | * mode_changed, active_changed and connectors_changed. This helper simply |
081e9c0f | 1043 | * combines these three to compute the overall need for a modeset for @state. |
d807ed1c BS |
1044 | * |
1045 | * The atomic helper code sets these booleans, but drivers can and should | |
1046 | * change them appropriately to accurately represent whether a modeset is | |
1047 | * really needed. In general, drivers should avoid full modesets whenever | |
1048 | * possible. | |
1049 | * | |
1050 | * For example if the CRTC mode has changed, and the hardware is able to enact | |
1051 | * the requested mode change without going through a full modeset, the driver | |
d574528a DV |
1052 | * should clear mode_changed in its &drm_mode_config_funcs.atomic_check |
1053 | * implementation. | |
081e9c0f | 1054 | */ |
2465ff62 | 1055 | static inline bool |
79b95552 | 1056 | drm_atomic_crtc_needs_modeset(const struct drm_crtc_state *state) |
2465ff62 | 1057 | { |
fc596660 ML |
1058 | return state->mode_changed || state->active_changed || |
1059 | state->connectors_changed; | |
2465ff62 DV |
1060 | } |
1061 | ||
1452c25b | 1062 | /** |
42240c90 | 1063 | * drm_atomic_crtc_effectively_active - compute whether CRTC is actually active |
1452c25b SP |
1064 | * @state: &drm_crtc_state for the CRTC |
1065 | * | |
1066 | * When in self refresh mode, the crtc_state->active value will be false, since | |
42240c90 | 1067 | * the CRTC is off. However in some cases we're interested in whether the CRTC |
1452c25b SP |
1068 | * is active, or effectively active (ie: it's connected to an active display). |
1069 | * In these cases, use this function instead of just checking active. | |
1070 | */ | |
1071 | static inline bool | |
1072 | drm_atomic_crtc_effectively_active(const struct drm_crtc_state *state) | |
1073 | { | |
1074 | return state->active || state->self_refresh_active; | |
1075 | } | |
1076 | ||
f32df58a BB |
1077 | /** |
1078 | * struct drm_bus_cfg - bus configuration | |
1079 | * | |
1080 | * This structure stores the configuration of a physical bus between two | |
1081 | * components in an output pipeline, usually between two bridges, an encoder | |
1082 | * and a bridge, or a bridge and a connector. | |
1083 | * | |
1084 | * The bus configuration is stored in &drm_bridge_state separately for the | |
1085 | * input and output buses, as seen from the point of view of each bridge. The | |
1086 | * bus configuration of a bridge output is usually identical to the | |
1087 | * configuration of the next bridge's input, but may differ if the signals are | |
1088 | * modified between the two bridges, for instance by an inverter on the board. | |
1089 | * The input and output configurations of a bridge may differ if the bridge | |
1090 | * modifies the signals internally, for instance by performing format | |
1091 | * conversion, or modifying signals polarities. | |
1092 | */ | |
1093 | struct drm_bus_cfg { | |
1094 | /** | |
1095 | * @format: format used on this bus (one of the MEDIA_BUS_FMT_* format) | |
1096 | * | |
1097 | * This field should not be directly modified by drivers | |
91ea8330 | 1098 | * (drm_atomic_bridge_chain_select_bus_fmts() takes care of the bus |
f32df58a BB |
1099 | * format negotiation). |
1100 | */ | |
1101 | u32 format; | |
1102 | ||
1103 | /** | |
1104 | * @flags: DRM_BUS_* flags used on this bus | |
1105 | */ | |
1106 | u32 flags; | |
1107 | }; | |
1108 | ||
75146591 BB |
1109 | /** |
1110 | * struct drm_bridge_state - Atomic bridge state object | |
1111 | */ | |
1112 | struct drm_bridge_state { | |
1113 | /** | |
1114 | * @base: inherit from &drm_private_state | |
1115 | */ | |
1116 | struct drm_private_state base; | |
1117 | ||
1118 | /** | |
1119 | * @bridge: the bridge this state refers to | |
1120 | */ | |
1121 | struct drm_bridge *bridge; | |
f32df58a BB |
1122 | |
1123 | /** | |
1124 | * @input_bus_cfg: input bus configuration | |
1125 | */ | |
1126 | struct drm_bus_cfg input_bus_cfg; | |
1127 | ||
1128 | /** | |
1129 | * @output_bus_cfg: input bus configuration | |
1130 | */ | |
1131 | struct drm_bus_cfg output_bus_cfg; | |
75146591 BB |
1132 | }; |
1133 | ||
1134 | static inline struct drm_bridge_state * | |
1135 | drm_priv_to_bridge_state(struct drm_private_state *priv) | |
1136 | { | |
1137 | return container_of(priv, struct drm_bridge_state, base); | |
1138 | } | |
1139 | ||
1140 | struct drm_bridge_state * | |
1141 | drm_atomic_get_bridge_state(struct drm_atomic_state *state, | |
1142 | struct drm_bridge *bridge); | |
1143 | struct drm_bridge_state * | |
2081bd89 | 1144 | drm_atomic_get_old_bridge_state(const struct drm_atomic_state *state, |
75146591 BB |
1145 | struct drm_bridge *bridge); |
1146 | struct drm_bridge_state * | |
2081bd89 | 1147 | drm_atomic_get_new_bridge_state(const struct drm_atomic_state *state, |
75146591 BB |
1148 | struct drm_bridge *bridge); |
1149 | ||
cc4ceb48 | 1150 | #endif /* DRM_ATOMIC_H_ */ |