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.c379
1 files changed, 239 insertions, 140 deletions
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);