Line data Source code
1 : /*
2 : * Copyright (C) 2018 Intel Corp.
3 : *
4 : * Permission is hereby granted, free of charge, to any person obtaining a
5 : * copy of this software and associated documentation files (the "Software"),
6 : * to deal in the Software without restriction, including without limitation
7 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 : * and/or sell copies of the Software, and to permit persons to whom the
9 : * Software is furnished to do so, subject to the following conditions:
10 : *
11 : * The above copyright notice and this permission notice shall be included in
12 : * all copies or substantial portions of the Software.
13 : *
14 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 : * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 : * OTHER DEALINGS IN THE SOFTWARE.
21 : *
22 : * Authors:
23 : * Rob Clark <robdclark@gmail.com>
24 : * Daniel Vetter <daniel.vetter@ffwll.ch>
25 : */
26 :
27 : #include <drm/drm_atomic.h>
28 : #include <drm/drm_atomic_state_helper.h>
29 : #include <drm/drm_blend.h>
30 : #include <drm/drm_bridge.h>
31 : #include <drm/drm_connector.h>
32 : #include <drm/drm_crtc.h>
33 : #include <drm/drm_device.h>
34 : #include <drm/drm_framebuffer.h>
35 : #include <drm/drm_plane.h>
36 : #include <drm/drm_print.h>
37 : #include <drm/drm_vblank.h>
38 : #include <drm/drm_writeback.h>
39 :
40 : #include <linux/slab.h>
41 : #include <linux/dma-fence.h>
42 :
43 : /**
44 : * DOC: atomic state reset and initialization
45 : *
46 : * Both the drm core and the atomic helpers assume that there is always the full
47 : * and correct atomic software state for all connectors, CRTCs and planes
48 : * available. Which is a bit a problem on driver load and also after system
49 : * suspend. One way to solve this is to have a hardware state read-out
50 : * infrastructure which reconstructs the full software state (e.g. the i915
51 : * driver).
52 : *
53 : * The simpler solution is to just reset the software state to everything off,
54 : * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
55 : * the atomic helpers provide default reset implementations for all hooks.
56 : *
57 : * On the upside the precise state tracking of atomic simplifies system suspend
58 : * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
59 : * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
60 : * For other drivers the building blocks are split out, see the documentation
61 : * for these functions.
62 : */
63 :
64 : /**
65 : * __drm_atomic_helper_crtc_state_reset - reset the CRTC state
66 : * @crtc_state: atomic CRTC state, must not be NULL
67 : * @crtc: CRTC object, must not be NULL
68 : *
69 : * Initializes the newly allocated @crtc_state with default
70 : * values. This is useful for drivers that subclass the CRTC state.
71 : */
72 : void
73 0 : __drm_atomic_helper_crtc_state_reset(struct drm_crtc_state *crtc_state,
74 : struct drm_crtc *crtc)
75 : {
76 0 : crtc_state->crtc = crtc;
77 0 : }
78 : EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_reset);
79 :
80 : /**
81 : * __drm_atomic_helper_crtc_reset - reset state on CRTC
82 : * @crtc: drm CRTC
83 : * @crtc_state: CRTC state to assign
84 : *
85 : * Initializes the newly allocated @crtc_state and assigns it to
86 : * the &drm_crtc->state pointer of @crtc, usually required when
87 : * initializing the drivers or when called from the &drm_crtc_funcs.reset
88 : * hook.
89 : *
90 : * This is useful for drivers that subclass the CRTC state.
91 : */
92 : void
93 0 : __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
94 : struct drm_crtc_state *crtc_state)
95 : {
96 0 : if (crtc_state)
97 : __drm_atomic_helper_crtc_state_reset(crtc_state, crtc);
98 :
99 0 : if (drm_dev_has_vblank(crtc->dev))
100 0 : drm_crtc_vblank_reset(crtc);
101 :
102 0 : crtc->state = crtc_state;
103 0 : }
104 : EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
105 :
106 : /**
107 : * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
108 : * @crtc: drm CRTC
109 : *
110 : * Resets the atomic state for @crtc by freeing the state pointer (which might
111 : * be NULL, e.g. at driver load time) and allocating a new empty state object.
112 : */
113 0 : void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
114 : {
115 0 : struct drm_crtc_state *crtc_state =
116 : kzalloc(sizeof(*crtc->state), GFP_KERNEL);
117 :
118 0 : if (crtc->state)
119 0 : crtc->funcs->atomic_destroy_state(crtc, crtc->state);
120 :
121 0 : __drm_atomic_helper_crtc_reset(crtc, crtc_state);
122 0 : }
123 : EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
124 :
125 : /**
126 : * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
127 : * @crtc: CRTC object
128 : * @state: atomic CRTC state
129 : *
130 : * Copies atomic state from a CRTC's current state and resets inferred values.
131 : * This is useful for drivers that subclass the CRTC state.
132 : */
133 0 : void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
134 : struct drm_crtc_state *state)
135 : {
136 0 : memcpy(state, crtc->state, sizeof(*state));
137 :
138 0 : if (state->mode_blob)
139 0 : drm_property_blob_get(state->mode_blob);
140 0 : if (state->degamma_lut)
141 0 : drm_property_blob_get(state->degamma_lut);
142 0 : if (state->ctm)
143 0 : drm_property_blob_get(state->ctm);
144 0 : if (state->gamma_lut)
145 0 : drm_property_blob_get(state->gamma_lut);
146 0 : state->mode_changed = false;
147 0 : state->active_changed = false;
148 0 : state->planes_changed = false;
149 0 : state->connectors_changed = false;
150 0 : state->color_mgmt_changed = false;
151 0 : state->zpos_changed = false;
152 0 : state->commit = NULL;
153 0 : state->event = NULL;
154 0 : state->async_flip = false;
155 :
156 : /* Self refresh should be canceled when a new update is available */
157 0 : state->active = drm_atomic_crtc_effectively_active(state);
158 0 : state->self_refresh_active = false;
159 0 : }
160 : EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
161 :
162 : /**
163 : * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
164 : * @crtc: drm CRTC
165 : *
166 : * Default CRTC state duplicate hook for drivers which don't have their own
167 : * subclassed CRTC state structure.
168 : */
169 : struct drm_crtc_state *
170 0 : drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
171 : {
172 : struct drm_crtc_state *state;
173 :
174 0 : if (WARN_ON(!crtc->state))
175 : return NULL;
176 :
177 0 : state = kmalloc(sizeof(*state), GFP_KERNEL);
178 0 : if (state)
179 0 : __drm_atomic_helper_crtc_duplicate_state(crtc, state);
180 :
181 : return state;
182 : }
183 : EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
184 :
185 : /**
186 : * __drm_atomic_helper_crtc_destroy_state - release CRTC state
187 : * @state: CRTC state object to release
188 : *
189 : * Releases all resources stored in the CRTC state without actually freeing
190 : * the memory of the CRTC state. This is useful for drivers that subclass the
191 : * CRTC state.
192 : */
193 0 : void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
194 : {
195 0 : if (state->commit) {
196 : /*
197 : * In the event that a non-blocking commit returns
198 : * -ERESTARTSYS before the commit_tail work is queued, we will
199 : * have an extra reference to the commit object. Release it, if
200 : * the event has not been consumed by the worker.
201 : *
202 : * state->event may be freed, so we can't directly look at
203 : * state->event->base.completion.
204 : */
205 0 : if (state->event && state->commit->abort_completion)
206 0 : drm_crtc_commit_put(state->commit);
207 :
208 0 : kfree(state->commit->event);
209 0 : state->commit->event = NULL;
210 :
211 0 : drm_crtc_commit_put(state->commit);
212 : }
213 :
214 0 : drm_property_blob_put(state->mode_blob);
215 0 : drm_property_blob_put(state->degamma_lut);
216 0 : drm_property_blob_put(state->ctm);
217 0 : drm_property_blob_put(state->gamma_lut);
218 0 : }
219 : EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
220 :
221 : /**
222 : * drm_atomic_helper_crtc_destroy_state - default state destroy hook
223 : * @crtc: drm CRTC
224 : * @state: CRTC state object to release
225 : *
226 : * Default CRTC state destroy hook for drivers which don't have their own
227 : * subclassed CRTC state structure.
228 : */
229 0 : void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
230 : struct drm_crtc_state *state)
231 : {
232 0 : __drm_atomic_helper_crtc_destroy_state(state);
233 0 : kfree(state);
234 0 : }
235 : EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
236 :
237 : /**
238 : * __drm_atomic_helper_plane_state_reset - resets plane state to default values
239 : * @plane_state: atomic plane state, must not be NULL
240 : * @plane: plane object, must not be NULL
241 : *
242 : * Initializes the newly allocated @plane_state with default
243 : * values. This is useful for drivers that subclass the CRTC state.
244 : */
245 0 : void __drm_atomic_helper_plane_state_reset(struct drm_plane_state *plane_state,
246 : struct drm_plane *plane)
247 : {
248 : u64 val;
249 :
250 0 : plane_state->plane = plane;
251 0 : plane_state->rotation = DRM_MODE_ROTATE_0;
252 :
253 0 : plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
254 0 : plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
255 :
256 0 : if (plane->color_encoding_property) {
257 0 : if (!drm_object_property_get_default_value(&plane->base,
258 : plane->color_encoding_property,
259 : &val))
260 0 : plane_state->color_encoding = val;
261 : }
262 :
263 0 : if (plane->color_range_property) {
264 0 : if (!drm_object_property_get_default_value(&plane->base,
265 : plane->color_range_property,
266 : &val))
267 0 : plane_state->color_range = val;
268 : }
269 :
270 0 : if (plane->zpos_property) {
271 0 : if (!drm_object_property_get_default_value(&plane->base,
272 : plane->zpos_property,
273 : &val)) {
274 0 : plane_state->zpos = val;
275 0 : plane_state->normalized_zpos = val;
276 : }
277 : }
278 0 : }
279 : EXPORT_SYMBOL(__drm_atomic_helper_plane_state_reset);
280 :
281 : /**
282 : * __drm_atomic_helper_plane_reset - reset state on plane
283 : * @plane: drm plane
284 : * @plane_state: plane state to assign
285 : *
286 : * Initializes the newly allocated @plane_state and assigns it to
287 : * the &drm_crtc->state pointer of @plane, usually required when
288 : * initializing the drivers or when called from the &drm_plane_funcs.reset
289 : * hook.
290 : *
291 : * This is useful for drivers that subclass the plane state.
292 : */
293 0 : void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
294 : struct drm_plane_state *plane_state)
295 : {
296 0 : if (plane_state)
297 0 : __drm_atomic_helper_plane_state_reset(plane_state, plane);
298 :
299 0 : plane->state = plane_state;
300 0 : }
301 : EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
302 :
303 : /**
304 : * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
305 : * @plane: drm plane
306 : *
307 : * Resets the atomic state for @plane by freeing the state pointer (which might
308 : * be NULL, e.g. at driver load time) and allocating a new empty state object.
309 : */
310 0 : void drm_atomic_helper_plane_reset(struct drm_plane *plane)
311 : {
312 0 : if (plane->state)
313 0 : __drm_atomic_helper_plane_destroy_state(plane->state);
314 :
315 0 : kfree(plane->state);
316 0 : plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
317 0 : if (plane->state)
318 0 : __drm_atomic_helper_plane_reset(plane, plane->state);
319 0 : }
320 : EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
321 :
322 : /**
323 : * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
324 : * @plane: plane object
325 : * @state: atomic plane state
326 : *
327 : * Copies atomic state from a plane's current state. This is useful for
328 : * drivers that subclass the plane state.
329 : */
330 0 : void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
331 : struct drm_plane_state *state)
332 : {
333 0 : memcpy(state, plane->state, sizeof(*state));
334 :
335 0 : if (state->fb)
336 0 : drm_framebuffer_get(state->fb);
337 :
338 0 : state->fence = NULL;
339 0 : state->commit = NULL;
340 0 : state->fb_damage_clips = NULL;
341 0 : }
342 : EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
343 :
344 : /**
345 : * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
346 : * @plane: drm plane
347 : *
348 : * Default plane state duplicate hook for drivers which don't have their own
349 : * subclassed plane state structure.
350 : */
351 : struct drm_plane_state *
352 0 : drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
353 : {
354 : struct drm_plane_state *state;
355 :
356 0 : if (WARN_ON(!plane->state))
357 : return NULL;
358 :
359 0 : state = kmalloc(sizeof(*state), GFP_KERNEL);
360 0 : if (state)
361 0 : __drm_atomic_helper_plane_duplicate_state(plane, state);
362 :
363 : return state;
364 : }
365 : EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
366 :
367 : /**
368 : * __drm_atomic_helper_plane_destroy_state - release plane state
369 : * @state: plane state object to release
370 : *
371 : * Releases all resources stored in the plane state without actually freeing
372 : * the memory of the plane state. This is useful for drivers that subclass the
373 : * plane state.
374 : */
375 0 : void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
376 : {
377 0 : if (state->fb)
378 0 : drm_framebuffer_put(state->fb);
379 :
380 0 : if (state->fence)
381 0 : dma_fence_put(state->fence);
382 :
383 0 : if (state->commit)
384 0 : drm_crtc_commit_put(state->commit);
385 :
386 0 : drm_property_blob_put(state->fb_damage_clips);
387 0 : }
388 : EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
389 :
390 : /**
391 : * drm_atomic_helper_plane_destroy_state - default state destroy hook
392 : * @plane: drm plane
393 : * @state: plane state object to release
394 : *
395 : * Default plane state destroy hook for drivers which don't have their own
396 : * subclassed plane state structure.
397 : */
398 0 : void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
399 : struct drm_plane_state *state)
400 : {
401 0 : __drm_atomic_helper_plane_destroy_state(state);
402 0 : kfree(state);
403 0 : }
404 : EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
405 :
406 : /**
407 : * __drm_atomic_helper_connector_state_reset - reset the connector state
408 : * @conn_state: atomic connector state, must not be NULL
409 : * @connector: connectotr object, must not be NULL
410 : *
411 : * Initializes the newly allocated @conn_state with default
412 : * values. This is useful for drivers that subclass the connector state.
413 : */
414 : void
415 0 : __drm_atomic_helper_connector_state_reset(struct drm_connector_state *conn_state,
416 : struct drm_connector *connector)
417 : {
418 0 : conn_state->connector = connector;
419 0 : }
420 : EXPORT_SYMBOL(__drm_atomic_helper_connector_state_reset);
421 :
422 : /**
423 : * __drm_atomic_helper_connector_reset - reset state on connector
424 : * @connector: drm connector
425 : * @conn_state: connector state to assign
426 : *
427 : * Initializes the newly allocated @conn_state and assigns it to
428 : * the &drm_connector->state pointer of @connector, usually required when
429 : * initializing the drivers or when called from the &drm_connector_funcs.reset
430 : * hook.
431 : *
432 : * This is useful for drivers that subclass the connector state.
433 : */
434 : void
435 0 : __drm_atomic_helper_connector_reset(struct drm_connector *connector,
436 : struct drm_connector_state *conn_state)
437 : {
438 0 : if (conn_state)
439 : __drm_atomic_helper_connector_state_reset(conn_state, connector);
440 :
441 0 : connector->state = conn_state;
442 0 : }
443 : EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
444 :
445 : /**
446 : * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
447 : * @connector: drm connector
448 : *
449 : * Resets the atomic state for @connector by freeing the state pointer (which
450 : * might be NULL, e.g. at driver load time) and allocating a new empty state
451 : * object.
452 : */
453 0 : void drm_atomic_helper_connector_reset(struct drm_connector *connector)
454 : {
455 0 : struct drm_connector_state *conn_state =
456 : kzalloc(sizeof(*conn_state), GFP_KERNEL);
457 :
458 0 : if (connector->state)
459 0 : __drm_atomic_helper_connector_destroy_state(connector->state);
460 :
461 0 : kfree(connector->state);
462 0 : __drm_atomic_helper_connector_reset(connector, conn_state);
463 0 : }
464 : EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
465 :
466 : /**
467 : * drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
468 : * @connector: DRM connector
469 : *
470 : * Resets the TV-related properties attached to a connector.
471 : */
472 0 : void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)
473 : {
474 0 : struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
475 0 : struct drm_connector_state *state = connector->state;
476 :
477 0 : state->tv.margins.left = cmdline->tv_margins.left;
478 0 : state->tv.margins.right = cmdline->tv_margins.right;
479 0 : state->tv.margins.top = cmdline->tv_margins.top;
480 0 : state->tv.margins.bottom = cmdline->tv_margins.bottom;
481 0 : }
482 : EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
483 :
484 : /**
485 : * drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
486 : * @connector: DRM connector
487 : *
488 : * Resets the analog TV properties attached to a connector
489 : */
490 0 : void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
491 : {
492 0 : struct drm_device *dev = connector->dev;
493 0 : struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
494 0 : struct drm_connector_state *state = connector->state;
495 : struct drm_property *prop;
496 : uint64_t val;
497 :
498 0 : prop = dev->mode_config.tv_mode_property;
499 0 : if (prop)
500 0 : if (!drm_object_property_get_default_value(&connector->base,
501 : prop, &val))
502 0 : state->tv.mode = val;
503 :
504 0 : if (cmdline->tv_mode_specified)
505 0 : state->tv.mode = cmdline->tv_mode;
506 :
507 0 : prop = dev->mode_config.tv_select_subconnector_property;
508 0 : if (prop)
509 0 : if (!drm_object_property_get_default_value(&connector->base,
510 : prop, &val))
511 0 : state->tv.select_subconnector = val;
512 :
513 0 : prop = dev->mode_config.tv_subconnector_property;
514 0 : if (prop)
515 0 : if (!drm_object_property_get_default_value(&connector->base,
516 : prop, &val))
517 0 : state->tv.subconnector = val;
518 :
519 0 : prop = dev->mode_config.tv_brightness_property;
520 0 : if (prop)
521 0 : if (!drm_object_property_get_default_value(&connector->base,
522 : prop, &val))
523 0 : state->tv.brightness = val;
524 :
525 0 : prop = dev->mode_config.tv_contrast_property;
526 0 : if (prop)
527 0 : if (!drm_object_property_get_default_value(&connector->base,
528 : prop, &val))
529 0 : state->tv.contrast = val;
530 :
531 0 : prop = dev->mode_config.tv_flicker_reduction_property;
532 0 : if (prop)
533 0 : if (!drm_object_property_get_default_value(&connector->base,
534 : prop, &val))
535 0 : state->tv.flicker_reduction = val;
536 :
537 0 : prop = dev->mode_config.tv_overscan_property;
538 0 : if (prop)
539 0 : if (!drm_object_property_get_default_value(&connector->base,
540 : prop, &val))
541 0 : state->tv.overscan = val;
542 :
543 0 : prop = dev->mode_config.tv_saturation_property;
544 0 : if (prop)
545 0 : if (!drm_object_property_get_default_value(&connector->base,
546 : prop, &val))
547 0 : state->tv.saturation = val;
548 :
549 0 : prop = dev->mode_config.tv_hue_property;
550 0 : if (prop)
551 0 : if (!drm_object_property_get_default_value(&connector->base,
552 : prop, &val))
553 0 : state->tv.hue = val;
554 :
555 0 : drm_atomic_helper_connector_tv_margins_reset(connector);
556 0 : }
557 : EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
558 :
559 : /**
560 : * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
561 : * @connector: DRM Connector
562 : * @state: the DRM State object
563 : *
564 : * Checks the state object to see if the requested state is valid for an
565 : * analog TV connector.
566 : *
567 : * Return:
568 : * %0 for success, a negative error code on error.
569 : */
570 0 : int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
571 : struct drm_atomic_state *state)
572 : {
573 0 : struct drm_connector_state *old_conn_state =
574 : drm_atomic_get_old_connector_state(state, connector);
575 0 : struct drm_connector_state *new_conn_state =
576 : drm_atomic_get_new_connector_state(state, connector);
577 : struct drm_crtc_state *crtc_state;
578 : struct drm_crtc *crtc;
579 :
580 0 : crtc = new_conn_state->crtc;
581 0 : if (!crtc)
582 : return 0;
583 :
584 0 : crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
585 0 : if (!crtc_state)
586 : return -EINVAL;
587 :
588 0 : if (old_conn_state->tv.mode != new_conn_state->tv.mode)
589 0 : crtc_state->mode_changed = true;
590 :
591 0 : if (old_conn_state->tv.margins.left != new_conn_state->tv.margins.left ||
592 0 : old_conn_state->tv.margins.right != new_conn_state->tv.margins.right ||
593 0 : old_conn_state->tv.margins.top != new_conn_state->tv.margins.top ||
594 0 : old_conn_state->tv.margins.bottom != new_conn_state->tv.margins.bottom ||
595 0 : old_conn_state->tv.mode != new_conn_state->tv.mode ||
596 0 : old_conn_state->tv.brightness != new_conn_state->tv.brightness ||
597 : old_conn_state->tv.contrast != new_conn_state->tv.contrast ||
598 0 : old_conn_state->tv.flicker_reduction != new_conn_state->tv.flicker_reduction ||
599 : old_conn_state->tv.overscan != new_conn_state->tv.overscan ||
600 0 : old_conn_state->tv.saturation != new_conn_state->tv.saturation ||
601 : old_conn_state->tv.hue != new_conn_state->tv.hue)
602 0 : crtc_state->connectors_changed = true;
603 :
604 : return 0;
605 : }
606 : EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
607 :
608 : /**
609 : * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
610 : * @connector: connector object
611 : * @state: atomic connector state
612 : *
613 : * Copies atomic state from a connector's current state. This is useful for
614 : * drivers that subclass the connector state.
615 : */
616 : void
617 0 : __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
618 : struct drm_connector_state *state)
619 : {
620 0 : memcpy(state, connector->state, sizeof(*state));
621 0 : if (state->crtc)
622 : drm_connector_get(connector);
623 0 : state->commit = NULL;
624 :
625 0 : if (state->hdr_output_metadata)
626 0 : drm_property_blob_get(state->hdr_output_metadata);
627 :
628 : /* Don't copy over a writeback job, they are used only once */
629 0 : state->writeback_job = NULL;
630 0 : }
631 : EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
632 :
633 : /**
634 : * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
635 : * @connector: drm connector
636 : *
637 : * Default connector state duplicate hook for drivers which don't have their own
638 : * subclassed connector state structure.
639 : */
640 : struct drm_connector_state *
641 0 : drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
642 : {
643 : struct drm_connector_state *state;
644 :
645 0 : if (WARN_ON(!connector->state))
646 : return NULL;
647 :
648 0 : state = kmalloc(sizeof(*state), GFP_KERNEL);
649 0 : if (state)
650 0 : __drm_atomic_helper_connector_duplicate_state(connector, state);
651 :
652 : return state;
653 : }
654 : EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
655 :
656 : /**
657 : * __drm_atomic_helper_connector_destroy_state - release connector state
658 : * @state: connector state object to release
659 : *
660 : * Releases all resources stored in the connector state without actually
661 : * freeing the memory of the connector state. This is useful for drivers that
662 : * subclass the connector state.
663 : */
664 : void
665 0 : __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
666 : {
667 0 : if (state->crtc)
668 0 : drm_connector_put(state->connector);
669 :
670 0 : if (state->commit)
671 0 : drm_crtc_commit_put(state->commit);
672 :
673 0 : if (state->writeback_job)
674 0 : drm_writeback_cleanup_job(state->writeback_job);
675 :
676 0 : drm_property_blob_put(state->hdr_output_metadata);
677 0 : }
678 : EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
679 :
680 : /**
681 : * drm_atomic_helper_connector_destroy_state - default state destroy hook
682 : * @connector: drm connector
683 : * @state: connector state object to release
684 : *
685 : * Default connector state destroy hook for drivers which don't have their own
686 : * subclassed connector state structure.
687 : */
688 0 : void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
689 : struct drm_connector_state *state)
690 : {
691 0 : __drm_atomic_helper_connector_destroy_state(state);
692 0 : kfree(state);
693 0 : }
694 : EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
695 :
696 : /**
697 : * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
698 : * @obj: CRTC object
699 : * @state: new private object state
700 : *
701 : * Copies atomic state from a private objects's current state and resets inferred values.
702 : * This is useful for drivers that subclass the private state.
703 : */
704 0 : void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
705 : struct drm_private_state *state)
706 : {
707 0 : memcpy(state, obj->state, sizeof(*state));
708 0 : }
709 : EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
710 :
711 : /**
712 : * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state
713 : * @bridge: bridge object
714 : * @state: atomic bridge state
715 : *
716 : * Copies atomic state from a bridge's current state and resets inferred values.
717 : * This is useful for drivers that subclass the bridge state.
718 : */
719 0 : void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
720 : struct drm_bridge_state *state)
721 : {
722 0 : __drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
723 : &state->base);
724 0 : state->bridge = bridge;
725 0 : }
726 : EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
727 :
728 : /**
729 : * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object
730 : * @bridge: bridge object
731 : *
732 : * Allocates a new bridge state and initializes it with the current bridge
733 : * state values. This helper is meant to be used as a bridge
734 : * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't
735 : * subclass the bridge state.
736 : */
737 : struct drm_bridge_state *
738 0 : drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
739 : {
740 : struct drm_bridge_state *new;
741 :
742 0 : if (WARN_ON(!bridge->base.state))
743 : return NULL;
744 :
745 0 : new = kzalloc(sizeof(*new), GFP_KERNEL);
746 0 : if (new)
747 : __drm_atomic_helper_bridge_duplicate_state(bridge, new);
748 :
749 : return new;
750 : }
751 : EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
752 :
753 : /**
754 : * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object
755 : * @bridge: the bridge this state refers to
756 : * @state: bridge state to destroy
757 : *
758 : * Destroys a bridge state previously created by
759 : * &drm_atomic_helper_bridge_reset() or
760 : * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be
761 : * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges
762 : * that don't subclass the bridge state.
763 : */
764 0 : void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
765 : struct drm_bridge_state *state)
766 : {
767 0 : kfree(state);
768 0 : }
769 : EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
770 :
771 : /**
772 : * __drm_atomic_helper_bridge_reset() - Initialize a bridge state to its
773 : * default
774 : * @bridge: the bridge this state refers to
775 : * @state: bridge state to initialize
776 : *
777 : * Initializes the bridge state to default values. This is meant to be called
778 : * by the bridge &drm_bridge_funcs.atomic_reset hook for bridges that subclass
779 : * the bridge state.
780 : */
781 0 : void __drm_atomic_helper_bridge_reset(struct drm_bridge *bridge,
782 : struct drm_bridge_state *state)
783 : {
784 0 : memset(state, 0, sizeof(*state));
785 0 : state->bridge = bridge;
786 0 : }
787 : EXPORT_SYMBOL(__drm_atomic_helper_bridge_reset);
788 :
789 : /**
790 : * drm_atomic_helper_bridge_reset() - Allocate and initialize a bridge state
791 : * to its default
792 : * @bridge: the bridge this state refers to
793 : *
794 : * Allocates the bridge state and initializes it to default values. This helper
795 : * is meant to be used as a bridge &drm_bridge_funcs.atomic_reset hook for
796 : * bridges that don't subclass the bridge state.
797 : */
798 : struct drm_bridge_state *
799 0 : drm_atomic_helper_bridge_reset(struct drm_bridge *bridge)
800 : {
801 : struct drm_bridge_state *bridge_state;
802 :
803 0 : bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL);
804 0 : if (!bridge_state)
805 : return ERR_PTR(-ENOMEM);
806 :
807 0 : __drm_atomic_helper_bridge_reset(bridge, bridge_state);
808 0 : return bridge_state;
809 : }
810 : EXPORT_SYMBOL(drm_atomic_helper_bridge_reset);
|