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
33
34
35
36#include <drm/drmP.h>
37#include "drm_trace.h"
38
39#include <linux/interrupt.h>
40#include <linux/slab.h>
41
42#include <linux/vgaarb.h>
43#include <linux/export.h>
44
45
46#define vblanktimestamp(dev, crtc, count) \
47 ((dev)->vblank[crtc].time[(count) % DRM_VBLANKTIME_RBSIZE])
48
49
50
51
52#define DRM_TIMESTAMP_MAXRETRIES 3
53
54
55
56
57#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72int drm_irq_by_busid(struct drm_device *dev, void *data,
73 struct drm_file *file_priv)
74{
75 struct drm_irq_busid *p = data;
76
77 if (!dev->driver->bus->irq_by_busid)
78 return -EINVAL;
79
80 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
81 return -EINVAL;
82
83 return dev->driver->bus->irq_by_busid(dev, p);
84}
85
86
87
88
89static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
90{
91 memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time));
92}
93
94
95
96
97
98
99
100static void vblank_disable_and_save(struct drm_device *dev, int crtc)
101{
102 unsigned long irqflags;
103 u32 vblcount;
104 s64 diff_ns;
105 int vblrc;
106 struct timeval tvblank;
107 int count = DRM_TIMESTAMP_MAXRETRIES;
108
109
110
111
112
113 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
114
115 dev->driver->disable_vblank(dev, crtc);
116 dev->vblank[crtc].enabled = false;
117
118
119
120
121
122
123
124
125
126
127
128
129
130 do {
131 dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc);
132 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
133 } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
134
135 if (!count)
136 vblrc = 0;
137
138
139
140
141 vblcount = atomic_read(&dev->vblank[crtc].count);
142 diff_ns = timeval_to_ns(&tvblank) -
143 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
144
145
146
147
148
149
150
151
152
153
154
155
156
157 if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) {
158 atomic_inc(&dev->vblank[crtc].count);
159 smp_mb__after_atomic_inc();
160 }
161
162
163 clear_vblank_timestamps(dev, crtc);
164
165 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
166}
167
168static void vblank_disable_fn(unsigned long arg)
169{
170 struct drm_device *dev = (struct drm_device *)arg;
171 unsigned long irqflags;
172 int i;
173
174 if (!dev->vblank_disable_allowed)
175 return;
176
177 for (i = 0; i < dev->num_crtcs; i++) {
178 spin_lock_irqsave(&dev->vbl_lock, irqflags);
179 if (atomic_read(&dev->vblank[i].refcount) == 0 &&
180 dev->vblank[i].enabled) {
181 DRM_DEBUG("disabling vblank on crtc %d\n", i);
182 vblank_disable_and_save(dev, i);
183 }
184 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
185 }
186}
187
188void drm_vblank_cleanup(struct drm_device *dev)
189{
190
191 if (dev->num_crtcs == 0)
192 return;
193
194 del_timer_sync(&dev->vblank_disable_timer);
195
196 vblank_disable_fn((unsigned long)dev);
197
198 kfree(dev->vblank);
199
200 dev->num_crtcs = 0;
201}
202EXPORT_SYMBOL(drm_vblank_cleanup);
203
204int drm_vblank_init(struct drm_device *dev, int num_crtcs)
205{
206 int i, ret = -ENOMEM;
207
208 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
209 (unsigned long)dev);
210 spin_lock_init(&dev->vbl_lock);
211 spin_lock_init(&dev->vblank_time_lock);
212
213 dev->num_crtcs = num_crtcs;
214
215 dev->vblank = kcalloc(num_crtcs, sizeof(*dev->vblank), GFP_KERNEL);
216 if (!dev->vblank)
217 goto err;
218
219 for (i = 0; i < num_crtcs; i++)
220 init_waitqueue_head(&dev->vblank[i].queue);
221
222 DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
223
224
225 if (dev->driver->get_vblank_timestamp)
226 DRM_INFO("Driver supports precise vblank timestamp query.\n");
227 else
228 DRM_INFO("No driver support for vblank timestamp query.\n");
229
230 dev->vblank_disable_allowed = false;
231
232 return 0;
233
234err:
235 drm_vblank_cleanup(dev);
236 return ret;
237}
238EXPORT_SYMBOL(drm_vblank_init);
239
240static void drm_irq_vgaarb_nokms(void *cookie, bool state)
241{
242 struct drm_device *dev = cookie;
243
244 if (dev->driver->vgaarb_irq) {
245 dev->driver->vgaarb_irq(dev, state);
246 return;
247 }
248
249 if (!dev->irq_enabled)
250 return;
251
252 if (state) {
253 if (dev->driver->irq_uninstall)
254 dev->driver->irq_uninstall(dev);
255 } else {
256 if (dev->driver->irq_preinstall)
257 dev->driver->irq_preinstall(dev);
258 if (dev->driver->irq_postinstall)
259 dev->driver->irq_postinstall(dev);
260 }
261}
262
263
264
265
266
267
268
269
270
271
272int drm_irq_install(struct drm_device *dev)
273{
274 int ret;
275 unsigned long sh_flags = 0;
276 char *irqname;
277
278 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
279 return -EINVAL;
280
281 if (drm_dev_to_irq(dev) == 0)
282 return -EINVAL;
283
284 mutex_lock(&dev->struct_mutex);
285
286
287 if (!dev->dev_private) {
288 mutex_unlock(&dev->struct_mutex);
289 return -EINVAL;
290 }
291
292 if (dev->irq_enabled) {
293 mutex_unlock(&dev->struct_mutex);
294 return -EBUSY;
295 }
296 dev->irq_enabled = true;
297 mutex_unlock(&dev->struct_mutex);
298
299 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
300
301
302 if (dev->driver->irq_preinstall)
303 dev->driver->irq_preinstall(dev);
304
305
306 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
307 sh_flags = IRQF_SHARED;
308
309 if (dev->devname)
310 irqname = dev->devname;
311 else
312 irqname = dev->driver->name;
313
314 ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
315 sh_flags, irqname, dev);
316
317 if (ret < 0) {
318 mutex_lock(&dev->struct_mutex);
319 dev->irq_enabled = false;
320 mutex_unlock(&dev->struct_mutex);
321 return ret;
322 }
323
324 if (!drm_core_check_feature(dev, DRIVER_MODESET))
325 vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
326
327
328 if (dev->driver->irq_postinstall)
329 ret = dev->driver->irq_postinstall(dev);
330
331 if (ret < 0) {
332 mutex_lock(&dev->struct_mutex);
333 dev->irq_enabled = false;
334 mutex_unlock(&dev->struct_mutex);
335 if (!drm_core_check_feature(dev, DRIVER_MODESET))
336 vga_client_register(dev->pdev, NULL, NULL, NULL);
337 free_irq(drm_dev_to_irq(dev), dev);
338 }
339
340 return ret;
341}
342EXPORT_SYMBOL(drm_irq_install);
343
344
345
346
347
348
349
350
351int drm_irq_uninstall(struct drm_device *dev)
352{
353 unsigned long irqflags;
354 bool irq_enabled;
355 int i;
356
357 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
358 return -EINVAL;
359
360 mutex_lock(&dev->struct_mutex);
361 irq_enabled = dev->irq_enabled;
362 dev->irq_enabled = false;
363 mutex_unlock(&dev->struct_mutex);
364
365
366
367
368 if (dev->num_crtcs) {
369 spin_lock_irqsave(&dev->vbl_lock, irqflags);
370 for (i = 0; i < dev->num_crtcs; i++) {
371 wake_up(&dev->vblank[i].queue);
372 dev->vblank[i].enabled = false;
373 dev->vblank[i].last =
374 dev->driver->get_vblank_counter(dev, i);
375 }
376 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
377 }
378
379 if (!irq_enabled)
380 return -EINVAL;
381
382 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
383
384 if (!drm_core_check_feature(dev, DRIVER_MODESET))
385 vga_client_register(dev->pdev, NULL, NULL, NULL);
386
387 if (dev->driver->irq_uninstall)
388 dev->driver->irq_uninstall(dev);
389
390 free_irq(drm_dev_to_irq(dev), dev);
391
392 return 0;
393}
394EXPORT_SYMBOL(drm_irq_uninstall);
395
396
397
398
399
400
401
402
403
404
405
406
407int drm_control(struct drm_device *dev, void *data,
408 struct drm_file *file_priv)
409{
410 struct drm_control *ctl = data;
411
412
413
414
415
416
417 switch (ctl->func) {
418 case DRM_INST_HANDLER:
419 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
420 return 0;
421 if (drm_core_check_feature(dev, DRIVER_MODESET))
422 return 0;
423 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
424 ctl->irq != drm_dev_to_irq(dev))
425 return -EINVAL;
426 return drm_irq_install(dev);
427 case DRM_UNINST_HANDLER:
428 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
429 return 0;
430 if (drm_core_check_feature(dev, DRIVER_MODESET))
431 return 0;
432 return drm_irq_uninstall(dev);
433 default:
434 return -EINVAL;
435 }
436}
437
438
439
440
441
442
443
444
445
446
447
448
449
450void drm_calc_timestamping_constants(struct drm_crtc *crtc,
451 const struct drm_display_mode *mode)
452{
453 int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0;
454 int dotclock = mode->crtc_clock;
455
456
457 if (dotclock > 0) {
458 int frame_size = mode->crtc_htotal * mode->crtc_vtotal;
459
460
461
462
463
464
465 pixeldur_ns = 1000000 / dotclock;
466 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
467 framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
468
469
470
471
472 if (mode->flags & DRM_MODE_FLAG_INTERLACE)
473 framedur_ns /= 2;
474 } else
475 DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n",
476 crtc->base.id);
477
478 crtc->pixeldur_ns = pixeldur_ns;
479 crtc->linedur_ns = linedur_ns;
480 crtc->framedur_ns = framedur_ns;
481
482 DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
483 crtc->base.id, mode->crtc_htotal,
484 mode->crtc_vtotal, mode->crtc_vdisplay);
485 DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n",
486 crtc->base.id, dotclock, framedur_ns,
487 linedur_ns, pixeldur_ns);
488}
489EXPORT_SYMBOL(drm_calc_timestamping_constants);
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
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
537 int *max_error,
538 struct timeval *vblank_time,
539 unsigned flags,
540 const struct drm_crtc *refcrtc,
541 const struct drm_display_mode *mode)
542{
543 ktime_t stime, etime, mono_time_offset;
544 struct timeval tv_etime;
545 int vbl_status;
546 int vpos, hpos, i;
547 int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns;
548 bool invbl;
549
550 if (crtc < 0 || crtc >= dev->num_crtcs) {
551 DRM_ERROR("Invalid crtc %d\n", crtc);
552 return -EINVAL;
553 }
554
555
556 if (!dev->driver->get_scanout_position) {
557 DRM_ERROR("Called from driver w/o get_scanout_position()!?\n");
558 return -EIO;
559 }
560
561
562 framedur_ns = refcrtc->framedur_ns;
563 linedur_ns = refcrtc->linedur_ns;
564 pixeldur_ns = refcrtc->pixeldur_ns;
565
566
567
568
569 if (framedur_ns == 0) {
570 DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc);
571 return -EAGAIN;
572 }
573
574
575
576
577
578
579
580
581 for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) {
582
583
584
585
586 vbl_status = dev->driver->get_scanout_position(dev, crtc, flags, &vpos,
587 &hpos, &stime, &etime);
588
589
590
591
592
593 if (!drm_timestamp_monotonic)
594 mono_time_offset = ktime_get_monotonic_offset();
595
596
597 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
598 DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n",
599 crtc, vbl_status);
600 return -EIO;
601 }
602
603
604 duration_ns = ktime_to_ns(etime) - ktime_to_ns(stime);
605
606
607 if (duration_ns <= *max_error)
608 break;
609 }
610
611
612 if (i == DRM_TIMESTAMP_MAXRETRIES) {
613 DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n",
614 crtc, duration_ns/1000, *max_error/1000, i);
615 }
616
617
618 *max_error = duration_ns;
619
620
621
622
623
624
625 invbl = vbl_status & DRM_SCANOUTPOS_INVBL;
626
627
628
629
630
631 delta_ns = vpos * linedur_ns + hpos * pixeldur_ns;
632
633 if (!drm_timestamp_monotonic)
634 etime = ktime_sub(etime, mono_time_offset);
635
636
637 tv_etime = ktime_to_timeval(etime);
638
639
640
641 if (delta_ns < 0)
642 etime = ktime_add_ns(etime, -delta_ns);
643 else
644 etime = ktime_sub_ns(etime, delta_ns);
645 *vblank_time = ktime_to_timeval(etime);
646
647 DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
648 crtc, (int)vbl_status, hpos, vpos,
649 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
650 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
651 duration_ns/1000, i);
652
653 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
654 if (invbl)
655 vbl_status |= DRM_VBLANKTIME_INVBL;
656
657 return vbl_status;
658}
659EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
660
661static struct timeval get_drm_timestamp(void)
662{
663 ktime_t now;
664
665 now = ktime_get();
666 if (!drm_timestamp_monotonic)
667 now = ktime_sub(now, ktime_get_monotonic_offset());
668
669 return ktime_to_timeval(now);
670}
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
693 struct timeval *tvblank, unsigned flags)
694{
695 int ret;
696
697
698 int max_error = (int) drm_timestamp_precision * 1000;
699
700
701 if (dev->driver->get_vblank_timestamp && (max_error > 0)) {
702 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error,
703 tvblank, flags);
704 if (ret > 0)
705 return (u32) ret;
706 }
707
708
709
710
711 *tvblank = get_drm_timestamp();
712
713 return 0;
714}
715EXPORT_SYMBOL(drm_get_last_vbltimestamp);
716
717
718
719
720
721
722
723
724
725
726u32 drm_vblank_count(struct drm_device *dev, int crtc)
727{
728 return atomic_read(&dev->vblank[crtc].count);
729}
730EXPORT_SYMBOL(drm_vblank_count);
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
747 struct timeval *vblanktime)
748{
749 u32 cur_vblank;
750
751
752
753
754
755
756 do {
757 cur_vblank = atomic_read(&dev->vblank[crtc].count);
758 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
759 smp_rmb();
760 } while (cur_vblank != atomic_read(&dev->vblank[crtc].count));
761
762 return cur_vblank;
763}
764EXPORT_SYMBOL(drm_vblank_count_and_time);
765
766static void send_vblank_event(struct drm_device *dev,
767 struct drm_pending_vblank_event *e,
768 unsigned long seq, struct timeval *now)
769{
770 WARN_ON_SMP(!spin_is_locked(&dev->event_lock));
771 e->event.sequence = seq;
772 e->event.tv_sec = now->tv_sec;
773 e->event.tv_usec = now->tv_usec;
774
775 list_add_tail(&e->base.link,
776 &e->base.file_priv->event_list);
777 wake_up_interruptible(&e->base.file_priv->event_wait);
778 trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
779 e->event.sequence);
780}
781
782
783
784
785
786
787
788
789
790
791void drm_send_vblank_event(struct drm_device *dev, int crtc,
792 struct drm_pending_vblank_event *e)
793{
794 struct timeval now;
795 unsigned int seq;
796 if (crtc >= 0) {
797 seq = drm_vblank_count_and_time(dev, crtc, &now);
798 } else {
799 seq = 0;
800
801 now = get_drm_timestamp();
802 }
803 e->pipe = crtc;
804 send_vblank_event(dev, e, seq, &now);
805}
806EXPORT_SYMBOL(drm_send_vblank_event);
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824static void drm_update_vblank_count(struct drm_device *dev, int crtc)
825{
826 u32 cur_vblank, diff, tslot, rc;
827 struct timeval t_vblank;
828
829
830
831
832
833
834
835
836
837
838
839
840
841 do {
842 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
843 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
844 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
845
846
847 diff = cur_vblank - dev->vblank[crtc].last;
848 if (cur_vblank < dev->vblank[crtc].last) {
849 diff += dev->max_vblank_count;
850
851 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
852 crtc, dev->vblank[crtc].last, cur_vblank, diff);
853 }
854
855 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
856 crtc, diff);
857
858
859
860
861
862 if (rc) {
863 tslot = atomic_read(&dev->vblank[crtc].count) + diff;
864 vblanktimestamp(dev, crtc, tslot) = t_vblank;
865 }
866
867 smp_mb__before_atomic_inc();
868 atomic_add(diff, &dev->vblank[crtc].count);
869 smp_mb__after_atomic_inc();
870}
871
872
873
874
875
876
877
878
879
880
881
882
883int drm_vblank_get(struct drm_device *dev, int crtc)
884{
885 unsigned long irqflags, irqflags2;
886 int ret = 0;
887
888 spin_lock_irqsave(&dev->vbl_lock, irqflags);
889
890 if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) {
891 spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
892 if (!dev->vblank[crtc].enabled) {
893
894
895
896
897
898
899 ret = dev->driver->enable_vblank(dev, crtc);
900 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n",
901 crtc, ret);
902 if (ret)
903 atomic_dec(&dev->vblank[crtc].refcount);
904 else {
905 dev->vblank[crtc].enabled = true;
906 drm_update_vblank_count(dev, crtc);
907 }
908 }
909 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
910 } else {
911 if (!dev->vblank[crtc].enabled) {
912 atomic_dec(&dev->vblank[crtc].refcount);
913 ret = -EINVAL;
914 }
915 }
916 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
917
918 return ret;
919}
920EXPORT_SYMBOL(drm_vblank_get);
921
922
923
924
925
926
927
928
929
930void drm_vblank_put(struct drm_device *dev, int crtc)
931{
932 BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0);
933
934
935 if (atomic_dec_and_test(&dev->vblank[crtc].refcount) &&
936 (drm_vblank_offdelay > 0))
937 mod_timer(&dev->vblank_disable_timer,
938 jiffies + ((drm_vblank_offdelay * HZ)/1000));
939}
940EXPORT_SYMBOL(drm_vblank_put);
941
942
943
944
945
946
947
948
949void drm_vblank_off(struct drm_device *dev, int crtc)
950{
951 struct drm_pending_vblank_event *e, *t;
952 struct timeval now;
953 unsigned long irqflags;
954 unsigned int seq;
955
956 spin_lock_irqsave(&dev->vbl_lock, irqflags);
957 vblank_disable_and_save(dev, crtc);
958 wake_up(&dev->vblank[crtc].queue);
959
960
961 seq = drm_vblank_count_and_time(dev, crtc, &now);
962
963 spin_lock(&dev->event_lock);
964 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
965 if (e->pipe != crtc)
966 continue;
967 DRM_DEBUG("Sending premature vblank event on disable: \
968 wanted %d, current %d\n",
969 e->event.sequence, seq);
970 list_del(&e->base.link);
971 drm_vblank_put(dev, e->pipe);
972 send_vblank_event(dev, e, seq, &now);
973 }
974 spin_unlock(&dev->event_lock);
975
976 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
977}
978EXPORT_SYMBOL(drm_vblank_off);
979
980
981
982
983
984
985
986
987
988void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
989{
990
991 if (!dev->num_crtcs)
992 return;
993
994
995
996
997
998
999
1000 if (!dev->vblank[crtc].inmodeset) {
1001 dev->vblank[crtc].inmodeset = 0x1;
1002 if (drm_vblank_get(dev, crtc) == 0)
1003 dev->vblank[crtc].inmodeset |= 0x2;
1004 }
1005}
1006EXPORT_SYMBOL(drm_vblank_pre_modeset);
1007
1008void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
1009{
1010 unsigned long irqflags;
1011
1012
1013 if (!dev->num_crtcs)
1014 return;
1015
1016 if (dev->vblank[crtc].inmodeset) {
1017 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1018 dev->vblank_disable_allowed = true;
1019 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1020
1021 if (dev->vblank[crtc].inmodeset & 0x2)
1022 drm_vblank_put(dev, crtc);
1023
1024 dev->vblank[crtc].inmodeset = 0;
1025 }
1026}
1027EXPORT_SYMBOL(drm_vblank_post_modeset);
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040int drm_modeset_ctl(struct drm_device *dev, void *data,
1041 struct drm_file *file_priv)
1042{
1043 struct drm_modeset_ctl *modeset = data;
1044 unsigned int crtc;
1045
1046
1047 if (!dev->num_crtcs)
1048 return 0;
1049
1050
1051 if (drm_core_check_feature(dev, DRIVER_MODESET))
1052 return 0;
1053
1054 crtc = modeset->crtc;
1055 if (crtc >= dev->num_crtcs)
1056 return -EINVAL;
1057
1058 switch (modeset->cmd) {
1059 case _DRM_PRE_MODESET:
1060 drm_vblank_pre_modeset(dev, crtc);
1061 break;
1062 case _DRM_POST_MODESET:
1063 drm_vblank_post_modeset(dev, crtc);
1064 break;
1065 default:
1066 return -EINVAL;
1067 }
1068
1069 return 0;
1070}
1071
1072static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1073 union drm_wait_vblank *vblwait,
1074 struct drm_file *file_priv)
1075{
1076 struct drm_pending_vblank_event *e;
1077 struct timeval now;
1078 unsigned long flags;
1079 unsigned int seq;
1080 int ret;
1081
1082 e = kzalloc(sizeof *e, GFP_KERNEL);
1083 if (e == NULL) {
1084 ret = -ENOMEM;
1085 goto err_put;
1086 }
1087
1088 e->pipe = pipe;
1089 e->base.pid = current->pid;
1090 e->event.base.type = DRM_EVENT_VBLANK;
1091 e->event.base.length = sizeof e->event;
1092 e->event.user_data = vblwait->request.signal;
1093 e->base.event = &e->event.base;
1094 e->base.file_priv = file_priv;
1095 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
1096
1097 spin_lock_irqsave(&dev->event_lock, flags);
1098
1099 if (file_priv->event_space < sizeof e->event) {
1100 ret = -EBUSY;
1101 goto err_unlock;
1102 }
1103
1104 file_priv->event_space -= sizeof e->event;
1105 seq = drm_vblank_count_and_time(dev, pipe, &now);
1106
1107 if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
1108 (seq - vblwait->request.sequence) <= (1 << 23)) {
1109 vblwait->request.sequence = seq + 1;
1110 vblwait->reply.sequence = vblwait->request.sequence;
1111 }
1112
1113 DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
1114 vblwait->request.sequence, seq, pipe);
1115
1116 trace_drm_vblank_event_queued(current->pid, pipe,
1117 vblwait->request.sequence);
1118
1119 e->event.sequence = vblwait->request.sequence;
1120 if ((seq - vblwait->request.sequence) <= (1 << 23)) {
1121 drm_vblank_put(dev, pipe);
1122 send_vblank_event(dev, e, seq, &now);
1123 vblwait->reply.sequence = seq;
1124 } else {
1125
1126 list_add_tail(&e->base.link, &dev->vblank_event_list);
1127 vblwait->reply.sequence = vblwait->request.sequence;
1128 }
1129
1130 spin_unlock_irqrestore(&dev->event_lock, flags);
1131
1132 return 0;
1133
1134err_unlock:
1135 spin_unlock_irqrestore(&dev->event_lock, flags);
1136 kfree(e);
1137err_put:
1138 drm_vblank_put(dev, pipe);
1139 return ret;
1140}
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156int drm_wait_vblank(struct drm_device *dev, void *data,
1157 struct drm_file *file_priv)
1158{
1159 union drm_wait_vblank *vblwait = data;
1160 int ret;
1161 unsigned int flags, seq, crtc, high_crtc;
1162
1163 if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
1164 if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
1165 return -EINVAL;
1166
1167 if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
1168 return -EINVAL;
1169
1170 if (vblwait->request.type &
1171 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
1172 _DRM_VBLANK_HIGH_CRTC_MASK)) {
1173 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
1174 vblwait->request.type,
1175 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK |
1176 _DRM_VBLANK_HIGH_CRTC_MASK));
1177 return -EINVAL;
1178 }
1179
1180 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
1181 high_crtc = (vblwait->request.type & _DRM_VBLANK_HIGH_CRTC_MASK);
1182 if (high_crtc)
1183 crtc = high_crtc >> _DRM_VBLANK_HIGH_CRTC_SHIFT;
1184 else
1185 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
1186 if (crtc >= dev->num_crtcs)
1187 return -EINVAL;
1188
1189 ret = drm_vblank_get(dev, crtc);
1190 if (ret) {
1191 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret);
1192 return ret;
1193 }
1194 seq = drm_vblank_count(dev, crtc);
1195
1196 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
1197 case _DRM_VBLANK_RELATIVE:
1198 vblwait->request.sequence += seq;
1199 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
1200 case _DRM_VBLANK_ABSOLUTE:
1201 break;
1202 default:
1203 ret = -EINVAL;
1204 goto done;
1205 }
1206
1207 if (flags & _DRM_VBLANK_EVENT) {
1208
1209
1210
1211 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
1212 }
1213
1214 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
1215 (seq - vblwait->request.sequence) <= (1<<23)) {
1216 vblwait->request.sequence = seq + 1;
1217 }
1218
1219 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
1220 vblwait->request.sequence, crtc);
1221 dev->vblank[crtc].last_wait = vblwait->request.sequence;
1222 DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * HZ,
1223 (((drm_vblank_count(dev, crtc) -
1224 vblwait->request.sequence) <= (1 << 23)) ||
1225 !dev->irq_enabled));
1226
1227 if (ret != -EINTR) {
1228 struct timeval now;
1229
1230 vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now);
1231 vblwait->reply.tval_sec = now.tv_sec;
1232 vblwait->reply.tval_usec = now.tv_usec;
1233
1234 DRM_DEBUG("returning %d to client\n",
1235 vblwait->reply.sequence);
1236 } else {
1237 DRM_DEBUG("vblank wait interrupted by signal\n");
1238 }
1239
1240done:
1241 drm_vblank_put(dev, crtc);
1242 return ret;
1243}
1244
1245static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1246{
1247 struct drm_pending_vblank_event *e, *t;
1248 struct timeval now;
1249 unsigned long flags;
1250 unsigned int seq;
1251
1252 seq = drm_vblank_count_and_time(dev, crtc, &now);
1253
1254 spin_lock_irqsave(&dev->event_lock, flags);
1255
1256 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1257 if (e->pipe != crtc)
1258 continue;
1259 if ((seq - e->event.sequence) > (1<<23))
1260 continue;
1261
1262 DRM_DEBUG("vblank event on %d, current %d\n",
1263 e->event.sequence, seq);
1264
1265 list_del(&e->base.link);
1266 drm_vblank_put(dev, e->pipe);
1267 send_vblank_event(dev, e, seq, &now);
1268 }
1269
1270 spin_unlock_irqrestore(&dev->event_lock, flags);
1271
1272 trace_drm_vblank_event(crtc, seq);
1273}
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283bool drm_handle_vblank(struct drm_device *dev, int crtc)
1284{
1285 u32 vblcount;
1286 s64 diff_ns;
1287 struct timeval tvblank;
1288 unsigned long irqflags;
1289
1290 if (!dev->num_crtcs)
1291 return false;
1292
1293
1294
1295
1296
1297 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
1298
1299
1300 if (!dev->vblank[crtc].enabled) {
1301 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
1302 return false;
1303 }
1304
1305
1306
1307
1308
1309
1310 vblcount = atomic_read(&dev->vblank[crtc].count);
1311 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
1312
1313
1314 diff_ns = timeval_to_ns(&tvblank) -
1315 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326 if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) {
1327
1328 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank;
1329
1330
1331
1332
1333 smp_mb__before_atomic_inc();
1334 atomic_inc(&dev->vblank[crtc].count);
1335 smp_mb__after_atomic_inc();
1336 } else {
1337 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
1338 crtc, (int) diff_ns);
1339 }
1340
1341 wake_up(&dev->vblank[crtc].queue);
1342 drm_handle_vblank_events(dev, crtc);
1343
1344 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
1345 return true;
1346}
1347EXPORT_SYMBOL(drm_handle_vblank);
1348