1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <drm/drmP.h>
30#include <drm/drm_atomic.h>
31#include <drm/drm_atomic_uapi.h>
32#include <drm/drm_mode.h>
33#include <drm/drm_print.h>
34#include <drm/drm_writeback.h>
35#include <linux/sync_file.h>
36
37#include "drm_crtc_internal.h"
38#include "drm_internal.h"
39
40void __drm_crtc_commit_free(struct kref *kref)
41{
42 struct drm_crtc_commit *commit =
43 container_of(kref, struct drm_crtc_commit, ref);
44
45 kfree(commit);
46}
47EXPORT_SYMBOL(__drm_crtc_commit_free);
48
49
50
51
52
53
54
55
56
57
58void drm_atomic_state_default_release(struct drm_atomic_state *state)
59{
60 kfree(state->connectors);
61 kfree(state->crtcs);
62 kfree(state->planes);
63 kfree(state->private_objs);
64}
65EXPORT_SYMBOL(drm_atomic_state_default_release);
66
67
68
69
70
71
72
73
74
75
76int
77drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
78{
79 kref_init(&state->ref);
80
81
82
83
84 state->allow_modeset = true;
85
86 state->crtcs = kcalloc(dev->mode_config.num_crtc,
87 sizeof(*state->crtcs), GFP_KERNEL);
88 if (!state->crtcs)
89 goto fail;
90 state->planes = kcalloc(dev->mode_config.num_total_plane,
91 sizeof(*state->planes), GFP_KERNEL);
92 if (!state->planes)
93 goto fail;
94
95 state->dev = dev;
96
97 DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
98
99 return 0;
100fail:
101 drm_atomic_state_default_release(state);
102 return -ENOMEM;
103}
104EXPORT_SYMBOL(drm_atomic_state_init);
105
106
107
108
109
110
111
112struct drm_atomic_state *
113drm_atomic_state_alloc(struct drm_device *dev)
114{
115 struct drm_mode_config *config = &dev->mode_config;
116
117 if (!config->funcs->atomic_state_alloc) {
118 struct drm_atomic_state *state;
119
120 state = kzalloc(sizeof(*state), GFP_KERNEL);
121 if (!state)
122 return NULL;
123 if (drm_atomic_state_init(dev, state) < 0) {
124 kfree(state);
125 return NULL;
126 }
127 return state;
128 }
129
130 return config->funcs->atomic_state_alloc(dev);
131}
132EXPORT_SYMBOL(drm_atomic_state_alloc);
133
134
135
136
137
138
139
140
141
142void drm_atomic_state_default_clear(struct drm_atomic_state *state)
143{
144 struct drm_device *dev = state->dev;
145 struct drm_mode_config *config = &dev->mode_config;
146 int i;
147
148 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
149
150 for (i = 0; i < state->num_connector; i++) {
151 struct drm_connector *connector = state->connectors[i].ptr;
152
153 if (!connector)
154 continue;
155
156 connector->funcs->atomic_destroy_state(connector,
157 state->connectors[i].state);
158 state->connectors[i].ptr = NULL;
159 state->connectors[i].state = NULL;
160 state->connectors[i].old_state = NULL;
161 state->connectors[i].new_state = NULL;
162 drm_connector_put(connector);
163 }
164
165 for (i = 0; i < config->num_crtc; i++) {
166 struct drm_crtc *crtc = state->crtcs[i].ptr;
167
168 if (!crtc)
169 continue;
170
171 crtc->funcs->atomic_destroy_state(crtc,
172 state->crtcs[i].state);
173
174 state->crtcs[i].ptr = NULL;
175 state->crtcs[i].state = NULL;
176 state->crtcs[i].old_state = NULL;
177 state->crtcs[i].new_state = NULL;
178
179 if (state->crtcs[i].commit) {
180 drm_crtc_commit_put(state->crtcs[i].commit);
181 state->crtcs[i].commit = NULL;
182 }
183 }
184
185 for (i = 0; i < config->num_total_plane; i++) {
186 struct drm_plane *plane = state->planes[i].ptr;
187
188 if (!plane)
189 continue;
190
191 plane->funcs->atomic_destroy_state(plane,
192 state->planes[i].state);
193 state->planes[i].ptr = NULL;
194 state->planes[i].state = NULL;
195 state->planes[i].old_state = NULL;
196 state->planes[i].new_state = NULL;
197 }
198
199 for (i = 0; i < state->num_private_objs; i++) {
200 struct drm_private_obj *obj = state->private_objs[i].ptr;
201
202 obj->funcs->atomic_destroy_state(obj,
203 state->private_objs[i].state);
204 state->private_objs[i].ptr = NULL;
205 state->private_objs[i].state = NULL;
206 state->private_objs[i].old_state = NULL;
207 state->private_objs[i].new_state = NULL;
208 }
209 state->num_private_objs = 0;
210
211 if (state->fake_commit) {
212 drm_crtc_commit_put(state->fake_commit);
213 state->fake_commit = NULL;
214 }
215}
216EXPORT_SYMBOL(drm_atomic_state_default_clear);
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232void drm_atomic_state_clear(struct drm_atomic_state *state)
233{
234 struct drm_device *dev = state->dev;
235 struct drm_mode_config *config = &dev->mode_config;
236
237 if (config->funcs->atomic_state_clear)
238 config->funcs->atomic_state_clear(state);
239 else
240 drm_atomic_state_default_clear(state);
241}
242EXPORT_SYMBOL(drm_atomic_state_clear);
243
244
245
246
247
248
249
250
251void __drm_atomic_state_free(struct kref *ref)
252{
253 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
254 struct drm_mode_config *config = &state->dev->mode_config;
255
256 drm_atomic_state_clear(state);
257
258 DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
259
260 if (config->funcs->atomic_state_free) {
261 config->funcs->atomic_state_free(state);
262 } else {
263 drm_atomic_state_default_release(state);
264 kfree(state);
265 }
266}
267EXPORT_SYMBOL(__drm_atomic_state_free);
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284struct drm_crtc_state *
285drm_atomic_get_crtc_state(struct drm_atomic_state *state,
286 struct drm_crtc *crtc)
287{
288 int ret, index = drm_crtc_index(crtc);
289 struct drm_crtc_state *crtc_state;
290
291 WARN_ON(!state->acquire_ctx);
292
293 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
294 if (crtc_state)
295 return crtc_state;
296
297 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
298 if (ret)
299 return ERR_PTR(ret);
300
301 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
302 if (!crtc_state)
303 return ERR_PTR(-ENOMEM);
304
305 state->crtcs[index].state = crtc_state;
306 state->crtcs[index].old_state = crtc->state;
307 state->crtcs[index].new_state = crtc_state;
308 state->crtcs[index].ptr = crtc;
309 crtc_state->state = state;
310
311 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
312 crtc->base.id, crtc->name, crtc_state, state);
313
314 return crtc_state;
315}
316EXPORT_SYMBOL(drm_atomic_get_crtc_state);
317
318static int drm_atomic_crtc_check(struct drm_crtc *crtc,
319 struct drm_crtc_state *state)
320{
321
322
323
324
325
326
327
328
329 if (state->active && !state->enable) {
330 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
331 crtc->base.id, crtc->name);
332 return -EINVAL;
333 }
334
335
336
337
338 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
339 WARN_ON(state->enable && !state->mode_blob)) {
340 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
341 crtc->base.id, crtc->name);
342 return -EINVAL;
343 }
344
345 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
346 WARN_ON(!state->enable && state->mode_blob)) {
347 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
348 crtc->base.id, crtc->name);
349 return -EINVAL;
350 }
351
352
353
354
355
356
357
358
359
360
361
362 if (state->event && !state->active && !crtc->state->active) {
363 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n",
364 crtc->base.id, crtc->name);
365 return -EINVAL;
366 }
367
368 return 0;
369}
370
371static void drm_atomic_crtc_print_state(struct drm_printer *p,
372 const struct drm_crtc_state *state)
373{
374 struct drm_crtc *crtc = state->crtc;
375
376 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
377 drm_printf(p, "\tenable=%d\n", state->enable);
378 drm_printf(p, "\tactive=%d\n", state->active);
379 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
380 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
381 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
382 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
383 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
384 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
385 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
386 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
387 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
388
389 if (crtc->funcs->atomic_print_state)
390 crtc->funcs->atomic_print_state(p, state);
391}
392
393static int drm_atomic_connector_check(struct drm_connector *connector,
394 struct drm_connector_state *state)
395{
396 struct drm_crtc_state *crtc_state;
397 struct drm_writeback_job *writeback_job = state->writeback_job;
398
399 if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
400 return 0;
401
402 if (writeback_job->fb && !state->crtc) {
403 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
404 connector->base.id, connector->name);
405 return -EINVAL;
406 }
407
408 if (state->crtc)
409 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
410 state->crtc);
411
412 if (writeback_job->fb && !crtc_state->active) {
413 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] has framebuffer, but [CRTC:%d] is off\n",
414 connector->base.id, connector->name,
415 state->crtc->base.id);
416 return -EINVAL;
417 }
418
419 if (writeback_job->out_fence && !writeback_job->fb) {
420 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
421 connector->base.id, connector->name);
422 return -EINVAL;
423 }
424
425 return 0;
426}
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443struct drm_plane_state *
444drm_atomic_get_plane_state(struct drm_atomic_state *state,
445 struct drm_plane *plane)
446{
447 int ret, index = drm_plane_index(plane);
448 struct drm_plane_state *plane_state;
449
450 WARN_ON(!state->acquire_ctx);
451
452
453 WARN_ON(plane->fb);
454 WARN_ON(plane->old_fb);
455 WARN_ON(plane->crtc);
456
457 plane_state = drm_atomic_get_existing_plane_state(state, plane);
458 if (plane_state)
459 return plane_state;
460
461 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
462 if (ret)
463 return ERR_PTR(ret);
464
465 plane_state = plane->funcs->atomic_duplicate_state(plane);
466 if (!plane_state)
467 return ERR_PTR(-ENOMEM);
468
469 state->planes[index].state = plane_state;
470 state->planes[index].ptr = plane;
471 state->planes[index].old_state = plane->state;
472 state->planes[index].new_state = plane_state;
473 plane_state->state = state;
474
475 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
476 plane->base.id, plane->name, plane_state, state);
477
478 if (plane_state->crtc) {
479 struct drm_crtc_state *crtc_state;
480
481 crtc_state = drm_atomic_get_crtc_state(state,
482 plane_state->crtc);
483 if (IS_ERR(crtc_state))
484 return ERR_CAST(crtc_state);
485 }
486
487 return plane_state;
488}
489EXPORT_SYMBOL(drm_atomic_get_plane_state);
490
491static bool
492plane_switching_crtc(struct drm_atomic_state *state,
493 struct drm_plane *plane,
494 struct drm_plane_state *plane_state)
495{
496 if (!plane->state->crtc || !plane_state->crtc)
497 return false;
498
499 if (plane->state->crtc == plane_state->crtc)
500 return false;
501
502
503
504
505
506
507 return true;
508}
509
510
511
512
513
514
515
516
517
518
519
520static int drm_atomic_plane_check(struct drm_plane *plane,
521 struct drm_plane_state *state)
522{
523 unsigned int fb_width, fb_height;
524 int ret;
525
526
527 if (state->crtc && !state->fb) {
528 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n",
529 plane->base.id, plane->name);
530 return -EINVAL;
531 } else if (state->fb && !state->crtc) {
532 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n",
533 plane->base.id, plane->name);
534 return -EINVAL;
535 }
536
537
538 if (!state->crtc)
539 return 0;
540
541
542 if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
543 DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
544 state->crtc->base.id, state->crtc->name,
545 plane->base.id, plane->name);
546 return -EINVAL;
547 }
548
549
550 ret = drm_plane_check_pixel_format(plane, state->fb->format->format,
551 state->fb->modifier);
552 if (ret) {
553 struct drm_format_name_buf format_name;
554 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n",
555 plane->base.id, plane->name,
556 drm_get_format_name(state->fb->format->format,
557 &format_name),
558 state->fb->modifier);
559 return ret;
560 }
561
562
563 if (state->crtc_w > INT_MAX ||
564 state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
565 state->crtc_h > INT_MAX ||
566 state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
567 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
568 plane->base.id, plane->name,
569 state->crtc_w, state->crtc_h,
570 state->crtc_x, state->crtc_y);
571 return -ERANGE;
572 }
573
574 fb_width = state->fb->width << 16;
575 fb_height = state->fb->height << 16;
576
577
578 if (state->src_w > fb_width ||
579 state->src_x > fb_width - state->src_w ||
580 state->src_h > fb_height ||
581 state->src_y > fb_height - state->src_h) {
582 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates "
583 "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
584 plane->base.id, plane->name,
585 state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
586 state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
587 state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
588 state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10,
589 state->fb->width, state->fb->height);
590 return -ENOSPC;
591 }
592
593 if (plane_switching_crtc(state->state, plane, state)) {
594 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
595 plane->base.id, plane->name);
596 return -EINVAL;
597 }
598
599 return 0;
600}
601
602static void drm_atomic_plane_print_state(struct drm_printer *p,
603 const struct drm_plane_state *state)
604{
605 struct drm_plane *plane = state->plane;
606 struct drm_rect src = drm_plane_state_src(state);
607 struct drm_rect dest = drm_plane_state_dest(state);
608
609 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
610 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
611 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
612 if (state->fb)
613 drm_framebuffer_print_info(p, 2, state->fb);
614 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
615 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
616 drm_printf(p, "\trotation=%x\n", state->rotation);
617 drm_printf(p, "\tnormalized-zpos=%x\n", state->normalized_zpos);
618 drm_printf(p, "\tcolor-encoding=%s\n",
619 drm_get_color_encoding_name(state->color_encoding));
620 drm_printf(p, "\tcolor-range=%s\n",
621 drm_get_color_range_name(state->color_range));
622
623 if (plane->funcs->atomic_print_state)
624 plane->funcs->atomic_print_state(p, state);
625}
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673void
674drm_atomic_private_obj_init(struct drm_private_obj *obj,
675 struct drm_private_state *state,
676 const struct drm_private_state_funcs *funcs)
677{
678 memset(obj, 0, sizeof(*obj));
679
680 obj->state = state;
681 obj->funcs = funcs;
682}
683EXPORT_SYMBOL(drm_atomic_private_obj_init);
684
685
686
687
688
689
690
691void
692drm_atomic_private_obj_fini(struct drm_private_obj *obj)
693{
694 obj->funcs->atomic_destroy_state(obj, obj->state);
695}
696EXPORT_SYMBOL(drm_atomic_private_obj_fini);
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711struct drm_private_state *
712drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
713 struct drm_private_obj *obj)
714{
715 int index, num_objs, i;
716 size_t size;
717 struct __drm_private_objs_state *arr;
718 struct drm_private_state *obj_state;
719
720 for (i = 0; i < state->num_private_objs; i++)
721 if (obj == state->private_objs[i].ptr)
722 return state->private_objs[i].state;
723
724 num_objs = state->num_private_objs + 1;
725 size = sizeof(*state->private_objs) * num_objs;
726 arr = krealloc(state->private_objs, size, GFP_KERNEL);
727 if (!arr)
728 return ERR_PTR(-ENOMEM);
729
730 state->private_objs = arr;
731 index = state->num_private_objs;
732 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
733
734 obj_state = obj->funcs->atomic_duplicate_state(obj);
735 if (!obj_state)
736 return ERR_PTR(-ENOMEM);
737
738 state->private_objs[index].state = obj_state;
739 state->private_objs[index].old_state = obj->state;
740 state->private_objs[index].new_state = obj_state;
741 state->private_objs[index].ptr = obj;
742 obj_state->state = state;
743
744 state->num_private_objs = num_objs;
745
746 DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
747 obj, obj_state, state);
748
749 return obj_state;
750}
751EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768struct drm_connector_state *
769drm_atomic_get_connector_state(struct drm_atomic_state *state,
770 struct drm_connector *connector)
771{
772 int ret, index;
773 struct drm_mode_config *config = &connector->dev->mode_config;
774 struct drm_connector_state *connector_state;
775
776 WARN_ON(!state->acquire_ctx);
777
778 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
779 if (ret)
780 return ERR_PTR(ret);
781
782 index = drm_connector_index(connector);
783
784 if (index >= state->num_connector) {
785 struct __drm_connnectors_state *c;
786 int alloc = max(index + 1, config->num_connector);
787
788 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
789 if (!c)
790 return ERR_PTR(-ENOMEM);
791
792 state->connectors = c;
793 memset(&state->connectors[state->num_connector], 0,
794 sizeof(*state->connectors) * (alloc - state->num_connector));
795
796 state->num_connector = alloc;
797 }
798
799 if (state->connectors[index].state)
800 return state->connectors[index].state;
801
802 connector_state = connector->funcs->atomic_duplicate_state(connector);
803 if (!connector_state)
804 return ERR_PTR(-ENOMEM);
805
806 drm_connector_get(connector);
807 state->connectors[index].state = connector_state;
808 state->connectors[index].old_state = connector->state;
809 state->connectors[index].new_state = connector_state;
810 state->connectors[index].ptr = connector;
811 connector_state->state = state;
812
813 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
814 connector->base.id, connector->name,
815 connector_state, state);
816
817 if (connector_state->crtc) {
818 struct drm_crtc_state *crtc_state;
819
820 crtc_state = drm_atomic_get_crtc_state(state,
821 connector_state->crtc);
822 if (IS_ERR(crtc_state))
823 return ERR_CAST(crtc_state);
824 }
825
826 return connector_state;
827}
828EXPORT_SYMBOL(drm_atomic_get_connector_state);
829
830static void drm_atomic_connector_print_state(struct drm_printer *p,
831 const struct drm_connector_state *state)
832{
833 struct drm_connector *connector = state->connector;
834
835 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
836 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
837
838 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
839 if (state->writeback_job && state->writeback_job->fb)
840 drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
841
842 if (connector->funcs->atomic_print_state)
843 connector->funcs->atomic_print_state(p, state);
844}
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863int
864drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
865 struct drm_crtc *crtc)
866{
867 struct drm_mode_config *config = &state->dev->mode_config;
868 struct drm_connector *connector;
869 struct drm_connector_state *conn_state;
870 struct drm_connector_list_iter conn_iter;
871 struct drm_crtc_state *crtc_state;
872 int ret;
873
874 crtc_state = drm_atomic_get_crtc_state(state, crtc);
875 if (IS_ERR(crtc_state))
876 return PTR_ERR(crtc_state);
877
878 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
879 if (ret)
880 return ret;
881
882 DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
883 crtc->base.id, crtc->name, state);
884
885
886
887
888
889 drm_connector_list_iter_begin(state->dev, &conn_iter);
890 drm_for_each_connector_iter(connector, &conn_iter) {
891 if (!(crtc_state->connector_mask & drm_connector_mask(connector)))
892 continue;
893
894 conn_state = drm_atomic_get_connector_state(state, connector);
895 if (IS_ERR(conn_state)) {
896 drm_connector_list_iter_end(&conn_iter);
897 return PTR_ERR(conn_state);
898 }
899 }
900 drm_connector_list_iter_end(&conn_iter);
901
902 return 0;
903}
904EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926int
927drm_atomic_add_affected_planes(struct drm_atomic_state *state,
928 struct drm_crtc *crtc)
929{
930 struct drm_plane *plane;
931
932 WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
933
934 DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n",
935 crtc->base.id, crtc->name, state);
936
937 drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
938 struct drm_plane_state *plane_state =
939 drm_atomic_get_plane_state(state, plane);
940
941 if (IS_ERR(plane_state))
942 return PTR_ERR(plane_state);
943 }
944 return 0;
945}
946EXPORT_SYMBOL(drm_atomic_add_affected_planes);
947
948
949
950
951
952
953
954
955
956
957
958
959int drm_atomic_check_only(struct drm_atomic_state *state)
960{
961 struct drm_device *dev = state->dev;
962 struct drm_mode_config *config = &dev->mode_config;
963 struct drm_plane *plane;
964 struct drm_plane_state *plane_state;
965 struct drm_crtc *crtc;
966 struct drm_crtc_state *crtc_state;
967 struct drm_connector *conn;
968 struct drm_connector_state *conn_state;
969 int i, ret = 0;
970
971 DRM_DEBUG_ATOMIC("checking %p\n", state);
972
973 for_each_new_plane_in_state(state, plane, plane_state, i) {
974 ret = drm_atomic_plane_check(plane, plane_state);
975 if (ret) {
976 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
977 plane->base.id, plane->name);
978 return ret;
979 }
980 }
981
982 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
983 ret = drm_atomic_crtc_check(crtc, crtc_state);
984 if (ret) {
985 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
986 crtc->base.id, crtc->name);
987 return ret;
988 }
989 }
990
991 for_each_new_connector_in_state(state, conn, conn_state, i) {
992 ret = drm_atomic_connector_check(conn, conn_state);
993 if (ret) {
994 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
995 conn->base.id, conn->name);
996 return ret;
997 }
998 }
999
1000 if (config->funcs->atomic_check) {
1001 ret = config->funcs->atomic_check(state->dev, state);
1002
1003 if (ret) {
1004 DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
1005 state, ret);
1006 return ret;
1007 }
1008 }
1009
1010 if (!state->allow_modeset) {
1011 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1012 if (drm_atomic_crtc_needs_modeset(crtc_state)) {
1013 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
1014 crtc->base.id, crtc->name);
1015 return -EINVAL;
1016 }
1017 }
1018 }
1019
1020 return 0;
1021}
1022EXPORT_SYMBOL(drm_atomic_check_only);
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038int drm_atomic_commit(struct drm_atomic_state *state)
1039{
1040 struct drm_mode_config *config = &state->dev->mode_config;
1041 int ret;
1042
1043 ret = drm_atomic_check_only(state);
1044 if (ret)
1045 return ret;
1046
1047 DRM_DEBUG_ATOMIC("committing %p\n", state);
1048
1049 return config->funcs->atomic_commit(state->dev, state, false);
1050}
1051EXPORT_SYMBOL(drm_atomic_commit);
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1068{
1069 struct drm_mode_config *config = &state->dev->mode_config;
1070 int ret;
1071
1072 ret = drm_atomic_check_only(state);
1073 if (ret)
1074 return ret;
1075
1076 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1077
1078 return config->funcs->atomic_commit(state->dev, state, true);
1079}
1080EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1081
1082void drm_atomic_print_state(const struct drm_atomic_state *state)
1083{
1084 struct drm_printer p = drm_info_printer(state->dev->dev);
1085 struct drm_plane *plane;
1086 struct drm_plane_state *plane_state;
1087 struct drm_crtc *crtc;
1088 struct drm_crtc_state *crtc_state;
1089 struct drm_connector *connector;
1090 struct drm_connector_state *connector_state;
1091 int i;
1092
1093 DRM_DEBUG_ATOMIC("checking %p\n", state);
1094
1095 for_each_new_plane_in_state(state, plane, plane_state, i)
1096 drm_atomic_plane_print_state(&p, plane_state);
1097
1098 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1099 drm_atomic_crtc_print_state(&p, crtc_state);
1100
1101 for_each_new_connector_in_state(state, connector, connector_state, i)
1102 drm_atomic_connector_print_state(&p, connector_state);
1103}
1104
1105static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1106 bool take_locks)
1107{
1108 struct drm_mode_config *config = &dev->mode_config;
1109 struct drm_plane *plane;
1110 struct drm_crtc *crtc;
1111 struct drm_connector *connector;
1112 struct drm_connector_list_iter conn_iter;
1113
1114 if (!drm_drv_uses_atomic_modeset(dev))
1115 return;
1116
1117 list_for_each_entry(plane, &config->plane_list, head) {
1118 if (take_locks)
1119 drm_modeset_lock(&plane->mutex, NULL);
1120 drm_atomic_plane_print_state(p, plane->state);
1121 if (take_locks)
1122 drm_modeset_unlock(&plane->mutex);
1123 }
1124
1125 list_for_each_entry(crtc, &config->crtc_list, head) {
1126 if (take_locks)
1127 drm_modeset_lock(&crtc->mutex, NULL);
1128 drm_atomic_crtc_print_state(p, crtc->state);
1129 if (take_locks)
1130 drm_modeset_unlock(&crtc->mutex);
1131 }
1132
1133 drm_connector_list_iter_begin(dev, &conn_iter);
1134 if (take_locks)
1135 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1136 drm_for_each_connector_iter(connector, &conn_iter)
1137 drm_atomic_connector_print_state(p, connector->state);
1138 if (take_locks)
1139 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1140 drm_connector_list_iter_end(&conn_iter);
1141}
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1159{
1160 __drm_state_dump(dev, p, false);
1161}
1162EXPORT_SYMBOL(drm_state_dump);
1163
1164#ifdef CONFIG_DEBUG_FS
1165static int drm_state_info(struct seq_file *m, void *data)
1166{
1167 struct drm_info_node *node = (struct drm_info_node *) m->private;
1168 struct drm_device *dev = node->minor->dev;
1169 struct drm_printer p = drm_seq_file_printer(m);
1170
1171 __drm_state_dump(dev, &p, true);
1172
1173 return 0;
1174}
1175
1176
1177static const struct drm_info_list drm_atomic_debugfs_list[] = {
1178 {"state", drm_state_info, 0},
1179};
1180
1181int drm_atomic_debugfs_init(struct drm_minor *minor)
1182{
1183 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1184 ARRAY_SIZE(drm_atomic_debugfs_list),
1185 minor->debugfs_root, minor);
1186}
1187#endif
1188
1189