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/fence.h>
34
35
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
62static void
63drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
64 struct drm_plane_state *plane_state,
65 struct drm_plane *plane)
66{
67 struct drm_crtc_state *crtc_state;
68
69 if (plane->state->crtc) {
70 crtc_state = state->crtc_states[drm_crtc_index(plane->state->crtc)];
71
72 if (WARN_ON(!crtc_state))
73 return;
74
75 crtc_state->planes_changed = true;
76 }
77
78 if (plane_state->crtc) {
79 crtc_state =
80 state->crtc_states[drm_crtc_index(plane_state->crtc)];
81
82 if (WARN_ON(!crtc_state))
83 return;
84
85 crtc_state->planes_changed = true;
86 }
87}
88
89static bool
90check_pending_encoder_assignment(struct drm_atomic_state *state,
91 struct drm_encoder *new_encoder)
92{
93 struct drm_connector *connector;
94 struct drm_connector_state *conn_state;
95 int i;
96
97 for_each_connector_in_state(state, connector, conn_state, i) {
98 if (conn_state->best_encoder != new_encoder)
99 continue;
100
101
102 if (connector->state->best_encoder != conn_state->best_encoder)
103 return false;
104 }
105
106 return true;
107}
108
109static struct drm_crtc *
110get_current_crtc_for_encoder(struct drm_device *dev,
111 struct drm_encoder *encoder)
112{
113 struct drm_mode_config *config = &dev->mode_config;
114 struct drm_connector *connector;
115
116 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
117
118 drm_for_each_connector(connector, dev) {
119 if (connector->state->best_encoder != encoder)
120 continue;
121
122 return connector->state->crtc;
123 }
124
125 return NULL;
126}
127
128static int
129steal_encoder(struct drm_atomic_state *state,
130 struct drm_encoder *encoder,
131 struct drm_crtc *encoder_crtc)
132{
133 struct drm_mode_config *config = &state->dev->mode_config;
134 struct drm_crtc_state *crtc_state;
135 struct drm_connector *connector;
136 struct drm_connector_state *connector_state;
137 int ret;
138
139
140
141
142
143 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
144
145 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
146 encoder->base.id, encoder->name,
147 encoder_crtc->base.id, encoder_crtc->name);
148
149 crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc);
150 if (IS_ERR(crtc_state))
151 return PTR_ERR(crtc_state);
152
153 crtc_state->connectors_changed = true;
154
155 list_for_each_entry(connector, &config->connector_list, head) {
156 if (connector->state->best_encoder != encoder)
157 continue;
158
159 DRM_DEBUG_ATOMIC("Stealing encoder from [CONNECTOR:%d:%s]\n",
160 connector->base.id,
161 connector->name);
162
163 connector_state = drm_atomic_get_connector_state(state,
164 connector);
165 if (IS_ERR(connector_state))
166 return PTR_ERR(connector_state);
167
168 ret = drm_atomic_set_crtc_for_connector(connector_state, NULL);
169 if (ret)
170 return ret;
171 connector_state->best_encoder = NULL;
172 }
173
174 return 0;
175}
176
177static int
178update_connector_routing(struct drm_atomic_state *state, int conn_idx)
179{
180 const struct drm_connector_helper_funcs *funcs;
181 struct drm_encoder *new_encoder;
182 struct drm_crtc *encoder_crtc;
183 struct drm_connector *connector;
184 struct drm_connector_state *connector_state;
185 struct drm_crtc_state *crtc_state;
186 int idx, ret;
187
188 connector = state->connectors[conn_idx];
189 connector_state = state->connector_states[conn_idx];
190
191 if (!connector)
192 return 0;
193
194 DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n",
195 connector->base.id,
196 connector->name);
197
198 if (connector->state->crtc != connector_state->crtc) {
199 if (connector->state->crtc) {
200 idx = drm_crtc_index(connector->state->crtc);
201
202 crtc_state = state->crtc_states[idx];
203 crtc_state->connectors_changed = true;
204 }
205
206 if (connector_state->crtc) {
207 idx = drm_crtc_index(connector_state->crtc);
208
209 crtc_state = state->crtc_states[idx];
210 crtc_state->connectors_changed = true;
211 }
212 }
213
214 if (!connector_state->crtc) {
215 DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n",
216 connector->base.id,
217 connector->name);
218
219 connector_state->best_encoder = NULL;
220
221 return 0;
222 }
223
224 funcs = connector->helper_private;
225
226 if (funcs->atomic_best_encoder)
227 new_encoder = funcs->atomic_best_encoder(connector,
228 connector_state);
229 else
230 new_encoder = funcs->best_encoder(connector);
231
232 if (!new_encoder) {
233 DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n",
234 connector->base.id,
235 connector->name);
236 return -EINVAL;
237 }
238
239 if (!drm_encoder_crtc_ok(new_encoder, connector_state->crtc)) {
240 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d]\n",
241 new_encoder->base.id,
242 new_encoder->name,
243 connector_state->crtc->base.id);
244 return -EINVAL;
245 }
246
247 if (new_encoder == connector_state->best_encoder) {
248 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
249 connector->base.id,
250 connector->name,
251 new_encoder->base.id,
252 new_encoder->name,
253 connector_state->crtc->base.id,
254 connector_state->crtc->name);
255
256 return 0;
257 }
258
259 if (!check_pending_encoder_assignment(state, new_encoder)) {
260 DRM_DEBUG_ATOMIC("Encoder for [CONNECTOR:%d:%s] already assigned\n",
261 connector->base.id,
262 connector->name);
263 return -EINVAL;
264 }
265
266 encoder_crtc = get_current_crtc_for_encoder(state->dev,
267 new_encoder);
268
269 if (encoder_crtc) {
270 ret = steal_encoder(state, new_encoder, encoder_crtc);
271 if (ret) {
272 DRM_DEBUG_ATOMIC("Encoder stealing failed for [CONNECTOR:%d:%s]\n",
273 connector->base.id,
274 connector->name);
275 return ret;
276 }
277 }
278
279 if (WARN_ON(!connector_state->crtc))
280 return -EINVAL;
281
282 connector_state->best_encoder = new_encoder;
283 idx = drm_crtc_index(connector_state->crtc);
284
285 crtc_state = state->crtc_states[idx];
286 crtc_state->connectors_changed = true;
287
288 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
289 connector->base.id,
290 connector->name,
291 new_encoder->base.id,
292 new_encoder->name,
293 connector_state->crtc->base.id,
294 connector_state->crtc->name);
295
296 return 0;
297}
298
299static int
300mode_fixup(struct drm_atomic_state *state)
301{
302 struct drm_crtc *crtc;
303 struct drm_crtc_state *crtc_state;
304 struct drm_connector *connector;
305 struct drm_connector_state *conn_state;
306 int i;
307 bool ret;
308
309 for_each_crtc_in_state(state, crtc, crtc_state, i) {
310 if (!crtc_state->mode_changed &&
311 !crtc_state->connectors_changed)
312 continue;
313
314 drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
315 }
316
317 for_each_connector_in_state(state, connector, conn_state, i) {
318 const struct drm_encoder_helper_funcs *funcs;
319 struct drm_encoder *encoder;
320
321 WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc);
322
323 if (!conn_state->crtc || !conn_state->best_encoder)
324 continue;
325
326 crtc_state =
327 state->crtc_states[drm_crtc_index(conn_state->crtc)];
328
329
330
331
332
333 encoder = conn_state->best_encoder;
334 funcs = encoder->helper_private;
335 if (!funcs)
336 continue;
337
338 ret = drm_bridge_mode_fixup(encoder->bridge, &crtc_state->mode,
339 &crtc_state->adjusted_mode);
340 if (!ret) {
341 DRM_DEBUG_ATOMIC("Bridge fixup failed\n");
342 return -EINVAL;
343 }
344
345 if (funcs->atomic_check) {
346 ret = funcs->atomic_check(encoder, crtc_state,
347 conn_state);
348 if (ret) {
349 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n",
350 encoder->base.id, encoder->name);
351 return ret;
352 }
353 } else if (funcs->mode_fixup) {
354 ret = funcs->mode_fixup(encoder, &crtc_state->mode,
355 &crtc_state->adjusted_mode);
356 if (!ret) {
357 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n",
358 encoder->base.id, encoder->name);
359 return -EINVAL;
360 }
361 }
362 }
363
364 for_each_crtc_in_state(state, crtc, crtc_state, i) {
365 const struct drm_crtc_helper_funcs *funcs;
366
367 if (!crtc_state->mode_changed &&
368 !crtc_state->connectors_changed)
369 continue;
370
371 funcs = crtc->helper_private;
372 if (!funcs->mode_fixup)
373 continue;
374
375 ret = funcs->mode_fixup(crtc, &crtc_state->mode,
376 &crtc_state->adjusted_mode);
377 if (!ret) {
378 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n",
379 crtc->base.id, crtc->name);
380 return -EINVAL;
381 }
382 }
383
384 return 0;
385}
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414int
415drm_atomic_helper_check_modeset(struct drm_device *dev,
416 struct drm_atomic_state *state)
417{
418 struct drm_crtc *crtc;
419 struct drm_crtc_state *crtc_state;
420 struct drm_connector *connector;
421 struct drm_connector_state *connector_state;
422 int i, ret;
423
424 for_each_crtc_in_state(state, crtc, crtc_state, i) {
425 if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
426 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode changed\n",
427 crtc->base.id, crtc->name);
428 crtc_state->mode_changed = true;
429 }
430
431 if (crtc->state->enable != crtc_state->enable) {
432 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enable changed\n",
433 crtc->base.id, crtc->name);
434
435
436
437
438
439
440
441
442
443 crtc_state->mode_changed = true;
444 crtc_state->connectors_changed = true;
445 }
446 }
447
448 for_each_connector_in_state(state, connector, connector_state, i) {
449
450
451
452
453
454 ret = update_connector_routing(state, i);
455 if (ret)
456 return ret;
457 }
458
459
460
461
462
463
464
465 for_each_crtc_in_state(state, crtc, crtc_state, i) {
466 bool has_connectors =
467 !!crtc_state->connector_mask;
468
469
470
471
472
473
474 if (crtc->state->active != crtc_state->active) {
475 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active changed\n",
476 crtc->base.id, crtc->name);
477 crtc_state->active_changed = true;
478 }
479
480 if (!drm_atomic_crtc_needs_modeset(crtc_state))
481 continue;
482
483 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] needs all connectors, enable: %c, active: %c\n",
484 crtc->base.id, crtc->name,
485 crtc_state->enable ? 'y' : 'n',
486 crtc_state->active ? 'y' : 'n');
487
488 ret = drm_atomic_add_affected_connectors(state, crtc);
489 if (ret != 0)
490 return ret;
491
492 ret = drm_atomic_add_affected_planes(state, crtc);
493 if (ret != 0)
494 return ret;
495
496 if (crtc_state->enable != has_connectors) {
497 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] enabled/connectors mismatch\n",
498 crtc->base.id, crtc->name);
499
500 return -EINVAL;
501 }
502 }
503
504 return mode_fixup(state);
505}
506EXPORT_SYMBOL(drm_atomic_helper_check_modeset);
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523int
524drm_atomic_helper_check_planes(struct drm_device *dev,
525 struct drm_atomic_state *state)
526{
527 struct drm_crtc *crtc;
528 struct drm_crtc_state *crtc_state;
529 struct drm_plane *plane;
530 struct drm_plane_state *plane_state;
531 int i, ret = 0;
532
533 for_each_plane_in_state(state, plane, plane_state, i) {
534 const struct drm_plane_helper_funcs *funcs;
535
536 funcs = plane->helper_private;
537
538 drm_atomic_helper_plane_changed(state, plane_state, plane);
539
540 if (!funcs || !funcs->atomic_check)
541 continue;
542
543 ret = funcs->atomic_check(plane, plane_state);
544 if (ret) {
545 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n",
546 plane->base.id, plane->name);
547 return ret;
548 }
549 }
550
551 for_each_crtc_in_state(state, crtc, crtc_state, i) {
552 const struct drm_crtc_helper_funcs *funcs;
553
554 funcs = crtc->helper_private;
555
556 if (!funcs || !funcs->atomic_check)
557 continue;
558
559 ret = funcs->atomic_check(crtc, state->crtc_states[i]);
560 if (ret) {
561 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
562 crtc->base.id, crtc->name);
563 return ret;
564 }
565 }
566
567 return ret;
568}
569EXPORT_SYMBOL(drm_atomic_helper_check_planes);
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591int drm_atomic_helper_check(struct drm_device *dev,
592 struct drm_atomic_state *state)
593{
594 int ret;
595
596 ret = drm_atomic_helper_check_modeset(dev, state);
597 if (ret)
598 return ret;
599
600 ret = drm_atomic_helper_check_planes(dev, state);
601 if (ret)
602 return ret;
603
604 return ret;
605}
606EXPORT_SYMBOL(drm_atomic_helper_check);
607
608static void
609disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
610{
611 struct drm_connector *connector;
612 struct drm_connector_state *old_conn_state;
613 struct drm_crtc *crtc;
614 struct drm_crtc_state *old_crtc_state;
615 int i;
616
617 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
618 const struct drm_encoder_helper_funcs *funcs;
619 struct drm_encoder *encoder;
620 struct drm_crtc_state *old_crtc_state;
621
622
623
624 if (!old_conn_state->crtc)
625 continue;
626
627 old_crtc_state = old_state->crtc_states[drm_crtc_index(old_conn_state->crtc)];
628
629 if (!old_crtc_state->active ||
630 !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
631 continue;
632
633 encoder = old_conn_state->best_encoder;
634
635
636
637
638 if (WARN_ON(!encoder))
639 continue;
640
641 funcs = encoder->helper_private;
642
643 DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
644 encoder->base.id, encoder->name);
645
646
647
648
649
650 drm_bridge_disable(encoder->bridge);
651
652
653 if (connector->state->crtc && funcs->prepare)
654 funcs->prepare(encoder);
655 else if (funcs->disable)
656 funcs->disable(encoder);
657 else
658 funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
659
660 drm_bridge_post_disable(encoder->bridge);
661 }
662
663 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
664 const struct drm_crtc_helper_funcs *funcs;
665
666
667 if (!drm_atomic_crtc_needs_modeset(crtc->state))
668 continue;
669
670 if (!old_crtc_state->active)
671 continue;
672
673 funcs = crtc->helper_private;
674
675 DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n",
676 crtc->base.id, crtc->name);
677
678
679
680 if (crtc->state->enable && funcs->prepare)
681 funcs->prepare(crtc);
682 else if (funcs->disable)
683 funcs->disable(crtc);
684 else
685 funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
686 }
687}
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702void
703drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
704 struct drm_atomic_state *old_state)
705{
706 struct drm_connector *connector;
707 struct drm_connector_state *old_conn_state;
708 struct drm_crtc *crtc;
709 struct drm_crtc_state *old_crtc_state;
710 int i;
711
712
713 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
714 if (connector->encoder) {
715 WARN_ON(!connector->encoder->crtc);
716
717 connector->encoder->crtc = NULL;
718 connector->encoder = NULL;
719 }
720
721 crtc = connector->state->crtc;
722 if ((!crtc && old_conn_state->crtc) ||
723 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
724 struct drm_property *dpms_prop =
725 dev->mode_config.dpms_property;
726 int mode = DRM_MODE_DPMS_OFF;
727
728 if (crtc && crtc->state->active)
729 mode = DRM_MODE_DPMS_ON;
730
731 connector->dpms = mode;
732 drm_object_property_set_value(&connector->base,
733 dpms_prop, mode);
734 }
735 }
736
737
738 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
739 if (!connector->state->crtc)
740 continue;
741
742 if (WARN_ON(!connector->state->best_encoder))
743 continue;
744
745 connector->encoder = connector->state->best_encoder;
746 connector->encoder->crtc = connector->state->crtc;
747 }
748
749
750 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
751 struct drm_plane *primary = crtc->primary;
752
753 crtc->mode = crtc->state->mode;
754 crtc->enabled = crtc->state->enable;
755
756 if (drm_atomic_get_existing_plane_state(old_state, primary) &&
757 primary->state->crtc == crtc) {
758 crtc->x = primary->state->src_x >> 16;
759 crtc->y = primary->state->src_y >> 16;
760 }
761
762 if (crtc->state->enable)
763 drm_calc_timestamping_constants(crtc,
764 &crtc->state->adjusted_mode);
765 }
766}
767EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
768
769static void
770crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
771{
772 struct drm_crtc *crtc;
773 struct drm_crtc_state *old_crtc_state;
774 struct drm_connector *connector;
775 struct drm_connector_state *old_conn_state;
776 int i;
777
778 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
779 const struct drm_crtc_helper_funcs *funcs;
780
781 if (!crtc->state->mode_changed)
782 continue;
783
784 funcs = crtc->helper_private;
785
786 if (crtc->state->enable && funcs->mode_set_nofb) {
787 DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
788 crtc->base.id, crtc->name);
789
790 funcs->mode_set_nofb(crtc);
791 }
792 }
793
794 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
795 const struct drm_encoder_helper_funcs *funcs;
796 struct drm_crtc_state *new_crtc_state;
797 struct drm_encoder *encoder;
798 struct drm_display_mode *mode, *adjusted_mode;
799
800 if (!connector->state->best_encoder)
801 continue;
802
803 encoder = connector->state->best_encoder;
804 funcs = encoder->helper_private;
805 new_crtc_state = connector->state->crtc->state;
806 mode = &new_crtc_state->mode;
807 adjusted_mode = &new_crtc_state->adjusted_mode;
808
809 if (!new_crtc_state->mode_changed)
810 continue;
811
812 DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n",
813 encoder->base.id, encoder->name);
814
815
816
817
818
819 if (funcs->mode_set)
820 funcs->mode_set(encoder, mode, adjusted_mode);
821
822 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
823 }
824}
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
841 struct drm_atomic_state *old_state)
842{
843 disable_outputs(dev, old_state);
844
845 drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
846
847 crtc_set_mode(dev, old_state);
848}
849EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
866 struct drm_atomic_state *old_state)
867{
868 struct drm_crtc *crtc;
869 struct drm_crtc_state *old_crtc_state;
870 struct drm_connector *connector;
871 struct drm_connector_state *old_conn_state;
872 int i;
873
874 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
875 const struct drm_crtc_helper_funcs *funcs;
876
877
878 if (!drm_atomic_crtc_needs_modeset(crtc->state))
879 continue;
880
881 if (!crtc->state->active)
882 continue;
883
884 funcs = crtc->helper_private;
885
886 if (crtc->state->enable) {
887 DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
888 crtc->base.id, crtc->name);
889
890 if (funcs->enable)
891 funcs->enable(crtc);
892 else
893 funcs->commit(crtc);
894 }
895 }
896
897 for_each_connector_in_state(old_state, connector, old_conn_state, i) {
898 const struct drm_encoder_helper_funcs *funcs;
899 struct drm_encoder *encoder;
900
901 if (!connector->state->best_encoder)
902 continue;
903
904 if (!connector->state->crtc->state->active ||
905 !drm_atomic_crtc_needs_modeset(connector->state->crtc->state))
906 continue;
907
908 encoder = connector->state->best_encoder;
909 funcs = encoder->helper_private;
910
911 DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
912 encoder->base.id, encoder->name);
913
914
915
916
917
918 drm_bridge_pre_enable(encoder->bridge);
919
920 if (funcs->enable)
921 funcs->enable(encoder);
922 else
923 funcs->commit(encoder);
924
925 drm_bridge_enable(encoder->bridge);
926 }
927}
928EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
929
930static void wait_for_fences(struct drm_device *dev,
931 struct drm_atomic_state *state)
932{
933 struct drm_plane *plane;
934 struct drm_plane_state *plane_state;
935 int i;
936
937 for_each_plane_in_state(state, plane, plane_state, i) {
938 if (!plane->state->fence)
939 continue;
940
941 WARN_ON(!plane->state->fb);
942
943 fence_wait(plane->state->fence, false);
944 fence_put(plane->state->fence);
945 plane->state->fence = NULL;
946 }
947}
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
964 struct drm_atomic_state *old_state,
965 struct drm_crtc *crtc)
966{
967 struct drm_plane *plane;
968 struct drm_plane_state *old_plane_state;
969 int i;
970
971 for_each_plane_in_state(old_state, plane, old_plane_state, i) {
972 if (plane->state->crtc != crtc &&
973 old_plane_state->crtc != crtc)
974 continue;
975
976 if (plane->state->fb != old_plane_state->fb)
977 return true;
978 }
979
980 return false;
981}
982EXPORT_SYMBOL(drm_atomic_helper_framebuffer_changed);
983
984
985
986
987
988
989
990
991
992
993
994
995void
996drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
997 struct drm_atomic_state *old_state)
998{
999 struct drm_crtc *crtc;
1000 struct drm_crtc_state *old_crtc_state;
1001 int i, ret;
1002
1003 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1004
1005
1006
1007 old_crtc_state->enable = false;
1008
1009 if (!crtc->state->enable)
1010 continue;
1011
1012
1013
1014 if (old_state->legacy_cursor_update)
1015 continue;
1016
1017 if (!drm_atomic_helper_framebuffer_changed(dev,
1018 old_state, crtc))
1019 continue;
1020
1021 ret = drm_crtc_vblank_get(crtc);
1022 if (ret != 0)
1023 continue;
1024
1025 old_crtc_state->enable = true;
1026 old_crtc_state->last_vblank_count = drm_crtc_vblank_count(crtc);
1027 }
1028
1029 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1030 if (!old_crtc_state->enable)
1031 continue;
1032
1033 ret = wait_event_timeout(dev->vblank[i].queue,
1034 old_crtc_state->last_vblank_count !=
1035 drm_crtc_vblank_count(crtc),
1036 msecs_to_jiffies(50));
1037
1038 drm_crtc_vblank_put(crtc);
1039 }
1040}
1041EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072int drm_atomic_helper_commit(struct drm_device *dev,
1073 struct drm_atomic_state *state,
1074 bool async)
1075{
1076 int ret;
1077
1078 if (async)
1079 return -EBUSY;
1080
1081 ret = drm_atomic_helper_prepare_planes(dev, state);
1082 if (ret)
1083 return ret;
1084
1085
1086
1087
1088
1089
1090
1091 drm_atomic_helper_swap_state(dev, state);
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109 wait_for_fences(dev, state);
1110
1111 drm_atomic_helper_commit_modeset_disables(dev, state);
1112
1113 drm_atomic_helper_commit_planes(dev, state, false);
1114
1115 drm_atomic_helper_commit_modeset_enables(dev, state);
1116
1117 drm_atomic_helper_wait_for_vblanks(dev, state);
1118
1119 drm_atomic_helper_cleanup_planes(dev, state);
1120
1121 drm_atomic_state_free(state);
1122
1123 return 0;
1124}
1125EXPORT_SYMBOL(drm_atomic_helper_commit);
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177int drm_atomic_helper_prepare_planes(struct drm_device *dev,
1178 struct drm_atomic_state *state)
1179{
1180 int nplanes = dev->mode_config.num_total_plane;
1181 int ret, i;
1182
1183 for (i = 0; i < nplanes; i++) {
1184 const struct drm_plane_helper_funcs *funcs;
1185 struct drm_plane *plane = state->planes[i];
1186 struct drm_plane_state *plane_state = state->plane_states[i];
1187
1188 if (!plane)
1189 continue;
1190
1191 funcs = plane->helper_private;
1192
1193 if (funcs->prepare_fb) {
1194 ret = funcs->prepare_fb(plane, plane_state);
1195 if (ret)
1196 goto fail;
1197 }
1198 }
1199
1200 return 0;
1201
1202fail:
1203 for (i--; i >= 0; i--) {
1204 const struct drm_plane_helper_funcs *funcs;
1205 struct drm_plane *plane = state->planes[i];
1206 struct drm_plane_state *plane_state = state->plane_states[i];
1207
1208 if (!plane)
1209 continue;
1210
1211 funcs = plane->helper_private;
1212
1213 if (funcs->cleanup_fb)
1214 funcs->cleanup_fb(plane, plane_state);
1215
1216 }
1217
1218 return ret;
1219}
1220EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
1221
1222bool plane_crtc_active(struct drm_plane_state *state)
1223{
1224 return state->crtc && state->crtc->state->active;
1225}
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261void drm_atomic_helper_commit_planes(struct drm_device *dev,
1262 struct drm_atomic_state *old_state,
1263 bool active_only)
1264{
1265 struct drm_crtc *crtc;
1266 struct drm_crtc_state *old_crtc_state;
1267 struct drm_plane *plane;
1268 struct drm_plane_state *old_plane_state;
1269 int i;
1270
1271 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1272 const struct drm_crtc_helper_funcs *funcs;
1273
1274 funcs = crtc->helper_private;
1275
1276 if (!funcs || !funcs->atomic_begin)
1277 continue;
1278
1279 if (active_only && !crtc->state->active)
1280 continue;
1281
1282 funcs->atomic_begin(crtc, old_crtc_state);
1283 }
1284
1285 for_each_plane_in_state(old_state, plane, old_plane_state, i) {
1286 const struct drm_plane_helper_funcs *funcs;
1287 bool disabling;
1288
1289 funcs = plane->helper_private;
1290
1291 if (!funcs)
1292 continue;
1293
1294 disabling = drm_atomic_plane_disabling(plane, old_plane_state);
1295
1296 if (active_only) {
1297
1298
1299
1300
1301
1302
1303
1304 if (!disabling && !plane_crtc_active(plane->state))
1305 continue;
1306 if (disabling && !plane_crtc_active(old_plane_state))
1307 continue;
1308 }
1309
1310
1311
1312
1313 if (disabling && funcs->atomic_disable)
1314 funcs->atomic_disable(plane, old_plane_state);
1315 else if (plane->state->crtc || disabling)
1316 funcs->atomic_update(plane, old_plane_state);
1317 }
1318
1319 for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1320 const struct drm_crtc_helper_funcs *funcs;
1321
1322 funcs = crtc->helper_private;
1323
1324 if (!funcs || !funcs->atomic_flush)
1325 continue;
1326
1327 if (active_only && !crtc->state->active)
1328 continue;
1329
1330 funcs->atomic_flush(crtc, old_crtc_state);
1331 }
1332}
1333EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352void
1353drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
1354{
1355 const struct drm_crtc_helper_funcs *crtc_funcs;
1356 struct drm_crtc *crtc = old_crtc_state->crtc;
1357 struct drm_atomic_state *old_state = old_crtc_state->state;
1358 struct drm_plane *plane;
1359 unsigned plane_mask;
1360
1361 plane_mask = old_crtc_state->plane_mask;
1362 plane_mask |= crtc->state->plane_mask;
1363
1364 crtc_funcs = crtc->helper_private;
1365 if (crtc_funcs && crtc_funcs->atomic_begin)
1366 crtc_funcs->atomic_begin(crtc, old_crtc_state);
1367
1368 drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
1369 struct drm_plane_state *old_plane_state =
1370 drm_atomic_get_existing_plane_state(old_state, plane);
1371 const struct drm_plane_helper_funcs *plane_funcs;
1372
1373 plane_funcs = plane->helper_private;
1374
1375 if (!old_plane_state || !plane_funcs)
1376 continue;
1377
1378 WARN_ON(plane->state->crtc && plane->state->crtc != crtc);
1379
1380 if (drm_atomic_plane_disabling(plane, old_plane_state) &&
1381 plane_funcs->atomic_disable)
1382 plane_funcs->atomic_disable(plane, old_plane_state);
1383 else if (plane->state->crtc ||
1384 drm_atomic_plane_disabling(plane, old_plane_state))
1385 plane_funcs->atomic_update(plane, old_plane_state);
1386 }
1387
1388 if (crtc_funcs && crtc_funcs->atomic_flush)
1389 crtc_funcs->atomic_flush(crtc, old_crtc_state);
1390}
1391EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409void drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc *crtc,
1410 bool atomic)
1411{
1412 const struct drm_crtc_helper_funcs *crtc_funcs =
1413 crtc->helper_private;
1414 struct drm_plane *plane;
1415
1416 if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
1417 crtc_funcs->atomic_begin(crtc, NULL);
1418
1419 drm_for_each_plane(plane, crtc->dev) {
1420 const struct drm_plane_helper_funcs *plane_funcs =
1421 plane->helper_private;
1422
1423 if (plane->state->crtc != crtc || !plane_funcs)
1424 continue;
1425
1426 WARN_ON(!plane_funcs->atomic_disable);
1427 if (plane_funcs->atomic_disable)
1428 plane_funcs->atomic_disable(plane, NULL);
1429 }
1430
1431 if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
1432 crtc_funcs->atomic_flush(crtc, NULL);
1433}
1434EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
1449 struct drm_atomic_state *old_state)
1450{
1451 struct drm_plane *plane;
1452 struct drm_plane_state *plane_state;
1453 int i;
1454
1455 for_each_plane_in_state(old_state, plane, plane_state, i) {
1456 const struct drm_plane_helper_funcs *funcs;
1457
1458 funcs = plane->helper_private;
1459
1460 if (funcs->cleanup_fb)
1461 funcs->cleanup_fb(plane, plane_state);
1462 }
1463}
1464EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491void drm_atomic_helper_swap_state(struct drm_device *dev,
1492 struct drm_atomic_state *state)
1493{
1494 int i;
1495
1496 for (i = 0; i < state->num_connector; i++) {
1497 struct drm_connector *connector = state->connectors[i];
1498
1499 if (!connector)
1500 continue;
1501
1502 connector->state->state = state;
1503 swap(state->connector_states[i], connector->state);
1504 connector->state->state = NULL;
1505 }
1506
1507 for (i = 0; i < dev->mode_config.num_crtc; i++) {
1508 struct drm_crtc *crtc = state->crtcs[i];
1509
1510 if (!crtc)
1511 continue;
1512
1513 crtc->state->state = state;
1514 swap(state->crtc_states[i], crtc->state);
1515 crtc->state->state = NULL;
1516 }
1517
1518 for (i = 0; i < dev->mode_config.num_total_plane; i++) {
1519 struct drm_plane *plane = state->planes[i];
1520
1521 if (!plane)
1522 continue;
1523
1524 plane->state->state = state;
1525 swap(state->plane_states[i], plane->state);
1526 plane->state->state = NULL;
1527 }
1528}
1529EXPORT_SYMBOL(drm_atomic_helper_swap_state);
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550int drm_atomic_helper_update_plane(struct drm_plane *plane,
1551 struct drm_crtc *crtc,
1552 struct drm_framebuffer *fb,
1553 int crtc_x, int crtc_y,
1554 unsigned int crtc_w, unsigned int crtc_h,
1555 uint32_t src_x, uint32_t src_y,
1556 uint32_t src_w, uint32_t src_h)
1557{
1558 struct drm_atomic_state *state;
1559 struct drm_plane_state *plane_state;
1560 int ret = 0;
1561
1562 state = drm_atomic_state_alloc(plane->dev);
1563 if (!state)
1564 return -ENOMEM;
1565
1566 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1567retry:
1568 plane_state = drm_atomic_get_plane_state(state, plane);
1569 if (IS_ERR(plane_state)) {
1570 ret = PTR_ERR(plane_state);
1571 goto fail;
1572 }
1573
1574 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
1575 if (ret != 0)
1576 goto fail;
1577 drm_atomic_set_fb_for_plane(plane_state, fb);
1578 plane_state->crtc_x = crtc_x;
1579 plane_state->crtc_y = crtc_y;
1580 plane_state->crtc_w = crtc_w;
1581 plane_state->crtc_h = crtc_h;
1582 plane_state->src_x = src_x;
1583 plane_state->src_y = src_y;
1584 plane_state->src_w = src_w;
1585 plane_state->src_h = src_h;
1586
1587 if (plane == crtc->cursor)
1588 state->legacy_cursor_update = true;
1589
1590 ret = drm_atomic_commit(state);
1591 if (ret != 0)
1592 goto fail;
1593
1594
1595 return 0;
1596fail:
1597 if (ret == -EDEADLK)
1598 goto backoff;
1599
1600 drm_atomic_state_free(state);
1601
1602 return ret;
1603backoff:
1604 drm_atomic_state_clear(state);
1605 drm_atomic_legacy_backoff(state);
1606
1607
1608
1609
1610
1611
1612 plane->old_fb = plane->fb;
1613
1614 goto retry;
1615}
1616EXPORT_SYMBOL(drm_atomic_helper_update_plane);
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627int drm_atomic_helper_disable_plane(struct drm_plane *plane)
1628{
1629 struct drm_atomic_state *state;
1630 struct drm_plane_state *plane_state;
1631 int ret = 0;
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641 if (!plane->crtc)
1642 return 0;
1643
1644 state = drm_atomic_state_alloc(plane->dev);
1645 if (!state)
1646 return -ENOMEM;
1647
1648 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc);
1649retry:
1650 plane_state = drm_atomic_get_plane_state(state, plane);
1651 if (IS_ERR(plane_state)) {
1652 ret = PTR_ERR(plane_state);
1653 goto fail;
1654 }
1655
1656 if (plane_state->crtc && (plane == plane->crtc->cursor))
1657 plane_state->state->legacy_cursor_update = true;
1658
1659 ret = __drm_atomic_helper_disable_plane(plane, plane_state);
1660 if (ret != 0)
1661 goto fail;
1662
1663 ret = drm_atomic_commit(state);
1664 if (ret != 0)
1665 goto fail;
1666
1667
1668 return 0;
1669fail:
1670 if (ret == -EDEADLK)
1671 goto backoff;
1672
1673 drm_atomic_state_free(state);
1674
1675 return ret;
1676backoff:
1677 drm_atomic_state_clear(state);
1678 drm_atomic_legacy_backoff(state);
1679
1680
1681
1682
1683
1684
1685 plane->old_fb = plane->fb;
1686
1687 goto retry;
1688}
1689EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
1690
1691
1692int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
1693 struct drm_plane_state *plane_state)
1694{
1695 int ret;
1696
1697 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
1698 if (ret != 0)
1699 return ret;
1700
1701 drm_atomic_set_fb_for_plane(plane_state, NULL);
1702 plane_state->crtc_x = 0;
1703 plane_state->crtc_y = 0;
1704 plane_state->crtc_w = 0;
1705 plane_state->crtc_h = 0;
1706 plane_state->src_x = 0;
1707 plane_state->src_y = 0;
1708 plane_state->src_w = 0;
1709 plane_state->src_h = 0;
1710
1711 return 0;
1712}
1713
1714static int update_output_state(struct drm_atomic_state *state,
1715 struct drm_mode_set *set)
1716{
1717 struct drm_device *dev = set->crtc->dev;
1718 struct drm_crtc *crtc;
1719 struct drm_crtc_state *crtc_state;
1720 struct drm_connector *connector;
1721 struct drm_connector_state *conn_state;
1722 int ret, i, j;
1723
1724 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1725 state->acquire_ctx);
1726 if (ret)
1727 return ret;
1728
1729
1730 for (i = 0; i < set->num_connectors; i++) {
1731 conn_state = drm_atomic_get_connector_state(state,
1732 set->connectors[i]);
1733 if (IS_ERR(conn_state))
1734 return PTR_ERR(conn_state);
1735 }
1736
1737 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1738 ret = drm_atomic_add_affected_connectors(state, crtc);
1739 if (ret)
1740 return ret;
1741 }
1742
1743
1744 for_each_connector_in_state(state, connector, conn_state, i) {
1745 if (conn_state->crtc == set->crtc) {
1746 ret = drm_atomic_set_crtc_for_connector(conn_state,
1747 NULL);
1748 if (ret)
1749 return ret;
1750 }
1751
1752 for (j = 0; j < set->num_connectors; j++) {
1753 if (set->connectors[j] == connector) {
1754 ret = drm_atomic_set_crtc_for_connector(conn_state,
1755 set->crtc);
1756 if (ret)
1757 return ret;
1758 break;
1759 }
1760 }
1761 }
1762
1763 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1764
1765
1766
1767
1768 if (crtc == set->crtc)
1769 continue;
1770
1771 if (!crtc_state->connector_mask) {
1772 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
1773 NULL);
1774 if (ret < 0)
1775 return ret;
1776
1777 crtc_state->active = false;
1778 }
1779 }
1780
1781 return 0;
1782}
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793int drm_atomic_helper_set_config(struct drm_mode_set *set)
1794{
1795 struct drm_atomic_state *state;
1796 struct drm_crtc *crtc = set->crtc;
1797 int ret = 0;
1798
1799 state = drm_atomic_state_alloc(crtc->dev);
1800 if (!state)
1801 return -ENOMEM;
1802
1803 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1804retry:
1805 ret = __drm_atomic_helper_set_config(set, state);
1806 if (ret != 0)
1807 goto fail;
1808
1809 ret = drm_atomic_commit(state);
1810 if (ret != 0)
1811 goto fail;
1812
1813
1814 return 0;
1815fail:
1816 if (ret == -EDEADLK)
1817 goto backoff;
1818
1819 drm_atomic_state_free(state);
1820
1821 return ret;
1822backoff:
1823 drm_atomic_state_clear(state);
1824 drm_atomic_legacy_backoff(state);
1825
1826
1827
1828
1829
1830
1831 crtc->primary->old_fb = crtc->primary->fb;
1832
1833 goto retry;
1834}
1835EXPORT_SYMBOL(drm_atomic_helper_set_config);
1836
1837
1838int __drm_atomic_helper_set_config(struct drm_mode_set *set,
1839 struct drm_atomic_state *state)
1840{
1841 struct drm_crtc_state *crtc_state;
1842 struct drm_plane_state *primary_state;
1843 struct drm_crtc *crtc = set->crtc;
1844 int hdisplay, vdisplay;
1845 int ret;
1846
1847 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1848 if (IS_ERR(crtc_state))
1849 return PTR_ERR(crtc_state);
1850
1851 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1852 if (IS_ERR(primary_state))
1853 return PTR_ERR(primary_state);
1854
1855 if (!set->mode) {
1856 WARN_ON(set->fb);
1857 WARN_ON(set->num_connectors);
1858
1859 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1860 if (ret != 0)
1861 return ret;
1862
1863 crtc_state->active = false;
1864
1865 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
1866 if (ret != 0)
1867 return ret;
1868
1869 drm_atomic_set_fb_for_plane(primary_state, NULL);
1870
1871 goto commit;
1872 }
1873
1874 WARN_ON(!set->fb);
1875 WARN_ON(!set->num_connectors);
1876
1877 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
1878 if (ret != 0)
1879 return ret;
1880
1881 crtc_state->active = true;
1882
1883 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
1884 if (ret != 0)
1885 return ret;
1886
1887 drm_crtc_get_hv_timing(set->mode, &hdisplay, &vdisplay);
1888
1889 drm_atomic_set_fb_for_plane(primary_state, set->fb);
1890 primary_state->crtc_x = 0;
1891 primary_state->crtc_y = 0;
1892 primary_state->crtc_w = hdisplay;
1893 primary_state->crtc_h = vdisplay;
1894 primary_state->src_x = set->x << 16;
1895 primary_state->src_y = set->y << 16;
1896 if (primary_state->rotation & (BIT(DRM_ROTATE_90) | BIT(DRM_ROTATE_270))) {
1897 primary_state->src_w = vdisplay << 16;
1898 primary_state->src_h = hdisplay << 16;
1899 } else {
1900 primary_state->src_w = hdisplay << 16;
1901 primary_state->src_h = vdisplay << 16;
1902 }
1903
1904commit:
1905 ret = update_output_state(state, set);
1906 if (ret)
1907 return ret;
1908
1909 return 0;
1910}
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933int drm_atomic_helper_disable_all(struct drm_device *dev,
1934 struct drm_modeset_acquire_ctx *ctx)
1935{
1936 struct drm_atomic_state *state;
1937 struct drm_connector *conn;
1938 int err;
1939
1940 state = drm_atomic_state_alloc(dev);
1941 if (!state)
1942 return -ENOMEM;
1943
1944 state->acquire_ctx = ctx;
1945
1946 drm_for_each_connector(conn, dev) {
1947 struct drm_crtc *crtc = conn->state->crtc;
1948 struct drm_crtc_state *crtc_state;
1949
1950 if (!crtc || conn->dpms != DRM_MODE_DPMS_ON)
1951 continue;
1952
1953 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1954 if (IS_ERR(crtc_state)) {
1955 err = PTR_ERR(crtc_state);
1956 goto free;
1957 }
1958
1959 crtc_state->active = false;
1960 }
1961
1962 err = drm_atomic_commit(state);
1963
1964free:
1965 if (err < 0)
1966 drm_atomic_state_free(state);
1967
1968 return err;
1969}
1970EXPORT_SYMBOL(drm_atomic_helper_disable_all);
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
1998{
1999 struct drm_modeset_acquire_ctx ctx;
2000 struct drm_atomic_state *state;
2001 int err;
2002
2003 drm_modeset_acquire_init(&ctx, 0);
2004
2005retry:
2006 err = drm_modeset_lock_all_ctx(dev, &ctx);
2007 if (err < 0) {
2008 state = ERR_PTR(err);
2009 goto unlock;
2010 }
2011
2012 state = drm_atomic_helper_duplicate_state(dev, &ctx);
2013 if (IS_ERR(state))
2014 goto unlock;
2015
2016 err = drm_atomic_helper_disable_all(dev, &ctx);
2017 if (err < 0) {
2018 drm_atomic_state_free(state);
2019 state = ERR_PTR(err);
2020 goto unlock;
2021 }
2022
2023unlock:
2024 if (PTR_ERR(state) == -EDEADLK) {
2025 drm_modeset_backoff(&ctx);
2026 goto retry;
2027 }
2028
2029 drm_modeset_drop_locks(&ctx);
2030 drm_modeset_acquire_fini(&ctx);
2031 return state;
2032}
2033EXPORT_SYMBOL(drm_atomic_helper_suspend);
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051int drm_atomic_helper_resume(struct drm_device *dev,
2052 struct drm_atomic_state *state)
2053{
2054 struct drm_mode_config *config = &dev->mode_config;
2055 int err;
2056
2057 drm_mode_config_reset(dev);
2058 drm_modeset_lock_all(dev);
2059 state->acquire_ctx = config->acquire_ctx;
2060 err = drm_atomic_commit(state);
2061 drm_modeset_unlock_all(dev);
2062
2063 return err;
2064}
2065EXPORT_SYMBOL(drm_atomic_helper_resume);
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079int
2080drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
2081 struct drm_property *property,
2082 uint64_t val)
2083{
2084 struct drm_atomic_state *state;
2085 struct drm_crtc_state *crtc_state;
2086 int ret = 0;
2087
2088 state = drm_atomic_state_alloc(crtc->dev);
2089 if (!state)
2090 return -ENOMEM;
2091
2092
2093 state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
2094retry:
2095 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2096 if (IS_ERR(crtc_state)) {
2097 ret = PTR_ERR(crtc_state);
2098 goto fail;
2099 }
2100
2101 ret = drm_atomic_crtc_set_property(crtc, crtc_state,
2102 property, val);
2103 if (ret)
2104 goto fail;
2105
2106 ret = drm_atomic_commit(state);
2107 if (ret != 0)
2108 goto fail;
2109
2110
2111 return 0;
2112fail:
2113 if (ret == -EDEADLK)
2114 goto backoff;
2115
2116 drm_atomic_state_free(state);
2117
2118 return ret;
2119backoff:
2120 drm_atomic_state_clear(state);
2121 drm_atomic_legacy_backoff(state);
2122
2123 goto retry;
2124}
2125EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139int
2140drm_atomic_helper_plane_set_property(struct drm_plane *plane,
2141 struct drm_property *property,
2142 uint64_t val)
2143{
2144 struct drm_atomic_state *state;
2145 struct drm_plane_state *plane_state;
2146 int ret = 0;
2147
2148 state = drm_atomic_state_alloc(plane->dev);
2149 if (!state)
2150 return -ENOMEM;
2151
2152
2153 state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
2154retry:
2155 plane_state = drm_atomic_get_plane_state(state, plane);
2156 if (IS_ERR(plane_state)) {
2157 ret = PTR_ERR(plane_state);
2158 goto fail;
2159 }
2160
2161 ret = drm_atomic_plane_set_property(plane, plane_state,
2162 property, val);
2163 if (ret)
2164 goto fail;
2165
2166 ret = drm_atomic_commit(state);
2167 if (ret != 0)
2168 goto fail;
2169
2170
2171 return 0;
2172fail:
2173 if (ret == -EDEADLK)
2174 goto backoff;
2175
2176 drm_atomic_state_free(state);
2177
2178 return ret;
2179backoff:
2180 drm_atomic_state_clear(state);
2181 drm_atomic_legacy_backoff(state);
2182
2183 goto retry;
2184}
2185EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199int
2200drm_atomic_helper_connector_set_property(struct drm_connector *connector,
2201 struct drm_property *property,
2202 uint64_t val)
2203{
2204 struct drm_atomic_state *state;
2205 struct drm_connector_state *connector_state;
2206 int ret = 0;
2207
2208 state = drm_atomic_state_alloc(connector->dev);
2209 if (!state)
2210 return -ENOMEM;
2211
2212
2213 state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
2214retry:
2215 connector_state = drm_atomic_get_connector_state(state, connector);
2216 if (IS_ERR(connector_state)) {
2217 ret = PTR_ERR(connector_state);
2218 goto fail;
2219 }
2220
2221 ret = drm_atomic_connector_set_property(connector, connector_state,
2222 property, val);
2223 if (ret)
2224 goto fail;
2225
2226 ret = drm_atomic_commit(state);
2227 if (ret != 0)
2228 goto fail;
2229
2230
2231 return 0;
2232fail:
2233 if (ret == -EDEADLK)
2234 goto backoff;
2235
2236 drm_atomic_state_free(state);
2237
2238 return ret;
2239backoff:
2240 drm_atomic_state_clear(state);
2241 drm_atomic_legacy_backoff(state);
2242
2243 goto retry;
2244}
2245EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
2264 struct drm_framebuffer *fb,
2265 struct drm_pending_vblank_event *event,
2266 uint32_t flags)
2267{
2268 struct drm_plane *plane = crtc->primary;
2269 struct drm_atomic_state *state;
2270 struct drm_plane_state *plane_state;
2271 struct drm_crtc_state *crtc_state;
2272 int ret = 0;
2273
2274 if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
2275 return -EINVAL;
2276
2277 state = drm_atomic_state_alloc(plane->dev);
2278 if (!state)
2279 return -ENOMEM;
2280
2281 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2282retry:
2283 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2284 if (IS_ERR(crtc_state)) {
2285 ret = PTR_ERR(crtc_state);
2286 goto fail;
2287 }
2288 crtc_state->event = event;
2289
2290 plane_state = drm_atomic_get_plane_state(state, plane);
2291 if (IS_ERR(plane_state)) {
2292 ret = PTR_ERR(plane_state);
2293 goto fail;
2294 }
2295
2296 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2297 if (ret != 0)
2298 goto fail;
2299 drm_atomic_set_fb_for_plane(plane_state, fb);
2300
2301
2302 state->allow_modeset = false;
2303 if (!crtc_state->active) {
2304 DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n",
2305 crtc->base.id);
2306 ret = -EINVAL;
2307 goto fail;
2308 }
2309
2310 ret = drm_atomic_async_commit(state);
2311 if (ret != 0)
2312 goto fail;
2313
2314
2315 return 0;
2316fail:
2317 if (ret == -EDEADLK)
2318 goto backoff;
2319
2320 drm_atomic_state_free(state);
2321
2322 return ret;
2323backoff:
2324 drm_atomic_state_clear(state);
2325 drm_atomic_legacy_backoff(state);
2326
2327
2328
2329
2330
2331
2332 plane->old_fb = plane->fb;
2333
2334 goto retry;
2335}
2336EXPORT_SYMBOL(drm_atomic_helper_page_flip);
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351int drm_atomic_helper_connector_dpms(struct drm_connector *connector,
2352 int mode)
2353{
2354 struct drm_mode_config *config = &connector->dev->mode_config;
2355 struct drm_atomic_state *state;
2356 struct drm_crtc_state *crtc_state;
2357 struct drm_crtc *crtc;
2358 struct drm_connector *tmp_connector;
2359 int ret;
2360 bool active = false;
2361 int old_mode = connector->dpms;
2362
2363 if (mode != DRM_MODE_DPMS_ON)
2364 mode = DRM_MODE_DPMS_OFF;
2365
2366 connector->dpms = mode;
2367 crtc = connector->state->crtc;
2368
2369 if (!crtc)
2370 return 0;
2371
2372 state = drm_atomic_state_alloc(connector->dev);
2373 if (!state)
2374 return -ENOMEM;
2375
2376 state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
2377retry:
2378 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2379 if (IS_ERR(crtc_state)) {
2380 ret = PTR_ERR(crtc_state);
2381 goto fail;
2382 }
2383
2384 WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
2385
2386 drm_for_each_connector(tmp_connector, connector->dev) {
2387 if (tmp_connector->state->crtc != crtc)
2388 continue;
2389
2390 if (tmp_connector->dpms == DRM_MODE_DPMS_ON) {
2391 active = true;
2392 break;
2393 }
2394 }
2395 crtc_state->active = active;
2396
2397 ret = drm_atomic_commit(state);
2398 if (ret != 0)
2399 goto fail;
2400
2401
2402 return 0;
2403fail:
2404 if (ret == -EDEADLK)
2405 goto backoff;
2406
2407 connector->dpms = old_mode;
2408 drm_atomic_state_free(state);
2409
2410 return ret;
2411backoff:
2412 drm_atomic_state_clear(state);
2413 drm_atomic_legacy_backoff(state);
2414
2415 goto retry;
2416}
2417EXPORT_SYMBOL(drm_atomic_helper_connector_dpms);
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
2448{
2449 if (crtc->state)
2450 drm_property_unreference_blob(crtc->state->mode_blob);
2451 kfree(crtc->state);
2452 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
2453
2454 if (crtc->state)
2455 crtc->state->crtc = crtc;
2456}
2457EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
2468 struct drm_crtc_state *state)
2469{
2470 memcpy(state, crtc->state, sizeof(*state));
2471
2472 if (state->mode_blob)
2473 drm_property_reference_blob(state->mode_blob);
2474 state->mode_changed = false;
2475 state->active_changed = false;
2476 state->planes_changed = false;
2477 state->connectors_changed = false;
2478 state->event = NULL;
2479}
2480EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
2481
2482
2483
2484
2485
2486
2487
2488
2489struct drm_crtc_state *
2490drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
2491{
2492 struct drm_crtc_state *state;
2493
2494 if (WARN_ON(!crtc->state))
2495 return NULL;
2496
2497 state = kmalloc(sizeof(*state), GFP_KERNEL);
2498 if (state)
2499 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
2500
2501 return state;
2502}
2503EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2515 struct drm_crtc_state *state)
2516{
2517 drm_property_unreference_blob(state->mode_blob);
2518}
2519EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2530 struct drm_crtc_state *state)
2531{
2532 __drm_atomic_helper_crtc_destroy_state(crtc, state);
2533 kfree(state);
2534}
2535EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
2536
2537
2538
2539
2540
2541
2542
2543
2544void drm_atomic_helper_plane_reset(struct drm_plane *plane)
2545{
2546 if (plane->state && plane->state->fb)
2547 drm_framebuffer_unreference(plane->state->fb);
2548
2549 kfree(plane->state);
2550 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
2551
2552 if (plane->state)
2553 plane->state->plane = plane;
2554}
2555EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
2566 struct drm_plane_state *state)
2567{
2568 memcpy(state, plane->state, sizeof(*state));
2569
2570 if (state->fb)
2571 drm_framebuffer_reference(state->fb);
2572}
2573EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
2574
2575
2576
2577
2578
2579
2580
2581
2582struct drm_plane_state *
2583drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
2584{
2585 struct drm_plane_state *state;
2586
2587 if (WARN_ON(!plane->state))
2588 return NULL;
2589
2590 state = kmalloc(sizeof(*state), GFP_KERNEL);
2591 if (state)
2592 __drm_atomic_helper_plane_duplicate_state(plane, state);
2593
2594 return state;
2595}
2596EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
2608 struct drm_plane_state *state)
2609{
2610 if (state->fb)
2611 drm_framebuffer_unreference(state->fb);
2612}
2613EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
2624 struct drm_plane_state *state)
2625{
2626 __drm_atomic_helper_plane_destroy_state(plane, state);
2627 kfree(state);
2628}
2629EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642void
2643__drm_atomic_helper_connector_reset(struct drm_connector *connector,
2644 struct drm_connector_state *conn_state)
2645{
2646 if (conn_state)
2647 conn_state->connector = connector;
2648
2649 connector->state = conn_state;
2650}
2651EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661void drm_atomic_helper_connector_reset(struct drm_connector *connector)
2662{
2663 struct drm_connector_state *conn_state =
2664 kzalloc(sizeof(*conn_state), GFP_KERNEL);
2665
2666 kfree(connector->state);
2667 __drm_atomic_helper_connector_reset(connector, conn_state);
2668}
2669EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679void
2680__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
2681 struct drm_connector_state *state)
2682{
2683 memcpy(state, connector->state, sizeof(*state));
2684}
2685EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
2686
2687
2688
2689
2690
2691
2692
2693
2694struct drm_connector_state *
2695drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
2696{
2697 struct drm_connector_state *state;
2698
2699 if (WARN_ON(!connector->state))
2700 return NULL;
2701
2702 state = kmalloc(sizeof(*state), GFP_KERNEL);
2703 if (state)
2704 __drm_atomic_helper_connector_duplicate_state(connector, state);
2705
2706 return state;
2707}
2708EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734struct drm_atomic_state *
2735drm_atomic_helper_duplicate_state(struct drm_device *dev,
2736 struct drm_modeset_acquire_ctx *ctx)
2737{
2738 struct drm_atomic_state *state;
2739 struct drm_connector *conn;
2740 struct drm_plane *plane;
2741 struct drm_crtc *crtc;
2742 int err = 0;
2743
2744 state = drm_atomic_state_alloc(dev);
2745 if (!state)
2746 return ERR_PTR(-ENOMEM);
2747
2748 state->acquire_ctx = ctx;
2749
2750 drm_for_each_crtc(crtc, dev) {
2751 struct drm_crtc_state *crtc_state;
2752
2753 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2754 if (IS_ERR(crtc_state)) {
2755 err = PTR_ERR(crtc_state);
2756 goto free;
2757 }
2758 }
2759
2760 drm_for_each_plane(plane, dev) {
2761 struct drm_plane_state *plane_state;
2762
2763 plane_state = drm_atomic_get_plane_state(state, plane);
2764 if (IS_ERR(plane_state)) {
2765 err = PTR_ERR(plane_state);
2766 goto free;
2767 }
2768 }
2769
2770 drm_for_each_connector(conn, dev) {
2771 struct drm_connector_state *conn_state;
2772
2773 conn_state = drm_atomic_get_connector_state(state, conn);
2774 if (IS_ERR(conn_state)) {
2775 err = PTR_ERR(conn_state);
2776 goto free;
2777 }
2778 }
2779
2780
2781 state->acquire_ctx = NULL;
2782
2783free:
2784 if (err < 0) {
2785 drm_atomic_state_free(state);
2786 state = ERR_PTR(err);
2787 }
2788
2789 return state;
2790}
2791EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802void
2803__drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
2804 struct drm_connector_state *state)
2805{
2806
2807
2808
2809
2810
2811}
2812EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
2823 struct drm_connector_state *state)
2824{
2825 __drm_atomic_helper_connector_destroy_state(connector, state);
2826 kfree(state);
2827}
2828EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
2829