0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 #include <linux/export.h>
0033 #include <linux/kernel.h>
0034 #include <linux/moduleparam.h>
0035
0036 #include <drm/drm_atomic.h>
0037 #include <drm/drm_atomic_helper.h>
0038 #include <drm/drm_atomic_uapi.h>
0039 #include <drm/drm_bridge.h>
0040 #include <drm/drm_crtc.h>
0041 #include <drm/drm_crtc_helper.h>
0042 #include <drm/drm_drv.h>
0043 #include <drm/drm_edid.h>
0044 #include <drm/drm_encoder.h>
0045 #include <drm/drm_fb_helper.h>
0046 #include <drm/drm_fourcc.h>
0047 #include <drm/drm_framebuffer.h>
0048 #include <drm/drm_plane_helper.h>
0049 #include <drm/drm_print.h>
0050 #include <drm/drm_vblank.h>
0051
0052 #include "drm_crtc_helper_internal.h"
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
0097 {
0098 struct drm_connector *connector;
0099 struct drm_connector_list_iter conn_iter;
0100 struct drm_device *dev = encoder->dev;
0101
0102 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0103
0104
0105
0106
0107
0108 if (!oops_in_progress) {
0109 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
0110 WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
0111 }
0112
0113
0114 drm_connector_list_iter_begin(dev, &conn_iter);
0115 drm_for_each_connector_iter(connector, &conn_iter) {
0116 if (connector->encoder == encoder) {
0117 drm_connector_list_iter_end(&conn_iter);
0118 return true;
0119 }
0120 }
0121 drm_connector_list_iter_end(&conn_iter);
0122 return false;
0123 }
0124 EXPORT_SYMBOL(drm_helper_encoder_in_use);
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137 bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
0138 {
0139 struct drm_encoder *encoder;
0140 struct drm_device *dev = crtc->dev;
0141
0142 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0143
0144
0145
0146
0147
0148 if (!oops_in_progress)
0149 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
0150
0151 drm_for_each_encoder(encoder, dev)
0152 if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
0153 return true;
0154 return false;
0155 }
0156 EXPORT_SYMBOL(drm_helper_crtc_in_use);
0157
0158 static void
0159 drm_encoder_disable(struct drm_encoder *encoder)
0160 {
0161 const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
0162
0163 if (!encoder_funcs)
0164 return;
0165
0166 if (encoder_funcs->disable)
0167 (*encoder_funcs->disable)(encoder);
0168 else if (encoder_funcs->dpms)
0169 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
0170 }
0171
0172 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
0173 {
0174 struct drm_encoder *encoder;
0175 struct drm_crtc *crtc;
0176
0177 drm_warn_on_modeset_not_all_locked(dev);
0178
0179 drm_for_each_encoder(encoder, dev) {
0180 if (!drm_helper_encoder_in_use(encoder)) {
0181 drm_encoder_disable(encoder);
0182
0183 encoder->crtc = NULL;
0184 }
0185 }
0186
0187 drm_for_each_crtc(crtc, dev) {
0188 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0189
0190 crtc->enabled = drm_helper_crtc_in_use(crtc);
0191 if (!crtc->enabled) {
0192 if (crtc_funcs->disable)
0193 (*crtc_funcs->disable)(crtc);
0194 else
0195 (*crtc_funcs->dpms)(crtc, DRM_MODE_DPMS_OFF);
0196 crtc->primary->fb = NULL;
0197 }
0198 }
0199 }
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220 void drm_helper_disable_unused_functions(struct drm_device *dev)
0221 {
0222 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0223
0224 drm_modeset_lock_all(dev);
0225 __drm_helper_disable_unused_functions(dev);
0226 drm_modeset_unlock_all(dev);
0227 }
0228 EXPORT_SYMBOL(drm_helper_disable_unused_functions);
0229
0230
0231
0232
0233
0234
0235 static void
0236 drm_crtc_prepare_encoders(struct drm_device *dev)
0237 {
0238 const struct drm_encoder_helper_funcs *encoder_funcs;
0239 struct drm_encoder *encoder;
0240
0241 drm_for_each_encoder(encoder, dev) {
0242 encoder_funcs = encoder->helper_private;
0243 if (!encoder_funcs)
0244 continue;
0245
0246
0247 if (encoder->crtc == NULL)
0248 drm_encoder_disable(encoder);
0249 }
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272 bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
0273 struct drm_display_mode *mode,
0274 int x, int y,
0275 struct drm_framebuffer *old_fb)
0276 {
0277 struct drm_device *dev = crtc->dev;
0278 struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
0279 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0280 const struct drm_encoder_helper_funcs *encoder_funcs;
0281 int saved_x, saved_y;
0282 bool saved_enabled;
0283 struct drm_encoder *encoder;
0284 bool ret = true;
0285
0286 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0287
0288 drm_warn_on_modeset_not_all_locked(dev);
0289
0290 saved_enabled = crtc->enabled;
0291 crtc->enabled = drm_helper_crtc_in_use(crtc);
0292 if (!crtc->enabled)
0293 return true;
0294
0295 adjusted_mode = drm_mode_duplicate(dev, mode);
0296 if (!adjusted_mode) {
0297 crtc->enabled = saved_enabled;
0298 return false;
0299 }
0300
0301 drm_mode_init(&saved_mode, &crtc->mode);
0302 drm_mode_init(&saved_hwmode, &crtc->hwmode);
0303 saved_x = crtc->x;
0304 saved_y = crtc->y;
0305
0306
0307
0308
0309 drm_mode_copy(&crtc->mode, mode);
0310 crtc->x = x;
0311 crtc->y = y;
0312
0313
0314
0315
0316
0317 drm_for_each_encoder(encoder, dev) {
0318
0319 if (encoder->crtc != crtc)
0320 continue;
0321
0322 encoder_funcs = encoder->helper_private;
0323 if (!encoder_funcs)
0324 continue;
0325
0326 encoder_funcs = encoder->helper_private;
0327 if (encoder_funcs->mode_fixup) {
0328 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
0329 adjusted_mode))) {
0330 DRM_DEBUG_KMS("Encoder fixup failed\n");
0331 goto done;
0332 }
0333 }
0334 }
0335
0336 if (crtc_funcs->mode_fixup) {
0337 if (!(ret = crtc_funcs->mode_fixup(crtc, mode,
0338 adjusted_mode))) {
0339 DRM_DEBUG_KMS("CRTC fixup failed\n");
0340 goto done;
0341 }
0342 }
0343 DRM_DEBUG_KMS("[CRTC:%d:%s]\n", crtc->base.id, crtc->name);
0344
0345 drm_mode_copy(&crtc->hwmode, adjusted_mode);
0346
0347
0348 drm_for_each_encoder(encoder, dev) {
0349
0350 if (encoder->crtc != crtc)
0351 continue;
0352
0353 encoder_funcs = encoder->helper_private;
0354 if (!encoder_funcs)
0355 continue;
0356
0357
0358 if (encoder_funcs->prepare)
0359 encoder_funcs->prepare(encoder);
0360 }
0361
0362 drm_crtc_prepare_encoders(dev);
0363
0364 crtc_funcs->prepare(crtc);
0365
0366
0367
0368
0369 ret = !crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y, old_fb);
0370 if (!ret)
0371 goto done;
0372
0373 drm_for_each_encoder(encoder, dev) {
0374
0375 if (encoder->crtc != crtc)
0376 continue;
0377
0378 encoder_funcs = encoder->helper_private;
0379 if (!encoder_funcs)
0380 continue;
0381
0382 DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
0383 encoder->base.id, encoder->name, mode->name);
0384 if (encoder_funcs->mode_set)
0385 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
0386 }
0387
0388
0389 crtc_funcs->commit(crtc);
0390
0391 drm_for_each_encoder(encoder, dev) {
0392
0393 if (encoder->crtc != crtc)
0394 continue;
0395
0396 encoder_funcs = encoder->helper_private;
0397 if (!encoder_funcs)
0398 continue;
0399
0400 if (encoder_funcs->commit)
0401 encoder_funcs->commit(encoder);
0402 }
0403
0404
0405
0406
0407
0408 drm_calc_timestamping_constants(crtc, &crtc->hwmode);
0409
0410
0411 done:
0412 drm_mode_destroy(dev, adjusted_mode);
0413 if (!ret) {
0414 crtc->enabled = saved_enabled;
0415 drm_mode_copy(&crtc->mode, &saved_mode);
0416 drm_mode_copy(&crtc->hwmode, &saved_hwmode);
0417 crtc->x = saved_x;
0418 crtc->y = saved_y;
0419 }
0420
0421 return ret;
0422 }
0423 EXPORT_SYMBOL(drm_crtc_helper_set_mode);
0424
0425 static void
0426 drm_crtc_helper_disable(struct drm_crtc *crtc)
0427 {
0428 struct drm_device *dev = crtc->dev;
0429 struct drm_connector *connector;
0430 struct drm_encoder *encoder;
0431
0432
0433 drm_for_each_encoder(encoder, dev) {
0434 struct drm_connector_list_iter conn_iter;
0435
0436 if (encoder->crtc != crtc)
0437 continue;
0438
0439 drm_connector_list_iter_begin(dev, &conn_iter);
0440 drm_for_each_connector_iter(connector, &conn_iter) {
0441 if (connector->encoder != encoder)
0442 continue;
0443
0444 connector->encoder = NULL;
0445
0446
0447
0448
0449
0450
0451
0452 connector->dpms = DRM_MODE_DPMS_OFF;
0453
0454
0455 drm_connector_put(connector);
0456 }
0457 drm_connector_list_iter_end(&conn_iter);
0458 }
0459
0460 __drm_helper_disable_unused_functions(dev);
0461 }
0462
0463
0464
0465
0466
0467 struct drm_encoder *
0468 drm_connector_get_single_encoder(struct drm_connector *connector)
0469 {
0470 struct drm_encoder *encoder;
0471
0472 WARN_ON(hweight32(connector->possible_encoders) > 1);
0473 drm_connector_for_each_possible_encoder(connector, encoder)
0474 return encoder;
0475
0476 return NULL;
0477 }
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 int drm_crtc_helper_set_config(struct drm_mode_set *set,
0518 struct drm_modeset_acquire_ctx *ctx)
0519 {
0520 struct drm_device *dev;
0521 struct drm_crtc **save_encoder_crtcs, *new_crtc;
0522 struct drm_encoder **save_connector_encoders, *new_encoder, *encoder;
0523 bool mode_changed = false;
0524 bool fb_changed = false;
0525 struct drm_connector *connector;
0526 struct drm_connector_list_iter conn_iter;
0527 int count = 0, ro, fail = 0;
0528 const struct drm_crtc_helper_funcs *crtc_funcs;
0529 struct drm_mode_set save_set;
0530 int ret;
0531 int i;
0532
0533 DRM_DEBUG_KMS("\n");
0534
0535 BUG_ON(!set);
0536 BUG_ON(!set->crtc);
0537 BUG_ON(!set->crtc->helper_private);
0538
0539
0540 BUG_ON(!set->mode && set->fb);
0541 BUG_ON(set->fb && set->num_connectors == 0);
0542
0543 crtc_funcs = set->crtc->helper_private;
0544
0545 dev = set->crtc->dev;
0546 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0547
0548 if (!set->mode)
0549 set->fb = NULL;
0550
0551 if (set->fb) {
0552 DRM_DEBUG_KMS("[CRTC:%d:%s] [FB:%d] #connectors=%d (x y) (%i %i)\n",
0553 set->crtc->base.id, set->crtc->name,
0554 set->fb->base.id,
0555 (int)set->num_connectors, set->x, set->y);
0556 } else {
0557 DRM_DEBUG_KMS("[CRTC:%d:%s] [NOFB]\n",
0558 set->crtc->base.id, set->crtc->name);
0559 drm_crtc_helper_disable(set->crtc);
0560 return 0;
0561 }
0562
0563 drm_warn_on_modeset_not_all_locked(dev);
0564
0565
0566
0567
0568
0569 save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder,
0570 sizeof(struct drm_crtc *), GFP_KERNEL);
0571 if (!save_encoder_crtcs)
0572 return -ENOMEM;
0573
0574 save_connector_encoders = kcalloc(dev->mode_config.num_connector,
0575 sizeof(struct drm_encoder *), GFP_KERNEL);
0576 if (!save_connector_encoders) {
0577 kfree(save_encoder_crtcs);
0578 return -ENOMEM;
0579 }
0580
0581
0582
0583
0584
0585
0586 count = 0;
0587 drm_for_each_encoder(encoder, dev) {
0588 save_encoder_crtcs[count++] = encoder->crtc;
0589 }
0590
0591 count = 0;
0592 drm_connector_list_iter_begin(dev, &conn_iter);
0593 drm_for_each_connector_iter(connector, &conn_iter)
0594 save_connector_encoders[count++] = connector->encoder;
0595 drm_connector_list_iter_end(&conn_iter);
0596
0597 save_set.crtc = set->crtc;
0598 save_set.mode = &set->crtc->mode;
0599 save_set.x = set->crtc->x;
0600 save_set.y = set->crtc->y;
0601 save_set.fb = set->crtc->primary->fb;
0602
0603
0604
0605 if (set->crtc->primary->fb != set->fb) {
0606
0607 if (set->crtc->primary->fb == NULL) {
0608 DRM_DEBUG_KMS("crtc has no fb, full mode set\n");
0609 mode_changed = true;
0610 } else if (set->fb->format != set->crtc->primary->fb->format) {
0611 mode_changed = true;
0612 } else
0613 fb_changed = true;
0614 }
0615
0616 if (set->x != set->crtc->x || set->y != set->crtc->y)
0617 fb_changed = true;
0618
0619 if (!drm_mode_equal(set->mode, &set->crtc->mode)) {
0620 DRM_DEBUG_KMS("modes are different, full mode set\n");
0621 drm_mode_debug_printmodeline(&set->crtc->mode);
0622 drm_mode_debug_printmodeline(set->mode);
0623 mode_changed = true;
0624 }
0625
0626
0627
0628
0629 for (ro = 0; ro < set->num_connectors; ro++) {
0630 if (set->connectors[ro]->encoder)
0631 continue;
0632 drm_connector_get(set->connectors[ro]);
0633 }
0634
0635
0636 count = 0;
0637 drm_connector_list_iter_begin(dev, &conn_iter);
0638 drm_for_each_connector_iter(connector, &conn_iter) {
0639 const struct drm_connector_helper_funcs *connector_funcs =
0640 connector->helper_private;
0641 new_encoder = connector->encoder;
0642 for (ro = 0; ro < set->num_connectors; ro++) {
0643 if (set->connectors[ro] == connector) {
0644 if (connector_funcs->best_encoder)
0645 new_encoder = connector_funcs->best_encoder(connector);
0646 else
0647 new_encoder = drm_connector_get_single_encoder(connector);
0648
0649
0650
0651 if (new_encoder == NULL)
0652
0653 fail = 1;
0654
0655 if (connector->dpms != DRM_MODE_DPMS_ON) {
0656 DRM_DEBUG_KMS("connector dpms not on, full mode switch\n");
0657 mode_changed = true;
0658 }
0659
0660 break;
0661 }
0662 }
0663
0664 if (new_encoder != connector->encoder) {
0665 DRM_DEBUG_KMS("encoder changed, full mode switch\n");
0666 mode_changed = true;
0667
0668
0669
0670 if (connector->encoder)
0671 connector->encoder->crtc = NULL;
0672 connector->encoder = new_encoder;
0673 }
0674 }
0675 drm_connector_list_iter_end(&conn_iter);
0676
0677 if (fail) {
0678 ret = -EINVAL;
0679 goto fail;
0680 }
0681
0682 count = 0;
0683 drm_connector_list_iter_begin(dev, &conn_iter);
0684 drm_for_each_connector_iter(connector, &conn_iter) {
0685 if (!connector->encoder)
0686 continue;
0687
0688 if (connector->encoder->crtc == set->crtc)
0689 new_crtc = NULL;
0690 else
0691 new_crtc = connector->encoder->crtc;
0692
0693 for (ro = 0; ro < set->num_connectors; ro++) {
0694 if (set->connectors[ro] == connector)
0695 new_crtc = set->crtc;
0696 }
0697
0698
0699 if (new_crtc &&
0700 !drm_encoder_crtc_ok(connector->encoder, new_crtc)) {
0701 ret = -EINVAL;
0702 drm_connector_list_iter_end(&conn_iter);
0703 goto fail;
0704 }
0705 if (new_crtc != connector->encoder->crtc) {
0706 DRM_DEBUG_KMS("crtc changed, full mode switch\n");
0707 mode_changed = true;
0708 connector->encoder->crtc = new_crtc;
0709 }
0710 if (new_crtc) {
0711 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d:%s]\n",
0712 connector->base.id, connector->name,
0713 new_crtc->base.id, new_crtc->name);
0714 } else {
0715 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n",
0716 connector->base.id, connector->name);
0717 }
0718 }
0719 drm_connector_list_iter_end(&conn_iter);
0720
0721
0722 if (fb_changed && !crtc_funcs->mode_set_base)
0723 mode_changed = true;
0724
0725 if (mode_changed) {
0726 if (drm_helper_crtc_in_use(set->crtc)) {
0727 DRM_DEBUG_KMS("attempting to set mode from"
0728 " userspace\n");
0729 drm_mode_debug_printmodeline(set->mode);
0730 set->crtc->primary->fb = set->fb;
0731 if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
0732 set->x, set->y,
0733 save_set.fb)) {
0734 DRM_ERROR("failed to set mode on [CRTC:%d:%s]\n",
0735 set->crtc->base.id, set->crtc->name);
0736 set->crtc->primary->fb = save_set.fb;
0737 ret = -EINVAL;
0738 goto fail;
0739 }
0740 DRM_DEBUG_KMS("Setting connector DPMS state to on\n");
0741 for (i = 0; i < set->num_connectors; i++) {
0742 DRM_DEBUG_KMS("\t[CONNECTOR:%d:%s] set DPMS on\n", set->connectors[i]->base.id,
0743 set->connectors[i]->name);
0744 set->connectors[i]->funcs->dpms(set->connectors[i], DRM_MODE_DPMS_ON);
0745 }
0746 }
0747 __drm_helper_disable_unused_functions(dev);
0748 } else if (fb_changed) {
0749 set->crtc->x = set->x;
0750 set->crtc->y = set->y;
0751 set->crtc->primary->fb = set->fb;
0752 ret = crtc_funcs->mode_set_base(set->crtc,
0753 set->x, set->y, save_set.fb);
0754 if (ret != 0) {
0755 set->crtc->x = save_set.x;
0756 set->crtc->y = save_set.y;
0757 set->crtc->primary->fb = save_set.fb;
0758 goto fail;
0759 }
0760 }
0761
0762 kfree(save_connector_encoders);
0763 kfree(save_encoder_crtcs);
0764 return 0;
0765
0766 fail:
0767
0768 count = 0;
0769 drm_for_each_encoder(encoder, dev) {
0770 encoder->crtc = save_encoder_crtcs[count++];
0771 }
0772
0773 count = 0;
0774 drm_connector_list_iter_begin(dev, &conn_iter);
0775 drm_for_each_connector_iter(connector, &conn_iter)
0776 connector->encoder = save_connector_encoders[count++];
0777 drm_connector_list_iter_end(&conn_iter);
0778
0779
0780
0781
0782 for (ro = 0; ro < set->num_connectors; ro++) {
0783 if (set->connectors[ro]->encoder)
0784 continue;
0785 drm_connector_put(set->connectors[ro]);
0786 }
0787
0788
0789 if (mode_changed &&
0790 !drm_crtc_helper_set_mode(save_set.crtc, save_set.mode, save_set.x,
0791 save_set.y, save_set.fb))
0792 DRM_ERROR("failed to restore config after modeset failure\n");
0793
0794 kfree(save_connector_encoders);
0795 kfree(save_encoder_crtcs);
0796 return ret;
0797 }
0798 EXPORT_SYMBOL(drm_crtc_helper_set_config);
0799
0800 static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
0801 {
0802 int dpms = DRM_MODE_DPMS_OFF;
0803 struct drm_connector *connector;
0804 struct drm_connector_list_iter conn_iter;
0805 struct drm_device *dev = encoder->dev;
0806
0807 drm_connector_list_iter_begin(dev, &conn_iter);
0808 drm_for_each_connector_iter(connector, &conn_iter)
0809 if (connector->encoder == encoder)
0810 if (connector->dpms < dpms)
0811 dpms = connector->dpms;
0812 drm_connector_list_iter_end(&conn_iter);
0813
0814 return dpms;
0815 }
0816
0817
0818 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
0819 {
0820 const struct drm_encoder_helper_funcs *encoder_funcs;
0821
0822 encoder_funcs = encoder->helper_private;
0823 if (!encoder_funcs)
0824 return;
0825
0826 if (encoder_funcs->dpms)
0827 encoder_funcs->dpms(encoder, mode);
0828 }
0829
0830 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
0831 {
0832 int dpms = DRM_MODE_DPMS_OFF;
0833 struct drm_connector *connector;
0834 struct drm_connector_list_iter conn_iter;
0835 struct drm_device *dev = crtc->dev;
0836
0837 drm_connector_list_iter_begin(dev, &conn_iter);
0838 drm_for_each_connector_iter(connector, &conn_iter)
0839 if (connector->encoder && connector->encoder->crtc == crtc)
0840 if (connector->dpms < dpms)
0841 dpms = connector->dpms;
0842 drm_connector_list_iter_end(&conn_iter);
0843
0844 return dpms;
0845 }
0846
0847
0848
0849
0850
0851
0852
0853
0854
0855
0856
0857
0858
0859
0860
0861
0862
0863
0864
0865
0866
0867
0868 int drm_helper_connector_dpms(struct drm_connector *connector, int mode)
0869 {
0870 struct drm_encoder *encoder = connector->encoder;
0871 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
0872 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
0873
0874 WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
0875
0876 if (mode == connector->dpms)
0877 return 0;
0878
0879 old_dpms = connector->dpms;
0880 connector->dpms = mode;
0881
0882 if (encoder)
0883 encoder_dpms = drm_helper_choose_encoder_dpms(encoder);
0884
0885
0886 if (mode < old_dpms) {
0887 if (crtc) {
0888 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0889
0890 if (crtc_funcs->dpms)
0891 (*crtc_funcs->dpms) (crtc,
0892 drm_helper_choose_crtc_dpms(crtc));
0893 }
0894 if (encoder)
0895 drm_helper_encoder_dpms(encoder, encoder_dpms);
0896 }
0897
0898
0899 if (mode > old_dpms) {
0900 if (encoder)
0901 drm_helper_encoder_dpms(encoder, encoder_dpms);
0902 if (crtc) {
0903 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0904
0905 if (crtc_funcs->dpms)
0906 (*crtc_funcs->dpms) (crtc,
0907 drm_helper_choose_crtc_dpms(crtc));
0908 }
0909 }
0910
0911 return 0;
0912 }
0913 EXPORT_SYMBOL(drm_helper_connector_dpms);
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930
0931
0932
0933
0934
0935
0936
0937
0938
0939
0940
0941 void drm_helper_resume_force_mode(struct drm_device *dev)
0942 {
0943 struct drm_crtc *crtc;
0944 struct drm_encoder *encoder;
0945 const struct drm_crtc_helper_funcs *crtc_funcs;
0946 int encoder_dpms;
0947 bool ret;
0948
0949 WARN_ON(drm_drv_uses_atomic_modeset(dev));
0950
0951 drm_modeset_lock_all(dev);
0952 drm_for_each_crtc(crtc, dev) {
0953
0954 if (!crtc->enabled)
0955 continue;
0956
0957 ret = drm_crtc_helper_set_mode(crtc, &crtc->mode,
0958 crtc->x, crtc->y, crtc->primary->fb);
0959
0960
0961 if (ret == false)
0962 DRM_ERROR("failed to set mode on crtc %p\n", crtc);
0963
0964
0965 if (drm_helper_choose_crtc_dpms(crtc)) {
0966 drm_for_each_encoder(encoder, dev) {
0967
0968 if(encoder->crtc != crtc)
0969 continue;
0970
0971 encoder_dpms = drm_helper_choose_encoder_dpms(
0972 encoder);
0973
0974 drm_helper_encoder_dpms(encoder, encoder_dpms);
0975 }
0976
0977 crtc_funcs = crtc->helper_private;
0978 if (crtc_funcs->dpms)
0979 (*crtc_funcs->dpms) (crtc,
0980 drm_helper_choose_crtc_dpms(crtc));
0981 }
0982 }
0983
0984
0985 __drm_helper_disable_unused_functions(dev);
0986 drm_modeset_unlock_all(dev);
0987 }
0988 EXPORT_SYMBOL(drm_helper_resume_force_mode);
0989
0990
0991
0992
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003 int 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 }
1019 out:
1020 drm_modeset_unlock_all(dev);
1021 return ret;
1022 }
1023 EXPORT_SYMBOL(drm_helper_force_disable_all);