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#include <drm/drmP.h>
29#include <drm/drm_atomic.h>
30#include <drm/drm_plane_helper.h>
31#include <drm/drm_crtc_helper.h>
32#include <drm/drm_atomic_helper.h>
33#include <linux/dma-fence.h>
34
35#include "drm_crtc_internal.h"
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64static void
65drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
66 struct drm_plane_state *plane_state,
67 struct drm_plane *plane)
68{
69 struct drm_crtc_state *crtc_state;
70
71 if (plane->state->crtc) {
72 crtc_state = drm_atomic_get_existing_crtc_state(state,
73 plane->state->crtc);
74
75 if (WARN_ON(!crtc_state))
76 return;
77
78 crtc_state->planes_changed = true;
79 }
80
81 if (plane_state->crtc) {
82 crtc_state = drm_atomic_get_existing_crtc_state(state,
83 plane_state->crtc);
84
85 if (WARN_ON(!crtc_state))
86 return;
87
88 crtc_state->planes_changed = true;
89 }
90}
91
92static int handle_conflicting_encoders(struct drm_atomic_state *state,
93 bool disable_conflicting_encoders)
94{
95 struct drm_connector_state *conn_state;
96 struct drm_connector *connector;
97 struct drm_connector_list_iter conn_iter;
98 struct drm_encoder *encoder;
99 unsigned encoder_mask = 0;
100 int i, ret = 0;
101
102
103
104
105
106
107 for_each_connector_in_state(state, connector, conn_state, i) {
108 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
109 struct drm_encoder *new_encoder;
110
111 if (!conn_state->crtc)
112 continue;
113
114 if (funcs->atomic_best_encoder)
115 new_encoder = funcs->atomic_best_encoder(connector, conn_state);
116 else if (funcs->best_encoder)
117 new_encoder = funcs->best_encoder(connector);
118 else
119 new_encoder = drm_atomic_helper_best_encoder(connector);
120
121 if (new_encoder) {
122 if (encoder_mask & (1 << drm_encoder_index(new_encoder))) {
123 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n",
124 new_encoder->base.id, new_encoder->name,
125 connector->base.id, connector->name);
126
127 return -EINVAL;
128 }
129
130 encoder_mask |= 1 << drm_encoder_index(new_encoder);
131 }
132 }
133
134 if (!encoder_mask)
135 return 0;
136
137
138
139
140
141
142
143
144
145
146
147
148 drm_connector_list_iter_get(state->dev, &conn_iter);
149 drm_for_each_connector_iter(connector, &conn_iter) {
150 struct drm_crtc_state *crtc_state;
151
152 if (drm_atomic_get_existing_connector_state(state, connector))
153 continue;
154
155 encoder = connector->state->best_encoder;
156 if (!encoder || !(encoder_mask & (1 << drm_encoder_index(encoder))))
157 continue;
158
159 if (!disable_conflicting_encoders) {
160 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n",
161 encoder->base.id, encoder->name,
162 connector->state->crtc->base.id,
163 connector->state->crtc->name,
164 connector->base.id, connector->name);
165 ret = -EINVAL;
166 goto out;
167 }
168
169 conn_state = drm_atomic_get_connector_state(state, connector);
170 if (IS_ERR(conn_state)) {
171 ret = PTR_ERR(conn_state);
172 goto out;
173 }
174
175 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
176 encoder->base.id, encoder->name,
177 conn_state->crtc->base.id, conn_state->crtc->name,
178 connector->base.id, connector->name);
179
180 crtc_state = drm_atomic_get_existing_crtc_state(state, conn_state->crtc);
181
182 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
183 if (ret)
184 goto out;
185
186 if (!crtc_state->connector_mask) {
187 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
188 NULL);
189 if (ret < 0)
190 goto out;
191
192 crtc_state->active = false;
193 }
194 }
195out:
196 drm_connector_list_iter_put(&conn_iter);
197
198 return ret;
199}
200
201static void
202set_best_encoder(struct drm_atomic_state *state,
203 struct drm_connector_state *conn_state,
204 struct drm_encoder *encoder)
205{
206 struct drm_crtc_state *crtc_state;
207 struct drm_crtc *crtc;
208
209 if (conn_state->best_encoder) {
210
211 crtc = conn_state->connector->state->crtc;
212
213
214
215
216
217
218
219 WARN_ON(!crtc && encoder != conn_state->best_encoder);
220 if (crtc) {
221 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
222
223 crtc_state->encoder_mask &=
224 ~(1 << drm_encoder_index(conn_state->best_encoder));
225 }
226 }
227
228 if (encoder) {
229 crtc = conn_state->crtc;
230 WARN_ON(!crtc);
231 if (crtc) {
232 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
233
234 crtc_state->encoder_mask |=
235 1 << drm_encoder_index(encoder);
236 }
237 }
238
239 conn_state->best_encoder = encoder;
240}
241
242static void
243steal_encoder(struct drm_atomic_state *state,
244 struct drm_encoder *encoder)
245{
246 struct drm_crtc_state *crtc_state;
247 struct drm_connector *connector;
248 struct drm_connector_state *connector_state;
249 int i;
250
251 for_each_connector_in_state(state, connector, connector_state, i) {
252 struct drm_crtc *encoder_crtc;
253
254 if (connector_state->best_encoder != encoder)
255 continue;
256
257 encoder_crtc = connector->state->crtc;
258
259 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
260 encoder->base.id, encoder->name,
261 encoder_crtc->base.id, encoder_crtc->name);
262
263 set_best_encoder(state, connector_state, NULL);
264
265 crtc_state = drm_atomic_get_existing_crtc_state(state, encoder_crtc);
266 crtc_state->connectors_changed = true;
267
268 return;
269 }
270}
271
272static int
273update_connector_routing(struct drm_atomic_state *state,
274 struct drm_connector *connector,
275 struct drm_connector_state *connector_state)
276{
277 const struct drm_connector_helper_funcs *funcs;
278 struct drm_encoder *new_encoder;
279 struct drm_crtc_state *crtc_state;
280
281 DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n",
282 connector->base.id,
283 connector->name);
284
285 if (connector->state->crtc != connector_state->crtc) {
286 if (connector->state->crtc) {
287 crtc_state = drm_atomic_get_existing_crtc_state(state, connector->state->crtc);
288 crtc_state->connectors_changed = true;
289 }
290
291 if (connector_state->crtc) {
292 crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc);
293 crtc_state->connectors_changed = true;
294 }
295 }
296
297 if (!connector_state->crtc) {
298 DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n",
299 connector->base.id,
300 connector->name);
301
302 set_best_encoder(state, connector_state, NULL);
303
304 return 0;
305 }
306
307 funcs = connector->helper_private;
308
309 if (funcs->atomic_best_encoder)
310 new_encoder = funcs->atomic_best_encoder(connector,
311 connector_state);
312 else if (funcs->best_encoder)
313 new_encoder = funcs->best_encoder(connector);
314 else
315 new_encoder = drm_atomic_helper_best_encoder(connector);
316
317 if (!new_encoder) {
318 DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n",
319 connector->base.id,
320 connector->name);
321 return -EINVAL;
322 }
323
324 if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) {
325 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d]\n",
326 new_encoder->base.id,
327 new_encoder->name,
328 connector_state->crtc->base.id);
329 return -EINVAL;
330 }
331
332 if (new_encoder == connector_state->best_encoder) {
333 set_best_encoder(state, connector_state, new_encoder);
334
335 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
336 connector->base.id,
337 connector->name,
338 new_encoder->base.id,
339 new_encoder->name,
340 connector_state->crtc->base.id,
341 connector_state->crtc->name);
342
343 return 0;
344 }
345
346 steal_encoder(state, new_encoder);
347
348 set_best_encoder(state, connector_state, new_encoder);
349
350 crtc_state = drm_atomic_get_existing_crtc_state(state, connector_state->crtc);
351 crtc_state->connectors_changed = true;
352
353 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
354 connector->base.id,
355 connector->name,
356 new_encoder->base.id,
357 new_encoder->name,
358 connector_state->crtc->base.id,
359 connector_state->crtc->name);
360
361 return 0;
362}
363
364static int
365mode_fixup(struct drm_atomic_state *state)
366{
367 struct drm_crtc *crtc;
368 struct drm_crtc_state *crtc_state;
369 struct drm_connector *connector;
370 struct drm_connector_state *conn_state;
371 int i;
372 int ret;
373
374 for_each_crtc_in_state(state, crtc, crtc_state, i) {
375 if (!crtc_state->mode_changed &&
376 !crtc_state->connectors_changed)
377 continue;
378
379 drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
380 }
381
382 for_each_connector_in_state(state, connector, conn_state, i) {
383 const struct drm_encoder_helper_funcs *funcs;
384 struct drm_encoder *encoder;
385
386 WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc);
387
388 if (!conn_state->crtc || !conn_state->best_encoder)
389 continue;
390
391 crtc_state = drm_atomic_get_existing_crtc_state(state,
392 conn_state->crtc);
393
394
395
396
397
398 encoder = conn_state->best_encoder;
399 funcs = encoder->helper_private;
400
401 ret = drm_bridge_mode_fixup(encoder->bridge, &crtc_state->mode,
402 &crtc_state->adjusted_mode);
403 if (!ret) {
404 DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
405 return -EINVAL;
406 }
407
408 if (funcs && funcs->atomic_check) {
409 ret = funcs->atomic_check(encoder, crtc_state,
410 conn_state);
411 if (ret) {
412 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n",
413 encoder->base.id, encoder->name);
414 return ret;
415 }
416 } else if (funcs && funcs->mode_fixup) {
417 ret = funcs->mode_fixup(encoder, &crtc_state->mode,
418 &crtc_state->adjusted_mode);
419 if (!ret) {
420 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n",
421 encoder->base.id, encoder->name);
422 return -EINVAL;
423 }
424 }
425 }
426
427 for_each_crtc_in_state(state, crtc, crtc_state, i) {
428 const struct drm_crtc_helper_funcs *funcs;
429
430 if (!crtc_state->enable)
431 continue;
432
433 if (!crtc_state->mode_changed &&
434 !crtc_state->connectors_changed)
435 continue;
436
437 funcs = crtc->helper_private;
438 if (!funcs->mode_fixup)
439 continue;
440
441 ret = funcs->mode_fixup(crtc, &crtc_state->mode,
442 &crtc_state->adjusted_mode);
443 if (!ret) {
444 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n",
445 crtc->base.id, crtc->name);
446 return -EINVAL;
447 }
448 }
449
450 return 0;
451}
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484int
485drm_atomic_helper_check_modeset(struct drm_device *dev,
486 struct drm_atomic_state *state)
487{
488 struct drm_crtc *crtc;
489 struct drm_crtc_state *crtc_state;
490 struct drm_connector *connector;
491 struct drm_connector_state *connector_state;
492 int i, ret;
493
494 for_each_crtc_in_state(state, crtc, crtc_state, i) {
495 if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
496 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
497 crtc->base.id, crtc->name);
498 crtc_state->mode_changed = true;
499 }
500
501 if (crtc->state->enable != crtc_state->enable) {
502 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n",
503 crtc->base.id, crtc->name);
504
505
506
507
508
509
510
511
512
513 crtc_state->mode_changed = true;
514 crtc_state->connectors_changed = true;
515 }
516 }
517
518 ret = handle_conflicting_encoders(state, state->legacy_set_config);
519 if (ret)
520 return ret;
521
522 for_each_connector_in_state(state, connector, connector_state, i) {
523
524
525
526
527
528 ret = update_connector_routing(state, connector,
529 connector_state);
530 if (ret)
531 return ret;
532 }
533
534
535
536
537
538
539
540 for_each_crtc_in_state(state, crtc, crtc_state, i) {
541 bool has_connectors =
542 !!crtc_state->connector_mask;
543
544
545
546
547
548
549 if (crtc->state->active != crtc_state->active) {
550 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n",
551 crtc->base.id, crtc->name);
552 crtc_state->active_changed = true;
553 }
554
555 if (!drm_atomic_crtc_needs_modeset(crtc_state))
556 continue;
557
558 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n",
559 crtc->base.id, crtc->name,
560 crtc_state->enable ? 'y' : 'n',
561 crtc_state->active ? 'y' : 'n');
562
563 ret = drm_atomic_add_affected_connectors(state, crtc);
564 if (ret != 0)
565 return ret;
566
567 ret = drm_atomic_add_affected_planes(state, crtc);
568 if (ret != 0)
569 return ret;
570
571 if (crtc_state->enable != has_connectors) {
572 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
573 crtc->base.id, crtc->name);
574
575 return -EINVAL;
576 }
577 }
578
579 return mode_fixup(state);
580}
581EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599int
600drm_atomic_helper_check_planes(struct drm_device *dev,
601 struct drm_atomic_state *state)
602{
603 struct drm_crtc *crtc;
604 struct drm_crtc_state *crtc_state;
605 struct drm_plane *plane;
606 struct drm_plane_state *plane_state;
607 int i, ret = 0;
608
609 for_each_plane_in_state(state, plane, plane_state, i) {
610 const struct drm_plane_helper_funcs *funcs;
611
612 funcs = plane->helper_private;
613
614 drm_atomic_helper_plane_changed(state, plane_state, plane);
615
616 if (!funcs || !funcs->atomic_check)
617 continue;
618
619 ret = funcs->atomic_check(plane, plane_state);
620 if (ret) {
621 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n",
622 plane->base.id, plane->name);
623 return ret;
624 }
625 }
626
627 for_each_crtc_in_state(state, crtc, crtc_state, i) {
628 const struct drm_crtc_helper_funcs *funcs;
629
630 funcs = crtc->helper_private;
631
632 if (!funcs || !funcs->atomic_check)
633 continue;
634
635 ret = funcs->atomic_check(crtc, crtc_state);
636 if (ret) {
637 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
638 crtc->base.id, crtc->name);
639 return ret;
640 }
641 }
642
643 return ret;
644}
645EXPORT_SYMBOL(drm_atomic_helper_check_planes);
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668int drm_atomic_helper_check(struct drm_device *dev,
669 struct drm_atomic_state *state)
670{
671 int ret;
672
673 ret = drm_atomic_helper_check_modeset(dev, state);
674 if (ret)
675 return ret;
676
677 ret = drm_atomic_helper_check_planes(dev, state);
678 if (ret)
679 return ret;
680
681 return ret;
682}
683EXPORT_SYMBOL(drm_atomic_helper_check);
684
685static void
686disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
687{
688 struct drm_connector *connector;
689 struct drm_connector_state *old_conn_state;
690 struct drm_crtc *crtc;
691 struct drm_crtc_state *old_crtc_state;
692 int i;
693
694 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
695 const struct drm_encoder_helper_funcs *funcs;
696 struct drm_encoder *encoder;
697
698
699
700 if (!old_conn_state->crtc)
701 continue;
702
703 old_crtc_state = drm_atomic_get_existing_crtc_state(old_state,
704 old_conn_state->crtc);
705
706 if (!old_crtc_state->active ||
707 !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
708 continue;
709
710 encoder = old_conn_state->best_encoder;
711
712
713
714
715 if (WARN_ON(!encoder))
716 continue;
717
718 funcs = encoder->helper_private;
719
720 DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
721 encoder->base.id, encoder->name);
722
723
724
725
726
727 drm_bridge_disable(encoder->bridge);
728
729
730 if (funcs) {
731 if (connector->state->crtc && funcs->prepare)
732 funcs->prepare(encoder);
733 else if (funcs->disable)
734 funcs->disable(encoder);
735 else if (funcs->dpms)
736 funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
737 }
738
739 drm_bridge_post_disable(encoder->bridge);
740 }
741
742 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
743 const struct drm_crtc_helper_funcs *funcs;
744
745
746 if (!drm_atomic_crtc_needs_modeset(crtc->state))
747 continue;
748
749 if (!old_crtc_state->active)
750 continue;
751
752 funcs = crtc->helper_private;
753
754 DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n",
755 crtc->base.id, crtc->name);
756
757
758
759 if (crtc->state->enable && funcs->prepare)
760 funcs->prepare(crtc);
761 else if (funcs->atomic_disable)
762 funcs->atomic_disable(crtc, old_crtc_state);
763 else if (funcs->disable)
764 funcs->disable(crtc);
765 else
766 funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
767 }
768}
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783void
784drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
785 struct drm_atomic_state *old_state)
786{
787 struct drm_connector *connector;
788 struct drm_connector_state *old_conn_state;
789 struct drm_crtc *crtc;
790 struct drm_crtc_state *old_crtc_state;
791 int i;
792
793
794 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
795 if (connector->encoder) {
796 WARN_ON(!connector->encoder->crtc);
797
798 connector->encoder->crtc = NULL;
799 connector->encoder = NULL;
800 }
801
802 crtc = connector->state->crtc;
803 if ((!crtc && old_conn_state->crtc) ||
804 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
805 struct drm_property *dpms_prop =
806 dev->mode_config.dpms_property;
807 int mode = DRM_MODE_DPMS_OFF;
808
809 if (crtc && crtc->state->active)
810 mode = DRM_MODE_DPMS_ON;
811
812 connector->dpms = mode;
813 drm_object_property_set_value(&connector->base,
814 dpms_prop, mode);
815 }
816 }
817
818
819 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
820 if (!connector->state->crtc)
821 continue;
822
823 if (WARN_ON(!connector->state->best_encoder))
824 continue;
825
826 connector->encoder = connector->state->best_encoder;
827 connector->encoder->crtc = connector->state->crtc;
828 }
829
830
831 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
832 struct drm_plane *primary = crtc->primary;
833
834 crtc->mode = crtc->state->mode;
835 crtc->enabled = crtc->state->enable;
836
837 if (drm_atomic_get_existing_plane_state(old_state, primary) &&
838 primary->state->crtc == crtc) {
839 crtc->x = primary->state->src_x >> 16;
840 crtc->y = primary->state->src_y >> 16;
841 }
842
843 if (crtc->state->enable)
844 drm_calc_timestamping_constants(crtc,
845 &crtc->state->adjusted_mode);
846 }
847}
848EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
849
850static void
851crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
852{
853 struct drm_crtc *crtc;
854 struct drm_crtc_state *old_crtc_state;
855 struct drm_connector *connector;
856 struct drm_connector_state *old_conn_state;
857 int i;
858
859 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
860 const struct drm_crtc_helper_funcs *funcs;
861
862 if (!crtc->state->mode_changed)
863 continue;
864
865 funcs = crtc->helper_private;
866
867 if (crtc->state->enable && funcs->mode_set_nofb) {
868 DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
869 crtc->base.id, crtc->name);
870
871 funcs->mode_set_nofb(crtc);
872 }
873 }
874
875 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
876 const struct drm_encoder_helper_funcs *funcs;
877 struct drm_crtc_state *new_crtc_state;
878 struct drm_encoder *encoder;
879 struct drm_display_mode *mode, *adjusted_mode;
880
881 if (!connector->state->best_encoder)
882 continue;
883
884 encoder = connector->state->best_encoder;
885 funcs = encoder->helper_private;
886 new_crtc_state = connector->state->crtc->state;
887 mode = &new_crtc_state->mode;
888 adjusted_mode = &new_crtc_state->adjusted_mode;
889
890 if (!new_crtc_state->mode_changed)
891 continue;
892
893 DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n",
894 encoder->base.id, encoder->name);
895
896
897
898
899
900 if (funcs && funcs->atomic_mode_set) {
901 funcs->atomic_mode_set(encoder, new_crtc_state,
902 connector->state);
903 } else if (funcs && funcs->mode_set) {
904 funcs->mode_set(encoder, mode, adjusted_mode);
905 }
906
907 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
908 }
909}
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
926 struct drm_atomic_state *old_state)
927{
928 disable_outputs(dev, old_state);
929
930 drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
931
932 crtc_set_mode(dev, old_state);
933}
934EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
951 struct drm_atomic_state *old_state)
952{
953 struct drm_crtc *crtc;
954 struct drm_crtc_state *old_crtc_state;
955 struct drm_connector *connector;
956 struct drm_connector_state *old_conn_state;
957 int i;
958
959 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
960 const struct drm_crtc_helper_funcs *funcs;
961
962
963 if (!drm_atomic_crtc_needs_modeset(crtc->state))
964 continue;
965
966 if (!crtc->state->active)
967 continue;
968
969 funcs = crtc->helper_private;
970
971 if (crtc->state->enable) {
972 DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
973 crtc->base.id, crtc->name);
974
975 if (funcs->enable)
976 funcs->enable(crtc);
977 else
978 funcs->commit(crtc);
979 }
980 }
981
982 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
983 const struct drm_encoder_helper_funcs *funcs;
984 struct drm_encoder *encoder;
985
986 if (!connector->state->best_encoder)
987 continue;
988
989 if (!connector->state->crtc->state->active ||
990 !drm_atomic_crtc_needs_modeset(connector->state->crtc->state))
991 continue;
992
993 encoder = connector->state->best_encoder;
994 funcs = encoder->helper_private;
995
996 DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
997 encoder->base.id, encoder->name);
998
999
1000
1001
1002
1003 drm_bridge_pre_enable(encoder->bridge);
1004
1005 if (funcs) {
1006 if (funcs->enable)
1007 funcs->enable(encoder);
1008 else if (funcs->commit)
1009 funcs->commit(encoder);
1010 }
1011
1012 drm_bridge_enable(encoder->bridge);
1013 }
1014}
1015EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
1039 struct drm_atomic_state *state,
1040 bool pre_swap)
1041{
1042 struct drm_plane *plane;
1043 struct drm_plane_state *plane_state;
1044 int i, ret;
1045
1046 for_each_plane_in_state(state, plane, plane_state, i) {
1047 if (!pre_swap)
1048 plane_state = plane->state;
1049
1050 if (!plane_state->fence)
1051 continue;
1052
1053 WARN_ON(!plane_state->fb);
1054
1055
1056
1057
1058
1059
1060 ret = dma_fence_wait(plane_state->fence, pre_swap);
1061 if (ret)
1062 return ret;
1063
1064 dma_fence_put(plane_state->fence);
1065 plane_state->fence = NULL;
1066 }
1067
1068 return 0;
1069}
1070EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences);
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083void
1084drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
1085 struct drm_atomic_state *old_state)
1086{
1087 struct drm_crtc *crtc;
1088 struct drm_crtc_state *old_crtc_state;
1089 int i, ret;
1090 unsigned crtc_mask = 0;
1091
1092
1093
1094
1095
1096 if (old_state->legacy_cursor_update)
1097 return;
1098
1099 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1100 struct drm_crtc_state *new_crtc_state = crtc->state;
1101
1102 if (!new_crtc_state->active || !new_crtc_state->planes_changed)
1103 continue;
1104
1105 ret = drm_crtc_vblank_get(crtc);
1106 if (ret != 0)
1107 continue;
1108
1109 crtc_mask |= drm_crtc_mask(crtc);
1110 old_state->crtcs[i].last_vblank_count = drm_crtc_vblank_count(crtc);
1111 }
1112
1113 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1114 if (!(crtc_mask & drm_crtc_mask(crtc)))
1115 continue;
1116
1117 ret = wait_event_timeout(dev->vblank[i].queue,
1118 old_state->crtcs[i].last_vblank_count !=
1119 drm_crtc_vblank_count(crtc),
1120 msecs_to_jiffies(50));
1121
1122 WARN(!ret, "[CRTC:%d] vblank wait timed out\n", crtc->base.id);
1123
1124 drm_crtc_vblank_put(crtc);
1125 }
1126}
1127EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
1153{
1154 struct drm_device *dev = old_state->dev;
1155
1156 drm_atomic_helper_commit_modeset_disables(dev, old_state);
1157
1158 drm_atomic_helper_commit_planes(dev, old_state, 0);
1159
1160 drm_atomic_helper_commit_modeset_enables(dev, old_state);
1161
1162 drm_atomic_helper_commit_hw_done(old_state);
1163
1164 drm_atomic_helper_wait_for_vblanks(dev, old_state);
1165
1166 drm_atomic_helper_cleanup_planes(dev, old_state);
1167}
1168EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
1169
1170static void commit_tail(struct drm_atomic_state *old_state)
1171{
1172 struct drm_device *dev = old_state->dev;
1173 struct drm_mode_config_helper_funcs *funcs;
1174
1175 funcs = dev->mode_config.helper_private;
1176
1177 drm_atomic_helper_wait_for_fences(dev, old_state, false);
1178
1179 drm_atomic_helper_wait_for_dependencies(old_state);
1180
1181 if (funcs && funcs->atomic_commit_tail)
1182 funcs->atomic_commit_tail(old_state);
1183 else
1184 drm_atomic_helper_commit_tail(old_state);
1185
1186 drm_atomic_helper_commit_cleanup_done(old_state);
1187
1188 drm_atomic_state_put(old_state);
1189}
1190
1191static void commit_work(struct work_struct *work)
1192{
1193 struct drm_atomic_state *state = container_of(work,
1194 struct drm_atomic_state,
1195 commit_work);
1196 commit_tail(state);
1197}
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217int drm_atomic_helper_commit(struct drm_device *dev,
1218 struct drm_atomic_state *state,
1219 bool nonblock)
1220{
1221 int ret;
1222
1223 ret = drm_atomic_helper_setup_commit(state, nonblock);
1224 if (ret)
1225 return ret;
1226
1227 INIT_WORK(&state->commit_work, commit_work);
1228
1229 ret = drm_atomic_helper_prepare_planes(dev, state);
1230 if (ret)
1231 return ret;
1232
1233 if (!nonblock) {
1234 ret = drm_atomic_helper_wait_for_fences(dev, state, true);
1235 if (ret) {
1236 drm_atomic_helper_cleanup_planes(dev, state);
1237 return ret;
1238 }
1239 }
1240
1241
1242
1243
1244
1245
1246
1247 drm_atomic_helper_swap_state(state, true);
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 drm_atomic_state_get(state);
1270 if (nonblock)
1271 queue_work(system_unbound_wq, &state->commit_work);
1272 else
1273 commit_tail(state);
1274
1275 return 0;
1276}
1277EXPORT_SYMBOL(drm_atomic_helper_commit);
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320static int stall_checks(struct drm_crtc *crtc, bool nonblock)
1321{
1322 struct drm_crtc_commit *commit, *stall_commit = NULL;
1323 bool completed = true;
1324 int i;
1325 long ret = 0;
1326
1327 spin_lock(&crtc->commit_lock);
1328 i = 0;
1329 list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
1330 if (i == 0) {
1331 completed = try_wait_for_completion(&commit->flip_done);
1332
1333
1334 if (!completed && nonblock) {
1335 spin_unlock(&crtc->commit_lock);
1336 return -EBUSY;
1337 }
1338 } else if (i == 1) {
1339 stall_commit = commit;
1340 drm_crtc_commit_get(stall_commit);
1341 break;
1342 }
1343
1344 i++;
1345 }
1346 spin_unlock(&crtc->commit_lock);
1347
1348 if (!stall_commit)
1349 return 0;
1350
1351
1352
1353
1354 ret = wait_for_completion_interruptible_timeout(&stall_commit->cleanup_done,
1355 10*HZ);
1356 if (ret == 0)
1357 DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
1358 crtc->base.id, crtc->name);
1359
1360 drm_crtc_commit_put(stall_commit);
1361
1362 return ret < 0 ? ret : 0;
1363}
1364
1365static void release_crtc_commit(struct completion *completion)
1366{
1367 struct drm_crtc_commit *commit = container_of(completion,
1368 typeof(*commit),
1369 flip_done);
1370
1371 drm_crtc_commit_put(commit);
1372}
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1418 bool nonblock)
1419{
1420 struct drm_crtc *crtc;
1421 struct drm_crtc_state *crtc_state;
1422 struct drm_crtc_commit *commit;
1423 int i, ret;
1424
1425 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1426 commit = kzalloc(sizeof(*commit), GFP_KERNEL);
1427 if (!commit)
1428 return -ENOMEM;
1429
1430 init_completion(&commit->flip_done);
1431 init_completion(&commit->hw_done);
1432 init_completion(&commit->cleanup_done);
1433 INIT_LIST_HEAD(&commit->commit_entry);
1434 kref_init(&commit->ref);
1435 commit->crtc = crtc;
1436
1437 state->crtcs[i].commit = commit;
1438
1439 ret = stall_checks(crtc, nonblock);
1440 if (ret)
1441 return ret;
1442
1443
1444
1445
1446 if (!crtc->state->active && !crtc_state->active) {
1447 complete_all(&commit->flip_done);
1448 continue;
1449 }
1450
1451
1452 if (state->legacy_cursor_update) {
1453 complete_all(&commit->flip_done);
1454 continue;
1455 }
1456
1457 if (!crtc_state->event) {
1458 commit->event = kzalloc(sizeof(*commit->event),
1459 GFP_KERNEL);
1460 if (!commit->event)
1461 return -ENOMEM;
1462
1463 crtc_state->event = commit->event;
1464 }
1465
1466 crtc_state->event->base.completion = &commit->flip_done;
1467 crtc_state->event->base.completion_release = release_crtc_commit;
1468 drm_crtc_commit_get(commit);
1469 }
1470
1471 return 0;
1472}
1473EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
1474
1475
1476static struct drm_crtc_commit *preceeding_commit(struct drm_crtc *crtc)
1477{
1478 struct drm_crtc_commit *commit;
1479 int i = 0;
1480
1481 list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
1482
1483 if (i == 1)
1484 return commit;
1485 i++;
1486 }
1487
1488 return NULL;
1489}
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
1504{
1505 struct drm_crtc *crtc;
1506 struct drm_crtc_state *crtc_state;
1507 struct drm_crtc_commit *commit;
1508 int i;
1509 long ret;
1510
1511 for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
1512 spin_lock(&crtc->commit_lock);
1513 commit = preceeding_commit(crtc);
1514 if (commit)
1515 drm_crtc_commit_get(commit);
1516 spin_unlock(&crtc->commit_lock);
1517
1518 if (!commit)
1519 continue;
1520
1521 ret = wait_for_completion_timeout(&commit->hw_done,
1522 10*HZ);
1523 if (ret == 0)
1524 DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
1525 crtc->base.id, crtc->name);
1526
1527
1528
1529 ret = wait_for_completion_timeout(&commit->flip_done,
1530 10*HZ);
1531 if (ret == 0)
1532 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1533 crtc->base.id, crtc->name);
1534
1535 drm_crtc_commit_put(commit);
1536 }
1537}
1538EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
1556{
1557 struct drm_crtc *crtc;
1558 struct drm_crtc_state *crtc_state;
1559 struct drm_crtc_commit *commit;
1560 int i;
1561
1562 for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
1563 commit = old_state->crtcs[i].commit;
1564 if (!commit)
1565 continue;
1566
1567
1568 WARN_ON(crtc->state->event);
1569 spin_lock(&crtc->commit_lock);
1570 complete_all(&commit->hw_done);
1571 spin_unlock(&crtc->commit_lock);
1572 }
1573}
1574EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
1588{
1589 struct drm_crtc *crtc;
1590 struct drm_crtc_state *crtc_state;
1591 struct drm_crtc_commit *commit;
1592 int i;
1593 long ret;
1594
1595 for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
1596 commit = old_state->crtcs[i].commit;
1597 if (WARN_ON(!commit))
1598 continue;
1599
1600 spin_lock(&crtc->commit_lock);
1601 complete_all(&commit->cleanup_done);
1602 WARN_ON(!try_wait_for_completion(&commit->hw_done));
1603
1604
1605
1606
1607 if (try_wait_for_completion(&commit->flip_done))
1608 goto del_commit;
1609
1610 spin_unlock(&crtc->commit_lock);
1611
1612
1613
1614
1615 ret = wait_for_completion_timeout(&commit->flip_done,
1616 10*HZ);
1617 if (ret == 0)
1618 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1619 crtc->base.id, crtc->name);
1620
1621 spin_lock(&crtc->commit_lock);
1622del_commit:
1623 list_del(&commit->commit_entry);
1624 spin_unlock(&crtc->commit_lock);
1625 }
1626}
1627EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642int drm_atomic_helper_prepare_planes(struct drm_device *dev,
1643 struct drm_atomic_state *state)
1644{
1645 struct drm_plane *plane;
1646 struct drm_plane_state *plane_state;
1647 int ret, i, j;
1648
1649 for_each_plane_in_state(state, plane, plane_state, i) {
1650 const struct drm_plane_helper_funcs *funcs;
1651
1652 funcs = plane->helper_private;
1653
1654 if (funcs->prepare_fb) {
1655 ret = funcs->prepare_fb(plane, plane_state);
1656 if (ret)
1657 goto fail;
1658 }
1659 }
1660
1661 return 0;
1662
1663fail:
1664 for_each_plane_in_state(state, plane, plane_state, j) {
1665 const struct drm_plane_helper_funcs *funcs;
1666
1667 if (j >= i)
1668 continue;
1669
1670 funcs = plane->helper_private;
1671
1672 if (funcs->cleanup_fb)
1673 funcs->cleanup_fb(plane, plane_state);
1674 }
1675
1676 return ret;
1677}
1678EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
1679
1680static bool plane_crtc_active(const struct drm_plane_state *state)
1681{
1682 return state->crtc && state->crtc->state->active;
1683}
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726void drm_atomic_helper_commit_planes(struct drm_device *dev,
1727 struct drm_atomic_state *old_state,
1728 uint32_t flags)
1729{
1730 struct drm_crtc *crtc;
1731 struct drm_crtc_state *old_crtc_state;
1732 struct drm_plane *plane;
1733 struct drm_plane_state *old_plane_state;
1734 int i;
1735 bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
1736 bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
1737
1738 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1739 const struct drm_crtc_helper_funcs *funcs;
1740
1741 funcs = crtc->helper_private;
1742
1743 if (!funcs || !funcs->atomic_begin)
1744 continue;
1745
1746 if (active_only && !crtc->state->active)
1747 continue;
1748
1749 funcs->atomic_begin(crtc, old_crtc_state);
1750 }
1751
1752 for_each_plane_in_state(old_state, plane, old_plane_state, i) {
1753 const struct drm_plane_helper_funcs *funcs;
1754 bool disabling;
1755
1756 funcs = plane->helper_private;
1757
1758 if (!funcs)
1759 continue;
1760
1761 disabling = drm_atomic_plane_disabling(plane, old_plane_state);
1762
1763 if (active_only) {
1764
1765
1766
1767
1768
1769
1770
1771 if (!disabling && !plane_crtc_active(plane->state))
1772 continue;
1773 if (disabling && !plane_crtc_active(old_plane_state))
1774 continue;
1775 }
1776
1777
1778
1779
1780 if (disabling && funcs->atomic_disable) {
1781 struct drm_crtc_state *crtc_state;
1782
1783 crtc_state = old_plane_state->crtc->state;
1784
1785 if (drm_atomic_crtc_needs_modeset(crtc_state) &&
1786 no_disable)
1787 continue;
1788
1789 funcs->atomic_disable(plane, old_plane_state);
1790 } else if (plane->state->crtc || disabling) {
1791 funcs->atomic_update(plane, old_plane_state);
1792 }
1793 }
1794
1795 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1796 const struct drm_crtc_helper_funcs *funcs;
1797
1798 funcs = crtc->helper_private;
1799
1800 if (!funcs || !funcs->atomic_flush)
1801 continue;
1802
1803 if (active_only && !crtc->state->active)
1804 continue;
1805
1806 funcs->atomic_flush(crtc, old_crtc_state);
1807 }
1808}
1809EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828void
1829drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
1830{
1831 const struct drm_crtc_helper_funcs *crtc_funcs;
1832 struct drm_crtc *crtc = old_crtc_state->crtc;
1833 struct drm_atomic_state *old_state = old_crtc_state->state;
1834 struct drm_plane *plane;
1835 unsigned plane_mask;
1836
1837 plane_mask = old_crtc_state->plane_mask;
1838 plane_mask |= crtc->state->plane_mask;
1839
1840 crtc_funcs = crtc->helper_private;
1841 if (crtc_funcs && crtc_funcs->atomic_begin)
1842 crtc_funcs->atomic_begin(crtc, old_crtc_state);
1843
1844 drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
1845 struct drm_plane_state *old_plane_state =
1846 drm_atomic_get_existing_plane_state(old_state, plane);
1847 const struct drm_plane_helper_funcs *plane_funcs;
1848
1849 plane_funcs = plane->helper_private;
1850
1851 if (!old_plane_state || !plane_funcs)
1852 continue;
1853
1854 WARN_ON(plane->state->crtc && plane->state->crtc != crtc);
1855
1856 if (drm_atomic_plane_disabling(plane, old_plane_state) &&
1857 plane_funcs->atomic_disable)
1858 plane_funcs->atomic_disable(plane, old_plane_state);
1859 else if (plane->state->crtc ||
1860 drm_atomic_plane_disabling(plane, old_plane_state))
1861 plane_funcs->atomic_update(plane, old_plane_state);
1862 }
1863
1864 if (crtc_funcs && crtc_funcs->atomic_flush)
1865 crtc_funcs->atomic_flush(crtc, old_crtc_state);
1866}
1867EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885void
1886drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
1887 bool atomic)
1888{
1889 struct drm_crtc *crtc = old_crtc_state->crtc;
1890 const struct drm_crtc_helper_funcs *crtc_funcs =
1891 crtc->helper_private;
1892 struct drm_plane *plane;
1893
1894 if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
1895 crtc_funcs->atomic_begin(crtc, NULL);
1896
1897 drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
1898 const struct drm_plane_helper_funcs *plane_funcs =
1899 plane->helper_private;
1900
1901 if (!plane_funcs)
1902 continue;
1903
1904 WARN_ON(!plane_funcs->atomic_disable);
1905 if (plane_funcs->atomic_disable)
1906 plane_funcs->atomic_disable(plane, NULL);
1907 }
1908
1909 if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
1910 crtc_funcs->atomic_flush(crtc, NULL);
1911}
1912EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
1927 struct drm_atomic_state *old_state)
1928{
1929 struct drm_plane *plane;
1930 struct drm_plane_state *plane_state;
1931 int i;
1932
1933 for_each_plane_in_state(old_state, plane, plane_state, i) {
1934 const struct drm_plane_helper_funcs *funcs;
1935
1936 funcs = plane->helper_private;
1937
1938 if (funcs->cleanup_fb)
1939 funcs->cleanup_fb(plane, plane_state);
1940 }
1941}
1942EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974void drm_atomic_helper_swap_state(struct drm_atomic_state *state,
1975 bool stall)
1976{
1977 int i;
1978 long ret;
1979 struct drm_connector *connector;
1980 struct drm_connector_state *conn_state;
1981 struct drm_crtc *crtc;
1982 struct drm_crtc_state *crtc_state;
1983 struct drm_plane *plane;
1984 struct drm_plane_state *plane_state;
1985 struct drm_crtc_commit *commit;
1986
1987 if (stall) {
1988 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1989 spin_lock(&crtc->commit_lock);
1990 commit = list_first_entry_or_null(&crtc->commit_list,
1991 struct drm_crtc_commit, commit_entry);
1992 if (commit)
1993 drm_crtc_commit_get(commit);
1994 spin_unlock(&crtc->commit_lock);
1995
1996 if (!commit)
1997 continue;
1998
1999 ret = wait_for_completion_timeout(&commit->hw_done,
2000 10*HZ);
2001 if (ret == 0)
2002 DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
2003 crtc->base.id, crtc->name);
2004 drm_crtc_commit_put(commit);
2005 }
2006 }
2007
2008 for_each_connector_in_state(state, connector, conn_state, i) {
2009 connector->state->state = state;
2010 swap(state->connectors[i].state, connector->state);
2011 connector->state->state = NULL;
2012 }
2013
2014 for_each_crtc_in_state(state, crtc, crtc_state, i) {
2015 crtc->state->state = state;
2016 swap(state->crtcs[i].state, crtc->state);
2017 crtc->state->state = NULL;
2018
2019 if (state->crtcs[i].commit) {
2020 spin_lock(&crtc->commit_lock);
2021 list_add(&state->crtcs[i].commit->commit_entry,
2022 &crtc->commit_list);
2023 spin_unlock(&crtc->commit_lock);
2024
2025 state->crtcs[i].commit->event = NULL;
2026 }
2027 }
2028
2029 for_each_plane_in_state(state, plane, plane_state, i) {
2030 plane->state->state = state;
2031 swap(state->planes[i].state, plane->state);
2032 plane->state->state = NULL;
2033 }
2034}
2035EXPORT_SYMBOL(drm_atomic_helper_swap_state);
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056int drm_atomic_helper_update_plane(struct drm_plane *plane,
2057 struct drm_crtc *crtc,
2058 struct drm_framebuffer *fb,
2059 int crtc_x, int crtc_y,
2060 unsigned int crtc_w, unsigned int crtc_h,
2061 uint32_t src_x, uint32_t src_y,
2062 uint32_t src_w, uint32_t src_h)
2063{
2064 struct drm_atomic_state *state;
2065 struct drm_plane_state *plane_state;
2066 int ret = 0;
2067
2068 state = drm_atomic_state_alloc(plane->dev);
2069 if (!state)
2070 return -ENOMEM;
2071
2072 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2073retry:
2074 plane_state = drm_atomic_get_plane_state(state, plane);
2075 if (IS_ERR(plane_state)) {
2076 ret = PTR_ERR(plane_state);
2077 goto fail;
2078 }
2079
2080 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2081 if (ret != 0)
2082 goto fail;
2083 drm_atomic_set_fb_for_plane(plane_state, fb);
2084 plane_state->crtc_x = crtc_x;
2085 plane_state->crtc_y = crtc_y;
2086 plane_state->crtc_w = crtc_w;
2087 plane_state->crtc_h = crtc_h;
2088 plane_state->src_x = src_x;
2089 plane_state->src_y = src_y;
2090 plane_state->src_w = src_w;
2091 plane_state->src_h = src_h;
2092
2093 if (plane == crtc->cursor)
2094 state->legacy_cursor_update = true;
2095
2096 ret = drm_atomic_commit(state);
2097fail:
2098 if (ret == -EDEADLK)
2099 goto backoff;
2100
2101 drm_atomic_state_put(state);
2102 return ret;
2103
2104backoff:
2105 drm_atomic_state_clear(state);
2106 drm_atomic_legacy_backoff(state);
2107
2108
2109
2110
2111
2112
2113 plane->old_fb = plane->fb;
2114
2115 goto retry;
2116}
2117EXPORT_SYMBOL(drm_atomic_helper_update_plane);
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128int drm_atomic_helper_disable_plane(struct drm_plane *plane)
2129{
2130 struct drm_atomic_state *state;
2131 struct drm_plane_state *plane_state;
2132 int ret = 0;
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142 if (!plane->crtc)
2143 return 0;
2144
2145 state = drm_atomic_state_alloc(plane->dev);
2146 if (!state)
2147 return -ENOMEM;
2148
2149 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc);
2150retry:
2151 plane_state = drm_atomic_get_plane_state(state, plane);
2152 if (IS_ERR(plane_state)) {
2153 ret = PTR_ERR(plane_state);
2154 goto fail;
2155 }
2156
2157 if (plane_state->crtc && (plane == plane->crtc->cursor))
2158 plane_state->state->legacy_cursor_update = true;
2159
2160 ret = __drm_atomic_helper_disable_plane(plane, plane_state);
2161 if (ret != 0)
2162 goto fail;
2163
2164 ret = drm_atomic_commit(state);
2165fail:
2166 if (ret == -EDEADLK)
2167 goto backoff;
2168
2169 drm_atomic_state_put(state);
2170 return ret;
2171
2172backoff:
2173 drm_atomic_state_clear(state);
2174 drm_atomic_legacy_backoff(state);
2175
2176
2177
2178
2179
2180
2181 plane->old_fb = plane->fb;
2182
2183 goto retry;
2184}
2185EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
2186
2187
2188int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
2189 struct drm_plane_state *plane_state)
2190{
2191 int ret;
2192
2193 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
2194 if (ret != 0)
2195 return ret;
2196
2197 drm_atomic_set_fb_for_plane(plane_state, NULL);
2198 plane_state->crtc_x = 0;
2199 plane_state->crtc_y = 0;
2200 plane_state->crtc_w = 0;
2201 plane_state->crtc_h = 0;
2202 plane_state->src_x = 0;
2203 plane_state->src_y = 0;
2204 plane_state->src_w = 0;
2205 plane_state->src_h = 0;
2206
2207 return 0;
2208}
2209
2210static int update_output_state(struct drm_atomic_state *state,
2211 struct drm_mode_set *set)
2212{
2213 struct drm_device *dev = set->crtc->dev;
2214 struct drm_crtc *crtc;
2215 struct drm_crtc_state *crtc_state;
2216 struct drm_connector *connector;
2217 struct drm_connector_state *conn_state;
2218 int ret, i;
2219
2220 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
2221 state->acquire_ctx);
2222 if (ret)
2223 return ret;
2224
2225
2226 ret = drm_atomic_add_affected_connectors(state, set->crtc);
2227 if (ret)
2228 return ret;
2229
2230 for_each_connector_in_state(state, connector, conn_state, i) {
2231 if (conn_state->crtc == set->crtc) {
2232 ret = drm_atomic_set_crtc_for_connector(conn_state,
2233 NULL);
2234 if (ret)
2235 return ret;
2236 }
2237 }
2238
2239
2240 for (i = 0; i < set->num_connectors; i++) {
2241 conn_state = drm_atomic_get_connector_state(state,
2242 set->connectors[i]);
2243 if (IS_ERR(conn_state))
2244 return PTR_ERR(conn_state);
2245
2246 ret = drm_atomic_set_crtc_for_connector(conn_state,
2247 set->crtc);
2248 if (ret)
2249 return ret;
2250 }
2251
2252 for_each_crtc_in_state(state, crtc, crtc_state, i) {
2253
2254
2255
2256
2257 if (crtc == set->crtc)
2258 continue;
2259
2260 if (!crtc_state->connector_mask) {
2261 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
2262 NULL);
2263 if (ret < 0)
2264 return ret;
2265
2266 crtc_state->active = false;
2267 }
2268 }
2269
2270 return 0;
2271}
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282int drm_atomic_helper_set_config(struct drm_mode_set *set)
2283{
2284 struct drm_atomic_state *state;
2285 struct drm_crtc *crtc = set->crtc;
2286 int ret = 0;
2287
2288 state = drm_atomic_state_alloc(crtc->dev);
2289 if (!state)
2290 return -ENOMEM;
2291
2292 state->legacy_set_config = true;
2293 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2294retry:
2295 ret = __drm_atomic_helper_set_config(set, state);
2296 if (ret != 0)
2297 goto fail;
2298
2299 ret = drm_atomic_commit(state);
2300fail:
2301 if (ret == -EDEADLK)
2302 goto backoff;
2303
2304 drm_atomic_state_put(state);
2305 return ret;
2306
2307backoff:
2308 drm_atomic_state_clear(state);
2309 drm_atomic_legacy_backoff(state);
2310
2311
2312
2313
2314
2315
2316 crtc->primary->old_fb = crtc->primary->fb;
2317
2318 goto retry;
2319}
2320EXPORT_SYMBOL(drm_atomic_helper_set_config);
2321
2322
2323int __drm_atomic_helper_set_config(struct drm_mode_set *set,
2324 struct drm_atomic_state *state)
2325{
2326 struct drm_crtc_state *crtc_state;
2327 struct drm_plane_state *primary_state;
2328 struct drm_crtc *crtc = set->crtc;
2329 int hdisplay, vdisplay;
2330 int ret;
2331
2332 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2333 if (IS_ERR(crtc_state))
2334 return PTR_ERR(crtc_state);
2335
2336 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
2337 if (IS_ERR(primary_state))
2338 return PTR_ERR(primary_state);
2339
2340 if (!set->mode) {
2341 WARN_ON(set->fb);
2342 WARN_ON(set->num_connectors);
2343
2344 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
2345 if (ret != 0)
2346 return ret;
2347
2348 crtc_state->active = false;
2349
2350 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
2351 if (ret != 0)
2352 return ret;
2353
2354 drm_atomic_set_fb_for_plane(primary_state, NULL);
2355
2356 goto commit;
2357 }
2358
2359 WARN_ON(!set->fb);
2360 WARN_ON(!set->num_connectors);
2361
2362 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
2363 if (ret != 0)
2364 return ret;
2365
2366 crtc_state->active = true;
2367
2368 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
2369 if (ret != 0)
2370 return ret;
2371
2372 drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
2373
2374 drm_atomic_set_fb_for_plane(primary_state, set->fb);
2375 primary_state->crtc_x = 0;
2376 primary_state->crtc_y = 0;
2377 primary_state->crtc_w = hdisplay;
2378 primary_state->crtc_h = vdisplay;
2379 primary_state->src_x = set->x << 16;
2380 primary_state->src_y = set->y << 16;
2381 if (drm_rotation_90_or_270(primary_state->rotation)) {
2382 primary_state->src_w = vdisplay << 16;
2383 primary_state->src_h = hdisplay << 16;
2384 } else {
2385 primary_state->src_w = hdisplay << 16;
2386 primary_state->src_h = vdisplay << 16;
2387 }
2388
2389commit:
2390 ret = update_output_state(state, set);
2391 if (ret)
2392 return ret;
2393
2394 return 0;
2395}
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418int drm_atomic_helper_disable_all(struct drm_device *dev,
2419 struct drm_modeset_acquire_ctx *ctx)
2420{
2421 struct drm_atomic_state *state;
2422 struct drm_connector *conn;
2423 struct drm_connector_list_iter conn_iter;
2424 int err;
2425
2426 state = drm_atomic_state_alloc(dev);
2427 if (!state)
2428 return -ENOMEM;
2429
2430 state->acquire_ctx = ctx;
2431
2432 drm_connector_list_iter_get(dev, &conn_iter);
2433 drm_for_each_connector_iter(conn, &conn_iter) {
2434 struct drm_crtc *crtc = conn->state->crtc;
2435 struct drm_crtc_state *crtc_state;
2436
2437 if (!crtc || conn->dpms != DRM_MODE_DPMS_ON)
2438 continue;
2439
2440 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2441 if (IS_ERR(crtc_state)) {
2442 err = PTR_ERR(crtc_state);
2443 goto free;
2444 }
2445
2446 crtc_state->active = false;
2447 }
2448
2449 err = drm_atomic_commit(state);
2450free:
2451 drm_connector_list_iter_put(&conn_iter);
2452 drm_atomic_state_put(state);
2453 return err;
2454}
2455EXPORT_SYMBOL(drm_atomic_helper_disable_all);
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
2483{
2484 struct drm_modeset_acquire_ctx ctx;
2485 struct drm_atomic_state *state;
2486 int err;
2487
2488 drm_modeset_acquire_init(&ctx, 0);
2489
2490retry:
2491 err = drm_modeset_lock_all_ctx(dev, &ctx);
2492 if (err < 0) {
2493 state = ERR_PTR(err);
2494 goto unlock;
2495 }
2496
2497 state = drm_atomic_helper_duplicate_state(dev, &ctx);
2498 if (IS_ERR(state))
2499 goto unlock;
2500
2501 err = drm_atomic_helper_disable_all(dev, &ctx);
2502 if (err < 0) {
2503 drm_atomic_state_put(state);
2504 state = ERR_PTR(err);
2505 goto unlock;
2506 }
2507
2508unlock:
2509 if (PTR_ERR(state) == -EDEADLK) {
2510 drm_modeset_backoff(&ctx);
2511 goto retry;
2512 }
2513
2514 drm_modeset_drop_locks(&ctx);
2515 drm_modeset_acquire_fini(&ctx);
2516 return state;
2517}
2518EXPORT_SYMBOL(drm_atomic_helper_suspend);
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536int drm_atomic_helper_resume(struct drm_device *dev,
2537 struct drm_atomic_state *state)
2538{
2539 struct drm_mode_config *config = &dev->mode_config;
2540 int err;
2541
2542 drm_mode_config_reset(dev);
2543 drm_modeset_lock_all(dev);
2544 state->acquire_ctx = config->acquire_ctx;
2545 err = drm_atomic_commit(state);
2546 drm_modeset_unlock_all(dev);
2547
2548 return err;
2549}
2550EXPORT_SYMBOL(drm_atomic_helper_resume);
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564int
2565drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
2566 struct drm_property *property,
2567 uint64_t val)
2568{
2569 struct drm_atomic_state *state;
2570 struct drm_crtc_state *crtc_state;
2571 int ret = 0;
2572
2573 state = drm_atomic_state_alloc(crtc->dev);
2574 if (!state)
2575 return -ENOMEM;
2576
2577
2578 state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
2579retry:
2580 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2581 if (IS_ERR(crtc_state)) {
2582 ret = PTR_ERR(crtc_state);
2583 goto fail;
2584 }
2585
2586 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
2587 property, val);
2588 if (ret)
2589 goto fail;
2590
2591 ret = drm_atomic_commit(state);
2592fail:
2593 if (ret == -EDEADLK)
2594 goto backoff;
2595
2596 drm_atomic_state_put(state);
2597 return ret;
2598
2599backoff:
2600 drm_atomic_state_clear(state);
2601 drm_atomic_legacy_backoff(state);
2602
2603 goto retry;
2604}
2605EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619int
2620drm_atomic_helper_plane_set_property(struct drm_plane *plane,
2621 struct drm_property *property,
2622 uint64_t val)
2623{
2624 struct drm_atomic_state *state;
2625 struct drm_plane_state *plane_state;
2626 int ret = 0;
2627
2628 state = drm_atomic_state_alloc(plane->dev);
2629 if (!state)
2630 return -ENOMEM;
2631
2632
2633 state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
2634retry:
2635 plane_state = drm_atomic_get_plane_state(state, plane);
2636 if (IS_ERR(plane_state)) {
2637 ret = PTR_ERR(plane_state);
2638 goto fail;
2639 }
2640
2641 ret = drm_atomic_plane_set_property(plane, plane_state,
2642 property, val);
2643 if (ret)
2644 goto fail;
2645
2646 ret = drm_atomic_commit(state);
2647fail:
2648 if (ret == -EDEADLK)
2649 goto backoff;
2650
2651 drm_atomic_state_put(state);
2652 return ret;
2653
2654backoff:
2655 drm_atomic_state_clear(state);
2656 drm_atomic_legacy_backoff(state);
2657
2658 goto retry;
2659}
2660EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674int
2675drm_atomic_helper_connector_set_property(struct drm_connector *connector,
2676 struct drm_property *property,
2677 uint64_t val)
2678{
2679 struct drm_atomic_state *state;
2680 struct drm_connector_state *connector_state;
2681 int ret = 0;
2682
2683 state = drm_atomic_state_alloc(connector->dev);
2684 if (!state)
2685 return -ENOMEM;
2686
2687
2688 state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
2689retry:
2690 connector_state = drm_atomic_get_connector_state(state, connector);
2691 if (IS_ERR(connector_state)) {
2692 ret = PTR_ERR(connector_state);
2693 goto fail;
2694 }
2695
2696 ret = drm_atomic_connector_set_property(connector, connector_state,
2697 property, val);
2698 if (ret)
2699 goto fail;
2700
2701 ret = drm_atomic_commit(state);
2702fail:
2703 if (ret == -EDEADLK)
2704 goto backoff;
2705
2706 drm_atomic_state_put(state);
2707 return ret;
2708
2709backoff:
2710 drm_atomic_state_clear(state);
2711 drm_atomic_legacy_backoff(state);
2712
2713 goto retry;
2714}
2715EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
2716
2717static int page_flip_common(
2718 struct drm_atomic_state *state,
2719 struct drm_crtc *crtc,
2720 struct drm_framebuffer *fb,
2721 struct drm_pending_vblank_event *event)
2722{
2723 struct drm_plane *plane = crtc->primary;
2724 struct drm_plane_state *plane_state;
2725 struct drm_crtc_state *crtc_state;
2726 int ret = 0;
2727
2728 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2729 if (IS_ERR(crtc_state))
2730 return PTR_ERR(crtc_state);
2731
2732 crtc_state->event = event;
2733
2734 plane_state = drm_atomic_get_plane_state(state, plane);
2735 if (IS_ERR(plane_state))
2736 return PTR_ERR(plane_state);
2737
2738
2739 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2740 if (ret != 0)
2741 return ret;
2742 drm_atomic_set_fb_for_plane(plane_state, fb);
2743
2744
2745 state->allow_modeset = false;
2746 if (!crtc_state->active) {
2747 DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n",
2748 crtc->base.id);
2749 return -EINVAL;
2750 }
2751
2752 return ret;
2753}
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2776 struct drm_framebuffer *fb,
2777 struct drm_pending_vblank_event *event,
2778 uint32_t flags)
2779{
2780 struct drm_plane *plane = crtc->primary;
2781 struct drm_atomic_state *state;
2782 int ret = 0;
2783
2784 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
2785 return -EINVAL;
2786
2787 state = drm_atomic_state_alloc(plane->dev);
2788 if (!state)
2789 return -ENOMEM;
2790
2791 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2792
2793retry:
2794 ret = page_flip_common(state, crtc, fb, event);
2795 if (ret != 0)
2796 goto fail;
2797
2798 ret = drm_atomic_nonblocking_commit(state);
2799
2800fail:
2801 if (ret == -EDEADLK)
2802 goto backoff;
2803
2804 drm_atomic_state_put(state);
2805 return ret;
2806
2807backoff:
2808 drm_atomic_state_clear(state);
2809 drm_atomic_legacy_backoff(state);
2810
2811
2812
2813
2814
2815
2816 plane->old_fb = plane->fb;
2817
2818 goto retry;
2819}
2820EXPORT_SYMBOL(drm_atomic_helper_page_flip);
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837int drm_atomic_helper_page_flip_target(
2838 struct drm_crtc *crtc,
2839 struct drm_framebuffer *fb,
2840 struct drm_pending_vblank_event *event,
2841 uint32_t flags,
2842 uint32_t target)
2843{
2844 struct drm_plane *plane = crtc->primary;
2845 struct drm_atomic_state *state;
2846 struct drm_crtc_state *crtc_state;
2847 int ret = 0;
2848
2849 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
2850 return -EINVAL;
2851
2852 state = drm_atomic_state_alloc(plane->dev);
2853 if (!state)
2854 return -ENOMEM;
2855
2856 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2857
2858retry:
2859 ret = page_flip_common(state, crtc, fb, event);
2860 if (ret != 0)
2861 goto fail;
2862
2863 crtc_state = drm_atomic_get_existing_crtc_state(state, crtc);
2864 if (WARN_ON(!crtc_state)) {
2865 ret = -EINVAL;
2866 goto fail;
2867 }
2868 crtc_state->target_vblank = target;
2869
2870 ret = drm_atomic_nonblocking_commit(state);
2871
2872fail:
2873 if (ret == -EDEADLK)
2874 goto backoff;
2875
2876 drm_atomic_state_put(state);
2877 return ret;
2878
2879backoff:
2880 drm_atomic_state_clear(state);
2881 drm_atomic_legacy_backoff(state);
2882
2883
2884
2885
2886
2887
2888 plane->old_fb = plane->fb;
2889
2890 goto retry;
2891}
2892EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
2908 int mode)
2909{
2910 struct drm_mode_config *config = &connector->dev->mode_config;
2911 struct drm_atomic_state *state;
2912 struct drm_crtc_state *crtc_state;
2913 struct drm_crtc *crtc;
2914 struct drm_connector *tmp_connector;
2915 struct drm_connector_list_iter conn_iter;
2916 int ret;
2917 bool active = false;
2918 int old_mode = connector->dpms;
2919
2920 if (mode != DRM_MODE_DPMS_ON)
2921 mode = DRM_MODE_DPMS_OFF;
2922
2923 connector->dpms = mode;
2924 crtc = connector->state->crtc;
2925
2926 if (!crtc)
2927 return 0;
2928
2929 state = drm_atomic_state_alloc(connector->dev);
2930 if (!state)
2931 return -ENOMEM;
2932
2933 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2934retry:
2935 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2936 if (IS_ERR(crtc_state)) {
2937 ret = PTR_ERR(crtc_state);
2938 goto fail;
2939 }
2940
2941 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
2942
2943 drm_connector_list_iter_get(connector->dev, &conn_iter);
2944 drm_for_each_connector_iter(tmp_connector, &conn_iter) {
2945 if (tmp_connector->state->crtc != crtc)
2946 continue;
2947
2948 if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
2949 active = true;
2950 break;
2951 }
2952 }
2953 drm_connector_list_iter_put(&conn_iter);
2954 crtc_state->active = active;
2955
2956 ret = drm_atomic_commit(state);
2957fail:
2958 if (ret == -EDEADLK)
2959 goto backoff;
2960 if (ret != 0)
2961 connector->dpms = old_mode;
2962 drm_atomic_state_put(state);
2963 return ret;
2964
2965backoff:
2966 drm_atomic_state_clear(state);
2967 drm_atomic_legacy_backoff(state);
2968
2969 goto retry;
2970}
2971EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982struct drm_encoder *
2983drm_atomic_helper_best_encoder(struct drm_connector *connector)
2984{
2985 WARN_ON(connector->encoder_ids[1]);
2986 return drm_encoder_find(connector->dev, connector->encoder_ids[0]);
2987}
2988EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
3019{
3020 if (crtc->state)
3021 __drm_atomic_helper_crtc_destroy_state(crtc->state);
3022
3023 kfree(crtc->state);
3024 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
3025
3026 if (crtc->state)
3027 crtc->state->crtc = crtc;
3028}
3029EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
3040 struct drm_crtc_state *state)
3041{
3042 memcpy(state, crtc->state, sizeof(*state));
3043
3044 if (state->mode_blob)
3045 drm_property_reference_blob(state->mode_blob);
3046 if (state->degamma_lut)
3047 drm_property_reference_blob(state->degamma_lut);
3048 if (state->ctm)
3049 drm_property_reference_blob(state->ctm);
3050 if (state->gamma_lut)
3051 drm_property_reference_blob(state->gamma_lut);
3052 state->mode_changed = false;
3053 state->active_changed = false;
3054 state->planes_changed = false;
3055 state->connectors_changed = false;
3056 state->color_mgmt_changed = false;
3057 state->zpos_changed = false;
3058 state->event = NULL;
3059}
3060EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
3061
3062
3063
3064
3065
3066
3067
3068
3069struct drm_crtc_state *
3070drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
3071{
3072 struct drm_crtc_state *state;
3073
3074 if (WARN_ON(!crtc->state))
3075 return NULL;
3076
3077 state = kmalloc(sizeof(*state), GFP_KERNEL);
3078 if (state)
3079 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
3080
3081 return state;
3082}
3083EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
3094{
3095 drm_property_unreference_blob(state->mode_blob);
3096 drm_property_unreference_blob(state->degamma_lut);
3097 drm_property_unreference_blob(state->ctm);
3098 drm_property_unreference_blob(state->gamma_lut);
3099}
3100EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
3111 struct drm_crtc_state *state)
3112{
3113 __drm_atomic_helper_crtc_destroy_state(state);
3114 kfree(state);
3115}
3116EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
3117
3118
3119
3120
3121
3122
3123
3124
3125void drm_atomic_helper_plane_reset(struct drm_plane *plane)
3126{
3127 if (plane->state)
3128 __drm_atomic_helper_plane_destroy_state(plane->state);
3129
3130 kfree(plane->state);
3131 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
3132
3133 if (plane->state) {
3134 plane->state->plane = plane;
3135 plane->state->rotation = DRM_ROTATE_0;
3136 }
3137}
3138EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
3149 struct drm_plane_state *state)
3150{
3151 memcpy(state, plane->state, sizeof(*state));
3152
3153 if (state->fb)
3154 drm_framebuffer_reference(state->fb);
3155
3156 state->fence = NULL;
3157}
3158EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
3159
3160
3161
3162
3163
3164
3165
3166
3167struct drm_plane_state *
3168drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
3169{
3170 struct drm_plane_state *state;
3171
3172 if (WARN_ON(!plane->state))
3173 return NULL;
3174
3175 state = kmalloc(sizeof(*state), GFP_KERNEL);
3176 if (state)
3177 __drm_atomic_helper_plane_duplicate_state(plane, state);
3178
3179 return state;
3180}
3181EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
3192{
3193 if (state->fb)
3194 drm_framebuffer_unreference(state->fb);
3195
3196 if (state->fence)
3197 dma_fence_put(state->fence);
3198}
3199EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
3210 struct drm_plane_state *state)
3211{
3212 __drm_atomic_helper_plane_destroy_state(state);
3213 kfree(state);
3214}
3215EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229void
3230__drm_atomic_helper_connector_reset(struct drm_connector *connector,
3231 struct drm_connector_state *conn_state)
3232{
3233 if (conn_state)
3234 conn_state->connector = connector;
3235
3236 connector->state = conn_state;
3237}
3238EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248void drm_atomic_helper_connector_reset(struct drm_connector *connector)
3249{
3250 struct drm_connector_state *conn_state =
3251 kzalloc(sizeof(*conn_state), GFP_KERNEL);
3252
3253 if (connector->state)
3254 __drm_atomic_helper_connector_destroy_state(connector->state);
3255
3256 kfree(connector->state);
3257 __drm_atomic_helper_connector_reset(connector, conn_state);
3258}
3259EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269void
3270__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
3271 struct drm_connector_state *state)
3272{
3273 memcpy(state, connector->state, sizeof(*state));
3274 if (state->crtc)
3275 drm_connector_reference(connector);
3276}
3277EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
3278
3279
3280
3281
3282
3283
3284
3285
3286struct drm_connector_state *
3287drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
3288{
3289 struct drm_connector_state *state;
3290
3291 if (WARN_ON(!connector->state))
3292 return NULL;
3293
3294 state = kmalloc(sizeof(*state), GFP_KERNEL);
3295 if (state)
3296 __drm_atomic_helper_connector_duplicate_state(connector, state);
3297
3298 return state;
3299}
3300EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326struct drm_atomic_state *
3327drm_atomic_helper_duplicate_state(struct drm_device *dev,
3328 struct drm_modeset_acquire_ctx *ctx)
3329{
3330 struct drm_atomic_state *state;
3331 struct drm_connector *conn;
3332 struct drm_connector_list_iter conn_iter;
3333 struct drm_plane *plane;
3334 struct drm_crtc *crtc;
3335 int err = 0;
3336
3337 state = drm_atomic_state_alloc(dev);
3338 if (!state)
3339 return ERR_PTR(-ENOMEM);
3340
3341 state->acquire_ctx = ctx;
3342
3343 drm_for_each_crtc(crtc, dev) {
3344 struct drm_crtc_state *crtc_state;
3345
3346 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3347 if (IS_ERR(crtc_state)) {
3348 err = PTR_ERR(crtc_state);
3349 goto free;
3350 }
3351 }
3352
3353 drm_for_each_plane(plane, dev) {
3354 struct drm_plane_state *plane_state;
3355
3356 plane_state = drm_atomic_get_plane_state(state, plane);
3357 if (IS_ERR(plane_state)) {
3358 err = PTR_ERR(plane_state);
3359 goto free;
3360 }
3361 }
3362
3363 drm_connector_list_iter_get(dev, &conn_iter);
3364 drm_for_each_connector_iter(conn, &conn_iter) {
3365 struct drm_connector_state *conn_state;
3366
3367 conn_state = drm_atomic_get_connector_state(state, conn);
3368 if (IS_ERR(conn_state)) {
3369 err = PTR_ERR(conn_state);
3370 drm_connector_list_iter_put(&conn_iter);
3371 goto free;
3372 }
3373 }
3374 drm_connector_list_iter_put(&conn_iter);
3375
3376
3377 state->acquire_ctx = NULL;
3378
3379free:
3380 if (err < 0) {
3381 drm_atomic_state_put(state);
3382 state = ERR_PTR(err);
3383 }
3384
3385 return state;
3386}
3387EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397void
3398__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
3399{
3400 if (state->crtc)
3401 drm_connector_unreference(state->connector);
3402}
3403EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
3414 struct drm_connector_state *state)
3415{
3416 __drm_atomic_helper_connector_destroy_state(state);
3417 kfree(state);
3418}
3419EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3434 u16 *red, u16 *green, u16 *blue,
3435 uint32_t size)
3436{
3437 struct drm_device *dev = crtc->dev;
3438 struct drm_mode_config *config = &dev->mode_config;
3439 struct drm_atomic_state *state;
3440 struct drm_crtc_state *crtc_state;
3441 struct drm_property_blob *blob = NULL;
3442 struct drm_color_lut *blob_data;
3443 int i, ret = 0;
3444
3445 state = drm_atomic_state_alloc(crtc->dev);
3446 if (!state)
3447 return -ENOMEM;
3448
3449 blob = drm_property_create_blob(dev,
3450 sizeof(struct drm_color_lut) * size,
3451 NULL);
3452 if (IS_ERR(blob)) {
3453 ret = PTR_ERR(blob);
3454 blob = NULL;
3455 goto fail;
3456 }
3457
3458
3459 blob_data = (struct drm_color_lut *) blob->data;
3460 for (i = 0; i < size; i++) {
3461 blob_data[i].red = red[i];
3462 blob_data[i].green = green[i];
3463 blob_data[i].blue = blue[i];
3464 }
3465
3466 state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
3467retry:
3468 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3469 if (IS_ERR(crtc_state)) {
3470 ret = PTR_ERR(crtc_state);
3471 goto fail;
3472 }
3473
3474
3475 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
3476 config->degamma_lut_property, 0);
3477 if (ret)
3478 goto fail;
3479
3480 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
3481 config->ctm_property, 0);
3482 if (ret)
3483 goto fail;
3484
3485 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
3486 config->gamma_lut_property, blob->base.id);
3487 if (ret)
3488 goto fail;
3489
3490 ret = drm_atomic_commit(state);
3491fail:
3492 if (ret == -EDEADLK)
3493 goto backoff;
3494
3495 drm_atomic_state_put(state);
3496 drm_property_unreference_blob(blob);
3497 return ret;
3498
3499backoff:
3500 drm_atomic_state_clear(state);
3501 drm_atomic_legacy_backoff(state);
3502
3503 goto retry;
3504}
3505EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
3506