]> git.ipfire.org Git - thirdparty/kernel/stable.git/blame - drivers/gpu/drm/drm_atomic_state_helper.c
Merge tag 'drm-intel-next-2019-05-24' of git://anongit.freedesktop.org/drm/drm-intel...
[thirdparty/kernel/stable.git] / drivers / gpu / drm / drm_atomic_state_helper.c
CommitLineData
9ef8a9dc
SV
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_state_helper.h>
28#include <drm/drm_crtc.h>
29#include <drm/drm_plane.h>
30#include <drm/drm_connector.h>
31#include <drm/drm_atomic.h>
32#include <drm/drm_device.h>
e482ae9b 33#include <drm/drm_writeback.h>
9ef8a9dc
SV
34
35#include <linux/slab.h>
36#include <linux/dma-fence.h>
37
38/**
39 * DOC: atomic state reset and initialization
40 *
41 * Both the drm core and the atomic helpers assume that there is always the full
42 * and correct atomic software state for all connectors, CRTCs and planes
43 * available. Which is a bit a problem on driver load and also after system
44 * suspend. One way to solve this is to have a hardware state read-out
45 * infrastructure which reconstructs the full software state (e.g. the i915
46 * driver).
47 *
48 * The simpler solution is to just reset the software state to everything off,
49 * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
50 * the atomic helpers provide default reset implementations for all hooks.
51 *
52 * On the upside the precise state tracking of atomic simplifies system suspend
53 * and resume a lot. For drivers using drm_mode_config_reset() a complete recipe
54 * is implemented in drm_atomic_helper_suspend() and drm_atomic_helper_resume().
55 * For other drivers the building blocks are split out, see the documentation
56 * for these functions.
57 */
58
7d26097b
ML
59/**
60 * __drm_atomic_helper_crtc_reset - reset state on CRTC
61 * @crtc: drm CRTC
62 * @crtc_state: CRTC state to assign
63 *
64 * Initializes the newly allocated @crtc_state and assigns it to
65 * the &drm_crtc->state pointer of @crtc, usually required when
66 * initializing the drivers or when called from the &drm_crtc_funcs.reset
67 * hook.
68 *
69 * This is useful for drivers that subclass the CRTC state.
70 */
71void
72__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
73 struct drm_crtc_state *crtc_state)
74{
75 if (crtc_state)
76 crtc_state->crtc = crtc;
77
78 crtc->state = crtc_state;
79}
80EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
81
9ef8a9dc
SV
82/**
83 * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
84 * @crtc: drm CRTC
85 *
86 * Resets the atomic state for @crtc by freeing the state pointer (which might
87 * be NULL, e.g. at driver load time) and allocating a new empty state object.
88 */
89void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
90{
7d26097b
ML
91 struct drm_crtc_state *crtc_state =
92 kzalloc(sizeof(*crtc->state), GFP_KERNEL);
9ef8a9dc
SV
93
94 if (crtc->state)
7d26097b
ML
95 crtc->funcs->atomic_destroy_state(crtc, crtc->state);
96
97 __drm_atomic_helper_crtc_reset(crtc, crtc_state);
9ef8a9dc
SV
98}
99EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
100
101/**
102 * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
103 * @crtc: CRTC object
104 * @state: atomic CRTC state
105 *
106 * Copies atomic state from a CRTC's current state and resets inferred values.
107 * This is useful for drivers that subclass the CRTC state.
108 */
109void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
110 struct drm_crtc_state *state)
111{
112 memcpy(state, crtc->state, sizeof(*state));
113
114 if (state->mode_blob)
115 drm_property_blob_get(state->mode_blob);
116 if (state->degamma_lut)
117 drm_property_blob_get(state->degamma_lut);
118 if (state->ctm)
119 drm_property_blob_get(state->ctm);
120 if (state->gamma_lut)
121 drm_property_blob_get(state->gamma_lut);
122 state->mode_changed = false;
123 state->active_changed = false;
124 state->planes_changed = false;
125 state->connectors_changed = false;
126 state->color_mgmt_changed = false;
127 state->zpos_changed = false;
128 state->commit = NULL;
129 state->event = NULL;
130 state->pageflip_flags = 0;
131}
132EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
133
134/**
135 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
136 * @crtc: drm CRTC
137 *
138 * Default CRTC state duplicate hook for drivers which don't have their own
139 * subclassed CRTC state structure.
140 */
141struct drm_crtc_state *
142drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
143{
144 struct drm_crtc_state *state;
145
146 if (WARN_ON(!crtc->state))
147 return NULL;
148
149 state = kmalloc(sizeof(*state), GFP_KERNEL);
150 if (state)
151 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
152
153 return state;
154}
155EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
156
157/**
158 * __drm_atomic_helper_crtc_destroy_state - release CRTC state
159 * @state: CRTC state object to release
160 *
161 * Releases all resources stored in the CRTC state without actually freeing
162 * the memory of the CRTC state. This is useful for drivers that subclass the
163 * CRTC state.
164 */
165void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
166{
167 if (state->commit) {
168 /*
169 * In the event that a non-blocking commit returns
170 * -ERESTARTSYS before the commit_tail work is queued, we will
171 * have an extra reference to the commit object. Release it, if
172 * the event has not been consumed by the worker.
173 *
174 * state->event may be freed, so we can't directly look at
175 * state->event->base.completion.
176 */
177 if (state->event && state->commit->abort_completion)
178 drm_crtc_commit_put(state->commit);
179
180 kfree(state->commit->event);
181 state->commit->event = NULL;
182
183 drm_crtc_commit_put(state->commit);
184 }
185
186 drm_property_blob_put(state->mode_blob);
187 drm_property_blob_put(state->degamma_lut);
188 drm_property_blob_put(state->ctm);
189 drm_property_blob_put(state->gamma_lut);
190}
191EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
192
193/**
194 * drm_atomic_helper_crtc_destroy_state - default state destroy hook
195 * @crtc: drm CRTC
196 * @state: CRTC state object to release
197 *
198 * Default CRTC state destroy hook for drivers which don't have their own
199 * subclassed CRTC state structure.
200 */
201void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
202 struct drm_crtc_state *state)
203{
204 __drm_atomic_helper_crtc_destroy_state(state);
205 kfree(state);
206}
207EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
208
209/**
210 * __drm_atomic_helper_plane_reset - resets planes state to default values
211 * @plane: plane object, must not be NULL
212 * @state: atomic plane state, must not be NULL
213 *
214 * Initializes plane state to default. This is useful for drivers that subclass
215 * the plane state.
216 */
217void __drm_atomic_helper_plane_reset(struct drm_plane *plane,
218 struct drm_plane_state *state)
219{
220 state->plane = plane;
221 state->rotation = DRM_MODE_ROTATE_0;
222
223 state->alpha = DRM_BLEND_ALPHA_OPAQUE;
224 state->pixel_blend_mode = DRM_MODE_BLEND_PREMULTI;
225
226 plane->state = state;
227}
228EXPORT_SYMBOL(__drm_atomic_helper_plane_reset);
229
230/**
231 * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes
232 * @plane: drm plane
233 *
234 * Resets the atomic state for @plane by freeing the state pointer (which might
235 * be NULL, e.g. at driver load time) and allocating a new empty state object.
236 */
237void drm_atomic_helper_plane_reset(struct drm_plane *plane)
238{
239 if (plane->state)
240 __drm_atomic_helper_plane_destroy_state(plane->state);
241
242 kfree(plane->state);
243 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
244 if (plane->state)
245 __drm_atomic_helper_plane_reset(plane, plane->state);
246}
247EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
248
249/**
250 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
251 * @plane: plane object
252 * @state: atomic plane state
253 *
254 * Copies atomic state from a plane's current state. This is useful for
255 * drivers that subclass the plane state.
256 */
257void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
258 struct drm_plane_state *state)
259{
260 memcpy(state, plane->state, sizeof(*state));
261
262 if (state->fb)
263 drm_framebuffer_get(state->fb);
264
265 state->fence = NULL;
266 state->commit = NULL;
c75ff001 267 state->fb_damage_clips = NULL;
9ef8a9dc
SV
268}
269EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
270
271/**
272 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
273 * @plane: drm plane
274 *
275 * Default plane state duplicate hook for drivers which don't have their own
276 * subclassed plane state structure.
277 */
278struct drm_plane_state *
279drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
280{
281 struct drm_plane_state *state;
282
283 if (WARN_ON(!plane->state))
284 return NULL;
285
286 state = kmalloc(sizeof(*state), GFP_KERNEL);
287 if (state)
288 __drm_atomic_helper_plane_duplicate_state(plane, state);
289
290 return state;
291}
292EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
293
294/**
295 * __drm_atomic_helper_plane_destroy_state - release plane state
296 * @state: plane state object to release
297 *
298 * Releases all resources stored in the plane state without actually freeing
299 * the memory of the plane state. This is useful for drivers that subclass the
300 * plane state.
301 */
302void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
303{
304 if (state->fb)
305 drm_framebuffer_put(state->fb);
306
307 if (state->fence)
308 dma_fence_put(state->fence);
309
310 if (state->commit)
311 drm_crtc_commit_put(state->commit);
c75ff001
DR
312
313 drm_property_blob_put(state->fb_damage_clips);
9ef8a9dc
SV
314}
315EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
316
317/**
318 * drm_atomic_helper_plane_destroy_state - default state destroy hook
319 * @plane: drm plane
320 * @state: plane state object to release
321 *
322 * Default plane state destroy hook for drivers which don't have their own
323 * subclassed plane state structure.
324 */
325void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
326 struct drm_plane_state *state)
327{
328 __drm_atomic_helper_plane_destroy_state(state);
329 kfree(state);
330}
331EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
332
333/**
334 * __drm_atomic_helper_connector_reset - reset state on connector
335 * @connector: drm connector
336 * @conn_state: connector state to assign
337 *
338 * Initializes the newly allocated @conn_state and assigns it to
12d7a93c 339 * the &drm_connector->state pointer of @connector, usually required when
9ef8a9dc
SV
340 * initializing the drivers or when called from the &drm_connector_funcs.reset
341 * hook.
342 *
343 * This is useful for drivers that subclass the connector state.
344 */
345void
346__drm_atomic_helper_connector_reset(struct drm_connector *connector,
347 struct drm_connector_state *conn_state)
348{
349 if (conn_state)
350 conn_state->connector = connector;
351
352 connector->state = conn_state;
353}
354EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
355
356/**
357 * drm_atomic_helper_connector_reset - default &drm_connector_funcs.reset hook for connectors
358 * @connector: drm connector
359 *
360 * Resets the atomic state for @connector by freeing the state pointer (which
361 * might be NULL, e.g. at driver load time) and allocating a new empty state
362 * object.
363 */
364void drm_atomic_helper_connector_reset(struct drm_connector *connector)
365{
366 struct drm_connector_state *conn_state =
367 kzalloc(sizeof(*conn_state), GFP_KERNEL);
368
369 if (connector->state)
370 __drm_atomic_helper_connector_destroy_state(connector->state);
371
372 kfree(connector->state);
373 __drm_atomic_helper_connector_reset(connector, conn_state);
374}
375EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
376
377/**
378 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
379 * @connector: connector object
380 * @state: atomic connector state
381 *
382 * Copies atomic state from a connector's current state. This is useful for
383 * drivers that subclass the connector state.
384 */
385void
386__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
387 struct drm_connector_state *state)
388{
389 memcpy(state, connector->state, sizeof(*state));
390 if (state->crtc)
391 drm_connector_get(connector);
392 state->commit = NULL;
393
c0b0ebb1
JK
394 if (state->hdr_output_metadata)
395 drm_property_blob_get(state->hdr_output_metadata);
396
9ef8a9dc
SV
397 /* Don't copy over a writeback job, they are used only once */
398 state->writeback_job = NULL;
399}
400EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
401
402/**
403 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
404 * @connector: drm connector
405 *
406 * Default connector state duplicate hook for drivers which don't have their own
407 * subclassed connector state structure.
408 */
409struct drm_connector_state *
410drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
411{
412 struct drm_connector_state *state;
413
414 if (WARN_ON(!connector->state))
415 return NULL;
416
417 state = kmalloc(sizeof(*state), GFP_KERNEL);
418 if (state)
419 __drm_atomic_helper_connector_duplicate_state(connector, state);
420
421 return state;
422}
423EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
424
9ef8a9dc
SV
425/**
426 * __drm_atomic_helper_connector_destroy_state - release connector state
427 * @state: connector state object to release
428 *
429 * Releases all resources stored in the connector state without actually
430 * freeing the memory of the connector state. This is useful for drivers that
431 * subclass the connector state.
432 */
433void
434__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
435{
436 if (state->crtc)
437 drm_connector_put(state->connector);
438
439 if (state->commit)
440 drm_crtc_commit_put(state->commit);
e482ae9b
LP
441
442 if (state->writeback_job)
443 drm_writeback_cleanup_job(state->writeback_job);
c0b0ebb1
JK
444
445 drm_property_blob_put(state->hdr_output_metadata);
9ef8a9dc
SV
446}
447EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
448
449/**
450 * drm_atomic_helper_connector_destroy_state - default state destroy hook
451 * @connector: drm connector
452 * @state: connector state object to release
453 *
454 * Default connector state destroy hook for drivers which don't have their own
455 * subclassed connector state structure.
456 */
457void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
458 struct drm_connector_state *state)
459{
460 __drm_atomic_helper_connector_destroy_state(state);
461 kfree(state);
462}
463EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
464
9ef8a9dc
SV
465/**
466 * __drm_atomic_helper_private_duplicate_state - copy atomic private state
467 * @obj: CRTC object
468 * @state: new private object state
469 *
470 * Copies atomic state from a private objects's current state and resets inferred values.
471 * This is useful for drivers that subclass the private state.
472 */
473void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
474 struct drm_private_state *state)
475{
476 memcpy(state, obj->state, sizeof(*state));
477}
478EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);