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