blob: cd1b16b2571660ffb19bacba45bf5817a1b6ee30 [file] [log] [blame]
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001/*
2 * Copyright (C) 2014 Red Hat
3 * Copyright (C) 2014 Intel Corp.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 * Authors:
24 * Rob Clark <robdclark@gmail.com>
25 * Daniel Vetter <daniel.vetter@ffwll.ch>
26 */
27
28
29#include <drm/drmP.h>
30#include <drm/drm_atomic.h>
31#include <drm/drm_plane_helper.h>
32
Maarten Lankhorst036ef572015-05-18 10:06:40 +020033/**
34 * drm_atomic_state_default_release -
35 * release memory initialized by drm_atomic_state_init
36 * @state: atomic state
37 *
38 * Free all the memory allocated by drm_atomic_state_init.
39 * This is useful for drivers that subclass the atomic state.
40 */
41void drm_atomic_state_default_release(struct drm_atomic_state *state)
Daniel Vettercc4ceb42014-07-25 21:30:38 +020042{
43 kfree(state->connectors);
44 kfree(state->connector_states);
45 kfree(state->crtcs);
46 kfree(state->crtc_states);
47 kfree(state->planes);
48 kfree(state->plane_states);
Daniel Vettercc4ceb42014-07-25 21:30:38 +020049}
Maarten Lankhorst036ef572015-05-18 10:06:40 +020050EXPORT_SYMBOL(drm_atomic_state_default_release);
Daniel Vettercc4ceb42014-07-25 21:30:38 +020051
52/**
Maarten Lankhorst036ef572015-05-18 10:06:40 +020053 * drm_atomic_state_init - init new atomic state
Daniel Vettercc4ceb42014-07-25 21:30:38 +020054 * @dev: DRM device
Maarten Lankhorst036ef572015-05-18 10:06:40 +020055 * @state: atomic state
Daniel Vettercc4ceb42014-07-25 21:30:38 +020056 *
Maarten Lankhorst036ef572015-05-18 10:06:40 +020057 * Default implementation for filling in a new atomic state.
58 * This is useful for drivers that subclass the atomic state.
Daniel Vettercc4ceb42014-07-25 21:30:38 +020059 */
Maarten Lankhorst036ef572015-05-18 10:06:40 +020060int
61drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
Daniel Vettercc4ceb42014-07-25 21:30:38 +020062{
Rob Clarkd34f20d2014-12-18 16:01:56 -050063 /* TODO legacy paths should maybe do a better job about
64 * setting this appropriately?
65 */
66 state->allow_modeset = true;
67
Daniel Vetterf52b69f12014-11-19 18:38:08 +010068 state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector);
69
Daniel Vettercc4ceb42014-07-25 21:30:38 +020070 state->crtcs = kcalloc(dev->mode_config.num_crtc,
71 sizeof(*state->crtcs), GFP_KERNEL);
72 if (!state->crtcs)
73 goto fail;
74 state->crtc_states = kcalloc(dev->mode_config.num_crtc,
75 sizeof(*state->crtc_states), GFP_KERNEL);
76 if (!state->crtc_states)
77 goto fail;
78 state->planes = kcalloc(dev->mode_config.num_total_plane,
79 sizeof(*state->planes), GFP_KERNEL);
80 if (!state->planes)
81 goto fail;
82 state->plane_states = kcalloc(dev->mode_config.num_total_plane,
83 sizeof(*state->plane_states), GFP_KERNEL);
84 if (!state->plane_states)
85 goto fail;
Daniel Vetterf52b69f12014-11-19 18:38:08 +010086 state->connectors = kcalloc(state->num_connector,
Daniel Vettercc4ceb42014-07-25 21:30:38 +020087 sizeof(*state->connectors),
88 GFP_KERNEL);
89 if (!state->connectors)
90 goto fail;
Daniel Vetterf52b69f12014-11-19 18:38:08 +010091 state->connector_states = kcalloc(state->num_connector,
Daniel Vettercc4ceb42014-07-25 21:30:38 +020092 sizeof(*state->connector_states),
93 GFP_KERNEL);
94 if (!state->connector_states)
95 goto fail;
96
97 state->dev = dev;
98
Maarten Lankhorst036ef572015-05-18 10:06:40 +020099 DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200100
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200101 return 0;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200102fail:
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200103 drm_atomic_state_default_release(state);
104 return -ENOMEM;
105}
106EXPORT_SYMBOL(drm_atomic_state_init);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200107
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200108/**
109 * drm_atomic_state_alloc - allocate atomic state
110 * @dev: DRM device
111 *
112 * This allocates an empty atomic state to track updates.
113 */
114struct drm_atomic_state *
115drm_atomic_state_alloc(struct drm_device *dev)
116{
117 struct drm_mode_config *config = &dev->mode_config;
118 struct drm_atomic_state *state;
119
120 if (!config->funcs->atomic_state_alloc) {
121 state = kzalloc(sizeof(*state), GFP_KERNEL);
122 if (!state)
123 return NULL;
124 if (drm_atomic_state_init(dev, state) < 0) {
125 kfree(state);
126 return NULL;
127 }
128 return state;
129 }
130
131 return config->funcs->atomic_state_alloc(dev);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200132}
133EXPORT_SYMBOL(drm_atomic_state_alloc);
134
135/**
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200136 * drm_atomic_state_default_clear - clear base atomic state
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200137 * @state: atomic state
138 *
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200139 * Default implementation for clearing atomic state.
140 * This is useful for drivers that subclass the atomic state.
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200141 */
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200142void drm_atomic_state_default_clear(struct drm_atomic_state *state)
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200143{
144 struct drm_device *dev = state->dev;
Daniel Vetter6f75cea2014-11-19 18:38:07 +0100145 struct drm_mode_config *config = &dev->mode_config;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200146 int i;
147
Daniel Vetter17a38d92015-02-22 12:24:16 +0100148 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200149
Daniel Vetterf52b69f12014-11-19 18:38:08 +0100150 for (i = 0; i < state->num_connector; i++) {
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200151 struct drm_connector *connector = state->connectors[i];
152
153 if (!connector)
154 continue;
155
Daniel Vetter6f75cea2014-11-19 18:38:07 +0100156 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
157
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200158 connector->funcs->atomic_destroy_state(connector,
159 state->connector_states[i]);
Ander Conselvan de Oliveira8a5c0bd2015-03-30 10:41:19 +0300160 state->connectors[i] = NULL;
Ander Conselvan de Oliveira94692442015-01-23 09:27:59 +0200161 state->connector_states[i] = NULL;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200162 }
163
Daniel Vetter6f75cea2014-11-19 18:38:07 +0100164 for (i = 0; i < config->num_crtc; i++) {
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200165 struct drm_crtc *crtc = state->crtcs[i];
166
167 if (!crtc)
168 continue;
169
170 crtc->funcs->atomic_destroy_state(crtc,
171 state->crtc_states[i]);
Ander Conselvan de Oliveira8a5c0bd2015-03-30 10:41:19 +0300172 state->crtcs[i] = NULL;
Ander Conselvan de Oliveira94692442015-01-23 09:27:59 +0200173 state->crtc_states[i] = NULL;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200174 }
175
Daniel Vetter6f75cea2014-11-19 18:38:07 +0100176 for (i = 0; i < config->num_total_plane; i++) {
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200177 struct drm_plane *plane = state->planes[i];
178
179 if (!plane)
180 continue;
181
182 plane->funcs->atomic_destroy_state(plane,
183 state->plane_states[i]);
Ander Conselvan de Oliveira8a5c0bd2015-03-30 10:41:19 +0300184 state->planes[i] = NULL;
Ander Conselvan de Oliveira94692442015-01-23 09:27:59 +0200185 state->plane_states[i] = NULL;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200186 }
187}
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200188EXPORT_SYMBOL(drm_atomic_state_default_clear);
189
190/**
191 * drm_atomic_state_clear - clear state object
192 * @state: atomic state
193 *
194 * When the w/w mutex algorithm detects a deadlock we need to back off and drop
195 * all locks. So someone else could sneak in and change the current modeset
196 * configuration. Which means that all the state assembled in @state is no
197 * longer an atomic update to the current state, but to some arbitrary earlier
198 * state. Which could break assumptions the driver's ->atomic_check likely
199 * relies on.
200 *
201 * Hence we must clear all cached state and completely start over, using this
202 * function.
203 */
204void drm_atomic_state_clear(struct drm_atomic_state *state)
205{
206 struct drm_device *dev = state->dev;
207 struct drm_mode_config *config = &dev->mode_config;
208
209 if (config->funcs->atomic_state_clear)
210 config->funcs->atomic_state_clear(state);
211 else
212 drm_atomic_state_default_clear(state);
213}
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200214EXPORT_SYMBOL(drm_atomic_state_clear);
215
216/**
217 * drm_atomic_state_free - free all memory for an atomic state
218 * @state: atomic state to deallocate
219 *
220 * This frees all memory associated with an atomic state, including all the
221 * per-object state for planes, crtcs and connectors.
222 */
223void drm_atomic_state_free(struct drm_atomic_state *state)
224{
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200225 struct drm_device *dev;
226 struct drm_mode_config *config;
227
Ander Conselvan de Oliveiraa0211bb2015-03-30 14:05:43 +0300228 if (!state)
229 return;
230
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200231 dev = state->dev;
232 config = &dev->mode_config;
233
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200234 drm_atomic_state_clear(state);
235
Daniel Vetter17a38d92015-02-22 12:24:16 +0100236 DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200237
Maarten Lankhorst036ef572015-05-18 10:06:40 +0200238 if (config->funcs->atomic_state_free) {
239 config->funcs->atomic_state_free(state);
240 } else {
241 drm_atomic_state_default_release(state);
242 kfree(state);
243 }
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200244}
245EXPORT_SYMBOL(drm_atomic_state_free);
246
247/**
248 * drm_atomic_get_crtc_state - get crtc state
249 * @state: global atomic state object
250 * @crtc: crtc to get state object for
251 *
252 * This function returns the crtc state for the given crtc, allocating it if
253 * needed. It will also grab the relevant crtc lock to make sure that the state
254 * is consistent.
255 *
256 * Returns:
257 *
258 * Either the allocated state or the error code encoded into the pointer. When
259 * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
260 * entire atomic sequence must be restarted. All other errors are fatal.
261 */
262struct drm_crtc_state *
263drm_atomic_get_crtc_state(struct drm_atomic_state *state,
264 struct drm_crtc *crtc)
265{
Maarten Lankhorst1b26a5e2015-05-13 10:37:25 +0200266 int ret, index = drm_crtc_index(crtc);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200267 struct drm_crtc_state *crtc_state;
268
Maarten Lankhorst1b26a5e2015-05-13 10:37:25 +0200269 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
270 if (crtc_state)
271 return crtc_state;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200272
273 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
274 if (ret)
275 return ERR_PTR(ret);
276
277 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
278 if (!crtc_state)
279 return ERR_PTR(-ENOMEM);
280
281 state->crtc_states[index] = crtc_state;
282 state->crtcs[index] = crtc;
283 crtc_state->state = state;
284
Daniel Vetter17a38d92015-02-22 12:24:16 +0100285 DRM_DEBUG_ATOMIC("Added [CRTC:%d] %p state to %p\n",
286 crtc->base.id, crtc_state, state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200287
288 return crtc_state;
289}
290EXPORT_SYMBOL(drm_atomic_get_crtc_state);
291
292/**
Rob Clark40ecc692014-12-18 16:01:46 -0500293 * drm_atomic_crtc_set_property - set property on CRTC
294 * @crtc: the drm CRTC to set a property on
295 * @state: the state object to update with the new property value
296 * @property: the property to set
297 * @val: the new property value
298 *
299 * Use this instead of calling crtc->atomic_set_property directly.
300 * This function handles generic/core properties and calls out to
301 * driver's ->atomic_set_property() for driver properties. To ensure
302 * consistent behavior you must call this function rather than the
303 * driver hook directly.
304 *
305 * RETURNS:
306 * Zero on success, error code on failure
307 */
308int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
309 struct drm_crtc_state *state, struct drm_property *property,
310 uint64_t val)
311{
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100312 struct drm_device *dev = crtc->dev;
313 struct drm_mode_config *config = &dev->mode_config;
314
315 /* FIXME: Mode prop is missing, which also controls ->enable. */
Daniel Stone27798362015-03-19 04:33:26 +0000316 if (property == config->prop_active)
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100317 state->active = val;
Daniel Stone27798362015-03-19 04:33:26 +0000318 else if (crtc->funcs->atomic_set_property)
Rob Clark40ecc692014-12-18 16:01:46 -0500319 return crtc->funcs->atomic_set_property(crtc, state, property, val);
Daniel Stone27798362015-03-19 04:33:26 +0000320 else
321 return -EINVAL;
322
323 return 0;
Rob Clark40ecc692014-12-18 16:01:46 -0500324}
325EXPORT_SYMBOL(drm_atomic_crtc_set_property);
326
Daniel Vettera97df1c2014-12-18 22:49:02 +0100327/*
Rob Clarkac9c9252014-12-18 16:01:47 -0500328 * This function handles generic/core properties and calls out to
329 * driver's ->atomic_get_property() for driver properties. To ensure
330 * consistent behavior you must call this function rather than the
331 * driver hook directly.
Rob Clarkac9c9252014-12-18 16:01:47 -0500332 */
333int drm_atomic_crtc_get_property(struct drm_crtc *crtc,
334 const struct drm_crtc_state *state,
335 struct drm_property *property, uint64_t *val)
336{
Daniel Stone8f164ce2015-03-19 04:33:25 +0000337 struct drm_device *dev = crtc->dev;
338 struct drm_mode_config *config = &dev->mode_config;
339
340 if (property == config->prop_active)
341 *val = state->active;
342 else if (crtc->funcs->atomic_get_property)
Rob Clarkac9c9252014-12-18 16:01:47 -0500343 return crtc->funcs->atomic_get_property(crtc, state, property, val);
Daniel Stone8f164ce2015-03-19 04:33:25 +0000344 else
345 return -EINVAL;
346
347 return 0;
Rob Clarkac9c9252014-12-18 16:01:47 -0500348}
Rob Clarkac9c9252014-12-18 16:01:47 -0500349
350/**
Rob Clark5e743732014-12-18 16:01:51 -0500351 * drm_atomic_crtc_check - check crtc state
352 * @crtc: crtc to check
353 * @state: crtc state to check
354 *
355 * Provides core sanity checks for crtc state.
356 *
357 * RETURNS:
358 * Zero on success, error code on failure
359 */
360static int drm_atomic_crtc_check(struct drm_crtc *crtc,
361 struct drm_crtc_state *state)
362{
363 /* NOTE: we explicitly don't enforce constraints such as primary
364 * layer covering entire screen, since that is something we want
365 * to allow (on hw that supports it). For hw that does not, it
366 * should be checked in driver's crtc->atomic_check() vfunc.
367 *
368 * TODO: Add generic modeset state checks once we support those.
369 */
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100370
371 if (state->active && !state->enable) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100372 DRM_DEBUG_ATOMIC("[CRTC:%d] active without enabled\n",
373 crtc->base.id);
Daniel Vettereab3bbe2015-01-22 16:36:21 +0100374 return -EINVAL;
375 }
376
Rob Clark5e743732014-12-18 16:01:51 -0500377 return 0;
378}
379
380/**
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200381 * drm_atomic_get_plane_state - get plane state
382 * @state: global atomic state object
383 * @plane: plane to get state object for
384 *
385 * This function returns the plane state for the given plane, allocating it if
386 * needed. It will also grab the relevant plane lock to make sure that the state
387 * is consistent.
388 *
389 * Returns:
390 *
391 * Either the allocated state or the error code encoded into the pointer. When
392 * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
393 * entire atomic sequence must be restarted. All other errors are fatal.
394 */
395struct drm_plane_state *
396drm_atomic_get_plane_state(struct drm_atomic_state *state,
397 struct drm_plane *plane)
398{
Maarten Lankhorst1b26a5e2015-05-13 10:37:25 +0200399 int ret, index = drm_plane_index(plane);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200400 struct drm_plane_state *plane_state;
401
Maarten Lankhorst1b26a5e2015-05-13 10:37:25 +0200402 plane_state = drm_atomic_get_existing_plane_state(state, plane);
403 if (plane_state)
404 return plane_state;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200405
Daniel Vetter4d02e2d2014-11-11 10:12:00 +0100406 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200407 if (ret)
408 return ERR_PTR(ret);
409
410 plane_state = plane->funcs->atomic_duplicate_state(plane);
411 if (!plane_state)
412 return ERR_PTR(-ENOMEM);
413
414 state->plane_states[index] = plane_state;
415 state->planes[index] = plane;
416 plane_state->state = state;
417
Daniel Vetter17a38d92015-02-22 12:24:16 +0100418 DRM_DEBUG_ATOMIC("Added [PLANE:%d] %p state to %p\n",
419 plane->base.id, plane_state, state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200420
421 if (plane_state->crtc) {
422 struct drm_crtc_state *crtc_state;
423
424 crtc_state = drm_atomic_get_crtc_state(state,
425 plane_state->crtc);
426 if (IS_ERR(crtc_state))
427 return ERR_CAST(crtc_state);
428 }
429
430 return plane_state;
431}
432EXPORT_SYMBOL(drm_atomic_get_plane_state);
433
434/**
Rob Clark40ecc692014-12-18 16:01:46 -0500435 * drm_atomic_plane_set_property - set property on plane
436 * @plane: the drm plane to set a property on
437 * @state: the state object to update with the new property value
438 * @property: the property to set
439 * @val: the new property value
440 *
441 * Use this instead of calling plane->atomic_set_property directly.
442 * This function handles generic/core properties and calls out to
443 * driver's ->atomic_set_property() for driver properties. To ensure
444 * consistent behavior you must call this function rather than the
445 * driver hook directly.
446 *
447 * RETURNS:
448 * Zero on success, error code on failure
449 */
450int drm_atomic_plane_set_property(struct drm_plane *plane,
451 struct drm_plane_state *state, struct drm_property *property,
452 uint64_t val)
453{
Rob Clark6b4959f2014-12-18 16:01:53 -0500454 struct drm_device *dev = plane->dev;
455 struct drm_mode_config *config = &dev->mode_config;
456
457 if (property == config->prop_fb_id) {
458 struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, val);
459 drm_atomic_set_fb_for_plane(state, fb);
460 if (fb)
461 drm_framebuffer_unreference(fb);
462 } else if (property == config->prop_crtc_id) {
463 struct drm_crtc *crtc = drm_crtc_find(dev, val);
464 return drm_atomic_set_crtc_for_plane(state, crtc);
465 } else if (property == config->prop_crtc_x) {
466 state->crtc_x = U642I64(val);
467 } else if (property == config->prop_crtc_y) {
468 state->crtc_y = U642I64(val);
469 } else if (property == config->prop_crtc_w) {
470 state->crtc_w = val;
471 } else if (property == config->prop_crtc_h) {
472 state->crtc_h = val;
473 } else if (property == config->prop_src_x) {
474 state->src_x = val;
475 } else if (property == config->prop_src_y) {
476 state->src_y = val;
477 } else if (property == config->prop_src_w) {
478 state->src_w = val;
479 } else if (property == config->prop_src_h) {
480 state->src_h = val;
Matt Roper1da30622015-01-21 16:35:40 -0800481 } else if (property == config->rotation_property) {
482 state->rotation = val;
Rob Clark6b4959f2014-12-18 16:01:53 -0500483 } else if (plane->funcs->atomic_set_property) {
484 return plane->funcs->atomic_set_property(plane, state,
485 property, val);
486 } else {
487 return -EINVAL;
488 }
489
490 return 0;
Rob Clark40ecc692014-12-18 16:01:46 -0500491}
492EXPORT_SYMBOL(drm_atomic_plane_set_property);
493
Daniel Vettera97df1c2014-12-18 22:49:02 +0100494/*
Rob Clarkac9c9252014-12-18 16:01:47 -0500495 * This function handles generic/core properties and calls out to
496 * driver's ->atomic_get_property() for driver properties. To ensure
497 * consistent behavior you must call this function rather than the
498 * driver hook directly.
Rob Clarkac9c9252014-12-18 16:01:47 -0500499 */
Daniel Vettera97df1c2014-12-18 22:49:02 +0100500static int
501drm_atomic_plane_get_property(struct drm_plane *plane,
Rob Clarkac9c9252014-12-18 16:01:47 -0500502 const struct drm_plane_state *state,
503 struct drm_property *property, uint64_t *val)
504{
Rob Clark6b4959f2014-12-18 16:01:53 -0500505 struct drm_device *dev = plane->dev;
506 struct drm_mode_config *config = &dev->mode_config;
507
508 if (property == config->prop_fb_id) {
509 *val = (state->fb) ? state->fb->base.id : 0;
510 } else if (property == config->prop_crtc_id) {
511 *val = (state->crtc) ? state->crtc->base.id : 0;
512 } else if (property == config->prop_crtc_x) {
513 *val = I642U64(state->crtc_x);
514 } else if (property == config->prop_crtc_y) {
515 *val = I642U64(state->crtc_y);
516 } else if (property == config->prop_crtc_w) {
517 *val = state->crtc_w;
518 } else if (property == config->prop_crtc_h) {
519 *val = state->crtc_h;
520 } else if (property == config->prop_src_x) {
521 *val = state->src_x;
522 } else if (property == config->prop_src_y) {
523 *val = state->src_y;
524 } else if (property == config->prop_src_w) {
525 *val = state->src_w;
526 } else if (property == config->prop_src_h) {
527 *val = state->src_h;
Tvrtko Ursulin4cda09c2015-02-26 13:49:17 +0000528 } else if (property == config->rotation_property) {
529 *val = state->rotation;
Rob Clark6b4959f2014-12-18 16:01:53 -0500530 } else if (plane->funcs->atomic_get_property) {
Rob Clarkac9c9252014-12-18 16:01:47 -0500531 return plane->funcs->atomic_get_property(plane, state, property, val);
Rob Clark6b4959f2014-12-18 16:01:53 -0500532 } else {
533 return -EINVAL;
534 }
535
536 return 0;
Rob Clarkac9c9252014-12-18 16:01:47 -0500537}
Rob Clarkac9c9252014-12-18 16:01:47 -0500538
539/**
Rob Clark5e743732014-12-18 16:01:51 -0500540 * drm_atomic_plane_check - check plane state
541 * @plane: plane to check
542 * @state: plane state to check
543 *
544 * Provides core sanity checks for plane state.
545 *
546 * RETURNS:
547 * Zero on success, error code on failure
548 */
549static int drm_atomic_plane_check(struct drm_plane *plane,
550 struct drm_plane_state *state)
551{
552 unsigned int fb_width, fb_height;
Laurent Pinchartead86102015-03-05 02:25:43 +0200553 int ret;
Rob Clark5e743732014-12-18 16:01:51 -0500554
555 /* either *both* CRTC and FB must be set, or neither */
556 if (WARN_ON(state->crtc && !state->fb)) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100557 DRM_DEBUG_ATOMIC("CRTC set but no FB\n");
Rob Clark5e743732014-12-18 16:01:51 -0500558 return -EINVAL;
559 } else if (WARN_ON(state->fb && !state->crtc)) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100560 DRM_DEBUG_ATOMIC("FB set but no CRTC\n");
Rob Clark5e743732014-12-18 16:01:51 -0500561 return -EINVAL;
562 }
563
564 /* if disabled, we don't care about the rest of the state: */
565 if (!state->crtc)
566 return 0;
567
568 /* Check whether this plane is usable on this CRTC */
569 if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100570 DRM_DEBUG_ATOMIC("Invalid crtc for plane\n");
Rob Clark5e743732014-12-18 16:01:51 -0500571 return -EINVAL;
572 }
573
574 /* Check whether this plane supports the fb pixel format. */
Laurent Pinchartead86102015-03-05 02:25:43 +0200575 ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format);
576 if (ret) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100577 DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
578 drm_get_format_name(state->fb->pixel_format));
Laurent Pinchartead86102015-03-05 02:25:43 +0200579 return ret;
Rob Clark5e743732014-12-18 16:01:51 -0500580 }
581
582 /* Give drivers some help against integer overflows */
583 if (state->crtc_w > INT_MAX ||
584 state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
585 state->crtc_h > INT_MAX ||
586 state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100587 DRM_DEBUG_ATOMIC("Invalid CRTC coordinates %ux%u+%d+%d\n",
588 state->crtc_w, state->crtc_h,
589 state->crtc_x, state->crtc_y);
Rob Clark5e743732014-12-18 16:01:51 -0500590 return -ERANGE;
591 }
592
593 fb_width = state->fb->width << 16;
594 fb_height = state->fb->height << 16;
595
596 /* Make sure source coordinates are inside the fb. */
597 if (state->src_w > fb_width ||
598 state->src_x > fb_width - state->src_w ||
599 state->src_h > fb_height ||
600 state->src_y > fb_height - state->src_h) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100601 DRM_DEBUG_ATOMIC("Invalid source coordinates "
602 "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
603 state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
604 state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
605 state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
606 state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10);
Rob Clark5e743732014-12-18 16:01:51 -0500607 return -ENOSPC;
608 }
609
610 return 0;
611}
612
613/**
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200614 * drm_atomic_get_connector_state - get connector state
615 * @state: global atomic state object
616 * @connector: connector to get state object for
617 *
618 * This function returns the connector state for the given connector,
619 * allocating it if needed. It will also grab the relevant connector lock to
620 * make sure that the state is consistent.
621 *
622 * Returns:
623 *
624 * Either the allocated state or the error code encoded into the pointer. When
625 * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
626 * entire atomic sequence must be restarted. All other errors are fatal.
627 */
628struct drm_connector_state *
629drm_atomic_get_connector_state(struct drm_atomic_state *state,
630 struct drm_connector *connector)
631{
632 int ret, index;
633 struct drm_mode_config *config = &connector->dev->mode_config;
634 struct drm_connector_state *connector_state;
635
Daniel Vetterc7eb76f2014-11-19 18:38:06 +0100636 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
637 if (ret)
638 return ERR_PTR(ret);
639
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200640 index = drm_connector_index(connector);
641
Daniel Vetterf52b69f12014-11-19 18:38:08 +0100642 /*
643 * Construction of atomic state updates can race with a connector
644 * hot-add which might overflow. In this case flip the table and just
645 * restart the entire ioctl - no one is fast enough to livelock a cpu
646 * with physical hotplug events anyway.
647 *
648 * Note that we only grab the indexes once we have the right lock to
649 * prevent hotplug/unplugging of connectors. So removal is no problem,
650 * at most the array is a bit too large.
651 */
652 if (index >= state->num_connector) {
Daniel Vetter17a38d92015-02-22 12:24:16 +0100653 DRM_DEBUG_ATOMIC("Hot-added connector would overflow state array, restarting\n");
Daniel Vetterfc2d2bc2014-11-20 09:53:35 +0100654 return ERR_PTR(-EAGAIN);
Daniel Vetterf52b69f12014-11-19 18:38:08 +0100655 }
656
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200657 if (state->connector_states[index])
658 return state->connector_states[index];
659
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200660 connector_state = connector->funcs->atomic_duplicate_state(connector);
661 if (!connector_state)
662 return ERR_PTR(-ENOMEM);
663
664 state->connector_states[index] = connector_state;
665 state->connectors[index] = connector;
666 connector_state->state = state;
667
Daniel Vetter17a38d92015-02-22 12:24:16 +0100668 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
669 connector->base.id, connector_state, state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200670
671 if (connector_state->crtc) {
672 struct drm_crtc_state *crtc_state;
673
674 crtc_state = drm_atomic_get_crtc_state(state,
675 connector_state->crtc);
676 if (IS_ERR(crtc_state))
677 return ERR_CAST(crtc_state);
678 }
679
680 return connector_state;
681}
682EXPORT_SYMBOL(drm_atomic_get_connector_state);
683
684/**
Rob Clark40ecc692014-12-18 16:01:46 -0500685 * drm_atomic_connector_set_property - set property on connector.
686 * @connector: the drm connector to set a property on
687 * @state: the state object to update with the new property value
688 * @property: the property to set
689 * @val: the new property value
690 *
691 * Use this instead of calling connector->atomic_set_property directly.
692 * This function handles generic/core properties and calls out to
693 * driver's ->atomic_set_property() for driver properties. To ensure
694 * consistent behavior you must call this function rather than the
695 * driver hook directly.
696 *
697 * RETURNS:
698 * Zero on success, error code on failure
699 */
700int drm_atomic_connector_set_property(struct drm_connector *connector,
701 struct drm_connector_state *state, struct drm_property *property,
702 uint64_t val)
703{
704 struct drm_device *dev = connector->dev;
705 struct drm_mode_config *config = &dev->mode_config;
706
Rob Clarkae16c592014-12-18 16:01:54 -0500707 if (property == config->prop_crtc_id) {
708 struct drm_crtc *crtc = drm_crtc_find(dev, val);
709 return drm_atomic_set_crtc_for_connector(state, crtc);
710 } else if (property == config->dpms_property) {
Rob Clark40ecc692014-12-18 16:01:46 -0500711 /* setting DPMS property requires special handling, which
712 * is done in legacy setprop path for us. Disallow (for
713 * now?) atomic writes to DPMS property:
714 */
715 return -EINVAL;
716 } else if (connector->funcs->atomic_set_property) {
717 return connector->funcs->atomic_set_property(connector,
718 state, property, val);
719 } else {
720 return -EINVAL;
721 }
722}
723EXPORT_SYMBOL(drm_atomic_connector_set_property);
724
Daniel Vettera97df1c2014-12-18 22:49:02 +0100725/*
Rob Clarkac9c9252014-12-18 16:01:47 -0500726 * This function handles generic/core properties and calls out to
727 * driver's ->atomic_get_property() for driver properties. To ensure
728 * consistent behavior you must call this function rather than the
729 * driver hook directly.
Rob Clarkac9c9252014-12-18 16:01:47 -0500730 */
Daniel Vettera97df1c2014-12-18 22:49:02 +0100731static int
732drm_atomic_connector_get_property(struct drm_connector *connector,
Rob Clarkac9c9252014-12-18 16:01:47 -0500733 const struct drm_connector_state *state,
734 struct drm_property *property, uint64_t *val)
735{
736 struct drm_device *dev = connector->dev;
737 struct drm_mode_config *config = &dev->mode_config;
738
Rob Clarkae16c592014-12-18 16:01:54 -0500739 if (property == config->prop_crtc_id) {
740 *val = (state->crtc) ? state->crtc->base.id : 0;
741 } else if (property == config->dpms_property) {
Rob Clarkac9c9252014-12-18 16:01:47 -0500742 *val = connector->dpms;
743 } else if (connector->funcs->atomic_get_property) {
744 return connector->funcs->atomic_get_property(connector,
745 state, property, val);
746 } else {
747 return -EINVAL;
748 }
749
750 return 0;
751}
Rob Clarkac9c9252014-12-18 16:01:47 -0500752
Rob Clark88a48e22014-12-18 16:01:50 -0500753int drm_atomic_get_property(struct drm_mode_object *obj,
754 struct drm_property *property, uint64_t *val)
755{
756 struct drm_device *dev = property->dev;
757 int ret;
758
759 switch (obj->type) {
760 case DRM_MODE_OBJECT_CONNECTOR: {
761 struct drm_connector *connector = obj_to_connector(obj);
762 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
763 ret = drm_atomic_connector_get_property(connector,
764 connector->state, property, val);
765 break;
766 }
767 case DRM_MODE_OBJECT_CRTC: {
768 struct drm_crtc *crtc = obj_to_crtc(obj);
769 WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
770 ret = drm_atomic_crtc_get_property(crtc,
771 crtc->state, property, val);
772 break;
773 }
774 case DRM_MODE_OBJECT_PLANE: {
775 struct drm_plane *plane = obj_to_plane(obj);
776 WARN_ON(!drm_modeset_is_locked(&plane->mutex));
777 ret = drm_atomic_plane_get_property(plane,
778 plane->state, property, val);
779 break;
780 }
781 default:
782 ret = -EINVAL;
783 break;
784 }
785
786 return ret;
787}
788
789/**
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200790 * drm_atomic_set_crtc_for_plane - set crtc for plane
Daniel Vetter07cc0ef2014-11-27 15:49:39 +0100791 * @plane_state: the plane whose incoming state to update
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200792 * @crtc: crtc to use for the plane
793 *
794 * Changing the assigned crtc for a plane requires us to grab the lock and state
795 * for the new crtc, as needed. This function takes care of all these details
796 * besides updating the pointer in the state object itself.
797 *
798 * Returns:
799 * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
800 * then the w/w mutex code has detected a deadlock and the entire atomic
801 * sequence must be restarted. All other errors are fatal.
802 */
803int
Daniel Vetter07cc0ef2014-11-27 15:49:39 +0100804drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
805 struct drm_crtc *crtc)
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200806{
Daniel Vetter07cc0ef2014-11-27 15:49:39 +0100807 struct drm_plane *plane = plane_state->plane;
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200808 struct drm_crtc_state *crtc_state;
809
Rob Clark6ddd3882014-11-21 15:28:31 -0500810 if (plane_state->crtc) {
811 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
812 plane_state->crtc);
813 if (WARN_ON(IS_ERR(crtc_state)))
814 return PTR_ERR(crtc_state);
815
816 crtc_state->plane_mask &= ~(1 << drm_plane_index(plane));
817 }
818
819 plane_state->crtc = crtc;
820
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200821 if (crtc) {
822 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
823 crtc);
824 if (IS_ERR(crtc_state))
825 return PTR_ERR(crtc_state);
Rob Clark6ddd3882014-11-21 15:28:31 -0500826 crtc_state->plane_mask |= (1 << drm_plane_index(plane));
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200827 }
828
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200829 if (crtc)
Daniel Vetter17a38d92015-02-22 12:24:16 +0100830 DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d]\n",
831 plane_state, crtc->base.id);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200832 else
Daniel Vetter17a38d92015-02-22 12:24:16 +0100833 DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n",
834 plane_state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200835
836 return 0;
837}
838EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane);
839
840/**
John Hunter16d78bc2e2015-04-07 19:38:50 +0800841 * drm_atomic_set_fb_for_plane - set framebuffer for plane
Daniel Vetter321ebf02014-11-04 22:57:27 +0100842 * @plane_state: atomic state object for the plane
843 * @fb: fb to use for the plane
844 *
845 * Changing the assigned framebuffer for a plane requires us to grab a reference
846 * to the new fb and drop the reference to the old fb, if there is one. This
847 * function takes care of all these details besides updating the pointer in the
848 * state object itself.
849 */
850void
851drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
852 struct drm_framebuffer *fb)
853{
854 if (plane_state->fb)
855 drm_framebuffer_unreference(plane_state->fb);
856 if (fb)
857 drm_framebuffer_reference(fb);
858 plane_state->fb = fb;
859
860 if (fb)
Daniel Vetter17a38d92015-02-22 12:24:16 +0100861 DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n",
862 fb->base.id, plane_state);
Daniel Vetter321ebf02014-11-04 22:57:27 +0100863 else
Daniel Vetter17a38d92015-02-22 12:24:16 +0100864 DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
865 plane_state);
Daniel Vetter321ebf02014-11-04 22:57:27 +0100866}
867EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
868
869/**
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200870 * drm_atomic_set_crtc_for_connector - set crtc for connector
871 * @conn_state: atomic state object for the connector
872 * @crtc: crtc to use for the connector
873 *
874 * Changing the assigned crtc for a connector requires us to grab the lock and
875 * state for the new crtc, as needed. This function takes care of all these
876 * details besides updating the pointer in the state object itself.
877 *
878 * Returns:
879 * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
880 * then the w/w mutex code has detected a deadlock and the entire atomic
881 * sequence must be restarted. All other errors are fatal.
882 */
883int
884drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
885 struct drm_crtc *crtc)
886{
887 struct drm_crtc_state *crtc_state;
888
889 if (crtc) {
890 crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
891 if (IS_ERR(crtc_state))
892 return PTR_ERR(crtc_state);
893 }
894
895 conn_state->crtc = crtc;
896
897 if (crtc)
Daniel Vetter17a38d92015-02-22 12:24:16 +0100898 DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d]\n",
899 conn_state, crtc->base.id);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200900 else
Daniel Vetter17a38d92015-02-22 12:24:16 +0100901 DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n",
902 conn_state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200903
904 return 0;
905}
906EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
907
908/**
909 * drm_atomic_add_affected_connectors - add connectors for crtc
910 * @state: atomic state
911 * @crtc: DRM crtc
912 *
913 * This function walks the current configuration and adds all connectors
914 * currently using @crtc to the atomic configuration @state. Note that this
915 * function must acquire the connection mutex. This can potentially cause
916 * unneeded seralization if the update is just for the planes on one crtc. Hence
917 * drivers and helpers should only call this when really needed (e.g. when a
918 * full modeset needs to happen due to some change).
919 *
920 * Returns:
921 * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
922 * then the w/w mutex code has detected a deadlock and the entire atomic
923 * sequence must be restarted. All other errors are fatal.
924 */
925int
926drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
927 struct drm_crtc *crtc)
928{
929 struct drm_mode_config *config = &state->dev->mode_config;
930 struct drm_connector *connector;
931 struct drm_connector_state *conn_state;
932 int ret;
933
934 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
935 if (ret)
936 return ret;
937
Daniel Vetter17a38d92015-02-22 12:24:16 +0100938 DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d] to %p\n",
939 crtc->base.id, state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200940
941 /*
942 * Changed connectors are already in @state, so only need to look at the
943 * current configuration.
944 */
945 list_for_each_entry(connector, &config->connector_list, head) {
946 if (connector->state->crtc != crtc)
947 continue;
948
949 conn_state = drm_atomic_get_connector_state(state, connector);
950 if (IS_ERR(conn_state))
951 return PTR_ERR(conn_state);
952 }
953
954 return 0;
955}
956EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
957
958/**
959 * drm_atomic_connectors_for_crtc - count number of connected outputs
960 * @state: atomic state
961 * @crtc: DRM crtc
962 *
963 * This function counts all connectors which will be connected to @crtc
964 * according to @state. Useful to recompute the enable state for @crtc.
965 */
966int
967drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
968 struct drm_crtc *crtc)
969{
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +0300970 struct drm_connector *connector;
971 struct drm_connector_state *conn_state;
972
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200973 int i, num_connected_connectors = 0;
974
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +0300975 for_each_connector_in_state(state, connector, conn_state, i) {
976 if (conn_state->crtc == crtc)
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200977 num_connected_connectors++;
978 }
979
Daniel Vetter17a38d92015-02-22 12:24:16 +0100980 DRM_DEBUG_ATOMIC("State %p has %i connectors for [CRTC:%d]\n",
981 state, num_connected_connectors, crtc->base.id);
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200982
983 return num_connected_connectors;
984}
985EXPORT_SYMBOL(drm_atomic_connectors_for_crtc);
986
987/**
988 * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
989 * @state: atomic state
990 *
991 * This function should be used by legacy entry points which don't understand
992 * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
John Hunter16d78bc2e2015-04-07 19:38:50 +0800993 * the slowpath completed.
Daniel Vettercc4ceb42014-07-25 21:30:38 +0200994 */
995void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
996{
997 int ret;
998
999retry:
1000 drm_modeset_backoff(state->acquire_ctx);
1001
1002 ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
1003 state->acquire_ctx);
1004 if (ret)
1005 goto retry;
1006 ret = drm_modeset_lock_all_crtcs(state->dev,
1007 state->acquire_ctx);
1008 if (ret)
1009 goto retry;
1010}
1011EXPORT_SYMBOL(drm_atomic_legacy_backoff);
1012
1013/**
1014 * drm_atomic_check_only - check whether a given config would work
1015 * @state: atomic configuration to check
1016 *
1017 * Note that this function can return -EDEADLK if the driver needed to acquire
1018 * more locks but encountered a deadlock. The caller must then do the usual w/w
1019 * backoff dance and restart. All other errors are fatal.
1020 *
1021 * Returns:
1022 * 0 on success, negative error code on failure.
1023 */
1024int drm_atomic_check_only(struct drm_atomic_state *state)
1025{
Rob Clark5e743732014-12-18 16:01:51 -05001026 struct drm_device *dev = state->dev;
1027 struct drm_mode_config *config = &dev->mode_config;
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001028 struct drm_plane *plane;
1029 struct drm_plane_state *plane_state;
1030 struct drm_crtc *crtc;
1031 struct drm_crtc_state *crtc_state;
Rob Clark5e743732014-12-18 16:01:51 -05001032 int i, ret = 0;
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001033
Daniel Vetter17a38d92015-02-22 12:24:16 +01001034 DRM_DEBUG_ATOMIC("checking %p\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001035
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001036 for_each_plane_in_state(state, plane, plane_state, i) {
1037 ret = drm_atomic_plane_check(plane, plane_state);
Rob Clark5e743732014-12-18 16:01:51 -05001038 if (ret) {
Daniel Vetter17a38d92015-02-22 12:24:16 +01001039 DRM_DEBUG_ATOMIC("[PLANE:%d] atomic core check failed\n",
1040 plane->base.id);
Rob Clark5e743732014-12-18 16:01:51 -05001041 return ret;
1042 }
1043 }
1044
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001045 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1046 ret = drm_atomic_crtc_check(crtc, crtc_state);
Rob Clark5e743732014-12-18 16:01:51 -05001047 if (ret) {
Daniel Vetter17a38d92015-02-22 12:24:16 +01001048 DRM_DEBUG_ATOMIC("[CRTC:%d] atomic core check failed\n",
1049 crtc->base.id);
Rob Clark5e743732014-12-18 16:01:51 -05001050 return ret;
1051 }
1052 }
1053
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001054 if (config->funcs->atomic_check)
Rob Clark5e743732014-12-18 16:01:51 -05001055 ret = config->funcs->atomic_check(state->dev, state);
1056
Rob Clarkd34f20d2014-12-18 16:01:56 -05001057 if (!state->allow_modeset) {
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001058 for_each_crtc_in_state(state, crtc, crtc_state, i) {
Daniel Vettereab3bbe2015-01-22 16:36:21 +01001059 if (crtc_state->mode_changed ||
1060 crtc_state->active_changed) {
Daniel Vetter17a38d92015-02-22 12:24:16 +01001061 DRM_DEBUG_ATOMIC("[CRTC:%d] requires full modeset\n",
1062 crtc->base.id);
Rob Clarkd34f20d2014-12-18 16:01:56 -05001063 return -EINVAL;
1064 }
1065 }
1066 }
1067
Rob Clark5e743732014-12-18 16:01:51 -05001068 return ret;
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001069}
1070EXPORT_SYMBOL(drm_atomic_check_only);
1071
1072/**
1073 * drm_atomic_commit - commit configuration atomically
1074 * @state: atomic configuration to check
1075 *
1076 * Note that this function can return -EDEADLK if the driver needed to acquire
1077 * more locks but encountered a deadlock. The caller must then do the usual w/w
1078 * backoff dance and restart. All other errors are fatal.
1079 *
1080 * Also note that on successful execution ownership of @state is transferred
1081 * from the caller of this function to the function itself. The caller must not
1082 * free or in any other way access @state. If the function fails then the caller
1083 * must clean up @state itself.
1084 *
1085 * Returns:
1086 * 0 on success, negative error code on failure.
1087 */
1088int drm_atomic_commit(struct drm_atomic_state *state)
1089{
1090 struct drm_mode_config *config = &state->dev->mode_config;
1091 int ret;
1092
1093 ret = drm_atomic_check_only(state);
1094 if (ret)
1095 return ret;
1096
Daniel Vetter17a38d92015-02-22 12:24:16 +01001097 DRM_DEBUG_ATOMIC("commiting %p\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001098
1099 return config->funcs->atomic_commit(state->dev, state, false);
1100}
1101EXPORT_SYMBOL(drm_atomic_commit);
1102
1103/**
1104 * drm_atomic_async_commit - atomic&async configuration commit
1105 * @state: atomic configuration to check
1106 *
1107 * Note that this function can return -EDEADLK if the driver needed to acquire
1108 * more locks but encountered a deadlock. The caller must then do the usual w/w
1109 * backoff dance and restart. All other errors are fatal.
1110 *
1111 * Also note that on successful execution ownership of @state is transferred
1112 * from the caller of this function to the function itself. The caller must not
1113 * free or in any other way access @state. If the function fails then the caller
1114 * must clean up @state itself.
1115 *
1116 * Returns:
1117 * 0 on success, negative error code on failure.
1118 */
1119int drm_atomic_async_commit(struct drm_atomic_state *state)
1120{
1121 struct drm_mode_config *config = &state->dev->mode_config;
1122 int ret;
1123
1124 ret = drm_atomic_check_only(state);
1125 if (ret)
1126 return ret;
1127
Daniel Vetter17a38d92015-02-22 12:24:16 +01001128 DRM_DEBUG_ATOMIC("commiting %p asynchronously\n", state);
Daniel Vettercc4ceb42014-07-25 21:30:38 +02001129
1130 return config->funcs->atomic_commit(state->dev, state, true);
1131}
1132EXPORT_SYMBOL(drm_atomic_async_commit);
Rob Clarkd34f20d2014-12-18 16:01:56 -05001133
1134/*
1135 * The big monstor ioctl
1136 */
1137
1138static struct drm_pending_vblank_event *create_vblank_event(
1139 struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data)
1140{
1141 struct drm_pending_vblank_event *e = NULL;
1142 unsigned long flags;
1143
1144 spin_lock_irqsave(&dev->event_lock, flags);
1145 if (file_priv->event_space < sizeof e->event) {
1146 spin_unlock_irqrestore(&dev->event_lock, flags);
1147 goto out;
1148 }
1149 file_priv->event_space -= sizeof e->event;
1150 spin_unlock_irqrestore(&dev->event_lock, flags);
1151
1152 e = kzalloc(sizeof *e, GFP_KERNEL);
1153 if (e == NULL) {
1154 spin_lock_irqsave(&dev->event_lock, flags);
1155 file_priv->event_space += sizeof e->event;
1156 spin_unlock_irqrestore(&dev->event_lock, flags);
1157 goto out;
1158 }
1159
1160 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
1161 e->event.base.length = sizeof e->event;
1162 e->event.user_data = user_data;
1163 e->base.event = &e->event.base;
1164 e->base.file_priv = file_priv;
1165 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
1166
1167out:
1168 return e;
1169}
1170
1171static void destroy_vblank_event(struct drm_device *dev,
1172 struct drm_file *file_priv, struct drm_pending_vblank_event *e)
1173{
1174 unsigned long flags;
1175
1176 spin_lock_irqsave(&dev->event_lock, flags);
1177 file_priv->event_space += sizeof e->event;
1178 spin_unlock_irqrestore(&dev->event_lock, flags);
1179 kfree(e);
1180}
1181
1182static int atomic_set_prop(struct drm_atomic_state *state,
1183 struct drm_mode_object *obj, struct drm_property *prop,
1184 uint64_t prop_value)
1185{
1186 struct drm_mode_object *ref;
1187 int ret;
1188
1189 if (!drm_property_change_valid_get(prop, prop_value, &ref))
1190 return -EINVAL;
1191
1192 switch (obj->type) {
1193 case DRM_MODE_OBJECT_CONNECTOR: {
1194 struct drm_connector *connector = obj_to_connector(obj);
1195 struct drm_connector_state *connector_state;
1196
1197 connector_state = drm_atomic_get_connector_state(state, connector);
1198 if (IS_ERR(connector_state)) {
1199 ret = PTR_ERR(connector_state);
1200 break;
1201 }
1202
1203 ret = drm_atomic_connector_set_property(connector,
1204 connector_state, prop, prop_value);
1205 break;
1206 }
1207 case DRM_MODE_OBJECT_CRTC: {
1208 struct drm_crtc *crtc = obj_to_crtc(obj);
1209 struct drm_crtc_state *crtc_state;
1210
1211 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1212 if (IS_ERR(crtc_state)) {
1213 ret = PTR_ERR(crtc_state);
1214 break;
1215 }
1216
1217 ret = drm_atomic_crtc_set_property(crtc,
1218 crtc_state, prop, prop_value);
1219 break;
1220 }
1221 case DRM_MODE_OBJECT_PLANE: {
1222 struct drm_plane *plane = obj_to_plane(obj);
1223 struct drm_plane_state *plane_state;
1224
1225 plane_state = drm_atomic_get_plane_state(state, plane);
1226 if (IS_ERR(plane_state)) {
1227 ret = PTR_ERR(plane_state);
1228 break;
1229 }
1230
1231 ret = drm_atomic_plane_set_property(plane,
1232 plane_state, prop, prop_value);
1233 break;
1234 }
1235 default:
1236 ret = -EINVAL;
1237 break;
1238 }
1239
1240 drm_property_change_valid_put(prop, ref);
1241 return ret;
1242}
1243
1244int drm_mode_atomic_ioctl(struct drm_device *dev,
1245 void *data, struct drm_file *file_priv)
1246{
1247 struct drm_mode_atomic *arg = data;
1248 uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr);
1249 uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
1250 uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
1251 uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
1252 unsigned int copied_objs, copied_props;
1253 struct drm_atomic_state *state;
1254 struct drm_modeset_acquire_ctx ctx;
1255 struct drm_plane *plane;
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001256 struct drm_crtc *crtc;
1257 struct drm_crtc_state *crtc_state;
Rob Clarkd34f20d2014-12-18 16:01:56 -05001258 unsigned plane_mask = 0;
1259 int ret = 0;
1260 unsigned int i, j;
1261
1262 /* disallow for drivers not supporting atomic: */
1263 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
1264 return -EINVAL;
1265
1266 /* disallow for userspace that has not enabled atomic cap (even
1267 * though this may be a bit overkill, since legacy userspace
1268 * wouldn't know how to call this ioctl)
1269 */
1270 if (!file_priv->atomic)
1271 return -EINVAL;
1272
1273 if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS)
1274 return -EINVAL;
1275
1276 if (arg->reserved)
1277 return -EINVAL;
1278
1279 if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) &&
1280 !dev->mode_config.async_page_flip)
1281 return -EINVAL;
1282
1283 /* can't test and expect an event at the same time. */
1284 if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
1285 (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
1286 return -EINVAL;
1287
1288 drm_modeset_acquire_init(&ctx, 0);
1289
1290 state = drm_atomic_state_alloc(dev);
1291 if (!state)
1292 return -ENOMEM;
1293
1294 state->acquire_ctx = &ctx;
1295 state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
1296
1297retry:
1298 copied_objs = 0;
1299 copied_props = 0;
1300
1301 for (i = 0; i < arg->count_objs; i++) {
1302 uint32_t obj_id, count_props;
1303 struct drm_mode_object *obj;
1304
1305 if (get_user(obj_id, objs_ptr + copied_objs)) {
1306 ret = -EFAULT;
1307 goto fail;
1308 }
1309
1310 obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_ANY);
1311 if (!obj || !obj->properties) {
1312 ret = -ENOENT;
1313 goto fail;
1314 }
1315
1316 if (obj->type == DRM_MODE_OBJECT_PLANE) {
1317 plane = obj_to_plane(obj);
1318 plane_mask |= (1 << drm_plane_index(plane));
1319 plane->old_fb = plane->fb;
1320 }
1321
1322 if (get_user(count_props, count_props_ptr + copied_objs)) {
1323 ret = -EFAULT;
1324 goto fail;
1325 }
1326
1327 copied_objs++;
1328
1329 for (j = 0; j < count_props; j++) {
1330 uint32_t prop_id;
1331 uint64_t prop_value;
1332 struct drm_property *prop;
1333
1334 if (get_user(prop_id, props_ptr + copied_props)) {
1335 ret = -EFAULT;
1336 goto fail;
1337 }
1338
1339 prop = drm_property_find(dev, prop_id);
1340 if (!prop) {
1341 ret = -ENOENT;
1342 goto fail;
1343 }
1344
Guenter Roeck42c58142015-01-12 21:12:17 -08001345 if (copy_from_user(&prop_value,
1346 prop_values_ptr + copied_props,
1347 sizeof(prop_value))) {
Rob Clarkd34f20d2014-12-18 16:01:56 -05001348 ret = -EFAULT;
1349 goto fail;
1350 }
1351
1352 ret = atomic_set_prop(state, obj, prop, prop_value);
1353 if (ret)
1354 goto fail;
1355
1356 copied_props++;
1357 }
1358 }
1359
1360 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001361 for_each_crtc_in_state(state, crtc, crtc_state, i) {
Rob Clarkd34f20d2014-12-18 16:01:56 -05001362 struct drm_pending_vblank_event *e;
1363
Rob Clarkd34f20d2014-12-18 16:01:56 -05001364 e = create_vblank_event(dev, file_priv, arg->user_data);
1365 if (!e) {
1366 ret = -ENOMEM;
1367 goto fail;
1368 }
1369
1370 crtc_state->event = e;
1371 }
1372 }
1373
1374 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
1375 ret = drm_atomic_check_only(state);
1376 /* _check_only() does not free state, unlike _commit() */
1377 drm_atomic_state_free(state);
1378 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
1379 ret = drm_atomic_async_commit(state);
1380 } else {
1381 ret = drm_atomic_commit(state);
1382 }
1383
1384 /* if succeeded, fixup legacy plane crtc/fb ptrs before dropping
1385 * locks (ie. while it is still safe to deref plane->state). We
1386 * need to do this here because the driver entry points cannot
1387 * distinguish between legacy and atomic ioctls.
1388 */
1389 drm_for_each_plane_mask(plane, dev, plane_mask) {
1390 if (ret == 0) {
1391 struct drm_framebuffer *new_fb = plane->state->fb;
1392 if (new_fb)
1393 drm_framebuffer_reference(new_fb);
1394 plane->fb = new_fb;
1395 plane->crtc = plane->state->crtc;
1396 } else {
1397 plane->old_fb = NULL;
1398 }
1399 if (plane->old_fb) {
1400 drm_framebuffer_unreference(plane->old_fb);
1401 plane->old_fb = NULL;
1402 }
1403 }
1404
1405 drm_modeset_drop_locks(&ctx);
1406 drm_modeset_acquire_fini(&ctx);
1407
1408 return ret;
1409
1410fail:
1411 if (ret == -EDEADLK)
1412 goto backoff;
1413
1414 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
Ander Conselvan de Oliveiradf63b992015-04-10 14:58:39 +03001415 for_each_crtc_in_state(state, crtc, crtc_state, i) {
Rob Clarkd34f20d2014-12-18 16:01:56 -05001416 destroy_vblank_event(dev, file_priv, crtc_state->event);
1417 crtc_state->event = NULL;
1418 }
1419 }
1420
1421 drm_atomic_state_free(state);
1422
1423 drm_modeset_drop_locks(&ctx);
1424 drm_modeset_acquire_fini(&ctx);
1425
1426 return ret;
1427
1428backoff:
1429 drm_atomic_state_clear(state);
1430 drm_modeset_backoff(&ctx);
1431
1432 goto retry;
1433}