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_mode.h>
32#include <drm/drm_print.h>
33#include <linux/sync_file.h>
34
35#include "drm_crtc_internal.h"
36
37void __drm_crtc_commit_free(struct kref *kref)
38{
39 struct drm_crtc_commit *commit =
40 container_of(kref, struct drm_crtc_commit, ref);
41
42 kfree(commit);
43}
44EXPORT_SYMBOL(__drm_crtc_commit_free);
45
46
47
48
49
50
51
52
53
54void drm_atomic_state_default_release(struct drm_atomic_state *state)
55{
56 kfree(state->connectors);
57 kfree(state->crtcs);
58 kfree(state->planes);
59 kfree(state->private_objs);
60}
61EXPORT_SYMBOL(drm_atomic_state_default_release);
62
63
64
65
66
67
68
69
70
71int
72drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
73{
74 kref_init(&state->ref);
75
76
77
78
79 state->allow_modeset = true;
80
81 state->crtcs = kcalloc(dev->mode_config.num_crtc,
82 sizeof(*state->crtcs), GFP_KERNEL);
83 if (!state->crtcs)
84 goto fail;
85 state->planes = kcalloc(dev->mode_config.num_total_plane,
86 sizeof(*state->planes), GFP_KERNEL);
87 if (!state->planes)
88 goto fail;
89
90 state->dev = dev;
91
92 DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
93
94 return 0;
95fail:
96 drm_atomic_state_default_release(state);
97 return -ENOMEM;
98}
99EXPORT_SYMBOL(drm_atomic_state_init);
100
101
102
103
104
105
106
107struct drm_atomic_state *
108drm_atomic_state_alloc(struct drm_device *dev)
109{
110 struct drm_mode_config *config = &dev->mode_config;
111
112 if (!config->funcs->atomic_state_alloc) {
113 struct drm_atomic_state *state;
114
115 state = kzalloc(sizeof(*state), GFP_KERNEL);
116 if (!state)
117 return NULL;
118 if (drm_atomic_state_init(dev, state) < 0) {
119 kfree(state);
120 return NULL;
121 }
122 return state;
123 }
124
125 return config->funcs->atomic_state_alloc(dev);
126}
127EXPORT_SYMBOL(drm_atomic_state_alloc);
128
129
130
131
132
133
134
135
136void drm_atomic_state_default_clear(struct drm_atomic_state *state)
137{
138 struct drm_device *dev = state->dev;
139 struct drm_mode_config *config = &dev->mode_config;
140 int i;
141
142 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
143
144 for (i = 0; i < state->num_connector; i++) {
145 struct drm_connector *connector = state->connectors[i].ptr;
146
147 if (!connector)
148 continue;
149
150 connector->funcs->atomic_destroy_state(connector,
151 state->connectors[i].state);
152 state->connectors[i].ptr = NULL;
153 state->connectors[i].state = NULL;
154 drm_connector_put(connector);
155 }
156
157 for (i = 0; i < config->num_crtc; i++) {
158 struct drm_crtc *crtc = state->crtcs[i].ptr;
159
160 if (!crtc)
161 continue;
162
163 crtc->funcs->atomic_destroy_state(crtc,
164 state->crtcs[i].state);
165
166 state->crtcs[i].ptr = NULL;
167 state->crtcs[i].state = NULL;
168 }
169
170 for (i = 0; i < config->num_total_plane; i++) {
171 struct drm_plane *plane = state->planes[i].ptr;
172
173 if (!plane)
174 continue;
175
176 plane->funcs->atomic_destroy_state(plane,
177 state->planes[i].state);
178 state->planes[i].ptr = NULL;
179 state->planes[i].state = NULL;
180 }
181
182 for (i = 0; i < state->num_private_objs; i++) {
183 struct drm_private_obj *obj = state->private_objs[i].ptr;
184
185 obj->funcs->atomic_destroy_state(obj,
186 state->private_objs[i].state);
187 state->private_objs[i].ptr = NULL;
188 state->private_objs[i].state = NULL;
189 }
190 state->num_private_objs = 0;
191
192 if (state->fake_commit) {
193 drm_crtc_commit_put(state->fake_commit);
194 state->fake_commit = NULL;
195 }
196}
197EXPORT_SYMBOL(drm_atomic_state_default_clear);
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213void drm_atomic_state_clear(struct drm_atomic_state *state)
214{
215 struct drm_device *dev = state->dev;
216 struct drm_mode_config *config = &dev->mode_config;
217
218 if (config->funcs->atomic_state_clear)
219 config->funcs->atomic_state_clear(state);
220 else
221 drm_atomic_state_default_clear(state);
222}
223EXPORT_SYMBOL(drm_atomic_state_clear);
224
225
226
227
228
229
230
231
232void __drm_atomic_state_free(struct kref *ref)
233{
234 struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
235 struct drm_mode_config *config = &state->dev->mode_config;
236
237 drm_atomic_state_clear(state);
238
239 DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
240
241 if (config->funcs->atomic_state_free) {
242 config->funcs->atomic_state_free(state);
243 } else {
244 drm_atomic_state_default_release(state);
245 kfree(state);
246 }
247}
248EXPORT_SYMBOL(__drm_atomic_state_free);
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265struct drm_crtc_state *
266drm_atomic_get_crtc_state(struct drm_atomic_state *state,
267 struct drm_crtc *crtc)
268{
269 int ret, index = drm_crtc_index(crtc);
270 struct drm_crtc_state *crtc_state;
271
272 WARN_ON(!state->acquire_ctx);
273
274 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
275 if (crtc_state)
276 return crtc_state;
277
278 ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
279 if (ret)
280 return ERR_PTR(ret);
281
282 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
283 if (!crtc_state)
284 return ERR_PTR(-ENOMEM);
285
286 state->crtcs[index].state = crtc_state;
287 state->crtcs[index].old_state = crtc->state;
288 state->crtcs[index].new_state = crtc_state;
289 state->crtcs[index].ptr = crtc;
290 crtc_state->state = state;
291
292 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
293 crtc->base.id, crtc->name, crtc_state, state);
294
295 return crtc_state;
296}
297EXPORT_SYMBOL(drm_atomic_get_crtc_state);
298
299static void set_out_fence_for_crtc(struct drm_atomic_state *state,
300 struct drm_crtc *crtc, s32 __user *fence_ptr)
301{
302 state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = fence_ptr;
303}
304
305static s32 __user *get_out_fence_for_crtc(struct drm_atomic_state *state,
306 struct drm_crtc *crtc)
307{
308 s32 __user *fence_ptr;
309
310 fence_ptr = state->crtcs[drm_crtc_index(crtc)].out_fence_ptr;
311 state->crtcs[drm_crtc_index(crtc)].out_fence_ptr = NULL;
312
313 return fence_ptr;
314}
315
316
317
318
319
320
321
322
323
324
325
326
327int drm_atomic_set_mode_for_crtc(struct drm_crtc_state *state,
328 const struct drm_display_mode *mode)
329{
330 struct drm_mode_modeinfo umode;
331
332
333 if (mode && memcmp(&state->mode, mode, sizeof(*mode)) == 0)
334 return 0;
335
336 drm_property_blob_put(state->mode_blob);
337 state->mode_blob = NULL;
338
339 if (mode) {
340 drm_mode_convert_to_umode(&umode, mode);
341 state->mode_blob =
342 drm_property_create_blob(state->crtc->dev,
343 sizeof(umode),
344 &umode);
345 if (IS_ERR(state->mode_blob))
346 return PTR_ERR(state->mode_blob);
347
348 drm_mode_copy(&state->mode, mode);
349 state->enable = true;
350 DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
351 mode->name, state);
352 } else {
353 memset(&state->mode, 0, sizeof(state->mode));
354 state->enable = false;
355 DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
356 state);
357 }
358
359 return 0;
360}
361EXPORT_SYMBOL(drm_atomic_set_mode_for_crtc);
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
377 struct drm_property_blob *blob)
378{
379 if (blob == state->mode_blob)
380 return 0;
381
382 drm_property_blob_put(state->mode_blob);
383 state->mode_blob = NULL;
384
385 memset(&state->mode, 0, sizeof(state->mode));
386
387 if (blob) {
388 if (blob->length != sizeof(struct drm_mode_modeinfo) ||
389 drm_mode_convert_umode(&state->mode,
390 (const struct drm_mode_modeinfo *)
391 blob->data))
392 return -EINVAL;
393
394 state->mode_blob = drm_property_blob_get(blob);
395 state->enable = true;
396 DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
397 state->mode.name, state);
398 } else {
399 state->enable = false;
400 DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
401 state);
402 }
403
404 return 0;
405}
406EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc);
407
408static int
409drm_atomic_replace_property_blob_from_id(struct drm_device *dev,
410 struct drm_property_blob **blob,
411 uint64_t blob_id,
412 ssize_t expected_size,
413 bool *replaced)
414{
415 struct drm_property_blob *new_blob = NULL;
416
417 if (blob_id != 0) {
418 new_blob = drm_property_lookup_blob(dev, blob_id);
419 if (new_blob == NULL)
420 return -EINVAL;
421
422 if (expected_size > 0 && expected_size != new_blob->length) {
423 drm_property_blob_put(new_blob);
424 return -EINVAL;
425 }
426 }
427
428 *replaced |= drm_property_replace_blob(blob, new_blob);
429 drm_property_blob_put(new_blob);
430
431 return 0;
432}
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
450 struct drm_crtc_state *state, struct drm_property *property,
451 uint64_t val)
452{
453 struct drm_device *dev = crtc->dev;
454 struct drm_mode_config *config = &dev->mode_config;
455 bool replaced = false;
456 int ret;
457
458 if (property == config->prop_active)
459 state->active = val;
460 else if (property == config->prop_mode_id) {
461 struct drm_property_blob *mode =
462 drm_property_lookup_blob(dev, val);
463 ret = drm_atomic_set_mode_prop_for_crtc(state, mode);
464 drm_property_blob_put(mode);
465 return ret;
466 } else if (property == config->degamma_lut_property) {
467 ret = drm_atomic_replace_property_blob_from_id(dev,
468 &state->degamma_lut,
469 val,
470 -1,
471 &replaced);
472 state->color_mgmt_changed |= replaced;
473 return ret;
474 } else if (property == config->ctm_property) {
475 ret = drm_atomic_replace_property_blob_from_id(dev,
476 &state->ctm,
477 val,
478 sizeof(struct drm_color_ctm),
479 &replaced);
480 state->color_mgmt_changed |= replaced;
481 return ret;
482 } else if (property == config->gamma_lut_property) {
483 ret = drm_atomic_replace_property_blob_from_id(dev,
484 &state->gamma_lut,
485 val,
486 -1,
487 &replaced);
488 state->color_mgmt_changed |= replaced;
489 return ret;
490 } else if (property == config->prop_out_fence_ptr) {
491 s32 __user *fence_ptr = u64_to_user_ptr(val);
492
493 if (!fence_ptr)
494 return 0;
495
496 if (put_user(-1, fence_ptr))
497 return -EFAULT;
498
499 set_out_fence_for_crtc(state->state, crtc, fence_ptr);
500 } else if (crtc->funcs->atomic_set_property)
501 return crtc->funcs->atomic_set_property(crtc, state, property, val);
502 else
503 return -EINVAL;
504
505 return 0;
506}
507EXPORT_SYMBOL(drm_atomic_crtc_set_property);
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524static int
525drm_atomic_crtc_get_property(struct drm_crtc *crtc,
526 const struct drm_crtc_state *state,
527 struct drm_property *property, uint64_t *val)
528{
529 struct drm_device *dev = crtc->dev;
530 struct drm_mode_config *config = &dev->mode_config;
531
532 if (property == config->prop_active)
533 *val = state->active;
534 else if (property == config->prop_mode_id)
535 *val = (state->mode_blob) ? state->mode_blob->base.id : 0;
536 else if (property == config->degamma_lut_property)
537 *val = (state->degamma_lut) ? state->degamma_lut->base.id : 0;
538 else if (property == config->ctm_property)
539 *val = (state->ctm) ? state->ctm->base.id : 0;
540 else if (property == config->gamma_lut_property)
541 *val = (state->gamma_lut) ? state->gamma_lut->base.id : 0;
542 else if (property == config->prop_out_fence_ptr)
543 *val = 0;
544 else if (crtc->funcs->atomic_get_property)
545 return crtc->funcs->atomic_get_property(crtc, state, property, val);
546 else
547 return -EINVAL;
548
549 return 0;
550}
551
552
553
554
555
556
557
558
559
560
561
562static int drm_atomic_crtc_check(struct drm_crtc *crtc,
563 struct drm_crtc_state *state)
564{
565
566
567
568
569
570
571
572
573 if (state->active && !state->enable) {
574 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
575 crtc->base.id, crtc->name);
576 return -EINVAL;
577 }
578
579
580
581
582 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
583 WARN_ON(state->enable && !state->mode_blob)) {
584 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled without mode blob\n",
585 crtc->base.id, crtc->name);
586 return -EINVAL;
587 }
588
589 if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
590 WARN_ON(!state->enable && state->mode_blob)) {
591 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled with mode blob\n",
592 crtc->base.id, crtc->name);
593 return -EINVAL;
594 }
595
596
597
598
599
600
601
602
603
604
605
606 if (state->event && !state->active && !crtc->state->active) {
607 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requesting event but off\n",
608 crtc->base.id, crtc->name);
609 return -EINVAL;
610 }
611
612 return 0;
613}
614
615static void drm_atomic_crtc_print_state(struct drm_printer *p,
616 const struct drm_crtc_state *state)
617{
618 struct drm_crtc *crtc = state->crtc;
619
620 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
621 drm_printf(p, "\tenable=%d\n", state->enable);
622 drm_printf(p, "\tactive=%d\n", state->active);
623 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
624 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
625 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
626 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
627 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
628 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
629 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
630 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
631 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
632
633 if (crtc->funcs->atomic_print_state)
634 crtc->funcs->atomic_print_state(p, state);
635}
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652struct drm_plane_state *
653drm_atomic_get_plane_state(struct drm_atomic_state *state,
654 struct drm_plane *plane)
655{
656 int ret, index = drm_plane_index(plane);
657 struct drm_plane_state *plane_state;
658
659 WARN_ON(!state->acquire_ctx);
660
661 plane_state = drm_atomic_get_existing_plane_state(state, plane);
662 if (plane_state)
663 return plane_state;
664
665 ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
666 if (ret)
667 return ERR_PTR(ret);
668
669 plane_state = plane->funcs->atomic_duplicate_state(plane);
670 if (!plane_state)
671 return ERR_PTR(-ENOMEM);
672
673 state->planes[index].state = plane_state;
674 state->planes[index].ptr = plane;
675 state->planes[index].old_state = plane->state;
676 state->planes[index].new_state = plane_state;
677 plane_state->state = state;
678
679 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
680 plane->base.id, plane->name, plane_state, state);
681
682 if (plane_state->crtc) {
683 struct drm_crtc_state *crtc_state;
684
685 crtc_state = drm_atomic_get_crtc_state(state,
686 plane_state->crtc);
687 if (IS_ERR(crtc_state))
688 return ERR_CAST(crtc_state);
689 }
690
691 return plane_state;
692}
693EXPORT_SYMBOL(drm_atomic_get_plane_state);
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710static int drm_atomic_plane_set_property(struct drm_plane *plane,
711 struct drm_plane_state *state, struct drm_property *property,
712 uint64_t val)
713{
714 struct drm_device *dev = plane->dev;
715 struct drm_mode_config *config = &dev->mode_config;
716
717 if (property == config->prop_fb_id) {
718 struct drm_framebuffer *fb = drm_framebuffer_lookup(dev, NULL, val);
719 drm_atomic_set_fb_for_plane(state, fb);
720 if (fb)
721 drm_framebuffer_put(fb);
722 } else if (property == config->prop_in_fence_fd) {
723 if (state->fence)
724 return -EINVAL;
725
726 if (U642I64(val) == -1)
727 return 0;
728
729 state->fence = sync_file_get_fence(val);
730 if (!state->fence)
731 return -EINVAL;
732
733 } else if (property == config->prop_crtc_id) {
734 struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
735 return drm_atomic_set_crtc_for_plane(state, crtc);
736 } else if (property == config->prop_crtc_x) {
737 state->crtc_x = U642I64(val);
738 } else if (property == config->prop_crtc_y) {
739 state->crtc_y = U642I64(val);
740 } else if (property == config->prop_crtc_w) {
741 state->crtc_w = val;
742 } else if (property == config->prop_crtc_h) {
743 state->crtc_h = val;
744 } else if (property == config->prop_src_x) {
745 state->src_x = val;
746 } else if (property == config->prop_src_y) {
747 state->src_y = val;
748 } else if (property == config->prop_src_w) {
749 state->src_w = val;
750 } else if (property == config->prop_src_h) {
751 state->src_h = val;
752 } else if (property == plane->rotation_property) {
753 if (!is_power_of_2(val & DRM_MODE_ROTATE_MASK))
754 return -EINVAL;
755 state->rotation = val;
756 } else if (property == plane->zpos_property) {
757 state->zpos = val;
758 } else if (plane->funcs->atomic_set_property) {
759 return plane->funcs->atomic_set_property(plane, state,
760 property, val);
761 } else {
762 return -EINVAL;
763 }
764
765 return 0;
766}
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783static int
784drm_atomic_plane_get_property(struct drm_plane *plane,
785 const struct drm_plane_state *state,
786 struct drm_property *property, uint64_t *val)
787{
788 struct drm_device *dev = plane->dev;
789 struct drm_mode_config *config = &dev->mode_config;
790
791 if (property == config->prop_fb_id) {
792 *val = (state->fb) ? state->fb->base.id : 0;
793 } else if (property == config->prop_in_fence_fd) {
794 *val = -1;
795 } else if (property == config->prop_crtc_id) {
796 *val = (state->crtc) ? state->crtc->base.id : 0;
797 } else if (property == config->prop_crtc_x) {
798 *val = I642U64(state->crtc_x);
799 } else if (property == config->prop_crtc_y) {
800 *val = I642U64(state->crtc_y);
801 } else if (property == config->prop_crtc_w) {
802 *val = state->crtc_w;
803 } else if (property == config->prop_crtc_h) {
804 *val = state->crtc_h;
805 } else if (property == config->prop_src_x) {
806 *val = state->src_x;
807 } else if (property == config->prop_src_y) {
808 *val = state->src_y;
809 } else if (property == config->prop_src_w) {
810 *val = state->src_w;
811 } else if (property == config->prop_src_h) {
812 *val = state->src_h;
813 } else if (property == plane->rotation_property) {
814 *val = state->rotation;
815 } else if (property == plane->zpos_property) {
816 *val = state->zpos;
817 } else if (plane->funcs->atomic_get_property) {
818 return plane->funcs->atomic_get_property(plane, state, property, val);
819 } else {
820 return -EINVAL;
821 }
822
823 return 0;
824}
825
826static bool
827plane_switching_crtc(struct drm_atomic_state *state,
828 struct drm_plane *plane,
829 struct drm_plane_state *plane_state)
830{
831 if (!plane->state->crtc || !plane_state->crtc)
832 return false;
833
834 if (plane->state->crtc == plane_state->crtc)
835 return false;
836
837
838
839
840
841
842 return true;
843}
844
845
846
847
848
849
850
851
852
853
854
855static int drm_atomic_plane_check(struct drm_plane *plane,
856 struct drm_plane_state *state)
857{
858 unsigned int fb_width, fb_height;
859 int ret;
860
861
862 if (WARN_ON(state->crtc && !state->fb)) {
863 DRM_DEBUG_ATOMIC("CRTC set but no FB\n");
864 return -EINVAL;
865 } else if (WARN_ON(state->fb && !state->crtc)) {
866 DRM_DEBUG_ATOMIC("FB set but no CRTC\n");
867 return -EINVAL;
868 }
869
870
871 if (!state->crtc)
872 return 0;
873
874
875 if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
876 DRM_DEBUG_ATOMIC("Invalid crtc for plane\n");
877 return -EINVAL;
878 }
879
880
881 ret = drm_plane_check_pixel_format(plane, state->fb->format->format);
882 if (ret) {
883 struct drm_format_name_buf format_name;
884 DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
885 drm_get_format_name(state->fb->format->format,
886 &format_name));
887 return ret;
888 }
889
890
891 if (state->crtc_w > INT_MAX ||
892 state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
893 state->crtc_h > INT_MAX ||
894 state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
895 DRM_DEBUG_ATOMIC("Invalid CRTC coordinates %ux%u+%d+%d\n",
896 state->crtc_w, state->crtc_h,
897 state->crtc_x, state->crtc_y);
898 return -ERANGE;
899 }
900
901 fb_width = state->fb->width << 16;
902 fb_height = state->fb->height << 16;
903
904
905 if (state->src_w > fb_width ||
906 state->src_x > fb_width - state->src_w ||
907 state->src_h > fb_height ||
908 state->src_y > fb_height - state->src_h) {
909 DRM_DEBUG_ATOMIC("Invalid source coordinates "
910 "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
911 state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
912 state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
913 state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
914 state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10);
915 return -ENOSPC;
916 }
917
918 if (plane_switching_crtc(state->state, plane, state)) {
919 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] switching CRTC directly\n",
920 plane->base.id, plane->name);
921 return -EINVAL;
922 }
923
924 return 0;
925}
926
927static void drm_atomic_plane_print_state(struct drm_printer *p,
928 const struct drm_plane_state *state)
929{
930 struct drm_plane *plane = state->plane;
931 struct drm_rect src = drm_plane_state_src(state);
932 struct drm_rect dest = drm_plane_state_dest(state);
933
934 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
935 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
936 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
937 if (state->fb) {
938 struct drm_framebuffer *fb = state->fb;
939 int i, n = fb->format->num_planes;
940 struct drm_format_name_buf format_name;
941
942 drm_printf(p, "\t\tformat=%s\n",
943 drm_get_format_name(fb->format->format, &format_name));
944 drm_printf(p, "\t\t\tmodifier=0x%llx\n", fb->modifier);
945 drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height);
946 drm_printf(p, "\t\tlayers:\n");
947 for (i = 0; i < n; i++) {
948 drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, fb->pitches[i]);
949 drm_printf(p, "\t\t\toffset[%d]=%u\n", i, fb->offsets[i]);
950 }
951 }
952 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
953 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
954 drm_printf(p, "\trotation=%x\n", state->rotation);
955
956 if (plane->funcs->atomic_print_state)
957 plane->funcs->atomic_print_state(p, state);
958}
959
960
961
962
963
964
965
966
967
968
969
970void
971drm_atomic_private_obj_init(struct drm_private_obj *obj,
972 struct drm_private_state *state,
973 const struct drm_private_state_funcs *funcs)
974{
975 memset(obj, 0, sizeof(*obj));
976
977 obj->state = state;
978 obj->funcs = funcs;
979}
980EXPORT_SYMBOL(drm_atomic_private_obj_init);
981
982
983
984
985
986
987
988void
989drm_atomic_private_obj_fini(struct drm_private_obj *obj)
990{
991 obj->funcs->atomic_destroy_state(obj, obj->state);
992}
993EXPORT_SYMBOL(drm_atomic_private_obj_fini);
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008struct drm_private_state *
1009drm_atomic_get_private_obj_state(struct drm_atomic_state *state,
1010 struct drm_private_obj *obj)
1011{
1012 int index, num_objs, i;
1013 size_t size;
1014 struct __drm_private_objs_state *arr;
1015 struct drm_private_state *obj_state;
1016
1017 for (i = 0; i < state->num_private_objs; i++)
1018 if (obj == state->private_objs[i].ptr)
1019 return state->private_objs[i].state;
1020
1021 num_objs = state->num_private_objs + 1;
1022 size = sizeof(*state->private_objs) * num_objs;
1023 arr = krealloc(state->private_objs, size, GFP_KERNEL);
1024 if (!arr)
1025 return ERR_PTR(-ENOMEM);
1026
1027 state->private_objs = arr;
1028 index = state->num_private_objs;
1029 memset(&state->private_objs[index], 0, sizeof(*state->private_objs));
1030
1031 obj_state = obj->funcs->atomic_duplicate_state(obj);
1032 if (!obj_state)
1033 return ERR_PTR(-ENOMEM);
1034
1035 state->private_objs[index].state = obj_state;
1036 state->private_objs[index].old_state = obj->state;
1037 state->private_objs[index].new_state = obj_state;
1038 state->private_objs[index].ptr = obj;
1039
1040 state->num_private_objs = num_objs;
1041
1042 DRM_DEBUG_ATOMIC("Added new private object %p state %p to %p\n",
1043 obj, obj_state, state);
1044
1045 return obj_state;
1046}
1047EXPORT_SYMBOL(drm_atomic_get_private_obj_state);
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064struct drm_connector_state *
1065drm_atomic_get_connector_state(struct drm_atomic_state *state,
1066 struct drm_connector *connector)
1067{
1068 int ret, index;
1069 struct drm_mode_config *config = &connector->dev->mode_config;
1070 struct drm_connector_state *connector_state;
1071
1072 WARN_ON(!state->acquire_ctx);
1073
1074 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1075 if (ret)
1076 return ERR_PTR(ret);
1077
1078 index = drm_connector_index(connector);
1079
1080 if (index >= state->num_connector) {
1081 struct __drm_connnectors_state *c;
1082 int alloc = max(index + 1, config->num_connector);
1083
1084 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
1085 if (!c)
1086 return ERR_PTR(-ENOMEM);
1087
1088 state->connectors = c;
1089 memset(&state->connectors[state->num_connector], 0,
1090 sizeof(*state->connectors) * (alloc - state->num_connector));
1091
1092 state->num_connector = alloc;
1093 }
1094
1095 if (state->connectors[index].state)
1096 return state->connectors[index].state;
1097
1098 connector_state = connector->funcs->atomic_duplicate_state(connector);
1099 if (!connector_state)
1100 return ERR_PTR(-ENOMEM);
1101
1102 drm_connector_get(connector);
1103 state->connectors[index].state = connector_state;
1104 state->connectors[index].old_state = connector->state;
1105 state->connectors[index].new_state = connector_state;
1106 state->connectors[index].ptr = connector;
1107 connector_state->state = state;
1108
1109 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d:%s] %p state to %p\n",
1110 connector->base.id, connector->name,
1111 connector_state, state);
1112
1113 if (connector_state->crtc) {
1114 struct drm_crtc_state *crtc_state;
1115
1116 crtc_state = drm_atomic_get_crtc_state(state,
1117 connector_state->crtc);
1118 if (IS_ERR(crtc_state))
1119 return ERR_CAST(crtc_state);
1120 }
1121
1122 return connector_state;
1123}
1124EXPORT_SYMBOL(drm_atomic_get_connector_state);
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141static int drm_atomic_connector_set_property(struct drm_connector *connector,
1142 struct drm_connector_state *state, struct drm_property *property,
1143 uint64_t val)
1144{
1145 struct drm_device *dev = connector->dev;
1146 struct drm_mode_config *config = &dev->mode_config;
1147
1148 if (property == config->prop_crtc_id) {
1149 struct drm_crtc *crtc = drm_crtc_find(dev, NULL, val);
1150 return drm_atomic_set_crtc_for_connector(state, crtc);
1151 } else if (property == config->dpms_property) {
1152
1153
1154
1155
1156 return -EINVAL;
1157 } else if (property == config->tv_select_subconnector_property) {
1158 state->tv.subconnector = val;
1159 } else if (property == config->tv_left_margin_property) {
1160 state->tv.margins.left = val;
1161 } else if (property == config->tv_right_margin_property) {
1162 state->tv.margins.right = val;
1163 } else if (property == config->tv_top_margin_property) {
1164 state->tv.margins.top = val;
1165 } else if (property == config->tv_bottom_margin_property) {
1166 state->tv.margins.bottom = val;
1167 } else if (property == config->tv_mode_property) {
1168 state->tv.mode = val;
1169 } else if (property == config->tv_brightness_property) {
1170 state->tv.brightness = val;
1171 } else if (property == config->tv_contrast_property) {
1172 state->tv.contrast = val;
1173 } else if (property == config->tv_flicker_reduction_property) {
1174 state->tv.flicker_reduction = val;
1175 } else if (property == config->tv_overscan_property) {
1176 state->tv.overscan = val;
1177 } else if (property == config->tv_saturation_property) {
1178 state->tv.saturation = val;
1179 } else if (property == config->tv_hue_property) {
1180 state->tv.hue = val;
1181 } else if (property == config->link_status_property) {
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193 if (state->link_status != DRM_LINK_STATUS_GOOD)
1194 state->link_status = val;
1195 } else if (property == config->aspect_ratio_property) {
1196 state->picture_aspect_ratio = val;
1197 } else if (property == connector->scaling_mode_property) {
1198 state->scaling_mode = val;
1199 } else if (connector->funcs->atomic_set_property) {
1200 return connector->funcs->atomic_set_property(connector,
1201 state, property, val);
1202 } else {
1203 return -EINVAL;
1204 }
1205
1206 return 0;
1207}
1208
1209static void drm_atomic_connector_print_state(struct drm_printer *p,
1210 const struct drm_connector_state *state)
1211{
1212 struct drm_connector *connector = state->connector;
1213
1214 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1215 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1216
1217 if (connector->funcs->atomic_print_state)
1218 connector->funcs->atomic_print_state(p, state);
1219}
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236static int
1237drm_atomic_connector_get_property(struct drm_connector *connector,
1238 const struct drm_connector_state *state,
1239 struct drm_property *property, uint64_t *val)
1240{
1241 struct drm_device *dev = connector->dev;
1242 struct drm_mode_config *config = &dev->mode_config;
1243
1244 if (property == config->prop_crtc_id) {
1245 *val = (state->crtc) ? state->crtc->base.id : 0;
1246 } else if (property == config->dpms_property) {
1247 *val = connector->dpms;
1248 } else if (property == config->tv_select_subconnector_property) {
1249 *val = state->tv.subconnector;
1250 } else if (property == config->tv_left_margin_property) {
1251 *val = state->tv.margins.left;
1252 } else if (property == config->tv_right_margin_property) {
1253 *val = state->tv.margins.right;
1254 } else if (property == config->tv_top_margin_property) {
1255 *val = state->tv.margins.top;
1256 } else if (property == config->tv_bottom_margin_property) {
1257 *val = state->tv.margins.bottom;
1258 } else if (property == config->tv_mode_property) {
1259 *val = state->tv.mode;
1260 } else if (property == config->tv_brightness_property) {
1261 *val = state->tv.brightness;
1262 } else if (property == config->tv_contrast_property) {
1263 *val = state->tv.contrast;
1264 } else if (property == config->tv_flicker_reduction_property) {
1265 *val = state->tv.flicker_reduction;
1266 } else if (property == config->tv_overscan_property) {
1267 *val = state->tv.overscan;
1268 } else if (property == config->tv_saturation_property) {
1269 *val = state->tv.saturation;
1270 } else if (property == config->tv_hue_property) {
1271 *val = state->tv.hue;
1272 } else if (property == config->link_status_property) {
1273 *val = state->link_status;
1274 } else if (property == config->aspect_ratio_property) {
1275 *val = state->picture_aspect_ratio;
1276 } else if (property == connector->scaling_mode_property) {
1277 *val = state->scaling_mode;
1278 } else if (connector->funcs->atomic_get_property) {
1279 return connector->funcs->atomic_get_property(connector,
1280 state, property, val);
1281 } else {
1282 return -EINVAL;
1283 }
1284
1285 return 0;
1286}
1287
1288int drm_atomic_get_property(struct drm_mode_object *obj,
1289 struct drm_property *property, uint64_t *val)
1290{
1291 struct drm_device *dev = property->dev;
1292 int ret;
1293
1294 switch (obj->type) {
1295 case DRM_MODE_OBJECT_CONNECTOR: {
1296 struct drm_connector *connector = obj_to_connector(obj);
1297 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
1298 ret = drm_atomic_connector_get_property(connector,
1299 connector->state, property, val);
1300 break;
1301 }
1302 case DRM_MODE_OBJECT_CRTC: {
1303 struct drm_crtc *crtc = obj_to_crtc(obj);
1304 WARN_ON(!drm_modeset_is_locked(&crtc->mutex));
1305 ret = drm_atomic_crtc_get_property(crtc,
1306 crtc->state, property, val);
1307 break;
1308 }
1309 case DRM_MODE_OBJECT_PLANE: {
1310 struct drm_plane *plane = obj_to_plane(obj);
1311 WARN_ON(!drm_modeset_is_locked(&plane->mutex));
1312 ret = drm_atomic_plane_get_property(plane,
1313 plane->state, property, val);
1314 break;
1315 }
1316 default:
1317 ret = -EINVAL;
1318 break;
1319 }
1320
1321 return ret;
1322}
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338int
1339drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
1340 struct drm_crtc *crtc)
1341{
1342 struct drm_plane *plane = plane_state->plane;
1343 struct drm_crtc_state *crtc_state;
1344
1345 if (plane_state->crtc) {
1346 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
1347 plane_state->crtc);
1348 if (WARN_ON(IS_ERR(crtc_state)))
1349 return PTR_ERR(crtc_state);
1350
1351 crtc_state->plane_mask &= ~(1 << drm_plane_index(plane));
1352 }
1353
1354 plane_state->crtc = crtc;
1355
1356 if (crtc) {
1357 crtc_state = drm_atomic_get_crtc_state(plane_state->state,
1358 crtc);
1359 if (IS_ERR(crtc_state))
1360 return PTR_ERR(crtc_state);
1361 crtc_state->plane_mask |= (1 << drm_plane_index(plane));
1362 }
1363
1364 if (crtc)
1365 DRM_DEBUG_ATOMIC("Link plane state %p to [CRTC:%d:%s]\n",
1366 plane_state, crtc->base.id, crtc->name);
1367 else
1368 DRM_DEBUG_ATOMIC("Link plane state %p to [NOCRTC]\n",
1369 plane_state);
1370
1371 return 0;
1372}
1373EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane);
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385void
1386drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
1387 struct drm_framebuffer *fb)
1388{
1389 if (fb)
1390 DRM_DEBUG_ATOMIC("Set [FB:%d] for plane state %p\n",
1391 fb->base.id, plane_state);
1392 else
1393 DRM_DEBUG_ATOMIC("Set [NOFB] for plane state %p\n",
1394 plane_state);
1395
1396 drm_framebuffer_assign(&plane_state->fb, fb);
1397}
1398EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416void
1417drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
1418 struct dma_fence *fence)
1419{
1420 if (plane_state->fence) {
1421 dma_fence_put(fence);
1422 return;
1423 }
1424
1425 plane_state->fence = fence;
1426}
1427EXPORT_SYMBOL(drm_atomic_set_fence_for_plane);
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443int
1444drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
1445 struct drm_crtc *crtc)
1446{
1447 struct drm_crtc_state *crtc_state;
1448
1449 if (conn_state->crtc == crtc)
1450 return 0;
1451
1452 if (conn_state->crtc) {
1453 crtc_state = drm_atomic_get_new_crtc_state(conn_state->state,
1454 conn_state->crtc);
1455
1456 crtc_state->connector_mask &=
1457 ~(1 << drm_connector_index(conn_state->connector));
1458
1459 drm_connector_put(conn_state->connector);
1460 conn_state->crtc = NULL;
1461 }
1462
1463 if (crtc) {
1464 crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
1465 if (IS_ERR(crtc_state))
1466 return PTR_ERR(crtc_state);
1467
1468 crtc_state->connector_mask |=
1469 1 << drm_connector_index(conn_state->connector);
1470
1471 drm_connector_get(conn_state->connector);
1472 conn_state->crtc = crtc;
1473
1474 DRM_DEBUG_ATOMIC("Link connector state %p to [CRTC:%d:%s]\n",
1475 conn_state, crtc->base.id, crtc->name);
1476 } else {
1477 DRM_DEBUG_ATOMIC("Link connector state %p to [NOCRTC]\n",
1478 conn_state);
1479 }
1480
1481 return 0;
1482}
1483EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502int
1503drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
1504 struct drm_crtc *crtc)
1505{
1506 struct drm_mode_config *config = &state->dev->mode_config;
1507 struct drm_connector *connector;
1508 struct drm_connector_state *conn_state;
1509 struct drm_connector_list_iter conn_iter;
1510 struct drm_crtc_state *crtc_state;
1511 int ret;
1512
1513 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1514 if (IS_ERR(crtc_state))
1515 return PTR_ERR(crtc_state);
1516
1517 ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
1518 if (ret)
1519 return ret;
1520
1521 DRM_DEBUG_ATOMIC("Adding all current connectors for [CRTC:%d:%s] to %p\n",
1522 crtc->base.id, crtc->name, state);
1523
1524
1525
1526
1527
1528 drm_connector_list_iter_begin(state->dev, &conn_iter);
1529 drm_for_each_connector_iter(connector, &conn_iter) {
1530 if (!(crtc_state->connector_mask & (1 << drm_connector_index(connector))))
1531 continue;
1532
1533 conn_state = drm_atomic_get_connector_state(state, connector);
1534 if (IS_ERR(conn_state)) {
1535 drm_connector_list_iter_end(&conn_iter);
1536 return PTR_ERR(conn_state);
1537 }
1538 }
1539 drm_connector_list_iter_end(&conn_iter);
1540
1541 return 0;
1542}
1543EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565int
1566drm_atomic_add_affected_planes(struct drm_atomic_state *state,
1567 struct drm_crtc *crtc)
1568{
1569 struct drm_plane *plane;
1570
1571 WARN_ON(!drm_atomic_get_new_crtc_state(state, crtc));
1572
1573 drm_for_each_plane_mask(plane, state->dev, crtc->state->plane_mask) {
1574 struct drm_plane_state *plane_state =
1575 drm_atomic_get_plane_state(state, plane);
1576
1577 if (IS_ERR(plane_state))
1578 return PTR_ERR(plane_state);
1579 }
1580 return 0;
1581}
1582EXPORT_SYMBOL(drm_atomic_add_affected_planes);
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595int drm_atomic_check_only(struct drm_atomic_state *state)
1596{
1597 struct drm_device *dev = state->dev;
1598 struct drm_mode_config *config = &dev->mode_config;
1599 struct drm_plane *plane;
1600 struct drm_plane_state *plane_state;
1601 struct drm_crtc *crtc;
1602 struct drm_crtc_state *crtc_state;
1603 int i, ret = 0;
1604
1605 DRM_DEBUG_ATOMIC("checking %p\n", state);
1606
1607 for_each_new_plane_in_state(state, plane, plane_state, i) {
1608 ret = drm_atomic_plane_check(plane, plane_state);
1609 if (ret) {
1610 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic core check failed\n",
1611 plane->base.id, plane->name);
1612 return ret;
1613 }
1614 }
1615
1616 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1617 ret = drm_atomic_crtc_check(crtc, crtc_state);
1618 if (ret) {
1619 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic core check failed\n",
1620 crtc->base.id, crtc->name);
1621 return ret;
1622 }
1623 }
1624
1625 if (config->funcs->atomic_check)
1626 ret = config->funcs->atomic_check(state->dev, state);
1627
1628 if (ret)
1629 return ret;
1630
1631 if (!state->allow_modeset) {
1632 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1633 if (drm_atomic_crtc_needs_modeset(crtc_state)) {
1634 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] requires full modeset\n",
1635 crtc->base.id, crtc->name);
1636 return -EINVAL;
1637 }
1638 }
1639 }
1640
1641 return 0;
1642}
1643EXPORT_SYMBOL(drm_atomic_check_only);
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659int drm_atomic_commit(struct drm_atomic_state *state)
1660{
1661 struct drm_mode_config *config = &state->dev->mode_config;
1662 int ret;
1663
1664 ret = drm_atomic_check_only(state);
1665 if (ret)
1666 return ret;
1667
1668 DRM_DEBUG_ATOMIC("committing %p\n", state);
1669
1670 return config->funcs->atomic_commit(state->dev, state, false);
1671}
1672EXPORT_SYMBOL(drm_atomic_commit);
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1689{
1690 struct drm_mode_config *config = &state->dev->mode_config;
1691 int ret;
1692
1693 ret = drm_atomic_check_only(state);
1694 if (ret)
1695 return ret;
1696
1697 DRM_DEBUG_ATOMIC("committing %p nonblocking\n", state);
1698
1699 return config->funcs->atomic_commit(state->dev, state, true);
1700}
1701EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1702
1703static void drm_atomic_print_state(const struct drm_atomic_state *state)
1704{
1705 struct drm_printer p = drm_info_printer(state->dev->dev);
1706 struct drm_plane *plane;
1707 struct drm_plane_state *plane_state;
1708 struct drm_crtc *crtc;
1709 struct drm_crtc_state *crtc_state;
1710 struct drm_connector *connector;
1711 struct drm_connector_state *connector_state;
1712 int i;
1713
1714 DRM_DEBUG_ATOMIC("checking %p\n", state);
1715
1716 for_each_new_plane_in_state(state, plane, plane_state, i)
1717 drm_atomic_plane_print_state(&p, plane_state);
1718
1719 for_each_new_crtc_in_state(state, crtc, crtc_state, i)
1720 drm_atomic_crtc_print_state(&p, crtc_state);
1721
1722 for_each_new_connector_in_state(state, connector, connector_state, i)
1723 drm_atomic_connector_print_state(&p, connector_state);
1724}
1725
1726static void __drm_state_dump(struct drm_device *dev, struct drm_printer *p,
1727 bool take_locks)
1728{
1729 struct drm_mode_config *config = &dev->mode_config;
1730 struct drm_plane *plane;
1731 struct drm_crtc *crtc;
1732 struct drm_connector *connector;
1733 struct drm_connector_list_iter conn_iter;
1734
1735 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
1736 return;
1737
1738 list_for_each_entry(plane, &config->plane_list, head) {
1739 if (take_locks)
1740 drm_modeset_lock(&plane->mutex, NULL);
1741 drm_atomic_plane_print_state(p, plane->state);
1742 if (take_locks)
1743 drm_modeset_unlock(&plane->mutex);
1744 }
1745
1746 list_for_each_entry(crtc, &config->crtc_list, head) {
1747 if (take_locks)
1748 drm_modeset_lock(&crtc->mutex, NULL);
1749 drm_atomic_crtc_print_state(p, crtc->state);
1750 if (take_locks)
1751 drm_modeset_unlock(&crtc->mutex);
1752 }
1753
1754 drm_connector_list_iter_begin(dev, &conn_iter);
1755 if (take_locks)
1756 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
1757 drm_for_each_connector_iter(connector, &conn_iter)
1758 drm_atomic_connector_print_state(p, connector->state);
1759 if (take_locks)
1760 drm_modeset_unlock(&dev->mode_config.connection_mutex);
1761 drm_connector_list_iter_end(&conn_iter);
1762}
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1780{
1781 __drm_state_dump(dev, p, false);
1782}
1783EXPORT_SYMBOL(drm_state_dump);
1784
1785#ifdef CONFIG_DEBUG_FS
1786static int drm_state_info(struct seq_file *m, void *data)
1787{
1788 struct drm_info_node *node = (struct drm_info_node *) m->private;
1789 struct drm_device *dev = node->minor->dev;
1790 struct drm_printer p = drm_seq_file_printer(m);
1791
1792 __drm_state_dump(dev, &p, true);
1793
1794 return 0;
1795}
1796
1797
1798static const struct drm_info_list drm_atomic_debugfs_list[] = {
1799 {"state", drm_state_info, 0},
1800};
1801
1802int drm_atomic_debugfs_init(struct drm_minor *minor)
1803{
1804 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1805 ARRAY_SIZE(drm_atomic_debugfs_list),
1806 minor->debugfs_root, minor);
1807}
1808#endif
1809
1810
1811
1812
1813
1814static struct drm_pending_vblank_event *create_vblank_event(
1815 struct drm_crtc *crtc, uint64_t user_data)
1816{
1817 struct drm_pending_vblank_event *e = NULL;
1818
1819 e = kzalloc(sizeof *e, GFP_KERNEL);
1820 if (!e)
1821 return NULL;
1822
1823 e->event.base.type = DRM_EVENT_FLIP_COMPLETE;
1824 e->event.base.length = sizeof(e->event);
1825 e->event.vbl.crtc_id = crtc->base.id;
1826 e->event.vbl.user_data = user_data;
1827
1828 return e;
1829}
1830
1831int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state,
1832 struct drm_connector *connector,
1833 int mode)
1834{
1835 struct drm_connector *tmp_connector;
1836 struct drm_connector_state *new_conn_state;
1837 struct drm_crtc *crtc;
1838 struct drm_crtc_state *crtc_state;
1839 int i, ret, old_mode = connector->dpms;
1840 bool active = false;
1841
1842 ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
1843 state->acquire_ctx);
1844 if (ret)
1845 return ret;
1846
1847 if (mode != DRM_MODE_DPMS_ON)
1848 mode = DRM_MODE_DPMS_OFF;
1849 connector->dpms = mode;
1850
1851 crtc = connector->state->crtc;
1852 if (!crtc)
1853 goto out;
1854 ret = drm_atomic_add_affected_connectors(state, crtc);
1855 if (ret)
1856 goto out;
1857
1858 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1859 if (IS_ERR(crtc_state)) {
1860 ret = PTR_ERR(crtc_state);
1861 goto out;
1862 }
1863
1864 for_each_new_connector_in_state(state, tmp_connector, new_conn_state, i) {
1865 if (new_conn_state->crtc != crtc)
1866 continue;
1867 if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
1868 active = true;
1869 break;
1870 }
1871 }
1872
1873 crtc_state->active = active;
1874 ret = drm_atomic_commit(state);
1875out:
1876 if (ret != 0)
1877 connector->dpms = old_mode;
1878 return ret;
1879}
1880
1881int drm_atomic_set_property(struct drm_atomic_state *state,
1882 struct drm_mode_object *obj,
1883 struct drm_property *prop,
1884 uint64_t prop_value)
1885{
1886 struct drm_mode_object *ref;
1887 int ret;
1888
1889 if (!drm_property_change_valid_get(prop, prop_value, &ref))
1890 return -EINVAL;
1891
1892 switch (obj->type) {
1893 case DRM_MODE_OBJECT_CONNECTOR: {
1894 struct drm_connector *connector = obj_to_connector(obj);
1895 struct drm_connector_state *connector_state;
1896
1897 connector_state = drm_atomic_get_connector_state(state, connector);
1898 if (IS_ERR(connector_state)) {
1899 ret = PTR_ERR(connector_state);
1900 break;
1901 }
1902
1903 ret = drm_atomic_connector_set_property(connector,
1904 connector_state, prop, prop_value);
1905 break;
1906 }
1907 case DRM_MODE_OBJECT_CRTC: {
1908 struct drm_crtc *crtc = obj_to_crtc(obj);
1909 struct drm_crtc_state *crtc_state;
1910
1911 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1912 if (IS_ERR(crtc_state)) {
1913 ret = PTR_ERR(crtc_state);
1914 break;
1915 }
1916
1917 ret = drm_atomic_crtc_set_property(crtc,
1918 crtc_state, prop, prop_value);
1919 break;
1920 }
1921 case DRM_MODE_OBJECT_PLANE: {
1922 struct drm_plane *plane = obj_to_plane(obj);
1923 struct drm_plane_state *plane_state;
1924
1925 plane_state = drm_atomic_get_plane_state(state, plane);
1926 if (IS_ERR(plane_state)) {
1927 ret = PTR_ERR(plane_state);
1928 break;
1929 }
1930
1931 ret = drm_atomic_plane_set_property(plane,
1932 plane_state, prop, prop_value);
1933 break;
1934 }
1935 default:
1936 ret = -EINVAL;
1937 break;
1938 }
1939
1940 drm_property_change_valid_put(prop, ref);
1941 return ret;
1942}
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956void drm_atomic_clean_old_fb(struct drm_device *dev,
1957 unsigned plane_mask,
1958 int ret)
1959{
1960 struct drm_plane *plane;
1961
1962
1963
1964
1965
1966
1967 drm_for_each_plane_mask(plane, dev, plane_mask) {
1968 if (ret == 0) {
1969 struct drm_framebuffer *new_fb = plane->state->fb;
1970 if (new_fb)
1971 drm_framebuffer_get(new_fb);
1972 plane->fb = new_fb;
1973 plane->crtc = plane->state->crtc;
1974
1975 if (plane->old_fb)
1976 drm_framebuffer_put(plane->old_fb);
1977 }
1978 plane->old_fb = NULL;
1979 }
1980}
1981EXPORT_SYMBOL(drm_atomic_clean_old_fb);
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035struct drm_out_fence_state {
2036 s32 __user *out_fence_ptr;
2037 struct sync_file *sync_file;
2038 int fd;
2039};
2040
2041static int setup_out_fence(struct drm_out_fence_state *fence_state,
2042 struct dma_fence *fence)
2043{
2044 fence_state->fd = get_unused_fd_flags(O_CLOEXEC);
2045 if (fence_state->fd < 0)
2046 return fence_state->fd;
2047
2048 if (put_user(fence_state->fd, fence_state->out_fence_ptr))
2049 return -EFAULT;
2050
2051 fence_state->sync_file = sync_file_create(fence);
2052 if (!fence_state->sync_file)
2053 return -ENOMEM;
2054
2055 return 0;
2056}
2057
2058static int prepare_crtc_signaling(struct drm_device *dev,
2059 struct drm_atomic_state *state,
2060 struct drm_mode_atomic *arg,
2061 struct drm_file *file_priv,
2062 struct drm_out_fence_state **fence_state,
2063 unsigned int *num_fences)
2064{
2065 struct drm_crtc *crtc;
2066 struct drm_crtc_state *crtc_state;
2067 int i, c = 0, ret;
2068
2069 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
2070 return 0;
2071
2072 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
2073 s32 __user *fence_ptr;
2074
2075 fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc);
2076
2077 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) {
2078 struct drm_pending_vblank_event *e;
2079
2080 e = create_vblank_event(crtc, arg->user_data);
2081 if (!e)
2082 return -ENOMEM;
2083
2084 crtc_state->event = e;
2085 }
2086
2087 if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
2088 struct drm_pending_vblank_event *e = crtc_state->event;
2089
2090 if (!file_priv)
2091 continue;
2092
2093 ret = drm_event_reserve_init(dev, file_priv, &e->base,
2094 &e->event.base);
2095 if (ret) {
2096 kfree(e);
2097 crtc_state->event = NULL;
2098 return ret;
2099 }
2100 }
2101
2102 if (fence_ptr) {
2103 struct dma_fence *fence;
2104 struct drm_out_fence_state *f;
2105
2106 f = krealloc(*fence_state, sizeof(**fence_state) *
2107 (*num_fences + 1), GFP_KERNEL);
2108 if (!f)
2109 return -ENOMEM;
2110
2111 memset(&f[*num_fences], 0, sizeof(*f));
2112
2113 f[*num_fences].out_fence_ptr = fence_ptr;
2114 *fence_state = f;
2115
2116 fence = drm_crtc_create_fence(crtc);
2117 if (!fence)
2118 return -ENOMEM;
2119
2120 ret = setup_out_fence(&f[(*num_fences)++], fence);
2121 if (ret) {
2122 dma_fence_put(fence);
2123 return ret;
2124 }
2125
2126 crtc_state->event->base.fence = fence;
2127 }
2128
2129 c++;
2130 }
2131
2132
2133
2134
2135
2136 if (c == 0 && (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
2137 return -EINVAL;
2138
2139 return 0;
2140}
2141
2142static void complete_crtc_signaling(struct drm_device *dev,
2143 struct drm_atomic_state *state,
2144 struct drm_out_fence_state *fence_state,
2145 unsigned int num_fences,
2146 bool install_fds)
2147{
2148 struct drm_crtc *crtc;
2149 struct drm_crtc_state *crtc_state;
2150 int i;
2151
2152 if (install_fds) {
2153 for (i = 0; i < num_fences; i++)
2154 fd_install(fence_state[i].fd,
2155 fence_state[i].sync_file->file);
2156
2157 kfree(fence_state);
2158 return;
2159 }
2160
2161 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
2162 struct drm_pending_vblank_event *event = crtc_state->event;
2163
2164
2165
2166
2167
2168 if (event && (event->base.fence || event->base.file_priv)) {
2169 drm_event_cancel_free(dev, &event->base);
2170 crtc_state->event = NULL;
2171 }
2172 }
2173
2174 if (!fence_state)
2175 return;
2176
2177 for (i = 0; i < num_fences; i++) {
2178 if (fence_state[i].sync_file)
2179 fput(fence_state[i].sync_file->file);
2180 if (fence_state[i].fd >= 0)
2181 put_unused_fd(fence_state[i].fd);
2182
2183
2184 if (fence_state[i].out_fence_ptr &&
2185 put_user(-1, fence_state[i].out_fence_ptr))
2186 DRM_DEBUG_ATOMIC("Couldn't clear out_fence_ptr\n");
2187 }
2188
2189 kfree(fence_state);
2190}
2191
2192int drm_mode_atomic_ioctl(struct drm_device *dev,
2193 void *data, struct drm_file *file_priv)
2194{
2195 struct drm_mode_atomic *arg = data;
2196 uint32_t __user *objs_ptr = (uint32_t __user *)(unsigned long)(arg->objs_ptr);
2197 uint32_t __user *count_props_ptr = (uint32_t __user *)(unsigned long)(arg->count_props_ptr);
2198 uint32_t __user *props_ptr = (uint32_t __user *)(unsigned long)(arg->props_ptr);
2199 uint64_t __user *prop_values_ptr = (uint64_t __user *)(unsigned long)(arg->prop_values_ptr);
2200 unsigned int copied_objs, copied_props;
2201 struct drm_atomic_state *state;
2202 struct drm_modeset_acquire_ctx ctx;
2203 struct drm_plane *plane;
2204 struct drm_out_fence_state *fence_state;
2205 unsigned plane_mask;
2206 int ret = 0;
2207 unsigned int i, j, num_fences;
2208
2209
2210 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
2211 return -EINVAL;
2212
2213
2214
2215
2216
2217 if (!file_priv->atomic)
2218 return -EINVAL;
2219
2220 if (arg->flags & ~DRM_MODE_ATOMIC_FLAGS)
2221 return -EINVAL;
2222
2223 if (arg->reserved)
2224 return -EINVAL;
2225
2226 if ((arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) &&
2227 !dev->mode_config.async_page_flip)
2228 return -EINVAL;
2229
2230
2231 if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
2232 (arg->flags & DRM_MODE_PAGE_FLIP_EVENT))
2233 return -EINVAL;
2234
2235 drm_modeset_acquire_init(&ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE);
2236
2237 state = drm_atomic_state_alloc(dev);
2238 if (!state)
2239 return -ENOMEM;
2240
2241 state->acquire_ctx = &ctx;
2242 state->allow_modeset = !!(arg->flags & DRM_MODE_ATOMIC_ALLOW_MODESET);
2243
2244retry:
2245 plane_mask = 0;
2246 copied_objs = 0;
2247 copied_props = 0;
2248 fence_state = NULL;
2249 num_fences = 0;
2250
2251 for (i = 0; i < arg->count_objs; i++) {
2252 uint32_t obj_id, count_props;
2253 struct drm_mode_object *obj;
2254
2255 if (get_user(obj_id, objs_ptr + copied_objs)) {
2256 ret = -EFAULT;
2257 goto out;
2258 }
2259
2260 obj = drm_mode_object_find(dev, file_priv, obj_id, DRM_MODE_OBJECT_ANY);
2261 if (!obj) {
2262 ret = -ENOENT;
2263 goto out;
2264 }
2265
2266 if (!obj->properties) {
2267 drm_mode_object_put(obj);
2268 ret = -ENOENT;
2269 goto out;
2270 }
2271
2272 if (get_user(count_props, count_props_ptr + copied_objs)) {
2273 drm_mode_object_put(obj);
2274 ret = -EFAULT;
2275 goto out;
2276 }
2277
2278 copied_objs++;
2279
2280 for (j = 0; j < count_props; j++) {
2281 uint32_t prop_id;
2282 uint64_t prop_value;
2283 struct drm_property *prop;
2284
2285 if (get_user(prop_id, props_ptr + copied_props)) {
2286 drm_mode_object_put(obj);
2287 ret = -EFAULT;
2288 goto out;
2289 }
2290
2291 prop = drm_mode_obj_find_prop_id(obj, prop_id);
2292 if (!prop) {
2293 drm_mode_object_put(obj);
2294 ret = -ENOENT;
2295 goto out;
2296 }
2297
2298 if (copy_from_user(&prop_value,
2299 prop_values_ptr + copied_props,
2300 sizeof(prop_value))) {
2301 drm_mode_object_put(obj);
2302 ret = -EFAULT;
2303 goto out;
2304 }
2305
2306 ret = drm_atomic_set_property(state, obj, prop,
2307 prop_value);
2308 if (ret) {
2309 drm_mode_object_put(obj);
2310 goto out;
2311 }
2312
2313 copied_props++;
2314 }
2315
2316 if (obj->type == DRM_MODE_OBJECT_PLANE && count_props &&
2317 !(arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)) {
2318 plane = obj_to_plane(obj);
2319 plane_mask |= (1 << drm_plane_index(plane));
2320 plane->old_fb = plane->fb;
2321 }
2322 drm_mode_object_put(obj);
2323 }
2324
2325 ret = prepare_crtc_signaling(dev, state, arg, file_priv, &fence_state,
2326 &num_fences);
2327 if (ret)
2328 goto out;
2329
2330 if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
2331 ret = drm_atomic_check_only(state);
2332 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
2333 ret = drm_atomic_nonblocking_commit(state);
2334 } else {
2335 if (unlikely(drm_debug & DRM_UT_STATE))
2336 drm_atomic_print_state(state);
2337
2338 ret = drm_atomic_commit(state);
2339 }
2340
2341out:
2342 drm_atomic_clean_old_fb(dev, plane_mask, ret);
2343
2344 complete_crtc_signaling(dev, state, fence_state, num_fences, !ret);
2345
2346 if (ret == -EDEADLK) {
2347 drm_atomic_state_clear(state);
2348 ret = drm_modeset_backoff(&ctx);
2349 if (!ret)
2350 goto retry;
2351 }
2352
2353 drm_atomic_state_put(state);
2354
2355 drm_modeset_drop_locks(&ctx);
2356 drm_modeset_acquire_fini(&ctx);
2357
2358 return ret;
2359}
2360