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