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
44
45#define vblanktimestamp(dev, crtc, count) ( \
46 (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \
47 ((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 (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
78 return -EINVAL;
79
80 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
81 return -EINVAL;
82
83 if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
84 (p->busnum & 0xff) != dev->pdev->bus->number ||
85 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
86 return -EINVAL;
87
88 p->irq = dev->pdev->irq;
89
90 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
91 p->irq);
92
93 return 0;
94}
95
96
97
98
99static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
100{
101 memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0,
102 DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval));
103}
104
105
106
107
108
109
110
111static void vblank_disable_and_save(struct drm_device *dev, int crtc)
112{
113 unsigned long irqflags;
114 u32 vblcount;
115 s64 diff_ns;
116 int vblrc;
117 struct timeval tvblank;
118
119
120
121
122
123
124
125 preempt_disable();
126 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
127
128 dev->driver->disable_vblank(dev, crtc);
129 dev->vblank_enabled[crtc] = 0;
130
131
132
133
134
135
136
137
138
139
140
141
142
143 do {
144 dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc);
145 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
146 } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc));
147
148
149
150
151 vblcount = atomic_read(&dev->_vblank_count[crtc]);
152 diff_ns = timeval_to_ns(&tvblank) -
153 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
154
155
156
157
158
159
160
161
162
163
164
165
166
167 if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) {
168 atomic_inc(&dev->_vblank_count[crtc]);
169 smp_mb__after_atomic_inc();
170 }
171
172
173 clear_vblank_timestamps(dev, crtc);
174
175 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
176 preempt_enable();
177}
178
179static void vblank_disable_fn(unsigned long arg)
180{
181 struct drm_device *dev = (struct drm_device *)arg;
182 unsigned long irqflags;
183 int i;
184
185 if (!dev->vblank_disable_allowed)
186 return;
187
188 for (i = 0; i < dev->num_crtcs; i++) {
189 spin_lock_irqsave(&dev->vbl_lock, irqflags);
190 if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
191 dev->vblank_enabled[i]) {
192 DRM_DEBUG("disabling vblank on crtc %d\n", i);
193 vblank_disable_and_save(dev, i);
194 }
195 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
196 }
197}
198
199void drm_vblank_cleanup(struct drm_device *dev)
200{
201
202 if (dev->num_crtcs == 0)
203 return;
204
205 del_timer(&dev->vblank_disable_timer);
206
207 vblank_disable_fn((unsigned long)dev);
208
209 kfree(dev->vbl_queue);
210 kfree(dev->_vblank_count);
211 kfree(dev->vblank_refcount);
212 kfree(dev->vblank_enabled);
213 kfree(dev->last_vblank);
214 kfree(dev->last_vblank_wait);
215 kfree(dev->vblank_inmodeset);
216 kfree(dev->_vblank_time);
217
218 dev->num_crtcs = 0;
219}
220EXPORT_SYMBOL(drm_vblank_cleanup);
221
222int drm_vblank_init(struct drm_device *dev, int num_crtcs)
223{
224 int i, ret = -ENOMEM;
225
226 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
227 (unsigned long)dev);
228 spin_lock_init(&dev->vbl_lock);
229 spin_lock_init(&dev->vblank_time_lock);
230
231 dev->num_crtcs = num_crtcs;
232
233 dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs,
234 GFP_KERNEL);
235 if (!dev->vbl_queue)
236 goto err;
237
238 dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL);
239 if (!dev->_vblank_count)
240 goto err;
241
242 dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs,
243 GFP_KERNEL);
244 if (!dev->vblank_refcount)
245 goto err;
246
247 dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
248 if (!dev->vblank_enabled)
249 goto err;
250
251 dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
252 if (!dev->last_vblank)
253 goto err;
254
255 dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL);
256 if (!dev->last_vblank_wait)
257 goto err;
258
259 dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL);
260 if (!dev->vblank_inmodeset)
261 goto err;
262
263 dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE,
264 sizeof(struct timeval), GFP_KERNEL);
265 if (!dev->_vblank_time)
266 goto err;
267
268 DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n");
269
270
271 if (dev->driver->get_vblank_timestamp)
272 DRM_INFO("Driver supports precise vblank timestamp query.\n");
273 else
274 DRM_INFO("No driver support for vblank timestamp query.\n");
275
276
277 for (i = 0; i < num_crtcs; i++) {
278 init_waitqueue_head(&dev->vbl_queue[i]);
279 atomic_set(&dev->_vblank_count[i], 0);
280 atomic_set(&dev->vblank_refcount[i], 0);
281 }
282
283 dev->vblank_disable_allowed = 0;
284 return 0;
285
286err:
287 drm_vblank_cleanup(dev);
288 return ret;
289}
290EXPORT_SYMBOL(drm_vblank_init);
291
292static void drm_irq_vgaarb_nokms(void *cookie, bool state)
293{
294 struct drm_device *dev = cookie;
295
296 if (dev->driver->vgaarb_irq) {
297 dev->driver->vgaarb_irq(dev, state);
298 return;
299 }
300
301 if (!dev->irq_enabled)
302 return;
303
304 if (state)
305 dev->driver->irq_uninstall(dev);
306 else {
307 dev->driver->irq_preinstall(dev);
308 dev->driver->irq_postinstall(dev);
309 }
310}
311
312
313
314
315
316
317
318
319
320
321int drm_irq_install(struct drm_device *dev)
322{
323 int ret = 0;
324 unsigned long sh_flags = 0;
325 char *irqname;
326
327 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
328 return -EINVAL;
329
330 if (drm_dev_to_irq(dev) == 0)
331 return -EINVAL;
332
333 mutex_lock(&dev->struct_mutex);
334
335
336 if (!dev->dev_private) {
337 mutex_unlock(&dev->struct_mutex);
338 return -EINVAL;
339 }
340
341 if (dev->irq_enabled) {
342 mutex_unlock(&dev->struct_mutex);
343 return -EBUSY;
344 }
345 dev->irq_enabled = 1;
346 mutex_unlock(&dev->struct_mutex);
347
348 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
349
350
351 dev->driver->irq_preinstall(dev);
352
353
354 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
355 sh_flags = IRQF_SHARED;
356
357 if (dev->devname)
358 irqname = dev->devname;
359 else
360 irqname = dev->driver->name;
361
362 ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
363 sh_flags, irqname, dev);
364
365 if (ret < 0) {
366 mutex_lock(&dev->struct_mutex);
367 dev->irq_enabled = 0;
368 mutex_unlock(&dev->struct_mutex);
369 return ret;
370 }
371
372 if (!drm_core_check_feature(dev, DRIVER_MODESET))
373 vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL);
374
375
376 ret = dev->driver->irq_postinstall(dev);
377 if (ret < 0) {
378 mutex_lock(&dev->struct_mutex);
379 dev->irq_enabled = 0;
380 mutex_unlock(&dev->struct_mutex);
381 }
382
383 return ret;
384}
385EXPORT_SYMBOL(drm_irq_install);
386
387
388
389
390
391
392
393
394int drm_irq_uninstall(struct drm_device *dev)
395{
396 unsigned long irqflags;
397 int irq_enabled, i;
398
399 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
400 return -EINVAL;
401
402 mutex_lock(&dev->struct_mutex);
403 irq_enabled = dev->irq_enabled;
404 dev->irq_enabled = 0;
405 mutex_unlock(&dev->struct_mutex);
406
407
408
409
410 spin_lock_irqsave(&dev->vbl_lock, irqflags);
411 for (i = 0; i < dev->num_crtcs; i++) {
412 DRM_WAKEUP(&dev->vbl_queue[i]);
413 dev->vblank_enabled[i] = 0;
414 dev->last_vblank[i] = dev->driver->get_vblank_counter(dev, i);
415 }
416 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
417
418 if (!irq_enabled)
419 return -EINVAL;
420
421 DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
422
423 if (!drm_core_check_feature(dev, DRIVER_MODESET))
424 vga_client_register(dev->pdev, NULL, NULL, NULL);
425
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)@ %d.%d -> %d.%d [e %d us, %d rep]\n",
698 crtc, (int) vbl_status, hpos, vpos, raw_time.tv_sec,
699 raw_time.tv_usec, vblank_time->tv_sec, vblank_time->tv_usec,
700 (int) duration_ns/1000, i);
701
702 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
703 if (invbl)
704 vbl_status |= DRM_VBLANKTIME_INVBL;
705
706 return vbl_status;
707}
708EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
731 struct timeval *tvblank, unsigned flags)
732{
733 int ret = 0;
734
735
736 int max_error = (int) drm_timestamp_precision * 1000;
737
738
739 if (dev->driver->get_vblank_timestamp && (max_error > 0)) {
740 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error,
741 tvblank, flags);
742 if (ret > 0)
743 return (u32) ret;
744 }
745
746
747
748
749 do_gettimeofday(tvblank);
750
751 return 0;
752}
753EXPORT_SYMBOL(drm_get_last_vbltimestamp);
754
755
756
757
758
759
760
761
762
763
764u32 drm_vblank_count(struct drm_device *dev, int crtc)
765{
766 return atomic_read(&dev->_vblank_count[crtc]);
767}
768EXPORT_SYMBOL(drm_vblank_count);
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
785 struct timeval *vblanktime)
786{
787 u32 cur_vblank;
788
789
790
791
792
793
794 do {
795 cur_vblank = atomic_read(&dev->_vblank_count[crtc]);
796 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
797 smp_rmb();
798 } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc]));
799
800 return cur_vblank;
801}
802EXPORT_SYMBOL(drm_vblank_count_and_time);
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820static void drm_update_vblank_count(struct drm_device *dev, int crtc)
821{
822 u32 cur_vblank, diff, tslot, rc;
823 struct timeval t_vblank;
824
825
826
827
828
829
830
831
832
833
834
835
836
837 do {
838 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
839 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
840 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
841
842
843 diff = cur_vblank - dev->last_vblank[crtc];
844 if (cur_vblank < dev->last_vblank[crtc]) {
845 diff += dev->max_vblank_count;
846
847 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
848 crtc, dev->last_vblank[crtc], cur_vblank, diff);
849 }
850
851 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
852 crtc, diff);
853
854
855
856
857
858 if (rc) {
859 tslot = atomic_read(&dev->_vblank_count[crtc]) + diff;
860 vblanktimestamp(dev, crtc, tslot) = t_vblank;
861 }
862
863 smp_mb__before_atomic_inc();
864 atomic_add(diff, &dev->_vblank_count[crtc]);
865 smp_mb__after_atomic_inc();
866}
867
868
869
870
871
872
873
874
875
876
877
878
879int drm_vblank_get(struct drm_device *dev, int crtc)
880{
881 unsigned long irqflags, irqflags2;
882 int ret = 0;
883
884 spin_lock_irqsave(&dev->vbl_lock, irqflags);
885
886 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) {
887
888
889
890 preempt_disable();
891 spin_lock_irqsave(&dev->vblank_time_lock, irqflags2);
892 if (!dev->vblank_enabled[crtc]) {
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_refcount[crtc]);
904 else {
905 dev->vblank_enabled[crtc] = 1;
906 drm_update_vblank_count(dev, crtc);
907 }
908 }
909 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2);
910 preempt_enable();
911 } else {
912 if (!dev->vblank_enabled[crtc]) {
913 atomic_dec(&dev->vblank_refcount[crtc]);
914 ret = -EINVAL;
915 }
916 }
917 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
918
919 return ret;
920}
921EXPORT_SYMBOL(drm_vblank_get);
922
923
924
925
926
927
928
929
930
931void drm_vblank_put(struct drm_device *dev, int crtc)
932{
933 BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0);
934
935
936 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) &&
937 (drm_vblank_offdelay > 0))
938 mod_timer(&dev->vblank_disable_timer,
939 jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000));
940}
941EXPORT_SYMBOL(drm_vblank_put);
942
943void drm_vblank_off(struct drm_device *dev, int crtc)
944{
945 unsigned long irqflags;
946
947 spin_lock_irqsave(&dev->vbl_lock, irqflags);
948 vblank_disable_and_save(dev, crtc);
949 DRM_WAKEUP(&dev->vbl_queue[crtc]);
950 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
951}
952EXPORT_SYMBOL(drm_vblank_off);
953
954
955
956
957
958
959
960
961
962
963void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
964{
965
966 if (!dev->num_crtcs)
967 return;
968
969
970
971
972
973
974
975 if (!dev->vblank_inmodeset[crtc]) {
976 dev->vblank_inmodeset[crtc] = 0x1;
977 if (drm_vblank_get(dev, crtc) == 0)
978 dev->vblank_inmodeset[crtc] |= 0x2;
979 }
980}
981EXPORT_SYMBOL(drm_vblank_pre_modeset);
982
983void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
984{
985 unsigned long irqflags;
986
987 if (dev->vblank_inmodeset[crtc]) {
988 spin_lock_irqsave(&dev->vbl_lock, irqflags);
989 dev->vblank_disable_allowed = 1;
990 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
991
992 if (dev->vblank_inmodeset[crtc] & 0x2)
993 drm_vblank_put(dev, crtc);
994
995 dev->vblank_inmodeset[crtc] = 0;
996 }
997}
998EXPORT_SYMBOL(drm_vblank_post_modeset);
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011int drm_modeset_ctl(struct drm_device *dev, void *data,
1012 struct drm_file *file_priv)
1013{
1014 struct drm_modeset_ctl *modeset = data;
1015 int ret = 0;
1016 unsigned int crtc;
1017
1018
1019 if (!dev->num_crtcs)
1020 goto out;
1021
1022 crtc = modeset->crtc;
1023 if (crtc >= dev->num_crtcs) {
1024 ret = -EINVAL;
1025 goto out;
1026 }
1027
1028 switch (modeset->cmd) {
1029 case _DRM_PRE_MODESET:
1030 drm_vblank_pre_modeset(dev, crtc);
1031 break;
1032 case _DRM_POST_MODESET:
1033 drm_vblank_post_modeset(dev, crtc);
1034 break;
1035 default:
1036 ret = -EINVAL;
1037 break;
1038 }
1039
1040out:
1041 return ret;
1042}
1043
1044static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1045 union drm_wait_vblank *vblwait,
1046 struct drm_file *file_priv)
1047{
1048 struct drm_pending_vblank_event *e;
1049 struct timeval now;
1050 unsigned long flags;
1051 unsigned int seq;
1052 int ret;
1053
1054 e = kzalloc(sizeof *e, GFP_KERNEL);
1055 if (e == NULL) {
1056 ret = -ENOMEM;
1057 goto err_put;
1058 }
1059
1060 e->pipe = pipe;
1061 e->base.pid = current->pid;
1062 e->event.base.type = DRM_EVENT_VBLANK;
1063 e->event.base.length = sizeof e->event;
1064 e->event.user_data = vblwait->request.signal;
1065 e->base.event = &e->event.base;
1066 e->base.file_priv = file_priv;
1067 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
1068
1069 spin_lock_irqsave(&dev->event_lock, flags);
1070
1071 if (file_priv->event_space < sizeof e->event) {
1072 ret = -EBUSY;
1073 goto err_unlock;
1074 }
1075
1076 file_priv->event_space -= sizeof e->event;
1077 seq = drm_vblank_count_and_time(dev, pipe, &now);
1078
1079 if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
1080 (seq - vblwait->request.sequence) <= (1 << 23)) {
1081 vblwait->request.sequence = seq + 1;
1082 vblwait->reply.sequence = vblwait->request.sequence;
1083 }
1084
1085 DRM_DEBUG("event on vblank count %d, current %d, crtc %d\n",
1086 vblwait->request.sequence, seq, pipe);
1087
1088 trace_drm_vblank_event_queued(current->pid, pipe,
1089 vblwait->request.sequence);
1090
1091 e->event.sequence = vblwait->request.sequence;
1092 if ((seq - vblwait->request.sequence) <= (1 << 23)) {
1093 e->event.sequence = seq;
1094 e->event.tv_sec = now.tv_sec;
1095 e->event.tv_usec = now.tv_usec;
1096 drm_vblank_put(dev, pipe);
1097 list_add_tail(&e->base.link, &e->base.file_priv->event_list);
1098 wake_up_interruptible(&e->base.file_priv->event_wait);
1099 vblwait->reply.sequence = seq;
1100 trace_drm_vblank_event_delivered(current->pid, pipe,
1101 vblwait->request.sequence);
1102 } else {
1103 list_add_tail(&e->base.link, &dev->vblank_event_list);
1104 vblwait->reply.sequence = vblwait->request.sequence;
1105 }
1106
1107 spin_unlock_irqrestore(&dev->event_lock, flags);
1108
1109 return 0;
1110
1111err_unlock:
1112 spin_unlock_irqrestore(&dev->event_lock, flags);
1113 kfree(e);
1114err_put:
1115 drm_vblank_put(dev, pipe);
1116 return ret;
1117}
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133int drm_wait_vblank(struct drm_device *dev, void *data,
1134 struct drm_file *file_priv)
1135{
1136 union drm_wait_vblank *vblwait = data;
1137 int ret = 0;
1138 unsigned int flags, seq, crtc;
1139
1140 if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
1141 return -EINVAL;
1142
1143 if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
1144 return -EINVAL;
1145
1146 if (vblwait->request.type &
1147 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
1148 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
1149 vblwait->request.type,
1150 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
1151 return -EINVAL;
1152 }
1153
1154 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
1155 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
1156
1157 if (crtc >= dev->num_crtcs)
1158 return -EINVAL;
1159
1160 ret = drm_vblank_get(dev, crtc);
1161 if (ret) {
1162 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret);
1163 return ret;
1164 }
1165 seq = drm_vblank_count(dev, crtc);
1166
1167 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
1168 case _DRM_VBLANK_RELATIVE:
1169 vblwait->request.sequence += seq;
1170 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
1171 case _DRM_VBLANK_ABSOLUTE:
1172 break;
1173 default:
1174 ret = -EINVAL;
1175 goto done;
1176 }
1177
1178 if (flags & _DRM_VBLANK_EVENT)
1179 return drm_queue_vblank_event(dev, crtc, vblwait, file_priv);
1180
1181 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
1182 (seq - vblwait->request.sequence) <= (1<<23)) {
1183 vblwait->request.sequence = seq + 1;
1184 }
1185
1186 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
1187 vblwait->request.sequence, crtc);
1188 dev->last_vblank_wait[crtc] = vblwait->request.sequence;
1189 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
1190 (((drm_vblank_count(dev, crtc) -
1191 vblwait->request.sequence) <= (1 << 23)) ||
1192 !dev->irq_enabled));
1193
1194 if (ret != -EINTR) {
1195 struct timeval now;
1196
1197 vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now);
1198 vblwait->reply.tval_sec = now.tv_sec;
1199 vblwait->reply.tval_usec = now.tv_usec;
1200
1201 DRM_DEBUG("returning %d to client\n",
1202 vblwait->reply.sequence);
1203 } else {
1204 DRM_DEBUG("vblank wait interrupted by signal\n");
1205 }
1206
1207done:
1208 drm_vblank_put(dev, crtc);
1209 return ret;
1210}
1211
1212void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1213{
1214 struct drm_pending_vblank_event *e, *t;
1215 struct timeval now;
1216 unsigned long flags;
1217 unsigned int seq;
1218
1219 seq = drm_vblank_count_and_time(dev, crtc, &now);
1220
1221 spin_lock_irqsave(&dev->event_lock, flags);
1222
1223 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1224 if (e->pipe != crtc)
1225 continue;
1226 if ((seq - e->event.sequence) > (1<<23))
1227 continue;
1228
1229 DRM_DEBUG("vblank event on %d, current %d\n",
1230 e->event.sequence, seq);
1231
1232 e->event.sequence = seq;
1233 e->event.tv_sec = now.tv_sec;
1234 e->event.tv_usec = now.tv_usec;
1235 drm_vblank_put(dev, e->pipe);
1236 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
1237 wake_up_interruptible(&e->base.file_priv->event_wait);
1238 trace_drm_vblank_event_delivered(e->base.pid, e->pipe,
1239 e->event.sequence);
1240 }
1241
1242 spin_unlock_irqrestore(&dev->event_lock, flags);
1243
1244 trace_drm_vblank_event(crtc, seq);
1245}
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255bool drm_handle_vblank(struct drm_device *dev, int crtc)
1256{
1257 u32 vblcount;
1258 s64 diff_ns;
1259 struct timeval tvblank;
1260 unsigned long irqflags;
1261
1262 if (!dev->num_crtcs)
1263 return false;
1264
1265
1266
1267
1268
1269 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
1270
1271
1272 if (!dev->vblank_enabled[crtc]) {
1273 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
1274 return false;
1275 }
1276
1277
1278
1279
1280
1281
1282 vblcount = atomic_read(&dev->_vblank_count[crtc]);
1283 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
1284
1285
1286 diff_ns = timeval_to_ns(&tvblank) -
1287 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298 if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) {
1299
1300 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank;
1301
1302
1303
1304
1305 smp_mb__before_atomic_inc();
1306 atomic_inc(&dev->_vblank_count[crtc]);
1307 smp_mb__after_atomic_inc();
1308 } else {
1309 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
1310 crtc, (int) diff_ns);
1311 }
1312
1313 DRM_WAKEUP(&dev->vbl_queue[crtc]);
1314 drm_handle_vblank_events(dev, crtc);
1315
1316 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
1317 return true;
1318}
1319EXPORT_SYMBOL(drm_handle_vblank);
1320