xref: /linux/drivers/gpu/drm/drm_atomic_state_helper.c (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
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