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