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/moduleparam.h>
34
35#include <drm/drm_client.h>
36#include <drm/drm_crtc.h>
37#include <drm/drm_edid.h>
38#include <drm/drm_fb_helper.h>
39#include <drm/drm_fourcc.h>
40#include <drm/drm_modeset_helper_vtables.h>
41#include <drm/drm_print.h>
42#include <drm/drm_probe_helper.h>
43#include <drm/drm_sysfs.h>
44
45#include "drm_crtc_helper_internal.h"
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66static bool drm_kms_helper_poll = true;
67module_param_named(poll, drm_kms_helper_poll, bool, 0600);
68
69static enum drm_mode_status
70drm_mode_validate_flag(const struct drm_display_mode *mode,
71 int flags)
72{
73 if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
74 !(flags & DRM_MODE_FLAG_INTERLACE))
75 return MODE_NO_INTERLACE;
76
77 if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
78 !(flags & DRM_MODE_FLAG_DBLSCAN))
79 return MODE_NO_DBLESCAN;
80
81 if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
82 !(flags & DRM_MODE_FLAG_3D_MASK))
83 return MODE_NO_STEREO;
84
85 return MODE_OK;
86}
87
88static enum drm_mode_status
89drm_mode_validate_pipeline(struct drm_display_mode *mode,
90 struct drm_connector *connector)
91{
92 struct drm_device *dev = connector->dev;
93 enum drm_mode_status ret = MODE_OK;
94 struct drm_encoder *encoder;
95 int i;
96
97
98 ret = drm_connector_mode_valid(connector, mode);
99 if (ret != MODE_OK)
100 return ret;
101
102
103 drm_connector_for_each_possible_encoder(connector, encoder, i) {
104 struct drm_crtc *crtc;
105
106 ret = drm_encoder_mode_valid(encoder, mode);
107 if (ret != MODE_OK) {
108
109
110
111
112 continue;
113 }
114
115 ret = drm_bridge_mode_valid(encoder->bridge, mode);
116 if (ret != MODE_OK) {
117
118
119 continue;
120 }
121
122 drm_for_each_crtc(crtc, dev) {
123 if (!drm_encoder_crtc_ok(encoder, crtc))
124 continue;
125
126 ret = drm_crtc_mode_valid(crtc, mode);
127 if (ret == MODE_OK) {
128
129
130
131 return ret;
132 }
133 }
134 }
135
136 return ret;
137}
138
139static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
140{
141 struct drm_cmdline_mode *cmdline_mode;
142 struct drm_display_mode *mode;
143
144 cmdline_mode = &connector->cmdline_mode;
145 if (!cmdline_mode->specified)
146 return 0;
147
148
149 list_for_each_entry(mode, &connector->probed_modes, head) {
150 if (mode->hdisplay != cmdline_mode->xres ||
151 mode->vdisplay != cmdline_mode->yres)
152 continue;
153
154 if (cmdline_mode->refresh_specified) {
155
156 if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
157 continue;
158 }
159
160 return 0;
161 }
162
163 mode = drm_mode_create_from_cmdline_mode(connector->dev,
164 cmdline_mode);
165 if (mode == NULL)
166 return 0;
167
168 drm_mode_probed_add(connector, mode);
169 return 1;
170}
171
172enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
173 const struct drm_display_mode *mode)
174{
175 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
176
177 if (!crtc_funcs || !crtc_funcs->mode_valid)
178 return MODE_OK;
179
180 return crtc_funcs->mode_valid(crtc, mode);
181}
182
183enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
184 const struct drm_display_mode *mode)
185{
186 const struct drm_encoder_helper_funcs *encoder_funcs =
187 encoder->helper_private;
188
189 if (!encoder_funcs || !encoder_funcs->mode_valid)
190 return MODE_OK;
191
192 return encoder_funcs->mode_valid(encoder, mode);
193}
194
195enum drm_mode_status drm_connector_mode_valid(struct drm_connector *connector,
196 struct drm_display_mode *mode)
197{
198 const struct drm_connector_helper_funcs *connector_funcs =
199 connector->helper_private;
200
201 if (!connector_funcs || !connector_funcs->mode_valid)
202 return MODE_OK;
203
204 return connector_funcs->mode_valid(connector, mode);
205}
206
207#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223void drm_kms_helper_poll_enable(struct drm_device *dev)
224{
225 bool poll = false;
226 struct drm_connector *connector;
227 struct drm_connector_list_iter conn_iter;
228 unsigned long delay = DRM_OUTPUT_POLL_PERIOD;
229
230 if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
231 return;
232
233 drm_connector_list_iter_begin(dev, &conn_iter);
234 drm_for_each_connector_iter(connector, &conn_iter) {
235 if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
236 DRM_CONNECTOR_POLL_DISCONNECT))
237 poll = true;
238 }
239 drm_connector_list_iter_end(&conn_iter);
240
241 if (dev->mode_config.delayed_event) {
242
243
244
245
246
247
248
249
250
251
252 poll = true;
253 delay = HZ;
254 }
255
256 if (poll)
257 schedule_delayed_work(&dev->mode_config.output_poll_work, delay);
258}
259EXPORT_SYMBOL(drm_kms_helper_poll_enable);
260
261static enum drm_connector_status
262drm_helper_probe_detect_ctx(struct drm_connector *connector, bool force)
263{
264 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
265 struct drm_modeset_acquire_ctx ctx;
266 int ret;
267
268 drm_modeset_acquire_init(&ctx, 0);
269
270retry:
271 ret = drm_modeset_lock(&connector->dev->mode_config.connection_mutex, &ctx);
272 if (!ret) {
273 if (funcs->detect_ctx)
274 ret = funcs->detect_ctx(connector, &ctx, force);
275 else if (connector->funcs->detect)
276 ret = connector->funcs->detect(connector, force);
277 else
278 ret = connector_status_connected;
279 }
280
281 if (ret == -EDEADLK) {
282 drm_modeset_backoff(&ctx);
283 goto retry;
284 }
285
286 if (WARN_ON(ret < 0))
287 ret = connector_status_unknown;
288
289 drm_modeset_drop_locks(&ctx);
290 drm_modeset_acquire_fini(&ctx);
291
292 return ret;
293}
294
295
296
297
298
299
300
301
302
303
304
305int
306drm_helper_probe_detect(struct drm_connector *connector,
307 struct drm_modeset_acquire_ctx *ctx,
308 bool force)
309{
310 const struct drm_connector_helper_funcs *funcs = connector->helper_private;
311 struct drm_device *dev = connector->dev;
312 int ret;
313
314 if (!ctx)
315 return drm_helper_probe_detect_ctx(connector, force);
316
317 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, ctx);
318 if (ret)
319 return ret;
320
321 if (funcs->detect_ctx)
322 return funcs->detect_ctx(connector, ctx, force);
323 else if (connector->funcs->detect)
324 return connector->funcs->detect(connector, force);
325 else
326 return connector_status_connected;
327}
328EXPORT_SYMBOL(drm_helper_probe_detect);
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
389 uint32_t maxX, uint32_t maxY)
390{
391 struct drm_device *dev = connector->dev;
392 struct drm_display_mode *mode;
393 const struct drm_connector_helper_funcs *connector_funcs =
394 connector->helper_private;
395 int count = 0, ret;
396 int mode_flags = 0;
397 bool verbose_prune = true;
398 enum drm_connector_status old_status;
399 struct drm_modeset_acquire_ctx ctx;
400
401 WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
402
403 drm_modeset_acquire_init(&ctx, 0);
404
405 DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
406 connector->name);
407
408retry:
409 ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
410 if (ret == -EDEADLK) {
411 drm_modeset_backoff(&ctx);
412 goto retry;
413 } else
414 WARN_ON(ret < 0);
415
416
417 list_for_each_entry(mode, &connector->modes, head)
418 mode->status = MODE_STALE;
419
420 old_status = connector->status;
421
422 if (connector->force) {
423 if (connector->force == DRM_FORCE_ON ||
424 connector->force == DRM_FORCE_ON_DIGITAL)
425 connector->status = connector_status_connected;
426 else
427 connector->status = connector_status_disconnected;
428 if (connector->funcs->force)
429 connector->funcs->force(connector);
430 } else {
431 ret = drm_helper_probe_detect(connector, &ctx, true);
432
433 if (ret == -EDEADLK) {
434 drm_modeset_backoff(&ctx);
435 goto retry;
436 } else if (WARN(ret < 0, "Invalid return value %i for connector detection\n", ret))
437 ret = connector_status_unknown;
438
439 connector->status = ret;
440 }
441
442
443
444
445
446
447
448 if (old_status != connector->status) {
449 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
450 connector->base.id,
451 connector->name,
452 drm_get_connector_status_name(old_status),
453 drm_get_connector_status_name(connector->status));
454
455
456
457
458
459
460
461 dev->mode_config.delayed_event = true;
462 if (dev->mode_config.poll_enabled)
463 schedule_delayed_work(&dev->mode_config.output_poll_work,
464 0);
465 }
466
467
468 if (drm_kms_helper_poll != dev->mode_config.poll_running)
469 drm_kms_helper_poll_enable(dev);
470
471 dev->mode_config.poll_running = drm_kms_helper_poll;
472
473 if (connector->status == connector_status_disconnected) {
474 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
475 connector->base.id, connector->name);
476 drm_connector_update_edid_property(connector, NULL);
477 verbose_prune = false;
478 goto prune;
479 }
480
481 count = (*connector_funcs->get_modes)(connector);
482
483
484
485
486
487 if (count == 0 && connector->status == connector_status_connected)
488 count = drm_add_override_edid_modes(connector);
489
490 if (count == 0 && connector->status == connector_status_connected)
491 count = drm_add_modes_noedid(connector, 1024, 768);
492 count += drm_helper_probe_add_cmdline_mode(connector);
493 if (count == 0)
494 goto prune;
495
496 drm_connector_list_update(connector);
497
498 if (connector->interlace_allowed)
499 mode_flags |= DRM_MODE_FLAG_INTERLACE;
500 if (connector->doublescan_allowed)
501 mode_flags |= DRM_MODE_FLAG_DBLSCAN;
502 if (connector->stereo_allowed)
503 mode_flags |= DRM_MODE_FLAG_3D_MASK;
504
505 list_for_each_entry(mode, &connector->modes, head) {
506 if (mode->status == MODE_OK)
507 mode->status = drm_mode_validate_driver(dev, mode);
508
509 if (mode->status == MODE_OK)
510 mode->status = drm_mode_validate_size(mode, maxX, maxY);
511
512 if (mode->status == MODE_OK)
513 mode->status = drm_mode_validate_flag(mode, mode_flags);
514
515 if (mode->status == MODE_OK)
516 mode->status = drm_mode_validate_pipeline(mode,
517 connector);
518
519 if (mode->status == MODE_OK)
520 mode->status = drm_mode_validate_ycbcr420(mode,
521 connector);
522 }
523
524prune:
525 drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
526
527 drm_modeset_drop_locks(&ctx);
528 drm_modeset_acquire_fini(&ctx);
529
530 if (list_empty(&connector->modes))
531 return 0;
532
533 list_for_each_entry(mode, &connector->modes, head)
534 mode->vrefresh = drm_mode_vrefresh(mode);
535
536 drm_mode_sort(&connector->modes);
537
538 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
539 connector->name);
540 list_for_each_entry(mode, &connector->modes, head) {
541 drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
542 drm_mode_debug_printmodeline(mode);
543 }
544
545 return count;
546}
547EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565void drm_kms_helper_hotplug_event(struct drm_device *dev)
566{
567
568 drm_sysfs_hotplug_event(dev);
569 if (dev->mode_config.funcs->output_poll_changed)
570 dev->mode_config.funcs->output_poll_changed(dev);
571
572 drm_client_dev_hotplug(dev);
573}
574EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
575
576static void output_poll_execute(struct work_struct *work)
577{
578 struct delayed_work *delayed_work = to_delayed_work(work);
579 struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
580 struct drm_connector *connector;
581 struct drm_connector_list_iter conn_iter;
582 enum drm_connector_status old_status;
583 bool repoll = false, changed;
584
585 if (!dev->mode_config.poll_enabled)
586 return;
587
588
589 changed = dev->mode_config.delayed_event;
590 dev->mode_config.delayed_event = false;
591
592 if (!drm_kms_helper_poll)
593 goto out;
594
595 if (!mutex_trylock(&dev->mode_config.mutex)) {
596 repoll = true;
597 goto out;
598 }
599
600 drm_connector_list_iter_begin(dev, &conn_iter);
601 drm_for_each_connector_iter(connector, &conn_iter) {
602
603 if (connector->force)
604 continue;
605
606
607
608 if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
609 continue;
610
611 old_status = connector->status;
612
613
614 if (old_status == connector_status_connected &&
615 !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
616 continue;
617
618 repoll = true;
619
620 connector->status = drm_helper_probe_detect(connector, NULL, false);
621 if (old_status != connector->status) {
622 const char *old, *new;
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637 if (connector->status == connector_status_unknown) {
638 connector->status = old_status;
639 continue;
640 }
641
642 old = drm_get_connector_status_name(old_status);
643 new = drm_get_connector_status_name(connector->status);
644
645 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
646 "status updated from %s to %s\n",
647 connector->base.id,
648 connector->name,
649 old, new);
650
651 changed = true;
652 }
653 }
654 drm_connector_list_iter_end(&conn_iter);
655
656 mutex_unlock(&dev->mode_config.mutex);
657
658out:
659 if (changed)
660 drm_kms_helper_hotplug_event(dev);
661
662 if (repoll)
663 schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
664}
665
666
667
668
669
670
671
672
673
674
675
676
677
678bool drm_kms_helper_is_poll_worker(void)
679{
680 struct work_struct *work = current_work();
681
682 return work && work->func == output_poll_execute;
683}
684EXPORT_SYMBOL(drm_kms_helper_is_poll_worker);
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700void drm_kms_helper_poll_disable(struct drm_device *dev)
701{
702 if (!dev->mode_config.poll_enabled)
703 return;
704 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
705}
706EXPORT_SYMBOL(drm_kms_helper_poll_disable);
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727void drm_kms_helper_poll_init(struct drm_device *dev)
728{
729 INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
730 dev->mode_config.poll_enabled = true;
731
732 drm_kms_helper_poll_enable(dev);
733}
734EXPORT_SYMBOL(drm_kms_helper_poll_init);
735
736
737
738
739
740void drm_kms_helper_poll_fini(struct drm_device *dev)
741{
742 if (!dev->mode_config.poll_enabled)
743 return;
744
745 dev->mode_config.poll_enabled = false;
746 cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
747}
748EXPORT_SYMBOL(drm_kms_helper_poll_fini);
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773bool drm_helper_hpd_irq_event(struct drm_device *dev)
774{
775 struct drm_connector *connector;
776 struct drm_connector_list_iter conn_iter;
777 enum drm_connector_status old_status;
778 bool changed = false;
779
780 if (!dev->mode_config.poll_enabled)
781 return false;
782
783 mutex_lock(&dev->mode_config.mutex);
784 drm_connector_list_iter_begin(dev, &conn_iter);
785 drm_for_each_connector_iter(connector, &conn_iter) {
786
787 if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
788 continue;
789
790 old_status = connector->status;
791
792 connector->status = drm_helper_probe_detect(connector, NULL, false);
793 DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
794 connector->base.id,
795 connector->name,
796 drm_get_connector_status_name(old_status),
797 drm_get_connector_status_name(connector->status));
798 if (old_status != connector->status)
799 changed = true;
800 }
801 drm_connector_list_iter_end(&conn_iter);
802 mutex_unlock(&dev->mode_config.mutex);
803
804 if (changed)
805 drm_kms_helper_hotplug_event(dev);
806
807 return changed;
808}
809EXPORT_SYMBOL(drm_helper_hpd_irq_event);
810