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 <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
45void __drm_crtc_commit_free(struct kref *kref)
46{
47 struct drm_crtc_commit *commit =
48 container_of(kref, struct drm_crtc_commit, ref);
49
50 kfree(commit);
51}
52EXPORT_SYMBOL(__drm_crtc_commit_free);
53
54
55
56
57
58
59
60
61
62
63void drm_atomic_state_default_release(struct drm_atomic_state *state)
64{
65 kfree(state->connectors);
66 kfree(state->crtcs);
67 kfree(state->planes);
68 kfree(state->private_objs);
69}
70EXPORT_SYMBOL(drm_atomic_state_default_release);
71
72
73
74
75
76
77
78
79
80
81int
82drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
83{
84 kref_init(&state->ref);
85
86
87
88
89 state->allow_modeset = true;
90
91 state->crtcs = kcalloc(dev->mode_config.num_crtc,
92 sizeof(*state->crtcs), GFP_KERNEL);
93 if (!state->crtcs)
94 goto fail;
95 state->planes = kcalloc(dev->mode_config.num_total_plane,
96 sizeof(*state->planes), GFP_KERNEL);
97 if (!state->planes)
98 goto fail;
99
100 state->dev = dev;
101
102 DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
103
104 return 0;
105fail:
106 drm_atomic_state_default_release(state);
107 return -ENOMEM;
108}
109EXPORT_SYMBOL(drm_atomic_state_init);
110
111
112
113
114
115
116
117struct drm_atomic_state *
118drm_atomic_state_alloc(struct drm_device *dev)
119{
120 struct drm_mode_config *config = &dev->mode_config;
121
122 if (!config->funcs->atomic_state_alloc) {
123 struct drm_atomic_state *state;
124
125 state = kzalloc(sizeof(*state), GFP_KERNEL);
126 if (!state)
127 return NULL;
128 if (drm_atomic_state_init(dev, state) < 0) {
129 kfree(state);
130 return NULL;
131 }
132 return state;
133 }
134
135 return config->funcs->atomic_state_alloc(dev);
136}
137EXPORT_SYMBOL(drm_atomic_state_alloc);
138
139
140
141
142
143
144
145
146
147void drm_atomic_state_default_clear(struct drm_atomic_state *state)
148{
149 struct drm_device *dev = state->dev;
150 struct drm_mode_config *config = &dev->mode_config;
151 int i;
152
153 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
154
155 for (i = 0; i < state->num_connector; i++) {
156 struct drm_connector *connector = state->connectors[i].ptr;
157
158 if (!connector)
159 continue;
160
161 connector->funcs->atomic_destroy_state(connector,
162 state->connectors[i].state);
163 state->connectors[i].ptr = NULL;
164 state->connectors[i].state = NULL;
165 state->connectors[i].old_state = NULL;
166 state->connectors[i].new_state = NULL;
167 drm_connector_put(connector);
168 }
169
170 for (i = 0; i < config->num_crtc; i++) {
171 struct drm_crtc *crtc = state->crtcs[i].ptr;
172
173 if (!crtc)
174 continue;
175
176 crtc->funcs->atomic_destroy_state(crtc,
177 state->crtcs[i].state);
178
179 state->crtcs[i].ptr = NULL;
180 state->crtcs[i].state = NULL;
181 state->crtcs[i].old_state = NULL;
182 state->crtcs[i].new_state = NULL;
183
184 if (state->crtcs[i].commit) {
185 drm_crtc_commit_put(state->crtcs[i].commit);
186 state->crtcs[i].commit = NULL;
187 }
188 }
189
190 for (i = 0; i < config->num_total_plane; i++) {
191 struct drm_plane *plane = state->planes[i].ptr;
192
193 if (!plane)
194 continue;
195
196 plane->funcs->atomic_destroy_state(plane,
197 state->planes[i].state);
198 state->planes[i].ptr = NULL;
199 state->planes[i].state = NULL;
200 state->planes[i].old_state = NULL;
201 state->planes[i].new_state = NULL;
202 }
203
204 for (i = 0; i < state->num_private_objs; i++) {
205 struct drm_private_obj *obj = state->private_objs[i].ptr;
206
207 obj->funcs->atomic_destroy_state(obj,
208 state->private_objs[i].state);
209 state->private_objs[i].ptr = NULL;
210 state->private_objs[i].state = NULL;
211 state->private_objs[i].old_state = NULL;
212 state->private_objs[i].new_state = NULL;
213 }
214 state->num_private_objs = 0;
215
216 if (state->fake_commit) {
217 drm_crtc_commit_put(state->fake_commit);
218 state->fake_commit = NULL;
219 }
220}
221EXPORT_SYMBOL(drm_atomic_state_default_clear);
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237void drm_atomic_state_clear(struct drm_atomic_state *state)
238{
239 struct drm_device *dev = state->dev;
240 struct drm_mode_config *config = &dev->mode_config;
241
242 if (config->funcs->atomic_state_clear)
243 config->funcs->atomic_state_clear(state);
244 else
245 drm_atomic_state_default_clear(state);
246}
247EXPORT_SYMBOL(drm_atomic_state_clear);
248
249
250
251
252
253
254
255
256void __drm_atomic_state_free(struct kref *ref)
257{
258 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
259 struct drm_mode_config *config = &state->dev->mode_config;
260
261 drm_atomic_state_clear(state);
262
263 DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
264
265 if (config->funcs->atomic_state_free) {
266 config->funcs->atomic_state_free(state);
267 } else {
268 drm_atomic_state_default_release(state);
269 kfree(state);
270 }
271}
272EXPORT_SYMBOL(__drm_atomic_state_free);
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289struct drm_crtc_state *
290drm_atomic_get_crtc_state(struct drm_atomic_state *state,
291 struct drm_crtc *crtc)
292{
293 int ret, index = drm_crtc_index(crtc);
294 struct drm_crtc_state *crtc_state;
295
296 WARN_ON(!state->acquire_ctx);
297
298 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
299 if (crtc_state)
300 return crtc_state;
301
302 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
303 if (ret)
304 return ERR_PTR(ret);
305
306 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
307 if (!crtc_state)
308 return ERR_PTR(-ENOMEM);
309
310 state->crtcs[index].state = crtc_state;
311 state->crtcs[index].old_state = crtc->state;
312 state->crtcs[index].new_state = crtc_state;
313 state->crtcs[index].ptr = crtc;
314 crtc_state->state = state;
315
316 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
317 crtc->base.id, crtc->name, crtc_state, state);
318
319 return crtc_state;
320}
321EXPORT_SYMBOL(drm_atomic_get_crtc_state);
322
323static 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
329
330
331
332
333
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
343
344
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
361
362
363
364
365
366
367
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
379static void drm_atomic_crtc_print_state(struct drm_printer *p,
380 const struct drm_crtc_state *state)
381{
382 struct drm_crtc *crtc = state->crtc;
383
384 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
385 drm_printf(p, "\tenable=%d\n", state->enable);
386 drm_printf(p, "\tactive=%d\n", state->active);
387 drm_printf(p, "\tself_refresh_active=%d\n", state->self_refresh_active);
388 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
389 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
390 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
391 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
392 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
393 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
394 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
395 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
396 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
397
398 if (crtc->funcs->atomic_print_state)
399 crtc->funcs->atomic_print_state(p, state);
400}
401
402static int drm_atomic_connector_check(struct drm_connector *connector,
403 struct drm_connector_state *state)
404{
405 struct drm_crtc_state *crtc_state;
406 struct drm_writeback_job *writeback_job = state->writeback_job;
407 const struct drm_display_info *info = &connector->display_info;
408
409 state->max_bpc = info->bpc ? info->bpc : 8;
410 if (connector->max_bpc_property)
411 state->max_bpc = min(state->max_bpc, state->max_requested_bpc);
412
413 if ((connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) || !writeback_job)
414 return 0;
415
416 if (writeback_job->fb && !state->crtc) {
417 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] framebuffer without CRTC\n",
418 connector->base.id, connector->name);
419 return -EINVAL;
420 }
421
422 if (state->crtc)
423 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
424 state->crtc);
425
426 if (writeback_job->fb && !crtc_state->active) {
427 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 return -EINVAL;
431 }
432
433 if (writeback_job->out_fence && !writeback_job->fb) {
434 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] requesting out-fence without framebuffer\n",
435 connector->base.id, connector->name);
436 return -EINVAL;
437 }
438
439 return 0;
440}
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457struct drm_plane_state *
458drm_atomic_get_plane_state(struct drm_atomic_state *state,
459 struct drm_plane *plane)
460{
461 int ret, index = drm_plane_index(plane);
462 struct drm_plane_state *plane_state;
463
464 WARN_ON(!state->acquire_ctx);
465
466
467 WARN_ON(plane->fb);
468 WARN_ON(plane->old_fb);
469 WARN_ON(plane->crtc);
470
471 plane_state = drm_atomic_get_existing_plane_state(state, plane);
472 if (plane_state)
473 return plane_state;
474
475 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
476 if (ret)
477 return ERR_PTR(ret);
478
479 plane_state = plane->funcs->atomic_duplicate_state(plane);
480 if (!plane_state)
481 return ERR_PTR(-ENOMEM);
482
483 state->planes[index].state = plane_state;
484 state->planes[index].ptr = plane;
485 state->planes[index].old_state = plane->state;
486 state->planes[index].new_state = plane_state;
487 plane_state->state = state;
488
489 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
490 plane->base.id, plane->name, plane_state, state);
491
492 if (plane_state->crtc) {
493 struct drm_crtc_state *crtc_state;
494
495 crtc_state = drm_atomic_get_crtc_state(state,
496 plane_state->crtc);
497 if (IS_ERR(crtc_state))
498 return ERR_CAST(crtc_state);
499 }
500
501 return plane_state;
502}
503EXPORT_SYMBOL(drm_atomic_get_plane_state);
504
505static bool
506plane_switching_crtc(const struct drm_plane_state *old_plane_state,
507 const struct drm_plane_state *new_plane_state)
508{
509 if (!old_plane_state->crtc || !new_plane_state->crtc)
510 return false;
511
512 if (old_plane_state->crtc == new_plane_state->crtc)
513 return false;
514
515
516
517
518
519
520 return true;
521}
522
523
524
525
526
527
528
529
530
531
532
533static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
534 const struct drm_plane_state *new_plane_state)
535{
536 struct drm_plane *plane = new_plane_state->plane;
537 struct drm_crtc *crtc = new_plane_state->crtc;
538 const struct drm_framebuffer *fb = new_plane_state->fb;
539 unsigned int fb_width, fb_height;
540 struct drm_mode_rect *clips;
541 uint32_t num_clips;
542 int ret;
543
544
545 if (crtc && !fb) {
546 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n",
547 plane->base.id, plane->name);
548 return -EINVAL;
549 } else if (fb && !crtc) {
550 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n",
551 plane->base.id, plane->name);
552 return -EINVAL;
553 }
554
555
556 if (!crtc)
557 return 0;
558
559
560 if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
561 DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
562 crtc->base.id, crtc->name,
563 plane->base.id, plane->name);
564 return -EINVAL;
565 }
566
567
568 ret = drm_plane_check_pixel_format(plane, fb->format->format,
569 fb->modifier);
570 if (ret) {
571 struct drm_format_name_buf format_name;
572 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n",
573 plane->base.id, plane->name,
574 drm_get_format_name(fb->format->format,
575 &format_name),
576 fb->modifier);
577 return ret;
578 }
579
580
581 if (new_plane_state->crtc_w > INT_MAX ||
582 new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
583 new_plane_state->crtc_h > INT_MAX ||
584 new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) {
585 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
586 plane->base.id, plane->name,
587 new_plane_state->crtc_w, new_plane_state->crtc_h,
588 new_plane_state->crtc_x, new_plane_state->crtc_y);
589 return -ERANGE;
590 }
591
592 fb_width = fb->width << 16;
593 fb_height = fb->height << 16;
594
595
596 if (new_plane_state->src_w > fb_width ||
597 new_plane_state->src_x > fb_width - new_plane_state->src_w ||
598 new_plane_state->src_h > fb_height ||
599 new_plane_state->src_y > fb_height - new_plane_state->src_h) {
600 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates "
601 "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
602 plane->base.id, plane->name,
603 new_plane_state->src_w >> 16,
604 ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
605 new_plane_state->src_h >> 16,
606 ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
607 new_plane_state->src_x >> 16,
608 ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
609 new_plane_state->src_y >> 16,
610 ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
611 fb->width, fb->height);
612 return -ENOSPC;
613 }
614
615 clips = drm_plane_get_damage_clips(new_plane_state);
616 num_clips = drm_plane_get_damage_clips_count(new_plane_state);
617
618
619 while (num_clips > 0) {
620 if (clips->x1 >= clips->x2 ||
621 clips->y1 >= clips->y2 ||
622 clips->x1 < 0 ||
623 clips->y1 < 0 ||
624 clips->x2 > fb_width ||
625 clips->y2 > fb_height) {
626 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid damage clip %d %d %d %d\n",
627 plane->base.id, plane->name, clips->x1,
628 clips->y1, clips->x2, clips->y2);
629 return -EINVAL;
630 }
631 clips++;
632 num_clips--;
633 }
634
635 if (plane_switching_crtc(old_plane_state, new_plane_state)) {
636 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
637 plane->base.id, plane->name);
638 return -EINVAL;
639 }
640
641 return 0;
642}
643
644static void drm_atomic_plane_print_state(struct drm_printer *p,
645 const struct drm_plane_state *state)
646{
647 struct drm_plane *plane = state->plane;
648 struct drm_rect src = drm_plane_state_src(state);
649 struct drm_rect dest = drm_plane_state_dest(state);
650
651 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
652 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
653 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
654 if (state->fb)
655 drm_framebuffer_print_info(p, 2, state->fb);
656 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
657 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
658 drm_printf(p, "\trotation=%x\n", state->rotation);
659 drm_printf(p, "\tnormalized-zpos=%x\n", state->normalized_zpos);
660 drm_printf(p, "\tcolor-encoding=%s\n",
661 drm_get_color_encoding_name(state->color_encoding));
662 drm_printf(p, "\tcolor-range=%s\n",
663 drm_get_color_range_name(state->color_range));
664
665 if (plane->funcs->atomic_print_state)
666 plane->funcs->atomic_print_state(p, state);
667}
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716void
717drm_atomic_private_obj_init(struct drm_device *dev,
718 struct drm_private_obj *obj,
719 struct drm_private_state *state,
720 const struct drm_private_state_funcs *funcs)
721{
722 memset(obj, 0, sizeof(*obj));
723
724 drm_modeset_lock_init(&obj->lock);
725
726 obj->state = state;
727 obj->funcs = funcs;
728 list_add_tail(&obj->head, &dev->mode_config.privobj_list);
729}
730EXPORT_SYMBOL(drm_atomic_private_obj_init);
731
732
733
734
735
736
737
738void
739drm_atomic_private_obj_fini(struct drm_private_obj *obj)
740{
741 list_del(&obj->head);
742 obj->funcs->atomic_destroy_state(obj, obj->state);
743 drm_modeset_lock_fini(&obj->lock);
744}
745EXPORT_SYMBOL(drm_atomic_private_obj_fini);
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760struct drm_private_state *
761drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
762 struct drm_private_obj *obj)
763{
764 int index, num_objs, i, ret;
765 size_t size;
766 struct __drm_private_objs_state *arr;
767 struct drm_private_state *obj_state;
768
769 for (i = 0; i < state->num_private_objs; i++)
770 if (obj == state->private_objs[i].ptr)
771 return state->private_objs[i].state;
772
773 ret = drm_modeset_lock(&obj->lock, state->acquire_ctx);
774 if (ret)
775 return ERR_PTR(ret);
776
777 num_objs = state->num_private_objs + 1;
778 size = sizeof(*state->private_objs) * num_objs;
779 arr = krealloc(state->private_objs, size, GFP_KERNEL);
780 if (!arr)
781 return ERR_PTR(-ENOMEM);
782
783 state->private_objs = arr;
784 index = state->num_private_objs;
785 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
786
787 obj_state = obj->funcs->atomic_duplicate_state(obj);
788 if (!obj_state)
789 return ERR_PTR(-ENOMEM);
790
791 state->private_objs[index].state = obj_state;
792 state->private_objs[index].old_state = obj->state;
793 state->private_objs[index].new_state = obj_state;
794 state->private_objs[index].ptr = obj;
795 obj_state->state = state;
796
797 state->num_private_objs = num_objs;
798
799 DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
800 obj, obj_state, state);
801
802 return obj_state;
803}
804EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
805
806
807
808
809
810
811
812
813
814struct drm_private_state *
815drm_atomic_get_old_private_obj_state(struct drm_atomic_state *state,
816 struct drm_private_obj *obj)
817{
818 int i;
819
820 for (i = 0; i < state->num_private_objs; i++)
821 if (obj == state->private_objs[i].ptr)
822 return state->private_objs[i].old_state;
823
824 return NULL;
825}
826EXPORT_SYMBOL(drm_atomic_get_old_private_obj_state);
827
828
829
830
831
832
833
834
835
836struct drm_private_state *
837drm_atomic_get_new_private_obj_state(struct drm_atomic_state *state,
838 struct drm_private_obj *obj)
839{
840 int i;
841
842 for (i = 0; i < state->num_private_objs; i++)
843 if (obj == state->private_objs[i].ptr)
844 return state->private_objs[i].new_state;
845
846 return NULL;
847}
848EXPORT_SYMBOL(drm_atomic_get_new_private_obj_state);
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868struct drm_connector *
869drm_atomic_get_old_connector_for_encoder(struct drm_atomic_state *state,
870 struct drm_encoder *encoder)
871{
872 struct drm_connector_state *conn_state;
873 struct drm_connector *connector;
874 unsigned int i;
875
876 for_each_old_connector_in_state(state, connector, conn_state, i) {
877 if (conn_state->best_encoder == encoder)
878 return connector;
879 }
880
881 return NULL;
882}
883EXPORT_SYMBOL(drm_atomic_get_old_connector_for_encoder);
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902struct drm_connector *
903drm_atomic_get_new_connector_for_encoder(struct drm_atomic_state *state,
904 struct drm_encoder *encoder)
905{
906 struct drm_connector_state *conn_state;
907 struct drm_connector *connector;
908 unsigned int i;
909
910 for_each_new_connector_in_state(state, connector, conn_state, i) {
911 if (conn_state->best_encoder == encoder)
912 return connector;
913 }
914
915 return NULL;
916}
917EXPORT_SYMBOL(drm_atomic_get_new_connector_for_encoder);
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934struct drm_connector_state *
935drm_atomic_get_connector_state(struct drm_atomic_state *state,
936 struct drm_connector *connector)
937{
938 int ret, index;
939 struct drm_mode_config *config = &connector->dev->mode_config;
940 struct drm_connector_state *connector_state;
941
942 WARN_ON(!state->acquire_ctx);
943
944 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
945 if (ret)
946 return ERR_PTR(ret);
947
948 index = drm_connector_index(connector);
949
950 if (index >= state->num_connector) {
951 struct __drm_connnectors_state *c;
952 int alloc = max(index + 1, config->num_connector);
953
954 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
955 if (!c)
956 return ERR_PTR(-ENOMEM);
957
958 state->connectors = c;
959 memset(&state->connectors[state->num_connector], 0,
960 sizeof(*state->connectors) * (alloc - state->num_connector));
961
962 state->num_connector = alloc;
963 }
964
965 if (state->connectors[index].state)
966 return state->connectors[index].state;
967
968 connector_state = connector->funcs->atomic_duplicate_state(connector);
969 if (!connector_state)
970 return ERR_PTR(-ENOMEM);
971
972 drm_connector_get(connector);
973 state->connectors[index].state = connector_state;
974 state->connectors[index].old_state = connector->state;
975 state->connectors[index].new_state = connector_state;
976 state->connectors[index].ptr = connector;
977 connector_state->state = state;
978
979 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
980 connector->base.id, connector->name,
981 connector_state, state);
982
983 if (connector_state->crtc) {
984 struct drm_crtc_state *crtc_state;
985
986 crtc_state = drm_atomic_get_crtc_state(state,
987 connector_state->crtc);
988 if (IS_ERR(crtc_state))
989 return ERR_CAST(crtc_state);
990 }
991
992 return connector_state;
993}
994EXPORT_SYMBOL(drm_atomic_get_connector_state);
995
996static void drm_atomic_connector_print_state(struct drm_printer *p,
997 const struct drm_connector_state *state)
998{
999 struct drm_connector *connector = state->connector;
1000
1001 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1002 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1003 drm_printf(p, "\tself_refresh_aware=%d\n", state->self_refresh_aware);
1004
1005 if (connector->connector_type == DRM_MODE_CONNECTOR_WRITEBACK)
1006 if (state->writeback_job && state->writeback_job->fb)
1007 drm_printf(p, "\tfb=%d\n", state->writeback_job->fb->base.id);
1008
1009 if (connector->funcs->atomic_print_state)
1010 connector->funcs->atomic_print_state(p, state);
1011}
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030int
1031drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
1032 struct drm_crtc *crtc)
1033{
1034 struct drm_mode_config *config = &state->dev->mode_config;
1035 struct drm_connector *connector;
1036 struct drm_connector_state *conn_state;
1037 struct drm_connector_list_iter conn_iter;
1038 struct drm_crtc_state *crtc_state;
1039 int ret;
1040
1041 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1042 if (IS_ERR(crtc_state))
1043 return PTR_ERR(crtc_state);
1044
1045 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1046 if (ret)
1047 return ret;
1048
1049 DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
1050 crtc->base.id, crtc->name, state);
1051
1052
1053
1054
1055
1056 drm_connector_list_iter_begin(state->dev, &conn_iter);
1057 drm_for_each_connector_iter(connector, &conn_iter) {
1058 if (!(crtc_state->connector_mask & drm_connector_mask(connector)))
1059 continue;
1060
1061 conn_state = drm_atomic_get_connector_state(state, connector);
1062 if (IS_ERR(conn_state)) {
1063 drm_connector_list_iter_end(&conn_iter);
1064 return PTR_ERR(conn_state);
1065 }
1066 }
1067 drm_connector_list_iter_end(&conn_iter);
1068
1069 return 0;
1070}
1071EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093int
1094drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1095 struct drm_crtc *crtc)
1096{
1097 const struct drm_crtc_state *old_crtc_state =
1098 drm_atomic_get_old_crtc_state(state, crtc);
1099 struct drm_plane *plane;
1100
1101 WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
1102
1103 DRM_DEBUG_ATOMIC("Adding all current planes for [CRTC:%d:%s] to %p\n",
1104 crtc->base.id, crtc->name, state);
1105
1106 drm_for_each_plane_mask(plane, state->dev, old_crtc_state->plane_mask) {
1107 struct drm_plane_state *plane_state =
1108 drm_atomic_get_plane_state(state, plane);
1109
1110 if (IS_ERR(plane_state))
1111 return PTR_ERR(plane_state);
1112 }
1113 return 0;
1114}
1115EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128int drm_atomic_check_only(struct drm_atomic_state *state)
1129{
1130 struct drm_device *dev = state->dev;
1131 struct drm_mode_config *config = &dev->mode_config;
1132 struct drm_plane *plane;
1133 struct drm_plane_state *old_plane_state;
1134 struct drm_plane_state *new_plane_state;
1135 struct drm_crtc *crtc;
1136 struct drm_crtc_state *old_crtc_state;
1137 struct drm_crtc_state *new_crtc_state;
1138 struct drm_connector *conn;
1139 struct drm_connector_state *conn_state;
1140 int i, ret = 0;
1141
1142 DRM_DEBUG_ATOMIC("checking %p\n", state);
1143
1144 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1145 ret = drm_atomic_plane_check(old_plane_state, new_plane_state);
1146 if (ret) {
1147 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
1148 plane->base.id, plane->name);
1149 return ret;
1150 }
1151 }
1152
1153 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1154 ret = drm_atomic_crtc_check(old_crtc_state, new_crtc_state);
1155 if (ret) {
1156 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
1157 crtc->base.id, crtc->name);
1158 return ret;
1159 }
1160 }
1161
1162 for_each_new_connector_in_state(state, conn, conn_state, i) {
1163 ret = drm_atomic_connector_check(conn, conn_state);
1164 if (ret) {
1165 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] atomic core check failed\n",
1166 conn->base.id, conn->name);
1167 return ret;
1168 }
1169 }
1170
1171 if (config->funcs->atomic_check) {
1172 ret = config->funcs->atomic_check(state->dev, state);
1173
1174 if (ret) {
1175 DRM_DEBUG_ATOMIC("atomic driver check for %p failed: %d\n",
1176 state, ret);
1177 return ret;
1178 }
1179 }
1180
1181 if (!state->allow_modeset) {
1182 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1183 if (drm_atomic_crtc_needs_modeset(new_crtc_state)) {
1184 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
1185 crtc->base.id, crtc->name);
1186 return -EINVAL;
1187 }
1188 }
1189 }
1190
1191 return 0;
1192}
1193EXPORT_SYMBOL(drm_atomic_check_only);
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209int drm_atomic_commit(struct drm_atomic_state *state)
1210{
1211 struct drm_mode_config *config = &state->dev->mode_config;
1212 int ret;
1213
1214 ret = drm_atomic_check_only(state);
1215 if (ret)
1216 return ret;
1217
1218 DRM_DEBUG_ATOMIC("committing %p\n", state);
1219
1220 return config->funcs->atomic_commit(state->dev, state, false);
1221}
1222EXPORT_SYMBOL(drm_atomic_commit);
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1239{
1240 struct drm_mode_config *config = &state->dev->mode_config;
1241 int ret;
1242
1243 ret = drm_atomic_check_only(state);
1244 if (ret)
1245 return ret;
1246
1247 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1248
1249 return config->funcs->atomic_commit(state->dev, state, true);
1250}
1251EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1252
1253
1254int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
1255 struct drm_plane_state *plane_state)
1256{
1257 int ret;
1258
1259 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1260 if (ret != 0)
1261 return ret;
1262
1263 drm_atomic_set_fb_for_plane(plane_state, NULL);
1264 plane_state->crtc_x = 0;
1265 plane_state->crtc_y = 0;
1266 plane_state->crtc_w = 0;
1267 plane_state->crtc_h = 0;
1268 plane_state->src_x = 0;
1269 plane_state->src_y = 0;
1270 plane_state->src_w = 0;
1271 plane_state->src_h = 0;
1272
1273 return 0;
1274}
1275EXPORT_SYMBOL(__drm_atomic_helper_disable_plane);
1276
1277static int update_output_state(struct drm_atomic_state *state,
1278 struct drm_mode_set *set)
1279{
1280 struct drm_device *dev = set->crtc->dev;
1281 struct drm_crtc *crtc;
1282 struct drm_crtc_state *new_crtc_state;
1283 struct drm_connector *connector;
1284 struct drm_connector_state *new_conn_state;
1285 int ret, i;
1286
1287 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1288 state->acquire_ctx);
1289 if (ret)
1290 return ret;
1291
1292
1293 ret = drm_atomic_add_affected_connectors(state, set->crtc);
1294 if (ret)
1295 return ret;
1296
1297 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
1298 if (new_conn_state->crtc == set->crtc) {
1299 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1300 NULL);
1301 if (ret)
1302 return ret;
1303
1304
1305 new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
1306 }
1307 }
1308
1309
1310 for (i = 0; i < set->num_connectors; i++) {
1311 new_conn_state = drm_atomic_get_connector_state(state,
1312 set->connectors[i]);
1313 if (IS_ERR(new_conn_state))
1314 return PTR_ERR(new_conn_state);
1315
1316 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
1317 set->crtc);
1318 if (ret)
1319 return ret;
1320 }
1321
1322 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1323
1324
1325
1326
1327
1328
1329 if (crtc == set->crtc)
1330 continue;
1331
1332 if (!new_crtc_state->connector_mask) {
1333 ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
1334 NULL);
1335 if (ret < 0)
1336 return ret;
1337
1338 new_crtc_state->active = false;
1339 }
1340 }
1341
1342 return 0;
1343}
1344
1345
1346int __drm_atomic_helper_set_config(struct drm_mode_set *set,
1347 struct drm_atomic_state *state)
1348{
1349 struct drm_crtc_state *crtc_state;
1350 struct drm_plane_state *primary_state;
1351 struct drm_crtc *crtc = set->crtc;
1352 int hdisplay, vdisplay;
1353 int ret;
1354
1355 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1356 if (IS_ERR(crtc_state))
1357 return PTR_ERR(crtc_state);
1358
1359 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1360 if (IS_ERR(primary_state))
1361 return PTR_ERR(primary_state);
1362
1363 if (!set->mode) {
1364 WARN_ON(set->fb);
1365 WARN_ON(set->num_connectors);
1366
1367 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1368 if (ret != 0)
1369 return ret;
1370
1371 crtc_state->active = false;
1372
1373 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1374 if (ret != 0)
1375 return ret;
1376
1377 drm_atomic_set_fb_for_plane(primary_state, NULL);
1378
1379 goto commit;
1380 }
1381
1382 WARN_ON(!set->fb);
1383 WARN_ON(!set->num_connectors);
1384
1385 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
1386 if (ret != 0)
1387 return ret;
1388
1389 crtc_state->active = true;
1390
1391 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1392 if (ret != 0)
1393 return ret;
1394
1395 drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
1396
1397 drm_atomic_set_fb_for_plane(primary_state, set->fb);
1398 primary_state->crtc_x = 0;
1399 primary_state->crtc_y = 0;
1400 primary_state->crtc_w = hdisplay;
1401 primary_state->crtc_h = vdisplay;
1402 primary_state->src_x = set->x << 16;
1403 primary_state->src_y = set->y << 16;
1404 if (drm_rotation_90_or_270(primary_state->rotation)) {
1405 primary_state->src_w = vdisplay << 16;
1406 primary_state->src_h = hdisplay << 16;
1407 } else {
1408 primary_state->src_w = hdisplay << 16;
1409 primary_state->src_h = vdisplay << 16;
1410 }
1411
1412commit:
1413 ret = update_output_state(state, set);
1414 if (ret)
1415 return ret;
1416
1417 return 0;
1418}
1419EXPORT_SYMBOL(__drm_atomic_helper_set_config);
1420
1421void drm_atomic_print_state(const struct drm_atomic_state *state)
1422{
1423 struct drm_printer p = drm_info_printer(state->dev->dev);
1424 struct drm_plane *plane;
1425 struct drm_plane_state *plane_state;
1426 struct drm_crtc *crtc;
1427 struct drm_crtc_state *crtc_state;
1428 struct drm_connector *connector;
1429 struct drm_connector_state *connector_state;
1430 int i;
1431
1432 DRM_DEBUG_ATOMIC("checking %p\n", state);
1433
1434 for_each_new_plane_in_state(state, plane, plane_state, i)
1435 drm_atomic_plane_print_state(&p, plane_state);
1436
1437 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1438 drm_atomic_crtc_print_state(&p, crtc_state);
1439
1440 for_each_new_connector_in_state(state, connector, connector_state, i)
1441 drm_atomic_connector_print_state(&p, connector_state);
1442}
1443
1444static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1445 bool take_locks)
1446{
1447 struct drm_mode_config *config = &dev->mode_config;
1448 struct drm_plane *plane;
1449 struct drm_crtc *crtc;
1450 struct drm_connector *connector;
1451 struct drm_connector_list_iter conn_iter;
1452
1453 if (!drm_drv_uses_atomic_modeset(dev))
1454 return;
1455
1456 list_for_each_entry(plane, &config->plane_list, head) {
1457 if (take_locks)
1458 drm_modeset_lock(&plane->mutex, NULL);
1459 drm_atomic_plane_print_state(p, plane->state);
1460 if (take_locks)
1461 drm_modeset_unlock(&plane->mutex);
1462 }
1463
1464 list_for_each_entry(crtc, &config->crtc_list, head) {
1465 if (take_locks)
1466 drm_modeset_lock(&crtc->mutex, NULL);
1467 drm_atomic_crtc_print_state(p, crtc->state);
1468 if (take_locks)
1469 drm_modeset_unlock(&crtc->mutex);
1470 }
1471
1472 drm_connector_list_iter_begin(dev, &conn_iter);
1473 if (take_locks)
1474 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1475 drm_for_each_connector_iter(connector, &conn_iter)
1476 drm_atomic_connector_print_state(p, connector->state);
1477 if (take_locks)
1478 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1479 drm_connector_list_iter_end(&conn_iter);
1480}
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1498{
1499 __drm_state_dump(dev, p, false);
1500}
1501EXPORT_SYMBOL(drm_state_dump);
1502
1503#ifdef CONFIG_DEBUG_FS
1504static int drm_state_info(struct seq_file *m, void *data)
1505{
1506 struct drm_info_node *node = (struct drm_info_node *) m->private;
1507 struct drm_device *dev = node->minor->dev;
1508 struct drm_printer p = drm_seq_file_printer(m);
1509
1510 __drm_state_dump(dev, &p, true);
1511
1512 return 0;
1513}
1514
1515
1516static const struct drm_info_list drm_atomic_debugfs_list[] = {
1517 {"state", drm_state_info, 0},
1518};
1519
1520int drm_atomic_debugfs_init(struct drm_minor *minor)
1521{
1522 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1523 ARRAY_SIZE(drm_atomic_debugfs_list),
1524 minor->debugfs_root, minor);
1525}
1526#endif
1527