aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-09-12 05:04:53 -0400
committerDave Airlie <airlied@redhat.com>2014-09-12 05:04:53 -0400
commitedbaae5a5cab89de0e64b8c03ebd9a8d5d266550 (patch)
tree97844f26ad675a37a74c70ea715f42b891827fa4
parenta9d6dd2554e35c0213382fff19f5dbf151707955 (diff)
parent336879b1da97fffc097f77c6d6f818660f2826f0 (diff)
Merge tag 'topic/vblank-rework-2014-09-12' of git://anongit.freedesktop.org/drm-intel into drm-next
So updated vblank-rework pull request, now with the polish that Mario requested applied (and reviewed by him). Also with backmerge like you've requested for easier merging. The neat thing this finally allows is to immediately disable the vblank interrupt on the last drm_vblank_put if the hardware has perfectly accurate vblank counter and timestamp readout support. On i915 that required piles of small adjustements from Ville since depending upon the platform and port the vblank happens at different scanout lines. Of course this is fully opt-in and per-device (we need that since gen2 doesn't have a hw vblank counter). * tag 'topic/vblank-rework-2014-09-12' of git://anongit.freedesktop.org/drm-intel: (22 commits) drm: Clarify vblank ts/scanoutpos sampling #defines drm: Simplify return value of drm_get_last_vbltimestamp drm: Only update final vblank count when precise ts is available drm: Really never disable vblank irqs for offdelay==0 drm: Use vblank_disable_and_save in drm_vblank_cleanup() drm: Remove drm_vblank_cleanup from drm_vblank_init error path. drm: Store the vblank timestamp when adjusting the counter during disable drm: Fix confusing debug message in drm_update_vblank_count() drm/i915: Update scanline_offset only for active crtcs drm: Kick start vblank interrupts at drm_vblank_on() drm/i915: Opt out of vblank disable timer on >gen2 drm: Add dev->vblank_disable_immediate flag drm: Disable vblank interrupt immediately when drm_vblank_offdelay<0 drm: Fix race between drm_vblank_off() and drm_queue_vblank_event() drm: Fix deadlock between event_lock and vbl_lock/vblank_time_lock drm: Reduce the amount of dev->vblank[crtc] in the code drm: Avoid random vblank counter jumps if the hardware counter has been reset drm: Have the vblank counter account for the time between vblank irq disable and drm_vblank_off() drm: Move drm_update_vblank_count() drm: Don't clear vblank timestamps when vblank interrupt is disabled ...
-rw-r--r--Documentation/DocBook/drm.tmpl7
-rw-r--r--drivers/gpu/drm/drm_drv.c4
-rw-r--r--drivers/gpu/drm/drm_irq.c379
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
-rw-r--r--drivers/gpu/drm/i915/intel_display.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c2
-rw-r--r--include/drm/drmP.h18
9 files changed, 286 insertions, 155 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 1fce7dc46d87..ca44d9fe7d7d 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -3385,6 +3385,13 @@ void (*disable_vblank) (struct drm_device *dev, int crtc);</synopsis>
3385 by scheduling a timer. The delay is accessible through the vblankoffdelay 3385 by scheduling a timer. The delay is accessible through the vblankoffdelay
3386 module parameter or the <varname>drm_vblank_offdelay</varname> global 3386 module parameter or the <varname>drm_vblank_offdelay</varname> global
3387 variable and expressed in milliseconds. Its default value is 5000 ms. 3387 variable and expressed in milliseconds. Its default value is 5000 ms.
3388 Zero means never disable, and a negative value means disable immediately.
3389 Drivers may override the behaviour by setting the
3390 <structname>drm_device</structname>
3391 <structfield>vblank_disable_immediate</structfield> flag, which when set
3392 causes vblank interrupts to be disabled immediately regardless of the
3393 drm_vblank_offdelay value. The flag should only be set if there's a
3394 properly working hardware vblank counter present.
3388 </para> 3395 </para>
3389 <para> 3396 <para>
3390 When a vertical blanking interrupt occurs drivers only need to call the 3397 When a vertical blanking interrupt occurs drivers only need to call the
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 66456698447e..970613c5a1eb 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -39,7 +39,7 @@
39unsigned int drm_debug = 0; /* 1 to enable debug output */ 39unsigned int drm_debug = 0; /* 1 to enable debug output */
40EXPORT_SYMBOL(drm_debug); 40EXPORT_SYMBOL(drm_debug);
41 41
42unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ 42int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
43 43
44unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ 44unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */
45 45
@@ -53,7 +53,7 @@ MODULE_AUTHOR(CORE_AUTHOR);
53MODULE_DESCRIPTION(CORE_DESC); 53MODULE_DESCRIPTION(CORE_DESC);
54MODULE_LICENSE("GPL and additional rights"); 54MODULE_LICENSE("GPL and additional rights");
55MODULE_PARM_DESC(debug, "Enable debug output"); 55MODULE_PARM_DESC(debug, "Enable debug output");
56MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); 56MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)");
57MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); 57MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]");
58MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); 58MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps");
59 59
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 5708c056fa1b..034297640b48 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -55,12 +55,74 @@
55 */ 55 */
56#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 56#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
57 57
58/* 58static bool
59 * Clear vblank timestamp buffer for a crtc. 59drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
60 struct timeval *tvblank, unsigned flags);
61
62/**
63 * drm_update_vblank_count - update the master vblank counter
64 * @dev: DRM device
65 * @crtc: counter to update
66 *
67 * Call back into the driver to update the appropriate vblank counter
68 * (specified by @crtc). Deal with wraparound, if it occurred, and
69 * update the last read value so we can deal with wraparound on the next
70 * call if necessary.
71 *
72 * Only necessary when going from off->on, to account for frames we
73 * didn't get an interrupt for.
74 *
75 * Note: caller must hold dev->vbl_lock since this reads & writes
76 * device vblank fields.
60 */ 77 */
61static void clear_vblank_timestamps(struct drm_device *dev, int crtc) 78static void drm_update_vblank_count(struct drm_device *dev, int crtc)
62{ 79{
63 memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time)); 80 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
81 u32 cur_vblank, diff, tslot;
82 bool rc;
83 struct timeval t_vblank;
84
85 /*
86 * Interrupts were disabled prior to this call, so deal with counter
87 * wrap if needed.
88 * NOTE! It's possible we lost a full dev->max_vblank_count events
89 * here if the register is small or we had vblank interrupts off for
90 * a long time.
91 *
92 * We repeat the hardware vblank counter & timestamp query until
93 * we get consistent results. This to prevent races between gpu
94 * updating its hardware counter while we are retrieving the
95 * corresponding vblank timestamp.
96 */
97 do {
98 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
99 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
100 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
101
102 /* Deal with counter wrap */
103 diff = cur_vblank - vblank->last;
104 if (cur_vblank < vblank->last) {
105 diff += dev->max_vblank_count;
106
107 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
108 crtc, vblank->last, cur_vblank, diff);
109 }
110
111 DRM_DEBUG("updating vblank count on crtc %d, missed %d\n",
112 crtc, diff);
113
114 /* Reinitialize corresponding vblank timestamp if high-precision query
115 * available. Skip this step if query unsupported or failed. Will
116 * reinitialize delayed at next vblank interrupt in that case.
117 */
118 if (rc) {
119 tslot = atomic_read(&vblank->count) + diff;
120 vblanktimestamp(dev, crtc, tslot) = t_vblank;
121 }
122
123 smp_mb__before_atomic();
124 atomic_add(diff, &vblank->count);
125 smp_mb__after_atomic();
64} 126}
65 127
66/* 128/*
@@ -71,10 +133,11 @@ static void clear_vblank_timestamps(struct drm_device *dev, int crtc)
71 */ 133 */
72static void vblank_disable_and_save(struct drm_device *dev, int crtc) 134static void vblank_disable_and_save(struct drm_device *dev, int crtc)
73{ 135{
136 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
74 unsigned long irqflags; 137 unsigned long irqflags;
75 u32 vblcount; 138 u32 vblcount;
76 s64 diff_ns; 139 s64 diff_ns;
77 int vblrc; 140 bool vblrc;
78 struct timeval tvblank; 141 struct timeval tvblank;
79 int count = DRM_TIMESTAMP_MAXRETRIES; 142 int count = DRM_TIMESTAMP_MAXRETRIES;
80 143
@@ -84,8 +147,28 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
84 */ 147 */
85 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); 148 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
86 149
150 /*
151 * If the vblank interrupt was already disbled update the count
152 * and timestamp to maintain the appearance that the counter
153 * has been ticking all along until this time. This makes the
154 * count account for the entire time between drm_vblank_on() and
155 * drm_vblank_off().
156 *
157 * But only do this if precise vblank timestamps are available.
158 * Otherwise we might read a totally bogus timestamp since drivers
159 * lacking precise timestamp support rely upon sampling the system clock
160 * at vblank interrupt time. Which obviously won't work out well if the
161 * vblank interrupt is disabled.
162 */
163 if (!vblank->enabled &&
164 drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0)) {
165 drm_update_vblank_count(dev, crtc);
166 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
167 return;
168 }
169
87 dev->driver->disable_vblank(dev, crtc); 170 dev->driver->disable_vblank(dev, crtc);
88 dev->vblank[crtc].enabled = false; 171 vblank->enabled = false;
89 172
90 /* No further vblank irq's will be processed after 173 /* No further vblank irq's will be processed after
91 * this point. Get current hardware vblank count and 174 * this point. Get current hardware vblank count and
@@ -100,9 +183,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
100 * delayed gpu counter increment. 183 * delayed gpu counter increment.
101 */ 184 */
102 do { 185 do {
103 dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc); 186 vblank->last = dev->driver->get_vblank_counter(dev, crtc);
104 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); 187 vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0);
105 } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); 188 } while (vblank->last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc);
106 189
107 if (!count) 190 if (!count)
108 vblrc = 0; 191 vblrc = 0;
@@ -110,7 +193,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc)
110 /* Compute time difference to stored timestamp of last vblank 193 /* Compute time difference to stored timestamp of last vblank
111 * as updated by last invocation of drm_handle_vblank() in vblank irq. 194 * as updated by last invocation of drm_handle_vblank() in vblank irq.
112 */ 195 */
113 vblcount = atomic_read(&dev->vblank[crtc].count); 196 vblcount = atomic_read(&vblank->count);
114 diff_ns = timeval_to_ns(&tvblank) - 197 diff_ns = timeval_to_ns(&tvblank) -
115 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); 198 timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount));
116 199
@@ -126,14 +209,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 209 * available. In that case we can't account for this and just
127 * hope for the best. 210 * hope for the best.
128 */ 211 */
129 if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { 212 if (vblrc && (abs64(diff_ns) > 1000000)) {
130 atomic_inc(&dev->vblank[crtc].count); 213 /* Store new timestamp in ringbuffer. */
214 vblanktimestamp(dev, crtc, vblcount + 1) = tvblank;
215
216 /* Increment cooked vblank count. This also atomically commits
217 * the timestamp computed above.
218 */
219 smp_mb__before_atomic();
220 atomic_inc(&vblank->count);
131 smp_mb__after_atomic(); 221 smp_mb__after_atomic();
132 } 222 }
133 223
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); 224 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
138} 225}
139 226
@@ -164,14 +251,20 @@ static void vblank_disable_fn(unsigned long arg)
164void drm_vblank_cleanup(struct drm_device *dev) 251void drm_vblank_cleanup(struct drm_device *dev)
165{ 252{
166 int crtc; 253 int crtc;
254 unsigned long irqflags;
167 255
168 /* Bail if the driver didn't call drm_vblank_init() */ 256 /* Bail if the driver didn't call drm_vblank_init() */
169 if (dev->num_crtcs == 0) 257 if (dev->num_crtcs == 0)
170 return; 258 return;
171 259
172 for (crtc = 0; crtc < dev->num_crtcs; crtc++) { 260 for (crtc = 0; crtc < dev->num_crtcs; crtc++) {
173 del_timer_sync(&dev->vblank[crtc].disable_timer); 261 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
174 vblank_disable_fn((unsigned long)&dev->vblank[crtc]); 262
263 del_timer_sync(&vblank->disable_timer);
264
265 spin_lock_irqsave(&dev->vbl_lock, irqflags);
266 vblank_disable_and_save(dev, crtc);
267 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
175 } 268 }
176 269
177 kfree(dev->vblank); 270 kfree(dev->vblank);
@@ -204,11 +297,13 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
204 goto err; 297 goto err;
205 298
206 for (i = 0; i < num_crtcs; i++) { 299 for (i = 0; i < num_crtcs; i++) {
207 dev->vblank[i].dev = dev; 300 struct drm_vblank_crtc *vblank = &dev->vblank[i];
208 dev->vblank[i].crtc = i; 301
209 init_waitqueue_head(&dev->vblank[i].queue); 302 vblank->dev = dev;
210 setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn, 303 vblank->crtc = i;
211 (unsigned long)&dev->vblank[i]); 304 init_waitqueue_head(&vblank->queue);
305 setup_timer(&vblank->disable_timer, vblank_disable_fn,
306 (unsigned long)vblank);
212 } 307 }
213 308
214 DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); 309 DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n");
@@ -224,7 +319,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs)
224 return 0; 319 return 0;
225 320
226err: 321err:
227 drm_vblank_cleanup(dev); 322 dev->num_crtcs = 0;
228 return ret; 323 return ret;
229} 324}
230EXPORT_SYMBOL(drm_vblank_init); 325EXPORT_SYMBOL(drm_vblank_init);
@@ -360,9 +455,11 @@ int drm_irq_uninstall(struct drm_device *dev)
360 if (dev->num_crtcs) { 455 if (dev->num_crtcs) {
361 spin_lock_irqsave(&dev->vbl_lock, irqflags); 456 spin_lock_irqsave(&dev->vbl_lock, irqflags);
362 for (i = 0; i < dev->num_crtcs; i++) { 457 for (i = 0; i < dev->num_crtcs; i++) {
363 wake_up(&dev->vblank[i].queue); 458 struct drm_vblank_crtc *vblank = &dev->vblank[i];
364 dev->vblank[i].enabled = false; 459
365 dev->vblank[i].last = 460 wake_up(&vblank->queue);
461 vblank->enabled = false;
462 vblank->last =
366 dev->driver->get_vblank_counter(dev, i); 463 dev->driver->get_vblank_counter(dev, i);
367 } 464 }
368 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 465 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
@@ -617,7 +714,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
617 * within vblank area, counting down the number of lines until 714 * within vblank area, counting down the number of lines until
618 * start of scanout. 715 * start of scanout.
619 */ 716 */
620 invbl = vbl_status & DRM_SCANOUTPOS_INVBL; 717 invbl = vbl_status & DRM_SCANOUTPOS_IN_VBLANK;
621 718
622 /* Convert scanout position into elapsed time at raw_time query 719 /* Convert scanout position into elapsed time at raw_time query
623 * since start of scanout at first display scanline. delta_ns 720 * since start of scanout at first display scanline. delta_ns
@@ -647,7 +744,7 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc,
647 744
648 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 745 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
649 if (invbl) 746 if (invbl)
650 vbl_status |= DRM_VBLANKTIME_INVBL; 747 vbl_status |= DRM_VBLANKTIME_IN_VBLANK;
651 748
652 return vbl_status; 749 return vbl_status;
653} 750}
@@ -679,10 +776,11 @@ static struct timeval get_drm_timestamp(void)
679 * call, i.e., it isn't very precisely locked to the true vblank. 776 * call, i.e., it isn't very precisely locked to the true vblank.
680 * 777 *
681 * Returns: 778 * Returns:
682 * Non-zero if timestamp is considered to be very precise, zero otherwise. 779 * True if timestamp is considered to be very precise, false otherwise.
683 */ 780 */
684u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, 781static bool
685 struct timeval *tvblank, unsigned flags) 782drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
783 struct timeval *tvblank, unsigned flags)
686{ 784{
687 int ret; 785 int ret;
688 786
@@ -694,7 +792,7 @@ u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
694 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, 792 ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error,
695 tvblank, flags); 793 tvblank, flags);
696 if (ret > 0) 794 if (ret > 0)
697 return (u32) ret; 795 return true;
698 } 796 }
699 797
700 /* GPU high precision timestamp query unsupported or failed. 798 /* GPU high precision timestamp query unsupported or failed.
@@ -702,9 +800,8 @@ u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
702 */ 800 */
703 *tvblank = get_drm_timestamp(); 801 *tvblank = get_drm_timestamp();
704 802
705 return 0; 803 return false;
706} 804}
707EXPORT_SYMBOL(drm_get_last_vbltimestamp);
708 805
709/** 806/**
710 * drm_vblank_count - retrieve "cooked" vblank counter value 807 * drm_vblank_count - retrieve "cooked" vblank counter value
@@ -720,9 +817,11 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp);
720 */ 817 */
721u32 drm_vblank_count(struct drm_device *dev, int crtc) 818u32 drm_vblank_count(struct drm_device *dev, int crtc)
722{ 819{
820 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
821
723 if (WARN_ON(crtc >= dev->num_crtcs)) 822 if (WARN_ON(crtc >= dev->num_crtcs))
724 return 0; 823 return 0;
725 return atomic_read(&dev->vblank[crtc].count); 824 return atomic_read(&vblank->count);
726} 825}
727EXPORT_SYMBOL(drm_vblank_count); 826EXPORT_SYMBOL(drm_vblank_count);
728 827
@@ -742,6 +841,7 @@ EXPORT_SYMBOL(drm_vblank_count);
742u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, 841u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
743 struct timeval *vblanktime) 842 struct timeval *vblanktime)
744{ 843{
844 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
745 u32 cur_vblank; 845 u32 cur_vblank;
746 846
747 if (WARN_ON(crtc >= dev->num_crtcs)) 847 if (WARN_ON(crtc >= dev->num_crtcs))
@@ -753,10 +853,10 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc,
753 * a seqlock. 853 * a seqlock.
754 */ 854 */
755 do { 855 do {
756 cur_vblank = atomic_read(&dev->vblank[crtc].count); 856 cur_vblank = atomic_read(&vblank->count);
757 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); 857 *vblanktime = vblanktimestamp(dev, crtc, cur_vblank);
758 smp_rmb(); 858 smp_rmb();
759 } while (cur_vblank != atomic_read(&dev->vblank[crtc].count)); 859 } while (cur_vblank != atomic_read(&vblank->count));
760 860
761 return cur_vblank; 861 return cur_vblank;
762} 862}
@@ -805,83 +905,20 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
805EXPORT_SYMBOL(drm_send_vblank_event); 905EXPORT_SYMBOL(drm_send_vblank_event);
806 906
807/** 907/**
808 * drm_update_vblank_count - update the master vblank counter
809 * @dev: DRM device
810 * @crtc: counter to update
811 *
812 * Call back into the driver to update the appropriate vblank counter
813 * (specified by @crtc). Deal with wraparound, if it occurred, and
814 * update the last read value so we can deal with wraparound on the next
815 * call if necessary.
816 *
817 * Only necessary when going from off->on, to account for frames we
818 * didn't get an interrupt for.
819 *
820 * Note: caller must hold dev->vbl_lock since this reads & writes
821 * device vblank fields.
822 */
823static void drm_update_vblank_count(struct drm_device *dev, int crtc)
824{
825 u32 cur_vblank, diff, tslot, rc;
826 struct timeval t_vblank;
827
828 /*
829 * Interrupts were disabled prior to this call, so deal with counter
830 * wrap if needed.
831 * NOTE! It's possible we lost a full dev->max_vblank_count events
832 * here if the register is small or we had vblank interrupts off for
833 * a long time.
834 *
835 * We repeat the hardware vblank counter & timestamp query until
836 * we get consistent results. This to prevent races between gpu
837 * updating its hardware counter while we are retrieving the
838 * corresponding vblank timestamp.
839 */
840 do {
841 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
842 rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0);
843 } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc));
844
845 /* Deal with counter wrap */
846 diff = cur_vblank - dev->vblank[crtc].last;
847 if (cur_vblank < dev->vblank[crtc].last) {
848 diff += dev->max_vblank_count;
849
850 DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
851 crtc, dev->vblank[crtc].last, cur_vblank, diff);
852 }
853
854 DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
855 crtc, diff);
856
857 /* Reinitialize corresponding vblank timestamp if high-precision query
858 * available. Skip this step if query unsupported or failed. Will
859 * reinitialize delayed at next vblank interrupt in that case.
860 */
861 if (rc) {
862 tslot = atomic_read(&dev->vblank[crtc].count) + diff;
863 vblanktimestamp(dev, crtc, tslot) = t_vblank;
864 }
865
866 smp_mb__before_atomic();
867 atomic_add(diff, &dev->vblank[crtc].count);
868 smp_mb__after_atomic();
869}
870
871/**
872 * drm_vblank_enable - enable the vblank interrupt on a CRTC 908 * drm_vblank_enable - enable the vblank interrupt on a CRTC
873 * @dev: DRM device 909 * @dev: DRM device
874 * @crtc: CRTC in question 910 * @crtc: CRTC in question
875 */ 911 */
876static int drm_vblank_enable(struct drm_device *dev, int crtc) 912static int drm_vblank_enable(struct drm_device *dev, int crtc)
877{ 913{
914 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
878 int ret = 0; 915 int ret = 0;
879 916
880 assert_spin_locked(&dev->vbl_lock); 917 assert_spin_locked(&dev->vbl_lock);
881 918
882 spin_lock(&dev->vblank_time_lock); 919 spin_lock(&dev->vblank_time_lock);
883 920
884 if (!dev->vblank[crtc].enabled) { 921 if (!vblank->enabled) {
885 /* 922 /*
886 * Enable vblank irqs under vblank_time_lock protection. 923 * Enable vblank irqs under vblank_time_lock protection.
887 * All vblank count & timestamp updates are held off 924 * All vblank count & timestamp updates are held off
@@ -892,9 +929,9 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc)
892 ret = dev->driver->enable_vblank(dev, crtc); 929 ret = dev->driver->enable_vblank(dev, crtc);
893 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); 930 DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
894 if (ret) 931 if (ret)
895 atomic_dec(&dev->vblank[crtc].refcount); 932 atomic_dec(&vblank->refcount);
896 else { 933 else {
897 dev->vblank[crtc].enabled = true; 934 vblank->enabled = true;
898 drm_update_vblank_count(dev, crtc); 935 drm_update_vblank_count(dev, crtc);
899 } 936 }
900 } 937 }
@@ -919,6 +956,7 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc)
919 */ 956 */
920int drm_vblank_get(struct drm_device *dev, int crtc) 957int drm_vblank_get(struct drm_device *dev, int crtc)
921{ 958{
959 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
922 unsigned long irqflags; 960 unsigned long irqflags;
923 int ret = 0; 961 int ret = 0;
924 962
@@ -927,11 +965,11 @@ int drm_vblank_get(struct drm_device *dev, int crtc)
927 965
928 spin_lock_irqsave(&dev->vbl_lock, irqflags); 966 spin_lock_irqsave(&dev->vbl_lock, irqflags);
929 /* Going from 0->1 means we have to enable interrupts again */ 967 /* Going from 0->1 means we have to enable interrupts again */
930 if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { 968 if (atomic_add_return(1, &vblank->refcount) == 1) {
931 ret = drm_vblank_enable(dev, crtc); 969 ret = drm_vblank_enable(dev, crtc);
932 } else { 970 } else {
933 if (!dev->vblank[crtc].enabled) { 971 if (!vblank->enabled) {
934 atomic_dec(&dev->vblank[crtc].refcount); 972 atomic_dec(&vblank->refcount);
935 ret = -EINVAL; 973 ret = -EINVAL;
936 } 974 }
937 } 975 }
@@ -971,16 +1009,23 @@ EXPORT_SYMBOL(drm_crtc_vblank_get);
971 */ 1009 */
972void drm_vblank_put(struct drm_device *dev, int crtc) 1010void drm_vblank_put(struct drm_device *dev, int crtc)
973{ 1011{
974 BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); 1012 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1013
1014 BUG_ON(atomic_read(&vblank->refcount) == 0);
975 1015
976 if (WARN_ON(crtc >= dev->num_crtcs)) 1016 if (WARN_ON(crtc >= dev->num_crtcs))
977 return; 1017 return;
978 1018
979 /* Last user schedules interrupt disable */ 1019 /* Last user schedules interrupt disable */
980 if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && 1020 if (atomic_dec_and_test(&vblank->refcount)) {
981 (drm_vblank_offdelay > 0)) 1021 if (drm_vblank_offdelay == 0)
982 mod_timer(&dev->vblank[crtc].disable_timer, 1022 return;
983 jiffies + ((drm_vblank_offdelay * HZ)/1000)); 1023 else if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0)
1024 vblank_disable_fn((unsigned long)vblank);
1025 else
1026 mod_timer(&vblank->disable_timer,
1027 jiffies + ((drm_vblank_offdelay * HZ)/1000));
1028 }
984} 1029}
985EXPORT_SYMBOL(drm_vblank_put); 1030EXPORT_SYMBOL(drm_vblank_put);
986 1031
@@ -1059,6 +1104,7 @@ EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
1059 */ 1104 */
1060void drm_vblank_off(struct drm_device *dev, int crtc) 1105void drm_vblank_off(struct drm_device *dev, int crtc)
1061{ 1106{
1107 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1062 struct drm_pending_vblank_event *e, *t; 1108 struct drm_pending_vblank_event *e, *t;
1063 struct timeval now; 1109 struct timeval now;
1064 unsigned long irqflags; 1110 unsigned long irqflags;
@@ -1067,14 +1113,25 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
1067 if (WARN_ON(crtc >= dev->num_crtcs)) 1113 if (WARN_ON(crtc >= dev->num_crtcs))
1068 return; 1114 return;
1069 1115
1070 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1116 spin_lock_irqsave(&dev->event_lock, irqflags);
1117
1118 spin_lock(&dev->vbl_lock);
1071 vblank_disable_and_save(dev, crtc); 1119 vblank_disable_and_save(dev, crtc);
1072 wake_up(&dev->vblank[crtc].queue); 1120 wake_up(&vblank->queue);
1121
1122 /*
1123 * Prevent subsequent drm_vblank_get() from re-enabling
1124 * the vblank interrupt by bumping the refcount.
1125 */
1126 if (!vblank->inmodeset) {
1127 atomic_inc(&vblank->refcount);
1128 vblank->inmodeset = 1;
1129 }
1130 spin_unlock(&dev->vbl_lock);
1073 1131
1074 /* Send any queued vblank events, lest the natives grow disquiet */ 1132 /* Send any queued vblank events, lest the natives grow disquiet */
1075 seq = drm_vblank_count_and_time(dev, crtc, &now); 1133 seq = drm_vblank_count_and_time(dev, crtc, &now);
1076 1134
1077 spin_lock(&dev->event_lock);
1078 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1135 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1079 if (e->pipe != crtc) 1136 if (e->pipe != crtc)
1080 continue; 1137 continue;
@@ -1085,9 +1142,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc)
1085 drm_vblank_put(dev, e->pipe); 1142 drm_vblank_put(dev, e->pipe);
1086 send_vblank_event(dev, e, seq, &now); 1143 send_vblank_event(dev, e, seq, &now);
1087 } 1144 }
1088 spin_unlock(&dev->event_lock); 1145 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1089
1090 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1091} 1146}
1092EXPORT_SYMBOL(drm_vblank_off); 1147EXPORT_SYMBOL(drm_vblank_off);
1093 1148
@@ -1124,14 +1179,35 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
1124 */ 1179 */
1125void drm_vblank_on(struct drm_device *dev, int crtc) 1180void drm_vblank_on(struct drm_device *dev, int crtc)
1126{ 1181{
1182 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1127 unsigned long irqflags; 1183 unsigned long irqflags;
1128 1184
1129 if (WARN_ON(crtc >= dev->num_crtcs)) 1185 if (WARN_ON(crtc >= dev->num_crtcs))
1130 return; 1186 return;
1131 1187
1132 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1188 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1133 /* re-enable interrupts if there's are users left */ 1189 /* Drop our private "prevent drm_vblank_get" refcount */
1134 if (atomic_read(&dev->vblank[crtc].refcount) != 0) 1190 if (vblank->inmodeset) {
1191 atomic_dec(&vblank->refcount);
1192 vblank->inmodeset = 0;
1193 }
1194
1195 /*
1196 * sample the current counter to avoid random jumps
1197 * when drm_vblank_enable() applies the diff
1198 *
1199 * -1 to make sure user will never see the same
1200 * vblank counter value before and after a modeset
1201 */
1202 vblank->last =
1203 (dev->driver->get_vblank_counter(dev, crtc) - 1) &
1204 dev->max_vblank_count;
1205 /*
1206 * re-enable interrupts if there are users left, or the
1207 * user wishes vblank interrupts to be enabled all the time.
1208 */
1209 if (atomic_read(&vblank->refcount) != 0 ||
1210 (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0))
1135 WARN_ON(drm_vblank_enable(dev, crtc)); 1211 WARN_ON(drm_vblank_enable(dev, crtc));
1136 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 1212 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1137} 1213}
@@ -1179,6 +1255,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_on);
1179 */ 1255 */
1180void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) 1256void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
1181{ 1257{
1258 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1259
1182 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1260 /* vblank is not initialized (IRQ not installed ?), or has been freed */
1183 if (!dev->num_crtcs) 1261 if (!dev->num_crtcs)
1184 return; 1262 return;
@@ -1193,10 +1271,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc)
1193 * to avoid corrupting the count if multiple, mismatch calls occur), 1271 * to avoid corrupting the count if multiple, mismatch calls occur),
1194 * so that interrupts remain enabled in the interim. 1272 * so that interrupts remain enabled in the interim.
1195 */ 1273 */
1196 if (!dev->vblank[crtc].inmodeset) { 1274 if (!vblank->inmodeset) {
1197 dev->vblank[crtc].inmodeset = 0x1; 1275 vblank->inmodeset = 0x1;
1198 if (drm_vblank_get(dev, crtc) == 0) 1276 if (drm_vblank_get(dev, crtc) == 0)
1199 dev->vblank[crtc].inmodeset |= 0x2; 1277 vblank->inmodeset |= 0x2;
1200 } 1278 }
1201} 1279}
1202EXPORT_SYMBOL(drm_vblank_pre_modeset); 1280EXPORT_SYMBOL(drm_vblank_pre_modeset);
@@ -1211,21 +1289,22 @@ EXPORT_SYMBOL(drm_vblank_pre_modeset);
1211 */ 1289 */
1212void drm_vblank_post_modeset(struct drm_device *dev, int crtc) 1290void drm_vblank_post_modeset(struct drm_device *dev, int crtc)
1213{ 1291{
1292 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1214 unsigned long irqflags; 1293 unsigned long irqflags;
1215 1294
1216 /* vblank is not initialized (IRQ not installed ?), or has been freed */ 1295 /* vblank is not initialized (IRQ not installed ?), or has been freed */
1217 if (!dev->num_crtcs) 1296 if (!dev->num_crtcs)
1218 return; 1297 return;
1219 1298
1220 if (dev->vblank[crtc].inmodeset) { 1299 if (vblank->inmodeset) {
1221 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1300 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1222 dev->vblank_disable_allowed = true; 1301 dev->vblank_disable_allowed = true;
1223 spin_unlock_irqrestore(&dev->vbl_lock, irqflags); 1302 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
1224 1303
1225 if (dev->vblank[crtc].inmodeset & 0x2) 1304 if (vblank->inmodeset & 0x2)
1226 drm_vblank_put(dev, crtc); 1305 drm_vblank_put(dev, crtc);
1227 1306
1228 dev->vblank[crtc].inmodeset = 0; 1307 vblank->inmodeset = 0;
1229 } 1308 }
1230} 1309}
1231EXPORT_SYMBOL(drm_vblank_post_modeset); 1310EXPORT_SYMBOL(drm_vblank_post_modeset);
@@ -1277,6 +1356,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1277 union drm_wait_vblank *vblwait, 1356 union drm_wait_vblank *vblwait,
1278 struct drm_file *file_priv) 1357 struct drm_file *file_priv)
1279{ 1358{
1359 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1280 struct drm_pending_vblank_event *e; 1360 struct drm_pending_vblank_event *e;
1281 struct timeval now; 1361 struct timeval now;
1282 unsigned long flags; 1362 unsigned long flags;
@@ -1300,6 +1380,18 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe,
1300 1380
1301 spin_lock_irqsave(&dev->event_lock, flags); 1381 spin_lock_irqsave(&dev->event_lock, flags);
1302 1382
1383 /*
1384 * drm_vblank_off() might have been called after we called
1385 * drm_vblank_get(). drm_vblank_off() holds event_lock
1386 * around the vblank disable, so no need for further locking.
1387 * The reference from drm_vblank_get() protects against
1388 * vblank disable from another source.
1389 */
1390 if (!vblank->enabled) {
1391 ret = -EINVAL;
1392 goto err_unlock;
1393 }
1394
1303 if (file_priv->event_space < sizeof e->event) { 1395 if (file_priv->event_space < sizeof e->event) {
1304 ret = -EBUSY; 1396 ret = -EBUSY;
1305 goto err_unlock; 1397 goto err_unlock;
@@ -1360,6 +1452,7 @@ err_put:
1360int drm_wait_vblank(struct drm_device *dev, void *data, 1452int drm_wait_vblank(struct drm_device *dev, void *data,
1361 struct drm_file *file_priv) 1453 struct drm_file *file_priv)
1362{ 1454{
1455 struct drm_vblank_crtc *vblank;
1363 union drm_wait_vblank *vblwait = data; 1456 union drm_wait_vblank *vblwait = data;
1364 int ret; 1457 int ret;
1365 unsigned int flags, seq, crtc, high_crtc; 1458 unsigned int flags, seq, crtc, high_crtc;
@@ -1389,6 +1482,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1389 if (crtc >= dev->num_crtcs) 1482 if (crtc >= dev->num_crtcs)
1390 return -EINVAL; 1483 return -EINVAL;
1391 1484
1485 vblank = &dev->vblank[crtc];
1486
1392 ret = drm_vblank_get(dev, crtc); 1487 ret = drm_vblank_get(dev, crtc);
1393 if (ret) { 1488 if (ret) {
1394 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); 1489 DRM_DEBUG("failed to acquire vblank counter, %d\n", ret);
@@ -1421,11 +1516,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
1421 1516
1422 DRM_DEBUG("waiting on vblank count %d, crtc %d\n", 1517 DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
1423 vblwait->request.sequence, crtc); 1518 vblwait->request.sequence, crtc);
1424 dev->vblank[crtc].last_wait = vblwait->request.sequence; 1519 vblank->last_wait = vblwait->request.sequence;
1425 DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * HZ, 1520 DRM_WAIT_ON(ret, vblank->queue, 3 * HZ,
1426 (((drm_vblank_count(dev, crtc) - 1521 (((drm_vblank_count(dev, crtc) -
1427 vblwait->request.sequence) <= (1 << 23)) || 1522 vblwait->request.sequence) <= (1 << 23)) ||
1428 !dev->vblank[crtc].enabled || 1523 !vblank->enabled ||
1429 !dev->irq_enabled)); 1524 !dev->irq_enabled));
1430 1525
1431 if (ret != -EINTR) { 1526 if (ret != -EINTR) {
@@ -1450,12 +1545,11 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1450{ 1545{
1451 struct drm_pending_vblank_event *e, *t; 1546 struct drm_pending_vblank_event *e, *t;
1452 struct timeval now; 1547 struct timeval now;
1453 unsigned long flags;
1454 unsigned int seq; 1548 unsigned int seq;
1455 1549
1456 seq = drm_vblank_count_and_time(dev, crtc, &now); 1550 assert_spin_locked(&dev->event_lock);
1457 1551
1458 spin_lock_irqsave(&dev->event_lock, flags); 1552 seq = drm_vblank_count_and_time(dev, crtc, &now);
1459 1553
1460 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { 1554 list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) {
1461 if (e->pipe != crtc) 1555 if (e->pipe != crtc)
@@ -1471,8 +1565,6 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1471 send_vblank_event(dev, e, seq, &now); 1565 send_vblank_event(dev, e, seq, &now);
1472 } 1566 }
1473 1567
1474 spin_unlock_irqrestore(&dev->event_lock, flags);
1475
1476 trace_drm_vblank_event(crtc, seq); 1568 trace_drm_vblank_event(crtc, seq);
1477} 1569}
1478 1570
@@ -1486,6 +1578,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1486 */ 1578 */
1487bool drm_handle_vblank(struct drm_device *dev, int crtc) 1579bool drm_handle_vblank(struct drm_device *dev, int crtc)
1488{ 1580{
1581 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1489 u32 vblcount; 1582 u32 vblcount;
1490 s64 diff_ns; 1583 s64 diff_ns;
1491 struct timeval tvblank; 1584 struct timeval tvblank;
@@ -1497,15 +1590,18 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1497 if (WARN_ON(crtc >= dev->num_crtcs)) 1590 if (WARN_ON(crtc >= dev->num_crtcs))
1498 return false; 1591 return false;
1499 1592
1593 spin_lock_irqsave(&dev->event_lock, irqflags);
1594
1500 /* Need timestamp lock to prevent concurrent execution with 1595 /* Need timestamp lock to prevent concurrent execution with
1501 * vblank enable/disable, as this would cause inconsistent 1596 * vblank enable/disable, as this would cause inconsistent
1502 * or corrupted timestamps and vblank counts. 1597 * or corrupted timestamps and vblank counts.
1503 */ 1598 */
1504 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); 1599 spin_lock(&dev->vblank_time_lock);
1505 1600
1506 /* Vblank irq handling disabled. Nothing to do. */ 1601 /* Vblank irq handling disabled. Nothing to do. */
1507 if (!dev->vblank[crtc].enabled) { 1602 if (!vblank->enabled) {
1508 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 1603 spin_unlock(&dev->vblank_time_lock);
1604 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1509 return false; 1605 return false;
1510 } 1606 }
1511 1607
@@ -1514,7 +1610,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1514 */ 1610 */
1515 1611
1516 /* Get current timestamp and count. */ 1612 /* Get current timestamp and count. */
1517 vblcount = atomic_read(&dev->vblank[crtc].count); 1613 vblcount = atomic_read(&vblank->count);
1518 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); 1614 drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ);
1519 1615
1520 /* Compute time difference to timestamp of last vblank */ 1616 /* Compute time difference to timestamp of last vblank */
@@ -1538,17 +1634,20 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1538 * the timestamp computed above. 1634 * the timestamp computed above.
1539 */ 1635 */
1540 smp_mb__before_atomic(); 1636 smp_mb__before_atomic();
1541 atomic_inc(&dev->vblank[crtc].count); 1637 atomic_inc(&vblank->count);
1542 smp_mb__after_atomic(); 1638 smp_mb__after_atomic();
1543 } else { 1639 } else {
1544 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", 1640 DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n",
1545 crtc, (int) diff_ns); 1641 crtc, (int) diff_ns);
1546 } 1642 }
1547 1643
1548 wake_up(&dev->vblank[crtc].queue); 1644 spin_unlock(&dev->vblank_time_lock);
1645
1646 wake_up(&vblank->queue);
1549 drm_handle_vblank_events(dev, crtc); 1647 drm_handle_vblank_events(dev, crtc);
1550 1648
1551 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 1649 spin_unlock_irqrestore(&dev->event_lock, irqflags);
1650
1552 return true; 1651 return true;
1553} 1652}
1554EXPORT_SYMBOL(drm_handle_vblank); 1653EXPORT_SYMBOL(drm_handle_vblank);
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8b158f02bd0f..7391697c25e7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1020,7 +1020,7 @@ static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
1020 1020
1021 /* In vblank? */ 1021 /* In vblank? */
1022 if (in_vbl) 1022 if (in_vbl)
1023 ret |= DRM_SCANOUTPOS_INVBL; 1023 ret |= DRM_SCANOUTPOS_IN_VBLANK;
1024 1024
1025 return ret; 1025 return ret;
1026} 1026}
@@ -4701,6 +4701,14 @@ void intel_irq_init(struct drm_device *dev)
4701 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ 4701 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
4702 } 4702 }
4703 4703
4704 /*
4705 * Opt out of the vblank disable timer on everything except gen2.
4706 * Gen2 doesn't have a hardware frame counter and so depends on
4707 * vblank interrupts to produce sane vblank seuquence numbers.
4708 */
4709 if (!IS_GEN2(dev))
4710 dev->vblank_disable_immediate = true;
4711
4704 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 4712 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
4705 dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; 4713 dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
4706 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; 4714 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ca8592e73644..0b327ebb2d9e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1342,6 +1342,12 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv,
1342 } 1342 }
1343} 1343}
1344 1344
1345static void assert_vblank_disabled(struct drm_crtc *crtc)
1346{
1347 if (WARN_ON(drm_crtc_vblank_get(crtc) == 0))
1348 drm_crtc_vblank_put(crtc);
1349}
1350
1345static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) 1351static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv)
1346{ 1352{
1347 u32 val; 1353 u32 val;
@@ -3891,6 +3897,8 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc)
3891 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 3897 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3892 int pipe = intel_crtc->pipe; 3898 int pipe = intel_crtc->pipe;
3893 3899
3900 assert_vblank_disabled(crtc);
3901
3894 drm_vblank_on(dev, pipe); 3902 drm_vblank_on(dev, pipe);
3895 3903
3896 intel_enable_primary_hw_plane(crtc->primary, crtc); 3904 intel_enable_primary_hw_plane(crtc->primary, crtc);
@@ -3940,6 +3948,8 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc)
3940 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe)); 3948 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_ALL_MASK(pipe));
3941 3949
3942 drm_vblank_off(dev, pipe); 3950 drm_vblank_off(dev, pipe);
3951
3952 assert_vblank_disabled(crtc);
3943} 3953}
3944 3954
3945static void ironlake_crtc_enable(struct drm_crtc *crtc) 3955static void ironlake_crtc_enable(struct drm_crtc *crtc)
@@ -12766,9 +12776,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
12766 I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); 12776 I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
12767 12777
12768 /* restore vblank interrupts to correct state */ 12778 /* restore vblank interrupts to correct state */
12769 if (crtc->active) 12779 if (crtc->active) {
12780 update_scanline_offset(crtc);
12770 drm_vblank_on(dev, crtc->pipe); 12781 drm_vblank_on(dev, crtc->pipe);
12771 else 12782 } else
12772 drm_vblank_off(dev, crtc->pipe); 12783 drm_vblank_off(dev, crtc->pipe);
12773 12784
12774 /* We need to sanitize the plane -> pipe mapping first because this will 12785 /* We need to sanitize the plane -> pipe mapping first because this will
@@ -12867,8 +12878,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
12867 */ 12878 */
12868 crtc->cpu_fifo_underrun_disabled = true; 12879 crtc->cpu_fifo_underrun_disabled = true;
12869 crtc->pch_fifo_underrun_disabled = true; 12880 crtc->pch_fifo_underrun_disabled = true;
12870
12871 update_scanline_offset(crtc);
12872 } 12881 }
12873} 12882}
12874 12883
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c
index a9ec525c0994..6d0a3cdc752b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_display.c
+++ b/drivers/gpu/drm/nouveau/nouveau_display.c
@@ -126,7 +126,7 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
126 if (etime) *etime = ns_to_ktime(args.scan.time[1]); 126 if (etime) *etime = ns_to_ktime(args.scan.time[1]);
127 127
128 if (*vpos < 0) 128 if (*vpos < 0)
129 ret |= DRM_SCANOUTPOS_INVBL; 129 ret |= DRM_SCANOUTPOS_IN_VBLANK;
130 return ret; 130 return ret;
131} 131}
132 132
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index bc894c17b2f9..4eb37976f879 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -1914,7 +1914,7 @@ int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int fl
1914 1914
1915 /* In vblank? */ 1915 /* In vblank? */
1916 if (in_vbl) 1916 if (in_vbl)
1917 ret |= DRM_SCANOUTPOS_INVBL; 1917 ret |= DRM_SCANOUTPOS_IN_VBLANK;
1918 1918
1919 /* Is vpos outside nominal vblank area, but less than 1919 /* Is vpos outside nominal vblank area, but less than
1920 * 1/100 of a frame height away from start of vblank? 1920 * 1/100 of a frame height away from start of vblank?
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 164898b0010c..32522cc940a1 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1556,7 +1556,7 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev)
1556 if (rdev->pm.active_crtcs & (1 << crtc)) { 1556 if (rdev->pm.active_crtcs & (1 << crtc)) {
1557 vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL); 1557 vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, 0, &vpos, &hpos, NULL, NULL);
1558 if ((vbl_status & DRM_SCANOUTPOS_VALID) && 1558 if ((vbl_status & DRM_SCANOUTPOS_VALID) &&
1559 !(vbl_status & DRM_SCANOUTPOS_INVBL)) 1559 !(vbl_status & DRM_SCANOUTPOS_IN_VBLANK))
1560 in_vbl = false; 1560 in_vbl = false;
1561 } 1561 }
1562 } 1562 }
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e4ba3de22601..027e4c5dbf03 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -580,11 +580,11 @@ struct drm_master {
580/* Flags and return codes for get_vblank_timestamp() driver function. */ 580/* Flags and return codes for get_vblank_timestamp() driver function. */
581#define DRM_CALLED_FROM_VBLIRQ 1 581#define DRM_CALLED_FROM_VBLIRQ 1
582#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) 582#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0)
583#define DRM_VBLANKTIME_INVBL (1 << 1) 583#define DRM_VBLANKTIME_IN_VBLANK (1 << 1)
584 584
585/* get_scanout_position() return flags */ 585/* get_scanout_position() return flags */
586#define DRM_SCANOUTPOS_VALID (1 << 0) 586#define DRM_SCANOUTPOS_VALID (1 << 0)
587#define DRM_SCANOUTPOS_INVBL (1 << 1) 587#define DRM_SCANOUTPOS_IN_VBLANK (1 << 1)
588#define DRM_SCANOUTPOS_ACCURATE (1 << 2) 588#define DRM_SCANOUTPOS_ACCURATE (1 << 2)
589 589
590/** 590/**
@@ -978,6 +978,16 @@ struct drm_device {
978 */ 978 */
979 bool vblank_disable_allowed; 979 bool vblank_disable_allowed;
980 980
981 /*
982 * If true, vblank interrupt will be disabled immediately when the
983 * refcount drops to zero, as opposed to via the vblank disable
984 * timer.
985 * This can be set to true it the hardware has a working vblank
986 * counter and the driver uses drm_vblank_on() and drm_vblank_off()
987 * appropriately.
988 */
989 bool vblank_disable_immediate;
990
981 /* array of size num_crtcs */ 991 /* array of size num_crtcs */
982 struct drm_vblank_crtc *vblank; 992 struct drm_vblank_crtc *vblank;
983 993
@@ -1164,8 +1174,6 @@ extern void drm_crtc_vblank_off(struct drm_crtc *crtc);
1164extern void drm_crtc_vblank_on(struct drm_crtc *crtc); 1174extern void drm_crtc_vblank_on(struct drm_crtc *crtc);
1165extern void drm_vblank_cleanup(struct drm_device *dev); 1175extern void drm_vblank_cleanup(struct drm_device *dev);
1166 1176
1167extern u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
1168 struct timeval *tvblank, unsigned flags);
1169extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, 1177extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
1170 int crtc, int *max_error, 1178 int crtc, int *max_error,
1171 struct timeval *vblank_time, 1179 struct timeval *vblank_time,
@@ -1206,7 +1214,7 @@ extern void drm_put_dev(struct drm_device *dev);
1206extern void drm_unplug_dev(struct drm_device *dev); 1214extern void drm_unplug_dev(struct drm_device *dev);
1207extern unsigned int drm_debug; 1215extern unsigned int drm_debug;
1208 1216
1209extern unsigned int drm_vblank_offdelay; 1217extern int drm_vblank_offdelay;
1210extern unsigned int drm_timestamp_precision; 1218extern unsigned int drm_timestamp_precision;
1211extern unsigned int drm_timestamp_monotonic; 1219extern unsigned int drm_timestamp_monotonic;
1212 1220