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