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/moduleparam.h>
0034
0035 #include <drm/drm_bridge.h>
0036 #include <drm/drm_client.h>
0037 #include <drm/drm_crtc.h>
0038 #include <drm/drm_edid.h>
0039 #include <drm/drm_fb_helper.h>
0040 #include <drm/drm_fourcc.h>
0041 #include <drm/drm_modeset_helper_vtables.h>
0042 #include <drm/drm_print.h>
0043 #include <drm/drm_probe_helper.h>
0044 #include <drm/drm_sysfs.h>
0045
0046 #include "drm_crtc_helper_internal.h"
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 static bool drm_kms_helper_poll = true;
0068 module_param_named(poll, drm_kms_helper_poll, bool, 0600);
0069
0070 static enum drm_mode_status
0071 drm_mode_validate_flag(const struct drm_display_mode *mode,
0072 int flags)
0073 {
0074 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
0075 !(flags & DRM_MODE_FLAG_INTERLACE))
0076 return MODE_NO_INTERLACE;
0077
0078 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
0079 !(flags & DRM_MODE_FLAG_DBLSCAN))
0080 return MODE_NO_DBLESCAN;
0081
0082 if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
0083 !(flags & DRM_MODE_FLAG_3D_MASK))
0084 return MODE_NO_STEREO;
0085
0086 return MODE_OK;
0087 }
0088
0089 static int
0090 drm_mode_validate_pipeline(struct drm_display_mode *mode,
0091 struct drm_connector *connector,
0092 struct drm_modeset_acquire_ctx *ctx,
0093 enum drm_mode_status *status)
0094 {
0095 struct drm_device *dev = connector->dev;
0096 struct drm_encoder *encoder;
0097 int ret;
0098
0099
0100 ret = drm_connector_mode_valid(connector, mode, ctx, status);
0101 if (ret || *status != MODE_OK)
0102 return ret;
0103
0104
0105 drm_connector_for_each_possible_encoder(connector, encoder) {
0106 struct drm_bridge *bridge;
0107 struct drm_crtc *crtc;
0108
0109 *status = drm_encoder_mode_valid(encoder, mode);
0110 if (*status != MODE_OK) {
0111
0112
0113
0114
0115 continue;
0116 }
0117
0118 bridge = drm_bridge_chain_get_first_bridge(encoder);
0119 *status = drm_bridge_chain_mode_valid(bridge,
0120 &connector->display_info,
0121 mode);
0122 if (*status != MODE_OK) {
0123
0124
0125 continue;
0126 }
0127
0128 drm_for_each_crtc(crtc, dev) {
0129 if (!drm_encoder_crtc_ok(encoder, crtc))
0130 continue;
0131
0132 *status = drm_crtc_mode_valid(crtc, mode);
0133 if (*status == MODE_OK) {
0134
0135
0136
0137 return 0;
0138 }
0139 }
0140 }
0141
0142 return 0;
0143 }
0144
0145 static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
0146 {
0147 struct drm_cmdline_mode *cmdline_mode;
0148 struct drm_display_mode *mode;
0149
0150 cmdline_mode = &connector->cmdline_mode;
0151 if (!cmdline_mode->specified)
0152 return 0;
0153
0154
0155 list_for_each_entry(mode, &connector->probed_modes, head) {
0156 if (mode->hdisplay != cmdline_mode->xres ||
0157 mode->vdisplay != cmdline_mode->yres)
0158 continue;
0159
0160 if (cmdline_mode->refresh_specified) {
0161
0162 if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
0163 continue;
0164 }
0165
0166
0167 mode->type |= DRM_MODE_TYPE_USERDEF;
0168 return 0;
0169 }
0170
0171 mode = drm_mode_create_from_cmdline_mode(connector->dev,
0172 cmdline_mode);
0173 if (mode == NULL)
0174 return 0;
0175
0176 drm_mode_probed_add(connector, mode);
0177 return 1;
0178 }
0179
0180 enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
0181 const struct drm_display_mode *mode)
0182 {
0183 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
0184
0185 if (!crtc_funcs || !crtc_funcs->mode_valid)
0186 return MODE_OK;
0187
0188 return crtc_funcs->mode_valid(crtc, mode);
0189 }
0190
0191 enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
0192 const struct drm_display_mode *mode)
0193 {
0194 const struct drm_encoder_helper_funcs *encoder_funcs =
0195 encoder->helper_private;
0196
0197 if (!encoder_funcs || !encoder_funcs->mode_valid)
0198 return MODE_OK;
0199
0200 return encoder_funcs->mode_valid(encoder, mode);
0201 }
0202
0203 int
0204 drm_connector_mode_valid(struct drm_connector *connector,
0205 struct drm_display_mode *mode,
0206 struct drm_modeset_acquire_ctx *ctx,
0207 enum drm_mode_status *status)
0208 {
0209 const struct drm_connector_helper_funcs *connector_funcs =
0210 connector->helper_private;
0211 int ret = 0;
0212
0213 if (!connector_funcs)
0214 *status = MODE_OK;
0215 else if (connector_funcs->mode_valid_ctx)
0216 ret = connector_funcs->mode_valid_ctx(connector, mode, ctx,
0217 status);
0218 else if (connector_funcs->mode_valid)
0219 *status = connector_funcs->mode_valid(connector, mode);
0220 else
0221 *status = MODE_OK;
0222
0223 return ret;
0224 }
0225
0226 #define DRM_OUTPUT_POLL_PERIOD (10*HZ)
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 void drm_kms_helper_poll_enable(struct drm_device *dev)
0243 {
0244 bool poll = false;
0245 struct drm_connector *connector;
0246 struct drm_connector_list_iter conn_iter;
0247 unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
0248
0249 if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
0250 return;
0251
0252 drm_connector_list_iter_begin(dev, &conn_iter);
0253 drm_for_each_connector_iter(connector, &conn_iter) {
0254 if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
0255 DRM_CONNECTOR_POLL_DISCONNECT))
0256 poll = true;
0257 }
0258 drm_connector_list_iter_end(&conn_iter);
0259
0260 if (dev->mode_config.delayed_event) {
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 poll = true;
0272 delay = HZ;
0273 }
0274
0275 if (poll)
0276 schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
0277 }
0278 EXPORT_SYMBOL(drm_kms_helper_poll_enable);
0279
0280 static enum drm_connector_status
0281 drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
0282 {
0283 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
0284 struct drm_modeset_acquire_ctx ctx;
0285 int ret;
0286
0287 drm_modeset_acquire_init(&ctx, 0);
0288
0289 retry:
0290 ret = drm_modeset_lock(&connector->dev->mode_config.connection_mutex, &ctx);
0291 if (!ret) {
0292 if (funcs->detect_ctx)
0293 ret = funcs->detect_ctx(connector, &ctx, force);
0294 else if (connector->funcs->detect)
0295 ret = connector->funcs->detect(connector, force);
0296 else
0297 ret = connector_status_connected;
0298 }
0299
0300 if (ret == -EDEADLK) {
0301 drm_modeset_backoff(&ctx);
0302 goto retry;
0303 }
0304
0305 if (WARN_ON(ret < 0))
0306 ret = connector_status_unknown;
0307
0308 if (ret != connector->status)
0309 connector->epoch_counter += 1;
0310
0311 drm_modeset_drop_locks(&ctx);
0312 drm_modeset_acquire_fini(&ctx);
0313
0314 return ret;
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 int
0328 drm_helper_probe_detect(struct drm_connector *connector,
0329 struct drm_modeset_acquire_ctx *ctx,
0330 bool force)
0331 {
0332 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
0333 struct drm_device *dev = connector->dev;
0334 int ret;
0335
0336 if (!ctx)
0337 return drm_helper_probe_detect_ctx(connector, force);
0338
0339 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
0340 if (ret)
0341 return ret;
0342
0343 if (funcs->detect_ctx)
0344 ret = funcs->detect_ctx(connector, ctx, force);
0345 else if (connector->funcs->detect)
0346 ret = connector->funcs->detect(connector, force);
0347 else
0348 ret = connector_status_connected;
0349
0350 if (ret != connector->status)
0351 connector->epoch_counter += 1;
0352
0353 return ret;
0354 }
0355 EXPORT_SYMBOL(drm_helper_probe_detect);
0356
0357 static int drm_helper_probe_get_modes(struct drm_connector *connector)
0358 {
0359 const struct drm_connector_helper_funcs *connector_funcs =
0360 connector->helper_private;
0361 int count;
0362
0363 count = connector_funcs->get_modes(connector);
0364
0365
0366
0367
0368
0369 if (count == 0 && connector->status == connector_status_connected)
0370 count = drm_add_override_edid_modes(connector);
0371
0372 return count;
0373 }
0374
0375 static int __drm_helper_update_and_validate(struct drm_connector *connector,
0376 uint32_t maxX, uint32_t maxY,
0377 struct drm_modeset_acquire_ctx *ctx)
0378 {
0379 struct drm_device *dev = connector->dev;
0380 struct drm_display_mode *mode;
0381 int mode_flags = 0;
0382 int ret;
0383
0384 drm_connector_list_update(connector);
0385
0386 if (connector->interlace_allowed)
0387 mode_flags |= DRM_MODE_FLAG_INTERLACE;
0388 if (connector->doublescan_allowed)
0389 mode_flags |= DRM_MODE_FLAG_DBLSCAN;
0390 if (connector->stereo_allowed)
0391 mode_flags |= DRM_MODE_FLAG_3D_MASK;
0392
0393 list_for_each_entry(mode, &connector->modes, head) {
0394 if (mode->status != MODE_OK)
0395 continue;
0396
0397 mode->status = drm_mode_validate_driver(dev, mode);
0398 if (mode->status != MODE_OK)
0399 continue;
0400
0401 mode->status = drm_mode_validate_size(mode, maxX, maxY);
0402 if (mode->status != MODE_OK)
0403 continue;
0404
0405 mode->status = drm_mode_validate_flag(mode, mode_flags);
0406 if (mode->status != MODE_OK)
0407 continue;
0408
0409 ret = drm_mode_validate_pipeline(mode, connector, ctx,
0410 &mode->status);
0411 if (ret) {
0412 drm_dbg_kms(dev,
0413 "drm_mode_validate_pipeline failed: %d\n",
0414 ret);
0415
0416 if (drm_WARN_ON_ONCE(dev, ret != -EDEADLK))
0417 mode->status = MODE_ERROR;
0418 else
0419 return -EDEADLK;
0420 }
0421
0422 if (mode->status != MODE_OK)
0423 continue;
0424 mode->status = drm_mode_validate_ycbcr420(mode, connector);
0425 }
0426
0427 return 0;
0428 }
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489 int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
0490 uint32_t maxX, uint32_t maxY)
0491 {
0492 struct drm_device *dev = connector->dev;
0493 struct drm_display_mode *mode;
0494 int count = 0, ret;
0495 enum drm_connector_status old_status;
0496 struct drm_modeset_acquire_ctx ctx;
0497
0498 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
0499
0500 drm_modeset_acquire_init(&ctx, 0);
0501
0502 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
0503 connector->name);
0504
0505 retry:
0506 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
0507 if (ret == -EDEADLK) {
0508 drm_modeset_backoff(&ctx);
0509 goto retry;
0510 } else
0511 WARN_ON(ret < 0);
0512
0513
0514 list_for_each_entry(mode, &connector->modes, head)
0515 mode->status = MODE_STALE;
0516
0517 old_status = connector->status;
0518
0519 if (connector->force) {
0520 if (connector->force == DRM_FORCE_ON ||
0521 connector->force == DRM_FORCE_ON_DIGITAL)
0522 connector->status = connector_status_connected;
0523 else
0524 connector->status = connector_status_disconnected;
0525 if (connector->funcs->force)
0526 connector->funcs->force(connector);
0527 } else {
0528 ret = drm_helper_probe_detect(connector, &ctx, true);
0529
0530 if (ret == -EDEADLK) {
0531 drm_modeset_backoff(&ctx);
0532 goto retry;
0533 } else if (WARN(ret < 0, "Invalid return value %i for connector detection\n", ret))
0534 ret = connector_status_unknown;
0535
0536 connector->status = ret;
0537 }
0538
0539
0540
0541
0542
0543
0544
0545 if (old_status != connector->status) {
0546 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
0547 connector->base.id,
0548 connector->name,
0549 drm_get_connector_status_name(old_status),
0550 drm_get_connector_status_name(connector->status));
0551
0552
0553
0554
0555
0556
0557
0558 dev->mode_config.delayed_event = true;
0559 if (dev->mode_config.poll_enabled)
0560 schedule_delayed_work(&dev->mode_config.output_poll_work,
0561 0);
0562 }
0563
0564
0565 if (drm_kms_helper_poll != dev->mode_config.poll_running)
0566 drm_kms_helper_poll_enable(dev);
0567
0568 dev->mode_config.poll_running = drm_kms_helper_poll;
0569
0570 if (connector->status == connector_status_disconnected) {
0571 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
0572 connector->base.id, connector->name);
0573 drm_connector_update_edid_property(connector, NULL);
0574 drm_mode_prune_invalid(dev, &connector->modes, false);
0575 goto exit;
0576 }
0577
0578 count = drm_helper_probe_get_modes(connector);
0579
0580 if (count == 0 && (connector->status == connector_status_connected ||
0581 connector->status == connector_status_unknown)) {
0582 count = drm_add_modes_noedid(connector, 1024, 768);
0583
0584
0585
0586
0587
0588
0589 if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)
0590 drm_set_preferred_mode(connector, 640, 480);
0591 }
0592 count += drm_helper_probe_add_cmdline_mode(connector);
0593 if (count != 0) {
0594 ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);
0595 if (ret == -EDEADLK) {
0596 drm_modeset_backoff(&ctx);
0597 goto retry;
0598 }
0599 }
0600
0601 drm_mode_prune_invalid(dev, &connector->modes, true);
0602
0603
0604
0605
0606
0607
0608
0609
0610 if (list_empty(&connector->modes) &&
0611 connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
0612 count = drm_add_modes_noedid(connector, 640, 480);
0613 ret = __drm_helper_update_and_validate(connector, maxX, maxY, &ctx);
0614 if (ret == -EDEADLK) {
0615 drm_modeset_backoff(&ctx);
0616 goto retry;
0617 }
0618 drm_mode_prune_invalid(dev, &connector->modes, true);
0619 }
0620
0621 exit:
0622 drm_modeset_drop_locks(&ctx);
0623 drm_modeset_acquire_fini(&ctx);
0624
0625 if (list_empty(&connector->modes))
0626 return 0;
0627
0628 drm_mode_sort(&connector->modes);
0629
0630 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
0631 connector->name);
0632 list_for_each_entry(mode, &connector->modes, head) {
0633 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
0634 drm_mode_debug_printmodeline(mode);
0635 }
0636
0637 return count;
0638 }
0639 EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
0640
0641
0642
0643
0644
0645
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660 void drm_kms_helper_hotplug_event(struct drm_device *dev)
0661 {
0662
0663 drm_sysfs_hotplug_event(dev);
0664 if (dev->mode_config.funcs->output_poll_changed)
0665 dev->mode_config.funcs->output_poll_changed(dev);
0666
0667 drm_client_dev_hotplug(dev);
0668 }
0669 EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
0670
0671
0672
0673
0674
0675
0676
0677
0678 void drm_kms_helper_connector_hotplug_event(struct drm_connector *connector)
0679 {
0680 struct drm_device *dev = connector->dev;
0681
0682
0683 drm_sysfs_connector_hotplug_event(connector);
0684 if (dev->mode_config.funcs->output_poll_changed)
0685 dev->mode_config.funcs->output_poll_changed(dev);
0686
0687 drm_client_dev_hotplug(dev);
0688 }
0689 EXPORT_SYMBOL(drm_kms_helper_connector_hotplug_event);
0690
0691 static void output_poll_execute(struct work_struct *work)
0692 {
0693 struct delayed_work *delayed_work = to_delayed_work(work);
0694 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
0695 struct drm_connector *connector;
0696 struct drm_connector_list_iter conn_iter;
0697 enum drm_connector_status old_status;
0698 bool repoll = false, changed;
0699 u64 old_epoch_counter;
0700
0701 if (!dev->mode_config.poll_enabled)
0702 return;
0703
0704
0705 changed = dev->mode_config.delayed_event;
0706 dev->mode_config.delayed_event = false;
0707
0708 if (!drm_kms_helper_poll)
0709 goto out;
0710
0711 if (!mutex_trylock(&dev->mode_config.mutex)) {
0712 repoll = true;
0713 goto out;
0714 }
0715
0716 drm_connector_list_iter_begin(dev, &conn_iter);
0717 drm_for_each_connector_iter(connector, &conn_iter) {
0718
0719 if (connector->force)
0720 continue;
0721
0722
0723
0724 if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
0725 continue;
0726
0727 old_status = connector->status;
0728
0729
0730 if (old_status == connector_status_connected &&
0731 !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
0732 continue;
0733
0734 repoll = true;
0735
0736 old_epoch_counter = connector->epoch_counter;
0737 connector->status = drm_helper_probe_detect(connector, NULL, false);
0738 if (old_epoch_counter != connector->epoch_counter) {
0739 const char *old, *new;
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754 if (connector->status == connector_status_unknown) {
0755 connector->status = old_status;
0756 continue;
0757 }
0758
0759 old = drm_get_connector_status_name(old_status);
0760 new = drm_get_connector_status_name(connector->status);
0761
0762 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
0763 "status updated from %s to %s\n",
0764 connector->base.id,
0765 connector->name,
0766 old, new);
0767 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] epoch counter %llu -> %llu\n",
0768 connector->base.id, connector->name,
0769 old_epoch_counter, connector->epoch_counter);
0770
0771 changed = true;
0772 }
0773 }
0774 drm_connector_list_iter_end(&conn_iter);
0775
0776 mutex_unlock(&dev->mode_config.mutex);
0777
0778 out:
0779 if (changed)
0780 drm_kms_helper_hotplug_event(dev);
0781
0782 if (repoll)
0783 schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
0784 }
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796
0797
0798 bool drm_kms_helper_is_poll_worker(void)
0799 {
0800 struct work_struct *work = current_work();
0801
0802 return work && work->func == output_poll_execute;
0803 }
0804 EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
0805
0806
0807
0808
0809
0810
0811
0812
0813
0814
0815
0816
0817
0818
0819
0820 void drm_kms_helper_poll_disable(struct drm_device *dev)
0821 {
0822 if (!dev->mode_config.poll_enabled)
0823 return;
0824 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
0825 }
0826 EXPORT_SYMBOL(drm_kms_helper_poll_disable);
0827
0828
0829
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847 void drm_kms_helper_poll_init(struct drm_device *dev)
0848 {
0849 INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
0850 dev->mode_config.poll_enabled = true;
0851
0852 drm_kms_helper_poll_enable(dev);
0853 }
0854 EXPORT_SYMBOL(drm_kms_helper_poll_init);
0855
0856
0857
0858
0859
0860 void drm_kms_helper_poll_fini(struct drm_device *dev)
0861 {
0862 if (!dev->mode_config.poll_enabled)
0863 return;
0864
0865 dev->mode_config.poll_enabled = false;
0866 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
0867 }
0868 EXPORT_SYMBOL(drm_kms_helper_poll_fini);
0869
0870 static bool check_connector_changed(struct drm_connector *connector)
0871 {
0872 struct drm_device *dev = connector->dev;
0873 enum drm_connector_status old_status;
0874 u64 old_epoch_counter;
0875
0876
0877 drm_WARN_ON(dev, !(connector->polled & DRM_CONNECTOR_POLL_HPD));
0878
0879 drm_WARN_ON(dev, !mutex_is_locked(&dev->mode_config.mutex));
0880
0881 old_status = connector->status;
0882 old_epoch_counter = connector->epoch_counter;
0883 connector->status = drm_helper_probe_detect(connector, NULL, false);
0884
0885 if (old_epoch_counter == connector->epoch_counter) {
0886 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Same epoch counter %llu\n",
0887 connector->base.id,
0888 connector->name,
0889 connector->epoch_counter);
0890
0891 return false;
0892 }
0893
0894 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] status updated from %s to %s\n",
0895 connector->base.id,
0896 connector->name,
0897 drm_get_connector_status_name(old_status),
0898 drm_get_connector_status_name(connector->status));
0899
0900 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Changed epoch counter %llu => %llu\n",
0901 connector->base.id,
0902 connector->name,
0903 old_epoch_counter,
0904 connector->epoch_counter);
0905
0906 return true;
0907 }
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922
0923
0924
0925
0926
0927
0928
0929
0930 bool drm_connector_helper_hpd_irq_event(struct drm_connector *connector)
0931 {
0932 struct drm_device *dev = connector->dev;
0933 bool changed;
0934
0935 mutex_lock(&dev->mode_config.mutex);
0936 changed = check_connector_changed(connector);
0937 mutex_unlock(&dev->mode_config.mutex);
0938
0939 if (changed) {
0940 drm_kms_helper_connector_hotplug_event(connector);
0941 drm_dbg_kms(dev, "[CONNECTOR:%d:%s] Sent hotplug event\n",
0942 connector->base.id,
0943 connector->name);
0944 }
0945
0946 return changed;
0947 }
0948 EXPORT_SYMBOL(drm_connector_helper_hpd_irq_event);
0949
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963
0964
0965
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977 bool drm_helper_hpd_irq_event(struct drm_device *dev)
0978 {
0979 struct drm_connector *connector, *first_changed_connector = NULL;
0980 struct drm_connector_list_iter conn_iter;
0981 int changed = 0;
0982
0983 if (!dev->mode_config.poll_enabled)
0984 return false;
0985
0986 mutex_lock(&dev->mode_config.mutex);
0987 drm_connector_list_iter_begin(dev, &conn_iter);
0988 drm_for_each_connector_iter(connector, &conn_iter) {
0989
0990 if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
0991 continue;
0992
0993 if (check_connector_changed(connector)) {
0994 if (!first_changed_connector) {
0995 drm_connector_get(connector);
0996 first_changed_connector = connector;
0997 }
0998
0999 changed++;
1000 }
1001 }
1002 drm_connector_list_iter_end(&conn_iter);
1003 mutex_unlock(&dev->mode_config.mutex);
1004
1005 if (changed == 1)
1006 drm_kms_helper_connector_hotplug_event(first_changed_connector);
1007 else if (changed > 0)
1008 drm_kms_helper_hotplug_event(dev);
1009
1010 if (first_changed_connector)
1011 drm_connector_put(first_changed_connector);
1012
1013 return changed;
1014 }
1015 EXPORT_SYMBOL(drm_helper_hpd_irq_event);
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 int drm_connector_helper_get_modes_from_ddc(struct drm_connector *connector)
1032 {
1033 struct edid *edid;
1034 int count = 0;
1035
1036 if (!connector->ddc)
1037 return 0;
1038
1039 edid = drm_get_edid(connector, connector->ddc);
1040
1041
1042 drm_connector_update_edid_property(connector, edid);
1043
1044 if (edid) {
1045 count = drm_add_edid_modes(connector, edid);
1046 kfree(edid);
1047 }
1048
1049 return count;
1050 }
1051 EXPORT_SYMBOL(drm_connector_helper_get_modes_from_ddc);
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066 int drm_connector_helper_get_modes(struct drm_connector *connector)
1067 {
1068 const struct drm_edid *drm_edid;
1069 int count;
1070
1071 drm_edid = drm_edid_read(connector);
1072
1073
1074
1075
1076
1077
1078
1079 count = drm_edid_connector_update(connector, drm_edid);
1080
1081 drm_edid_free(drm_edid);
1082
1083 return count;
1084 }
1085 EXPORT_SYMBOL(drm_connector_helper_get_modes);