aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c463
1 files changed, 324 insertions, 139 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 08ba1209228e..5ef03c216a27 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -34,6 +34,7 @@
34 34
35#include <drm/drmP.h> 35#include <drm/drmP.h>
36#include "drm_trace.h" 36#include "drm_trace.h"
37#include "drm_internal.h"
37 38
38#include <linux/interrupt.h> /* For task queue support */ 39#include <linux/interrupt.h> /* For task queue support */
39#include <linux/slab.h> 40#include <linux/slab.h>
@@ -55,12 +56,91 @@
55 */ 56 */
56#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 57#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
57 58
59static bool
60drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
61 struct timeval *tvblank, unsigned flags);
62
63static unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
64
58/* 65/*
59 * Clear vblank timestamp buffer for a crtc. 66 * Default to use monotonic timestamps for wait-for-vblank and page-flip
67 * complete events.
68 */
69unsigned int drm_timestamp_monotonic = 1;
70
71static int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
72
73module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
74module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
75module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
76
77/**
78 * drm_update_vblank_count - update the master vblank counter
79 * @dev: DRM device
80 * @crtc: counter to update
81 *
82 * Call back into the driver to update the appropriate vblank counter
83 * (specified by @crtc). Deal with wraparound, if it occurred, and
84 * update the last read value so we can deal with wraparound on the next
85 * call if necessary.
86 *
87 * Only necessary when going from off->on, to account for frames we
88 * didn't get an interrupt for.
89 *
90 * Note: caller must hold dev->vbl_lock since this reads & writes
91 * device vblank fields.
60 */ 92 */
61static void clear_vblank_timestamps(struct drm_device *dev, int crtc) 93static void drm_update_vblank_count(struct drm_device *dev, int crtc)
62{ 94{
63 memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time)); 95 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
96 u32 cur_vblank, diff, tslot;
97 bool rc;
98 struct timeval t_vblank;
99
100 /*
101 * Interrupts were disabled prior to this call, so deal with counter
102 * wrap if needed.
103 * NOTE! It's possible we lost a full dev->max_vblank_count events
104 * here if the register is small or we had vblank interrupts off for
105 * a long time.
106 *
107 * We repeat the hardware vblank counter & timestamp query until
108 * we get consistent results. This to prevent races between gpu
109 * updating its hardware counter while we are retrieving the
110 * corresponding vblank timestamp.
111 */
112 do {
113 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
114 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
115 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
116
117 /* Deal with counter wrap */
118 diff = cur_vblank - vblank->last;
119 if (cur_vblank < vblank->last) {
120 diff += dev->max_vblank_count;
121
122 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
123 crtc, vblank->last, cur_vblank, diff);
124 }
125
126 DRM_DEBUG("updating vblank count on crtc %d, missed %d\n",
127 crtc, diff);
128
129 if (diff == 0)
130 return;
131
132 /* Reinitialize corresponding vblank timestamp if high-precision query
133 * available. Skip this step if query unsupported or failed. Will
134 * reinitialize delayed at next vblank interrupt in that case.
135 */
136 if (rc) {
137 tslot = atomic_read(&vblank->count) + diff;
138 vblanktimestamp(dev, crtc, tslot) = t_vblank;
139 }
140
141 smp_mb__before_atomic();
142 atomic_add(diff, &vblank->count);
143 smp_mb__after_atomic();
64} 144}
65 145
66/* 146/*
@@ -71,10 +151,11 @@ static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
71 */ 151 */
72static void vblank_disable_and_save(struct drm_device *dev, int crtc) 152static void vblank_disable_and_save(struct drm_device *dev, int crtc)
73{ 153{
154 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
74 unsigned long irqflags; 155 unsigned long irqflags;
75 u32 vblcount; 156 u32 vblcount;
76 s64 diff_ns; 157 s64 diff_ns;
77 int vblrc; 158 bool vblrc;
78 struct timeval tvblank; 159 struct timeval tvblank;
79 int count = DRM_TIMESTAMP_MAXRETRIES; 160 int count = DRM_TIMESTAMP_MAXRETRIES;
80 161
@@ -84,8 +165,28 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
84 */ 165 */
85 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); 166 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
86 167
168 /*
169 * If the vblank interrupt was already disbled update the count
170 * and timestamp to maintain the appearance that the counter
171 * has been ticking all along until this time. This makes the
172 * count account for the entire time between drm_vblank_on() and
173 * drm_vblank_off().
174 *
175 * But only do this if precise vblank timestamps are available.
176 * Otherwise we might read a totally bogus timestamp since drivers
177 * lacking precise timestamp support rely upon sampling the system clock
178 * at vblank interrupt time. Which obviously won't work out well if the
179 * vblank interrupt is disabled.
180 */
181 if (!vblank->enabled &&
182 drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0)) {
183 drm_update_vblank_count(dev, crtc);
184 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
185 return;
186 }
187
87 dev->driver->disable_vblank(dev, crtc); 188 dev->driver->disable_vblank(dev, crtc);
88 dev->vblank[crtc].enabled = false; 189 vblank->enabled = false;
89 190
90 /* No further vblank irq's will be processed after 191 /* No further vblank irq's will be processed after
91 * this point. Get current hardware vblank count and 192 * this point. Get current hardware vblank count and
@@ -100,9 +201,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
100 * delayed gpu counter increment. 201 * delayed gpu counter increment.
101 */ 202 */
102 do { 203 do {
103 dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc); 204 vblank->last = dev->driver->get_vblank_counter(dev, crtc);
104 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); 205 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
105 } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); 206 } while (vblank->last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
106 207
107 if (!count) 208 if (!count)
108 vblrc = 0; 209 vblrc = 0;
@@ -110,7 +211,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
110 /* Compute time difference to stored timestamp of last vblank 211 /* Compute time difference to stored timestamp of last vblank
111 * as updated by last invocation of drm_handle_vblank() in vblank irq. 212 * as updated by last invocation of drm_handle_vblank() in vblank irq.
112 */ 213 */
113 vblcount = atomic_read(&dev->vblank[crtc].count); 214 vblcount = atomic_read(&vblank->count);
114 diff_ns = timeval_to_ns(&tvblank) - 215 diff_ns = timeval_to_ns(&tvblank) -
115 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); 216 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
116 217
@@ -126,14 +227,18 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
126 * available. In that case we can't account for this and just 227 * available. In that case we can't account for this and just
127 * hope for the best. 228 * hope for the best.
128 */ 229 */
129 if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { 230 if (vblrc && (abs64(diff_ns) > 1000000)) {
130 atomic_inc(&dev->vblank[crtc].count); 231 /* Store new timestamp in ringbuffer. */
232 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank;
233
234 /* Increment cooked vblank count. This also atomically commits
235 * the timestamp computed above.
236 */
237 smp_mb__before_atomic();
238 atomic_inc(&vblank->count);
131 smp_mb__after_atomic(); 239 smp_mb__after_atomic();
132 } 240 }
133 241
134 /* Invalidate all timestamps while vblank irq's are off. */
135 clear_vblank_timestamps(dev, crtc);
136
137 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 242 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
138} 243}
139 244
@@ -164,14 +269,20 @@ static void vblank_disable_fn(unsigned long arg)
164void drm_vblank_cleanup(struct drm_device *dev) 269void drm_vblank_cleanup(struct drm_device *dev)
165{ 270{
166 int crtc; 271 int crtc;
272 unsigned long irqflags;
167 273
168 /* Bail if the driver didn't call drm_vblank_init() */ 274 /* Bail if the driver didn't call drm_vblank_init() */
169 if (dev->num_crtcs == 0) 275 if (dev->num_crtcs == 0)
170 return; 276 return;
171 277
172 for (crtc = 0; crtc < dev->num_crtcs; crtc++) { 278 for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
173 del_timer_sync(&dev->vblank[crtc].disable_timer); 279 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
174 vblank_disable_fn((unsigned long)&dev->vblank[crtc]); 280
281 del_timer_sync(&vblank->disable_timer);
282
283 spin_lock_irqsave(&dev->vbl_lock, irqflags);
284 vblank_disable_and_save(dev, crtc);
285 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
175 } 286 }
176 287
177 kfree(dev->vblank); 288 kfree(dev->vblank);
@@ -204,11 +315,13 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
204 goto err; 315 goto err;
205 316
206 for (i = 0; i < num_crtcs; i++) { 317 for (i = 0; i < num_crtcs; i++) {
207 dev->vblank[i].dev = dev; 318 struct drm_vblank_crtc *vblank = &dev->vblank[i];
208 dev->vblank[i].crtc = i; 319
209 init_waitqueue_head(&dev->vblank[i].queue); 320 vblank->dev = dev;
210 setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn, 321 vblank->crtc = i;
211 (unsigned long)&dev->vblank[i]); 322 init_waitqueue_head(&vblank->queue);
323 setup_timer(&vblank->disable_timer, vblank_disable_fn,
324 (unsigned long)vblank);
212 } 325 }
213 326
214 DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); 327 DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
@@ -224,7 +337,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
224 return 0; 337 return 0;
225 338
226err: 339err:
227 drm_vblank_cleanup(dev); 340 dev->num_crtcs = 0;
228 return ret; 341 return ret;
229} 342}
230EXPORT_SYMBOL(drm_vblank_init); 343EXPORT_SYMBOL(drm_vblank_init);
@@ -360,9 +473,11 @@ int drm_irq_uninstall(struct drm_device *dev)
360 if (dev->num_crtcs) { 473 if (dev->num_crtcs) {
361 spin_lock_irqsave(&dev->vbl_lock, irqflags); 474 spin_lock_irqsave(&dev->vbl_lock, irqflags);
362 for (i = 0; i < dev->num_crtcs; i++) { 475 for (i = 0; i < dev->num_crtcs; i++) {
363 wake_up(&dev->vblank[i].queue); 476 struct drm_vblank_crtc *vblank = &dev->vblank[i];
364 dev->vblank[i].enabled = false; 477
365 dev->vblank[i].last = 478 wake_up(&vblank->queue);
479 vblank->enabled = false;
480 vblank->last =
366 dev->driver->get_vblank_counter(dev, i); 481 dev->driver->get_vblank_counter(dev, i);
367 } 482 }
368 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 483 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -617,7 +732,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
617 * within vblank area, counting down the number of lines until 732 * within vblank area, counting down the number of lines until
618 * start of scanout. 733 * start of scanout.
619 */ 734 */
620 invbl = vbl_status & DRM_SCANOUTPOS_INVBL; 735 invbl = vbl_status & DRM_SCANOUTPOS_IN_VBLANK;
621 736
622 /* Convert scanout position into elapsed time at raw_time query 737 /* Convert scanout position into elapsed time at raw_time query
623 * since start of scanout at first display scanline. delta_ns 738 * since start of scanout at first display scanline. delta_ns
@@ -647,7 +762,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
647 762
648 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 763 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
649 if (invbl) 764 if (invbl)
650 vbl_status |= DRM_VBLANKTIME_INVBL; 765 vbl_status |= DRM_VBLANKTIME_IN_VBLANK;
651 766
652 return vbl_status; 767 return vbl_status;
653} 768}
@@ -679,10 +794,11 @@ static struct timeval get_drm_timestamp(void)
679 * call, i.e., it isn't very precisely locked to the true vblank. 794 * call, i.e., it isn't very precisely locked to the true vblank.
680 * 795 *
681 * Returns: 796 * Returns:
682 * Non-zero if timestamp is considered to be very precise, zero otherwise. 797 * True if timestamp is considered to be very precise, false otherwise.
683 */ 798 */
684u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, 799static bool
685 struct timeval *tvblank, unsigned flags) 800drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
801 struct timeval *tvblank, unsigned flags)
686{ 802{
687 int ret; 803 int ret;
688 804
@@ -694,7 +810,7 @@ u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
694 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, 810 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error,
695 tvblank, flags); 811 tvblank, flags);
696 if (ret > 0) 812 if (ret > 0)
697 return (u32) ret; 813 return true;
698 } 814 }
699 815
700 /* GPU high precision timestamp query unsupported or failed. 816 /* GPU high precision timestamp query unsupported or failed.
@@ -702,9 +818,8 @@ u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
702 */ 818 */
703 *tvblank = get_drm_timestamp(); 819 *tvblank = get_drm_timestamp();
704 820
705 return 0; 821 return false;
706} 822}
707EXPORT_SYMBOL(drm_get_last_vbltimestamp);
708 823
709/** 824/**
710 * drm_vblank_count - retrieve "cooked" vblank counter value 825 * drm_vblank_count - retrieve "cooked" vblank counter value
@@ -720,7 +835,11 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp);
720 */ 835 */
721u32 drm_vblank_count(struct drm_device *dev, int crtc) 836u32 drm_vblank_count(struct drm_device *dev, int crtc)
722{ 837{
723 return atomic_read(&dev->vblank[crtc].count); 838 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
839
840 if (WARN_ON(crtc >= dev->num_crtcs))
841 return 0;
842 return atomic_read(&vblank->count);
724} 843}
725EXPORT_SYMBOL(drm_vblank_count); 844EXPORT_SYMBOL(drm_vblank_count);
726 845
@@ -740,18 +859,22 @@ EXPORT_SYMBOL(drm_vblank_count);
740u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, 859u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
741 struct timeval *vblanktime) 860 struct timeval *vblanktime)
742{ 861{
862 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
743 u32 cur_vblank; 863 u32 cur_vblank;
744 864
865 if (WARN_ON(crtc >= dev->num_crtcs))
866 return 0;
867
745 /* Read timestamp from slot of _vblank_time ringbuffer 868 /* Read timestamp from slot of _vblank_time ringbuffer
746 * that corresponds to current vblank count. Retry if 869 * that corresponds to current vblank count. Retry if
747 * count has incremented during readout. This works like 870 * count has incremented during readout. This works like
748 * a seqlock. 871 * a seqlock.
749 */ 872 */
750 do { 873 do {
751 cur_vblank = atomic_read(&dev->vblank[crtc].count); 874 cur_vblank = atomic_read(&vblank->count);
752 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); 875 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
753 smp_rmb(); 876 smp_rmb();
754 } while (cur_vblank != atomic_read(&dev->vblank[crtc].count)); 877 } while (cur_vblank != atomic_read(&vblank->count));
755 878
756 return cur_vblank; 879 return cur_vblank;
757} 880}
@@ -800,83 +923,20 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
800EXPORT_SYMBOL(drm_send_vblank_event); 923EXPORT_SYMBOL(drm_send_vblank_event);
801 924
802/** 925/**
803 * drm_update_vblank_count - update the master vblank counter
804 * @dev: DRM device
805 * @crtc: counter to update
806 *
807 * Call back into the driver to update the appropriate vblank counter
808 * (specified by @crtc). Deal with wraparound, if it occurred, and
809 * update the last read value so we can deal with wraparound on the next
810 * call if necessary.
811 *
812 * Only necessary when going from off->on, to account for frames we
813 * didn't get an interrupt for.
814 *
815 * Note: caller must hold dev->vbl_lock since this reads & writes
816 * device vblank fields.
817 */
818static void drm_update_vblank_count(struct drm_device *dev, int crtc)
819{
820 u32 cur_vblank, diff, tslot, rc;
821 struct timeval t_vblank;
822
823 /*
824 * Interrupts were disabled prior to this call, so deal with counter
825 * wrap if needed.
826 * NOTE! It's possible we lost a full dev->max_vblank_count events
827 * here if the register is small or we had vblank interrupts off for
828 * a long time.
829 *
830 * We repeat the hardware vblank counter & timestamp query until
831 * we get consistent results. This to prevent races between gpu
832 * updating its hardware counter while we are retrieving the
833 * corresponding vblank timestamp.
834 */
835 do {
836 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
837 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
838 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
839
840 /* Deal with counter wrap */
841 diff = cur_vblank - dev->vblank[crtc].last;
842 if (cur_vblank < dev->vblank[crtc].last) {
843 diff += dev->max_vblank_count;
844
845 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
846 crtc, dev->vblank[crtc].last, cur_vblank, diff);
847 }
848
849 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
850 crtc, diff);
851
852 /* Reinitialize corresponding vblank timestamp if high-precision query
853 * available. Skip this step if query unsupported or failed. Will
854 * reinitialize delayed at next vblank interrupt in that case.
855 */
856 if (rc) {
857 tslot = atomic_read(&dev->vblank[crtc].count) + diff;
858 vblanktimestamp(dev, crtc, tslot) = t_vblank;
859 }
860
861 smp_mb__before_atomic();
862 atomic_add(diff, &dev->vblank[crtc].count);
863 smp_mb__after_atomic();
864}
865
866/**
867 * drm_vblank_enable - enable the vblank interrupt on a CRTC 926 * drm_vblank_enable - enable the vblank interrupt on a CRTC
868 * @dev: DRM device 927 * @dev: DRM device
869 * @crtc: CRTC in question 928 * @crtc: CRTC in question
870 */ 929 */
871static int drm_vblank_enable(struct drm_device *dev, int crtc) 930static int drm_vblank_enable(struct drm_device *dev, int crtc)
872{ 931{
932 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
873 int ret = 0; 933 int ret = 0;
874 934
875 assert_spin_locked(&dev->vbl_lock); 935 assert_spin_locked(&dev->vbl_lock);
876 936
877 spin_lock(&dev->vblank_time_lock); 937 spin_lock(&dev->vblank_time_lock);
878 938
879 if (!dev->vblank[crtc].enabled) { 939 if (!vblank->enabled) {
880 /* 940 /*
881 * Enable vblank irqs under vblank_time_lock protection. 941 * Enable vblank irqs under vblank_time_lock protection.
882 * All vblank count & timestamp updates are held off 942 * All vblank count & timestamp updates are held off
@@ -887,9 +947,9 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc)
887 ret = dev->driver->enable_vblank(dev, crtc); 947 ret = dev->driver->enable_vblank(dev, crtc);
888 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); 948 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
889 if (ret) 949 if (ret)
890 atomic_dec(&dev->vblank[crtc].refcount); 950 atomic_dec(&vblank->refcount);
891 else { 951 else {
892 dev->vblank[crtc].enabled = true; 952 vblank->enabled = true;
893 drm_update_vblank_count(dev, crtc); 953 drm_update_vblank_count(dev, crtc);
894 } 954 }
895 } 955 }
@@ -914,16 +974,20 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc)
914 */ 974 */
915int drm_vblank_get(struct drm_device *dev, int crtc) 975int drm_vblank_get(struct drm_device *dev, int crtc)
916{ 976{
977 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
917 unsigned long irqflags; 978 unsigned long irqflags;
918 int ret = 0; 979 int ret = 0;
919 980
981 if (WARN_ON(crtc >= dev->num_crtcs))
982 return -EINVAL;
983
920 spin_lock_irqsave(&dev->vbl_lock, irqflags); 984 spin_lock_irqsave(&dev->vbl_lock, irqflags);
921 /* Going from 0->1 means we have to enable interrupts again */ 985 /* Going from 0->1 means we have to enable interrupts again */
922 if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { 986 if (atomic_add_return(1, &vblank->refcount) == 1) {
923 ret = drm_vblank_enable(dev, crtc); 987 ret = drm_vblank_enable(dev, crtc);
924 } else { 988 } else {
925 if (!dev->vblank[crtc].enabled) { 989 if (!vblank->enabled) {
926 atomic_dec(&dev->vblank[crtc].refcount); 990 atomic_dec(&vblank->refcount);
927 ret = -EINVAL; 991 ret = -EINVAL;
928 } 992 }
929 } 993 }
@@ -963,13 +1027,23 @@ EXPORT_SYMBOL(drm_crtc_vblank_get);
963 */ 1027 */
964void drm_vblank_put(struct drm_device *dev, int crtc) 1028void drm_vblank_put(struct drm_device *dev, int crtc)
965{ 1029{
966 BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); 1030 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1031
1032 BUG_ON(atomic_read(&vblank->refcount) == 0);
1033
1034 if (WARN_ON(crtc >= dev->num_crtcs))
1035 return;
967 1036
968 /* Last user schedules interrupt disable */ 1037 /* Last user schedules interrupt disable */
969 if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && 1038 if (atomic_dec_and_test(&vblank->refcount)) {
970 (drm_vblank_offdelay > 0)) 1039 if (drm_vblank_offdelay == 0)
971 mod_timer(&dev->vblank[crtc].disable_timer, 1040 return;
972 jiffies + ((drm_vblank_offdelay * HZ)/1000)); 1041 else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
1042 vblank_disable_fn((unsigned long)vblank);
1043 else
1044 mod_timer(&vblank->disable_timer,
1045 jiffies + ((drm_vblank_offdelay * HZ)/1000));
1046 }
973} 1047}
974EXPORT_SYMBOL(drm_vblank_put); 1048EXPORT_SYMBOL(drm_vblank_put);
975 1049
@@ -989,6 +1063,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc)
989EXPORT_SYMBOL(drm_crtc_vblank_put); 1063EXPORT_SYMBOL(drm_crtc_vblank_put);
990 1064
991/** 1065/**
1066 * drm_wait_one_vblank - wait for one vblank
1067 * @dev: DRM device
1068 * @crtc: crtc index
1069 *
1070 * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
1071 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
1072 * due to lack of driver support or because the crtc is off.
1073 */
1074void drm_wait_one_vblank(struct drm_device *dev, int crtc)
1075{
1076 int ret;
1077 u32 last;
1078
1079 ret = drm_vblank_get(dev, crtc);
1080 if (WARN(ret, "vblank not available on crtc %i, ret=%i\n", crtc, ret))
1081 return;
1082
1083 last = drm_vblank_count(dev, crtc);
1084
1085 ret = wait_event_timeout(dev->vblank[crtc].queue,
1086 last != drm_vblank_count(dev, crtc),
1087 msecs_to_jiffies(100));
1088
1089 WARN(ret == 0, "vblank wait timed out on crtc %i\n", crtc);
1090
1091 drm_vblank_put(dev, crtc);
1092}
1093EXPORT_SYMBOL(drm_wait_one_vblank);
1094
1095/**
1096 * drm_crtc_wait_one_vblank - wait for one vblank
1097 * @crtc: DRM crtc
1098 *
1099 * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
1100 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
1101 * due to lack of driver support or because the crtc is off.
1102 */
1103void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
1104{
1105 drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
1106}
1107EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
1108
1109/**
992 * drm_vblank_off - disable vblank events on a CRTC 1110 * drm_vblank_off - disable vblank events on a CRTC
993 * @dev: DRM device 1111 * @dev: DRM device
994 * @crtc: CRTC in question 1112 * @crtc: CRTC in question
@@ -1004,19 +1122,34 @@ EXPORT_SYMBOL(drm_crtc_vblank_put);
1004 */ 1122 */
1005void drm_vblank_off(struct drm_device *dev, int crtc) 1123void drm_vblank_off(struct drm_device *dev, int crtc)
1006{ 1124{
1125 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1007 struct drm_pending_vblank_event *e, *t; 1126 struct drm_pending_vblank_event *e, *t;
1008 struct timeval now; 1127 struct timeval now;
1009 unsigned long irqflags; 1128 unsigned long irqflags;
1010 unsigned int seq; 1129 unsigned int seq;
1011 1130
1012 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1131 if (WARN_ON(crtc >= dev->num_crtcs))
1132 return;
1133
1134 spin_lock_irqsave(&dev->event_lock, irqflags);
1135
1136 spin_lock(&dev->vbl_lock);
1013 vblank_disable_and_save(dev, crtc); 1137 vblank_disable_and_save(dev, crtc);
1014 wake_up(&dev->vblank[crtc].queue); 1138 wake_up(&vblank->queue);
1139
1140 /*
1141 * Prevent subsequent drm_vblank_get() from re-enabling
1142 * the vblank interrupt by bumping the refcount.
1143 */
1144 if (!vblank->inmodeset) {
1145 atomic_inc(&vblank->refcount);
1146 vblank->inmodeset = 1;
1147 }
1148 spin_unlock(&dev->vbl_lock);
1015 1149
1016 /* Send any queued vblank events, lest the natives grow disquiet */ 1150 /* Send any queued vblank events, lest the natives grow disquiet */
1017 seq = drm_vblank_count_and_time(dev, crtc, &now); 1151 seq = drm_vblank_count_and_time(dev, crtc, &now);
1018 1152
1019 spin_lock(&dev->event_lock);
1020 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1153 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1021 if (e->pipe != crtc) 1154 if (e->pipe != crtc)
1022 continue; 1155 continue;
@@ -1027,9 +1160,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
1027 drm_vblank_put(dev, e->pipe); 1160 drm_vblank_put(dev, e->pipe);
1028 send_vblank_event(dev, e, seq, &now); 1161 send_vblank_event(dev, e, seq, &now);
1029 } 1162 }
1030 spin_unlock(&dev->event_lock); 1163 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1031
1032 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1033} 1164}
1034EXPORT_SYMBOL(drm_vblank_off); 1165EXPORT_SYMBOL(drm_vblank_off);
1035 1166
@@ -1066,11 +1197,35 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
1066 */ 1197 */
1067void drm_vblank_on(struct drm_device *dev, int crtc) 1198void drm_vblank_on(struct drm_device *dev, int crtc)
1068{ 1199{
1200 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1069 unsigned long irqflags; 1201 unsigned long irqflags;
1070 1202
1203 if (WARN_ON(crtc >= dev->num_crtcs))
1204 return;
1205
1071 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1206 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1072 /* re-enable interrupts if there's are users left */ 1207 /* Drop our private "prevent drm_vblank_get" refcount */
1073 if (atomic_read(&dev->vblank[crtc].refcount) != 0) 1208 if (vblank->inmodeset) {
1209 atomic_dec(&vblank->refcount);
1210 vblank->inmodeset = 0;
1211 }
1212
1213 /*
1214 * sample the current counter to avoid random jumps
1215 * when drm_vblank_enable() applies the diff
1216 *
1217 * -1 to make sure user will never see the same
1218 * vblank counter value before and after a modeset
1219 */
1220 vblank->last =
1221 (dev->driver->get_vblank_counter(dev, crtc) - 1) &
1222 dev->max_vblank_count;
1223 /*
1224 * re-enable interrupts if there are users left, or the
1225 * user wishes vblank interrupts to be enabled all the time.
1226 */
1227 if (atomic_read(&vblank->refcount) != 0 ||
1228 (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
1074 WARN_ON(drm_vblank_enable(dev, crtc)); 1229 WARN_ON(drm_vblank_enable(dev, crtc));
1075 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 1230 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1076} 1231}
@@ -1118,9 +1273,15 @@ EXPORT_SYMBOL(drm_crtc_vblank_on);
1118 */ 1273 */
1119void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) 1274void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
1120{ 1275{
1276 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1277
1121 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1278 /* vblank is not initialized (IRQ not installed ?), or has been freed */
1122 if (!dev->num_crtcs) 1279 if (!dev->num_crtcs)
1123 return; 1280 return;
1281
1282 if (WARN_ON(crtc >= dev->num_crtcs))
1283 return;
1284
1124 /* 1285 /*
1125 * To avoid all the problems that might happen if interrupts 1286 * To avoid all the problems that might happen if interrupts
1126 * were enabled/disabled around or between these calls, we just 1287 * were enabled/disabled around or between these calls, we just
@@ -1128,10 +1289,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
1128 * to avoid corrupting the count if multiple, mismatch calls occur), 1289 * to avoid corrupting the count if multiple, mismatch calls occur),
1129 * so that interrupts remain enabled in the interim. 1290 * so that interrupts remain enabled in the interim.
1130 */ 1291 */
1131 if (!dev->vblank[crtc].inmodeset) { 1292 if (!vblank->inmodeset) {
1132 dev->vblank[crtc].inmodeset = 0x1; 1293 vblank->inmodeset = 0x1;
1133 if (drm_vblank_get(dev, crtc) == 0) 1294 if (drm_vblank_get(dev, crtc) == 0)
1134 dev->vblank[crtc].inmodeset |= 0x2; 1295 vblank->inmodeset |= 0x2;
1135 } 1296 }
1136} 1297}
1137EXPORT_SYMBOL(drm_vblank_pre_modeset); 1298EXPORT_SYMBOL(drm_vblank_pre_modeset);
@@ -1146,21 +1307,22 @@ EXPORT_SYMBOL(drm_vblank_pre_modeset);
1146 */ 1307 */
1147void drm_vblank_post_modeset(struct drm_device *dev, int crtc) 1308void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
1148{ 1309{
1310 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1149 unsigned long irqflags; 1311 unsigned long irqflags;
1150 1312
1151 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1313 /* vblank is not initialized (IRQ not installed ?), or has been freed */
1152 if (!dev->num_crtcs) 1314 if (!dev->num_crtcs)
1153 return; 1315 return;
1154 1316
1155 if (dev->vblank[crtc].inmodeset) { 1317 if (vblank->inmodeset) {
1156 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1318 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1157 dev->vblank_disable_allowed = true; 1319 dev->vblank_disable_allowed = true;
1158 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 1320 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1159 1321
1160 if (dev->vblank[crtc].inmodeset & 0x2) 1322 if (vblank->inmodeset & 0x2)
1161 drm_vblank_put(dev, crtc); 1323 drm_vblank_put(dev, crtc);
1162 1324
1163 dev->vblank[crtc].inmodeset = 0; 1325 vblank->inmodeset = 0;
1164 } 1326 }
1165} 1327}
1166EXPORT_SYMBOL(drm_vblank_post_modeset); 1328EXPORT_SYMBOL(drm_vblank_post_modeset);
@@ -1212,6 +1374,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1212 union drm_wait_vblank *vblwait, 1374 union drm_wait_vblank *vblwait,
1213 struct drm_file *file_priv) 1375 struct drm_file *file_priv)
1214{ 1376{
1377 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1215 struct drm_pending_vblank_event *e; 1378 struct drm_pending_vblank_event *e;
1216 struct timeval now; 1379 struct timeval now;
1217 unsigned long flags; 1380 unsigned long flags;
@@ -1235,6 +1398,18 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1235 1398
1236 spin_lock_irqsave(&dev->event_lock, flags); 1399 spin_lock_irqsave(&dev->event_lock, flags);
1237 1400
1401 /*
1402 * drm_vblank_off() might have been called after we called
1403 * drm_vblank_get(). drm_vblank_off() holds event_lock
1404 * around the vblank disable, so no need for further locking.
1405 * The reference from drm_vblank_get() protects against
1406 * vblank disable from another source.
1407 */
1408 if (!vblank->enabled) {
1409 ret = -EINVAL;
1410 goto err_unlock;
1411 }
1412
1238 if (file_priv->event_space < sizeof e->event) { 1413 if (file_priv->event_space < sizeof e->event) {
1239 ret = -EBUSY; 1414 ret = -EBUSY;
1240 goto err_unlock; 1415 goto err_unlock;
@@ -1295,6 +1470,7 @@ err_put:
1295int drm_wait_vblank(struct drm_device *dev, void *data, 1470int drm_wait_vblank(struct drm_device *dev, void *data,
1296 struct drm_file *file_priv) 1471 struct drm_file *file_priv)
1297{ 1472{
1473 struct drm_vblank_crtc *vblank;
1298 union drm_wait_vblank *vblwait = data; 1474 union drm_wait_vblank *vblwait = data;
1299 int ret; 1475 int ret;
1300 unsigned int flags, seq, crtc, high_crtc; 1476 unsigned int flags, seq, crtc, high_crtc;
@@ -1324,6 +1500,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1324 if (crtc >= dev->num_crtcs) 1500 if (crtc >= dev->num_crtcs)
1325 return -EINVAL; 1501 return -EINVAL;
1326 1502
1503 vblank = &dev->vblank[crtc];
1504
1327 ret = drm_vblank_get(dev, crtc); 1505 ret = drm_vblank_get(dev, crtc);
1328 if (ret) { 1506 if (ret) {
1329 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); 1507 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret);
@@ -1356,11 +1534,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1356 1534
1357 DRM_DEBUG("waiting on vblank count %d, crtc %d\n", 1535 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
1358 vblwait->request.sequence, crtc); 1536 vblwait->request.sequence, crtc);
1359 dev->vblank[crtc].last_wait = vblwait->request.sequence; 1537 vblank->last_wait = vblwait->request.sequence;
1360 DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * HZ, 1538 DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
1361 (((drm_vblank_count(dev, crtc) - 1539 (((drm_vblank_count(dev, crtc) -
1362 vblwait->request.sequence) <= (1 << 23)) || 1540 vblwait->request.sequence) <= (1 << 23)) ||
1363 !dev->vblank[crtc].enabled || 1541 !vblank->enabled ||
1364 !dev->irq_enabled)); 1542 !dev->irq_enabled));
1365 1543
1366 if (ret != -EINTR) { 1544 if (ret != -EINTR) {
@@ -1385,12 +1563,11 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1385{ 1563{
1386 struct drm_pending_vblank_event *e, *t; 1564 struct drm_pending_vblank_event *e, *t;
1387 struct timeval now; 1565 struct timeval now;
1388 unsigned long flags;
1389 unsigned int seq; 1566 unsigned int seq;
1390 1567
1391 seq = drm_vblank_count_and_time(dev, crtc, &now); 1568 assert_spin_locked(&dev->event_lock);
1392 1569
1393 spin_lock_irqsave(&dev->event_lock, flags); 1570 seq = drm_vblank_count_and_time(dev, crtc, &now);
1394 1571
1395 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1572 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1396 if (e->pipe != crtc) 1573 if (e->pipe != crtc)
@@ -1406,8 +1583,6 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1406 send_vblank_event(dev, e, seq, &now); 1583 send_vblank_event(dev, e, seq, &now);
1407 } 1584 }
1408 1585
1409 spin_unlock_irqrestore(&dev->event_lock, flags);
1410
1411 trace_drm_vblank_event(crtc, seq); 1586 trace_drm_vblank_event(crtc, seq);
1412} 1587}
1413 1588
@@ -1421,6 +1596,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1421 */ 1596 */
1422bool drm_handle_vblank(struct drm_device *dev, int crtc) 1597bool drm_handle_vblank(struct drm_device *dev, int crtc)
1423{ 1598{
1599 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1424 u32 vblcount; 1600 u32 vblcount;
1425 s64 diff_ns; 1601 s64 diff_ns;
1426 struct timeval tvblank; 1602 struct timeval tvblank;
@@ -1429,15 +1605,21 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1429 if (!dev->num_crtcs) 1605 if (!dev->num_crtcs)
1430 return false; 1606 return false;
1431 1607
1608 if (WARN_ON(crtc >= dev->num_crtcs))
1609 return false;
1610
1611 spin_lock_irqsave(&dev->event_lock, irqflags);
1612
1432 /* Need timestamp lock to prevent concurrent execution with 1613 /* Need timestamp lock to prevent concurrent execution with
1433 * vblank enable/disable, as this would cause inconsistent 1614 * vblank enable/disable, as this would cause inconsistent
1434 * or corrupted timestamps and vblank counts. 1615 * or corrupted timestamps and vblank counts.
1435 */ 1616 */
1436 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); 1617 spin_lock(&dev->vblank_time_lock);
1437 1618
1438 /* Vblank irq handling disabled. Nothing to do. */ 1619 /* Vblank irq handling disabled. Nothing to do. */
1439 if (!dev->vblank[crtc].enabled) { 1620 if (!vblank->enabled) {
1440 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 1621 spin_unlock(&dev->vblank_time_lock);
1622 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1441 return false; 1623 return false;
1442 } 1624 }
1443 1625
@@ -1446,7 +1628,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1446 */ 1628 */
1447 1629
1448 /* Get current timestamp and count. */ 1630 /* Get current timestamp and count. */
1449 vblcount = atomic_read(&dev->vblank[crtc].count); 1631 vblcount = atomic_read(&vblank->count);
1450 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); 1632 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
1451 1633
1452 /* Compute time difference to timestamp of last vblank */ 1634 /* Compute time difference to timestamp of last vblank */
@@ -1470,17 +1652,20 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1470 * the timestamp computed above. 1652 * the timestamp computed above.
1471 */ 1653 */
1472 smp_mb__before_atomic(); 1654 smp_mb__before_atomic();
1473 atomic_inc(&dev->vblank[crtc].count); 1655 atomic_inc(&vblank->count);
1474 smp_mb__after_atomic(); 1656 smp_mb__after_atomic();
1475 } else { 1657 } else {
1476 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", 1658 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
1477 crtc, (int) diff_ns); 1659 crtc, (int) diff_ns);
1478 } 1660 }
1479 1661
1480 wake_up(&dev->vblank[crtc].queue); 1662 spin_unlock(&dev->vblank_time_lock);
1663
1664 wake_up(&vblank->queue);
1481 drm_handle_vblank_events(dev, crtc); 1665 drm_handle_vblank_events(dev, crtc);
1482 1666
1483 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 1667 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1668
1484 return true; 1669 return true;
1485} 1670}
1486EXPORT_SYMBOL(drm_handle_vblank); 1671EXPORT_SYMBOL(drm_handle_vblank);