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