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/export.h>
41 #include <linux/slab.h>
42 #include <linux/dma-fence.h>
43
44 /**
45 * DOC: atomic state reset and initialization
46 *
47 * Both the drm core and the atomic helpers assume that there is always the full
48 * and correct atomic software state for all connectors, CRTCs and planes
49 * available. Which is a bit a problem on driver load and also after system
50 * suspend. One way to solve this is to have a hardware state read-out
51 * infrastructure which reconstructs the full software state (e.g. the i915
52 * driver).
53 *
54 * The simpler solution is to just reset the software state to everything off,
55 * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
56 * the atomic helpers provide default reset implementations for all hooks.
57 *
58 * On the upside the precise state tracking of atomic simplifies system suspend
59 * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
60 * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
61 * For other drivers the building blocks are split out, see the documentation
62 * for these functions.
63 */
64
65 /**
66 * __drm_atomic_helper_crtc_state_init - Initialize the CRTC state
67 * @crtc_state: atomic CRTC state, must not be NULL
68 * @crtc: CRTC object, must not be NULL
69 *
70 * Initializes the newly allocated @crtc_state with default
71 * values. This is useful for drivers that subclass the CRTC state.
72 */
73 void
__drm_atomic_helper_crtc_state_init(struct drm_crtc_state * crtc_state,struct drm_crtc * crtc)74 __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *crtc_state,
75 struct drm_crtc *crtc)
76 {
77 crtc_state->crtc = crtc;
78 crtc_state->background_color = DRM_ARGB64_PREP(0xffff, 0, 0, 0);
79 }
80 EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_init);
81
82 /**
83 * __drm_atomic_helper_crtc_reset - reset state on CRTC
84 * @crtc: drm CRTC
85 * @crtc_state: CRTC state to assign
86 *
87 * Initializes the newly allocated @crtc_state and assigns it to
88 * the &drm_crtc->state pointer of @crtc, usually required when
89 * initializing the drivers or when called from the &drm_crtc_funcs.reset
90 * hook.
91 *
92 * This is useful for drivers that subclass the CRTC state.
93 */
94 void
__drm_atomic_helper_crtc_reset(struct drm_crtc * crtc,struct drm_crtc_state * crtc_state)95 __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
96 struct drm_crtc_state *crtc_state)
97 {
98 if (crtc_state)
99 __drm_atomic_helper_crtc_state_init(crtc_state, crtc);
100
101 if (drm_dev_has_vblank(crtc->dev))
102 drm_crtc_vblank_reset(crtc);
103
104 crtc->state = crtc_state;
105 }
106 EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
107
108 /**
109 * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
110 * @crtc: drm CRTC
111 *
112 * Resets the atomic state for @crtc by freeing the state pointer (which might
113 * be NULL, e.g. at driver load time) and allocating a new empty state object.
114 */
drm_atomic_helper_crtc_reset(struct drm_crtc * crtc)115 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
116 {
117 struct drm_crtc_state *crtc_state =
118 kzalloc_obj(*crtc->state);
119
120 if (crtc->state)
121 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
122
123 __drm_atomic_helper_crtc_reset(crtc, crtc_state);
124 }
125 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
126
127 /**
128 * drm_atomic_helper_crtc_create_state - default &drm_crtc_funcs.atomic_create_state hook for crtcs
129 * @crtc: crtc object
130 *
131 * Allocates and initializes pristine @drm_crtc_state.
132 *
133 * This is useful for drivers that don't subclass @drm_crtc_state.
134 *
135 * RETURNS:
136 * Pointer to new crtc state, or ERR_PTR on failure.
137 */
drm_atomic_helper_crtc_create_state(struct drm_crtc * crtc)138 struct drm_crtc_state *drm_atomic_helper_crtc_create_state(struct drm_crtc *crtc)
139 {
140 struct drm_crtc_state *state;
141
142 state = kzalloc_obj(*state);
143 if (!state)
144 return ERR_PTR(-ENOMEM);
145
146 __drm_atomic_helper_crtc_state_init(state, crtc);
147
148 return state;
149 }
150 EXPORT_SYMBOL(drm_atomic_helper_crtc_create_state);
151
152 /**
153 * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
154 * @crtc: CRTC object
155 * @state: atomic CRTC state
156 *
157 * Copies atomic state from a CRTC's current state and resets inferred values.
158 * This is useful for drivers that subclass the CRTC state.
159 */
__drm_atomic_helper_crtc_duplicate_state(struct drm_crtc * crtc,struct drm_crtc_state * state)160 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
161 struct drm_crtc_state *state)
162 {
163 memcpy(state, crtc->state, sizeof(*state));
164
165 if (state->mode_blob)
166 drm_property_blob_get(state->mode_blob);
167 if (state->degamma_lut)
168 drm_property_blob_get(state->degamma_lut);
169 if (state->ctm)
170 drm_property_blob_get(state->ctm);
171 if (state->gamma_lut)
172 drm_property_blob_get(state->gamma_lut);
173 state->mode_changed = false;
174 state->active_changed = false;
175 state->planes_changed = false;
176 state->connectors_changed = false;
177 state->color_mgmt_changed = false;
178 state->zpos_changed = false;
179 state->commit = NULL;
180 state->event = NULL;
181 state->async_flip = false;
182
183 /* Self refresh should be canceled when a new update is available */
184 state->active = drm_atomic_crtc_effectively_active(state);
185 state->self_refresh_active = false;
186 }
187 EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
188
189 /**
190 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
191 * @crtc: drm CRTC
192 *
193 * Default CRTC state duplicate hook for drivers which don't have their own
194 * subclassed CRTC state structure.
195 */
196 struct drm_crtc_state *
drm_atomic_helper_crtc_duplicate_state(struct drm_crtc * crtc)197 drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
198 {
199 struct drm_crtc_state *state;
200
201 if (WARN_ON(!crtc->state))
202 return NULL;
203
204 state = kmalloc_obj(*state);
205 if (state)
206 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
207
208 return state;
209 }
210 EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
211
212 /**
213 * __drm_atomic_helper_crtc_destroy_state - release CRTC state
214 * @state: CRTC state object to release
215 *
216 * Releases all resources stored in the CRTC state without actually freeing
217 * the memory of the CRTC state. This is useful for drivers that subclass the
218 * CRTC state.
219 */
__drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state * state)220 void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
221 {
222 if (state->commit) {
223 /*
224 * In the event that a non-blocking commit returns
225 * -ERESTARTSYS before the commit_tail work is queued, we will
226 * have an extra reference to the commit object. Release it, if
227 * the event has not been consumed by the worker.
228 *
229 * state->event may be freed, so we can't directly look at
230 * state->event->base.completion.
231 */
232 if (state->event && state->commit->abort_completion)
233 drm_crtc_commit_put(state->commit);
234
235 kfree(state->commit->event);
236 state->commit->event = NULL;
237
238 drm_crtc_commit_put(state->commit);
239 }
240
241 drm_property_blob_put(state->mode_blob);
242 drm_property_blob_put(state->degamma_lut);
243 drm_property_blob_put(state->ctm);
244 drm_property_blob_put(state->gamma_lut);
245 }
246 EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
247
248 /**
249 * drm_atomic_helper_crtc_destroy_state - default state destroy hook
250 * @crtc: drm CRTC
251 * @state: CRTC state object to release
252 *
253 * Default CRTC state destroy hook for drivers which don't have their own
254 * subclassed CRTC state structure.
255 */
drm_atomic_helper_crtc_destroy_state(struct drm_crtc * crtc,struct drm_crtc_state * state)256 void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
257 struct drm_crtc_state *state)
258 {
259 __drm_atomic_helper_crtc_destroy_state(state);
260 kfree(state);
261 }
262 EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
263
264 /**
265 * __drm_atomic_helper_plane_state_init - Initialize the plane state
266 * @plane_state: atomic plane state, must not be NULL
267 * @plane: plane object, must not be NULL
268 *
269 * Initializes the newly allocated @plane_state with default
270 * values. This is useful for drivers that subclass the plane state.
271 */
__drm_atomic_helper_plane_state_init(struct drm_plane_state * plane_state,struct drm_plane * plane)272 void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state,
273 struct drm_plane *plane)
274 {
275 u64 val;
276
277 plane_state->plane = plane;
278 plane_state->rotation = DRM_MODE_ROTATE_0;
279
280 plane_state->alpha = DRM_BLEND_ALPHA_OPAQUE;
281
282 plane_state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
283 if (plane->blend_mode_property) {
284 if (!drm_object_property_get_default_value(&plane->base,
285 plane->blend_mode_property,
286 &val))
287 plane_state->pixel_blend_mode = val;
288 }
289
290 if (plane->color_encoding_property) {
291 if (!drm_object_property_get_default_value(&plane->base,
292 plane->color_encoding_property,
293 &val))
294 plane_state->color_encoding = val;
295 }
296
297 if (plane->color_range_property) {
298 if (!drm_object_property_get_default_value(&plane->base,
299 plane->color_range_property,
300 &val))
301 plane_state->color_range = val;
302 }
303
304 if (plane->color_pipeline_property) {
305 /* default is always NULL, i.e., bypass */
306 plane_state->color_pipeline = NULL;
307 }
308
309 if (plane->zpos_property) {
310 if (!drm_object_property_get_default_value(&plane->base,
311 plane->zpos_property,
312 &val)) {
313 plane_state->zpos = val;
314 plane_state->normalized_zpos = val;
315 }
316 }
317
318 if (plane->hotspot_x_property) {
319 if (!drm_object_property_get_default_value(&plane->base,
320 plane->hotspot_x_property,
321 &val))
322 plane_state->hotspot_x = val;
323 }
324
325 if (plane->hotspot_y_property) {
326 if (!drm_object_property_get_default_value(&plane->base,
327 plane->hotspot_y_property,
328 &val))
329 plane_state->hotspot_y = val;
330 }
331 }
332 EXPORT_SYMBOL(__drm_atomic_helper_plane_state_init);
333
334 /**
335 * __drm_atomic_helper_plane_reset - reset state on plane
336 * @plane: drm plane
337 * @plane_state: plane state to assign
338 *
339 * Initializes the newly allocated @plane_state and assigns it to
340 * the &drm_plane->state pointer of @plane, usually required when
341 * initializing the drivers or when called from the &drm_plane_funcs.reset
342 * hook.
343 *
344 * This is useful for drivers that subclass the plane state.
345 */
__drm_atomic_helper_plane_reset(struct drm_plane * plane,struct drm_plane_state * plane_state)346 void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
347 struct drm_plane_state *plane_state)
348 {
349 if (plane_state)
350 __drm_atomic_helper_plane_state_init(plane_state, plane);
351
352 plane->state = plane_state;
353 }
354 EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
355
356 /**
357 * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
358 * @plane: drm plane
359 *
360 * Resets the atomic state for @plane by freeing the state pointer (which might
361 * be NULL, e.g. at driver load time) and allocating a new empty state object.
362 */
drm_atomic_helper_plane_reset(struct drm_plane * plane)363 void drm_atomic_helper_plane_reset(struct drm_plane *plane)
364 {
365 if (plane->state)
366 __drm_atomic_helper_plane_destroy_state(plane->state);
367
368 kfree(plane->state);
369 plane->state = kzalloc_obj(*plane->state);
370 if (plane->state)
371 __drm_atomic_helper_plane_reset(plane, plane->state);
372 }
373 EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
374
375 /**
376 * drm_atomic_helper_plane_create_state - default &drm_plane_funcs.atomic_create_state hook for planes
377 * @plane: plane object
378 *
379 * Allocates and initializes pristine @drm_plane_state.
380 *
381 * This is useful for drivers that don't subclass @drm_plane_state.
382 *
383 * RETURNS:
384 * Pointer to new plane state, or ERR_PTR on failure.
385 */
drm_atomic_helper_plane_create_state(struct drm_plane * plane)386 struct drm_plane_state *drm_atomic_helper_plane_create_state(struct drm_plane *plane)
387 {
388 struct drm_plane_state *state;
389
390 state = kzalloc_obj(*state);
391 if (!state)
392 return ERR_PTR(-ENOMEM);
393
394 __drm_atomic_helper_plane_state_init(state, plane);
395
396 return state;
397 }
398 EXPORT_SYMBOL(drm_atomic_helper_plane_create_state);
399
400 /**
401 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
402 * @plane: plane object
403 * @state: atomic plane state
404 *
405 * Copies atomic state from a plane's current state. This is useful for
406 * drivers that subclass the plane state.
407 */
__drm_atomic_helper_plane_duplicate_state(struct drm_plane * plane,struct drm_plane_state * state)408 void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
409 struct drm_plane_state *state)
410 {
411 memcpy(state, plane->state, sizeof(*state));
412
413 if (state->fb)
414 drm_framebuffer_get(state->fb);
415
416 state->fence = NULL;
417 state->commit = NULL;
418 state->fb_damage_clips = NULL;
419 state->color_mgmt_changed = false;
420 }
421 EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
422
423 /**
424 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
425 * @plane: drm plane
426 *
427 * Default plane state duplicate hook for drivers which don't have their own
428 * subclassed plane state structure.
429 */
430 struct drm_plane_state *
drm_atomic_helper_plane_duplicate_state(struct drm_plane * plane)431 drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
432 {
433 struct drm_plane_state *state;
434
435 if (WARN_ON(!plane->state))
436 return NULL;
437
438 state = kmalloc_obj(*state);
439 if (state)
440 __drm_atomic_helper_plane_duplicate_state(plane, state);
441
442 return state;
443 }
444 EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
445
446 /**
447 * __drm_atomic_helper_plane_destroy_state - release plane state
448 * @state: plane state object to release
449 *
450 * Releases all resources stored in the plane state without actually freeing
451 * the memory of the plane state. This is useful for drivers that subclass the
452 * plane state.
453 */
__drm_atomic_helper_plane_destroy_state(struct drm_plane_state * state)454 void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
455 {
456 if (state->fb)
457 drm_framebuffer_put(state->fb);
458
459 if (state->fence)
460 dma_fence_put(state->fence);
461
462 if (state->commit)
463 drm_crtc_commit_put(state->commit);
464
465 drm_property_blob_put(state->fb_damage_clips);
466 }
467 EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
468
469 /**
470 * drm_atomic_helper_plane_destroy_state - default state destroy hook
471 * @plane: drm plane
472 * @state: plane state object to release
473 *
474 * Default plane state destroy hook for drivers which don't have their own
475 * subclassed plane state structure.
476 */
drm_atomic_helper_plane_destroy_state(struct drm_plane * plane,struct drm_plane_state * state)477 void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
478 struct drm_plane_state *state)
479 {
480 __drm_atomic_helper_plane_destroy_state(state);
481 kfree(state);
482 }
483 EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
484
485 /**
486 * __drm_atomic_helper_connector_state_init - Initialize the connector state
487 * @conn_state: atomic connector state, must not be NULL
488 * @connector: connector object, must not be NULL
489 *
490 * Initializes the newly allocated @conn_state with default
491 * values. This is useful for drivers that subclass the connector state.
492 */
493 void
__drm_atomic_helper_connector_state_init(struct drm_connector_state * conn_state,struct drm_connector * connector)494 __drm_atomic_helper_connector_state_init(struct drm_connector_state *conn_state,
495 struct drm_connector *connector)
496 {
497 conn_state->connector = connector;
498 }
499 EXPORT_SYMBOL(__drm_atomic_helper_connector_state_init);
500
501 /**
502 * __drm_atomic_helper_connector_reset - reset state on connector
503 * @connector: drm connector
504 * @conn_state: connector state to assign
505 *
506 * Initializes the newly allocated @conn_state and assigns it to
507 * the &drm_connector->state pointer of @connector, usually required when
508 * initializing the drivers or when called from the &drm_connector_funcs.reset
509 * hook.
510 *
511 * This is useful for drivers that subclass the connector state.
512 */
513 void
__drm_atomic_helper_connector_reset(struct drm_connector * connector,struct drm_connector_state * conn_state)514 __drm_atomic_helper_connector_reset(struct drm_connector *connector,
515 struct drm_connector_state *conn_state)
516 {
517 if (conn_state)
518 __drm_atomic_helper_connector_state_init(conn_state, connector);
519
520 connector->state = conn_state;
521 }
522 EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
523
524 /**
525 * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
526 * @connector: drm connector
527 *
528 * Resets the atomic state for @connector by freeing the state pointer (which
529 * might be NULL, e.g. at driver load time) and allocating a new empty state
530 * object.
531 */
drm_atomic_helper_connector_reset(struct drm_connector * connector)532 void drm_atomic_helper_connector_reset(struct drm_connector *connector)
533 {
534 struct drm_connector_state *conn_state = kzalloc_obj(*conn_state);
535
536 if (connector->state)
537 __drm_atomic_helper_connector_destroy_state(connector->state);
538
539 kfree(connector->state);
540 __drm_atomic_helper_connector_reset(connector, conn_state);
541 }
542 EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
543
544 /**
545 * drm_atomic_helper_connector_create_state - default &drm_connector_funcs.atomic_create_state hook for connectors
546 * @connector: connector object
547 *
548 * Allocates and initializes pristine @drm_connector_state.
549 *
550 * This is useful for drivers that don't subclass @drm_connector_state.
551 *
552 * RETURNS:
553 * Pointer to new connector state, or ERR_PTR on failure.
554 */
555 struct drm_connector_state *
drm_atomic_helper_connector_create_state(struct drm_connector * connector)556 drm_atomic_helper_connector_create_state(struct drm_connector *connector)
557 {
558 struct drm_connector_state *state;
559
560 state = kzalloc_obj(*state);
561 if (!state)
562 return ERR_PTR(-ENOMEM);
563
564 __drm_atomic_helper_connector_state_init(state, connector);
565
566 return state;
567 }
568 EXPORT_SYMBOL(drm_atomic_helper_connector_create_state);
569
570 /**
571 * drm_atomic_helper_connector_tv_margins_reset - Resets TV connector properties
572 * @connector: DRM connector
573 *
574 * Resets the TV-related properties attached to a connector.
575 */
drm_atomic_helper_connector_tv_margins_reset(struct drm_connector * connector)576 void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector)
577 {
578 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
579 struct drm_connector_state *state = connector->state;
580
581 state->tv.margins.left = cmdline->tv_margins.left;
582 state->tv.margins.right = cmdline->tv_margins.right;
583 state->tv.margins.top = cmdline->tv_margins.top;
584 state->tv.margins.bottom = cmdline->tv_margins.bottom;
585 }
586 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_margins_reset);
587
588 /**
589 * drm_atomic_helper_connector_tv_reset - Resets Analog TV connector properties
590 * @connector: DRM connector
591 *
592 * Resets the analog TV properties attached to a connector
593 */
drm_atomic_helper_connector_tv_reset(struct drm_connector * connector)594 void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector)
595 {
596 struct drm_device *dev = connector->dev;
597 struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
598 struct drm_connector_state *state = connector->state;
599 struct drm_property *prop;
600 uint64_t val;
601
602 prop = dev->mode_config.tv_mode_property;
603 if (prop)
604 if (!drm_object_property_get_default_value(&connector->base,
605 prop, &val))
606 state->tv.mode = val;
607
608 if (cmdline->tv_mode_specified)
609 state->tv.mode = cmdline->tv_mode;
610
611 prop = dev->mode_config.tv_select_subconnector_property;
612 if (prop)
613 if (!drm_object_property_get_default_value(&connector->base,
614 prop, &val))
615 state->tv.select_subconnector = val;
616
617 prop = dev->mode_config.tv_subconnector_property;
618 if (prop)
619 if (!drm_object_property_get_default_value(&connector->base,
620 prop, &val))
621 state->tv.subconnector = val;
622
623 prop = dev->mode_config.tv_brightness_property;
624 if (prop)
625 if (!drm_object_property_get_default_value(&connector->base,
626 prop, &val))
627 state->tv.brightness = val;
628
629 prop = dev->mode_config.tv_contrast_property;
630 if (prop)
631 if (!drm_object_property_get_default_value(&connector->base,
632 prop, &val))
633 state->tv.contrast = val;
634
635 prop = dev->mode_config.tv_flicker_reduction_property;
636 if (prop)
637 if (!drm_object_property_get_default_value(&connector->base,
638 prop, &val))
639 state->tv.flicker_reduction = val;
640
641 prop = dev->mode_config.tv_overscan_property;
642 if (prop)
643 if (!drm_object_property_get_default_value(&connector->base,
644 prop, &val))
645 state->tv.overscan = val;
646
647 prop = dev->mode_config.tv_saturation_property;
648 if (prop)
649 if (!drm_object_property_get_default_value(&connector->base,
650 prop, &val))
651 state->tv.saturation = val;
652
653 prop = dev->mode_config.tv_hue_property;
654 if (prop)
655 if (!drm_object_property_get_default_value(&connector->base,
656 prop, &val))
657 state->tv.hue = val;
658
659 drm_atomic_helper_connector_tv_margins_reset(connector);
660 }
661 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset);
662
663 /**
664 * drm_atomic_helper_connector_tv_check - Validate an analog TV connector state
665 * @connector: DRM Connector
666 * @state: the DRM State object
667 *
668 * Checks the state object to see if the requested state is valid for an
669 * analog TV connector.
670 *
671 * Return:
672 * %0 for success, a negative error code on error.
673 */
drm_atomic_helper_connector_tv_check(struct drm_connector * connector,struct drm_atomic_commit * state)674 int drm_atomic_helper_connector_tv_check(struct drm_connector *connector,
675 struct drm_atomic_commit *state)
676 {
677 struct drm_connector_state *old_conn_state =
678 drm_atomic_get_old_connector_state(state, connector);
679 struct drm_connector_state *new_conn_state =
680 drm_atomic_get_new_connector_state(state, connector);
681 struct drm_crtc_state *crtc_state;
682 struct drm_crtc *crtc;
683
684 crtc = new_conn_state->crtc;
685 if (!crtc)
686 return 0;
687
688 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
689 if (!crtc_state)
690 return -EINVAL;
691
692 if (old_conn_state->tv.mode != new_conn_state->tv.mode)
693 crtc_state->mode_changed = true;
694
695 if (old_conn_state->tv.margins.left != new_conn_state->tv.margins.left ||
696 old_conn_state->tv.margins.right != new_conn_state->tv.margins.right ||
697 old_conn_state->tv.margins.top != new_conn_state->tv.margins.top ||
698 old_conn_state->tv.margins.bottom != new_conn_state->tv.margins.bottom ||
699 old_conn_state->tv.mode != new_conn_state->tv.mode ||
700 old_conn_state->tv.brightness != new_conn_state->tv.brightness ||
701 old_conn_state->tv.contrast != new_conn_state->tv.contrast ||
702 old_conn_state->tv.flicker_reduction != new_conn_state->tv.flicker_reduction ||
703 old_conn_state->tv.overscan != new_conn_state->tv.overscan ||
704 old_conn_state->tv.saturation != new_conn_state->tv.saturation ||
705 old_conn_state->tv.hue != new_conn_state->tv.hue)
706 crtc_state->connectors_changed = true;
707
708 return 0;
709 }
710 EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check);
711
712 /**
713 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
714 * @connector: connector object
715 * @state: atomic connector state
716 *
717 * Copies atomic state from a connector's current state. This is useful for
718 * drivers that subclass the connector state.
719 */
720 void
__drm_atomic_helper_connector_duplicate_state(struct drm_connector * connector,struct drm_connector_state * state)721 __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
722 struct drm_connector_state *state)
723 {
724 memcpy(state, connector->state, sizeof(*state));
725 if (state->crtc)
726 drm_connector_get(connector);
727 state->commit = NULL;
728
729 if (state->hdr_output_metadata)
730 drm_property_blob_get(state->hdr_output_metadata);
731
732 /* Don't copy over a writeback job, they are used only once */
733 state->writeback_job = NULL;
734 }
735 EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
736
737 /**
738 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
739 * @connector: drm connector
740 *
741 * Default connector state duplicate hook for drivers which don't have their own
742 * subclassed connector state structure.
743 */
744 struct drm_connector_state *
drm_atomic_helper_connector_duplicate_state(struct drm_connector * connector)745 drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
746 {
747 struct drm_connector_state *state;
748
749 if (WARN_ON(!connector->state))
750 return NULL;
751
752 state = kmalloc_obj(*state);
753 if (state)
754 __drm_atomic_helper_connector_duplicate_state(connector, state);
755
756 return state;
757 }
758 EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
759
760 /**
761 * __drm_atomic_helper_connector_destroy_state - release connector state
762 * @state: connector state object to release
763 *
764 * Releases all resources stored in the connector state without actually
765 * freeing the memory of the connector state. This is useful for drivers that
766 * subclass the connector state.
767 */
768 void
__drm_atomic_helper_connector_destroy_state(struct drm_connector_state * state)769 __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
770 {
771 if (state->crtc)
772 drm_connector_put(state->connector);
773
774 if (state->commit)
775 drm_crtc_commit_put(state->commit);
776
777 if (state->writeback_job)
778 drm_writeback_cleanup_job(state->writeback_job);
779
780 drm_property_blob_put(state->hdr_output_metadata);
781 }
782 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
783
784 /**
785 * drm_atomic_helper_connector_destroy_state - default state destroy hook
786 * @connector: drm connector
787 * @state: connector state object to release
788 *
789 * Default connector state destroy hook for drivers which don't have their own
790 * subclassed connector state structure.
791 */
drm_atomic_helper_connector_destroy_state(struct drm_connector * connector,struct drm_connector_state * state)792 void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
793 struct drm_connector_state *state)
794 {
795 __drm_atomic_helper_connector_destroy_state(state);
796 kfree(state);
797 }
798 EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
799
800 /**
801 * __drm_atomic_helper_private_obj_create_state - initializes private object state
802 * @obj: private object
803 * @state: new state to initialize
804 *
805 * Initializes the newly allocated @state, usually required when
806 * initializing the drivers.
807 *
808 * @obj is assumed to be zeroed.
809 *
810 * This is useful for drivers that use private states.
811 */
__drm_atomic_helper_private_obj_create_state(struct drm_private_obj * obj,struct drm_private_state * state)812 void __drm_atomic_helper_private_obj_create_state(struct drm_private_obj *obj,
813 struct drm_private_state *state)
814 {
815 if (state)
816 state->obj = obj;
817 }
818 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_create_state);
819
820 /**
821 * __drm_atomic_helper_private_obj_duplicate_state - copy atomic private state
822 * @obj: CRTC object
823 * @state: new private object state
824 *
825 * Copies atomic state from a private objects's current state and resets inferred values.
826 * This is useful for drivers that subclass the private state.
827 */
__drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj * obj,struct drm_private_state * state)828 void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
829 struct drm_private_state *state)
830 {
831 memcpy(state, obj->state, sizeof(*state));
832 }
833 EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
834
835 /**
836 * __drm_atomic_helper_bridge_duplicate_state() - Copy atomic bridge state
837 * @bridge: bridge object
838 * @state: atomic bridge state
839 *
840 * Copies atomic state from a bridge's current state and resets inferred values.
841 * This is useful for drivers that subclass the bridge state.
842 */
__drm_atomic_helper_bridge_duplicate_state(struct drm_bridge * bridge,struct drm_bridge_state * state)843 void __drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge,
844 struct drm_bridge_state *state)
845 {
846 __drm_atomic_helper_private_obj_duplicate_state(&bridge->base,
847 &state->base);
848 state->bridge = bridge;
849 }
850 EXPORT_SYMBOL(__drm_atomic_helper_bridge_duplicate_state);
851
852 /**
853 * drm_atomic_helper_bridge_duplicate_state() - Duplicate a bridge state object
854 * @bridge: bridge object
855 *
856 * Allocates a new bridge state and initializes it with the current bridge
857 * state values. This helper is meant to be used as a bridge
858 * &drm_bridge_funcs.atomic_duplicate_state hook for bridges that don't
859 * subclass the bridge state.
860 */
861 struct drm_bridge_state *
drm_atomic_helper_bridge_duplicate_state(struct drm_bridge * bridge)862 drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge)
863 {
864 struct drm_bridge_state *new;
865
866 if (WARN_ON(!bridge->base.state))
867 return NULL;
868
869 new = kzalloc_obj(*new);
870 if (new)
871 __drm_atomic_helper_bridge_duplicate_state(bridge, new);
872
873 return new;
874 }
875 EXPORT_SYMBOL(drm_atomic_helper_bridge_duplicate_state);
876
877 /**
878 * drm_atomic_helper_bridge_destroy_state() - Destroy a bridge state object
879 * @bridge: the bridge this state refers to
880 * @state: bridge state to destroy
881 *
882 * Destroys a bridge state previously created by
883 * &drm_atomic_helper_bridge_create_state() or
884 * &drm_atomic_helper_bridge_duplicate_state(). This helper is meant to be
885 * used as a bridge &drm_bridge_funcs.atomic_destroy_state hook for bridges
886 * that don't subclass the bridge state.
887 */
drm_atomic_helper_bridge_destroy_state(struct drm_bridge * bridge,struct drm_bridge_state * state)888 void drm_atomic_helper_bridge_destroy_state(struct drm_bridge *bridge,
889 struct drm_bridge_state *state)
890 {
891 kfree(state);
892 }
893 EXPORT_SYMBOL(drm_atomic_helper_bridge_destroy_state);
894
895 /**
896 * __drm_atomic_helper_bridge_state_init() - Initialize a bridge state to its
897 * default
898 * @state: bridge state to initialize
899 * @bridge: the bridge this state refers to
900 *
901 * @state is assumed to be zeroed.
902 *
903 * Initializes the bridge state to default values. This is meant to be called
904 * by the bridge &drm_bridge_funcs.atomic_create_state hook for bridges that
905 * subclass the bridge state.
906 */
__drm_atomic_helper_bridge_state_init(struct drm_bridge_state * state,struct drm_bridge * bridge)907 void __drm_atomic_helper_bridge_state_init(struct drm_bridge_state *state,
908 struct drm_bridge *bridge)
909 {
910 __drm_atomic_helper_private_obj_create_state(&bridge->base, &state->base);
911 state->bridge = bridge;
912 }
913 EXPORT_SYMBOL(__drm_atomic_helper_bridge_state_init);
914
915 /**
916 * drm_atomic_helper_bridge_create_state - default
917 * &drm_bridge_funcs.atomic_create_state hook for bridges
918 * @bridge: bridge object
919 *
920 * Allocates and initializes pristine @drm_bridge_state.
921 *
922 * This is useful for drivers that don't subclass @drm_bridge_state.
923 *
924 * RETURNS:
925 * Pointer to new bridge state, or ERR_PTR on failure.
926 */
927 struct drm_bridge_state *
drm_atomic_helper_bridge_create_state(struct drm_bridge * bridge)928 drm_atomic_helper_bridge_create_state(struct drm_bridge *bridge)
929 {
930 struct drm_bridge_state *bridge_state;
931
932 bridge_state = kzalloc_obj(*bridge_state);
933 if (!bridge_state)
934 return ERR_PTR(-ENOMEM);
935
936 __drm_atomic_helper_bridge_state_init(bridge_state, bridge);
937 return bridge_state;
938 }
939 EXPORT_SYMBOL(drm_atomic_helper_bridge_create_state);
940