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/export.h>
33#include <linux/kernel.h>
34#include <linux/moduleparam.h>
35
36#include <drm/drm_atomic.h>
37#include <drm/drm_atomic_helper.h>
38#include <drm/drm_atomic_uapi.h>
39#include <drm/drm_bridge.h>
40#include <drm/drm_crtc.h>
41#include <drm/drm_crtc_helper.h>
42#include <drm/drm_drv.h>
43#include <drm/drm_edid.h>
44#include <drm/drm_encoder.h>
45#include <drm/drm_fb_helper.h>
46#include <drm/drm_fourcc.h>
47#include <drm/drm_plane_helper.h>
48#include <drm/drm_print.h>
49#include <drm/drm_vblank.h>
50
51#include "drm_crtc_helper_internal.h"
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
89
90
91
92
93
94
95bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
96{
97 struct drm_connector *connector;
98 struct drm_connector_list_iter conn_iter;
99 struct drm_device *dev = encoder->dev;
100
101 WARN_ON(drm_drv_uses_atomic_modeset(dev));
102
103
104
105
106
107 if (!oops_in_progress) {
108 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
109 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
110 }
111
112
113 drm_connector_list_iter_begin(dev, &conn_iter);
114 drm_for_each_connector_iter(connector, &conn_iter) {
115 if (connector->encoder == encoder) {
116 drm_connector_list_iter_end(&conn_iter);
117 return true;
118 }
119 }
120 drm_connector_list_iter_end(&conn_iter);
121 return false;
122}
123EXPORT_SYMBOL(drm_helper_encoder_in_use);
124
125
126
127
128
129
130
131
132
133
134
135
136bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
137{
138 struct drm_encoder *encoder;
139 struct drm_device *dev = crtc->dev;
140
141 WARN_ON(drm_drv_uses_atomic_modeset(dev));
142
143
144
145
146
147 if (!oops_in_progress)
148 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
149
150 drm_for_each_encoder(encoder, dev)
151 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
152 return true;
153 return false;
154}
155EXPORT_SYMBOL(drm_helper_crtc_in_use);
156
157static void
158drm_encoder_disable(struct drm_encoder *encoder)
159{
160 const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
161
162 if (!encoder_funcs)
163 return;
164
165 if (encoder_funcs->disable)
166 (*encoder_funcs->disable)(encoder);
167 else if (encoder_funcs->dpms)
168 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
169}
170
171static void __drm_helper_disable_unused_functions(struct drm_device *dev)
172{
173 struct drm_encoder *encoder;
174 struct drm_crtc *crtc;
175
176 drm_warn_on_modeset_not_all_locked(dev);
177
178 drm_for_each_encoder(encoder, dev) {
179 if (!drm_helper_encoder_in_use(encoder)) {
180 drm_encoder_disable(encoder);
181
182 encoder->crtc = NULL;
183 }
184 }
185
186 drm_for_each_crtc(crtc, dev) {
187 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
188 crtc->enabled = drm_helper_crtc_in_use(crtc);
189 if (!crtc->enabled) {
190 if (crtc_funcs->disable)
191 (*crtc_funcs->disable)(crtc);
192 else
193 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
194 crtc->primary->fb = NULL;
195 }
196 }
197}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218void drm_helper_disable_unused_functions(struct drm_device *dev)
219{
220 WARN_ON(drm_drv_uses_atomic_modeset(dev));
221
222 drm_modeset_lock_all(dev);
223 __drm_helper_disable_unused_functions(dev);
224 drm_modeset_unlock_all(dev);
225}
226EXPORT_SYMBOL(drm_helper_disable_unused_functions);
227
228
229
230
231
232
233static void
234drm_crtc_prepare_encoders(struct drm_device *dev)
235{
236 const struct drm_encoder_helper_funcs *encoder_funcs;
237 struct drm_encoder *encoder;
238
239 drm_for_each_encoder(encoder, dev) {
240 encoder_funcs = encoder->helper_private;
241 if (!encoder_funcs)
242 continue;
243
244
245 if (encoder->crtc == NULL)
246 drm_encoder_disable(encoder);
247
248 if (encoder_funcs->get_crtc &&
249 encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
250 drm_encoder_disable(encoder);
251 }
252}
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
275 struct drm_display_mode *mode,
276 int x, int y,
277 struct drm_framebuffer *old_fb)
278{
279 struct drm_device *dev = crtc->dev;
280 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
281 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
282 const struct drm_encoder_helper_funcs *encoder_funcs;
283 int saved_x, saved_y;
284 bool saved_enabled;
285 struct drm_encoder *encoder;
286 bool ret = true;
287
288 WARN_ON(drm_drv_uses_atomic_modeset(dev));
289
290 drm_warn_on_modeset_not_all_locked(dev);
291
292 saved_enabled = crtc->enabled;
293 crtc->enabled = drm_helper_crtc_in_use(crtc);
294 if (!crtc->enabled)
295 return true;
296
297 adjusted_mode = drm_mode_duplicate(dev, mode);
298 if (!adjusted_mode) {
299 crtc->enabled = saved_enabled;
300 return false;
301 }
302
303 saved_mode = crtc->mode;
304 saved_hwmode = crtc->hwmode;
305 saved_x = crtc->x;
306 saved_y = crtc->y;
307
308
309
310
311 crtc->mode = *mode;
312 crtc->x = x;
313 crtc->y = y;
314
315
316
317
318
319 drm_for_each_encoder(encoder, dev) {
320
321 if (encoder->crtc != crtc)
322 continue;
323
324 encoder_funcs = encoder->helper_private;
325 if (!encoder_funcs)
326 continue;
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
360 if (encoder_funcs->prepare)
361 encoder_funcs->prepare(encoder);
362 }
363
364 drm_crtc_prepare_encoders(dev);
365
366 crtc_funcs->prepare(crtc);
367
368
369
370
371 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
372 if (!ret)
373 goto done;
374
375 drm_for_each_encoder(encoder, dev) {
376
377 if (encoder->crtc != crtc)
378 continue;
379
380 encoder_funcs = encoder->helper_private;
381 if (!encoder_funcs)
382 continue;
383
384 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
385 encoder->base.id, encoder->name, mode->name);
386 if (encoder_funcs->mode_set)
387 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
388 }
389
390
391 crtc_funcs->commit(crtc);
392
393 drm_for_each_encoder(encoder, dev) {
394
395 if (encoder->crtc != crtc)
396 continue;
397
398 encoder_funcs = encoder->helper_private;
399 if (!encoder_funcs)
400 continue;
401
402 if (encoder_funcs->commit)
403 encoder_funcs->commit(encoder);
404 }
405
406
407
408
409
410 drm_calc_timestamping_constants(crtc, &crtc->hwmode);
411
412
413done:
414 drm_mode_destroy(dev, adjusted_mode);
415 if (!ret) {
416 crtc->enabled = saved_enabled;
417 crtc->mode = saved_mode;
418 crtc->hwmode = saved_hwmode;
419 crtc->x = saved_x;
420 crtc->y = saved_y;
421 }
422
423 return ret;
424}
425EXPORT_SYMBOL(drm_crtc_helper_set_mode);
426
427static void
428drm_crtc_helper_disable(struct drm_crtc *crtc)
429{
430 struct drm_device *dev = crtc->dev;
431 struct drm_connector *connector;
432 struct drm_encoder *encoder;
433
434
435 drm_for_each_encoder(encoder, dev) {
436 struct drm_connector_list_iter conn_iter;
437
438 if (encoder->crtc != crtc)
439 continue;
440
441 drm_connector_list_iter_begin(dev, &conn_iter);
442 drm_for_each_connector_iter(connector, &conn_iter) {
443 if (connector->encoder != encoder)
444 continue;
445
446 connector->encoder = NULL;
447
448
449
450
451
452
453
454 connector->dpms = DRM_MODE_DPMS_OFF;
455
456
457 drm_connector_put(connector);
458 }
459 drm_connector_list_iter_end(&conn_iter);
460 }
461
462 __drm_helper_disable_unused_functions(dev);
463}
464
465
466
467
468
469struct drm_encoder *
470drm_connector_get_single_encoder(struct drm_connector *connector)
471{
472 struct drm_encoder *encoder;
473
474 WARN_ON(hweight32(connector->possible_encoders) > 1);
475 drm_connector_for_each_possible_encoder(connector, encoder)
476 return encoder;
477
478 return NULL;
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
514
515
516
517
518
519int drm_crtc_helper_set_config(struct drm_mode_set *set,
520 struct drm_modeset_acquire_ctx *ctx)
521{
522 struct drm_device *dev;
523 struct drm_crtc **save_encoder_crtcs, *new_crtc;
524 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
525 bool mode_changed = false;
526 bool fb_changed = false;
527 struct drm_connector *connector;
528 struct drm_connector_list_iter conn_iter;
529 int count = 0, ro, fail = 0;
530 const struct drm_crtc_helper_funcs *crtc_funcs;
531 struct drm_mode_set save_set;
532 int ret;
533 int i;
534
535 DRM_DEBUG_KMS("\n");
536
537 BUG_ON(!set);
538 BUG_ON(!set->crtc);
539 BUG_ON(!set->crtc->helper_private);
540
541
542 BUG_ON(!set->mode && set->fb);
543 BUG_ON(set->fb && set->num_connectors == 0);
544
545 crtc_funcs = set->crtc->helper_private;
546
547 dev = set->crtc->dev;
548 WARN_ON(drm_drv_uses_atomic_modeset(dev));
549
550 if (!set->mode)
551 set->fb = NULL;
552
553 if (set->fb) {
554 DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
555 set->crtc->base.id, set->crtc->name,
556 set->fb->base.id,
557 (int)set->num_connectors, set->x, set->y);
558 } else {
559 DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
560 set->crtc->base.id, set->crtc->name);
561 drm_crtc_helper_disable(set->crtc);
562 return 0;
563 }
564
565 drm_warn_on_modeset_not_all_locked(dev);
566
567
568
569
570
571 save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder,
572 sizeof(struct drm_crtc *), GFP_KERNEL);
573 if (!save_encoder_crtcs)
574 return -ENOMEM;
575
576 save_connector_encoders = kcalloc(dev->mode_config.num_connector,
577 sizeof(struct drm_encoder *), GFP_KERNEL);
578 if (!save_connector_encoders) {
579 kfree(save_encoder_crtcs);
580 return -ENOMEM;
581 }
582
583
584
585
586
587
588 count = 0;
589 drm_for_each_encoder(encoder, dev) {
590 save_encoder_crtcs[count++] = encoder->crtc;
591 }
592
593 count = 0;
594 drm_connector_list_iter_begin(dev, &conn_iter);
595 drm_for_each_connector_iter(connector, &conn_iter)
596 save_connector_encoders[count++] = connector->encoder;
597 drm_connector_list_iter_end(&conn_iter);
598
599 save_set.crtc = set->crtc;
600 save_set.mode = &set->crtc->mode;
601 save_set.x = set->crtc->x;
602 save_set.y = set->crtc->y;
603 save_set.fb = set->crtc->primary->fb;
604
605
606
607 if (set->crtc->primary->fb != set->fb) {
608
609 if (set->crtc->primary->fb == NULL) {
610 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
611 mode_changed = true;
612 } else if (set->fb->format != set->crtc->primary->fb->format) {
613 mode_changed = true;
614 } else
615 fb_changed = true;
616 }
617
618 if (set->x != set->crtc->x || set->y != set->crtc->y)
619 fb_changed = true;
620
621 if (!drm_mode_equal(set->mode, &set->crtc->mode)) {
622 DRM_DEBUG_KMS("modes are different, full mode set\n");
623 drm_mode_debug_printmodeline(&set->crtc->mode);
624 drm_mode_debug_printmodeline(set->mode);
625 mode_changed = true;
626 }
627
628
629
630
631 for (ro = 0; ro < set->num_connectors; ro++) {
632 if (set->connectors[ro]->encoder)
633 continue;
634 drm_connector_get(set->connectors[ro]);
635 }
636
637
638 count = 0;
639 drm_connector_list_iter_begin(dev, &conn_iter);
640 drm_for_each_connector_iter(connector, &conn_iter) {
641 const struct drm_connector_helper_funcs *connector_funcs =
642 connector->helper_private;
643 new_encoder = connector->encoder;
644 for (ro = 0; ro < set->num_connectors; ro++) {
645 if (set->connectors[ro] == connector) {
646 if (connector_funcs->best_encoder)
647 new_encoder = connector_funcs->best_encoder(connector);
648 else
649 new_encoder = drm_connector_get_single_encoder(connector);
650
651
652
653 if (new_encoder == NULL)
654
655 fail = 1;
656
657 if (connector->dpms != DRM_MODE_DPMS_ON) {
658 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
659 mode_changed = true;
660 }
661
662 break;
663 }
664 }
665
666 if (new_encoder != connector->encoder) {
667 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
668 mode_changed = true;
669
670
671
672 if (connector->encoder)
673 connector->encoder->crtc = NULL;
674 connector->encoder = new_encoder;
675 }
676 }
677 drm_connector_list_iter_end(&conn_iter);
678
679 if (fail) {
680 ret = -EINVAL;
681 goto fail;
682 }
683
684 count = 0;
685 drm_connector_list_iter_begin(dev, &conn_iter);
686 drm_for_each_connector_iter(connector, &conn_iter) {
687 if (!connector->encoder)
688 continue;
689
690 if (connector->encoder->crtc == set->crtc)
691 new_crtc = NULL;
692 else
693 new_crtc = connector->encoder->crtc;
694
695 for (ro = 0; ro < set->num_connectors; ro++) {
696 if (set->connectors[ro] == connector)
697 new_crtc = set->crtc;
698 }
699
700
701 if (new_crtc &&
702 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
703 ret = -EINVAL;
704 drm_connector_list_iter_end(&conn_iter);
705 goto fail;
706 }
707 if (new_crtc != connector->encoder->crtc) {
708 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
709 mode_changed = true;
710 connector->encoder->crtc = new_crtc;
711 }
712 if (new_crtc) {
713 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
714 connector->base.id, connector->name,
715 new_crtc->base.id, new_crtc->name);
716 } else {
717 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
718 connector->base.id, connector->name);
719 }
720 }
721 drm_connector_list_iter_end(&conn_iter);
722
723
724 if (fb_changed && !crtc_funcs->mode_set_base)
725 mode_changed = true;
726
727 if (mode_changed) {
728 if (drm_helper_crtc_in_use(set->crtc)) {
729 DRM_DEBUG_KMS("attempting to set mode from"
730 " userspace\n");
731 drm_mode_debug_printmodeline(set->mode);
732 set->crtc->primary->fb = set->fb;
733 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
734 set->x, set->y,
735 save_set.fb)) {
736 DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
737 set->crtc->base.id, set->crtc->name);
738 set->crtc->primary->fb = save_set.fb;
739 ret = -EINVAL;
740 goto fail;
741 }
742 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
743 for (i = 0; i < set->num_connectors; i++) {
744 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
745 set->connectors[i]->name);
746 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
747 }
748 }
749 __drm_helper_disable_unused_functions(dev);
750 } else if (fb_changed) {
751 set->crtc->x = set->x;
752 set->crtc->y = set->y;
753 set->crtc->primary->fb = set->fb;
754 ret = crtc_funcs->mode_set_base(set->crtc,
755 set->x, set->y, save_set.fb);
756 if (ret != 0) {
757 set->crtc->x = save_set.x;
758 set->crtc->y = save_set.y;
759 set->crtc->primary->fb = save_set.fb;
760 goto fail;
761 }
762 }
763
764 kfree(save_connector_encoders);
765 kfree(save_encoder_crtcs);
766 return 0;
767
768fail:
769
770 count = 0;
771 drm_for_each_encoder(encoder, dev) {
772 encoder->crtc = save_encoder_crtcs[count++];
773 }
774
775 count = 0;
776 drm_connector_list_iter_begin(dev, &conn_iter);
777 drm_for_each_connector_iter(connector, &conn_iter)
778 connector->encoder = save_connector_encoders[count++];
779 drm_connector_list_iter_end(&conn_iter);
780
781
782
783
784 for (ro = 0; ro < set->num_connectors; ro++) {
785 if (set->connectors[ro]->encoder)
786 continue;
787 drm_connector_put(set->connectors[ro]);
788 }
789
790
791 if (mode_changed &&
792 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
793 save_set.y, save_set.fb))
794 DRM_ERROR("failed to restore config after modeset failure\n");
795
796 kfree(save_connector_encoders);
797 kfree(save_encoder_crtcs);
798 return ret;
799}
800EXPORT_SYMBOL(drm_crtc_helper_set_config);
801
802static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
803{
804 int dpms = DRM_MODE_DPMS_OFF;
805 struct drm_connector *connector;
806 struct drm_connector_list_iter conn_iter;
807 struct drm_device *dev = encoder->dev;
808
809 drm_connector_list_iter_begin(dev, &conn_iter);
810 drm_for_each_connector_iter(connector, &conn_iter)
811 if (connector->encoder == encoder)
812 if (connector->dpms < dpms)
813 dpms = connector->dpms;
814 drm_connector_list_iter_end(&conn_iter);
815
816 return dpms;
817}
818
819
820static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
821{
822 const struct drm_encoder_helper_funcs *encoder_funcs;
823
824 encoder_funcs = encoder->helper_private;
825 if (!encoder_funcs)
826 return;
827
828 if (encoder_funcs->dpms)
829 encoder_funcs->dpms(encoder, mode);
830}
831
832static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
833{
834 int dpms = DRM_MODE_DPMS_OFF;
835 struct drm_connector *connector;
836 struct drm_connector_list_iter conn_iter;
837 struct drm_device *dev = crtc->dev;
838
839 drm_connector_list_iter_begin(dev, &conn_iter);
840 drm_for_each_connector_iter(connector, &conn_iter)
841 if (connector->encoder && connector->encoder->crtc == crtc)
842 if (connector->dpms < dpms)
843 dpms = connector->dpms;
844 drm_connector_list_iter_end(&conn_iter);
845
846 return dpms;
847}
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
871{
872 struct drm_encoder *encoder = connector->encoder;
873 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
874 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
875
876 WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
877
878 if (mode == connector->dpms)
879 return 0;
880
881 old_dpms = connector->dpms;
882 connector->dpms = mode;
883
884 if (encoder)
885 encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
886
887
888 if (mode < old_dpms) {
889 if (crtc) {
890 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
891 if (crtc_funcs->dpms)
892 (*crtc_funcs->dpms) (crtc,
893 drm_helper_choose_crtc_dpms(crtc));
894 }
895 if (encoder)
896 drm_helper_encoder_dpms(encoder, encoder_dpms);
897 }
898
899
900 if (mode > old_dpms) {
901 if (encoder)
902 drm_helper_encoder_dpms(encoder, encoder_dpms);
903 if (crtc) {
904 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
905 if (crtc_funcs->dpms)
906 (*crtc_funcs->dpms) (crtc,
907 drm_helper_choose_crtc_dpms(crtc));
908 }
909 }
910
911 return 0;
912}
913EXPORT_SYMBOL(drm_helper_connector_dpms);
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
940
941void drm_helper_resume_force_mode(struct drm_device *dev)
942{
943 struct drm_crtc *crtc;
944 struct drm_encoder *encoder;
945 const struct drm_crtc_helper_funcs *crtc_funcs;
946 int encoder_dpms;
947 bool ret;
948
949 WARN_ON(drm_drv_uses_atomic_modeset(dev));
950
951 drm_modeset_lock_all(dev);
952 drm_for_each_crtc(crtc, dev) {
953
954 if (!crtc->enabled)
955 continue;
956
957 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
958 crtc->x, crtc->y, crtc->primary->fb);
959
960
961 if (ret == false)
962 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
963
964
965 if (drm_helper_choose_crtc_dpms(crtc)) {
966 drm_for_each_encoder(encoder, dev) {
967
968 if(encoder->crtc != crtc)
969 continue;
970
971 encoder_dpms = drm_helper_choose_encoder_dpms(
972 encoder);
973
974 drm_helper_encoder_dpms(encoder, encoder_dpms);
975 }
976
977 crtc_funcs = crtc->helper_private;
978 if (crtc_funcs->dpms)
979 (*crtc_funcs->dpms) (crtc,
980 drm_helper_choose_crtc_dpms(crtc));
981 }
982 }
983
984
985 __drm_helper_disable_unused_functions(dev);
986 drm_modeset_unlock_all(dev);
987}
988EXPORT_SYMBOL(drm_helper_resume_force_mode);
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003int drm_helper_force_disable_all(struct drm_device *dev)
1004{
1005 struct drm_crtc *crtc;
1006 int ret = 0;
1007
1008 drm_modeset_lock_all(dev);
1009 drm_for_each_crtc(crtc, dev)
1010 if (crtc->enabled) {
1011 struct drm_mode_set set = {
1012 .crtc = crtc,
1013 };
1014
1015 ret = drm_mode_set_config_internal(&set);
1016 if (ret)
1017 goto out;
1018 }
1019out:
1020 drm_modeset_unlock_all(dev);
1021 return ret;
1022}
1023EXPORT_SYMBOL(drm_helper_force_disable_all);
1024