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
29
30
31
32#include <linux/kernel.h>
33#include <linux/export.h>
34#include <linux/moduleparam.h>
35
36#include <drm/drmP.h>
37#include <drm/drm_atomic.h>
38#include <drm/drm_crtc.h>
39#include <drm/drm_encoder.h>
40#include <drm/drm_fourcc.h>
41#include <drm/drm_crtc_helper.h>
42#include <drm/drm_fb_helper.h>
43#include <drm/drm_plane_helper.h>
44#include <drm/drm_atomic_helper.h>
45#include <drm/drm_edid.h>
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
90{
91 struct drm_connector *connector;
92 struct drm_connector_list_iter conn_iter;
93 struct drm_device *dev = encoder->dev;
94
95
96
97
98
99 if (!oops_in_progress) {
100 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
101 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
102 }
103
104
105 drm_connector_list_iter_begin(dev, &conn_iter);
106 drm_for_each_connector_iter(connector, &conn_iter) {
107 if (connector->encoder == encoder) {
108 drm_connector_list_iter_end(&conn_iter);
109 return true;
110 }
111 }
112 drm_connector_list_iter_end(&conn_iter);
113 return false;
114}
115EXPORT_SYMBOL(drm_helper_encoder_in_use);
116
117
118
119
120
121
122
123
124
125
126
127
128bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
129{
130 struct drm_encoder *encoder;
131 struct drm_device *dev = crtc->dev;
132
133
134
135
136
137 if (!oops_in_progress)
138 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
139
140 drm_for_each_encoder(encoder, dev)
141 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
142 return true;
143 return false;
144}
145EXPORT_SYMBOL(drm_helper_crtc_in_use);
146
147static void
148drm_encoder_disable(struct drm_encoder *encoder)
149{
150 const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
151
152 if (!encoder_funcs)
153 return;
154
155 drm_bridge_disable(encoder->bridge);
156
157 if (encoder_funcs->disable)
158 (*encoder_funcs->disable)(encoder);
159 else if (encoder_funcs->dpms)
160 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
161
162 drm_bridge_post_disable(encoder->bridge);
163}
164
165static void __drm_helper_disable_unused_functions(struct drm_device *dev)
166{
167 struct drm_encoder *encoder;
168 struct drm_crtc *crtc;
169
170 drm_warn_on_modeset_not_all_locked(dev);
171
172 drm_for_each_encoder(encoder, dev) {
173 if (!drm_helper_encoder_in_use(encoder)) {
174 drm_encoder_disable(encoder);
175
176 encoder->crtc = NULL;
177 }
178 }
179
180 drm_for_each_crtc(crtc, dev) {
181 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
182 crtc->enabled = drm_helper_crtc_in_use(crtc);
183 if (!crtc->enabled) {
184 if (crtc_funcs->disable)
185 (*crtc_funcs->disable)(crtc);
186 else
187 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
188 crtc->primary->fb = NULL;
189 }
190 }
191}
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212void drm_helper_disable_unused_functions(struct drm_device *dev)
213{
214 if (drm_core_check_feature(dev, DRIVER_ATOMIC))
215 DRM_ERROR("Called for atomic driver, this is not what you want.\n");
216
217 drm_modeset_lock_all(dev);
218 __drm_helper_disable_unused_functions(dev);
219 drm_modeset_unlock_all(dev);
220}
221EXPORT_SYMBOL(drm_helper_disable_unused_functions);
222
223
224
225
226
227
228static void
229drm_crtc_prepare_encoders(struct drm_device *dev)
230{
231 const struct drm_encoder_helper_funcs *encoder_funcs;
232 struct drm_encoder *encoder;
233
234 drm_for_each_encoder(encoder, dev) {
235 encoder_funcs = encoder->helper_private;
236 if (!encoder_funcs)
237 continue;
238
239
240 if (encoder->crtc == NULL)
241 drm_encoder_disable(encoder);
242
243 if (encoder_funcs->get_crtc &&
244 encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
245 drm_encoder_disable(encoder);
246 }
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
270 struct drm_display_mode *mode,
271 int x, int y,
272 struct drm_framebuffer *old_fb)
273{
274 struct drm_device *dev = crtc->dev;
275 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
276 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
277 const struct drm_encoder_helper_funcs *encoder_funcs;
278 int saved_x, saved_y;
279 bool saved_enabled;
280 struct drm_encoder *encoder;
281 bool ret = true;
282
283 drm_warn_on_modeset_not_all_locked(dev);
284
285 saved_enabled = crtc->enabled;
286 crtc->enabled = drm_helper_crtc_in_use(crtc);
287 if (!crtc->enabled)
288 return true;
289
290 adjusted_mode = drm_mode_duplicate(dev, mode);
291 if (!adjusted_mode) {
292 crtc->enabled = saved_enabled;
293 return false;
294 }
295
296 saved_mode = crtc->mode;
297 saved_hwmode = crtc->hwmode;
298 saved_x = crtc->x;
299 saved_y = crtc->y;
300
301
302
303
304 crtc->mode = *mode;
305 crtc->x = x;
306 crtc->y = y;
307
308
309
310
311
312 drm_for_each_encoder(encoder, dev) {
313
314 if (encoder->crtc != crtc)
315 continue;
316
317 encoder_funcs = encoder->helper_private;
318 if (!encoder_funcs)
319 continue;
320
321 ret = drm_bridge_mode_fixup(encoder->bridge,
322 mode, adjusted_mode);
323 if (!ret) {
324 DRM_DEBUG_KMS("Bridge fixup failed\n");
325 goto done;
326 }
327
328 encoder_funcs = encoder->helper_private;
329 if (encoder_funcs->mode_fixup) {
330 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
331 adjusted_mode))) {
332 DRM_DEBUG_KMS("Encoder fixup failed\n");
333 goto done;
334 }
335 }
336 }
337
338 if (crtc_funcs->mode_fixup) {
339 if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
340 adjusted_mode))) {
341 DRM_DEBUG_KMS("CRTC fixup failed\n");
342 goto done;
343 }
344 }
345 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
346
347 crtc->hwmode = *adjusted_mode;
348
349
350 drm_for_each_encoder(encoder, dev) {
351
352 if (encoder->crtc != crtc)
353 continue;
354
355 encoder_funcs = encoder->helper_private;
356 if (!encoder_funcs)
357 continue;
358
359 drm_bridge_disable(encoder->bridge);
360
361
362 if (encoder_funcs->prepare)
363 encoder_funcs->prepare(encoder);
364
365 drm_bridge_post_disable(encoder->bridge);
366 }
367
368 drm_crtc_prepare_encoders(dev);
369
370 crtc_funcs->prepare(crtc);
371
372
373
374
375 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
376 if (!ret)
377 goto done;
378
379 drm_for_each_encoder(encoder, dev) {
380
381 if (encoder->crtc != crtc)
382 continue;
383
384 encoder_funcs = encoder->helper_private;
385 if (!encoder_funcs)
386 continue;
387
388 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
389 encoder->base.id, encoder->name,
390 mode->base.id, mode->name);
391 if (encoder_funcs->mode_set)
392 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
393
394 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
395 }
396
397
398 crtc_funcs->commit(crtc);
399
400 drm_for_each_encoder(encoder, dev) {
401
402 if (encoder->crtc != crtc)
403 continue;
404
405 encoder_funcs = encoder->helper_private;
406 if (!encoder_funcs)
407 continue;
408
409 drm_bridge_pre_enable(encoder->bridge);
410
411 if (encoder_funcs->commit)
412 encoder_funcs->commit(encoder);
413
414 drm_bridge_enable(encoder->bridge);
415 }
416
417
418
419
420
421 drm_calc_timestamping_constants(crtc, &crtc->hwmode);
422
423
424done:
425 drm_mode_destroy(dev, adjusted_mode);
426 if (!ret) {
427 crtc->enabled = saved_enabled;
428 crtc->mode = saved_mode;
429 crtc->hwmode = saved_hwmode;
430 crtc->x = saved_x;
431 crtc->y = saved_y;
432 }
433
434 return ret;
435}
436EXPORT_SYMBOL(drm_crtc_helper_set_mode);
437
438static void
439drm_crtc_helper_disable(struct drm_crtc *crtc)
440{
441 struct drm_device *dev = crtc->dev;
442 struct drm_connector *connector;
443 struct drm_encoder *encoder;
444
445
446 drm_for_each_encoder(encoder, dev) {
447 struct drm_connector_list_iter conn_iter;
448
449 if (encoder->crtc != crtc)
450 continue;
451
452 drm_connector_list_iter_begin(dev, &conn_iter);
453 drm_for_each_connector_iter(connector, &conn_iter) {
454 if (connector->encoder != encoder)
455 continue;
456
457 connector->encoder = NULL;
458
459
460
461
462
463
464
465 connector->dpms = DRM_MODE_DPMS_OFF;
466
467
468 drm_connector_put(connector);
469 }
470 drm_connector_list_iter_end(&conn_iter);
471 }
472
473 __drm_helper_disable_unused_functions(dev);
474}
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514int drm_crtc_helper_set_config(struct drm_mode_set *set,
515 struct drm_modeset_acquire_ctx *ctx)
516{
517 struct drm_device *dev;
518 struct drm_crtc **save_encoder_crtcs, *new_crtc;
519 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
520 bool mode_changed = false;
521 bool fb_changed = false;
522 struct drm_connector *connector;
523 struct drm_connector_list_iter conn_iter;
524 int count = 0, ro, fail = 0;
525 const struct drm_crtc_helper_funcs *crtc_funcs;
526 struct drm_mode_set save_set;
527 int ret;
528 int i;
529
530 DRM_DEBUG_KMS("\n");
531
532 BUG_ON(!set);
533 BUG_ON(!set->crtc);
534 BUG_ON(!set->crtc->helper_private);
535
536
537 BUG_ON(!set->mode && set->fb);
538 BUG_ON(set->fb && set->num_connectors == 0);
539
540 crtc_funcs = set->crtc->helper_private;
541
542 if (!set->mode)
543 set->fb = NULL;
544
545 if (set->fb) {
546 DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
547 set->crtc->base.id, set->crtc->name,
548 set->fb->base.id,
549 (int)set->num_connectors, set->x, set->y);
550 } else {
551 DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
552 set->crtc->base.id, set->crtc->name);
553 drm_crtc_helper_disable(set->crtc);
554 return 0;
555 }
556
557 dev = set->crtc->dev;
558
559 drm_warn_on_modeset_not_all_locked(dev);
560
561
562
563
564
565 save_encoder_crtcs = kzalloc(dev->mode_config.num_encoder *
566 sizeof(struct drm_crtc *), GFP_KERNEL);
567 if (!save_encoder_crtcs)
568 return -ENOMEM;
569
570 save_connector_encoders = kzalloc(dev->mode_config.num_connector *
571 sizeof(struct drm_encoder *), GFP_KERNEL);
572 if (!save_connector_encoders) {
573 kfree(save_encoder_crtcs);
574 return -ENOMEM;
575 }
576
577
578
579
580
581
582 count = 0;
583 drm_for_each_encoder(encoder, dev) {
584 save_encoder_crtcs[count++] = encoder->crtc;
585 }
586
587 count = 0;
588 drm_connector_list_iter_begin(dev, &conn_iter);
589 drm_for_each_connector_iter(connector, &conn_iter)
590 save_connector_encoders[count++] = connector->encoder;
591 drm_connector_list_iter_end(&conn_iter);
592
593 save_set.crtc = set->crtc;
594 save_set.mode = &set->crtc->mode;
595 save_set.x = set->crtc->x;
596 save_set.y = set->crtc->y;
597 save_set.fb = set->crtc->primary->fb;
598
599
600
601 if (set->crtc->primary->fb != set->fb) {
602
603 if (set->crtc->primary->fb == NULL) {
604 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
605 mode_changed = true;
606 } else if (set->fb->format != set->crtc->primary->fb->format) {
607 mode_changed = true;
608 } else
609 fb_changed = true;
610 }
611
612 if (set->x != set->crtc->x || set->y != set->crtc->y)
613 fb_changed = true;
614
615 if (!drm_mode_equal(set->mode, &set->crtc->mode)) {
616 DRM_DEBUG_KMS("modes are different, full mode set\n");
617 drm_mode_debug_printmodeline(&set->crtc->mode);
618 drm_mode_debug_printmodeline(set->mode);
619 mode_changed = true;
620 }
621
622
623
624
625 for (ro = 0; ro < set->num_connectors; ro++) {
626 if (set->connectors[ro]->encoder)
627 continue;
628 drm_connector_get(set->connectors[ro]);
629 }
630
631
632 count = 0;
633 drm_connector_list_iter_begin(dev, &conn_iter);
634 drm_for_each_connector_iter(connector, &conn_iter) {
635 const struct drm_connector_helper_funcs *connector_funcs =
636 connector->helper_private;
637 new_encoder = connector->encoder;
638 for (ro = 0; ro < set->num_connectors; ro++) {
639 if (set->connectors[ro] == connector) {
640 new_encoder = connector_funcs->best_encoder(connector);
641
642
643 if (new_encoder == NULL)
644
645 fail = 1;
646
647 if (connector->dpms != DRM_MODE_DPMS_ON) {
648 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
649 mode_changed = true;
650 }
651
652 break;
653 }
654 }
655
656 if (new_encoder != connector->encoder) {
657 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
658 mode_changed = true;
659
660
661
662 if (connector->encoder)
663 connector->encoder->crtc = NULL;
664 connector->encoder = new_encoder;
665 }
666 }
667 drm_connector_list_iter_end(&conn_iter);
668
669 if (fail) {
670 ret = -EINVAL;
671 goto fail;
672 }
673
674 count = 0;
675 drm_connector_list_iter_begin(dev, &conn_iter);
676 drm_for_each_connector_iter(connector, &conn_iter) {
677 if (!connector->encoder)
678 continue;
679
680 if (connector->encoder->crtc == set->crtc)
681 new_crtc = NULL;
682 else
683 new_crtc = connector->encoder->crtc;
684
685 for (ro = 0; ro < set->num_connectors; ro++) {
686 if (set->connectors[ro] == connector)
687 new_crtc = set->crtc;
688 }
689
690
691 if (new_crtc &&
692 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
693 ret = -EINVAL;
694 drm_connector_list_iter_end(&conn_iter);
695 goto fail;
696 }
697 if (new_crtc != connector->encoder->crtc) {
698 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
699 mode_changed = true;
700 connector->encoder->crtc = new_crtc;
701 }
702 if (new_crtc) {
703 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
704 connector->base.id, connector->name,
705 new_crtc->base.id, new_crtc->name);
706 } else {
707 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
708 connector->base.id, connector->name);
709 }
710 }
711 drm_connector_list_iter_end(&conn_iter);
712
713
714 if (fb_changed && !crtc_funcs->mode_set_base)
715 mode_changed = true;
716
717 if (mode_changed) {
718 if (drm_helper_crtc_in_use(set->crtc)) {
719 DRM_DEBUG_KMS("attempting to set mode from"
720 " userspace\n");
721 drm_mode_debug_printmodeline(set->mode);
722 set->crtc->primary->fb = set->fb;
723 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
724 set->x, set->y,
725 save_set.fb)) {
726 DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
727 set->crtc->base.id, set->crtc->name);
728 set->crtc->primary->fb = save_set.fb;
729 ret = -EINVAL;
730 goto fail;
731 }
732 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
733 for (i = 0; i < set->num_connectors; i++) {
734 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
735 set->connectors[i]->name);
736 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
737 }
738 }
739 __drm_helper_disable_unused_functions(dev);
740 } else if (fb_changed) {
741 set->crtc->x = set->x;
742 set->crtc->y = set->y;
743 set->crtc->primary->fb = set->fb;
744 ret = crtc_funcs->mode_set_base(set->crtc,
745 set->x, set->y, save_set.fb);
746 if (ret != 0) {
747 set->crtc->x = save_set.x;
748 set->crtc->y = save_set.y;
749 set->crtc->primary->fb = save_set.fb;
750 goto fail;
751 }
752 }
753
754 kfree(save_connector_encoders);
755 kfree(save_encoder_crtcs);
756 return 0;
757
758fail:
759
760 count = 0;
761 drm_for_each_encoder(encoder, dev) {
762 encoder->crtc = save_encoder_crtcs[count++];
763 }
764
765 count = 0;
766 drm_connector_list_iter_begin(dev, &conn_iter);
767 drm_for_each_connector_iter(connector, &conn_iter)
768 connector->encoder = save_connector_encoders[count++];
769 drm_connector_list_iter_end(&conn_iter);
770
771
772
773
774 for (ro = 0; ro < set->num_connectors; ro++) {
775 if (set->connectors[ro]->encoder)
776 continue;
777 drm_connector_put(set->connectors[ro]);
778 }
779
780
781 if (mode_changed &&
782 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
783 save_set.y, save_set.fb))
784 DRM_ERROR("failed to restore config after modeset failure\n");
785
786 kfree(save_connector_encoders);
787 kfree(save_encoder_crtcs);
788 return ret;
789}
790EXPORT_SYMBOL(drm_crtc_helper_set_config);
791
792static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
793{
794 int dpms = DRM_MODE_DPMS_OFF;
795 struct drm_connector *connector;
796 struct drm_connector_list_iter conn_iter;
797 struct drm_device *dev = encoder->dev;
798
799 drm_connector_list_iter_begin(dev, &conn_iter);
800 drm_for_each_connector_iter(connector, &conn_iter)
801 if (connector->encoder == encoder)
802 if (connector->dpms < dpms)
803 dpms = connector->dpms;
804 drm_connector_list_iter_end(&conn_iter);
805
806 return dpms;
807}
808
809
810static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
811{
812 struct drm_bridge *bridge = encoder->bridge;
813 const struct drm_encoder_helper_funcs *encoder_funcs;
814
815 encoder_funcs = encoder->helper_private;
816 if (!encoder_funcs)
817 return;
818
819 if (mode == DRM_MODE_DPMS_ON)
820 drm_bridge_pre_enable(bridge);
821 else
822 drm_bridge_disable(bridge);
823
824 if (encoder_funcs->dpms)
825 encoder_funcs->dpms(encoder, mode);
826
827 if (mode == DRM_MODE_DPMS_ON)
828 drm_bridge_enable(bridge);
829 else
830 drm_bridge_post_disable(bridge);
831}
832
833static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
834{
835 int dpms = DRM_MODE_DPMS_OFF;
836 struct drm_connector *connector;
837 struct drm_connector_list_iter conn_iter;
838 struct drm_device *dev = crtc->dev;
839
840 drm_connector_list_iter_begin(dev, &conn_iter);
841 drm_for_each_connector_iter(connector, &conn_iter)
842 if (connector->encoder && connector->encoder->crtc == crtc)
843 if (connector->dpms < dpms)
844 dpms = connector->dpms;
845 drm_connector_list_iter_end(&conn_iter);
846
847 return dpms;
848}
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
872{
873 struct drm_encoder *encoder = connector->encoder;
874 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
875 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
876
877 if (mode == connector->dpms)
878 return 0;
879
880 old_dpms = connector->dpms;
881 connector->dpms = mode;
882
883 if (encoder)
884 encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
885
886
887 if (mode < old_dpms) {
888 if (crtc) {
889 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
890 if (crtc_funcs->dpms)
891 (*crtc_funcs->dpms) (crtc,
892 drm_helper_choose_crtc_dpms(crtc));
893 }
894 if (encoder)
895 drm_helper_encoder_dpms(encoder, encoder_dpms);
896 }
897
898
899 if (mode > old_dpms) {
900 if (encoder)
901 drm_helper_encoder_dpms(encoder, encoder_dpms);
902 if (crtc) {
903 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
904 if (crtc_funcs->dpms)
905 (*crtc_funcs->dpms) (crtc,
906 drm_helper_choose_crtc_dpms(crtc));
907 }
908 }
909
910 return 0;
911}
912EXPORT_SYMBOL(drm_helper_connector_dpms);
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940void drm_helper_resume_force_mode(struct drm_device *dev)
941{
942 struct drm_crtc *crtc;
943 struct drm_encoder *encoder;
944 const struct drm_crtc_helper_funcs *crtc_funcs;
945 int encoder_dpms;
946 bool ret;
947
948 drm_modeset_lock_all(dev);
949 drm_for_each_crtc(crtc, dev) {
950
951 if (!crtc->enabled)
952 continue;
953
954 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
955 crtc->x, crtc->y, crtc->primary->fb);
956
957
958 if (ret == false)
959 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
960
961
962 if (drm_helper_choose_crtc_dpms(crtc)) {
963 drm_for_each_encoder(encoder, dev) {
964
965 if(encoder->crtc != crtc)
966 continue;
967
968 encoder_dpms = drm_helper_choose_encoder_dpms(
969 encoder);
970
971 drm_helper_encoder_dpms(encoder, encoder_dpms);
972 }
973
974 crtc_funcs = crtc->helper_private;
975 if (crtc_funcs->dpms)
976 (*crtc_funcs->dpms) (crtc,
977 drm_helper_choose_crtc_dpms(crtc));
978 }
979 }
980
981
982 __drm_helper_disable_unused_functions(dev);
983 drm_modeset_unlock_all(dev);
984}
985EXPORT_SYMBOL(drm_helper_resume_force_mode);
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
1005 struct drm_display_mode *adjusted_mode, int x, int y,
1006 struct drm_framebuffer *old_fb)
1007{
1008 struct drm_crtc_state *crtc_state;
1009 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1010 int ret;
1011
1012 if (crtc->funcs->atomic_duplicate_state)
1013 crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
1014 else {
1015 if (!crtc->state)
1016 drm_atomic_helper_crtc_reset(crtc);
1017
1018 crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc);
1019 }
1020
1021 if (!crtc_state)
1022 return -ENOMEM;
1023
1024 crtc_state->planes_changed = true;
1025 crtc_state->mode_changed = true;
1026 ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
1027 if (ret)
1028 goto out;
1029 drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
1030
1031 if (crtc_funcs->atomic_check) {
1032 ret = crtc_funcs->atomic_check(crtc, crtc_state);
1033 if (ret)
1034 goto out;
1035 }
1036
1037 swap(crtc->state, crtc_state);
1038
1039 crtc_funcs->mode_set_nofb(crtc);
1040
1041 ret = drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
1042
1043out:
1044 if (crtc_state) {
1045 if (crtc->funcs->atomic_destroy_state)
1046 crtc->funcs->atomic_destroy_state(crtc, crtc_state);
1047 else
1048 drm_atomic_helper_crtc_destroy_state(crtc, crtc_state);
1049 }
1050
1051 return ret;
1052}
1053EXPORT_SYMBOL(drm_helper_crtc_mode_set);
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
1070 struct drm_framebuffer *old_fb)
1071{
1072 struct drm_plane_state *plane_state;
1073 struct drm_plane *plane = crtc->primary;
1074
1075 if (plane->funcs->atomic_duplicate_state)
1076 plane_state = plane->funcs->atomic_duplicate_state(plane);
1077 else {
1078 if (!plane->state)
1079 drm_atomic_helper_plane_reset(plane);
1080
1081 plane_state = drm_atomic_helper_plane_duplicate_state(plane);
1082 }
1083 if (!plane_state)
1084 return -ENOMEM;
1085 plane_state->plane = plane;
1086
1087 plane_state->crtc = crtc;
1088 drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
1089 plane_state->crtc_x = 0;
1090 plane_state->crtc_y = 0;
1091 plane_state->crtc_h = crtc->mode.vdisplay;
1092 plane_state->crtc_w = crtc->mode.hdisplay;
1093 plane_state->src_x = x << 16;
1094 plane_state->src_y = y << 16;
1095 plane_state->src_h = crtc->mode.vdisplay << 16;
1096 plane_state->src_w = crtc->mode.hdisplay << 16;
1097
1098 return drm_plane_helper_commit(plane, plane_state, old_fb);
1099}
1100EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
1101