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 | |
31 | #include <drm/drm_crtc.h> |
32 | #include <drm/drm_util.h> |
33 | |
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 |
38 | * a per-CRTC basis. Since updating the list should never block this structure |
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 | * |
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 |
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. |
69 | */ |
70 | struct drm_crtc_commit { |
71 | /** |
72 | * @crtc: |
73 | * |
74 | * DRM CRTC for this commit. |
75 | */ |
76 | struct drm_crtc *crtc; |
77 | |
78 | /** |
79 | * @ref: |
80 | * |
81 | * Reference count for this structure. Needed to allow blocking on |
82 | * completions without the risk of the completion disappearing |
83 | * meanwhile. |
84 | */ |
85 | struct kref ref; |
86 | |
87 | /** |
88 | * @flip_done: |
89 | * |
90 | * Will be signaled when the hardware has flipped to the new set of |
91 | * buffers. Signals at the same time as when the drm event for this |
92 | * commit is sent to userspace, or when an out-fence is singalled. Note |
93 | * that for most hardware, in most cases this happens after @hw_done is |
94 | * signalled. |
95 | */ |
96 | struct completion flip_done; |
97 | |
98 | /** |
99 | * @hw_done: |
100 | * |
101 | * Will be signalled when all hw register changes for this commit have |
102 | * been written out. Especially when disabling a pipe this can be much |
103 | * later than than @flip_done, since that can signal already when the |
104 | * screen goes black, whereas to fully shut down a pipe more register |
105 | * I/O is required. |
106 | * |
107 | * Note that this does not need to include separately reference-counted |
108 | * resources like backing storage buffer pinning, or runtime pm |
109 | * management. |
110 | */ |
111 | struct completion hw_done; |
112 | |
113 | /** |
114 | * @cleanup_done: |
115 | * |
116 | * Will be signalled after old buffers have been cleaned up by calling |
117 | * drm_atomic_helper_cleanup_planes(). Since this can only happen after |
118 | * a vblank wait completed it might be a bit later. This completion is |
119 | * useful to throttle updates and avoid hardware updates getting ahead |
120 | * of the buffer cleanup too much. |
121 | */ |
122 | struct completion cleanup_done; |
123 | |
124 | /** |
125 | * @commit_entry: |
126 | * |
127 | * Entry on the per-CRTC &drm_crtc.commit_list. Protected by |
128 | * $drm_crtc.commit_lock. |
129 | */ |
130 | struct list_head commit_entry; |
131 | |
132 | /** |
133 | * @event: |
134 | * |
135 | * &drm_pending_vblank_event pointer to clean up private events. |
136 | */ |
137 | struct drm_pending_vblank_event *event; |
138 | |
139 | /** |
140 | * @abort_completion: |
141 | * |
142 | * A flag that's set after drm_atomic_helper_setup_commit() takes a |
143 | * second reference for the completion of $drm_crtc_state.event. It's |
144 | * used by the free code to remove the second reference if commit fails. |
145 | */ |
146 | bool abort_completion; |
147 | }; |
148 | |
149 | struct __drm_planes_state { |
150 | struct drm_plane *ptr; |
151 | struct drm_plane_state *state, *old_state, *new_state; |
152 | }; |
153 | |
154 | struct __drm_crtcs_state { |
155 | struct drm_crtc *ptr; |
156 | struct drm_crtc_state *state, *old_state, *new_state; |
157 | |
158 | /** |
159 | * @commit: |
160 | * |
161 | * A reference to the CRTC commit object that is kept for use by |
162 | * drm_atomic_helper_wait_for_flip_done() after |
163 | * drm_atomic_helper_commit_hw_done() is called. This ensures that a |
164 | * concurrent commit won't free a commit object that is still in use. |
165 | */ |
166 | struct drm_crtc_commit *commit; |
167 | |
168 | s32 __user *out_fence_ptr; |
169 | u64 last_vblank_count; |
170 | }; |
171 | |
172 | struct __drm_connnectors_state { |
173 | struct drm_connector *ptr; |
174 | struct drm_connector_state *state, *old_state, *new_state; |
175 | /** |
176 | * @out_fence_ptr: |
177 | * |
178 | * User-provided pointer which the kernel uses to return a sync_file |
179 | * file descriptor. Used by writeback connectors to signal completion of |
180 | * the writeback. |
181 | */ |
182 | s32 __user *out_fence_ptr; |
183 | }; |
184 | |
185 | struct drm_private_obj; |
186 | struct drm_private_state; |
187 | |
188 | /** |
189 | * struct drm_private_state_funcs - atomic state functions for private objects |
190 | * |
191 | * These hooks are used by atomic helpers to create, swap and destroy states of |
192 | * private objects. The structure itself is used as a vtable to identify the |
193 | * associated private object type. Each private object type that needs to be |
194 | * added to the atomic states is expected to have an implementation of these |
195 | * hooks and pass a pointer to its drm_private_state_funcs struct to |
196 | * drm_atomic_get_private_obj_state(). |
197 | */ |
198 | struct drm_private_state_funcs { |
199 | /** |
200 | * @atomic_duplicate_state: |
201 | * |
202 | * Duplicate the current state of the private object and return it. It |
203 | * is an error to call this before obj->state has been initialized. |
204 | * |
205 | * RETURNS: |
206 | * |
207 | * Duplicated atomic state or NULL when obj->state is not |
208 | * initialized or allocation failed. |
209 | */ |
210 | struct drm_private_state *(*atomic_duplicate_state)(struct drm_private_obj *obj); |
211 | |
212 | /** |
213 | * @atomic_destroy_state: |
214 | * |
215 | * Frees the private object state created with @atomic_duplicate_state. |
216 | */ |
217 | void (*atomic_destroy_state)(struct drm_private_obj *obj, |
218 | struct drm_private_state *state); |
219 | }; |
220 | |
221 | /** |
222 | * struct drm_private_obj - base struct for driver private atomic object |
223 | * |
224 | * A driver private object is initialized by calling |
225 | * drm_atomic_private_obj_init() and cleaned up by calling |
226 | * drm_atomic_private_obj_fini(). |
227 | * |
228 | * Currently only tracks the state update functions and the opaque driver |
229 | * private state itself, but in the future might also track which |
230 | * &drm_modeset_lock is required to duplicate and update this object's state. |
231 | * |
232 | * All private objects must be initialized before the DRM device they are |
233 | * attached to is registered to the DRM subsystem (call to drm_dev_register()) |
234 | * and should stay around until this DRM device is unregistered (call to |
235 | * drm_dev_unregister()). In other words, private objects lifetime is tied |
236 | * to the DRM device lifetime. This implies that: |
237 | * |
238 | * 1/ all calls to drm_atomic_private_obj_init() must be done before calling |
239 | * drm_dev_register() |
240 | * 2/ all calls to drm_atomic_private_obj_fini() must be done after calling |
241 | * drm_dev_unregister() |
242 | */ |
243 | struct drm_private_obj { |
244 | /** |
245 | * @head: List entry used to attach a private object to a &drm_device |
246 | * (queued to &drm_mode_config.privobj_list). |
247 | */ |
248 | struct list_head head; |
249 | |
250 | /** |
251 | * @lock: Modeset lock to protect the state object. |
252 | */ |
253 | struct drm_modeset_lock lock; |
254 | |
255 | /** |
256 | * @state: Current atomic state for this driver private object. |
257 | */ |
258 | struct drm_private_state *state; |
259 | |
260 | /** |
261 | * @funcs: |
262 | * |
263 | * Functions to manipulate the state of this driver private object, see |
264 | * &drm_private_state_funcs. |
265 | */ |
266 | const struct drm_private_state_funcs *funcs; |
267 | }; |
268 | |
269 | /** |
270 | * drm_for_each_privobj() - private object iterator |
271 | * |
272 | * @privobj: pointer to the current private object. Updated after each |
273 | * iteration |
274 | * @dev: the DRM device we want get private objects from |
275 | * |
276 | * Allows one to iterate over all private objects attached to @dev |
277 | */ |
278 | #define drm_for_each_privobj(privobj, dev) \ |
279 | list_for_each_entry(privobj, &(dev)->mode_config.privobj_list, head) |
280 | |
281 | /** |
282 | * struct drm_private_state - base struct for driver private object state |
283 | * @state: backpointer to global drm_atomic_state |
284 | * |
285 | * Currently only contains a backpointer to the overall atomic update, but in |
286 | * the future also might hold synchronization information similar to e.g. |
287 | * &drm_crtc.commit. |
288 | */ |
289 | struct drm_private_state { |
290 | struct drm_atomic_state *state; |
291 | }; |
292 | |
293 | struct __drm_private_objs_state { |
294 | struct drm_private_obj *ptr; |
295 | struct drm_private_state *state, *old_state, *new_state; |
296 | }; |
297 | |
298 | /** |
299 | * struct drm_atomic_state - the global state object for atomic updates |
300 | * @ref: count of all references to this state (will not be freed until zero) |
301 | * @dev: parent DRM device |
302 | * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics |
303 | * @async_update: hint for asynchronous plane update |
304 | * @planes: pointer to array of structures with per-plane data |
305 | * @crtcs: pointer to array of CRTC pointers |
306 | * @num_connector: size of the @connectors and @connector_states arrays |
307 | * @connectors: pointer to array of structures with per-connector data |
308 | * @num_private_objs: size of the @private_objs array |
309 | * @private_objs: pointer to array of private object pointers |
310 | * @acquire_ctx: acquire context for this atomic modeset state update |
311 | * |
312 | * States are added to an atomic update by calling drm_atomic_get_crtc_state(), |
313 | * drm_atomic_get_plane_state(), drm_atomic_get_connector_state(), or for |
314 | * private state structures, drm_atomic_get_private_obj_state(). |
315 | */ |
316 | struct drm_atomic_state { |
317 | struct kref ref; |
318 | |
319 | struct drm_device *dev; |
320 | |
321 | /** |
322 | * @allow_modeset: |
323 | * |
324 | * Allow full modeset. This is used by the ATOMIC IOCTL handler to |
325 | * implement the DRM_MODE_ATOMIC_ALLOW_MODESET flag. Drivers should |
326 | * never consult this flag, instead looking at the output of |
327 | * drm_atomic_crtc_needs_modeset(). |
328 | */ |
329 | bool allow_modeset : 1; |
330 | bool legacy_cursor_update : 1; |
331 | bool async_update : 1; |
332 | /** |
333 | * @duplicated: |
334 | * |
335 | * Indicates whether or not this atomic state was duplicated using |
336 | * drm_atomic_helper_duplicate_state(). Drivers and atomic helpers |
337 | * should use this to fixup normal inconsistencies in duplicated |
338 | * states. |
339 | */ |
340 | bool duplicated : 1; |
341 | struct __drm_planes_state *planes; |
342 | struct __drm_crtcs_state *crtcs; |
343 | int num_connector; |
344 | struct __drm_connnectors_state *connectors; |
345 | int num_private_objs; |
346 | struct __drm_private_objs_state *private_objs; |
347 | |
348 | struct drm_modeset_acquire_ctx *acquire_ctx; |
349 | |
350 | /** |
351 | * @fake_commit: |
352 | * |
353 | * Used for signaling unbound planes/connectors. |
354 | * When a connector or plane is not bound to any CRTC, it's still important |
355 | * to preserve linearity to prevent the atomic states from being freed to early. |
356 | * |
357 | * This commit (if set) is not bound to any crtc, but will be completed when |
358 | * drm_atomic_helper_commit_hw_done() is called. |
359 | */ |
360 | struct drm_crtc_commit *fake_commit; |
361 | |
362 | /** |
363 | * @commit_work: |
364 | * |
365 | * Work item which can be used by the driver or helpers to execute the |
366 | * commit without blocking. |
367 | */ |
368 | struct work_struct commit_work; |
369 | }; |
370 | |
371 | void __drm_crtc_commit_free(struct kref *kref); |
372 | |
373 | /** |
374 | * drm_crtc_commit_get - acquire a reference to the CRTC commit |
375 | * @commit: CRTC commit |
376 | * |
377 | * Increases the reference of @commit. |
378 | * |
379 | * Returns: |
380 | * The pointer to @commit, with reference increased. |
381 | */ |
382 | static inline struct drm_crtc_commit *drm_crtc_commit_get(struct drm_crtc_commit *commit) |
383 | { |
384 | kref_get(&commit->ref); |
385 | return commit; |
386 | } |
387 | |
388 | /** |
389 | * drm_crtc_commit_put - release a reference to the CRTC commmit |
390 | * @commit: CRTC commit |
391 | * |
392 | * This releases a reference to @commit which is freed after removing the |
393 | * final reference. No locking required and callable from any context. |
394 | */ |
395 | static inline void drm_crtc_commit_put(struct drm_crtc_commit *commit) |
396 | { |
397 | kref_put(&commit->ref, __drm_crtc_commit_free); |
398 | } |
399 | |
400 | struct drm_atomic_state * __must_check |
401 | drm_atomic_state_alloc(struct drm_device *dev); |
402 | void drm_atomic_state_clear(struct drm_atomic_state *state); |
403 | |
404 | /** |
405 | * drm_atomic_state_get - acquire a reference to the atomic state |
406 | * @state: The atomic state |
407 | * |
408 | * Returns a new reference to the @state |
409 | */ |
410 | static inline struct drm_atomic_state * |
411 | drm_atomic_state_get(struct drm_atomic_state *state) |
412 | { |
413 | kref_get(&state->ref); |
414 | return state; |
415 | } |
416 | |
417 | void __drm_atomic_state_free(struct kref *ref); |
418 | |
419 | /** |
420 | * drm_atomic_state_put - release a reference to the atomic state |
421 | * @state: The atomic state |
422 | * |
423 | * This releases a reference to @state which is freed after removing the |
424 | * final reference. No locking required and callable from any context. |
425 | */ |
426 | static inline void drm_atomic_state_put(struct drm_atomic_state *state) |
427 | { |
428 | kref_put(&state->ref, __drm_atomic_state_free); |
429 | } |
430 | |
431 | int __must_check |
432 | drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state); |
433 | void drm_atomic_state_default_clear(struct drm_atomic_state *state); |
434 | void drm_atomic_state_default_release(struct drm_atomic_state *state); |
435 | |
436 | struct drm_crtc_state * __must_check |
437 | drm_atomic_get_crtc_state(struct drm_atomic_state *state, |
438 | struct drm_crtc *crtc); |
439 | struct drm_plane_state * __must_check |
440 | drm_atomic_get_plane_state(struct drm_atomic_state *state, |
441 | struct drm_plane *plane); |
442 | struct drm_connector_state * __must_check |
443 | drm_atomic_get_connector_state(struct drm_atomic_state *state, |
444 | struct drm_connector *connector); |
445 | |
446 | void drm_atomic_private_obj_init(struct drm_device *dev, |
447 | struct drm_private_obj *obj, |
448 | struct drm_private_state *state, |
449 | const struct drm_private_state_funcs *funcs); |
450 | void drm_atomic_private_obj_fini(struct drm_private_obj *obj); |
451 | |
452 | struct drm_private_state * __must_check |
453 | drm_atomic_get_private_obj_state(struct drm_atomic_state *state, |
454 | struct drm_private_obj *obj); |
455 | |
456 | /** |
457 | * drm_atomic_get_existing_crtc_state - get crtc state, if it exists |
458 | * @state: global atomic state object |
459 | * @crtc: crtc to grab |
460 | * |
461 | * This function returns the crtc state for the given crtc, or NULL |
462 | * if the crtc is not part of the global atomic state. |
463 | * |
464 | * This function is deprecated, @drm_atomic_get_old_crtc_state or |
465 | * @drm_atomic_get_new_crtc_state should be used instead. |
466 | */ |
467 | static inline struct drm_crtc_state * |
468 | drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state, |
469 | struct drm_crtc *crtc) |
470 | { |
471 | return state->crtcs[drm_crtc_index(crtc)].state; |
472 | } |
473 | |
474 | /** |
475 | * drm_atomic_get_old_crtc_state - get old crtc state, if it exists |
476 | * @state: global atomic state object |
477 | * @crtc: crtc to grab |
478 | * |
479 | * This function returns the old crtc state for the given crtc, or |
480 | * NULL if the crtc is not part of the global atomic state. |
481 | */ |
482 | static inline struct drm_crtc_state * |
483 | drm_atomic_get_old_crtc_state(struct drm_atomic_state *state, |
484 | struct drm_crtc *crtc) |
485 | { |
486 | return state->crtcs[drm_crtc_index(crtc)].old_state; |
487 | } |
488 | /** |
489 | * drm_atomic_get_new_crtc_state - get new crtc state, if it exists |
490 | * @state: global atomic state object |
491 | * @crtc: crtc to grab |
492 | * |
493 | * This function returns the new crtc state for the given crtc, or |
494 | * NULL if the crtc is not part of the global atomic state. |
495 | */ |
496 | static inline struct drm_crtc_state * |
497 | drm_atomic_get_new_crtc_state(struct drm_atomic_state *state, |
498 | struct drm_crtc *crtc) |
499 | { |
500 | return state->crtcs[drm_crtc_index(crtc)].new_state; |
501 | } |
502 | |
503 | /** |
504 | * drm_atomic_get_existing_plane_state - get plane state, if it exists |
505 | * @state: global atomic state object |
506 | * @plane: plane to grab |
507 | * |
508 | * This function returns the plane state for the given plane, or NULL |
509 | * if the plane is not part of the global atomic state. |
510 | * |
511 | * This function is deprecated, @drm_atomic_get_old_plane_state or |
512 | * @drm_atomic_get_new_plane_state should be used instead. |
513 | */ |
514 | static inline struct drm_plane_state * |
515 | drm_atomic_get_existing_plane_state(struct drm_atomic_state *state, |
516 | struct drm_plane *plane) |
517 | { |
518 | return state->planes[drm_plane_index(plane)].state; |
519 | } |
520 | |
521 | /** |
522 | * drm_atomic_get_old_plane_state - get plane state, if it exists |
523 | * @state: global atomic state object |
524 | * @plane: plane to grab |
525 | * |
526 | * This function returns the old plane state for the given plane, or |
527 | * NULL if the plane is not part of the global atomic state. |
528 | */ |
529 | static inline struct drm_plane_state * |
530 | drm_atomic_get_old_plane_state(struct drm_atomic_state *state, |
531 | struct drm_plane *plane) |
532 | { |
533 | return state->planes[drm_plane_index(plane)].old_state; |
534 | } |
535 | |
536 | /** |
537 | * drm_atomic_get_new_plane_state - get plane state, if it exists |
538 | * @state: global atomic state object |
539 | * @plane: plane to grab |
540 | * |
541 | * This function returns the new plane state for the given plane, or |
542 | * NULL if the plane is not part of the global atomic state. |
543 | */ |
544 | static inline struct drm_plane_state * |
545 | drm_atomic_get_new_plane_state(struct drm_atomic_state *state, |
546 | struct drm_plane *plane) |
547 | { |
548 | return state->planes[drm_plane_index(plane)].new_state; |
549 | } |
550 | |
551 | /** |
552 | * drm_atomic_get_existing_connector_state - get connector state, if it exists |
553 | * @state: global atomic state object |
554 | * @connector: connector to grab |
555 | * |
556 | * This function returns the connector state for the given connector, |
557 | * or NULL if the connector is not part of the global atomic state. |
558 | * |
559 | * This function is deprecated, @drm_atomic_get_old_connector_state or |
560 | * @drm_atomic_get_new_connector_state should be used instead. |
561 | */ |
562 | static inline struct drm_connector_state * |
563 | drm_atomic_get_existing_connector_state(struct drm_atomic_state *state, |
564 | struct drm_connector *connector) |
565 | { |
566 | int index = drm_connector_index(connector); |
567 | |
568 | if (index >= state->num_connector) |
569 | return NULL; |
570 | |
571 | return state->connectors[index].state; |
572 | } |
573 | |
574 | /** |
575 | * drm_atomic_get_old_connector_state - get connector state, if it exists |
576 | * @state: global atomic state object |
577 | * @connector: connector to grab |
578 | * |
579 | * This function returns the old connector state for the given connector, |
580 | * or NULL if the connector is not part of the global atomic state. |
581 | */ |
582 | static inline struct drm_connector_state * |
583 | drm_atomic_get_old_connector_state(struct drm_atomic_state *state, |
584 | struct drm_connector *connector) |
585 | { |
586 | int index = drm_connector_index(connector); |
587 | |
588 | if (index >= state->num_connector) |
589 | return NULL; |
590 | |
591 | return state->connectors[index].old_state; |
592 | } |
593 | |
594 | /** |
595 | * drm_atomic_get_new_connector_state - get connector state, if it exists |
596 | * @state: global atomic state object |
597 | * @connector: connector to grab |
598 | * |
599 | * This function returns the new connector state for the given connector, |
600 | * or NULL if the connector is not part of the global atomic state. |
601 | */ |
602 | static inline struct drm_connector_state * |
603 | drm_atomic_get_new_connector_state(struct drm_atomic_state *state, |
604 | struct drm_connector *connector) |
605 | { |
606 | int index = drm_connector_index(connector); |
607 | |
608 | if (index >= state->num_connector) |
609 | return NULL; |
610 | |
611 | return state->connectors[index].new_state; |
612 | } |
613 | |
614 | /** |
615 | * __drm_atomic_get_current_plane_state - get current plane state |
616 | * @state: global atomic state object |
617 | * @plane: plane to grab |
618 | * |
619 | * This function returns the plane state for the given plane, either from |
620 | * @state, or if the plane isn't part of the atomic state update, from @plane. |
621 | * This is useful in atomic check callbacks, when drivers need to peek at, but |
622 | * not change, state of other planes, since it avoids threading an error code |
623 | * back up the call chain. |
624 | * |
625 | * WARNING: |
626 | * |
627 | * Note that this function is in general unsafe since it doesn't check for the |
628 | * required locking for access state structures. Drivers must ensure that it is |
629 | * safe to access the returned state structure through other means. One common |
630 | * example is when planes are fixed to a single CRTC, and the driver knows that |
631 | * the CRTC lock is held already. In that case holding the CRTC lock gives a |
632 | * read-lock on all planes connected to that CRTC. But if planes can be |
633 | * reassigned things get more tricky. In that case it's better to use |
634 | * drm_atomic_get_plane_state and wire up full error handling. |
635 | * |
636 | * Returns: |
637 | * |
638 | * Read-only pointer to the current plane state. |
639 | */ |
640 | static inline const struct drm_plane_state * |
641 | __drm_atomic_get_current_plane_state(struct drm_atomic_state *state, |
642 | struct drm_plane *plane) |
643 | { |
644 | if (state->planes[drm_plane_index(plane)].state) |
645 | return state->planes[drm_plane_index(plane)].state; |
646 | |
647 | return plane->state; |
648 | } |
649 | |
650 | int __must_check |
651 | drm_atomic_add_affected_connectors(struct drm_atomic_state *state, |
652 | struct drm_crtc *crtc); |
653 | int __must_check |
654 | drm_atomic_add_affected_planes(struct drm_atomic_state *state, |
655 | struct drm_crtc *crtc); |
656 | |
657 | int __must_check drm_atomic_check_only(struct drm_atomic_state *state); |
658 | int __must_check drm_atomic_commit(struct drm_atomic_state *state); |
659 | int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); |
660 | |
661 | void drm_state_dump(struct drm_device *dev, struct drm_printer *p); |
662 | |
663 | /** |
664 | * for_each_oldnew_connector_in_state - iterate over all connectors in an atomic update |
665 | * @__state: &struct drm_atomic_state pointer |
666 | * @connector: &struct drm_connector iteration cursor |
667 | * @old_connector_state: &struct drm_connector_state iteration cursor for the |
668 | * old state |
669 | * @new_connector_state: &struct drm_connector_state iteration cursor for the |
670 | * new state |
671 | * @__i: int iteration cursor, for macro-internal use |
672 | * |
673 | * This iterates over all connectors in an atomic update, tracking both old and |
674 | * new state. This is useful in places where the state delta needs to be |
675 | * considered, for example in atomic check functions. |
676 | */ |
677 | #define for_each_oldnew_connector_in_state(__state, connector, old_connector_state, new_connector_state, __i) \ |
678 | for ((__i) = 0; \ |
679 | (__i) < (__state)->num_connector; \ |
680 | (__i)++) \ |
681 | for_each_if ((__state)->connectors[__i].ptr && \ |
682 | ((connector) = (__state)->connectors[__i].ptr, \ |
683 | (old_connector_state) = (__state)->connectors[__i].old_state, \ |
684 | (new_connector_state) = (__state)->connectors[__i].new_state, 1)) |
685 | |
686 | /** |
687 | * for_each_old_connector_in_state - iterate over all connectors in an atomic update |
688 | * @__state: &struct drm_atomic_state pointer |
689 | * @connector: &struct drm_connector iteration cursor |
690 | * @old_connector_state: &struct drm_connector_state iteration cursor for the |
691 | * old state |
692 | * @__i: int iteration cursor, for macro-internal use |
693 | * |
694 | * This iterates over all connectors in an atomic update, tracking only the old |
695 | * state. This is useful in disable functions, where we need the old state the |
696 | * hardware is still in. |
697 | */ |
698 | #define for_each_old_connector_in_state(__state, connector, old_connector_state, __i) \ |
699 | for ((__i) = 0; \ |
700 | (__i) < (__state)->num_connector; \ |
701 | (__i)++) \ |
702 | for_each_if ((__state)->connectors[__i].ptr && \ |
703 | ((connector) = (__state)->connectors[__i].ptr, \ |
704 | (old_connector_state) = (__state)->connectors[__i].old_state, 1)) |
705 | |
706 | /** |
707 | * for_each_new_connector_in_state - iterate over all connectors in an atomic update |
708 | * @__state: &struct drm_atomic_state pointer |
709 | * @connector: &struct drm_connector iteration cursor |
710 | * @new_connector_state: &struct drm_connector_state iteration cursor for the |
711 | * new state |
712 | * @__i: int iteration cursor, for macro-internal use |
713 | * |
714 | * This iterates over all connectors in an atomic update, tracking only the new |
715 | * state. This is useful in enable functions, where we need the new state the |
716 | * hardware should be in when the atomic commit operation has completed. |
717 | */ |
718 | #define for_each_new_connector_in_state(__state, connector, new_connector_state, __i) \ |
719 | for ((__i) = 0; \ |
720 | (__i) < (__state)->num_connector; \ |
721 | (__i)++) \ |
722 | for_each_if ((__state)->connectors[__i].ptr && \ |
723 | ((connector) = (__state)->connectors[__i].ptr, \ |
724 | (new_connector_state) = (__state)->connectors[__i].new_state, 1)) |
725 | |
726 | /** |
727 | * for_each_oldnew_crtc_in_state - iterate over all CRTCs in an atomic update |
728 | * @__state: &struct drm_atomic_state pointer |
729 | * @crtc: &struct drm_crtc iteration cursor |
730 | * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state |
731 | * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state |
732 | * @__i: int iteration cursor, for macro-internal use |
733 | * |
734 | * This iterates over all CRTCs in an atomic update, tracking both old and |
735 | * new state. This is useful in places where the state delta needs to be |
736 | * considered, for example in atomic check functions. |
737 | */ |
738 | #define for_each_oldnew_crtc_in_state(__state, crtc, old_crtc_state, new_crtc_state, __i) \ |
739 | for ((__i) = 0; \ |
740 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
741 | (__i)++) \ |
742 | for_each_if ((__state)->crtcs[__i].ptr && \ |
743 | ((crtc) = (__state)->crtcs[__i].ptr, \ |
744 | (old_crtc_state) = (__state)->crtcs[__i].old_state, \ |
745 | (new_crtc_state) = (__state)->crtcs[__i].new_state, 1)) |
746 | |
747 | /** |
748 | * for_each_old_crtc_in_state - iterate over all CRTCs in an atomic update |
749 | * @__state: &struct drm_atomic_state pointer |
750 | * @crtc: &struct drm_crtc iteration cursor |
751 | * @old_crtc_state: &struct drm_crtc_state iteration cursor for the old state |
752 | * @__i: int iteration cursor, for macro-internal use |
753 | * |
754 | * This iterates over all CRTCs in an atomic update, tracking only the old |
755 | * state. This is useful in disable functions, where we need the old state the |
756 | * hardware is still in. |
757 | */ |
758 | #define for_each_old_crtc_in_state(__state, crtc, old_crtc_state, __i) \ |
759 | for ((__i) = 0; \ |
760 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
761 | (__i)++) \ |
762 | for_each_if ((__state)->crtcs[__i].ptr && \ |
763 | ((crtc) = (__state)->crtcs[__i].ptr, \ |
764 | (old_crtc_state) = (__state)->crtcs[__i].old_state, 1)) |
765 | |
766 | /** |
767 | * for_each_new_crtc_in_state - iterate over all CRTCs in an atomic update |
768 | * @__state: &struct drm_atomic_state pointer |
769 | * @crtc: &struct drm_crtc iteration cursor |
770 | * @new_crtc_state: &struct drm_crtc_state iteration cursor for the new state |
771 | * @__i: int iteration cursor, for macro-internal use |
772 | * |
773 | * This iterates over all CRTCs in an atomic update, tracking only the new |
774 | * state. This is useful in enable functions, where we need the new state the |
775 | * hardware should be in when the atomic commit operation has completed. |
776 | */ |
777 | #define for_each_new_crtc_in_state(__state, crtc, new_crtc_state, __i) \ |
778 | for ((__i) = 0; \ |
779 | (__i) < (__state)->dev->mode_config.num_crtc; \ |
780 | (__i)++) \ |
781 | for_each_if ((__state)->crtcs[__i].ptr && \ |
782 | ((crtc) = (__state)->crtcs[__i].ptr, \ |
783 | (new_crtc_state) = (__state)->crtcs[__i].new_state, 1)) |
784 | |
785 | /** |
786 | * for_each_oldnew_plane_in_state - iterate over all planes in an atomic update |
787 | * @__state: &struct drm_atomic_state pointer |
788 | * @plane: &struct drm_plane iteration cursor |
789 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state |
790 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state |
791 | * @__i: int iteration cursor, for macro-internal use |
792 | * |
793 | * This iterates over all planes in an atomic update, tracking both old and |
794 | * new state. This is useful in places where the state delta needs to be |
795 | * considered, for example in atomic check functions. |
796 | */ |
797 | #define for_each_oldnew_plane_in_state(__state, plane, old_plane_state, new_plane_state, __i) \ |
798 | for ((__i) = 0; \ |
799 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
800 | (__i)++) \ |
801 | for_each_if ((__state)->planes[__i].ptr && \ |
802 | ((plane) = (__state)->planes[__i].ptr, \ |
803 | (old_plane_state) = (__state)->planes[__i].old_state,\ |
804 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) |
805 | |
806 | /** |
807 | * for_each_oldnew_plane_in_state_reverse - iterate over all planes in an atomic |
808 | * update in reverse order |
809 | * @__state: &struct drm_atomic_state pointer |
810 | * @plane: &struct drm_plane iteration cursor |
811 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state |
812 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state |
813 | * @__i: int iteration cursor, for macro-internal use |
814 | * |
815 | * This iterates over all planes in an atomic update in reverse order, |
816 | * tracking both old and new state. This is useful in places where the |
817 | * state delta needs to be considered, for example in atomic check functions. |
818 | */ |
819 | #define for_each_oldnew_plane_in_state_reverse(__state, plane, old_plane_state, new_plane_state, __i) \ |
820 | for ((__i) = ((__state)->dev->mode_config.num_total_plane - 1); \ |
821 | (__i) >= 0; \ |
822 | (__i)--) \ |
823 | for_each_if ((__state)->planes[__i].ptr && \ |
824 | ((plane) = (__state)->planes[__i].ptr, \ |
825 | (old_plane_state) = (__state)->planes[__i].old_state,\ |
826 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) |
827 | |
828 | /** |
829 | * for_each_old_plane_in_state - iterate over all planes in an atomic update |
830 | * @__state: &struct drm_atomic_state pointer |
831 | * @plane: &struct drm_plane iteration cursor |
832 | * @old_plane_state: &struct drm_plane_state iteration cursor for the old state |
833 | * @__i: int iteration cursor, for macro-internal use |
834 | * |
835 | * This iterates over all planes in an atomic update, tracking only the old |
836 | * state. This is useful in disable functions, where we need the old state the |
837 | * hardware is still in. |
838 | */ |
839 | #define for_each_old_plane_in_state(__state, plane, old_plane_state, __i) \ |
840 | for ((__i) = 0; \ |
841 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
842 | (__i)++) \ |
843 | for_each_if ((__state)->planes[__i].ptr && \ |
844 | ((plane) = (__state)->planes[__i].ptr, \ |
845 | (old_plane_state) = (__state)->planes[__i].old_state, 1)) |
846 | /** |
847 | * for_each_new_plane_in_state - iterate over all planes in an atomic update |
848 | * @__state: &struct drm_atomic_state pointer |
849 | * @plane: &struct drm_plane iteration cursor |
850 | * @new_plane_state: &struct drm_plane_state iteration cursor for the new state |
851 | * @__i: int iteration cursor, for macro-internal use |
852 | * |
853 | * This iterates over all planes in an atomic update, tracking only the new |
854 | * state. This is useful in enable functions, where we need the new state the |
855 | * hardware should be in when the atomic commit operation has completed. |
856 | */ |
857 | #define for_each_new_plane_in_state(__state, plane, new_plane_state, __i) \ |
858 | for ((__i) = 0; \ |
859 | (__i) < (__state)->dev->mode_config.num_total_plane; \ |
860 | (__i)++) \ |
861 | for_each_if ((__state)->planes[__i].ptr && \ |
862 | ((plane) = (__state)->planes[__i].ptr, \ |
863 | (new_plane_state) = (__state)->planes[__i].new_state, 1)) |
864 | |
865 | /** |
866 | * for_each_oldnew_private_obj_in_state - iterate over all private objects in an atomic update |
867 | * @__state: &struct drm_atomic_state pointer |
868 | * @obj: &struct drm_private_obj iteration cursor |
869 | * @old_obj_state: &struct drm_private_state iteration cursor for the old state |
870 | * @new_obj_state: &struct drm_private_state iteration cursor for the new state |
871 | * @__i: int iteration cursor, for macro-internal use |
872 | * |
873 | * This iterates over all private objects in an atomic update, tracking both |
874 | * old and new state. This is useful in places where the state delta needs |
875 | * to be considered, for example in atomic check functions. |
876 | */ |
877 | #define for_each_oldnew_private_obj_in_state(__state, obj, old_obj_state, new_obj_state, __i) \ |
878 | for ((__i) = 0; \ |
879 | (__i) < (__state)->num_private_objs && \ |
880 | ((obj) = (__state)->private_objs[__i].ptr, \ |
881 | (old_obj_state) = (__state)->private_objs[__i].old_state, \ |
882 | (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ |
883 | (__i)++) |
884 | |
885 | /** |
886 | * for_each_old_private_obj_in_state - iterate over all private objects in an atomic update |
887 | * @__state: &struct drm_atomic_state pointer |
888 | * @obj: &struct drm_private_obj iteration cursor |
889 | * @old_obj_state: &struct drm_private_state iteration cursor for the old state |
890 | * @__i: int iteration cursor, for macro-internal use |
891 | * |
892 | * This iterates over all private objects in an atomic update, tracking only |
893 | * the old state. This is useful in disable functions, where we need the old |
894 | * state the hardware is still in. |
895 | */ |
896 | #define for_each_old_private_obj_in_state(__state, obj, old_obj_state, __i) \ |
897 | for ((__i) = 0; \ |
898 | (__i) < (__state)->num_private_objs && \ |
899 | ((obj) = (__state)->private_objs[__i].ptr, \ |
900 | (old_obj_state) = (__state)->private_objs[__i].old_state, 1); \ |
901 | (__i)++) |
902 | |
903 | /** |
904 | * for_each_new_private_obj_in_state - iterate over all private objects in an atomic update |
905 | * @__state: &struct drm_atomic_state pointer |
906 | * @obj: &struct drm_private_obj iteration cursor |
907 | * @new_obj_state: &struct drm_private_state iteration cursor for the new state |
908 | * @__i: int iteration cursor, for macro-internal use |
909 | * |
910 | * This iterates over all private objects in an atomic update, tracking only |
911 | * the new state. This is useful in enable functions, where we need the new state the |
912 | * hardware should be in when the atomic commit operation has completed. |
913 | */ |
914 | #define for_each_new_private_obj_in_state(__state, obj, new_obj_state, __i) \ |
915 | for ((__i) = 0; \ |
916 | (__i) < (__state)->num_private_objs && \ |
917 | ((obj) = (__state)->private_objs[__i].ptr, \ |
918 | (new_obj_state) = (__state)->private_objs[__i].new_state, 1); \ |
919 | (__i)++) |
920 | |
921 | /** |
922 | * drm_atomic_crtc_needs_modeset - compute combined modeset need |
923 | * @state: &drm_crtc_state for the CRTC |
924 | * |
925 | * To give drivers flexibility &struct drm_crtc_state has 3 booleans to track |
926 | * whether the state CRTC changed enough to need a full modeset cycle: |
927 | * mode_changed, active_changed and connectors_changed. This helper simply |
928 | * combines these three to compute the overall need for a modeset for @state. |
929 | * |
930 | * The atomic helper code sets these booleans, but drivers can and should |
931 | * change them appropriately to accurately represent whether a modeset is |
932 | * really needed. In general, drivers should avoid full modesets whenever |
933 | * possible. |
934 | * |
935 | * For example if the CRTC mode has changed, and the hardware is able to enact |
936 | * the requested mode change without going through a full modeset, the driver |
937 | * should clear mode_changed in its &drm_mode_config_funcs.atomic_check |
938 | * implementation. |
939 | */ |
940 | static inline bool |
941 | drm_atomic_crtc_needs_modeset(const struct drm_crtc_state *state) |
942 | { |
943 | return state->mode_changed || state->active_changed || |
944 | state->connectors_changed; |
945 | } |
946 | |
947 | #endif /* DRM_ATOMIC_H_ */ |
948 | |