aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 03:39:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-14 03:39:08 -0400
commit2d65a9f48fcdf7866aab6457bc707ca233e0c791 (patch)
treef93e5838d6ac2e59434367f4ff905f7d9c45fc2b /drivers/gpu/drm/drm_irq.c
parentda92da3638a04894afdca8b99e973ddd20268471 (diff)
parentdfda0df3426483cf5fc7441f23f318edbabecb03 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "This is the main git pull for the drm, I pretty much froze major pulls at -rc5/6 time, and haven't had much fallout, so will probably continue doing that. Lots of changes all over, big internal header cleanup to make it clear drm features are legacy things and what are things that modern KMS drivers should be using. Also big move to use the new generic fences in all the TTM drivers. core: atomic prep work, vblank rework changes, allows immediate vblank disables major header reworking and cleanups to better delinate legacy interfaces from what KMS drivers should be using. cursor planes locking fixes ttm: move to generic fences (affects all TTM drivers) ppc64 caching fixes radeon: userptr support, uvd for old asics, reset rework for fence changes better buffer placement changes, dpm feature enablement hdmi audio support fixes intel: Cherryview work, 180 degree rotation, skylake prep work, execlist command submission full ppgtt prep work cursor improvements edid caching, vdd handling improvements nouveau: fence reworking kepler memory clock work gt21x clock work fan control improvements hdmi infoframe fixes DP audio ast: ppc64 fixes caching fix rcar: rcar-du DT support ipuv3: prep work for capture support msm: LVDS support for mdp4, new panel, gpu refactoring exynos: exynos3250 SoC support, drop bad mmap interface, mipi dsi changes, and component match support" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (640 commits) drm/mst: rework payload table allocation to conform better. drm/ast: Fix HW cursor image drm/radeon/kv: add uvd/vce info to dpm debugfs output drm/radeon/ci: add uvd/vce info to dpm debugfs output drm/radeon: export reservation_object from dmabuf to ttm drm/radeon: cope with foreign fences inside the reservation object drm/radeon: cope with foreign fences inside display drm/core: use helper to check driver features drm/radeon/cik: write gfx ucode version to ucode addr reg drm/radeon/si: print full CS when we hit a packet 0 drm/radeon: remove unecessary includes drm/radeon/combios: declare legacy_connector_convert as static drm/radeon/atombios: declare connector convert tables as static drm/radeon: drop btc_get_max_clock_from_voltage_dependency_table drm/radeon/dpm: drop clk/voltage dependency filters for BTC drm/radeon/dpm: drop clk/voltage dependency filters for CI drm/radeon/dpm: drop clk/voltage dependency filters for SI drm/radeon/dpm: drop clk/voltage dependency filters for NI drm/radeon: disable audio when we disable hdmi (v2) drm/radeon: split audio enable between eg and r600 (v2) ...
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);