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_atomic_uapi.h>
39#include <drm/drm_crtc.h>
40#include <drm/drm_encoder.h>
41#include <drm/drm_fourcc.h>
42#include <drm/drm_crtc_helper.h>
43#include <drm/drm_fb_helper.h>
44#include <drm/drm_plane_helper.h>
45#include <drm/drm_atomic_helper.h>
46#include <drm/drm_edid.h>
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
89
90bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
91{
92 struct drm_connector *connector;
93 struct drm_connector_list_iter conn_iter;
94 struct drm_device *dev = encoder->dev;
95
96 WARN_ON(drm_drv_uses_atomic_modeset(dev));
97
98
99
100
101
102 if (!oops_in_progress) {
103 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
104 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
105 }
106
107
108 drm_connector_list_iter_begin(dev, &conn_iter);
109 drm_for_each_connector_iter(connector, &conn_iter) {
110 if (connector->encoder == encoder) {
111 drm_connector_list_iter_end(&conn_iter);
112 return true;
113 }
114 }
115 drm_connector_list_iter_end(&conn_iter);
116 return false;
117}
118EXPORT_SYMBOL(drm_helper_encoder_in_use);
119
120
121
122
123
124
125
126
127
128
129
130
131bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
132{
133 struct drm_encoder *encoder;
134 struct drm_device *dev = crtc->dev;
135
136 WARN_ON(drm_drv_uses_atomic_modeset(dev));
137
138
139
140
141
142 if (!oops_in_progress)
143 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
144
145 drm_for_each_encoder(encoder, dev)
146 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
147 return true;
148 return false;
149}
150EXPORT_SYMBOL(drm_helper_crtc_in_use);
151
152static void
153drm_encoder_disable(struct drm_encoder *encoder)
154{
155 const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
156
157 if (!encoder_funcs)
158 return;
159
160 drm_bridge_disable(encoder->bridge);
161
162 if (encoder_funcs->disable)
163 (*encoder_funcs->disable)(encoder);
164 else if (encoder_funcs->dpms)
165 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
166
167 drm_bridge_post_disable(encoder->bridge);
168}
169
170static void __drm_helper_disable_unused_functions(struct drm_device *dev)
171{
172 struct drm_encoder *encoder;
173 struct drm_crtc *crtc;
174
175 drm_warn_on_modeset_not_all_locked(dev);
176
177 drm_for_each_encoder(encoder, dev) {
178 if (!drm_helper_encoder_in_use(encoder)) {
179 drm_encoder_disable(encoder);
180
181 encoder->crtc = NULL;
182 }
183 }
184
185 drm_for_each_crtc(crtc, dev) {
186 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
187 crtc->enabled = drm_helper_crtc_in_use(crtc);
188 if (!crtc->enabled) {
189 if (crtc_funcs->disable)
190 (*crtc_funcs->disable)(crtc);
191 else
192 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
193 crtc->primary->fb = NULL;
194 }
195 }
196}
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217void drm_helper_disable_unused_functions(struct drm_device *dev)
218{
219 WARN_ON(drm_drv_uses_atomic_modeset(dev));
220
221 drm_modeset_lock_all(dev);
222 __drm_helper_disable_unused_functions(dev);
223 drm_modeset_unlock_all(dev);
224}
225EXPORT_SYMBOL(drm_helper_disable_unused_functions);
226
227
228
229
230
231
232static void
233drm_crtc_prepare_encoders(struct drm_device *dev)
234{
235 const struct drm_encoder_helper_funcs *encoder_funcs;
236 struct drm_encoder *encoder;
237
238 drm_for_each_encoder(encoder, dev) {
239 encoder_funcs = encoder->helper_private;
240 if (!encoder_funcs)
241 continue;
242
243
244 if (encoder->crtc == NULL)
245 drm_encoder_disable(encoder);
246
247 if (encoder_funcs->get_crtc &&
248 encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
249 drm_encoder_disable(encoder);
250 }
251}
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
274 struct drm_display_mode *mode,
275 int x, int y,
276 struct drm_framebuffer *old_fb)
277{
278 struct drm_device *dev = crtc->dev;
279 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
280 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
281 const struct drm_encoder_helper_funcs *encoder_funcs;
282 int saved_x, saved_y;
283 bool saved_enabled;
284 struct drm_encoder *encoder;
285 bool ret = true;
286
287 WARN_ON(drm_drv_uses_atomic_modeset(dev));
288
289 drm_warn_on_modeset_not_all_locked(dev);
290
291 saved_enabled = crtc->enabled;
292 crtc->enabled = drm_helper_crtc_in_use(crtc);
293 if (!crtc->enabled)
294 return true;
295
296 adjusted_mode = drm_mode_duplicate(dev, mode);
297 if (!adjusted_mode) {
298 crtc->enabled = saved_enabled;
299 return false;
300 }
301
302 saved_mode = crtc->mode;
303 saved_hwmode = crtc->hwmode;
304 saved_x = crtc->x;
305 saved_y = crtc->y;
306
307
308
309
310 crtc->mode = *mode;
311 crtc->x = x;
312 crtc->y = y;
313
314
315
316
317
318 drm_for_each_encoder(encoder, dev) {
319
320 if (encoder->crtc != crtc)
321 continue;
322
323 encoder_funcs = encoder->helper_private;
324 if (!encoder_funcs)
325 continue;
326
327 ret = drm_bridge_mode_fixup(encoder->bridge,
328 mode, adjusted_mode);
329 if (!ret) {
330 DRM_DEBUG_KMS("Bridge fixup failed\n");
331 goto done;
332 }
333
334 encoder_funcs = encoder->helper_private;
335 if (encoder_funcs->mode_fixup) {
336 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
337 adjusted_mode))) {
338 DRM_DEBUG_KMS("Encoder fixup failed\n");
339 goto done;
340 }
341 }
342 }
343
344 if (crtc_funcs->mode_fixup) {
345 if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
346 adjusted_mode))) {
347 DRM_DEBUG_KMS("CRTC fixup failed\n");
348 goto done;
349 }
350 }
351 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
352
353 crtc->hwmode = *adjusted_mode;
354
355
356 drm_for_each_encoder(encoder, dev) {
357
358 if (encoder->crtc != crtc)
359 continue;
360
361 encoder_funcs = encoder->helper_private;
362 if (!encoder_funcs)
363 continue;
364
365 drm_bridge_disable(encoder->bridge);
366
367
368 if (encoder_funcs->prepare)
369 encoder_funcs->prepare(encoder);
370
371 drm_bridge_post_disable(encoder->bridge);
372 }
373
374 drm_crtc_prepare_encoders(dev);
375
376 crtc_funcs->prepare(crtc);
377
378
379
380
381 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
382 if (!ret)
383 goto done;
384
385 drm_for_each_encoder(encoder, dev) {
386
387 if (encoder->crtc != crtc)
388 continue;
389
390 encoder_funcs = encoder->helper_private;
391 if (!encoder_funcs)
392 continue;
393
394 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
395 encoder->base.id, encoder->name, mode->name);
396 if (encoder_funcs->mode_set)
397 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
398
399 drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
400 }
401
402
403 crtc_funcs->commit(crtc);
404
405 drm_for_each_encoder(encoder, dev) {
406
407 if (encoder->crtc != crtc)
408 continue;
409
410 encoder_funcs = encoder->helper_private;
411 if (!encoder_funcs)
412 continue;
413
414 drm_bridge_pre_enable(encoder->bridge);
415
416 if (encoder_funcs->commit)
417 encoder_funcs->commit(encoder);
418
419 drm_bridge_enable(encoder->bridge);
420 }
421
422
423
424
425
426 drm_calc_timestamping_constants(crtc, &crtc->hwmode);
427
428
429done:
430 drm_mode_destroy(dev, adjusted_mode);
431 if (!ret) {
432 crtc->enabled = saved_enabled;
433 crtc->mode = saved_mode;
434 crtc->hwmode = saved_hwmode;
435 crtc->x = saved_x;
436 crtc->y = saved_y;
437 }
438
439 return ret;
440}
441EXPORT_SYMBOL(drm_crtc_helper_set_mode);
442
443static void
444drm_crtc_helper_disable(struct drm_crtc *crtc)
445{
446 struct drm_device *dev = crtc->dev;
447 struct drm_connector *connector;
448 struct drm_encoder *encoder;
449
450
451 drm_for_each_encoder(encoder, dev) {
452 struct drm_connector_list_iter conn_iter;
453
454 if (encoder->crtc != crtc)
455 continue;
456
457 drm_connector_list_iter_begin(dev, &conn_iter);
458 drm_for_each_connector_iter(connector, &conn_iter) {
459 if (connector->encoder != encoder)
460 continue;
461
462 connector->encoder = NULL;
463
464
465
466
467
468
469
470 connector->dpms = DRM_MODE_DPMS_OFF;
471
472
473 drm_connector_put(connector);
474 }
475 drm_connector_list_iter_end(&conn_iter);
476 }
477
478 __drm_helper_disable_unused_functions(dev);
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 new_encoder = connector_funcs->best_encoder(connector);
647
648
649 if (new_encoder == NULL)
650
651 fail = 1;
652
653 if (connector->dpms != DRM_MODE_DPMS_ON) {
654 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
655 mode_changed = true;
656 }
657
658 break;
659 }
660 }
661
662 if (new_encoder != connector->encoder) {
663 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
664 mode_changed = true;
665
666
667
668 if (connector->encoder)
669 connector->encoder->crtc = NULL;
670 connector->encoder = new_encoder;
671 }
672 }
673 drm_connector_list_iter_end(&conn_iter);
674
675 if (fail) {
676 ret = -EINVAL;
677 goto fail;
678 }
679
680 count = 0;
681 drm_connector_list_iter_begin(dev, &conn_iter);
682 drm_for_each_connector_iter(connector, &conn_iter) {
683 if (!connector->encoder)
684 continue;
685
686 if (connector->encoder->crtc == set->crtc)
687 new_crtc = NULL;
688 else
689 new_crtc = connector->encoder->crtc;
690
691 for (ro = 0; ro < set->num_connectors; ro++) {
692 if (set->connectors[ro] == connector)
693 new_crtc = set->crtc;
694 }
695
696
697 if (new_crtc &&
698 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
699 ret = -EINVAL;
700 drm_connector_list_iter_end(&conn_iter);
701 goto fail;
702 }
703 if (new_crtc != connector->encoder->crtc) {
704 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
705 mode_changed = true;
706 connector->encoder->crtc = new_crtc;
707 }
708 if (new_crtc) {
709 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
710 connector->base.id, connector->name,
711 new_crtc->base.id, new_crtc->name);
712 } else {
713 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
714 connector->base.id, connector->name);
715 }
716 }
717 drm_connector_list_iter_end(&conn_iter);
718
719
720 if (fb_changed && !crtc_funcs->mode_set_base)
721 mode_changed = true;
722
723 if (mode_changed) {
724 if (drm_helper_crtc_in_use(set->crtc)) {
725 DRM_DEBUG_KMS("attempting to set mode from"
726 " userspace\n");
727 drm_mode_debug_printmodeline(set->mode);
728 set->crtc->primary->fb = set->fb;
729 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
730 set->x, set->y,
731 save_set.fb)) {
732 DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
733 set->crtc->base.id, set->crtc->name);
734 set->crtc->primary->fb = save_set.fb;
735 ret = -EINVAL;
736 goto fail;
737 }
738 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
739 for (i = 0; i < set->num_connectors; i++) {
740 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
741 set->connectors[i]->name);
742 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
743 }
744 }
745 __drm_helper_disable_unused_functions(dev);
746 } else if (fb_changed) {
747 set->crtc->x = set->x;
748 set->crtc->y = set->y;
749 set->crtc->primary->fb = set->fb;
750 ret = crtc_funcs->mode_set_base(set->crtc,
751 set->x, set->y, save_set.fb);
752 if (ret != 0) {
753 set->crtc->x = save_set.x;
754 set->crtc->y = save_set.y;
755 set->crtc->primary->fb = save_set.fb;
756 goto fail;
757 }
758 }
759
760 kfree(save_connector_encoders);
761 kfree(save_encoder_crtcs);
762 return 0;
763
764fail:
765
766 count = 0;
767 drm_for_each_encoder(encoder, dev) {
768 encoder->crtc = save_encoder_crtcs[count++];
769 }
770
771 count = 0;
772 drm_connector_list_iter_begin(dev, &conn_iter);
773 drm_for_each_connector_iter(connector, &conn_iter)
774 connector->encoder = save_connector_encoders[count++];
775 drm_connector_list_iter_end(&conn_iter);
776
777
778
779
780 for (ro = 0; ro < set->num_connectors; ro++) {
781 if (set->connectors[ro]->encoder)
782 continue;
783 drm_connector_put(set->connectors[ro]);
784 }
785
786
787 if (mode_changed &&
788 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
789 save_set.y, save_set.fb))
790 DRM_ERROR("failed to restore config after modeset failure\n");
791
792 kfree(save_connector_encoders);
793 kfree(save_encoder_crtcs);
794 return ret;
795}
796EXPORT_SYMBOL(drm_crtc_helper_set_config);
797
798static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
799{
800 int dpms = DRM_MODE_DPMS_OFF;
801 struct drm_connector *connector;
802 struct drm_connector_list_iter conn_iter;
803 struct drm_device *dev = encoder->dev;
804
805 drm_connector_list_iter_begin(dev, &conn_iter);
806 drm_for_each_connector_iter(connector, &conn_iter)
807 if (connector->encoder == encoder)
808 if (connector->dpms < dpms)
809 dpms = connector->dpms;
810 drm_connector_list_iter_end(&conn_iter);
811
812 return dpms;
813}
814
815
816static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
817{
818 struct drm_bridge *bridge = encoder->bridge;
819 const struct drm_encoder_helper_funcs *encoder_funcs;
820
821 encoder_funcs = encoder->helper_private;
822 if (!encoder_funcs)
823 return;
824
825 if (mode == DRM_MODE_DPMS_ON)
826 drm_bridge_pre_enable(bridge);
827 else
828 drm_bridge_disable(bridge);
829
830 if (encoder_funcs->dpms)
831 encoder_funcs->dpms(encoder, mode);
832
833 if (mode == DRM_MODE_DPMS_ON)
834 drm_bridge_enable(bridge);
835 else
836 drm_bridge_post_disable(bridge);
837}
838
839static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
840{
841 int dpms = DRM_MODE_DPMS_OFF;
842 struct drm_connector *connector;
843 struct drm_connector_list_iter conn_iter;
844 struct drm_device *dev = crtc->dev;
845
846 drm_connector_list_iter_begin(dev, &conn_iter);
847 drm_for_each_connector_iter(connector, &conn_iter)
848 if (connector->encoder && connector->encoder->crtc == crtc)
849 if (connector->dpms < dpms)
850 dpms = connector->dpms;
851 drm_connector_list_iter_end(&conn_iter);
852
853 return dpms;
854}
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
878{
879 struct drm_encoder *encoder = connector->encoder;
880 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
881 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
882
883 WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
884
885 if (mode == connector->dpms)
886 return 0;
887
888 old_dpms = connector->dpms;
889 connector->dpms = mode;
890
891 if (encoder)
892 encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
893
894
895 if (mode < old_dpms) {
896 if (crtc) {
897 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
898 if (crtc_funcs->dpms)
899 (*crtc_funcs->dpms) (crtc,
900 drm_helper_choose_crtc_dpms(crtc));
901 }
902 if (encoder)
903 drm_helper_encoder_dpms(encoder, encoder_dpms);
904 }
905
906
907 if (mode > old_dpms) {
908 if (encoder)
909 drm_helper_encoder_dpms(encoder, encoder_dpms);
910 if (crtc) {
911 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
912 if (crtc_funcs->dpms)
913 (*crtc_funcs->dpms) (crtc,
914 drm_helper_choose_crtc_dpms(crtc));
915 }
916 }
917
918 return 0;
919}
920EXPORT_SYMBOL(drm_helper_connector_dpms);
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948void drm_helper_resume_force_mode(struct drm_device *dev)
949{
950 struct drm_crtc *crtc;
951 struct drm_encoder *encoder;
952 const struct drm_crtc_helper_funcs *crtc_funcs;
953 int encoder_dpms;
954 bool ret;
955
956 WARN_ON(drm_drv_uses_atomic_modeset(dev));
957
958 drm_modeset_lock_all(dev);
959 drm_for_each_crtc(crtc, dev) {
960
961 if (!crtc->enabled)
962 continue;
963
964 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
965 crtc->x, crtc->y, crtc->primary->fb);
966
967
968 if (ret == false)
969 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
970
971
972 if (drm_helper_choose_crtc_dpms(crtc)) {
973 drm_for_each_encoder(encoder, dev) {
974
975 if(encoder->crtc != crtc)
976 continue;
977
978 encoder_dpms = drm_helper_choose_encoder_dpms(
979 encoder);
980
981 drm_helper_encoder_dpms(encoder, encoder_dpms);
982 }
983
984 crtc_funcs = crtc->helper_private;
985 if (crtc_funcs->dpms)
986 (*crtc_funcs->dpms) (crtc,
987 drm_helper_choose_crtc_dpms(crtc));
988 }
989 }
990
991
992 __drm_helper_disable_unused_functions(dev);
993 drm_modeset_unlock_all(dev);
994}
995EXPORT_SYMBOL(drm_helper_resume_force_mode);
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010int drm_helper_force_disable_all(struct drm_device *dev)
1011{
1012 struct drm_crtc *crtc;
1013 int ret = 0;
1014
1015 drm_modeset_lock_all(dev);
1016 drm_for_each_crtc(crtc, dev)
1017 if (crtc->enabled) {
1018 struct drm_mode_set set = {
1019 .crtc = crtc,
1020 };
1021
1022 ret = drm_mode_set_config_internal(&set);
1023 if (ret)
1024 goto out;
1025 }
1026out:
1027 drm_modeset_unlock_all(dev);
1028 return ret;
1029}
1030EXPORT_SYMBOL(drm_helper_force_disable_all);
1031