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