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_plane_helper.h>
39#include <drm/drm_print.h>
40#include <drm/drm_self_refresh_helper.h>
41#include <drm/drm_vblank.h>
42#include <drm/drm_writeback.h>
43
44#include "drm_crtc_helper_internal.h"
45#include "drm_crtc_internal.h"
46
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
74static void
75drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
76 struct drm_plane_state *old_plane_state,
77 struct drm_plane_state *plane_state,
78 struct drm_plane *plane)
79{
80 struct drm_crtc_state *crtc_state;
81
82 if (old_plane_state->crtc) {
83 crtc_state = drm_atomic_get_new_crtc_state(state,
84 old_plane_state->crtc);
85
86 if (WARN_ON(!crtc_state))
87 return;
88
89 crtc_state->planes_changed = true;
90 }
91
92 if (plane_state->crtc) {
93 crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
94
95 if (WARN_ON(!crtc_state))
96 return;
97
98 crtc_state->planes_changed = true;
99 }
100}
101
102static int handle_conflicting_encoders(struct drm_atomic_state *state,
103 bool disable_conflicting_encoders)
104{
105 struct drm_connector_state *new_conn_state;
106 struct drm_connector *connector;
107 struct drm_connector_list_iter conn_iter;
108 struct drm_encoder *encoder;
109 unsigned encoder_mask = 0;
110 int i, ret = 0;
111
112
113
114
115
116
117 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
118 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
119 struct drm_encoder *new_encoder;
120
121 if (!new_conn_state->crtc)
122 continue;
123
124 if (funcs->atomic_best_encoder)
125 new_encoder = funcs->atomic_best_encoder(connector, new_conn_state);
126 else if (funcs->best_encoder)
127 new_encoder = funcs->best_encoder(connector);
128 else
129 new_encoder = drm_connector_get_single_encoder(connector);
130
131 if (new_encoder) {
132 if (encoder_mask & drm_encoder_mask(new_encoder)) {
133 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n",
134 new_encoder->base.id, new_encoder->name,
135 connector->base.id, connector->name);
136
137 return -EINVAL;
138 }
139
140 encoder_mask |= drm_encoder_mask(new_encoder);
141 }
142 }
143
144 if (!encoder_mask)
145 return 0;
146
147
148
149
150
151
152
153
154
155
156
157
158 drm_connector_list_iter_begin(state->dev, &conn_iter);
159 drm_for_each_connector_iter(connector, &conn_iter) {
160 struct drm_crtc_state *crtc_state;
161
162 if (drm_atomic_get_new_connector_state(state, connector))
163 continue;
164
165 encoder = connector->state->best_encoder;
166 if (!encoder || !(encoder_mask & drm_encoder_mask(encoder)))
167 continue;
168
169 if (!disable_conflicting_encoders) {
170 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n",
171 encoder->base.id, encoder->name,
172 connector->state->crtc->base.id,
173 connector->state->crtc->name,
174 connector->base.id, connector->name);
175 ret = -EINVAL;
176 goto out;
177 }
178
179 new_conn_state = drm_atomic_get_connector_state(state, connector);
180 if (IS_ERR(new_conn_state)) {
181 ret = PTR_ERR(new_conn_state);
182 goto out;
183 }
184
185 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
186 encoder->base.id, encoder->name,
187 new_conn_state->crtc->base.id, new_conn_state->crtc->name,
188 connector->base.id, connector->name);
189
190 crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
191
192 ret = drm_atomic_set_crtc_for_connector(new_conn_state, NULL);
193 if (ret)
194 goto out;
195
196 if (!crtc_state->connector_mask) {
197 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
198 NULL);
199 if (ret < 0)
200 goto out;
201
202 crtc_state->active = false;
203 }
204 }
205out:
206 drm_connector_list_iter_end(&conn_iter);
207
208 return ret;
209}
210
211static void
212set_best_encoder(struct drm_atomic_state *state,
213 struct drm_connector_state *conn_state,
214 struct drm_encoder *encoder)
215{
216 struct drm_crtc_state *crtc_state;
217 struct drm_crtc *crtc;
218
219 if (conn_state->best_encoder) {
220
221 crtc = conn_state->connector->state->crtc;
222
223
224
225
226
227
228
229 WARN_ON(!crtc && encoder != conn_state->best_encoder);
230 if (crtc) {
231 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
232
233 crtc_state->encoder_mask &=
234 ~drm_encoder_mask(conn_state->best_encoder);
235 }
236 }
237
238 if (encoder) {
239 crtc = conn_state->crtc;
240 WARN_ON(!crtc);
241 if (crtc) {
242 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
243
244 crtc_state->encoder_mask |=
245 drm_encoder_mask(encoder);
246 }
247 }
248
249 conn_state->best_encoder = encoder;
250}
251
252static void
253steal_encoder(struct drm_atomic_state *state,
254 struct drm_encoder *encoder)
255{
256 struct drm_crtc_state *crtc_state;
257 struct drm_connector *connector;
258 struct drm_connector_state *old_connector_state, *new_connector_state;
259 int i;
260
261 for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
262 struct drm_crtc *encoder_crtc;
263
264 if (new_connector_state->best_encoder != encoder)
265 continue;
266
267 encoder_crtc = old_connector_state->crtc;
268
269 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] in use on [CRTC:%d:%s], stealing it\n",
270 encoder->base.id, encoder->name,
271 encoder_crtc->base.id, encoder_crtc->name);
272
273 set_best_encoder(state, new_connector_state, NULL);
274
275 crtc_state = drm_atomic_get_new_crtc_state(state, encoder_crtc);
276 crtc_state->connectors_changed = true;
277
278 return;
279 }
280}
281
282static int
283update_connector_routing(struct drm_atomic_state *state,
284 struct drm_connector *connector,
285 struct drm_connector_state *old_connector_state,
286 struct drm_connector_state *new_connector_state)
287{
288 const struct drm_connector_helper_funcs *funcs;
289 struct drm_encoder *new_encoder;
290 struct drm_crtc_state *crtc_state;
291
292 DRM_DEBUG_ATOMIC("Updating routing for [CONNECTOR:%d:%s]\n",
293 connector->base.id,
294 connector->name);
295
296 if (old_connector_state->crtc != new_connector_state->crtc) {
297 if (old_connector_state->crtc) {
298 crtc_state = drm_atomic_get_new_crtc_state(state, old_connector_state->crtc);
299 crtc_state->connectors_changed = true;
300 }
301
302 if (new_connector_state->crtc) {
303 crtc_state = drm_atomic_get_new_crtc_state(state, new_connector_state->crtc);
304 crtc_state->connectors_changed = true;
305 }
306 }
307
308 if (!new_connector_state->crtc) {
309 DRM_DEBUG_ATOMIC("Disabling [CONNECTOR:%d:%s]\n",
310 connector->base.id,
311 connector->name);
312
313 set_best_encoder(state, new_connector_state, NULL);
314
315 return 0;
316 }
317
318 crtc_state = drm_atomic_get_new_crtc_state(state,
319 new_connector_state->crtc);
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338 if (!state->duplicated && drm_connector_is_unregistered(connector) &&
339 crtc_state->active) {
340 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] is not registered\n",
341 connector->base.id, connector->name);
342 return -EINVAL;
343 }
344
345 funcs = connector->helper_private;
346
347 if (funcs->atomic_best_encoder)
348 new_encoder = funcs->atomic_best_encoder(connector,
349 new_connector_state);
350 else if (funcs->best_encoder)
351 new_encoder = funcs->best_encoder(connector);
352 else
353 new_encoder = drm_connector_get_single_encoder(connector);
354
355 if (!new_encoder) {
356 DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n",
357 connector->base.id,
358 connector->name);
359 return -EINVAL;
360 }
361
362 if (!drm_encoder_crtc_ok(new_encoder, new_connector_state->crtc)) {
363 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] incompatible with [CRTC:%d:%s]\n",
364 new_encoder->base.id,
365 new_encoder->name,
366 new_connector_state->crtc->base.id,
367 new_connector_state->crtc->name);
368 return -EINVAL;
369 }
370
371 if (new_encoder == new_connector_state->best_encoder) {
372 set_best_encoder(state, new_connector_state, new_encoder);
373
374 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d:%s]\n",
375 connector->base.id,
376 connector->name,
377 new_encoder->base.id,
378 new_encoder->name,
379 new_connector_state->crtc->base.id,
380 new_connector_state->crtc->name);
381
382 return 0;
383 }
384
385 steal_encoder(state, new_encoder);
386
387 set_best_encoder(state, new_connector_state, new_encoder);
388
389 crtc_state->connectors_changed = true;
390
391 DRM_DEBUG_ATOMIC("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d:%s]\n",
392 connector->base.id,
393 connector->name,
394 new_encoder->base.id,
395 new_encoder->name,
396 new_connector_state->crtc->base.id,
397 new_connector_state->crtc->name);
398
399 return 0;
400}
401
402static int
403mode_fixup(struct drm_atomic_state *state)
404{
405 struct drm_crtc *crtc;
406 struct drm_crtc_state *new_crtc_state;
407 struct drm_connector *connector;
408 struct drm_connector_state *new_conn_state;
409 int i;
410 int ret;
411
412 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
413 if (!new_crtc_state->mode_changed &&
414 !new_crtc_state->connectors_changed)
415 continue;
416
417 drm_mode_copy(&new_crtc_state->adjusted_mode, &new_crtc_state->mode);
418 }
419
420 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
421 const struct drm_encoder_helper_funcs *funcs;
422 struct drm_encoder *encoder;
423 struct drm_bridge *bridge;
424
425 WARN_ON(!!new_conn_state->best_encoder != !!new_conn_state->crtc);
426
427 if (!new_conn_state->crtc || !new_conn_state->best_encoder)
428 continue;
429
430 new_crtc_state =
431 drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
432
433
434
435
436
437 encoder = new_conn_state->best_encoder;
438 funcs = encoder->helper_private;
439
440 bridge = drm_bridge_chain_get_first_bridge(encoder);
441 ret = drm_atomic_bridge_chain_check(bridge,
442 new_crtc_state,
443 new_conn_state);
444 if (ret) {
445 DRM_DEBUG_ATOMIC("Bridge atomic check failed\n");
446 return ret;
447 }
448
449 if (funcs && funcs->atomic_check) {
450 ret = funcs->atomic_check(encoder, new_crtc_state,
451 new_conn_state);
452 if (ret) {
453 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] check failed\n",
454 encoder->base.id, encoder->name);
455 return ret;
456 }
457 } else if (funcs && funcs->mode_fixup) {
458 ret = funcs->mode_fixup(encoder, &new_crtc_state->mode,
459 &new_crtc_state->adjusted_mode);
460 if (!ret) {
461 DRM_DEBUG_ATOMIC("[ENCODER:%d:%s] fixup failed\n",
462 encoder->base.id, encoder->name);
463 return -EINVAL;
464 }
465 }
466 }
467
468 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
469 const struct drm_crtc_helper_funcs *funcs;
470
471 if (!new_crtc_state->enable)
472 continue;
473
474 if (!new_crtc_state->mode_changed &&
475 !new_crtc_state->connectors_changed)
476 continue;
477
478 funcs = crtc->helper_private;
479 if (!funcs || !funcs->mode_fixup)
480 continue;
481
482 ret = funcs->mode_fixup(crtc, &new_crtc_state->mode,
483 &new_crtc_state->adjusted_mode);
484 if (!ret) {
485 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] fixup failed\n",
486 crtc->base.id, crtc->name);
487 return -EINVAL;
488 }
489 }
490
491 return 0;
492}
493
494static enum drm_mode_status mode_valid_path(struct drm_connector *connector,
495 struct drm_encoder *encoder,
496 struct drm_crtc *crtc,
497 const struct drm_display_mode *mode)
498{
499 struct drm_bridge *bridge;
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 bridge = drm_bridge_chain_get_first_bridge(encoder);
510 ret = drm_bridge_chain_mode_valid(bridge, &connector->display_info,
511 mode);
512 if (ret != MODE_OK) {
513 DRM_DEBUG_ATOMIC("[BRIDGE] mode_valid() failed\n");
514 return ret;
515 }
516
517 ret = drm_crtc_mode_valid(crtc, mode);
518 if (ret != MODE_OK) {
519 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] mode_valid() failed\n",
520 crtc->base.id, crtc->name);
521 return ret;
522 }
523
524 return ret;
525}
526
527static int
528mode_valid(struct drm_atomic_state *state)
529{
530 struct drm_connector_state *conn_state;
531 struct drm_connector *connector;
532 int i;
533
534 for_each_new_connector_in_state(state, connector, conn_state, i) {
535 struct drm_encoder *encoder = conn_state->best_encoder;
536 struct drm_crtc *crtc = conn_state->crtc;
537 struct drm_crtc_state *crtc_state;
538 enum drm_mode_status mode_status;
539 const struct drm_display_mode *mode;
540
541 if (!crtc || !encoder)
542 continue;
543
544 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
545 if (!crtc_state)
546 continue;
547 if (!crtc_state->mode_changed && !crtc_state->connectors_changed)
548 continue;
549
550 mode = &crtc_state->mode;
551
552 mode_status = mode_valid_path(connector, encoder, crtc, mode);
553 if (mode_status != MODE_OK)
554 return -EINVAL;
555 }
556
557 return 0;
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
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 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, new_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, new_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 if (!old_conn_state->crtc)
1025 continue;
1026
1027 old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc);
1028
1029 if (new_conn_state->crtc)
1030 new_crtc_state = drm_atomic_get_new_crtc_state(
1031 old_state,
1032 new_conn_state->crtc);
1033 else
1034 new_crtc_state = NULL;
1035
1036 if (!crtc_needs_disable(old_crtc_state, new_crtc_state) ||
1037 !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
1038 continue;
1039
1040 encoder = old_conn_state->best_encoder;
1041
1042
1043
1044
1045 if (WARN_ON(!encoder))
1046 continue;
1047
1048 funcs = encoder->helper_private;
1049
1050 DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
1051 encoder->base.id, encoder->name);
1052
1053
1054
1055
1056
1057 bridge = drm_bridge_chain_get_first_bridge(encoder);
1058 drm_atomic_bridge_chain_disable(bridge, old_state);
1059
1060
1061 if (funcs) {
1062 if (funcs->atomic_disable)
1063 funcs->atomic_disable(encoder, old_state);
1064 else if (new_conn_state->crtc && funcs->prepare)
1065 funcs->prepare(encoder);
1066 else if (funcs->disable)
1067 funcs->disable(encoder);
1068 else if (funcs->dpms)
1069 funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
1070 }
1071
1072 drm_atomic_bridge_chain_post_disable(bridge, old_state);
1073 }
1074
1075 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1076 const struct drm_crtc_helper_funcs *funcs;
1077 int ret;
1078
1079
1080 if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
1081 continue;
1082
1083 if (!crtc_needs_disable(old_crtc_state, new_crtc_state))
1084 continue;
1085
1086 funcs = crtc->helper_private;
1087
1088 DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n",
1089 crtc->base.id, crtc->name);
1090
1091
1092
1093 if (new_crtc_state->enable && funcs->prepare)
1094 funcs->prepare(crtc);
1095 else if (funcs->atomic_disable)
1096 funcs->atomic_disable(crtc, old_crtc_state);
1097 else if (funcs->disable)
1098 funcs->disable(crtc);
1099 else if (funcs->dpms)
1100 funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
1101
1102 if (!drm_dev_has_vblank(dev))
1103 continue;
1104
1105 ret = drm_crtc_vblank_get(crtc);
1106 WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
1107 if (ret == 0)
1108 drm_crtc_vblank_put(crtc);
1109 }
1110}
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129void
1130drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
1131 struct drm_atomic_state *old_state)
1132{
1133 struct drm_connector *connector;
1134 struct drm_connector_state *old_conn_state, *new_conn_state;
1135 struct drm_crtc *crtc;
1136 struct drm_crtc_state *new_crtc_state;
1137 int i;
1138
1139
1140 for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
1141 if (connector->encoder) {
1142 WARN_ON(!connector->encoder->crtc);
1143
1144 connector->encoder->crtc = NULL;
1145 connector->encoder = NULL;
1146 }
1147
1148 crtc = new_conn_state->crtc;
1149 if ((!crtc && old_conn_state->crtc) ||
1150 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
1151 int mode = DRM_MODE_DPMS_OFF;
1152
1153 if (crtc && crtc->state->active)
1154 mode = DRM_MODE_DPMS_ON;
1155
1156 connector->dpms = mode;
1157 }
1158 }
1159
1160
1161 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1162 if (!new_conn_state->crtc)
1163 continue;
1164
1165 if (WARN_ON(!new_conn_state->best_encoder))
1166 continue;
1167
1168 connector->encoder = new_conn_state->best_encoder;
1169 connector->encoder->crtc = new_conn_state->crtc;
1170 }
1171
1172
1173 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1174 struct drm_plane *primary = crtc->primary;
1175 struct drm_plane_state *new_plane_state;
1176
1177 crtc->mode = new_crtc_state->mode;
1178 crtc->enabled = new_crtc_state->enable;
1179
1180 new_plane_state =
1181 drm_atomic_get_new_plane_state(old_state, primary);
1182
1183 if (new_plane_state && new_plane_state->crtc == crtc) {
1184 crtc->x = new_plane_state->src_x >> 16;
1185 crtc->y = new_plane_state->src_y >> 16;
1186 }
1187 }
1188}
1189EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
1190
1191
1192
1193
1194
1195
1196
1197
1198void drm_atomic_helper_calc_timestamping_constants(struct drm_atomic_state *state)
1199{
1200 struct drm_crtc_state *new_crtc_state;
1201 struct drm_crtc *crtc;
1202 int i;
1203
1204 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
1205 if (new_crtc_state->enable)
1206 drm_calc_timestamping_constants(crtc,
1207 &new_crtc_state->adjusted_mode);
1208 }
1209}
1210EXPORT_SYMBOL(drm_atomic_helper_calc_timestamping_constants);
1211
1212static void
1213crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
1214{
1215 struct drm_crtc *crtc;
1216 struct drm_crtc_state *new_crtc_state;
1217 struct drm_connector *connector;
1218 struct drm_connector_state *new_conn_state;
1219 int i;
1220
1221 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1222 const struct drm_crtc_helper_funcs *funcs;
1223
1224 if (!new_crtc_state->mode_changed)
1225 continue;
1226
1227 funcs = crtc->helper_private;
1228
1229 if (new_crtc_state->enable && funcs->mode_set_nofb) {
1230 DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
1231 crtc->base.id, crtc->name);
1232
1233 funcs->mode_set_nofb(crtc);
1234 }
1235 }
1236
1237 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1238 const struct drm_encoder_helper_funcs *funcs;
1239 struct drm_encoder *encoder;
1240 struct drm_display_mode *mode, *adjusted_mode;
1241 struct drm_bridge *bridge;
1242
1243 if (!new_conn_state->best_encoder)
1244 continue;
1245
1246 encoder = new_conn_state->best_encoder;
1247 funcs = encoder->helper_private;
1248 new_crtc_state = new_conn_state->crtc->state;
1249 mode = &new_crtc_state->mode;
1250 adjusted_mode = &new_crtc_state->adjusted_mode;
1251
1252 if (!new_crtc_state->mode_changed)
1253 continue;
1254
1255 DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n",
1256 encoder->base.id, encoder->name);
1257
1258
1259
1260
1261
1262 if (funcs && funcs->atomic_mode_set) {
1263 funcs->atomic_mode_set(encoder, new_crtc_state,
1264 new_conn_state);
1265 } else if (funcs && funcs->mode_set) {
1266 funcs->mode_set(encoder, mode, adjusted_mode);
1267 }
1268
1269 bridge = drm_bridge_chain_get_first_bridge(encoder);
1270 drm_bridge_chain_mode_set(bridge, mode, adjusted_mode);
1271 }
1272}
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
1289 struct drm_atomic_state *old_state)
1290{
1291 disable_outputs(dev, old_state);
1292
1293 drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
1294 drm_atomic_helper_calc_timestamping_constants(old_state);
1295
1296 crtc_set_mode(dev, old_state);
1297}
1298EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
1299
1300static void drm_atomic_helper_commit_writebacks(struct drm_device *dev,
1301 struct drm_atomic_state *old_state)
1302{
1303 struct drm_connector *connector;
1304 struct drm_connector_state *new_conn_state;
1305 int i;
1306
1307 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1308 const struct drm_connector_helper_funcs *funcs;
1309
1310 funcs = connector->helper_private;
1311 if (!funcs->atomic_commit)
1312 continue;
1313
1314 if (new_conn_state->writeback_job && new_conn_state->writeback_job->fb) {
1315 WARN_ON(connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK);
1316 funcs->atomic_commit(connector, new_conn_state);
1317 }
1318 }
1319}
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
1336 struct drm_atomic_state *old_state)
1337{
1338 struct drm_crtc *crtc;
1339 struct drm_crtc_state *old_crtc_state;
1340 struct drm_crtc_state *new_crtc_state;
1341 struct drm_connector *connector;
1342 struct drm_connector_state *new_conn_state;
1343 int i;
1344
1345 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1346 const struct drm_crtc_helper_funcs *funcs;
1347
1348
1349 if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
1350 continue;
1351
1352 if (!new_crtc_state->active)
1353 continue;
1354
1355 funcs = crtc->helper_private;
1356
1357 if (new_crtc_state->enable) {
1358 DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
1359 crtc->base.id, crtc->name);
1360 if (funcs->atomic_enable)
1361 funcs->atomic_enable(crtc, old_crtc_state);
1362 else if (funcs->commit)
1363 funcs->commit(crtc);
1364 }
1365 }
1366
1367 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1368 const struct drm_encoder_helper_funcs *funcs;
1369 struct drm_encoder *encoder;
1370 struct drm_bridge *bridge;
1371
1372 if (!new_conn_state->best_encoder)
1373 continue;
1374
1375 if (!new_conn_state->crtc->state->active ||
1376 !drm_atomic_crtc_needs_modeset(new_conn_state->crtc->state))
1377 continue;
1378
1379 encoder = new_conn_state->best_encoder;
1380 funcs = encoder->helper_private;
1381
1382 DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
1383 encoder->base.id, encoder->name);
1384
1385
1386
1387
1388
1389 bridge = drm_bridge_chain_get_first_bridge(encoder);
1390 drm_atomic_bridge_chain_pre_enable(bridge, old_state);
1391
1392 if (funcs) {
1393 if (funcs->atomic_enable)
1394 funcs->atomic_enable(encoder, old_state);
1395 else if (funcs->enable)
1396 funcs->enable(encoder);
1397 else if (funcs->commit)
1398 funcs->commit(encoder);
1399 }
1400
1401 drm_atomic_bridge_chain_enable(bridge, old_state);
1402 }
1403
1404 drm_atomic_helper_commit_writebacks(dev, old_state);
1405}
1406EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
1430 struct drm_atomic_state *state,
1431 bool pre_swap)
1432{
1433 struct drm_plane *plane;
1434 struct drm_plane_state *new_plane_state;
1435 int i, ret;
1436
1437 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
1438 if (!new_plane_state->fence)
1439 continue;
1440
1441 WARN_ON(!new_plane_state->fb);
1442
1443
1444
1445
1446
1447
1448 ret = dma_fence_wait(new_plane_state->fence, pre_swap);
1449 if (ret)
1450 return ret;
1451
1452 dma_fence_put(new_plane_state->fence);
1453 new_plane_state->fence = NULL;
1454 }
1455
1456 return 0;
1457}
1458EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences);
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475void
1476drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
1477 struct drm_atomic_state *old_state)
1478{
1479 struct drm_crtc *crtc;
1480 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1481 int i, ret;
1482 unsigned crtc_mask = 0;
1483
1484
1485
1486
1487
1488 if (old_state->legacy_cursor_update)
1489 return;
1490
1491 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1492 if (!new_crtc_state->active)
1493 continue;
1494
1495 ret = drm_crtc_vblank_get(crtc);
1496 if (ret != 0)
1497 continue;
1498
1499 crtc_mask |= drm_crtc_mask(crtc);
1500 old_state->crtcs[i].last_vblank_count = drm_crtc_vblank_count(crtc);
1501 }
1502
1503 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1504 if (!(crtc_mask & drm_crtc_mask(crtc)))
1505 continue;
1506
1507 ret = wait_event_timeout(dev->vblank[i].queue,
1508 old_state->crtcs[i].last_vblank_count !=
1509 drm_crtc_vblank_count(crtc),
1510 msecs_to_jiffies(100));
1511
1512 WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
1513 crtc->base.id, crtc->name);
1514
1515 drm_crtc_vblank_put(crtc);
1516 }
1517}
1518EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
1536 struct drm_atomic_state *old_state)
1537{
1538 struct drm_crtc *crtc;
1539 int i;
1540
1541 for (i = 0; i < dev->mode_config.num_crtc; i++) {
1542 struct drm_crtc_commit *commit = old_state->crtcs[i].commit;
1543 int ret;
1544
1545 crtc = old_state->crtcs[i].ptr;
1546
1547 if (!crtc || !commit)
1548 continue;
1549
1550 ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
1551 if (ret == 0)
1552 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1553 crtc->base.id, crtc->name);
1554 }
1555
1556 if (old_state->fake_commit)
1557 complete_all(&old_state->fake_commit->flip_done);
1558}
1559EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
1575{
1576 struct drm_device *dev = old_state->dev;
1577
1578 drm_atomic_helper_commit_modeset_disables(dev, old_state);
1579
1580 drm_atomic_helper_commit_planes(dev, old_state, 0);
1581
1582 drm_atomic_helper_commit_modeset_enables(dev, old_state);
1583
1584 drm_atomic_helper_fake_vblank(old_state);
1585
1586 drm_atomic_helper_commit_hw_done(old_state);
1587
1588 drm_atomic_helper_wait_for_vblanks(dev, old_state);
1589
1590 drm_atomic_helper_cleanup_planes(dev, old_state);
1591}
1592EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
1605{
1606 struct drm_device *dev = old_state->dev;
1607
1608 drm_atomic_helper_commit_modeset_disables(dev, old_state);
1609
1610 drm_atomic_helper_commit_modeset_enables(dev, old_state);
1611
1612 drm_atomic_helper_commit_planes(dev, old_state,
1613 DRM_PLANE_COMMIT_ACTIVE_ONLY);
1614
1615 drm_atomic_helper_fake_vblank(old_state);
1616
1617 drm_atomic_helper_commit_hw_done(old_state);
1618
1619 drm_atomic_helper_wait_for_vblanks(dev, old_state);
1620
1621 drm_atomic_helper_cleanup_planes(dev, old_state);
1622}
1623EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm);
1624
1625static void commit_tail(struct drm_atomic_state *old_state)
1626{
1627 struct drm_device *dev = old_state->dev;
1628 const struct drm_mode_config_helper_funcs *funcs;
1629 struct drm_crtc_state *new_crtc_state;
1630 struct drm_crtc *crtc;
1631 ktime_t start;
1632 s64 commit_time_ms;
1633 unsigned int i, new_self_refresh_mask = 0;
1634
1635 funcs = dev->mode_config.helper_private;
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647 start = ktime_get();
1648
1649 drm_atomic_helper_wait_for_fences(dev, old_state, false);
1650
1651 drm_atomic_helper_wait_for_dependencies(old_state);
1652
1653
1654
1655
1656
1657
1658 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i)
1659 if (new_crtc_state->self_refresh_active)
1660 new_self_refresh_mask |= BIT(i);
1661
1662 if (funcs && funcs->atomic_commit_tail)
1663 funcs->atomic_commit_tail(old_state);
1664 else
1665 drm_atomic_helper_commit_tail(old_state);
1666
1667 commit_time_ms = ktime_ms_delta(ktime_get(), start);
1668 if (commit_time_ms > 0)
1669 drm_self_refresh_helper_update_avg_times(old_state,
1670 (unsigned long)commit_time_ms,
1671 new_self_refresh_mask);
1672
1673 drm_atomic_helper_commit_cleanup_done(old_state);
1674
1675 drm_atomic_state_put(old_state);
1676}
1677
1678static void commit_work(struct work_struct *work)
1679{
1680 struct drm_atomic_state *state = container_of(work,
1681 struct drm_atomic_state,
1682 commit_work);
1683 commit_tail(state);
1684}
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699int drm_atomic_helper_async_check(struct drm_device *dev,
1700 struct drm_atomic_state *state)
1701{
1702 struct drm_crtc *crtc;
1703 struct drm_crtc_state *crtc_state;
1704 struct drm_plane *plane = NULL;
1705 struct drm_plane_state *old_plane_state = NULL;
1706 struct drm_plane_state *new_plane_state = NULL;
1707 const struct drm_plane_helper_funcs *funcs;
1708 int i, n_planes = 0;
1709
1710 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1711 if (drm_atomic_crtc_needs_modeset(crtc_state))
1712 return -EINVAL;
1713 }
1714
1715 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
1716 n_planes++;
1717
1718
1719 if (n_planes != 1)
1720 return -EINVAL;
1721
1722 if (!new_plane_state->crtc ||
1723 old_plane_state->crtc != new_plane_state->crtc)
1724 return -EINVAL;
1725
1726 funcs = plane->helper_private;
1727 if (!funcs->atomic_async_update)
1728 return -EINVAL;
1729
1730 if (new_plane_state->fence)
1731 return -EINVAL;
1732
1733
1734
1735
1736
1737
1738 if (old_plane_state->commit &&
1739 !try_wait_for_completion(&old_plane_state->commit->hw_done))
1740 return -EBUSY;
1741
1742 return funcs->atomic_async_check(plane, new_plane_state);
1743}
1744EXPORT_SYMBOL(drm_atomic_helper_async_check);
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759void drm_atomic_helper_async_commit(struct drm_device *dev,
1760 struct drm_atomic_state *state)
1761{
1762 struct drm_plane *plane;
1763 struct drm_plane_state *plane_state;
1764 const struct drm_plane_helper_funcs *funcs;
1765 int i;
1766
1767 for_each_new_plane_in_state(state, plane, plane_state, i) {
1768 struct drm_framebuffer *new_fb = plane_state->fb;
1769 struct drm_framebuffer *old_fb = plane->state->fb;
1770
1771 funcs = plane->helper_private;
1772 funcs->atomic_async_update(plane, plane_state);
1773
1774
1775
1776
1777
1778
1779 WARN_ON_ONCE(plane->state->fb != new_fb);
1780 WARN_ON_ONCE(plane->state->crtc_x != plane_state->crtc_x);
1781 WARN_ON_ONCE(plane->state->crtc_y != plane_state->crtc_y);
1782 WARN_ON_ONCE(plane->state->src_x != plane_state->src_x);
1783 WARN_ON_ONCE(plane->state->src_y != plane_state->src_y);
1784
1785
1786
1787
1788
1789 WARN_ON_ONCE(plane_state->fb != old_fb);
1790 }
1791}
1792EXPORT_SYMBOL(drm_atomic_helper_async_commit);
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812int drm_atomic_helper_commit(struct drm_device *dev,
1813 struct drm_atomic_state *state,
1814 bool nonblock)
1815{
1816 int ret;
1817
1818 if (state->async_update) {
1819 ret = drm_atomic_helper_prepare_planes(dev, state);
1820 if (ret)
1821 return ret;
1822
1823 drm_atomic_helper_async_commit(dev, state);
1824 drm_atomic_helper_cleanup_planes(dev, state);
1825
1826 return 0;
1827 }
1828
1829 ret = drm_atomic_helper_setup_commit(state, nonblock);
1830 if (ret)
1831 return ret;
1832
1833 INIT_WORK(&state->commit_work, commit_work);
1834
1835 ret = drm_atomic_helper_prepare_planes(dev, state);
1836 if (ret)
1837 return ret;
1838
1839 if (!nonblock) {
1840 ret = drm_atomic_helper_wait_for_fences(dev, state, true);
1841 if (ret)
1842 goto err;
1843 }
1844
1845
1846
1847
1848
1849
1850
1851 ret = drm_atomic_helper_swap_state(state, true);
1852 if (ret)
1853 goto err;
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875 drm_atomic_state_get(state);
1876 if (nonblock)
1877 queue_work(system_unbound_wq, &state->commit_work);
1878 else
1879 commit_tail(state);
1880
1881 return 0;
1882
1883err:
1884 drm_atomic_helper_cleanup_planes(dev, state);
1885 return ret;
1886}
1887EXPORT_SYMBOL(drm_atomic_helper_commit);
1888
1889
1890
1891
1892
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
1942static int stall_checks(struct drm_crtc *crtc, bool nonblock)
1943{
1944 struct drm_crtc_commit *commit, *stall_commit = NULL;
1945 bool completed = true;
1946 int i;
1947 long ret = 0;
1948
1949 spin_lock(&crtc->commit_lock);
1950 i = 0;
1951 list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
1952 if (i == 0) {
1953 completed = try_wait_for_completion(&commit->flip_done);
1954
1955
1956 if (!completed && nonblock) {
1957 spin_unlock(&crtc->commit_lock);
1958 return -EBUSY;
1959 }
1960 } else if (i == 1) {
1961 stall_commit = drm_crtc_commit_get(commit);
1962 break;
1963 }
1964
1965 i++;
1966 }
1967 spin_unlock(&crtc->commit_lock);
1968
1969 if (!stall_commit)
1970 return 0;
1971
1972
1973
1974
1975 ret = wait_for_completion_interruptible_timeout(&stall_commit->cleanup_done,
1976 10*HZ);
1977 if (ret == 0)
1978 DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
1979 crtc->base.id, crtc->name);
1980
1981 drm_crtc_commit_put(stall_commit);
1982
1983 return ret < 0 ? ret : 0;
1984}
1985
1986static void release_crtc_commit(struct completion *completion)
1987{
1988 struct drm_crtc_commit *commit = container_of(completion,
1989 typeof(*commit),
1990 flip_done);
1991
1992 drm_crtc_commit_put(commit);
1993}
1994
1995static void init_commit(struct drm_crtc_commit *commit, struct drm_crtc *crtc)
1996{
1997 init_completion(&commit->flip_done);
1998 init_completion(&commit->hw_done);
1999 init_completion(&commit->cleanup_done);
2000 INIT_LIST_HEAD(&commit->commit_entry);
2001 kref_init(&commit->ref);
2002 commit->crtc = crtc;
2003}
2004
2005static struct drm_crtc_commit *
2006crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
2007{
2008 if (crtc) {
2009 struct drm_crtc_state *new_crtc_state;
2010
2011 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
2012
2013 return new_crtc_state->commit;
2014 }
2015
2016 if (!state->fake_commit) {
2017 state->fake_commit = kzalloc(sizeof(*state->fake_commit), GFP_KERNEL);
2018 if (!state->fake_commit)
2019 return NULL;
2020
2021 init_commit(state->fake_commit, NULL);
2022 }
2023
2024 return state->fake_commit;
2025}
2026
2027
2028
2029
2030
2031
2032
2033
2034
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
2070int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
2071 bool nonblock)
2072{
2073 struct drm_crtc *crtc;
2074 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2075 struct drm_connector *conn;
2076 struct drm_connector_state *old_conn_state, *new_conn_state;
2077 struct drm_plane *plane;
2078 struct drm_plane_state *old_plane_state, *new_plane_state;
2079 struct drm_crtc_commit *commit;
2080 int i, ret;
2081
2082 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
2083 commit = kzalloc(sizeof(*commit), GFP_KERNEL);
2084 if (!commit)
2085 return -ENOMEM;
2086
2087 init_commit(commit, crtc);
2088
2089 new_crtc_state->commit = commit;
2090
2091 ret = stall_checks(crtc, nonblock);
2092 if (ret)
2093 return ret;
2094
2095
2096
2097
2098 if (!old_crtc_state->active && !new_crtc_state->active) {
2099 complete_all(&commit->flip_done);
2100 continue;
2101 }
2102
2103
2104 if (state->legacy_cursor_update) {
2105 complete_all(&commit->flip_done);
2106 continue;
2107 }
2108
2109 if (!new_crtc_state->event) {
2110 commit->event = kzalloc(sizeof(*commit->event),
2111 GFP_KERNEL);
2112 if (!commit->event)
2113 return -ENOMEM;
2114
2115 new_crtc_state->event = commit->event;
2116 }
2117
2118 new_crtc_state->event->base.completion = &commit->flip_done;
2119 new_crtc_state->event->base.completion_release = release_crtc_commit;
2120 drm_crtc_commit_get(commit);
2121
2122 commit->abort_completion = true;
2123
2124 state->crtcs[i].commit = commit;
2125 drm_crtc_commit_get(commit);
2126 }
2127
2128 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
2129
2130
2131 if (nonblock && old_conn_state->commit &&
2132 !try_wait_for_completion(&old_conn_state->commit->flip_done))
2133 return -EBUSY;
2134
2135
2136 commit = crtc_or_fake_commit(state, new_conn_state->crtc ?: old_conn_state->crtc);
2137 if (!commit)
2138 return -ENOMEM;
2139
2140 new_conn_state->commit = drm_crtc_commit_get(commit);
2141 }
2142
2143 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
2144
2145
2146 if (nonblock && old_plane_state->commit &&
2147 !try_wait_for_completion(&old_plane_state->commit->flip_done))
2148 return -EBUSY;
2149
2150
2151 commit = crtc_or_fake_commit(state, new_plane_state->crtc ?: old_plane_state->crtc);
2152 if (!commit)
2153 return -ENOMEM;
2154
2155 new_plane_state->commit = drm_crtc_commit_get(commit);
2156 }
2157
2158 return 0;
2159}
2160EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
2175{
2176 struct drm_crtc *crtc;
2177 struct drm_crtc_state *old_crtc_state;
2178 struct drm_plane *plane;
2179 struct drm_plane_state *old_plane_state;
2180 struct drm_connector *conn;
2181 struct drm_connector_state *old_conn_state;
2182 struct drm_crtc_commit *commit;
2183 int i;
2184 long ret;
2185
2186 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
2187 commit = old_crtc_state->commit;
2188
2189 if (!commit)
2190 continue;
2191
2192 ret = wait_for_completion_timeout(&commit->hw_done,
2193 10*HZ);
2194 if (ret == 0)
2195 DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
2196 crtc->base.id, crtc->name);
2197
2198
2199
2200 ret = wait_for_completion_timeout(&commit->flip_done,
2201 10*HZ);
2202 if (ret == 0)
2203 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
2204 crtc->base.id, crtc->name);
2205 }
2206
2207 for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
2208 commit = old_conn_state->commit;
2209
2210 if (!commit)
2211 continue;
2212
2213 ret = wait_for_completion_timeout(&commit->hw_done,
2214 10*HZ);
2215 if (ret == 0)
2216 DRM_ERROR("[CONNECTOR:%d:%s] hw_done timed out\n",
2217 conn->base.id, conn->name);
2218
2219
2220
2221 ret = wait_for_completion_timeout(&commit->flip_done,
2222 10*HZ);
2223 if (ret == 0)
2224 DRM_ERROR("[CONNECTOR:%d:%s] flip_done timed out\n",
2225 conn->base.id, conn->name);
2226 }
2227
2228 for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
2229 commit = old_plane_state->commit;
2230
2231 if (!commit)
2232 continue;
2233
2234 ret = wait_for_completion_timeout(&commit->hw_done,
2235 10*HZ);
2236 if (ret == 0)
2237 DRM_ERROR("[PLANE:%d:%s] hw_done timed out\n",
2238 plane->base.id, plane->name);
2239
2240
2241
2242 ret = wait_for_completion_timeout(&commit->flip_done,
2243 10*HZ);
2244 if (ret == 0)
2245 DRM_ERROR("[PLANE:%d:%s] flip_done timed out\n",
2246 plane->base.id, plane->name);
2247 }
2248}
2249EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269void drm_atomic_helper_fake_vblank(struct drm_atomic_state *old_state)
2270{
2271 struct drm_crtc_state *new_crtc_state;
2272 struct drm_crtc *crtc;
2273 int i;
2274
2275 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
2276 unsigned long flags;
2277
2278 if (!new_crtc_state->no_vblank)
2279 continue;
2280
2281 spin_lock_irqsave(&old_state->dev->event_lock, flags);
2282 if (new_crtc_state->event) {
2283 drm_crtc_send_vblank_event(crtc,
2284 new_crtc_state->event);
2285 new_crtc_state->event = NULL;
2286 }
2287 spin_unlock_irqrestore(&old_state->dev->event_lock, flags);
2288 }
2289}
2290EXPORT_SYMBOL(drm_atomic_helper_fake_vblank);
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
2308{
2309 struct drm_crtc *crtc;
2310 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2311 struct drm_crtc_commit *commit;
2312 int i;
2313
2314 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2315 commit = new_crtc_state->commit;
2316 if (!commit)
2317 continue;
2318
2319
2320
2321
2322
2323
2324 if (old_crtc_state->commit)
2325 drm_crtc_commit_put(old_crtc_state->commit);
2326
2327 old_crtc_state->commit = drm_crtc_commit_get(commit);
2328
2329
2330 WARN_ON(new_crtc_state->event);
2331 complete_all(&commit->hw_done);
2332 }
2333
2334 if (old_state->fake_commit) {
2335 complete_all(&old_state->fake_commit->hw_done);
2336 complete_all(&old_state->fake_commit->flip_done);
2337 }
2338}
2339EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
2353{
2354 struct drm_crtc *crtc;
2355 struct drm_crtc_state *old_crtc_state;
2356 struct drm_crtc_commit *commit;
2357 int i;
2358
2359 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
2360 commit = old_crtc_state->commit;
2361 if (WARN_ON(!commit))
2362 continue;
2363
2364 complete_all(&commit->cleanup_done);
2365 WARN_ON(!try_wait_for_completion(&commit->hw_done));
2366
2367 spin_lock(&crtc->commit_lock);
2368 list_del(&commit->commit_entry);
2369 spin_unlock(&crtc->commit_lock);
2370 }
2371
2372 if (old_state->fake_commit) {
2373 complete_all(&old_state->fake_commit->cleanup_done);
2374 WARN_ON(!try_wait_for_completion(&old_state->fake_commit->hw_done));
2375 }
2376}
2377EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392int drm_atomic_helper_prepare_planes(struct drm_device *dev,
2393 struct drm_atomic_state *state)
2394{
2395 struct drm_connector *connector;
2396 struct drm_connector_state *new_conn_state;
2397 struct drm_plane *plane;
2398 struct drm_plane_state *new_plane_state;
2399 int ret, i, j;
2400
2401 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
2402 if (!new_conn_state->writeback_job)
2403 continue;
2404
2405 ret = drm_writeback_prepare_job(new_conn_state->writeback_job);
2406 if (ret < 0)
2407 return ret;
2408 }
2409
2410 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
2411 const struct drm_plane_helper_funcs *funcs;
2412
2413 funcs = plane->helper_private;
2414
2415 if (funcs->prepare_fb) {
2416 ret = funcs->prepare_fb(plane, new_plane_state);
2417 if (ret)
2418 goto fail;
2419 }
2420 }
2421
2422 return 0;
2423
2424fail:
2425 for_each_new_plane_in_state(state, plane, new_plane_state, j) {
2426 const struct drm_plane_helper_funcs *funcs;
2427
2428 if (j >= i)
2429 continue;
2430
2431 funcs = plane->helper_private;
2432
2433 if (funcs->cleanup_fb)
2434 funcs->cleanup_fb(plane, new_plane_state);
2435 }
2436
2437 return ret;
2438}
2439EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
2440
2441static bool plane_crtc_active(const struct drm_plane_state *state)
2442{
2443 return state->crtc && state->crtc->state->active;
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
2486
2487void drm_atomic_helper_commit_planes(struct drm_device *dev,
2488 struct drm_atomic_state *old_state,
2489 uint32_t flags)
2490{
2491 struct drm_crtc *crtc;
2492 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2493 struct drm_plane *plane;
2494 struct drm_plane_state *old_plane_state, *new_plane_state;
2495 int i;
2496 bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
2497 bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
2498
2499 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2500 const struct drm_crtc_helper_funcs *funcs;
2501
2502 funcs = crtc->helper_private;
2503
2504 if (!funcs || !funcs->atomic_begin)
2505 continue;
2506
2507 if (active_only && !new_crtc_state->active)
2508 continue;
2509
2510 funcs->atomic_begin(crtc, old_crtc_state);
2511 }
2512
2513 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
2514 const struct drm_plane_helper_funcs *funcs;
2515 bool disabling;
2516
2517 funcs = plane->helper_private;
2518
2519 if (!funcs)
2520 continue;
2521
2522 disabling = drm_atomic_plane_disabling(old_plane_state,
2523 new_plane_state);
2524
2525 if (active_only) {
2526
2527
2528
2529
2530
2531
2532
2533 if (!disabling && !plane_crtc_active(new_plane_state))
2534 continue;
2535 if (disabling && !plane_crtc_active(old_plane_state))
2536 continue;
2537 }
2538
2539
2540
2541
2542 if (disabling && funcs->atomic_disable) {
2543 struct drm_crtc_state *crtc_state;
2544
2545 crtc_state = old_plane_state->crtc->state;
2546
2547 if (drm_atomic_crtc_needs_modeset(crtc_state) &&
2548 no_disable)
2549 continue;
2550
2551 funcs->atomic_disable(plane, old_plane_state);
2552 } else if (new_plane_state->crtc || disabling) {
2553 funcs->atomic_update(plane, old_plane_state);
2554 }
2555 }
2556
2557 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2558 const struct drm_crtc_helper_funcs *funcs;
2559
2560 funcs = crtc->helper_private;
2561
2562 if (!funcs || !funcs->atomic_flush)
2563 continue;
2564
2565 if (active_only && !new_crtc_state->active)
2566 continue;
2567
2568 funcs->atomic_flush(crtc, old_crtc_state);
2569 }
2570}
2571EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590void
2591drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
2592{
2593 const struct drm_crtc_helper_funcs *crtc_funcs;
2594 struct drm_crtc *crtc = old_crtc_state->crtc;
2595 struct drm_atomic_state *old_state = old_crtc_state->state;
2596 struct drm_crtc_state *new_crtc_state =
2597 drm_atomic_get_new_crtc_state(old_state, crtc);
2598 struct drm_plane *plane;
2599 unsigned plane_mask;
2600
2601 plane_mask = old_crtc_state->plane_mask;
2602 plane_mask |= new_crtc_state->plane_mask;
2603
2604 crtc_funcs = crtc->helper_private;
2605 if (crtc_funcs && crtc_funcs->atomic_begin)
2606 crtc_funcs->atomic_begin(crtc, old_crtc_state);
2607
2608 drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
2609 struct drm_plane_state *old_plane_state =
2610 drm_atomic_get_old_plane_state(old_state, plane);
2611 struct drm_plane_state *new_plane_state =
2612 drm_atomic_get_new_plane_state(old_state, plane);
2613 const struct drm_plane_helper_funcs *plane_funcs;
2614
2615 plane_funcs = plane->helper_private;
2616
2617 if (!old_plane_state || !plane_funcs)
2618 continue;
2619
2620 WARN_ON(new_plane_state->crtc &&
2621 new_plane_state->crtc != crtc);
2622
2623 if (drm_atomic_plane_disabling(old_plane_state, new_plane_state) &&
2624 plane_funcs->atomic_disable)
2625 plane_funcs->atomic_disable(plane, old_plane_state);
2626 else if (new_plane_state->crtc ||
2627 drm_atomic_plane_disabling(old_plane_state, new_plane_state))
2628 plane_funcs->atomic_update(plane, old_plane_state);
2629 }
2630
2631 if (crtc_funcs && crtc_funcs->atomic_flush)
2632 crtc_funcs->atomic_flush(crtc, old_crtc_state);
2633}
2634EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652void
2653drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
2654 bool atomic)
2655{
2656 struct drm_crtc *crtc = old_crtc_state->crtc;
2657 const struct drm_crtc_helper_funcs *crtc_funcs =
2658 crtc->helper_private;
2659 struct drm_plane *plane;
2660
2661 if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
2662 crtc_funcs->atomic_begin(crtc, NULL);
2663
2664 drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
2665 const struct drm_plane_helper_funcs *plane_funcs =
2666 plane->helper_private;
2667
2668 if (!plane_funcs)
2669 continue;
2670
2671 WARN_ON(!plane_funcs->atomic_disable);
2672 if (plane_funcs->atomic_disable)
2673 plane_funcs->atomic_disable(plane, NULL);
2674 }
2675
2676 if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
2677 crtc_funcs->atomic_flush(crtc, NULL);
2678}
2679EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
2694 struct drm_atomic_state *old_state)
2695{
2696 struct drm_plane *plane;
2697 struct drm_plane_state *old_plane_state, *new_plane_state;
2698 int i;
2699
2700 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
2701 const struct drm_plane_helper_funcs *funcs;
2702 struct drm_plane_state *plane_state;
2703
2704
2705
2706
2707
2708 if (old_plane_state == plane->state)
2709 plane_state = new_plane_state;
2710 else
2711 plane_state = old_plane_state;
2712
2713 funcs = plane->helper_private;
2714
2715 if (funcs->cleanup_fb)
2716 funcs->cleanup_fb(plane, plane_state);
2717 }
2718}
2719EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
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
2755
2756int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2757 bool stall)
2758{
2759 int i, ret;
2760 struct drm_connector *connector;
2761 struct drm_connector_state *old_conn_state, *new_conn_state;
2762 struct drm_crtc *crtc;
2763 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2764 struct drm_plane *plane;
2765 struct drm_plane_state *old_plane_state, *new_plane_state;
2766 struct drm_crtc_commit *commit;
2767 struct drm_private_obj *obj;
2768 struct drm_private_state *old_obj_state, *new_obj_state;
2769
2770 if (stall) {
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780 for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
2781 commit = old_crtc_state->commit;
2782
2783 if (!commit)
2784 continue;
2785
2786 ret = wait_for_completion_interruptible(&commit->hw_done);
2787 if (ret)
2788 return ret;
2789 }
2790
2791 for_each_old_connector_in_state(state, connector, old_conn_state, i) {
2792 commit = old_conn_state->commit;
2793
2794 if (!commit)
2795 continue;
2796
2797 ret = wait_for_completion_interruptible(&commit->hw_done);
2798 if (ret)
2799 return ret;
2800 }
2801
2802 for_each_old_plane_in_state(state, plane, old_plane_state, i) {
2803 commit = old_plane_state->commit;
2804
2805 if (!commit)
2806 continue;
2807
2808 ret = wait_for_completion_interruptible(&commit->hw_done);
2809 if (ret)
2810 return ret;
2811 }
2812 }
2813
2814 for_each_oldnew_connector_in_state(state, connector, old_conn_state, new_conn_state, i) {
2815 WARN_ON(connector->state != old_conn_state);
2816
2817 old_conn_state->state = state;
2818 new_conn_state->state = NULL;
2819
2820 state->connectors[i].state = old_conn_state;
2821 connector->state = new_conn_state;
2822 }
2823
2824 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
2825 WARN_ON(crtc->state != old_crtc_state);
2826
2827 old_crtc_state->state = state;
2828 new_crtc_state->state = NULL;
2829
2830 state->crtcs[i].state = old_crtc_state;
2831 crtc->state = new_crtc_state;
2832
2833 if (new_crtc_state->commit) {
2834 spin_lock(&crtc->commit_lock);
2835 list_add(&new_crtc_state->commit->commit_entry,
2836 &crtc->commit_list);
2837 spin_unlock(&crtc->commit_lock);
2838
2839 new_crtc_state->commit->event = NULL;
2840 }
2841 }
2842
2843 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
2844 WARN_ON(plane->state != old_plane_state);
2845
2846 old_plane_state->state = state;
2847 new_plane_state->state = NULL;
2848
2849 state->planes[i].state = old_plane_state;
2850 plane->state = new_plane_state;
2851 }
2852
2853 for_each_oldnew_private_obj_in_state(state, obj, old_obj_state, new_obj_state, i) {
2854 WARN_ON(obj->state != old_obj_state);
2855
2856 old_obj_state->state = state;
2857 new_obj_state->state = NULL;
2858
2859 state->private_objs[i].state = old_obj_state;
2860 obj->state = new_obj_state;
2861 }
2862
2863 return 0;
2864}
2865EXPORT_SYMBOL(drm_atomic_helper_swap_state);
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887int drm_atomic_helper_update_plane(struct drm_plane *plane,
2888 struct drm_crtc *crtc,
2889 struct drm_framebuffer *fb,
2890 int crtc_x, int crtc_y,
2891 unsigned int crtc_w, unsigned int crtc_h,
2892 uint32_t src_x, uint32_t src_y,
2893 uint32_t src_w, uint32_t src_h,
2894 struct drm_modeset_acquire_ctx *ctx)
2895{
2896 struct drm_atomic_state *state;
2897 struct drm_plane_state *plane_state;
2898 int ret = 0;
2899
2900 state = drm_atomic_state_alloc(plane->dev);
2901 if (!state)
2902 return -ENOMEM;
2903
2904 state->acquire_ctx = ctx;
2905 plane_state = drm_atomic_get_plane_state(state, plane);
2906 if (IS_ERR(plane_state)) {
2907 ret = PTR_ERR(plane_state);
2908 goto fail;
2909 }
2910
2911 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2912 if (ret != 0)
2913 goto fail;
2914 drm_atomic_set_fb_for_plane(plane_state, fb);
2915 plane_state->crtc_x = crtc_x;
2916 plane_state->crtc_y = crtc_y;
2917 plane_state->crtc_w = crtc_w;
2918 plane_state->crtc_h = crtc_h;
2919 plane_state->src_x = src_x;
2920 plane_state->src_y = src_y;
2921 plane_state->src_w = src_w;
2922 plane_state->src_h = src_h;
2923
2924 if (plane == crtc->cursor)
2925 state->legacy_cursor_update = true;
2926
2927 ret = drm_atomic_commit(state);
2928fail:
2929 drm_atomic_state_put(state);
2930 return ret;
2931}
2932EXPORT_SYMBOL(drm_atomic_helper_update_plane);
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944int drm_atomic_helper_disable_plane(struct drm_plane *plane,
2945 struct drm_modeset_acquire_ctx *ctx)
2946{
2947 struct drm_atomic_state *state;
2948 struct drm_plane_state *plane_state;
2949 int ret = 0;
2950
2951 state = drm_atomic_state_alloc(plane->dev);
2952 if (!state)
2953 return -ENOMEM;
2954
2955 state->acquire_ctx = ctx;
2956 plane_state = drm_atomic_get_plane_state(state, plane);
2957 if (IS_ERR(plane_state)) {
2958 ret = PTR_ERR(plane_state);
2959 goto fail;
2960 }
2961
2962 if (plane_state->crtc && plane_state->crtc->cursor == plane)
2963 plane_state->state->legacy_cursor_update = true;
2964
2965 ret = __drm_atomic_helper_disable_plane(plane, plane_state);
2966 if (ret != 0)
2967 goto fail;
2968
2969 ret = drm_atomic_commit(state);
2970fail:
2971 drm_atomic_state_put(state);
2972 return ret;
2973}
2974EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992int drm_atomic_helper_set_config(struct drm_mode_set *set,
2993 struct drm_modeset_acquire_ctx *ctx)
2994{
2995 struct drm_atomic_state *state;
2996 struct drm_crtc *crtc = set->crtc;
2997 int ret = 0;
2998
2999 state = drm_atomic_state_alloc(crtc->dev);
3000 if (!state)
3001 return -ENOMEM;
3002
3003 state->acquire_ctx = ctx;
3004 ret = __drm_atomic_helper_set_config(set, state);
3005 if (ret != 0)
3006 goto fail;
3007
3008 ret = handle_conflicting_encoders(state, true);
3009 if (ret)
3010 return ret;
3011
3012 ret = drm_atomic_commit(state);
3013
3014fail:
3015 drm_atomic_state_put(state);
3016 return ret;
3017}
3018EXPORT_SYMBOL(drm_atomic_helper_set_config);
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043int drm_atomic_helper_disable_all(struct drm_device *dev,
3044 struct drm_modeset_acquire_ctx *ctx)
3045{
3046 struct drm_atomic_state *state;
3047 struct drm_connector_state *conn_state;
3048 struct drm_connector *conn;
3049 struct drm_plane_state *plane_state;
3050 struct drm_plane *plane;
3051 struct drm_crtc_state *crtc_state;
3052 struct drm_crtc *crtc;
3053 int ret, i;
3054
3055 state = drm_atomic_state_alloc(dev);
3056 if (!state)
3057 return -ENOMEM;
3058
3059 state->acquire_ctx = ctx;
3060
3061 drm_for_each_crtc(crtc, dev) {
3062 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3063 if (IS_ERR(crtc_state)) {
3064 ret = PTR_ERR(crtc_state);
3065 goto free;
3066 }
3067
3068 crtc_state->active = false;
3069
3070 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, NULL);
3071 if (ret < 0)
3072 goto free;
3073
3074 ret = drm_atomic_add_affected_planes(state, crtc);
3075 if (ret < 0)
3076 goto free;
3077
3078 ret = drm_atomic_add_affected_connectors(state, crtc);
3079 if (ret < 0)
3080 goto free;
3081 }
3082
3083 for_each_new_connector_in_state(state, conn, conn_state, i) {
3084 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
3085 if (ret < 0)
3086 goto free;
3087 }
3088
3089 for_each_new_plane_in_state(state, plane, plane_state, i) {
3090 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
3091 if (ret < 0)
3092 goto free;
3093
3094 drm_atomic_set_fb_for_plane(plane_state, NULL);
3095 }
3096
3097 ret = drm_atomic_commit(state);
3098free:
3099 drm_atomic_state_put(state);
3100 return ret;
3101}
3102EXPORT_SYMBOL(drm_atomic_helper_disable_all);
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115void drm_atomic_helper_shutdown(struct drm_device *dev)
3116{
3117 struct drm_modeset_acquire_ctx ctx;
3118 int ret;
3119
3120 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, ret);
3121
3122 ret = drm_atomic_helper_disable_all(dev, &ctx);
3123 if (ret)
3124 DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
3125
3126 DRM_MODESET_LOCK_ALL_END(dev, ctx, ret);
3127}
3128EXPORT_SYMBOL(drm_atomic_helper_shutdown);
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154struct drm_atomic_state *
3155drm_atomic_helper_duplicate_state(struct drm_device *dev,
3156 struct drm_modeset_acquire_ctx *ctx)
3157{
3158 struct drm_atomic_state *state;
3159 struct drm_connector *conn;
3160 struct drm_connector_list_iter conn_iter;
3161 struct drm_plane *plane;
3162 struct drm_crtc *crtc;
3163 int err = 0;
3164
3165 state = drm_atomic_state_alloc(dev);
3166 if (!state)
3167 return ERR_PTR(-ENOMEM);
3168
3169 state->acquire_ctx = ctx;
3170 state->duplicated = true;
3171
3172 drm_for_each_crtc(crtc, dev) {
3173 struct drm_crtc_state *crtc_state;
3174
3175 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3176 if (IS_ERR(crtc_state)) {
3177 err = PTR_ERR(crtc_state);
3178 goto free;
3179 }
3180 }
3181
3182 drm_for_each_plane(plane, dev) {
3183 struct drm_plane_state *plane_state;
3184
3185 plane_state = drm_atomic_get_plane_state(state, plane);
3186 if (IS_ERR(plane_state)) {
3187 err = PTR_ERR(plane_state);
3188 goto free;
3189 }
3190 }
3191
3192 drm_connector_list_iter_begin(dev, &conn_iter);
3193 drm_for_each_connector_iter(conn, &conn_iter) {
3194 struct drm_connector_state *conn_state;
3195
3196 conn_state = drm_atomic_get_connector_state(state, conn);
3197 if (IS_ERR(conn_state)) {
3198 err = PTR_ERR(conn_state);
3199 drm_connector_list_iter_end(&conn_iter);
3200 goto free;
3201 }
3202 }
3203 drm_connector_list_iter_end(&conn_iter);
3204
3205
3206 state->acquire_ctx = NULL;
3207
3208free:
3209 if (err < 0) {
3210 drm_atomic_state_put(state);
3211 state = ERR_PTR(err);
3212 }
3213
3214 return state;
3215}
3216EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);
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
3242
3243struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
3244{
3245 struct drm_modeset_acquire_ctx ctx;
3246 struct drm_atomic_state *state;
3247 int err;
3248
3249
3250 state = ERR_PTR(-EINVAL);
3251
3252 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);
3253
3254 state = drm_atomic_helper_duplicate_state(dev, &ctx);
3255 if (IS_ERR(state))
3256 goto unlock;
3257
3258 err = drm_atomic_helper_disable_all(dev, &ctx);
3259 if (err < 0) {
3260 drm_atomic_state_put(state);
3261 state = ERR_PTR(err);
3262 goto unlock;
3263 }
3264
3265unlock:
3266 DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
3267 if (err)
3268 return ERR_PTR(err);
3269
3270 return state;
3271}
3272EXPORT_SYMBOL(drm_atomic_helper_suspend);
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
3290 struct drm_modeset_acquire_ctx *ctx)
3291{
3292 int i, ret;
3293 struct drm_plane *plane;
3294 struct drm_plane_state *new_plane_state;
3295 struct drm_connector *connector;
3296 struct drm_connector_state *new_conn_state;
3297 struct drm_crtc *crtc;
3298 struct drm_crtc_state *new_crtc_state;
3299
3300 state->acquire_ctx = ctx;
3301
3302 for_each_new_plane_in_state(state, plane, new_plane_state, i)
3303 state->planes[i].old_state = plane->state;
3304
3305 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
3306 state->crtcs[i].old_state = crtc->state;
3307
3308 for_each_new_connector_in_state(state, connector, new_conn_state, i)
3309 state->connectors[i].old_state = connector->state;
3310
3311 ret = drm_atomic_commit(state);
3312
3313 state->acquire_ctx = NULL;
3314
3315 return ret;
3316}
3317EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335int drm_atomic_helper_resume(struct drm_device *dev,
3336 struct drm_atomic_state *state)
3337{
3338 struct drm_modeset_acquire_ctx ctx;
3339 int err;
3340
3341 drm_mode_config_reset(dev);
3342
3343 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, 0, err);
3344
3345 err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
3346
3347 DRM_MODESET_LOCK_ALL_END(dev, ctx, err);
3348 drm_atomic_state_put(state);
3349
3350 return err;
3351}
3352EXPORT_SYMBOL(drm_atomic_helper_resume);
3353
3354static int page_flip_common(struct drm_atomic_state *state,
3355 struct drm_crtc *crtc,
3356 struct drm_framebuffer *fb,
3357 struct drm_pending_vblank_event *event,
3358 uint32_t flags)
3359{
3360 struct drm_plane *plane = crtc->primary;
3361 struct drm_plane_state *plane_state;
3362 struct drm_crtc_state *crtc_state;
3363 int ret = 0;
3364
3365 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3366 if (IS_ERR(crtc_state))
3367 return PTR_ERR(crtc_state);
3368
3369 crtc_state->event = event;
3370 crtc_state->async_flip = flags & DRM_MODE_PAGE_FLIP_ASYNC;
3371
3372 plane_state = drm_atomic_get_plane_state(state, plane);
3373 if (IS_ERR(plane_state))
3374 return PTR_ERR(plane_state);
3375
3376 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
3377 if (ret != 0)
3378 return ret;
3379 drm_atomic_set_fb_for_plane(plane_state, fb);
3380
3381
3382 state->allow_modeset = false;
3383 if (!crtc_state->active) {
3384 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled, rejecting legacy flip\n",
3385 crtc->base.id, crtc->name);
3386 return -EINVAL;
3387 }
3388
3389 return ret;
3390}
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
3410 struct drm_framebuffer *fb,
3411 struct drm_pending_vblank_event *event,
3412 uint32_t flags,
3413 struct drm_modeset_acquire_ctx *ctx)
3414{
3415 struct drm_plane *plane = crtc->primary;
3416 struct drm_atomic_state *state;
3417 int ret = 0;
3418
3419 state = drm_atomic_state_alloc(plane->dev);
3420 if (!state)
3421 return -ENOMEM;
3422
3423 state->acquire_ctx = ctx;
3424
3425 ret = page_flip_common(state, crtc, fb, event, flags);
3426 if (ret != 0)
3427 goto fail;
3428
3429 ret = drm_atomic_nonblocking_commit(state);
3430fail:
3431 drm_atomic_state_put(state);
3432 return ret;
3433}
3434EXPORT_SYMBOL(drm_atomic_helper_page_flip);
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc,
3453 struct drm_framebuffer *fb,
3454 struct drm_pending_vblank_event *event,
3455 uint32_t flags,
3456 uint32_t target,
3457 struct drm_modeset_acquire_ctx *ctx)
3458{
3459 struct drm_plane *plane = crtc->primary;
3460 struct drm_atomic_state *state;
3461 struct drm_crtc_state *crtc_state;
3462 int ret = 0;
3463
3464 state = drm_atomic_state_alloc(plane->dev);
3465 if (!state)
3466 return -ENOMEM;
3467
3468 state->acquire_ctx = ctx;
3469
3470 ret = page_flip_common(state, crtc, fb, event, flags);
3471 if (ret != 0)
3472 goto fail;
3473
3474 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
3475 if (WARN_ON(!crtc_state)) {
3476 ret = -EINVAL;
3477 goto fail;
3478 }
3479 crtc_state->target_vblank = target;
3480
3481 ret = drm_atomic_nonblocking_commit(state);
3482fail:
3483 drm_atomic_state_put(state);
3484 return ret;
3485}
3486EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3503 u16 *red, u16 *green, u16 *blue,
3504 uint32_t size,
3505 struct drm_modeset_acquire_ctx *ctx)
3506{
3507 struct drm_device *dev = crtc->dev;
3508 struct drm_atomic_state *state;
3509 struct drm_crtc_state *crtc_state;
3510 struct drm_property_blob *blob = NULL;
3511 struct drm_color_lut *blob_data;
3512 int i, ret = 0;
3513 bool replaced;
3514
3515 state = drm_atomic_state_alloc(crtc->dev);
3516 if (!state)
3517 return -ENOMEM;
3518
3519 blob = drm_property_create_blob(dev,
3520 sizeof(struct drm_color_lut) * size,
3521 NULL);
3522 if (IS_ERR(blob)) {
3523 ret = PTR_ERR(blob);
3524 blob = NULL;
3525 goto fail;
3526 }
3527
3528
3529 blob_data = blob->data;
3530 for (i = 0; i < size; i++) {
3531 blob_data[i].red = red[i];
3532 blob_data[i].green = green[i];
3533 blob_data[i].blue = blue[i];
3534 }
3535
3536 state->acquire_ctx = ctx;
3537 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3538 if (IS_ERR(crtc_state)) {
3539 ret = PTR_ERR(crtc_state);
3540 goto fail;
3541 }
3542
3543
3544 replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
3545 replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
3546 replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
3547 crtc_state->color_mgmt_changed |= replaced;
3548
3549 ret = drm_atomic_commit(state);
3550
3551fail:
3552 drm_atomic_state_put(state);
3553 drm_property_blob_put(blob);
3554 return ret;
3555}
3556EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577u32 *
3578drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge,
3579 struct drm_bridge_state *bridge_state,
3580 struct drm_crtc_state *crtc_state,
3581 struct drm_connector_state *conn_state,
3582 u32 output_fmt,
3583 unsigned int *num_input_fmts)
3584{
3585 u32 *input_fmts;
3586
3587 input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL);
3588 if (!input_fmts) {
3589 *num_input_fmts = 0;
3590 return NULL;
3591 }
3592
3593 *num_input_fmts = 1;
3594 input_fmts[0] = output_fmt;
3595 return input_fmts;
3596}
3597EXPORT_SYMBOL(drm_atomic_helper_bridge_propagate_bus_fmt);
3598