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
719
720int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
721 const struct drm_crtc_state *crtc_state,
722 const struct drm_rect *clip,
723 int min_scale,
724 int max_scale,
725 bool can_position,
726 bool can_update_disabled)
727{
728 struct drm_framebuffer *fb = plane_state->fb;
729 struct drm_rect *src = &plane_state->src;
730 struct drm_rect *dst = &plane_state->dst;
731 unsigned int rotation = plane_state->rotation;
732 int hscale, vscale;
733
734 WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc);
735
736 *src = drm_plane_state_src(plane_state);
737 *dst = drm_plane_state_dest(plane_state);
738
739 if (!fb) {
740 plane_state->visible = false;
741 return 0;
742 }
743
744
745 if (WARN_ON(!plane_state->crtc)) {
746 plane_state->visible = false;
747 return 0;
748 }
749
750 if (!crtc_state->enable && !can_update_disabled) {
751 DRM_DEBUG_KMS("Cannot update plane of a disabled CRTC.\n");
752 return -EINVAL;
753 }
754
755 drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
756
757
758 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
759 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
760 if (hscale < 0 || vscale < 0) {
761 DRM_DEBUG_KMS("Invalid scaling of plane\n");
762 drm_rect_debug_print("src: ", &plane_state->src, true);
763 drm_rect_debug_print("dst: ", &plane_state->dst, false);
764 return -ERANGE;
765 }
766
767 plane_state->visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
768
769 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
770
771 if (!plane_state->visible)
772
773
774
775
776
777
778
779 return 0;
780
781 if (!can_position && !drm_rect_equals(dst, clip)) {
782 DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
783 drm_rect_debug_print("dst: ", dst, false);
784 drm_rect_debug_print("clip: ", clip, false);
785 return -EINVAL;
786 }
787
788 return 0;
789}
790EXPORT_SYMBOL(drm_atomic_helper_check_plane_state);
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808int
809drm_atomic_helper_check_planes(struct drm_device *dev,
810 struct drm_atomic_state *state)
811{
812 struct drm_crtc *crtc;
813 struct drm_crtc_state *new_crtc_state;
814 struct drm_plane *plane;
815 struct drm_plane_state *new_plane_state, *old_plane_state;
816 int i, ret = 0;
817
818 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
819 const struct drm_plane_helper_funcs *funcs;
820
821 WARN_ON(!drm_modeset_is_locked(&plane->mutex));
822
823 funcs = plane->helper_private;
824
825 drm_atomic_helper_plane_changed(state, old_plane_state, new_plane_state, plane);
826
827 if (!funcs || !funcs->atomic_check)
828 continue;
829
830 ret = funcs->atomic_check(plane, new_plane_state);
831 if (ret) {
832 DRM_DEBUG_ATOMIC("[PLANE:%d:%s] atomic driver check failed\n",
833 plane->base.id, plane->name);
834 return ret;
835 }
836 }
837
838 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
839 const struct drm_crtc_helper_funcs *funcs;
840
841 funcs = crtc->helper_private;
842
843 if (!funcs || !funcs->atomic_check)
844 continue;
845
846 ret = funcs->atomic_check(crtc, new_crtc_state);
847 if (ret) {
848 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
849 crtc->base.id, crtc->name);
850 return ret;
851 }
852 }
853
854 return ret;
855}
856EXPORT_SYMBOL(drm_atomic_helper_check_planes);
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879int drm_atomic_helper_check(struct drm_device *dev,
880 struct drm_atomic_state *state)
881{
882 int ret;
883
884 ret = drm_atomic_helper_check_modeset(dev, state);
885 if (ret)
886 return ret;
887
888 ret = drm_atomic_helper_check_planes(dev, state);
889 if (ret)
890 return ret;
891
892 if (state->legacy_cursor_update)
893 state->async_update = !drm_atomic_helper_async_check(dev, state);
894
895 return ret;
896}
897EXPORT_SYMBOL(drm_atomic_helper_check);
898
899static void
900disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
901{
902 struct drm_connector *connector;
903 struct drm_connector_state *old_conn_state, *new_conn_state;
904 struct drm_crtc *crtc;
905 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
906 int i;
907
908 for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
909 const struct drm_encoder_helper_funcs *funcs;
910 struct drm_encoder *encoder;
911
912
913
914 if (!old_conn_state->crtc)
915 continue;
916
917 old_crtc_state = drm_atomic_get_old_crtc_state(old_state, old_conn_state->crtc);
918
919 if (!old_crtc_state->active ||
920 !drm_atomic_crtc_needs_modeset(old_conn_state->crtc->state))
921 continue;
922
923 encoder = old_conn_state->best_encoder;
924
925
926
927
928 if (WARN_ON(!encoder))
929 continue;
930
931 funcs = encoder->helper_private;
932
933 DRM_DEBUG_ATOMIC("disabling [ENCODER:%d:%s]\n",
934 encoder->base.id, encoder->name);
935
936
937
938
939
940 drm_bridge_disable(encoder->bridge);
941
942
943 if (funcs) {
944 if (new_conn_state->crtc && funcs->prepare)
945 funcs->prepare(encoder);
946 else if (funcs->disable)
947 funcs->disable(encoder);
948 else if (funcs->dpms)
949 funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
950 }
951
952 drm_bridge_post_disable(encoder->bridge);
953 }
954
955 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
956 const struct drm_crtc_helper_funcs *funcs;
957 int ret;
958
959
960 if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
961 continue;
962
963 if (!old_crtc_state->active)
964 continue;
965
966 funcs = crtc->helper_private;
967
968 DRM_DEBUG_ATOMIC("disabling [CRTC:%d:%s]\n",
969 crtc->base.id, crtc->name);
970
971
972
973 if (new_crtc_state->enable && funcs->prepare)
974 funcs->prepare(crtc);
975 else if (funcs->atomic_disable)
976 funcs->atomic_disable(crtc, old_crtc_state);
977 else if (funcs->disable)
978 funcs->disable(crtc);
979 else
980 funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
981
982 if (!(dev->irq_enabled && dev->num_crtcs))
983 continue;
984
985 ret = drm_crtc_vblank_get(crtc);
986 WARN_ONCE(ret != -EINVAL, "driver forgot to call drm_crtc_vblank_off()\n");
987 if (ret == 0)
988 drm_crtc_vblank_put(crtc);
989 }
990}
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011void
1012drm_atomic_helper_update_legacy_modeset_state(struct drm_device *dev,
1013 struct drm_atomic_state *old_state)
1014{
1015 struct drm_connector *connector;
1016 struct drm_connector_state *old_conn_state, *new_conn_state;
1017 struct drm_crtc *crtc;
1018 struct drm_crtc_state *new_crtc_state;
1019 int i;
1020
1021
1022 for_each_oldnew_connector_in_state(old_state, connector, old_conn_state, new_conn_state, i) {
1023 if (connector->encoder) {
1024 WARN_ON(!connector->encoder->crtc);
1025
1026 connector->encoder->crtc = NULL;
1027 connector->encoder = NULL;
1028 }
1029
1030 crtc = new_conn_state->crtc;
1031 if ((!crtc && old_conn_state->crtc) ||
1032 (crtc && drm_atomic_crtc_needs_modeset(crtc->state))) {
1033 int mode = DRM_MODE_DPMS_OFF;
1034
1035 if (crtc && crtc->state->active)
1036 mode = DRM_MODE_DPMS_ON;
1037
1038 connector->dpms = mode;
1039 }
1040 }
1041
1042
1043 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1044 if (!new_conn_state->crtc)
1045 continue;
1046
1047 if (WARN_ON(!new_conn_state->best_encoder))
1048 continue;
1049
1050 connector->encoder = new_conn_state->best_encoder;
1051 connector->encoder->crtc = new_conn_state->crtc;
1052 }
1053
1054
1055 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1056 struct drm_plane *primary = crtc->primary;
1057 struct drm_plane_state *new_plane_state;
1058
1059 crtc->mode = new_crtc_state->mode;
1060 crtc->enabled = new_crtc_state->enable;
1061
1062 new_plane_state =
1063 drm_atomic_get_new_plane_state(old_state, primary);
1064
1065 if (new_plane_state && new_plane_state->crtc == crtc) {
1066 crtc->x = new_plane_state->src_x >> 16;
1067 crtc->y = new_plane_state->src_y >> 16;
1068 }
1069
1070 if (new_crtc_state->enable)
1071 drm_calc_timestamping_constants(crtc,
1072 &new_crtc_state->adjusted_mode);
1073 }
1074}
1075EXPORT_SYMBOL(drm_atomic_helper_update_legacy_modeset_state);
1076
1077static void
1078crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
1079{
1080 struct drm_crtc *crtc;
1081 struct drm_crtc_state *new_crtc_state;
1082 struct drm_connector *connector;
1083 struct drm_connector_state *new_conn_state;
1084 int i;
1085
1086 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1087 const struct drm_crtc_helper_funcs *funcs;
1088
1089 if (!new_crtc_state->mode_changed)
1090 continue;
1091
1092 funcs = crtc->helper_private;
1093
1094 if (new_crtc_state->enable && funcs->mode_set_nofb) {
1095 DRM_DEBUG_ATOMIC("modeset on [CRTC:%d:%s]\n",
1096 crtc->base.id, crtc->name);
1097
1098 funcs->mode_set_nofb(crtc);
1099 }
1100 }
1101
1102 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1103 const struct drm_encoder_helper_funcs *funcs;
1104 struct drm_encoder *encoder;
1105 struct drm_display_mode *mode, *adjusted_mode;
1106
1107 if (!new_conn_state->best_encoder)
1108 continue;
1109
1110 encoder = new_conn_state->best_encoder;
1111 funcs = encoder->helper_private;
1112 new_crtc_state = new_conn_state->crtc->state;
1113 mode = &new_crtc_state->mode;
1114 adjusted_mode = &new_crtc_state->adjusted_mode;
1115
1116 if (!new_crtc_state->mode_changed)
1117 continue;
1118
1119 DRM_DEBUG_ATOMIC("modeset on [ENCODER:%d:%s]\n",
1120 encoder->base.id, encoder->name);
1121
1122
1123
1124
1125
1126 if (funcs && funcs->atomic_mode_set) {
1127 funcs->atomic_mode_set(encoder, new_crtc_state,
1128 new_conn_state);
1129 } else if (funcs && funcs->mode_set) {
1130 funcs->mode_set(encoder, mode, adjusted_mode);
1131 }
1132
1133 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
1134 }
1135}
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151void drm_atomic_helper_commit_modeset_disables(struct drm_device *dev,
1152 struct drm_atomic_state *old_state)
1153{
1154 disable_outputs(dev, old_state);
1155
1156 drm_atomic_helper_update_legacy_modeset_state(dev, old_state);
1157
1158 crtc_set_mode(dev, old_state);
1159}
1160EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_disables);
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176void drm_atomic_helper_commit_modeset_enables(struct drm_device *dev,
1177 struct drm_atomic_state *old_state)
1178{
1179 struct drm_crtc *crtc;
1180 struct drm_crtc_state *old_crtc_state;
1181 struct drm_crtc_state *new_crtc_state;
1182 struct drm_connector *connector;
1183 struct drm_connector_state *new_conn_state;
1184 int i;
1185
1186 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1187 const struct drm_crtc_helper_funcs *funcs;
1188
1189
1190 if (!drm_atomic_crtc_needs_modeset(new_crtc_state))
1191 continue;
1192
1193 if (!new_crtc_state->active)
1194 continue;
1195
1196 funcs = crtc->helper_private;
1197
1198 if (new_crtc_state->enable) {
1199 DRM_DEBUG_ATOMIC("enabling [CRTC:%d:%s]\n",
1200 crtc->base.id, crtc->name);
1201
1202 if (funcs->atomic_enable)
1203 funcs->atomic_enable(crtc, old_crtc_state);
1204 else
1205 funcs->commit(crtc);
1206 }
1207 }
1208
1209 for_each_new_connector_in_state(old_state, connector, new_conn_state, i) {
1210 const struct drm_encoder_helper_funcs *funcs;
1211 struct drm_encoder *encoder;
1212
1213 if (!new_conn_state->best_encoder)
1214 continue;
1215
1216 if (!new_conn_state->crtc->state->active ||
1217 !drm_atomic_crtc_needs_modeset(new_conn_state->crtc->state))
1218 continue;
1219
1220 encoder = new_conn_state->best_encoder;
1221 funcs = encoder->helper_private;
1222
1223 DRM_DEBUG_ATOMIC("enabling [ENCODER:%d:%s]\n",
1224 encoder->base.id, encoder->name);
1225
1226
1227
1228
1229
1230 drm_bridge_pre_enable(encoder->bridge);
1231
1232 if (funcs) {
1233 if (funcs->enable)
1234 funcs->enable(encoder);
1235 else if (funcs->commit)
1236 funcs->commit(encoder);
1237 }
1238
1239 drm_bridge_enable(encoder->bridge);
1240 }
1241}
1242EXPORT_SYMBOL(drm_atomic_helper_commit_modeset_enables);
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265int drm_atomic_helper_wait_for_fences(struct drm_device *dev,
1266 struct drm_atomic_state *state,
1267 bool pre_swap)
1268{
1269 struct drm_plane *plane;
1270 struct drm_plane_state *new_plane_state;
1271 int i, ret;
1272
1273 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
1274 if (!new_plane_state->fence)
1275 continue;
1276
1277 WARN_ON(!new_plane_state->fb);
1278
1279
1280
1281
1282
1283
1284 ret = dma_fence_wait(new_plane_state->fence, pre_swap);
1285 if (ret)
1286 return ret;
1287
1288 dma_fence_put(new_plane_state->fence);
1289 new_plane_state->fence = NULL;
1290 }
1291
1292 return 0;
1293}
1294EXPORT_SYMBOL(drm_atomic_helper_wait_for_fences);
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311void
1312drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
1313 struct drm_atomic_state *old_state)
1314{
1315 struct drm_crtc *crtc;
1316 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1317 int i, ret;
1318 unsigned crtc_mask = 0;
1319
1320
1321
1322
1323
1324 if (old_state->legacy_cursor_update)
1325 return;
1326
1327 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
1328 if (!new_crtc_state->active)
1329 continue;
1330
1331 ret = drm_crtc_vblank_get(crtc);
1332 if (ret != 0)
1333 continue;
1334
1335 crtc_mask |= drm_crtc_mask(crtc);
1336 old_state->crtcs[i].last_vblank_count = drm_crtc_vblank_count(crtc);
1337 }
1338
1339 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1340 if (!(crtc_mask & drm_crtc_mask(crtc)))
1341 continue;
1342
1343 ret = wait_event_timeout(dev->vblank[i].queue,
1344 old_state->crtcs[i].last_vblank_count !=
1345 drm_crtc_vblank_count(crtc),
1346 msecs_to_jiffies(50));
1347
1348 WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
1349 crtc->base.id, crtc->name);
1350
1351 drm_crtc_vblank_put(crtc);
1352 }
1353}
1354EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371void drm_atomic_helper_wait_for_flip_done(struct drm_device *dev,
1372 struct drm_atomic_state *old_state)
1373{
1374 struct drm_crtc_state *new_crtc_state;
1375 struct drm_crtc *crtc;
1376 int i;
1377
1378 for_each_new_crtc_in_state(old_state, crtc, new_crtc_state, i) {
1379 struct drm_crtc_commit *commit = new_crtc_state->commit;
1380 int ret;
1381
1382 if (!commit)
1383 continue;
1384
1385 ret = wait_for_completion_timeout(&commit->flip_done, 10 * HZ);
1386 if (ret == 0)
1387 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1388 crtc->base.id, crtc->name);
1389 }
1390}
1391EXPORT_SYMBOL(drm_atomic_helper_wait_for_flip_done);
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406void drm_atomic_helper_commit_tail(struct drm_atomic_state *old_state)
1407{
1408 struct drm_device *dev = old_state->dev;
1409
1410 drm_atomic_helper_commit_modeset_disables(dev, old_state);
1411
1412 drm_atomic_helper_commit_planes(dev, old_state, 0);
1413
1414 drm_atomic_helper_commit_modeset_enables(dev, old_state);
1415
1416 drm_atomic_helper_commit_hw_done(old_state);
1417
1418 drm_atomic_helper_wait_for_vblanks(dev, old_state);
1419
1420 drm_atomic_helper_cleanup_planes(dev, old_state);
1421}
1422EXPORT_SYMBOL(drm_atomic_helper_commit_tail);
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_state *old_state)
1435{
1436 struct drm_device *dev = old_state->dev;
1437
1438 drm_atomic_helper_commit_modeset_disables(dev, old_state);
1439
1440 drm_atomic_helper_commit_modeset_enables(dev, old_state);
1441
1442 drm_atomic_helper_commit_planes(dev, old_state,
1443 DRM_PLANE_COMMIT_ACTIVE_ONLY);
1444
1445 drm_atomic_helper_commit_hw_done(old_state);
1446
1447 drm_atomic_helper_wait_for_vblanks(dev, old_state);
1448
1449 drm_atomic_helper_cleanup_planes(dev, old_state);
1450}
1451EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm);
1452
1453static void commit_tail(struct drm_atomic_state *old_state)
1454{
1455 struct drm_device *dev = old_state->dev;
1456 const struct drm_mode_config_helper_funcs *funcs;
1457
1458 funcs = dev->mode_config.helper_private;
1459
1460 drm_atomic_helper_wait_for_fences(dev, old_state, false);
1461
1462 drm_atomic_helper_wait_for_dependencies(old_state);
1463
1464 if (funcs && funcs->atomic_commit_tail)
1465 funcs->atomic_commit_tail(old_state);
1466 else
1467 drm_atomic_helper_commit_tail(old_state);
1468
1469 drm_atomic_helper_commit_cleanup_done(old_state);
1470
1471 drm_atomic_state_put(old_state);
1472}
1473
1474static void commit_work(struct work_struct *work)
1475{
1476 struct drm_atomic_state *state = container_of(work,
1477 struct drm_atomic_state,
1478 commit_work);
1479 commit_tail(state);
1480}
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495int drm_atomic_helper_async_check(struct drm_device *dev,
1496 struct drm_atomic_state *state)
1497{
1498 struct drm_crtc *crtc;
1499 struct drm_crtc_state *crtc_state;
1500 struct drm_plane *plane;
1501 struct drm_plane_state *old_plane_state, *new_plane_state;
1502 const struct drm_plane_helper_funcs *funcs;
1503 int i, n_planes = 0;
1504
1505 for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
1506 if (drm_atomic_crtc_needs_modeset(crtc_state))
1507 return -EINVAL;
1508 }
1509
1510 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
1511 n_planes++;
1512
1513
1514 if (n_planes != 1)
1515 return -EINVAL;
1516
1517 if (!new_plane_state->crtc)
1518 return -EINVAL;
1519
1520 funcs = plane->helper_private;
1521 if (!funcs->atomic_async_update)
1522 return -EINVAL;
1523
1524 if (new_plane_state->fence)
1525 return -EINVAL;
1526
1527
1528
1529
1530
1531
1532 if (old_plane_state->commit &&
1533 !try_wait_for_completion(&old_plane_state->commit->hw_done))
1534 return -EBUSY;
1535
1536 return funcs->atomic_async_check(plane, new_plane_state);
1537}
1538EXPORT_SYMBOL(drm_atomic_helper_async_check);
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551void drm_atomic_helper_async_commit(struct drm_device *dev,
1552 struct drm_atomic_state *state)
1553{
1554 struct drm_plane *plane;
1555 struct drm_plane_state *plane_state;
1556 const struct drm_plane_helper_funcs *funcs;
1557 int i;
1558
1559 for_each_new_plane_in_state(state, plane, plane_state, i) {
1560 funcs = plane->helper_private;
1561 funcs->atomic_async_update(plane, plane_state);
1562 }
1563}
1564EXPORT_SYMBOL(drm_atomic_helper_async_commit);
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584int drm_atomic_helper_commit(struct drm_device *dev,
1585 struct drm_atomic_state *state,
1586 bool nonblock)
1587{
1588 int ret;
1589
1590 if (state->async_update) {
1591 ret = drm_atomic_helper_prepare_planes(dev, state);
1592 if (ret)
1593 return ret;
1594
1595 drm_atomic_helper_async_commit(dev, state);
1596 drm_atomic_helper_cleanup_planes(dev, state);
1597
1598 return 0;
1599 }
1600
1601 ret = drm_atomic_helper_setup_commit(state, nonblock);
1602 if (ret)
1603 return ret;
1604
1605 INIT_WORK(&state->commit_work, commit_work);
1606
1607 ret = drm_atomic_helper_prepare_planes(dev, state);
1608 if (ret)
1609 return ret;
1610
1611 if (!nonblock) {
1612 ret = drm_atomic_helper_wait_for_fences(dev, state, true);
1613 if (ret)
1614 goto err;
1615 }
1616
1617
1618
1619
1620
1621
1622
1623 ret = drm_atomic_helper_swap_state(state, true);
1624 if (ret)
1625 goto err;
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647 drm_atomic_state_get(state);
1648 if (nonblock)
1649 queue_work(system_unbound_wq, &state->commit_work);
1650 else
1651 commit_tail(state);
1652
1653 return 0;
1654
1655err:
1656 drm_atomic_helper_cleanup_planes(dev, state);
1657 return ret;
1658}
1659EXPORT_SYMBOL(drm_atomic_helper_commit);
1660
1661
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
1702static int stall_checks(struct drm_crtc *crtc, bool nonblock)
1703{
1704 struct drm_crtc_commit *commit, *stall_commit = NULL;
1705 bool completed = true;
1706 int i;
1707 long ret = 0;
1708
1709 spin_lock(&crtc->commit_lock);
1710 i = 0;
1711 list_for_each_entry(commit, &crtc->commit_list, commit_entry) {
1712 if (i == 0) {
1713 completed = try_wait_for_completion(&commit->flip_done);
1714
1715
1716 if (!completed && nonblock) {
1717 spin_unlock(&crtc->commit_lock);
1718 return -EBUSY;
1719 }
1720 } else if (i == 1) {
1721 stall_commit = drm_crtc_commit_get(commit);
1722 break;
1723 }
1724
1725 i++;
1726 }
1727 spin_unlock(&crtc->commit_lock);
1728
1729 if (!stall_commit)
1730 return 0;
1731
1732
1733
1734
1735 ret = wait_for_completion_interruptible_timeout(&stall_commit->cleanup_done,
1736 10*HZ);
1737 if (ret == 0)
1738 DRM_ERROR("[CRTC:%d:%s] cleanup_done timed out\n",
1739 crtc->base.id, crtc->name);
1740
1741 drm_crtc_commit_put(stall_commit);
1742
1743 return ret < 0 ? ret : 0;
1744}
1745
1746static void release_crtc_commit(struct completion *completion)
1747{
1748 struct drm_crtc_commit *commit = container_of(completion,
1749 typeof(*commit),
1750 flip_done);
1751
1752 drm_crtc_commit_put(commit);
1753}
1754
1755static void init_commit(struct drm_crtc_commit *commit, struct drm_crtc *crtc)
1756{
1757 init_completion(&commit->flip_done);
1758 init_completion(&commit->hw_done);
1759 init_completion(&commit->cleanup_done);
1760 INIT_LIST_HEAD(&commit->commit_entry);
1761 kref_init(&commit->ref);
1762 commit->crtc = crtc;
1763}
1764
1765static struct drm_crtc_commit *
1766crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc)
1767{
1768 if (crtc) {
1769 struct drm_crtc_state *new_crtc_state;
1770
1771 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1772
1773 return new_crtc_state->commit;
1774 }
1775
1776 if (!state->fake_commit) {
1777 state->fake_commit = kzalloc(sizeof(*state->fake_commit), GFP_KERNEL);
1778 if (!state->fake_commit)
1779 return NULL;
1780
1781 init_commit(state->fake_commit, NULL);
1782 }
1783
1784 return state->fake_commit;
1785}
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
1831 bool nonblock)
1832{
1833 struct drm_crtc *crtc;
1834 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
1835 struct drm_connector *conn;
1836 struct drm_connector_state *old_conn_state, *new_conn_state;
1837 struct drm_plane *plane;
1838 struct drm_plane_state *old_plane_state, *new_plane_state;
1839 struct drm_crtc_commit *commit;
1840 int i, ret;
1841
1842 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
1843 commit = kzalloc(sizeof(*commit), GFP_KERNEL);
1844 if (!commit)
1845 return -ENOMEM;
1846
1847 init_commit(commit, crtc);
1848
1849 new_crtc_state->commit = commit;
1850
1851 ret = stall_checks(crtc, nonblock);
1852 if (ret)
1853 return ret;
1854
1855
1856
1857
1858 if (!old_crtc_state->active && !new_crtc_state->active) {
1859 complete_all(&commit->flip_done);
1860 continue;
1861 }
1862
1863
1864 if (state->legacy_cursor_update) {
1865 complete_all(&commit->flip_done);
1866 continue;
1867 }
1868
1869 if (!new_crtc_state->event) {
1870 commit->event = kzalloc(sizeof(*commit->event),
1871 GFP_KERNEL);
1872 if (!commit->event)
1873 return -ENOMEM;
1874
1875 new_crtc_state->event = commit->event;
1876 }
1877
1878 new_crtc_state->event->base.completion = &commit->flip_done;
1879 new_crtc_state->event->base.completion_release = release_crtc_commit;
1880 drm_crtc_commit_get(commit);
1881
1882 commit->abort_completion = true;
1883 }
1884
1885 for_each_oldnew_connector_in_state(state, conn, old_conn_state, new_conn_state, i) {
1886
1887
1888 if (nonblock && old_conn_state->commit &&
1889 !try_wait_for_completion(&old_conn_state->commit->flip_done))
1890 return -EBUSY;
1891
1892
1893 commit = crtc_or_fake_commit(state, new_conn_state->crtc ?: old_conn_state->crtc);
1894 if (!commit)
1895 return -ENOMEM;
1896
1897 new_conn_state->commit = drm_crtc_commit_get(commit);
1898 }
1899
1900 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
1901
1902
1903 if (nonblock && old_plane_state->commit &&
1904 !try_wait_for_completion(&old_plane_state->commit->flip_done))
1905 return -EBUSY;
1906
1907
1908 commit = crtc_or_fake_commit(state, new_plane_state->crtc ?: old_plane_state->crtc);
1909 if (!commit)
1910 return -ENOMEM;
1911
1912 new_plane_state->commit = drm_crtc_commit_get(commit);
1913 }
1914
1915 return 0;
1916}
1917EXPORT_SYMBOL(drm_atomic_helper_setup_commit);
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931void drm_atomic_helper_wait_for_dependencies(struct drm_atomic_state *old_state)
1932{
1933 struct drm_crtc *crtc;
1934 struct drm_crtc_state *old_crtc_state;
1935 struct drm_plane *plane;
1936 struct drm_plane_state *old_plane_state;
1937 struct drm_connector *conn;
1938 struct drm_connector_state *old_conn_state;
1939 struct drm_crtc_commit *commit;
1940 int i;
1941 long ret;
1942
1943 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
1944 commit = old_crtc_state->commit;
1945
1946 if (!commit)
1947 continue;
1948
1949 ret = wait_for_completion_timeout(&commit->hw_done,
1950 10*HZ);
1951 if (ret == 0)
1952 DRM_ERROR("[CRTC:%d:%s] hw_done timed out\n",
1953 crtc->base.id, crtc->name);
1954
1955
1956
1957 ret = wait_for_completion_timeout(&commit->flip_done,
1958 10*HZ);
1959 if (ret == 0)
1960 DRM_ERROR("[CRTC:%d:%s] flip_done timed out\n",
1961 crtc->base.id, crtc->name);
1962 }
1963
1964 for_each_old_connector_in_state(old_state, conn, old_conn_state, i) {
1965 commit = old_conn_state->commit;
1966
1967 if (!commit)
1968 continue;
1969
1970 ret = wait_for_completion_timeout(&commit->hw_done,
1971 10*HZ);
1972 if (ret == 0)
1973 DRM_ERROR("[CONNECTOR:%d:%s] hw_done timed out\n",
1974 conn->base.id, conn->name);
1975
1976
1977
1978 ret = wait_for_completion_timeout(&commit->flip_done,
1979 10*HZ);
1980 if (ret == 0)
1981 DRM_ERROR("[CONNECTOR:%d:%s] flip_done timed out\n",
1982 conn->base.id, conn->name);
1983 }
1984
1985 for_each_old_plane_in_state(old_state, plane, old_plane_state, i) {
1986 commit = old_plane_state->commit;
1987
1988 if (!commit)
1989 continue;
1990
1991 ret = wait_for_completion_timeout(&commit->hw_done,
1992 10*HZ);
1993 if (ret == 0)
1994 DRM_ERROR("[PLANE:%d:%s] hw_done timed out\n",
1995 plane->base.id, plane->name);
1996
1997
1998
1999 ret = wait_for_completion_timeout(&commit->flip_done,
2000 10*HZ);
2001 if (ret == 0)
2002 DRM_ERROR("[PLANE:%d:%s] flip_done timed out\n",
2003 plane->base.id, plane->name);
2004 }
2005}
2006EXPORT_SYMBOL(drm_atomic_helper_wait_for_dependencies);
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023void drm_atomic_helper_commit_hw_done(struct drm_atomic_state *old_state)
2024{
2025 struct drm_crtc *crtc;
2026 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2027 struct drm_crtc_commit *commit;
2028 int i;
2029
2030 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2031 commit = new_crtc_state->commit;
2032 if (!commit)
2033 continue;
2034
2035
2036
2037
2038
2039
2040 if (old_crtc_state->commit)
2041 drm_crtc_commit_put(old_crtc_state->commit);
2042
2043 old_crtc_state->commit = drm_crtc_commit_get(commit);
2044
2045
2046 WARN_ON(new_crtc_state->event);
2047 complete_all(&commit->hw_done);
2048 }
2049
2050 if (old_state->fake_commit) {
2051 complete_all(&old_state->fake_commit->hw_done);
2052 complete_all(&old_state->fake_commit->flip_done);
2053 }
2054}
2055EXPORT_SYMBOL(drm_atomic_helper_commit_hw_done);
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068void drm_atomic_helper_commit_cleanup_done(struct drm_atomic_state *old_state)
2069{
2070 struct drm_crtc *crtc;
2071 struct drm_crtc_state *old_crtc_state;
2072 struct drm_crtc_commit *commit;
2073 int i;
2074
2075 for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i) {
2076 commit = old_crtc_state->commit;
2077 if (WARN_ON(!commit))
2078 continue;
2079
2080 complete_all(&commit->cleanup_done);
2081 WARN_ON(!try_wait_for_completion(&commit->hw_done));
2082
2083 spin_lock(&crtc->commit_lock);
2084 list_del(&commit->commit_entry);
2085 spin_unlock(&crtc->commit_lock);
2086 }
2087
2088 if (old_state->fake_commit)
2089 complete_all(&old_state->fake_commit->cleanup_done);
2090}
2091EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106int drm_atomic_helper_prepare_planes(struct drm_device *dev,
2107 struct drm_atomic_state *state)
2108{
2109 struct drm_plane *plane;
2110 struct drm_plane_state *new_plane_state;
2111 int ret, i, j;
2112
2113 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
2114 const struct drm_plane_helper_funcs *funcs;
2115
2116 funcs = plane->helper_private;
2117
2118 if (funcs->prepare_fb) {
2119 ret = funcs->prepare_fb(plane, new_plane_state);
2120 if (ret)
2121 goto fail;
2122 }
2123 }
2124
2125 return 0;
2126
2127fail:
2128 for_each_new_plane_in_state(state, plane, new_plane_state, j) {
2129 const struct drm_plane_helper_funcs *funcs;
2130
2131 if (j >= i)
2132 continue;
2133
2134 funcs = plane->helper_private;
2135
2136 if (funcs->cleanup_fb)
2137 funcs->cleanup_fb(plane, new_plane_state);
2138 }
2139
2140 return ret;
2141}
2142EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
2143
2144static bool plane_crtc_active(const struct drm_plane_state *state)
2145{
2146 return state->crtc && state->crtc->state->active;
2147}
2148
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
2190void drm_atomic_helper_commit_planes(struct drm_device *dev,
2191 struct drm_atomic_state *old_state,
2192 uint32_t flags)
2193{
2194 struct drm_crtc *crtc;
2195 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2196 struct drm_plane *plane;
2197 struct drm_plane_state *old_plane_state, *new_plane_state;
2198 int i;
2199 bool active_only = flags & DRM_PLANE_COMMIT_ACTIVE_ONLY;
2200 bool no_disable = flags & DRM_PLANE_COMMIT_NO_DISABLE_AFTER_MODESET;
2201
2202 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2203 const struct drm_crtc_helper_funcs *funcs;
2204
2205 funcs = crtc->helper_private;
2206
2207 if (!funcs || !funcs->atomic_begin)
2208 continue;
2209
2210 if (active_only && !new_crtc_state->active)
2211 continue;
2212
2213 funcs->atomic_begin(crtc, old_crtc_state);
2214 }
2215
2216 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
2217 const struct drm_plane_helper_funcs *funcs;
2218 bool disabling;
2219
2220 funcs = plane->helper_private;
2221
2222 if (!funcs)
2223 continue;
2224
2225 disabling = drm_atomic_plane_disabling(old_plane_state,
2226 new_plane_state);
2227
2228 if (active_only) {
2229
2230
2231
2232
2233
2234
2235
2236 if (!disabling && !plane_crtc_active(new_plane_state))
2237 continue;
2238 if (disabling && !plane_crtc_active(old_plane_state))
2239 continue;
2240 }
2241
2242
2243
2244
2245 if (disabling && funcs->atomic_disable) {
2246 struct drm_crtc_state *crtc_state;
2247
2248 crtc_state = old_plane_state->crtc->state;
2249
2250 if (drm_atomic_crtc_needs_modeset(crtc_state) &&
2251 no_disable)
2252 continue;
2253
2254 funcs->atomic_disable(plane, old_plane_state);
2255 } else if (new_plane_state->crtc || disabling) {
2256 funcs->atomic_update(plane, old_plane_state);
2257 }
2258 }
2259
2260 for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
2261 const struct drm_crtc_helper_funcs *funcs;
2262
2263 funcs = crtc->helper_private;
2264
2265 if (!funcs || !funcs->atomic_flush)
2266 continue;
2267
2268 if (active_only && !new_crtc_state->active)
2269 continue;
2270
2271 funcs->atomic_flush(crtc, old_crtc_state);
2272 }
2273}
2274EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293void
2294drm_atomic_helper_commit_planes_on_crtc(struct drm_crtc_state *old_crtc_state)
2295{
2296 const struct drm_crtc_helper_funcs *crtc_funcs;
2297 struct drm_crtc *crtc = old_crtc_state->crtc;
2298 struct drm_atomic_state *old_state = old_crtc_state->state;
2299 struct drm_plane *plane;
2300 unsigned plane_mask;
2301
2302 plane_mask = old_crtc_state->plane_mask;
2303 plane_mask |= crtc->state->plane_mask;
2304
2305 crtc_funcs = crtc->helper_private;
2306 if (crtc_funcs && crtc_funcs->atomic_begin)
2307 crtc_funcs->atomic_begin(crtc, old_crtc_state);
2308
2309 drm_for_each_plane_mask(plane, crtc->dev, plane_mask) {
2310 struct drm_plane_state *old_plane_state =
2311 drm_atomic_get_old_plane_state(old_state, plane);
2312 const struct drm_plane_helper_funcs *plane_funcs;
2313
2314 plane_funcs = plane->helper_private;
2315
2316 if (!old_plane_state || !plane_funcs)
2317 continue;
2318
2319 WARN_ON(plane->state->crtc && plane->state->crtc != crtc);
2320
2321 if (drm_atomic_plane_disabling(old_plane_state, plane->state) &&
2322 plane_funcs->atomic_disable)
2323 plane_funcs->atomic_disable(plane, old_plane_state);
2324 else if (plane->state->crtc ||
2325 drm_atomic_plane_disabling(old_plane_state, plane->state))
2326 plane_funcs->atomic_update(plane, old_plane_state);
2327 }
2328
2329 if (crtc_funcs && crtc_funcs->atomic_flush)
2330 crtc_funcs->atomic_flush(crtc, old_crtc_state);
2331}
2332EXPORT_SYMBOL(drm_atomic_helper_commit_planes_on_crtc);
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350void
2351drm_atomic_helper_disable_planes_on_crtc(struct drm_crtc_state *old_crtc_state,
2352 bool atomic)
2353{
2354 struct drm_crtc *crtc = old_crtc_state->crtc;
2355 const struct drm_crtc_helper_funcs *crtc_funcs =
2356 crtc->helper_private;
2357 struct drm_plane *plane;
2358
2359 if (atomic && crtc_funcs && crtc_funcs->atomic_begin)
2360 crtc_funcs->atomic_begin(crtc, NULL);
2361
2362 drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) {
2363 const struct drm_plane_helper_funcs *plane_funcs =
2364 plane->helper_private;
2365
2366 if (!plane_funcs)
2367 continue;
2368
2369 WARN_ON(!plane_funcs->atomic_disable);
2370 if (plane_funcs->atomic_disable)
2371 plane_funcs->atomic_disable(plane, NULL);
2372 }
2373
2374 if (atomic && crtc_funcs && crtc_funcs->atomic_flush)
2375 crtc_funcs->atomic_flush(crtc, NULL);
2376}
2377EXPORT_SYMBOL(drm_atomic_helper_disable_planes_on_crtc);
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
2392 struct drm_atomic_state *old_state)
2393{
2394 struct drm_plane *plane;
2395 struct drm_plane_state *old_plane_state, *new_plane_state;
2396 int i;
2397
2398 for_each_oldnew_plane_in_state(old_state, plane, old_plane_state, new_plane_state, i) {
2399 const struct drm_plane_helper_funcs *funcs;
2400 struct drm_plane_state *plane_state;
2401
2402
2403
2404
2405
2406 if (old_plane_state == plane->state)
2407 plane_state = new_plane_state;
2408 else
2409 plane_state = old_plane_state;
2410
2411 funcs = plane->helper_private;
2412
2413 if (funcs->cleanup_fb)
2414 funcs->cleanup_fb(plane, plane_state);
2415 }
2416}
2417EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
2418
2419
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
2454int drm_atomic_helper_swap_state(struct drm_atomic_state *state,
2455 bool stall)
2456{
2457 int i, ret;
2458 struct drm_connector *connector;
2459 struct drm_connector_state *old_conn_state, *new_conn_state;
2460 struct drm_crtc *crtc;
2461 struct drm_crtc_state *old_crtc_state, *new_crtc_state;
2462 struct drm_plane *plane;
2463 struct drm_plane_state *old_plane_state, *new_plane_state;
2464 struct drm_crtc_commit *commit;
2465 struct drm_private_obj *obj;
2466 struct drm_private_state *old_obj_state, *new_obj_state;
2467
2468 if (stall) {
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478 for_each_old_crtc_in_state(state, crtc, old_crtc_state, i) {
2479 commit = old_crtc_state->commit;
2480
2481 if (!commit)
2482 continue;
2483
2484 ret = wait_for_completion_interruptible(&commit->hw_done);
2485 if (ret)
2486 return ret;
2487 }
2488
2489 for_each_old_connector_in_state(state, connector, old_conn_state, i) {
2490 commit = old_conn_state->commit;
2491
2492 if (!commit)
2493 continue;
2494
2495 ret = wait_for_completion_interruptible(&commit->hw_done);
2496 if (ret)
2497 return ret;
2498 }
2499
2500 for_each_old_plane_in_state(state, plane, old_plane_state, i) {
2501 commit = old_plane_state->commit;
2502
2503 if (!commit)
2504 continue;
2505
2506 ret = wait_for_completion_interruptible(&commit->hw_done);
2507 if (ret)
2508 return ret;
2509 }
2510 }
2511
2512 for_each_oldnew_connector_in_state(state, connector, old_conn_state, new_conn_state, i) {
2513 WARN_ON(connector->state != old_conn_state);
2514
2515 old_conn_state->state = state;
2516 new_conn_state->state = NULL;
2517
2518 state->connectors[i].state = old_conn_state;
2519 connector->state = new_conn_state;
2520 }
2521
2522 for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
2523 WARN_ON(crtc->state != old_crtc_state);
2524
2525 old_crtc_state->state = state;
2526 new_crtc_state->state = NULL;
2527
2528 state->crtcs[i].state = old_crtc_state;
2529 crtc->state = new_crtc_state;
2530
2531 if (new_crtc_state->commit) {
2532 spin_lock(&crtc->commit_lock);
2533 list_add(&new_crtc_state->commit->commit_entry,
2534 &crtc->commit_list);
2535 spin_unlock(&crtc->commit_lock);
2536
2537 new_crtc_state->commit->event = NULL;
2538 }
2539 }
2540
2541 for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
2542 WARN_ON(plane->state != old_plane_state);
2543
2544 old_plane_state->state = state;
2545 new_plane_state->state = NULL;
2546
2547 state->planes[i].state = old_plane_state;
2548 plane->state = new_plane_state;
2549 }
2550
2551 for_each_oldnew_private_obj_in_state(state, obj, old_obj_state, new_obj_state, i) {
2552 WARN_ON(obj->state != old_obj_state);
2553
2554 old_obj_state->state = state;
2555 new_obj_state->state = NULL;
2556
2557 state->private_objs[i].state = old_obj_state;
2558 obj->state = new_obj_state;
2559 }
2560
2561 return 0;
2562}
2563EXPORT_SYMBOL(drm_atomic_helper_swap_state);
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585int drm_atomic_helper_update_plane(struct drm_plane *plane,
2586 struct drm_crtc *crtc,
2587 struct drm_framebuffer *fb,
2588 int crtc_x, int crtc_y,
2589 unsigned int crtc_w, unsigned int crtc_h,
2590 uint32_t src_x, uint32_t src_y,
2591 uint32_t src_w, uint32_t src_h,
2592 struct drm_modeset_acquire_ctx *ctx)
2593{
2594 struct drm_atomic_state *state;
2595 struct drm_plane_state *plane_state;
2596 int ret = 0;
2597
2598 state = drm_atomic_state_alloc(plane->dev);
2599 if (!state)
2600 return -ENOMEM;
2601
2602 state->acquire_ctx = ctx;
2603 plane_state = drm_atomic_get_plane_state(state, plane);
2604 if (IS_ERR(plane_state)) {
2605 ret = PTR_ERR(plane_state);
2606 goto fail;
2607 }
2608
2609 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
2610 if (ret != 0)
2611 goto fail;
2612 drm_atomic_set_fb_for_plane(plane_state, fb);
2613 plane_state->crtc_x = crtc_x;
2614 plane_state->crtc_y = crtc_y;
2615 plane_state->crtc_w = crtc_w;
2616 plane_state->crtc_h = crtc_h;
2617 plane_state->src_x = src_x;
2618 plane_state->src_y = src_y;
2619 plane_state->src_w = src_w;
2620 plane_state->src_h = src_h;
2621
2622 if (plane == crtc->cursor)
2623 state->legacy_cursor_update = true;
2624
2625 ret = drm_atomic_commit(state);
2626fail:
2627 drm_atomic_state_put(state);
2628 return ret;
2629}
2630EXPORT_SYMBOL(drm_atomic_helper_update_plane);
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642int drm_atomic_helper_disable_plane(struct drm_plane *plane,
2643 struct drm_modeset_acquire_ctx *ctx)
2644{
2645 struct drm_atomic_state *state;
2646 struct drm_plane_state *plane_state;
2647 int ret = 0;
2648
2649 state = drm_atomic_state_alloc(plane->dev);
2650 if (!state)
2651 return -ENOMEM;
2652
2653 state->acquire_ctx = ctx;
2654 plane_state = drm_atomic_get_plane_state(state, plane);
2655 if (IS_ERR(plane_state)) {
2656 ret = PTR_ERR(plane_state);
2657 goto fail;
2658 }
2659
2660 if (plane_state->crtc && (plane == plane->crtc->cursor))
2661 plane_state->state->legacy_cursor_update = true;
2662
2663 ret = __drm_atomic_helper_disable_plane(plane, plane_state);
2664 if (ret != 0)
2665 goto fail;
2666
2667 ret = drm_atomic_commit(state);
2668fail:
2669 drm_atomic_state_put(state);
2670 return ret;
2671}
2672EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
2673
2674
2675int __drm_atomic_helper_disable_plane(struct drm_plane *plane,
2676 struct drm_plane_state *plane_state)
2677{
2678 int ret;
2679
2680 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
2681 if (ret != 0)
2682 return ret;
2683
2684 drm_atomic_set_fb_for_plane(plane_state, NULL);
2685 plane_state->crtc_x = 0;
2686 plane_state->crtc_y = 0;
2687 plane_state->crtc_w = 0;
2688 plane_state->crtc_h = 0;
2689 plane_state->src_x = 0;
2690 plane_state->src_y = 0;
2691 plane_state->src_w = 0;
2692 plane_state->src_h = 0;
2693
2694 return 0;
2695}
2696
2697static int update_output_state(struct drm_atomic_state *state,
2698 struct drm_mode_set *set)
2699{
2700 struct drm_device *dev = set->crtc->dev;
2701 struct drm_crtc *crtc;
2702 struct drm_crtc_state *new_crtc_state;
2703 struct drm_connector *connector;
2704 struct drm_connector_state *new_conn_state;
2705 int ret, i;
2706
2707 ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
2708 state->acquire_ctx);
2709 if (ret)
2710 return ret;
2711
2712
2713 ret = drm_atomic_add_affected_connectors(state, set->crtc);
2714 if (ret)
2715 return ret;
2716
2717 for_each_new_connector_in_state(state, connector, new_conn_state, i) {
2718 if (new_conn_state->crtc == set->crtc) {
2719 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
2720 NULL);
2721 if (ret)
2722 return ret;
2723
2724
2725 new_conn_state->link_status = DRM_LINK_STATUS_GOOD;
2726 }
2727 }
2728
2729
2730 for (i = 0; i < set->num_connectors; i++) {
2731 new_conn_state = drm_atomic_get_connector_state(state,
2732 set->connectors[i]);
2733 if (IS_ERR(new_conn_state))
2734 return PTR_ERR(new_conn_state);
2735
2736 ret = drm_atomic_set_crtc_for_connector(new_conn_state,
2737 set->crtc);
2738 if (ret)
2739 return ret;
2740 }
2741
2742 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
2743
2744
2745
2746
2747 if (crtc == set->crtc)
2748 continue;
2749
2750 if (!new_crtc_state->connector_mask) {
2751 ret = drm_atomic_set_mode_prop_for_crtc(new_crtc_state,
2752 NULL);
2753 if (ret < 0)
2754 return ret;
2755
2756 new_crtc_state->active = false;
2757 }
2758 }
2759
2760 return 0;
2761}
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779int drm_atomic_helper_set_config(struct drm_mode_set *set,
2780 struct drm_modeset_acquire_ctx *ctx)
2781{
2782 struct drm_atomic_state *state;
2783 struct drm_crtc *crtc = set->crtc;
2784 int ret = 0;
2785
2786 state = drm_atomic_state_alloc(crtc->dev);
2787 if (!state)
2788 return -ENOMEM;
2789
2790 state->acquire_ctx = ctx;
2791 ret = __drm_atomic_helper_set_config(set, state);
2792 if (ret != 0)
2793 goto fail;
2794
2795 ret = handle_conflicting_encoders(state, true);
2796 if (ret)
2797 return ret;
2798
2799 ret = drm_atomic_commit(state);
2800
2801fail:
2802 drm_atomic_state_put(state);
2803 return ret;
2804}
2805EXPORT_SYMBOL(drm_atomic_helper_set_config);
2806
2807
2808int __drm_atomic_helper_set_config(struct drm_mode_set *set,
2809 struct drm_atomic_state *state)
2810{
2811 struct drm_crtc_state *crtc_state;
2812 struct drm_plane_state *primary_state;
2813 struct drm_crtc *crtc = set->crtc;
2814 int hdisplay, vdisplay;
2815 int ret;
2816
2817 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2818 if (IS_ERR(crtc_state))
2819 return PTR_ERR(crtc_state);
2820
2821 primary_state = drm_atomic_get_plane_state(state, crtc->primary);
2822 if (IS_ERR(primary_state))
2823 return PTR_ERR(primary_state);
2824
2825 if (!set->mode) {
2826 WARN_ON(set->fb);
2827 WARN_ON(set->num_connectors);
2828
2829 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
2830 if (ret != 0)
2831 return ret;
2832
2833 crtc_state->active = false;
2834
2835 ret = drm_atomic_set_crtc_for_plane(primary_state, NULL);
2836 if (ret != 0)
2837 return ret;
2838
2839 drm_atomic_set_fb_for_plane(primary_state, NULL);
2840
2841 goto commit;
2842 }
2843
2844 WARN_ON(!set->fb);
2845 WARN_ON(!set->num_connectors);
2846
2847 ret = drm_atomic_set_mode_for_crtc(crtc_state, set->mode);
2848 if (ret != 0)
2849 return ret;
2850
2851 crtc_state->active = true;
2852
2853 ret = drm_atomic_set_crtc_for_plane(primary_state, crtc);
2854 if (ret != 0)
2855 return ret;
2856
2857 drm_mode_get_hv_timing(set->mode, &hdisplay, &vdisplay);
2858
2859 drm_atomic_set_fb_for_plane(primary_state, set->fb);
2860 primary_state->crtc_x = 0;
2861 primary_state->crtc_y = 0;
2862 primary_state->crtc_w = hdisplay;
2863 primary_state->crtc_h = vdisplay;
2864 primary_state->src_x = set->x << 16;
2865 primary_state->src_y = set->y << 16;
2866 if (drm_rotation_90_or_270(primary_state->rotation)) {
2867 primary_state->src_w = vdisplay << 16;
2868 primary_state->src_h = hdisplay << 16;
2869 } else {
2870 primary_state->src_w = hdisplay << 16;
2871 primary_state->src_h = vdisplay << 16;
2872 }
2873
2874commit:
2875 ret = update_output_state(state, set);
2876 if (ret)
2877 return ret;
2878
2879 return 0;
2880}
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905int drm_atomic_helper_disable_all(struct drm_device *dev,
2906 struct drm_modeset_acquire_ctx *ctx)
2907{
2908 struct drm_atomic_state *state;
2909 struct drm_connector_state *conn_state;
2910 struct drm_connector *conn;
2911 struct drm_plane_state *plane_state;
2912 struct drm_plane *plane;
2913 struct drm_crtc_state *crtc_state;
2914 struct drm_crtc *crtc;
2915 unsigned plane_mask = 0;
2916 int ret, i;
2917
2918 state = drm_atomic_state_alloc(dev);
2919 if (!state)
2920 return -ENOMEM;
2921
2922 state->acquire_ctx = ctx;
2923
2924 drm_for_each_crtc(crtc, dev) {
2925 crtc_state = drm_atomic_get_crtc_state(state, crtc);
2926 if (IS_ERR(crtc_state)) {
2927 ret = PTR_ERR(crtc_state);
2928 goto free;
2929 }
2930
2931 crtc_state->active = false;
2932
2933 ret = drm_atomic_set_mode_prop_for_crtc(crtc_state, NULL);
2934 if (ret < 0)
2935 goto free;
2936
2937 ret = drm_atomic_add_affected_planes(state, crtc);
2938 if (ret < 0)
2939 goto free;
2940
2941 ret = drm_atomic_add_affected_connectors(state, crtc);
2942 if (ret < 0)
2943 goto free;
2944 }
2945
2946 for_each_new_connector_in_state(state, conn, conn_state, i) {
2947 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
2948 if (ret < 0)
2949 goto free;
2950 }
2951
2952 for_each_new_plane_in_state(state, plane, plane_state, i) {
2953 ret = drm_atomic_set_crtc_for_plane(plane_state, NULL);
2954 if (ret < 0)
2955 goto free;
2956
2957 drm_atomic_set_fb_for_plane(plane_state, NULL);
2958 plane_mask |= BIT(drm_plane_index(plane));
2959 plane->old_fb = plane->fb;
2960 }
2961
2962 ret = drm_atomic_commit(state);
2963free:
2964 if (plane_mask)
2965 drm_atomic_clean_old_fb(dev, plane_mask, ret);
2966 drm_atomic_state_put(state);
2967 return ret;
2968}
2969
2970EXPORT_SYMBOL(drm_atomic_helper_disable_all);
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983void drm_atomic_helper_shutdown(struct drm_device *dev)
2984{
2985 struct drm_modeset_acquire_ctx ctx;
2986 int ret;
2987
2988 drm_modeset_acquire_init(&ctx, 0);
2989 while (1) {
2990 ret = drm_modeset_lock_all_ctx(dev, &ctx);
2991 if (!ret)
2992 ret = drm_atomic_helper_disable_all(dev, &ctx);
2993
2994 if (ret != -EDEADLK)
2995 break;
2996
2997 drm_modeset_backoff(&ctx);
2998 }
2999
3000 if (ret)
3001 DRM_ERROR("Disabling all crtc's during unload failed with %i\n", ret);
3002
3003 drm_modeset_drop_locks(&ctx);
3004 drm_modeset_acquire_fini(&ctx);
3005}
3006EXPORT_SYMBOL(drm_atomic_helper_shutdown);
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033struct drm_atomic_state *drm_atomic_helper_suspend(struct drm_device *dev)
3034{
3035 struct drm_modeset_acquire_ctx ctx;
3036 struct drm_atomic_state *state;
3037 int err;
3038
3039 drm_modeset_acquire_init(&ctx, 0);
3040
3041retry:
3042 err = drm_modeset_lock_all_ctx(dev, &ctx);
3043 if (err < 0) {
3044 state = ERR_PTR(err);
3045 goto unlock;
3046 }
3047
3048 state = drm_atomic_helper_duplicate_state(dev, &ctx);
3049 if (IS_ERR(state))
3050 goto unlock;
3051
3052 err = drm_atomic_helper_disable_all(dev, &ctx);
3053 if (err < 0) {
3054 drm_atomic_state_put(state);
3055 state = ERR_PTR(err);
3056 goto unlock;
3057 }
3058
3059unlock:
3060 if (PTR_ERR(state) == -EDEADLK) {
3061 drm_modeset_backoff(&ctx);
3062 goto retry;
3063 }
3064
3065 drm_modeset_drop_locks(&ctx);
3066 drm_modeset_acquire_fini(&ctx);
3067 return state;
3068}
3069EXPORT_SYMBOL(drm_atomic_helper_suspend);
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086int drm_atomic_helper_commit_duplicated_state(struct drm_atomic_state *state,
3087 struct drm_modeset_acquire_ctx *ctx)
3088{
3089 int i;
3090 struct drm_plane *plane;
3091 struct drm_plane_state *new_plane_state;
3092 struct drm_connector *connector;
3093 struct drm_connector_state *new_conn_state;
3094 struct drm_crtc *crtc;
3095 struct drm_crtc_state *new_crtc_state;
3096 unsigned plane_mask = 0;
3097 struct drm_device *dev = state->dev;
3098 int ret;
3099
3100 state->acquire_ctx = ctx;
3101
3102 for_each_new_plane_in_state(state, plane, new_plane_state, i) {
3103 plane_mask |= BIT(drm_plane_index(plane));
3104 state->planes[i].old_state = plane->state;
3105 }
3106
3107 for_each_new_crtc_in_state(state, crtc, new_crtc_state, i)
3108 state->crtcs[i].old_state = crtc->state;
3109
3110 for_each_new_connector_in_state(state, connector, new_conn_state, i)
3111 state->connectors[i].old_state = connector->state;
3112
3113 ret = drm_atomic_commit(state);
3114 if (plane_mask)
3115 drm_atomic_clean_old_fb(dev, plane_mask, ret);
3116
3117 return ret;
3118}
3119EXPORT_SYMBOL(drm_atomic_helper_commit_duplicated_state);
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137int drm_atomic_helper_resume(struct drm_device *dev,
3138 struct drm_atomic_state *state)
3139{
3140 struct drm_modeset_acquire_ctx ctx;
3141 int err;
3142
3143 drm_mode_config_reset(dev);
3144
3145 drm_modeset_acquire_init(&ctx, 0);
3146 while (1) {
3147 err = drm_modeset_lock_all_ctx(dev, &ctx);
3148 if (err)
3149 goto out;
3150
3151 err = drm_atomic_helper_commit_duplicated_state(state, &ctx);
3152out:
3153 if (err != -EDEADLK)
3154 break;
3155
3156 drm_modeset_backoff(&ctx);
3157 }
3158
3159 drm_atomic_state_put(state);
3160 drm_modeset_drop_locks(&ctx);
3161 drm_modeset_acquire_fini(&ctx);
3162
3163 return err;
3164}
3165EXPORT_SYMBOL(drm_atomic_helper_resume);
3166
3167static int page_flip_common(struct drm_atomic_state *state,
3168 struct drm_crtc *crtc,
3169 struct drm_framebuffer *fb,
3170 struct drm_pending_vblank_event *event,
3171 uint32_t flags)
3172{
3173 struct drm_plane *plane = crtc->primary;
3174 struct drm_plane_state *plane_state;
3175 struct drm_crtc_state *crtc_state;
3176 int ret = 0;
3177
3178 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3179 if (IS_ERR(crtc_state))
3180 return PTR_ERR(crtc_state);
3181
3182 crtc_state->event = event;
3183 crtc_state->pageflip_flags = flags;
3184
3185 plane_state = drm_atomic_get_plane_state(state, plane);
3186 if (IS_ERR(plane_state))
3187 return PTR_ERR(plane_state);
3188
3189 ret = drm_atomic_set_crtc_for_plane(plane_state, crtc);
3190 if (ret != 0)
3191 return ret;
3192 drm_atomic_set_fb_for_plane(plane_state, fb);
3193
3194
3195 state->allow_modeset = false;
3196 if (!crtc_state->active) {
3197 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] disabled, rejecting legacy flip\n",
3198 crtc->base.id, crtc->name);
3199 return -EINVAL;
3200 }
3201
3202 return ret;
3203}
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
3223 struct drm_framebuffer *fb,
3224 struct drm_pending_vblank_event *event,
3225 uint32_t flags,
3226 struct drm_modeset_acquire_ctx *ctx)
3227{
3228 struct drm_plane *plane = crtc->primary;
3229 struct drm_atomic_state *state;
3230 int ret = 0;
3231
3232 state = drm_atomic_state_alloc(plane->dev);
3233 if (!state)
3234 return -ENOMEM;
3235
3236 state->acquire_ctx = ctx;
3237
3238 ret = page_flip_common(state, crtc, fb, event, flags);
3239 if (ret != 0)
3240 goto fail;
3241
3242 ret = drm_atomic_nonblocking_commit(state);
3243fail:
3244 drm_atomic_state_put(state);
3245 return ret;
3246}
3247EXPORT_SYMBOL(drm_atomic_helper_page_flip);
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265int drm_atomic_helper_page_flip_target(struct drm_crtc *crtc,
3266 struct drm_framebuffer *fb,
3267 struct drm_pending_vblank_event *event,
3268 uint32_t flags,
3269 uint32_t target,
3270 struct drm_modeset_acquire_ctx *ctx)
3271{
3272 struct drm_plane *plane = crtc->primary;
3273 struct drm_atomic_state *state;
3274 struct drm_crtc_state *crtc_state;
3275 int ret = 0;
3276
3277 state = drm_atomic_state_alloc(plane->dev);
3278 if (!state)
3279 return -ENOMEM;
3280
3281 state->acquire_ctx = ctx;
3282
3283 ret = page_flip_common(state, crtc, fb, event, flags);
3284 if (ret != 0)
3285 goto fail;
3286
3287 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
3288 if (WARN_ON(!crtc_state)) {
3289 ret = -EINVAL;
3290 goto fail;
3291 }
3292 crtc_state->target_vblank = target;
3293
3294 ret = drm_atomic_nonblocking_commit(state);
3295fail:
3296 drm_atomic_state_put(state);
3297 return ret;
3298}
3299EXPORT_SYMBOL(drm_atomic_helper_page_flip_target);
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310struct drm_encoder *
3311drm_atomic_helper_best_encoder(struct drm_connector *connector)
3312{
3313 WARN_ON(connector->encoder_ids[1]);
3314 return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
3315}
3316EXPORT_SYMBOL(drm_atomic_helper_best_encoder);
3317
3318
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
3346void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
3347{
3348 if (crtc->state)
3349 __drm_atomic_helper_crtc_destroy_state(crtc->state);
3350
3351 kfree(crtc->state);
3352 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
3353
3354 if (crtc->state)
3355 crtc->state->crtc = crtc;
3356}
3357EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
3368 struct drm_crtc_state *state)
3369{
3370 memcpy(state, crtc->state, sizeof(*state));
3371
3372 if (state->mode_blob)
3373 drm_property_blob_get(state->mode_blob);
3374 if (state->degamma_lut)
3375 drm_property_blob_get(state->degamma_lut);
3376 if (state->ctm)
3377 drm_property_blob_get(state->ctm);
3378 if (state->gamma_lut)
3379 drm_property_blob_get(state->gamma_lut);
3380 state->mode_changed = false;
3381 state->active_changed = false;
3382 state->planes_changed = false;
3383 state->connectors_changed = false;
3384 state->color_mgmt_changed = false;
3385 state->zpos_changed = false;
3386 state->commit = NULL;
3387 state->event = NULL;
3388 state->pageflip_flags = 0;
3389}
3390EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
3391
3392
3393
3394
3395
3396
3397
3398
3399struct drm_crtc_state *
3400drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
3401{
3402 struct drm_crtc_state *state;
3403
3404 if (WARN_ON(!crtc->state))
3405 return NULL;
3406
3407 state = kmalloc(sizeof(*state), GFP_KERNEL);
3408 if (state)
3409 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
3410
3411 return state;
3412}
3413EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc_state *state)
3424{
3425 if (state->commit) {
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435 if (state->event && state->commit->abort_completion)
3436 drm_crtc_commit_put(state->commit);
3437
3438 kfree(state->commit->event);
3439 state->commit->event = NULL;
3440
3441 drm_crtc_commit_put(state->commit);
3442 }
3443
3444 drm_property_blob_put(state->mode_blob);
3445 drm_property_blob_put(state->degamma_lut);
3446 drm_property_blob_put(state->ctm);
3447 drm_property_blob_put(state->gamma_lut);
3448}
3449EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
3460 struct drm_crtc_state *state)
3461{
3462 __drm_atomic_helper_crtc_destroy_state(state);
3463 kfree(state);
3464}
3465EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
3466
3467
3468
3469
3470
3471
3472
3473
3474void drm_atomic_helper_plane_reset(struct drm_plane *plane)
3475{
3476 if (plane->state)
3477 __drm_atomic_helper_plane_destroy_state(plane->state);
3478
3479 kfree(plane->state);
3480 plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
3481
3482 if (plane->state) {
3483 plane->state->plane = plane;
3484 plane->state->rotation = DRM_MODE_ROTATE_0;
3485 }
3486}
3487EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
3498 struct drm_plane_state *state)
3499{
3500 memcpy(state, plane->state, sizeof(*state));
3501
3502 if (state->fb)
3503 drm_framebuffer_get(state->fb);
3504
3505 state->fence = NULL;
3506 state->commit = NULL;
3507}
3508EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
3509
3510
3511
3512
3513
3514
3515
3516
3517struct drm_plane_state *
3518drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
3519{
3520 struct drm_plane_state *state;
3521
3522 if (WARN_ON(!plane->state))
3523 return NULL;
3524
3525 state = kmalloc(sizeof(*state), GFP_KERNEL);
3526 if (state)
3527 __drm_atomic_helper_plane_duplicate_state(plane, state);
3528
3529 return state;
3530}
3531EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541void __drm_atomic_helper_plane_destroy_state(struct drm_plane_state *state)
3542{
3543 if (state->fb)
3544 drm_framebuffer_put(state->fb);
3545
3546 if (state->fence)
3547 dma_fence_put(state->fence);
3548
3549 if (state->commit)
3550 drm_crtc_commit_put(state->commit);
3551}
3552EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
3563 struct drm_plane_state *state)
3564{
3565 __drm_atomic_helper_plane_destroy_state(state);
3566 kfree(state);
3567}
3568EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582void
3583__drm_atomic_helper_connector_reset(struct drm_connector *connector,
3584 struct drm_connector_state *conn_state)
3585{
3586 if (conn_state)
3587 conn_state->connector = connector;
3588
3589 connector->state = conn_state;
3590}
3591EXPORT_SYMBOL(__drm_atomic_helper_connector_reset);
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601void drm_atomic_helper_connector_reset(struct drm_connector *connector)
3602{
3603 struct drm_connector_state *conn_state =
3604 kzalloc(sizeof(*conn_state), GFP_KERNEL);
3605
3606 if (connector->state)
3607 __drm_atomic_helper_connector_destroy_state(connector->state);
3608
3609 kfree(connector->state);
3610 __drm_atomic_helper_connector_reset(connector, conn_state);
3611}
3612EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622void
3623__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
3624 struct drm_connector_state *state)
3625{
3626 memcpy(state, connector->state, sizeof(*state));
3627 if (state->crtc)
3628 drm_connector_get(connector);
3629 state->commit = NULL;
3630}
3631EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
3632
3633
3634
3635
3636
3637
3638
3639
3640struct drm_connector_state *
3641drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
3642{
3643 struct drm_connector_state *state;
3644
3645 if (WARN_ON(!connector->state))
3646 return NULL;
3647
3648 state = kmalloc(sizeof(*state), GFP_KERNEL);
3649 if (state)
3650 __drm_atomic_helper_connector_duplicate_state(connector, state);
3651
3652 return state;
3653}
3654EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680struct drm_atomic_state *
3681drm_atomic_helper_duplicate_state(struct drm_device *dev,
3682 struct drm_modeset_acquire_ctx *ctx)
3683{
3684 struct drm_atomic_state *state;
3685 struct drm_connector *conn;
3686 struct drm_connector_list_iter conn_iter;
3687 struct drm_plane *plane;
3688 struct drm_crtc *crtc;
3689 int err = 0;
3690
3691 state = drm_atomic_state_alloc(dev);
3692 if (!state)
3693 return ERR_PTR(-ENOMEM);
3694
3695 state->acquire_ctx = ctx;
3696
3697 drm_for_each_crtc(crtc, dev) {
3698 struct drm_crtc_state *crtc_state;
3699
3700 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3701 if (IS_ERR(crtc_state)) {
3702 err = PTR_ERR(crtc_state);
3703 goto free;
3704 }
3705 }
3706
3707 drm_for_each_plane(plane, dev) {
3708 struct drm_plane_state *plane_state;
3709
3710 plane_state = drm_atomic_get_plane_state(state, plane);
3711 if (IS_ERR(plane_state)) {
3712 err = PTR_ERR(plane_state);
3713 goto free;
3714 }
3715 }
3716
3717 drm_connector_list_iter_begin(dev, &conn_iter);
3718 drm_for_each_connector_iter(conn, &conn_iter) {
3719 struct drm_connector_state *conn_state;
3720
3721 conn_state = drm_atomic_get_connector_state(state, conn);
3722 if (IS_ERR(conn_state)) {
3723 err = PTR_ERR(conn_state);
3724 drm_connector_list_iter_end(&conn_iter);
3725 goto free;
3726 }
3727 }
3728 drm_connector_list_iter_end(&conn_iter);
3729
3730
3731 state->acquire_ctx = NULL;
3732
3733free:
3734 if (err < 0) {
3735 drm_atomic_state_put(state);
3736 state = ERR_PTR(err);
3737 }
3738
3739 return state;
3740}
3741EXPORT_SYMBOL(drm_atomic_helper_duplicate_state);
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751void
3752__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)
3753{
3754 if (state->crtc)
3755 drm_connector_put(state->connector);
3756
3757 if (state->commit)
3758 drm_crtc_commit_put(state->commit);
3759}
3760EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
3771 struct drm_connector_state *state)
3772{
3773 __drm_atomic_helper_connector_destroy_state(state);
3774 kfree(state);
3775}
3776EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
3793 u16 *red, u16 *green, u16 *blue,
3794 uint32_t size,
3795 struct drm_modeset_acquire_ctx *ctx)
3796{
3797 struct drm_device *dev = crtc->dev;
3798 struct drm_atomic_state *state;
3799 struct drm_crtc_state *crtc_state;
3800 struct drm_property_blob *blob = NULL;
3801 struct drm_color_lut *blob_data;
3802 int i, ret = 0;
3803 bool replaced;
3804
3805 state = drm_atomic_state_alloc(crtc->dev);
3806 if (!state)
3807 return -ENOMEM;
3808
3809 blob = drm_property_create_blob(dev,
3810 sizeof(struct drm_color_lut) * size,
3811 NULL);
3812 if (IS_ERR(blob)) {
3813 ret = PTR_ERR(blob);
3814 blob = NULL;
3815 goto fail;
3816 }
3817
3818
3819 blob_data = (struct drm_color_lut *) blob->data;
3820 for (i = 0; i < size; i++) {
3821 blob_data[i].red = red[i];
3822 blob_data[i].green = green[i];
3823 blob_data[i].blue = blue[i];
3824 }
3825
3826 state->acquire_ctx = ctx;
3827 crtc_state = drm_atomic_get_crtc_state(state, crtc);
3828 if (IS_ERR(crtc_state)) {
3829 ret = PTR_ERR(crtc_state);
3830 goto fail;
3831 }
3832
3833
3834 replaced = drm_property_replace_blob(&crtc_state->degamma_lut, NULL);
3835 replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
3836 replaced |= drm_property_replace_blob(&crtc_state->gamma_lut, blob);
3837 crtc_state->color_mgmt_changed |= replaced;
3838
3839 ret = drm_atomic_commit(state);
3840
3841fail:
3842 drm_atomic_state_put(state);
3843 drm_property_blob_put(blob);
3844 return ret;
3845}
3846EXPORT_SYMBOL(drm_atomic_helper_legacy_gamma_set);
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856void __drm_atomic_helper_private_obj_duplicate_state(struct drm_private_obj *obj,
3857 struct drm_private_state *state)
3858{
3859 memcpy(state, obj->state, sizeof(*state));
3860}
3861EXPORT_SYMBOL(__drm_atomic_helper_private_obj_duplicate_state);
3862