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