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