Branch data Line data Source code
1 : : /*
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 <linux/sync_file.h>
30 : :
31 : : #include <drm/drm_atomic.h>
32 : : #include <drm/drm_atomic_uapi.h>
33 : : #include <drm/drm_debugfs.h>
34 : : #include <drm/drm_device.h>
35 : : #include <drm/drm_drv.h>
36 : : #include <drm/drm_file.h>
37 : : #include <drm/drm_fourcc.h>
38 : : #include <drm/drm_mode.h>
39 : : #include <drm/drm_print.h>
40 : : #include <drm/drm_writeback.h>
41 : :
42 : : #include "drm_crtc_internal.h"
43 : : #include "drm_internal.h"
44 : :
45 : 0 : void __drm_crtc_commit_free(struct kref *kref)
46 : : {
47 : 0 : struct drm_crtc_commit *commit =
48 : 0 : container_of(kref, struct drm_crtc_commit, ref);
49 : :
50 : 0 : kfree(commit);
51 : 0 : }
52 : : EXPORT_SYMBOL(__drm_crtc_commit_free);
53 : :
54 : : /**
55 : : * drm_atomic_state_default_release -
56 : : * release memory initialized by drm_atomic_state_init
57 : : * @state: atomic state
58 : : *
59 : : * Free all the memory allocated by drm_atomic_state_init.
60 : : * This should only be used by drivers which are still subclassing
61 : : * &drm_atomic_state and haven't switched to &drm_private_state yet.
62 : : */
63 : 0 : void drm_atomic_state_default_release(struct drm_atomic_state *state)
64 : : {
65 : 0 : kfree(state->connectors);
66 : 0 : kfree(state->crtcs);
67 : 0 : kfree(state->planes);
68 : 0 : kfree(state->private_objs);
69 : 0 : }
70 : : EXPORT_SYMBOL(drm_atomic_state_default_release);
71 : :
72 : : /**
73 : : * drm_atomic_state_init - init new atomic state
74 : : * @dev: DRM device
75 : : * @state: atomic state
76 : : *
77 : : * Default implementation for filling in a new atomic state.
78 : : * This should only be used by drivers which are still subclassing
79 : : * &drm_atomic_state and haven't switched to &drm_private_state yet.
80 : : */
81 : : int
82 : 0 : drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
83 : : {
84 : 0 : kref_init(&state->ref);
85 : :
86 : : /* TODO legacy paths should maybe do a better job about
87 : : * setting this appropriately?
88 : : */
89 : 0 : state->allow_modeset = true;
90 : :
91 : 0 : state->crtcs = kcalloc(dev->mode_config.num_crtc,
92 : : sizeof(*state->crtcs), GFP_KERNEL);
93 [ # # ]: 0 : if (!state->crtcs)
94 : 0 : goto fail;
95 : 0 : state->planes = kcalloc(dev->mode_config.num_total_plane,
96 : : sizeof(*state->planes), GFP_KERNEL);
97 [ # # ]: 0 : if (!state->planes)
98 : 0 : goto fail;
99 : :
100 : 0 : state->dev = dev;
101 : :
102 : 0 : DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
103 : :
104 : 0 : return 0;
105 : 0 : fail:
106 : 0 : drm_atomic_state_default_release(state);
107 : 0 : return -ENOMEM;
108 : : }
109 : : EXPORT_SYMBOL(drm_atomic_state_init);
110 : :
111 : : /**
112 : : * drm_atomic_state_alloc - allocate atomic state
113 : : * @dev: DRM device
114 : : *
115 : : * This allocates an empty atomic state to track updates.
116 : : */
117 : : struct drm_atomic_state *
118 : 0 : drm_atomic_state_alloc(struct drm_device *dev)
119 : : {
120 : 0 : struct drm_mode_config *config = &dev->mode_config;
121 : :
122 [ # # ]: 0 : if (!config->funcs->atomic_state_alloc) {
123 : 0 : struct drm_atomic_state *state;
124 : :
125 : 0 : state = kzalloc(sizeof(*state), GFP_KERNEL);
126 [ # # ]: 0 : if (!state)
127 : : return NULL;
128 [ # # ]: 0 : if (drm_atomic_state_init(dev, state) < 0) {
129 : 0 : kfree(state);
130 : 0 : return NULL;
131 : : }
132 : : return state;
133 : : }
134 : :
135 : 0 : return config->funcs->atomic_state_alloc(dev);
136 : : }
137 : : EXPORT_SYMBOL(drm_atomic_state_alloc);
138 : :
139 : : /**
140 : : * drm_atomic_state_default_clear - clear base atomic state
141 : : * @state: atomic state
142 : : *
143 : : * Default implementation for clearing atomic state.
144 : : * This should only be used by drivers which are still subclassing
145 : : * &drm_atomic_state and haven't switched to &drm_private_state yet.
146 : : */
147 : 0 : void drm_atomic_state_default_clear(struct drm_atomic_state *state)
148 : : {
149 : 0 : struct drm_device *dev = state->dev;
150 : 0 : struct drm_mode_config *config = &dev->mode_config;
151 : 0 : int i;
152 : :
153 : 0 : DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
154 : :
155 [ # # ]: 0 : for (i = 0; i < state->num_connector; i++) {
156 : 0 : struct drm_connector *connector = state->connectors[i].ptr;
157 : :
158 [ # # ]: 0 : if (!connector)
159 : 0 : continue;
160 : :
161 : 0 : connector->funcs->atomic_destroy_state(connector,
162 : : state->connectors[i].state);
163 : 0 : state->connectors[i].ptr = NULL;
164 : 0 : state->connectors[i].state = NULL;
165 : 0 : state->connectors[i].old_state = NULL;
166 : 0 : state->connectors[i].new_state = NULL;
167 : 0 : drm_connector_put(connector);
168 : : }
169 : :
170 [ # # ]: 0 : for (i = 0; i < config->num_crtc; i++) {
171 : 0 : struct drm_crtc *crtc = state->crtcs[i].ptr;
172 : :
173 [ # # ]: 0 : if (!crtc)
174 : 0 : continue;
175 : :
176 : 0 : crtc->funcs->atomic_destroy_state(crtc,
177 : : state->crtcs[i].state);
178 : :
179 : 0 : state->crtcs[i].ptr = NULL;
180 : 0 : state->crtcs[i].state = NULL;
181 : 0 : state->crtcs[i].old_state = NULL;
182 : 0 : state->crtcs[i].new_state = NULL;
183 : :
184 [ # # ]: 0 : if (state->crtcs[i].commit) {
185 : 0 : drm_crtc_commit_put(state->crtcs[i].commit);
186 : 0 : state->crtcs[i].commit = NULL;
187 : : }
188 : : }
189 : :
190 [ # # ]: 0 : for (i = 0; i < config->num_total_plane; i++) {
191 : 0 : struct drm_plane *plane = state->planes[i].ptr;
192 : :
193 [ # # ]: 0 : if (!plane)
194 : 0 : continue;
195 : :
196 : 0 : plane->funcs->atomic_destroy_state(plane,
197 : : state->planes[i].state);
198 : 0 : state->planes[i].ptr = NULL;
199 : 0 : state->planes[i].state = NULL;
200 : 0 : state->planes[i].old_state = NULL;
201 : 0 : state->planes[i].new_state = NULL;
202 : : }
203 : :
204 [ # # ]: 0 : for (i = 0; i < state->num_private_objs; i++) {
205 : 0 : struct drm_private_obj *obj = state->private_objs[i].ptr;
206 : :
207 : 0 : obj->funcs->atomic_destroy_state(obj,
208 : : state->private_objs[i].state);
209 : 0 : state->private_objs[i].ptr = NULL;
210 : 0 : state->private_objs[i].state = NULL;
211 : 0 : state->private_objs[i].old_state = NULL;
212 : 0 : state->private_objs[i].new_state = NULL;
213 : : }
214 : 0 : state->num_private_objs = 0;
215 : :
216 [ # # ]: 0 : if (state->fake_commit) {
217 : 0 : drm_crtc_commit_put(state->fake_commit);
218 : 0 : state->fake_commit = NULL;
219 : : }
220 : 0 : }
221 : : EXPORT_SYMBOL(drm_atomic_state_default_clear);
222 : :
223 : : /**
224 : : * drm_atomic_state_clear - clear state object
225 : : * @state: atomic state
226 : : *
227 : : * When the w/w mutex algorithm detects a deadlock we need to back off and drop
228 : : * all locks. So someone else could sneak in and change the current modeset
229 : : * configuration. Which means that all the state assembled in @state is no
230 : : * longer an atomic update to the current state, but to some arbitrary earlier
231 : : * state. Which could break assumptions the driver's
232 : : * &drm_mode_config_funcs.atomic_check likely relies on.
233 : : *
234 : : * Hence we must clear all cached state and completely start over, using this
235 : : * function.
236 : : */
237 : 0 : void drm_atomic_state_clear(struct drm_atomic_state *state)
238 : : {
239 : 0 : struct drm_device *dev = state->dev;
240 : 0 : struct drm_mode_config *config = &dev->mode_config;
241 : :
242 [ # # ]: 0 : if (config->funcs->atomic_state_clear)
243 : 0 : config->funcs->atomic_state_clear(state);
244 : : else
245 : 0 : drm_atomic_state_default_clear(state);
246 : 0 : }
247 : : EXPORT_SYMBOL(drm_atomic_state_clear);
248 : :
249 : : /**
250 : : * __drm_atomic_state_free - free all memory for an atomic state
251 : : * @ref: This atomic state to deallocate
252 : : *
253 : : * This frees all memory associated with an atomic state, including all the
254 : : * per-object state for planes, CRTCs and connectors.
255 : : */
256 : 0 : void __drm_atomic_state_free(struct kref *ref)
257 : : {
258 : 0 : struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
259 : 0 : struct drm_mode_config *config = &state->dev->mode_config;
260 : :
261 : 0 : drm_atomic_state_clear(state);
262 : :
263 : 0 : DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
264 : :
265 [ # # ]: 0 : if (config->funcs->atomic_state_free) {
266 : 0 : config->funcs->atomic_state_free(state);
267 : : } else {
268 : 0 : drm_atomic_state_default_release(state);
269 : 0 : kfree(state);
270 : : }
271 : 0 : }
272 : : EXPORT_SYMBOL(__drm_atomic_state_free);
273 : :
274 : : /**
275 : : * drm_atomic_get_crtc_state - get CRTC state
276 : : * @state: global atomic state object
277 : : * @crtc: CRTC to get state object for
278 : : *
279 : : * This function returns the CRTC state for the given CRTC, allocating it if
280 : : * needed. It will also grab the relevant CRTC lock to make sure that the state
281 : : * is consistent.
282 : : *
283 : : * Returns:
284 : : *
285 : : * Either the allocated state or the error code encoded into the pointer. When
286 : : * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
287 : : * entire atomic sequence must be restarted. All other errors are fatal.
288 : : */
289 : : struct drm_crtc_state *
290 : 0 : drm_atomic_get_crtc_state(struct drm_atomic_state *state,
291 : : struct drm_crtc *crtc)
292 : : {
293 [ # # ]: 0 : int ret, index = drm_crtc_index(crtc);
294 : 0 : struct drm_crtc_state *crtc_state;
295 : :
296 [ # # ]: 0 : WARN_ON(!state->acquire_ctx);
297 : :
298 [ # # ]: 0 : crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
299 [ # # ]: 0 : if (crtc_state)
300 : : return crtc_state;
301 : :
302 : 0 : ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
303 [ # # ]: 0 : if (ret)
304 : 0 : return ERR_PTR(ret);
305 : :
306 : 0 : crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
307 [ # # ]: 0 : if (!crtc_state)
308 : : return ERR_PTR(-ENOMEM);
309 : :
310 : 0 : state->crtcs[index].state = crtc_state;
311 : 0 : state->crtcs[index].old_state = crtc->state;
312 : 0 : state->crtcs[index].new_state = crtc_state;
313 : 0 : state->crtcs[index].ptr = crtc;
314 : 0 : crtc_state->state = state;
315 : :
316 : 0 : DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
317 : : crtc->base.id, crtc->name, crtc_state, state);
318 : :
319 : 0 : return crtc_state;
320 : : }
321 : : EXPORT_SYMBOL(drm_atomic_get_crtc_state);
322 : :
323 : : static int drm_atomic_crtc_check(const struct drm_crtc_state *old_crtc_state,
324 : : const struct drm_crtc_state *new_crtc_state)
325 : : {
326 : : struct drm_crtc *crtc = new_crtc_state->crtc;
327 : :
328 : : /* NOTE: we explicitly don't enforce constraints such as primary
329 : : * layer covering entire screen, since that is something we want
330 : : * to allow (on hw that supports it). For hw that does not, it
331 : : * should be checked in driver's crtc->atomic_check() vfunc.
332 : : *
333 : : * TODO: Add generic modeset state checks once we support those.
334 : : */
335 : :
336 : : if (new_crtc_state->active && !new_crtc_state->enable) {
337 : : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
338 : : crtc->base.id, crtc->name);
339 : : return -EINVAL;
340 : : }
341 : :
342 : : /* The state->enable vs. state->mode_blob checks can be WARN_ON,
343 : : * as this is a kernel-internal detail that userspace should never
344 : : * be able to trigger. */
345 : : if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
346 : : WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) {
347 : : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
348 : : crtc->base.id, crtc->name);
349 : : return -EINVAL;
350 : : }
351 : :
352 : : if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
353 : : WARN_ON(!new_crtc_state->enable && new_crtc_state->mode_blob)) {
354 : : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
355 : : crtc->base.id, crtc->name);
356 : : return -EINVAL;
357 : : }
358 : :
359 : : /*
360 : : * Reject event generation for when a CRTC is off and stays off.
361 : : * It wouldn't be hard to implement this, but userspace has a track
362 : : * record of happily burning through 100% cpu (or worse, crash) when the
363 : : * display pipe is suspended. To avoid all that fun just reject updates
364 : : * that ask for events since likely that indicates a bug in the
365 : : * compositor's drawing loop. This is consistent with the vblank IOCTL
366 : : * and legacy page_flip IOCTL which also reject service on a disabled
367 : : * pipe.
368 : : */
369 : : if (new_crtc_state->event &&
370 : : !new_crtc_state->active && !old_crtc_state->active) {
371 : : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n",
372 : : crtc->base.id, crtc->name);
373 : : return -EINVAL;
374 : : }
375 : :
376 : : return 0;
377 : : }
378 : :
379 : 0 : static void drm_atomic_crtc_print_state(struct drm_printer *p,
380 : : const struct drm_crtc_state *state)
381 : : {
382 : 0 : struct drm_crtc *crtc = state->crtc;
383 : :
384 : 0 : drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
385 : 0 : drm_printf(p, "\tenable=%d\n", state->enable);
386 : 0 : drm_printf(p, "\tactive=%d\n", state->active);
387 : 0 : drm_printf(p, "\tself_refresh_active=%d\n", state->self_refresh_active);
388 : 0 : drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
389 : 0 : drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
390 : 0 : drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
391 : 0 : drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
392 : 0 : drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
393 : 0 : drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
394 : 0 : drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
395 : 0 : drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
396 : 0 : drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
397 : :
398 [ # # ]: 0 : if (crtc->funcs->atomic_print_state)
399 : 0 : crtc->funcs->atomic_print_state(p, state);
400 : 0 : }
401 : :
402 : 0 : static int drm_atomic_connector_check(struct drm_connector *connector,
403 : : struct drm_connector_state *state)
404 : : {
405 : 0 : struct drm_crtc_state *crtc_state;
406 : 0 : struct drm_writeback_job *writeback_job = state->writeback_job;
407 : 0 : const struct drm_display_info *info = &connector->display_info;
408 : :
409 [ # # ]: 0 : state->max_bpc = info->bpc ? info->bpc : 8;
410 [ # # ]: 0 : if (connector->max_bpc_property)
411 : 0 : state->max_bpc = min(state->max_bpc, state->max_requested_bpc);
412 : :
413 [ # # # # ]: 0 : if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
414 : : return 0;
415 : :
416 [ # # # # ]: 0 : if (writeback_job->fb && !state->crtc) {
417 : 0 : DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
418 : : connector->base.id, connector->name);
419 : 0 : return -EINVAL;
420 : : }
421 : :
422 [ # # ]: 0 : if (state->crtc)
423 : 0 : crtc_state = drm_atomic_get_existing_crtc_state(state->state,
424 : : state->crtc);
425 : :
426 [ # # # # ]: 0 : if (writeback_job->fb && !crtc_state->active) {
427 : 0 : DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n",
428 : : connector->base.id, connector->name,
429 : : state->crtc->base.id);
430 : 0 : return -EINVAL;
431 : : }
432 : :
433 [ # # ]: 0 : if (!writeback_job->fb) {
434 [ # # ]: 0 : if (writeback_job->out_fence) {
435 : 0 : DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
436 : : connector->base.id, connector->name);
437 : 0 : return -EINVAL;
438 : : }
439 : :
440 : 0 : drm_writeback_cleanup_job(writeback_job);
441 : 0 : state->writeback_job = NULL;
442 : : }
443 : :
444 : : return 0;
445 : : }
446 : :
447 : : /**
448 : : * drm_atomic_get_plane_state - get plane state
449 : : * @state: global atomic state object
450 : : * @plane: plane to get state object for
451 : : *
452 : : * This function returns the plane state for the given plane, allocating it if
453 : : * needed. It will also grab the relevant plane lock to make sure that the state
454 : : * is consistent.
455 : : *
456 : : * Returns:
457 : : *
458 : : * Either the allocated state or the error code encoded into the pointer. When
459 : : * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
460 : : * entire atomic sequence must be restarted. All other errors are fatal.
461 : : */
462 : : struct drm_plane_state *
463 : 0 : drm_atomic_get_plane_state(struct drm_atomic_state *state,
464 : : struct drm_plane *plane)
465 : : {
466 [ # # ]: 0 : int ret, index = drm_plane_index(plane);
467 : 0 : struct drm_plane_state *plane_state;
468 : :
469 [ # # ]: 0 : WARN_ON(!state->acquire_ctx);
470 : :
471 : : /* the legacy pointers should never be set */
472 [ # # ]: 0 : WARN_ON(plane->fb);
473 [ # # ]: 0 : WARN_ON(plane->old_fb);
474 [ # # ]: 0 : WARN_ON(plane->crtc);
475 : :
476 [ # # ]: 0 : plane_state = drm_atomic_get_existing_plane_state(state, plane);
477 [ # # ]: 0 : if (plane_state)
478 : : return plane_state;
479 : :
480 : 0 : ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
481 [ # # ]: 0 : if (ret)
482 : 0 : return ERR_PTR(ret);
483 : :
484 : 0 : plane_state = plane->funcs->atomic_duplicate_state(plane);
485 [ # # ]: 0 : if (!plane_state)
486 : : return ERR_PTR(-ENOMEM);
487 : :
488 : 0 : state->planes[index].state = plane_state;
489 : 0 : state->planes[index].ptr = plane;
490 : 0 : state->planes[index].old_state = plane->state;
491 : 0 : state->planes[index].new_state = plane_state;
492 : 0 : plane_state->state = state;
493 : :
494 : 0 : DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
495 : : plane->base.id, plane->name, plane_state, state);
496 : :
497 [ # # ]: 0 : if (plane_state->crtc) {
498 : 0 : struct drm_crtc_state *crtc_state;
499 : :
500 : 0 : crtc_state = drm_atomic_get_crtc_state(state,
501 : : plane_state->crtc);
502 [ # # ]: 0 : if (IS_ERR(crtc_state))
503 : 0 : return ERR_CAST(crtc_state);
504 : : }
505 : :
506 : : return plane_state;
507 : : }
508 : : EXPORT_SYMBOL(drm_atomic_get_plane_state);
509 : :
510 : : static bool
511 : 0 : plane_switching_crtc(const struct drm_plane_state *old_plane_state,
512 : : const struct drm_plane_state *new_plane_state)
513 : : {
514 [ # # ]: 0 : if (!old_plane_state->crtc || !new_plane_state->crtc)
515 : : return false;
516 : :
517 [ # # ]: 0 : if (old_plane_state->crtc == new_plane_state->crtc)
518 : : return false;
519 : :
520 : : /* This could be refined, but currently there's no helper or driver code
521 : : * to implement direct switching of active planes nor userspace to take
522 : : * advantage of more direct plane switching without the intermediate
523 : : * full OFF state.
524 : : */
525 : : return true;
526 : : }
527 : :
528 : : /**
529 : : * drm_atomic_plane_check - check plane state
530 : : * @old_plane_state: old plane state to check
531 : : * @new_plane_state: new plane state to check
532 : : *
533 : : * Provides core sanity checks for plane state.
534 : : *
535 : : * RETURNS:
536 : : * Zero on success, error code on failure
537 : : */
538 : 0 : static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
539 : : const struct drm_plane_state *new_plane_state)
540 : : {
541 : 0 : struct drm_plane *plane = new_plane_state->plane;
542 : 0 : struct drm_crtc *crtc = new_plane_state->crtc;
543 : 0 : const struct drm_framebuffer *fb = new_plane_state->fb;
544 : 0 : unsigned int fb_width, fb_height;
545 : 0 : struct drm_mode_rect *clips;
546 : 0 : uint32_t num_clips;
547 : 0 : int ret;
548 : :
549 : : /* either *both* CRTC and FB must be set, or neither */
550 [ # # ]: 0 : if (crtc && !fb) {
551 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n",
552 : : plane->base.id, plane->name);
553 : 0 : return -EINVAL;
554 [ # # ]: 0 : } else if (fb && !crtc) {
555 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n",
556 : : plane->base.id, plane->name);
557 : 0 : return -EINVAL;
558 : : }
559 : :
560 : : /* if disabled, we don't care about the rest of the state: */
561 [ # # ]: 0 : if (!crtc)
562 : : return 0;
563 : :
564 : : /* Check whether this plane is usable on this CRTC */
565 [ # # ]: 0 : if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
566 : 0 : DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
567 : : crtc->base.id, crtc->name,
568 : : plane->base.id, plane->name);
569 : 0 : return -EINVAL;
570 : : }
571 : :
572 : : /* Check whether this plane supports the fb pixel format. */
573 : 0 : ret = drm_plane_check_pixel_format(plane, fb->format->format,
574 : : fb->modifier);
575 [ # # ]: 0 : if (ret) {
576 : 0 : struct drm_format_name_buf format_name;
577 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n",
578 : : plane->base.id, plane->name,
579 : : drm_get_format_name(fb->format->format,
580 : : &format_name),
581 : : fb->modifier);
582 : 0 : return ret;
583 : : }
584 : :
585 : : /* Give drivers some help against integer overflows */
586 [ # # ]: 0 : if (new_plane_state->crtc_w > INT_MAX ||
587 [ # # ]: 0 : new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
588 [ # # ]: 0 : new_plane_state->crtc_h > INT_MAX ||
589 [ # # ]: 0 : new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) {
590 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
591 : : plane->base.id, plane->name,
592 : : new_plane_state->crtc_w, new_plane_state->crtc_h,
593 : : new_plane_state->crtc_x, new_plane_state->crtc_y);
594 : 0 : return -ERANGE;
595 : : }
596 : :
597 : 0 : fb_width = fb->width << 16;
598 : 0 : fb_height = fb->height << 16;
599 : :
600 : : /* Make sure source coordinates are inside the fb. */
601 [ # # ]: 0 : if (new_plane_state->src_w > fb_width ||
602 [ # # ]: 0 : new_plane_state->src_x > fb_width - new_plane_state->src_w ||
603 [ # # ]: 0 : new_plane_state->src_h > fb_height ||
604 [ # # ]: 0 : new_plane_state->src_y > fb_height - new_plane_state->src_h) {
605 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates "
606 : : "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
607 : : plane->base.id, plane->name,
608 : : new_plane_state->src_w >> 16,
609 : : ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
610 : : new_plane_state->src_h >> 16,
611 : : ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
612 : : new_plane_state->src_x >> 16,
613 : : ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
614 : : new_plane_state->src_y >> 16,
615 : : ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
616 : : fb->width, fb->height);
617 : 0 : return -ENOSPC;
618 : : }
619 : :
620 [ # # ]: 0 : clips = drm_plane_get_damage_clips(new_plane_state);
621 [ # # ]: 0 : num_clips = drm_plane_get_damage_clips_count(new_plane_state);
622 : :
623 : : /* Make sure damage clips are valid and inside the fb. */
624 [ # # ]: 0 : while (num_clips > 0) {
625 [ # # ]: 0 : if (clips->x1 >= clips->x2 ||
626 [ # # # # ]: 0 : clips->y1 >= clips->y2 ||
627 [ # # ]: 0 : clips->x1 < 0 ||
628 : 0 : clips->y1 < 0 ||
629 [ # # ]: 0 : clips->x2 > fb_width ||
630 [ # # ]: 0 : clips->y2 > fb_height) {
631 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
632 : : plane->base.id, plane->name, clips->x1,
633 : : clips->y1, clips->x2, clips->y2);
634 : 0 : return -EINVAL;
635 : : }
636 : 0 : clips++;
637 : 0 : num_clips--;
638 : : }
639 : :
640 [ # # ]: 0 : if (plane_switching_crtc(old_plane_state, new_plane_state)) {
641 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
642 : : plane->base.id, plane->name);
643 : 0 : return -EINVAL;
644 : : }
645 : :
646 : : return 0;
647 : : }
648 : :
649 : 0 : static void drm_atomic_plane_print_state(struct drm_printer *p,
650 : : const struct drm_plane_state *state)
651 : : {
652 : 0 : struct drm_plane *plane = state->plane;
653 : 0 : struct drm_rect src = drm_plane_state_src(state);
654 : 0 : struct drm_rect dest = drm_plane_state_dest(state);
655 : :
656 : 0 : drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
657 [ # # ]: 0 : drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
658 [ # # ]: 0 : drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
659 [ # # ]: 0 : if (state->fb)
660 : 0 : drm_framebuffer_print_info(p, 2, state->fb);
661 : 0 : drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
662 : 0 : drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
663 : 0 : drm_printf(p, "\trotation=%x\n", state->rotation);
664 : 0 : drm_printf(p, "\tnormalized-zpos=%x\n", state->normalized_zpos);
665 : 0 : drm_printf(p, "\tcolor-encoding=%s\n",
666 : : drm_get_color_encoding_name(state->color_encoding));
667 : 0 : drm_printf(p, "\tcolor-range=%s\n",
668 : : drm_get_color_range_name(state->color_range));
669 : :
670 [ # # ]: 0 : if (plane->funcs->atomic_print_state)
671 : 0 : plane->funcs->atomic_print_state(p, state);
672 : 0 : }
673 : :
674 : : /**
675 : : * DOC: handling driver private state
676 : : *
677 : : * Very often the DRM objects exposed to userspace in the atomic modeset api
678 : : * (&drm_connector, &drm_crtc and &drm_plane) do not map neatly to the
679 : : * underlying hardware. Especially for any kind of shared resources (e.g. shared
680 : : * clocks, scaler units, bandwidth and fifo limits shared among a group of
681 : : * planes or CRTCs, and so on) it makes sense to model these as independent
682 : : * objects. Drivers then need to do similar state tracking and commit ordering for
683 : : * such private (since not exposed to userpace) objects as the atomic core and
684 : : * helpers already provide for connectors, planes and CRTCs.
685 : : *
686 : : * To make this easier on drivers the atomic core provides some support to track
687 : : * driver private state objects using struct &drm_private_obj, with the
688 : : * associated state struct &drm_private_state.
689 : : *
690 : : * Similar to userspace-exposed objects, private state structures can be
691 : : * acquired by calling drm_atomic_get_private_obj_state(). This also takes care
692 : : * of locking, hence drivers should not have a need to call drm_modeset_lock()
693 : : * directly. Sequence of the actual hardware state commit is not handled,
694 : : * drivers might need to keep track of struct drm_crtc_commit within subclassed
695 : : * structure of &drm_private_state as necessary, e.g. similar to
696 : : * &drm_plane_state.commit. See also &drm_atomic_state.fake_commit.
697 : : *
698 : : * All private state structures contained in a &drm_atomic_state update can be
699 : : * iterated using for_each_oldnew_private_obj_in_state(),
700 : : * for_each_new_private_obj_in_state() and for_each_old_private_obj_in_state().
701 : : * Drivers are recommended to wrap these for each type of driver private state
702 : : * object they have, filtering on &drm_private_obj.funcs using for_each_if(), at
703 : : * least if they want to iterate over all objects of a given type.
704 : : *
705 : : * An earlier way to handle driver private state was by subclassing struct
706 : : * &drm_atomic_state. But since that encourages non-standard ways to implement
707 : : * the check/commit split atomic requires (by using e.g. "check and rollback or
708 : : * commit instead" of "duplicate state, check, then either commit or release
709 : : * duplicated state) it is deprecated in favour of using &drm_private_state.
710 : : */
711 : :
712 : : /**
713 : : * drm_atomic_private_obj_init - initialize private object
714 : : * @dev: DRM device this object will be attached to
715 : : * @obj: private object
716 : : * @state: initial private object state
717 : : * @funcs: pointer to the struct of function pointers that identify the object
718 : : * type
719 : : *
720 : : * Initialize the private object, which can be embedded into any
721 : : * driver private object that needs its own atomic state.
722 : : */
723 : : void
724 : 0 : drm_atomic_private_obj_init(struct drm_device *dev,
725 : : struct drm_private_obj *obj,
726 : : struct drm_private_state *state,
727 : : const struct drm_private_state_funcs *funcs)
728 : : {
729 : 0 : memset(obj, 0, sizeof(*obj));
730 : :
731 : 0 : drm_modeset_lock_init(&obj->lock);
732 : :
733 : 0 : obj->state = state;
734 : 0 : obj->funcs = funcs;
735 : 0 : list_add_tail(&obj->head, &dev->mode_config.privobj_list);
736 : 0 : }
737 : : EXPORT_SYMBOL(drm_atomic_private_obj_init);
738 : :
739 : : /**
740 : : * drm_atomic_private_obj_fini - finalize private object
741 : : * @obj: private object
742 : : *
743 : : * Finalize the private object.
744 : : */
745 : : void
746 : 0 : drm_atomic_private_obj_fini(struct drm_private_obj *obj)
747 : : {
748 : 0 : list_del(&obj->head);
749 : 0 : obj->funcs->atomic_destroy_state(obj, obj->state);
750 [ # # ]: 0 : drm_modeset_lock_fini(&obj->lock);
751 : 0 : }
752 : : EXPORT_SYMBOL(drm_atomic_private_obj_fini);
753 : :
754 : : /**
755 : : * drm_atomic_get_private_obj_state - get private object state
756 : : * @state: global atomic state
757 : : * @obj: private object to get the state for
758 : : *
759 : : * This function returns the private object state for the given private object,
760 : : * allocating the state if needed. It will also grab the relevant private
761 : : * object lock to make sure that the state is consistent.
762 : : *
763 : : * RETURNS:
764 : : *
765 : : * Either the allocated state or the error code encoded into a pointer.
766 : : */
767 : : struct drm_private_state *
768 : 0 : drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
769 : : struct drm_private_obj *obj)
770 : : {
771 : 0 : int index, num_objs, i, ret;
772 : 0 : size_t size;
773 : 0 : struct __drm_private_objs_state *arr;
774 : 0 : struct drm_private_state *obj_state;
775 : :
776 [ # # ]: 0 : for (i = 0; i < state->num_private_objs; i++)
777 [ # # ]: 0 : if (obj == state->private_objs[i].ptr)
778 : 0 : return state->private_objs[i].state;
779 : :
780 : 0 : ret = drm_modeset_lock(&obj->lock, state->acquire_ctx);
781 [ # # ]: 0 : if (ret)
782 : 0 : return ERR_PTR(ret);
783 : :
784 : 0 : num_objs = state->num_private_objs + 1;
785 : 0 : size = sizeof(*state->private_objs) * num_objs;
786 : 0 : arr = krealloc(state->private_objs, size, GFP_KERNEL);
787 [ # # ]: 0 : if (!arr)
788 : : return ERR_PTR(-ENOMEM);
789 : :
790 : 0 : state->private_objs = arr;
791 : 0 : index = state->num_private_objs;
792 : 0 : memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
793 : :
794 : 0 : obj_state = obj->funcs->atomic_duplicate_state(obj);
795 [ # # ]: 0 : if (!obj_state)
796 : : return ERR_PTR(-ENOMEM);
797 : :
798 : 0 : state->private_objs[index].state = obj_state;
799 : 0 : state->private_objs[index].old_state = obj->state;
800 : 0 : state->private_objs[index].new_state = obj_state;
801 : 0 : state->private_objs[index].ptr = obj;
802 : 0 : obj_state->state = state;
803 : :
804 : 0 : state->num_private_objs = num_objs;
805 : :
806 : 0 : DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
807 : : obj, obj_state, state);
808 : :
809 : 0 : return obj_state;
810 : : }
811 : : EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
812 : :
813 : : /**
814 : : * drm_atomic_get_old_private_obj_state
815 : : * @state: global atomic state object
816 : : * @obj: private_obj to grab
817 : : *
818 : : * This function returns the old private object state for the given private_obj,
819 : : * or NULL if the private_obj is not part of the global atomic state.
820 : : */
821 : : struct drm_private_state *
822 : 0 : drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state,
823 : : struct drm_private_obj *obj)
824 : : {
825 : 0 : int i;
826 : :
827 [ # # ]: 0 : for (i = 0; i < state->num_private_objs; i++)
828 [ # # ]: 0 : if (obj == state->private_objs[i].ptr)
829 : 0 : return state->private_objs[i].old_state;
830 : :
831 : : return NULL;
832 : : }
833 : : EXPORT_SYMBOL(drm_atomic_get_old_private_obj_state);
834 : :
835 : : /**
836 : : * drm_atomic_get_new_private_obj_state
837 : : * @state: global atomic state object
838 : : * @obj: private_obj to grab
839 : : *
840 : : * This function returns the new private object state for the given private_obj,
841 : : * or NULL if the private_obj is not part of the global atomic state.
842 : : */
843 : : struct drm_private_state *
844 : 0 : drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state,
845 : : struct drm_private_obj *obj)
846 : : {
847 : 0 : int i;
848 : :
849 [ # # ]: 0 : for (i = 0; i < state->num_private_objs; i++)
850 [ # # ]: 0 : if (obj == state->private_objs[i].ptr)
851 : 0 : return state->private_objs[i].new_state;
852 : :
853 : : return NULL;
854 : : }
855 : : EXPORT_SYMBOL(drm_atomic_get_new_private_obj_state);
856 : :
857 : : /**
858 : : * drm_atomic_get_old_connector_for_encoder - Get old connector for an encoder
859 : : * @state: Atomic state
860 : : * @encoder: The encoder to fetch the connector state for
861 : : *
862 : : * This function finds and returns the connector that was connected to @encoder
863 : : * as specified by the @state.
864 : : *
865 : : * If there is no connector in @state which previously had @encoder connected to
866 : : * it, this function will return NULL. While this may seem like an invalid use
867 : : * case, it is sometimes useful to differentiate commits which had no prior
868 : : * connectors attached to @encoder vs ones that did (and to inspect their
869 : : * state). This is especially true in enable hooks because the pipeline has
870 : : * changed.
871 : : *
872 : : * Returns: The old connector connected to @encoder, or NULL if the encoder is
873 : : * not connected.
874 : : */
875 : : struct drm_connector *
876 : 0 : drm_atomic_get_old_connector_for_encoder(struct drm_atomic_state *state,
877 : : struct drm_encoder *encoder)
878 : : {
879 : 0 : struct drm_connector_state *conn_state;
880 : 0 : struct drm_connector *connector;
881 : 0 : unsigned int i;
882 : :
883 [ # # # # ]: 0 : for_each_old_connector_in_state(state, connector, conn_state, i) {
884 [ # # ]: 0 : if (conn_state->best_encoder == encoder)
885 : 0 : return connector;
886 : : }
887 : :
888 : : return NULL;
889 : : }
890 : : EXPORT_SYMBOL(drm_atomic_get_old_connector_for_encoder);
891 : :
892 : : /**
893 : : * drm_atomic_get_new_connector_for_encoder - Get new connector for an encoder
894 : : * @state: Atomic state
895 : : * @encoder: The encoder to fetch the connector state for
896 : : *
897 : : * This function finds and returns the connector that will be connected to
898 : : * @encoder as specified by the @state.
899 : : *
900 : : * If there is no connector in @state which will have @encoder connected to it,
901 : : * this function will return NULL. While this may seem like an invalid use case,
902 : : * it is sometimes useful to differentiate commits which have no connectors
903 : : * attached to @encoder vs ones that do (and to inspect their state). This is
904 : : * especially true in disable hooks because the pipeline will change.
905 : : *
906 : : * Returns: The new connector connected to @encoder, or NULL if the encoder is
907 : : * not connected.
908 : : */
909 : : struct drm_connector *
910 : 0 : drm_atomic_get_new_connector_for_encoder(struct drm_atomic_state *state,
911 : : struct drm_encoder *encoder)
912 : : {
913 : 0 : struct drm_connector_state *conn_state;
914 : 0 : struct drm_connector *connector;
915 : 0 : unsigned int i;
916 : :
917 [ # # # # ]: 0 : for_each_new_connector_in_state(state, connector, conn_state, i) {
918 [ # # ]: 0 : if (conn_state->best_encoder == encoder)
919 : 0 : return connector;
920 : : }
921 : :
922 : : return NULL;
923 : : }
924 : : EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
925 : :
926 : : /**
927 : : * drm_atomic_get_connector_state - get connector state
928 : : * @state: global atomic state object
929 : : * @connector: connector to get state object for
930 : : *
931 : : * This function returns the connector state for the given connector,
932 : : * allocating it if needed. It will also grab the relevant connector lock to
933 : : * make sure that the state is consistent.
934 : : *
935 : : * Returns:
936 : : *
937 : : * Either the allocated state or the error code encoded into the pointer. When
938 : : * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
939 : : * entire atomic sequence must be restarted. All other errors are fatal.
940 : : */
941 : : struct drm_connector_state *
942 : 0 : drm_atomic_get_connector_state(struct drm_atomic_state *state,
943 : : struct drm_connector *connector)
944 : : {
945 : 0 : int ret, index;
946 : 0 : struct drm_mode_config *config = &connector->dev->mode_config;
947 : 0 : struct drm_connector_state *connector_state;
948 : :
949 [ # # ]: 0 : WARN_ON(!state->acquire_ctx);
950 : :
951 : 0 : ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
952 [ # # ]: 0 : if (ret)
953 : 0 : return ERR_PTR(ret);
954 : :
955 [ # # ]: 0 : index = drm_connector_index(connector);
956 : :
957 [ # # ]: 0 : if (index >= state->num_connector) {
958 : 0 : struct __drm_connnectors_state *c;
959 : 0 : int alloc = max(index + 1, config->num_connector);
960 : :
961 : 0 : c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
962 [ # # ]: 0 : if (!c)
963 : : return ERR_PTR(-ENOMEM);
964 : :
965 : 0 : state->connectors = c;
966 : 0 : memset(&state->connectors[state->num_connector], 0,
967 : 0 : sizeof(*state->connectors) * (alloc - state->num_connector));
968 : :
969 : 0 : state->num_connector = alloc;
970 : : }
971 : :
972 [ # # ]: 0 : if (state->connectors[index].state)
973 : : return state->connectors[index].state;
974 : :
975 : 0 : connector_state = connector->funcs->atomic_duplicate_state(connector);
976 [ # # ]: 0 : if (!connector_state)
977 : : return ERR_PTR(-ENOMEM);
978 : :
979 : 0 : drm_connector_get(connector);
980 : 0 : state->connectors[index].state = connector_state;
981 : 0 : state->connectors[index].old_state = connector->state;
982 : 0 : state->connectors[index].new_state = connector_state;
983 : 0 : state->connectors[index].ptr = connector;
984 : 0 : connector_state->state = state;
985 : :
986 : 0 : DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
987 : : connector->base.id, connector->name,
988 : : connector_state, state);
989 : :
990 [ # # ]: 0 : if (connector_state->crtc) {
991 : 0 : struct drm_crtc_state *crtc_state;
992 : :
993 : 0 : crtc_state = drm_atomic_get_crtc_state(state,
994 : : connector_state->crtc);
995 [ # # ]: 0 : if (IS_ERR(crtc_state))
996 : 0 : return ERR_CAST(crtc_state);
997 : : }
998 : :
999 : : return connector_state;
1000 : : }
1001 : : EXPORT_SYMBOL(drm_atomic_get_connector_state);
1002 : :
1003 : 0 : static void drm_atomic_connector_print_state(struct drm_printer *p,
1004 : : const struct drm_connector_state *state)
1005 : : {
1006 : 0 : struct drm_connector *connector = state->connector;
1007 : :
1008 : 0 : drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1009 [ # # ]: 0 : drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1010 : 0 : drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
1011 : :
1012 [ # # ]: 0 : if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
1013 [ # # # # ]: 0 : if (state->writeback_job && state->writeback_job->fb)
1014 : 0 : drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
1015 : :
1016 [ # # ]: 0 : if (connector->funcs->atomic_print_state)
1017 : 0 : connector->funcs->atomic_print_state(p, state);
1018 : 0 : }
1019 : :
1020 : : /**
1021 : : * drm_atomic_add_affected_connectors - add connectors for CRTC
1022 : : * @state: atomic state
1023 : : * @crtc: DRM CRTC
1024 : : *
1025 : : * This function walks the current configuration and adds all connectors
1026 : : * currently using @crtc to the atomic configuration @state. Note that this
1027 : : * function must acquire the connection mutex. This can potentially cause
1028 : : * unneeded seralization if the update is just for the planes on one CRTC. Hence
1029 : : * drivers and helpers should only call this when really needed (e.g. when a
1030 : : * full modeset needs to happen due to some change).
1031 : : *
1032 : : * Returns:
1033 : : * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
1034 : : * then the w/w mutex code has detected a deadlock and the entire atomic
1035 : : * sequence must be restarted. All other errors are fatal.
1036 : : */
1037 : : int
1038 : 0 : drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
1039 : : struct drm_crtc *crtc)
1040 : : {
1041 : 0 : struct drm_mode_config *config = &state->dev->mode_config;
1042 : 0 : struct drm_connector *connector;
1043 : 0 : struct drm_connector_state *conn_state;
1044 : 0 : struct drm_connector_list_iter conn_iter;
1045 : 0 : struct drm_crtc_state *crtc_state;
1046 : 0 : int ret;
1047 : :
1048 : 0 : crtc_state = drm_atomic_get_crtc_state(state, crtc);
1049 [ # # ]: 0 : if (IS_ERR(crtc_state))
1050 : 0 : return PTR_ERR(crtc_state);
1051 : :
1052 : 0 : ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1053 [ # # ]: 0 : if (ret)
1054 : : return ret;
1055 : :
1056 : 0 : DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
1057 : : crtc->base.id, crtc->name, state);
1058 : :
1059 : : /*
1060 : : * Changed connectors are already in @state, so only need to look
1061 : : * at the connector_mask in crtc_state.
1062 : : */
1063 : 0 : drm_connector_list_iter_begin(state->dev, &conn_iter);
1064 [ # # ]: 0 : drm_for_each_connector_iter(connector, &conn_iter) {
1065 [ # # ]: 0 : if (!(crtc_state->connector_mask & drm_connector_mask(connector)))
1066 : 0 : continue;
1067 : :
1068 : 0 : conn_state = drm_atomic_get_connector_state(state, connector);
1069 [ # # ]: 0 : if (IS_ERR(conn_state)) {
1070 : 0 : drm_connector_list_iter_end(&conn_iter);
1071 : 0 : return PTR_ERR(conn_state);
1072 : : }
1073 : : }
1074 : 0 : drm_connector_list_iter_end(&conn_iter);
1075 : :
1076 : 0 : return 0;
1077 : : }
1078 : : EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
1079 : :
1080 : : /**
1081 : : * drm_atomic_add_affected_planes - add planes for CRTC
1082 : : * @state: atomic state
1083 : : * @crtc: DRM CRTC
1084 : : *
1085 : : * This function walks the current configuration and adds all planes
1086 : : * currently used by @crtc to the atomic configuration @state. This is useful
1087 : : * when an atomic commit also needs to check all currently enabled plane on
1088 : : * @crtc, e.g. when changing the mode. It's also useful when re-enabling a CRTC
1089 : : * to avoid special code to force-enable all planes.
1090 : : *
1091 : : * Since acquiring a plane state will always also acquire the w/w mutex of the
1092 : : * current CRTC for that plane (if there is any) adding all the plane states for
1093 : : * a CRTC will not reduce parallism of atomic updates.
1094 : : *
1095 : : * Returns:
1096 : : * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
1097 : : * then the w/w mutex code has detected a deadlock and the entire atomic
1098 : : * sequence must be restarted. All other errors are fatal.
1099 : : */
1100 : : int
1101 : 0 : drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1102 : : struct drm_crtc *crtc)
1103 : : {
1104 : 0 : const struct drm_crtc_state *old_crtc_state =
1105 [ # # ]: 0 : drm_atomic_get_old_crtc_state(state, crtc);
1106 : 0 : struct drm_plane *plane;
1107 : :
1108 [ # # ]: 0 : WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
1109 : :
1110 : 0 : DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n",
1111 : : crtc->base.id, crtc->name, state);
1112 : :
1113 [ # # # # ]: 0 : drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) {
1114 : 0 : struct drm_plane_state *plane_state =
1115 : 0 : drm_atomic_get_plane_state(state, plane);
1116 : :
1117 [ # # ]: 0 : if (IS_ERR(plane_state))
1118 : 0 : return PTR_ERR(plane_state);
1119 : : }
1120 : : return 0;
1121 : : }
1122 : : EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1123 : :
1124 : : /**
1125 : : * drm_atomic_check_only - check whether a given config would work
1126 : : * @state: atomic configuration to check
1127 : : *
1128 : : * Note that this function can return -EDEADLK if the driver needed to acquire
1129 : : * more locks but encountered a deadlock. The caller must then do the usual w/w
1130 : : * backoff dance and restart. All other errors are fatal.
1131 : : *
1132 : : * Returns:
1133 : : * 0 on success, negative error code on failure.
1134 : : */
1135 : 0 : int drm_atomic_check_only(struct drm_atomic_state *state)
1136 : : {
1137 : 0 : struct drm_device *dev = state->dev;
1138 : 0 : struct drm_mode_config *config = &dev->mode_config;
1139 : 0 : struct drm_plane *plane;
1140 : 0 : struct drm_plane_state *old_plane_state;
1141 : 0 : struct drm_plane_state *new_plane_state;
1142 : 0 : struct drm_crtc *crtc;
1143 : 0 : struct drm_crtc_state *old_crtc_state;
1144 : 0 : struct drm_crtc_state *new_crtc_state;
1145 : 0 : struct drm_connector *conn;
1146 : 0 : struct drm_connector_state *conn_state;
1147 : 0 : int i, ret = 0;
1148 : :
1149 : 0 : DRM_DEBUG_ATOMIC("checking %p\n", state);
1150 : :
1151 [ # # # # ]: 0 : for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1152 : 0 : ret = drm_atomic_plane_check(old_plane_state, new_plane_state);
1153 [ # # ]: 0 : if (ret) {
1154 : 0 : DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
1155 : : plane->base.id, plane->name);
1156 : 0 : return ret;
1157 : : }
1158 : : }
1159 : :
1160 [ # # # # ]: 0 : for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1161 : 0 : ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state);
1162 [ # # ]: 0 : if (ret) {
1163 : 0 : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
1164 : : crtc->base.id, crtc->name);
1165 : 0 : return ret;
1166 : : }
1167 : : }
1168 : :
1169 [ # # # # ]: 0 : for_each_new_connector_in_state(state, conn, conn_state, i) {
1170 : 0 : ret = drm_atomic_connector_check(conn, conn_state);
1171 [ # # ]: 0 : if (ret) {
1172 : 0 : DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
1173 : : conn->base.id, conn->name);
1174 : 0 : return ret;
1175 : : }
1176 : : }
1177 : :
1178 [ # # ]: 0 : if (config->funcs->atomic_check) {
1179 : 0 : ret = config->funcs->atomic_check(state->dev, state);
1180 : :
1181 [ # # ]: 0 : if (ret) {
1182 : 0 : DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
1183 : : state, ret);
1184 : 0 : return ret;
1185 : : }
1186 : : }
1187 : :
1188 [ # # ]: 0 : if (!state->allow_modeset) {
1189 [ # # # # ]: 0 : for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1190 [ # # ]: 0 : if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1191 : 0 : DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
1192 : : crtc->base.id, crtc->name);
1193 : 0 : return -EINVAL;
1194 : : }
1195 : : }
1196 : : }
1197 : :
1198 : : return 0;
1199 : : }
1200 : : EXPORT_SYMBOL(drm_atomic_check_only);
1201 : :
1202 : : /**
1203 : : * drm_atomic_commit - commit configuration atomically
1204 : : * @state: atomic configuration to check
1205 : : *
1206 : : * Note that this function can return -EDEADLK if the driver needed to acquire
1207 : : * more locks but encountered a deadlock. The caller must then do the usual w/w
1208 : : * backoff dance and restart. All other errors are fatal.
1209 : : *
1210 : : * This function will take its own reference on @state.
1211 : : * Callers should always release their reference with drm_atomic_state_put().
1212 : : *
1213 : : * Returns:
1214 : : * 0 on success, negative error code on failure.
1215 : : */
1216 : 0 : int drm_atomic_commit(struct drm_atomic_state *state)
1217 : : {
1218 : 0 : struct drm_mode_config *config = &state->dev->mode_config;
1219 : 0 : int ret;
1220 : :
1221 : 0 : ret = drm_atomic_check_only(state);
1222 [ # # ]: 0 : if (ret)
1223 : : return ret;
1224 : :
1225 : 0 : DRM_DEBUG_ATOMIC("committing %p\n", state);
1226 : :
1227 : 0 : return config->funcs->atomic_commit(state->dev, state, false);
1228 : : }
1229 : : EXPORT_SYMBOL(drm_atomic_commit);
1230 : :
1231 : : /**
1232 : : * drm_atomic_nonblocking_commit - atomic nonblocking commit
1233 : : * @state: atomic configuration to check
1234 : : *
1235 : : * Note that this function can return -EDEADLK if the driver needed to acquire
1236 : : * more locks but encountered a deadlock. The caller must then do the usual w/w
1237 : : * backoff dance and restart. All other errors are fatal.
1238 : : *
1239 : : * This function will take its own reference on @state.
1240 : : * Callers should always release their reference with drm_atomic_state_put().
1241 : : *
1242 : : * Returns:
1243 : : * 0 on success, negative error code on failure.
1244 : : */
1245 : 0 : int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1246 : : {
1247 : 0 : struct drm_mode_config *config = &state->dev->mode_config;
1248 : 0 : int ret;
1249 : :
1250 : 0 : ret = drm_atomic_check_only(state);
1251 [ # # ]: 0 : if (ret)
1252 : : return ret;
1253 : :
1254 : 0 : DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1255 : :
1256 : 0 : return config->funcs->atomic_commit(state->dev, state, true);
1257 : : }
1258 : : EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1259 : :
1260 : : /* just used from drm-client and atomic-helper: */
1261 : 0 : int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
1262 : : struct drm_plane_state *plane_state)
1263 : : {
1264 : 0 : int ret;
1265 : :
1266 : 0 : ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1267 [ # # ]: 0 : if (ret != 0)
1268 : : return ret;
1269 : :
1270 : 0 : drm_atomic_set_fb_for_plane(plane_state, NULL);
1271 : 0 : plane_state->crtc_x = 0;
1272 : 0 : plane_state->crtc_y = 0;
1273 : 0 : plane_state->crtc_w = 0;
1274 : 0 : plane_state->crtc_h = 0;
1275 : 0 : plane_state->src_x = 0;
1276 : 0 : plane_state->src_y = 0;
1277 : 0 : plane_state->src_w = 0;
1278 : 0 : plane_state->src_h = 0;
1279 : :
1280 : 0 : return 0;
1281 : : }
1282 : : EXPORT_SYMBOL(__drm_atomic_helper_disable_plane);
1283 : :
1284 : 0 : static int update_output_state(struct drm_atomic_state *state,
1285 : : struct drm_mode_set *set)
1286 : : {
1287 : 0 : struct drm_device *dev = set->crtc->dev;
1288 : 0 : struct drm_crtc *crtc;
1289 : 0 : struct drm_crtc_state *new_crtc_state;
1290 : 0 : struct drm_connector *connector;
1291 : 0 : struct drm_connector_state *new_conn_state;
1292 : 0 : int ret, i;
1293 : :
1294 : 0 : ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1295 : : state->acquire_ctx);
1296 [ # # ]: 0 : if (ret)
1297 : : return ret;
1298 : :
1299 : : /* First disable all connectors on the target crtc. */
1300 : 0 : ret = drm_atomic_add_affected_connectors(state, set->crtc);
1301 [ # # ]: 0 : if (ret)
1302 : : return ret;
1303 : :
1304 [ # # # # ]: 0 : for_each_new_connector_in_state(state, connector, new_conn_state, i) {
1305 [ # # ]: 0 : if (new_conn_state->crtc == set->crtc) {
1306 : 0 : ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1307 : : NULL);
1308 [ # # ]: 0 : if (ret)
1309 : 0 : return ret;
1310 : :
1311 : : /* Make sure legacy setCrtc always re-trains */
1312 : 0 : new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
1313 : : }
1314 : : }
1315 : :
1316 : : /* Then set all connectors from set->connectors on the target crtc */
1317 [ # # ]: 0 : for (i = 0; i < set->num_connectors; i++) {
1318 : 0 : new_conn_state = drm_atomic_get_connector_state(state,
1319 : 0 : set->connectors[i]);
1320 [ # # ]: 0 : if (IS_ERR(new_conn_state))
1321 : 0 : return PTR_ERR(new_conn_state);
1322 : :
1323 : 0 : ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1324 : : set->crtc);
1325 [ # # ]: 0 : if (ret)
1326 : 0 : return ret;
1327 : : }
1328 : :
1329 [ # # # # ]: 0 : for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1330 : : /*
1331 : : * Don't update ->enable for the CRTC in the set_config request,
1332 : : * since a mismatch would indicate a bug in the upper layers.
1333 : : * The actual modeset code later on will catch any
1334 : : * inconsistencies here.
1335 : : */
1336 [ # # ]: 0 : if (crtc == set->crtc)
1337 : 0 : continue;
1338 : :
1339 [ # # ]: 0 : if (!new_crtc_state->connector_mask) {
1340 : 0 : ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
1341 : : NULL);
1342 [ # # ]: 0 : if (ret < 0)
1343 : 0 : return ret;
1344 : :
1345 : 0 : new_crtc_state->active = false;
1346 : : }
1347 : : }
1348 : :
1349 : : return 0;
1350 : : }
1351 : :
1352 : : /* just used from drm-client and atomic-helper: */
1353 : 0 : int __drm_atomic_helper_set_config(struct drm_mode_set *set,
1354 : : struct drm_atomic_state *state)
1355 : : {
1356 : 0 : struct drm_crtc_state *crtc_state;
1357 : 0 : struct drm_plane_state *primary_state;
1358 : 0 : struct drm_crtc *crtc = set->crtc;
1359 : 0 : int hdisplay, vdisplay;
1360 : 0 : int ret;
1361 : :
1362 : 0 : crtc_state = drm_atomic_get_crtc_state(state, crtc);
1363 [ # # ]: 0 : if (IS_ERR(crtc_state))
1364 : 0 : return PTR_ERR(crtc_state);
1365 : :
1366 : 0 : primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1367 [ # # ]: 0 : if (IS_ERR(primary_state))
1368 : 0 : return PTR_ERR(primary_state);
1369 : :
1370 [ # # ]: 0 : if (!set->mode) {
1371 [ # # ]: 0 : WARN_ON(set->fb);
1372 [ # # ]: 0 : WARN_ON(set->num_connectors);
1373 : :
1374 : 0 : ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1375 [ # # ]: 0 : if (ret != 0)
1376 : : return ret;
1377 : :
1378 : 0 : crtc_state->active = false;
1379 : :
1380 : 0 : ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1381 [ # # ]: 0 : if (ret != 0)
1382 : : return ret;
1383 : :
1384 : 0 : drm_atomic_set_fb_for_plane(primary_state, NULL);
1385 : :
1386 : 0 : goto commit;
1387 : : }
1388 : :
1389 [ # # ]: 0 : WARN_ON(!set->fb);
1390 [ # # ]: 0 : WARN_ON(!set->num_connectors);
1391 : :
1392 : 0 : ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
1393 [ # # ]: 0 : if (ret != 0)
1394 : : return ret;
1395 : :
1396 : 0 : crtc_state->active = true;
1397 : :
1398 : 0 : ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1399 [ # # ]: 0 : if (ret != 0)
1400 : : return ret;
1401 : :
1402 : 0 : drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
1403 : :
1404 : 0 : drm_atomic_set_fb_for_plane(primary_state, set->fb);
1405 : 0 : primary_state->crtc_x = 0;
1406 : 0 : primary_state->crtc_y = 0;
1407 : 0 : primary_state->crtc_w = hdisplay;
1408 : 0 : primary_state->crtc_h = vdisplay;
1409 : 0 : primary_state->src_x = set->x << 16;
1410 : 0 : primary_state->src_y = set->y << 16;
1411 [ # # ]: 0 : if (drm_rotation_90_or_270(primary_state->rotation)) {
1412 : 0 : primary_state->src_w = vdisplay << 16;
1413 : 0 : primary_state->src_h = hdisplay << 16;
1414 : : } else {
1415 : 0 : primary_state->src_w = hdisplay << 16;
1416 : 0 : primary_state->src_h = vdisplay << 16;
1417 : : }
1418 : :
1419 : 0 : commit:
1420 : 0 : ret = update_output_state(state, set);
1421 [ # # ]: 0 : if (ret)
1422 : 0 : return ret;
1423 : :
1424 : : return 0;
1425 : : }
1426 : : EXPORT_SYMBOL(__drm_atomic_helper_set_config);
1427 : :
1428 : 0 : void drm_atomic_print_state(const struct drm_atomic_state *state)
1429 : : {
1430 : 0 : struct drm_printer p = drm_info_printer(state->dev->dev);
1431 : 0 : struct drm_plane *plane;
1432 : 0 : struct drm_plane_state *plane_state;
1433 : 0 : struct drm_crtc *crtc;
1434 : 0 : struct drm_crtc_state *crtc_state;
1435 : 0 : struct drm_connector *connector;
1436 : 0 : struct drm_connector_state *connector_state;
1437 : 0 : int i;
1438 : :
1439 : 0 : DRM_DEBUG_ATOMIC("checking %p\n", state);
1440 : :
1441 [ # # # # ]: 0 : for_each_new_plane_in_state(state, plane, plane_state, i)
1442 : 0 : drm_atomic_plane_print_state(&p, plane_state);
1443 : :
1444 [ # # # # ]: 0 : for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1445 : 0 : drm_atomic_crtc_print_state(&p, crtc_state);
1446 : :
1447 [ # # # # ]: 0 : for_each_new_connector_in_state(state, connector, connector_state, i)
1448 : 0 : drm_atomic_connector_print_state(&p, connector_state);
1449 : 0 : }
1450 : :
1451 : 0 : static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1452 : : bool take_locks)
1453 : : {
1454 : 0 : struct drm_mode_config *config = &dev->mode_config;
1455 : 0 : struct drm_plane *plane;
1456 : 0 : struct drm_crtc *crtc;
1457 : 0 : struct drm_connector *connector;
1458 : 0 : struct drm_connector_list_iter conn_iter;
1459 : :
1460 [ # # # # ]: 0 : if (!drm_drv_uses_atomic_modeset(dev))
1461 : 0 : return;
1462 : :
1463 [ # # ]: 0 : list_for_each_entry(plane, &config->plane_list, head) {
1464 [ # # ]: 0 : if (take_locks)
1465 : 0 : drm_modeset_lock(&plane->mutex, NULL);
1466 : 0 : drm_atomic_plane_print_state(p, plane->state);
1467 [ # # ]: 0 : if (take_locks)
1468 : 0 : drm_modeset_unlock(&plane->mutex);
1469 : : }
1470 : :
1471 [ # # ]: 0 : list_for_each_entry(crtc, &config->crtc_list, head) {
1472 [ # # ]: 0 : if (take_locks)
1473 : 0 : drm_modeset_lock(&crtc->mutex, NULL);
1474 : 0 : drm_atomic_crtc_print_state(p, crtc->state);
1475 [ # # ]: 0 : if (take_locks)
1476 : 0 : drm_modeset_unlock(&crtc->mutex);
1477 : : }
1478 : :
1479 : 0 : drm_connector_list_iter_begin(dev, &conn_iter);
1480 [ # # ]: 0 : if (take_locks)
1481 : 0 : drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1482 [ # # ]: 0 : drm_for_each_connector_iter(connector, &conn_iter)
1483 : 0 : drm_atomic_connector_print_state(p, connector->state);
1484 [ # # ]: 0 : if (take_locks)
1485 : 0 : drm_modeset_unlock(&dev->mode_config.connection_mutex);
1486 : 0 : drm_connector_list_iter_end(&conn_iter);
1487 : : }
1488 : :
1489 : : /**
1490 : : * drm_state_dump - dump entire device atomic state
1491 : : * @dev: the drm device
1492 : : * @p: where to print the state to
1493 : : *
1494 : : * Just for debugging. Drivers might want an option to dump state
1495 : : * to dmesg in case of error irq's. (Hint, you probably want to
1496 : : * ratelimit this!)
1497 : : *
1498 : : * The caller must drm_modeset_lock_all(), or if this is called
1499 : : * from error irq handler, it should not be enabled by default.
1500 : : * (Ie. if you are debugging errors you might not care that this
1501 : : * is racey. But calling this without all modeset locks held is
1502 : : * not inherently safe.)
1503 : : */
1504 : 0 : void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1505 : : {
1506 : 0 : __drm_state_dump(dev, p, false);
1507 : 0 : }
1508 : : EXPORT_SYMBOL(drm_state_dump);
1509 : :
1510 : : #ifdef CONFIG_DEBUG_FS
1511 : 0 : static int drm_state_info(struct seq_file *m, void *data)
1512 : : {
1513 : 0 : struct drm_info_node *node = (struct drm_info_node *) m->private;
1514 : 0 : struct drm_device *dev = node->minor->dev;
1515 : 0 : struct drm_printer p = drm_seq_file_printer(m);
1516 : :
1517 : 0 : __drm_state_dump(dev, &p, true);
1518 : :
1519 : 0 : return 0;
1520 : : }
1521 : :
1522 : : /* any use in debugfs files to dump individual planes/crtc/etc? */
1523 : : static const struct drm_info_list drm_atomic_debugfs_list[] = {
1524 : : {"state", drm_state_info, 0},
1525 : : };
1526 : :
1527 : 0 : int drm_atomic_debugfs_init(struct drm_minor *minor)
1528 : : {
1529 : 0 : return drm_debugfs_create_files(drm_atomic_debugfs_list,
1530 : : ARRAY_SIZE(drm_atomic_debugfs_list),
1531 : : minor->debugfs_root, minor);
1532 : : }
1533 : : #endif
|