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.c331
1 files changed, 161 insertions, 170 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 22d207e211e7..ed2394e1720b 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -74,22 +74,22 @@ module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600);
74module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); 74module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600);
75module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600); 75module_param_named(timestamp_monotonic, drm_timestamp_monotonic, int, 0600);
76 76
77static void store_vblank(struct drm_device *dev, int crtc, 77static void store_vblank(struct drm_device *dev, unsigned int pipe,
78 u32 vblank_count_inc, 78 u32 vblank_count_inc,
79 struct timeval *t_vblank) 79 struct timeval *t_vblank, u32 last)
80{ 80{
81 struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; 81 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
82 u32 tslot; 82 u32 tslot;
83 83
84 assert_spin_locked(&dev->vblank_time_lock); 84 assert_spin_locked(&dev->vblank_time_lock);
85 85
86 if (t_vblank) { 86 vblank->last = last;
87 /* All writers hold the spinlock, but readers are serialized by 87
88 * the latching of vblank->count below. 88 /* All writers hold the spinlock, but readers are serialized by
89 */ 89 * the latching of vblank->count below.
90 tslot = vblank->count + vblank_count_inc; 90 */
91 vblanktimestamp(dev, crtc, tslot) = *t_vblank; 91 tslot = vblank->count + vblank_count_inc;
92 } 92 vblanktimestamp(dev, pipe, tslot) = *t_vblank;
93 93
94 /* 94 /*
95 * vblank timestamp updates are protected on the write side with 95 * vblank timestamp updates are protected on the write side with
@@ -105,12 +105,60 @@ static void store_vblank(struct drm_device *dev, int crtc,
105} 105}
106 106
107/** 107/**
108 * drm_reset_vblank_timestamp - reset the last timestamp to the last vblank
109 * @dev: DRM device
110 * @pipe: index of CRTC for which to reset the timestamp
111 *
112 * Reset the stored timestamp for the current vblank count to correspond
113 * to the last vblank occurred.
114 *
115 * Only to be called from drm_vblank_on().
116 *
117 * Note: caller must hold dev->vbl_lock since this reads & writes
118 * device vblank fields.
119 */
120static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe)
121{
122 u32 cur_vblank;
123 bool rc;
124 struct timeval t_vblank;
125 int count = DRM_TIMESTAMP_MAXRETRIES;
126
127 spin_lock(&dev->vblank_time_lock);
128
129 /*
130 * sample the current counter to avoid random jumps
131 * when drm_vblank_enable() applies the diff
132 */
133 do {
134 cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
135 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0);
136 } while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && --count > 0);
137
138 /*
139 * Only reinitialize corresponding vblank timestamp if high-precision query
140 * available and didn't fail. Otherwise reinitialize delayed at next vblank
141 * interrupt and assign 0 for now, to mark the vblanktimestamp as invalid.
142 */
143 if (!rc)
144 t_vblank = (struct timeval) {0, 0};
145
146 /*
147 * +1 to make sure user will never see the same
148 * vblank counter value before and after a modeset
149 */
150 store_vblank(dev, pipe, 1, &t_vblank, cur_vblank);
151
152 spin_unlock(&dev->vblank_time_lock);
153}
154
155/**
108 * drm_update_vblank_count - update the master vblank counter 156 * drm_update_vblank_count - update the master vblank counter
109 * @dev: DRM device 157 * @dev: DRM device
110 * @pipe: counter to update 158 * @pipe: counter to update
111 * 159 *
112 * Call back into the driver to update the appropriate vblank counter 160 * Call back into the driver to update the appropriate vblank counter
113 * (specified by @crtc). Deal with wraparound, if it occurred, and 161 * (specified by @pipe). Deal with wraparound, if it occurred, and
114 * update the last read value so we can deal with wraparound on the next 162 * update the last read value so we can deal with wraparound on the next
115 * call if necessary. 163 * call if necessary.
116 * 164 *
@@ -120,12 +168,15 @@ static void store_vblank(struct drm_device *dev, int crtc,
120 * Note: caller must hold dev->vbl_lock since this reads & writes 168 * Note: caller must hold dev->vbl_lock since this reads & writes
121 * device vblank fields. 169 * device vblank fields.
122 */ 170 */
123static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe) 171static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
172 unsigned long flags)
124{ 173{
125 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 174 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
126 u32 cur_vblank, diff; 175 u32 cur_vblank, diff;
127 bool rc; 176 bool rc;
128 struct timeval t_vblank; 177 struct timeval t_vblank;
178 int count = DRM_TIMESTAMP_MAXRETRIES;
179 int framedur_ns = vblank->framedur_ns;
129 180
130 /* 181 /*
131 * Interrupts were disabled prior to this call, so deal with counter 182 * Interrupts were disabled prior to this call, so deal with counter
@@ -141,23 +192,43 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe)
141 */ 192 */
142 do { 193 do {
143 cur_vblank = dev->driver->get_vblank_counter(dev, pipe); 194 cur_vblank = dev->driver->get_vblank_counter(dev, pipe);
144 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, 0); 195 rc = drm_get_last_vbltimestamp(dev, pipe, &t_vblank, flags);
145 } while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe)); 196 } while (cur_vblank != dev->driver->get_vblank_counter(dev, pipe) && --count > 0);
197
198 if (dev->max_vblank_count != 0) {
199 /* trust the hw counter when it's around */
200 diff = (cur_vblank - vblank->last) & dev->max_vblank_count;
201 } else if (rc && framedur_ns) {
202 const struct timeval *t_old;
203 u64 diff_ns;
146 204
147 /* Deal with counter wrap */ 205 t_old = &vblanktimestamp(dev, pipe, vblank->count);
148 diff = cur_vblank - vblank->last; 206 diff_ns = timeval_to_ns(&t_vblank) - timeval_to_ns(t_old);
149 if (cur_vblank < vblank->last) { 207
150 diff += dev->max_vblank_count + 1; 208 /*
209 * Figure out how many vblanks we've missed based
210 * on the difference in the timestamps and the
211 * frame/field duration.
212 */
213 diff = DIV_ROUND_CLOSEST_ULL(diff_ns, framedur_ns);
151 214
152 DRM_DEBUG("last_vblank[%u]=0x%x, cur_vblank=0x%x => diff=0x%x\n", 215 if (diff == 0 && flags & DRM_CALLED_FROM_VBLIRQ)
153 pipe, vblank->last, cur_vblank, diff); 216 DRM_DEBUG("crtc %u: Redundant vblirq ignored."
217 " diff_ns = %lld, framedur_ns = %d)\n",
218 pipe, (long long) diff_ns, framedur_ns);
219 } else {
220 /* some kind of default for drivers w/o accurate vbl timestamping */
221 diff = (flags & DRM_CALLED_FROM_VBLIRQ) != 0;
154 } 222 }
155 223
156 DRM_DEBUG("updating vblank count on crtc %u, missed %d\n", 224 DRM_DEBUG("updating vblank count on crtc %u:"
157 pipe, diff); 225 " current=%u, diff=%u, hw=%u hw_last=%u\n",
226 pipe, vblank->count, diff, cur_vblank, vblank->last);
158 227
159 if (diff == 0) 228 if (diff == 0) {
229 WARN_ON_ONCE(cur_vblank != vblank->last);
160 return; 230 return;
231 }
161 232
162 /* 233 /*
163 * Only reinitialize corresponding vblank timestamp if high-precision query 234 * Only reinitialize corresponding vblank timestamp if high-precision query
@@ -167,7 +238,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe)
167 if (!rc) 238 if (!rc)
168 t_vblank = (struct timeval) {0, 0}; 239 t_vblank = (struct timeval) {0, 0};
169 240
170 store_vblank(dev, pipe, diff, &t_vblank); 241 store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
171} 242}
172 243
173/* 244/*
@@ -180,11 +251,6 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
180{ 251{
181 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 252 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
182 unsigned long irqflags; 253 unsigned long irqflags;
183 u32 vblcount;
184 s64 diff_ns;
185 bool vblrc;
186 struct timeval tvblank;
187 int count = DRM_TIMESTAMP_MAXRETRIES;
188 254
189 /* Prevent vblank irq processing while disabling vblank irqs, 255 /* Prevent vblank irq processing while disabling vblank irqs,
190 * so no updates of timestamps or count can happen after we've 256 * so no updates of timestamps or count can happen after we've
@@ -193,26 +259,6 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
193 spin_lock_irqsave(&dev->vblank_time_lock, irqflags); 259 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
194 260
195 /* 261 /*
196 * If the vblank interrupt was already disabled update the count
197 * and timestamp to maintain the appearance that the counter
198 * has been ticking all along until this time. This makes the
199 * count account for the entire time between drm_vblank_on() and
200 * drm_vblank_off().
201 *
202 * But only do this if precise vblank timestamps are available.
203 * Otherwise we might read a totally bogus timestamp since drivers
204 * lacking precise timestamp support rely upon sampling the system clock
205 * at vblank interrupt time. Which obviously won't work out well if the
206 * vblank interrupt is disabled.
207 */
208 if (!vblank->enabled &&
209 drm_get_last_vbltimestamp(dev, pipe, &tvblank, 0)) {
210 drm_update_vblank_count(dev, pipe);
211 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
212 return;
213 }
214
215 /*
216 * Only disable vblank interrupts if they're enabled. This avoids 262 * Only disable vblank interrupts if they're enabled. This avoids
217 * calling the ->disable_vblank() operation in atomic context with the 263 * calling the ->disable_vblank() operation in atomic context with the
218 * hardware potentially runtime suspended. 264 * hardware potentially runtime suspended.
@@ -222,47 +268,13 @@ static void vblank_disable_and_save(struct drm_device *dev, unsigned int pipe)
222 vblank->enabled = false; 268 vblank->enabled = false;
223 } 269 }
224 270
225 /* No further vblank irq's will be processed after 271 /*
226 * this point. Get current hardware vblank count and 272 * Always update the count and timestamp to maintain the
227 * vblank timestamp, repeat until they are consistent. 273 * appearance that the counter has been ticking all along until
228 * 274 * this time. This makes the count account for the entire time
229 * FIXME: There is still a race condition here and in 275 * between drm_vblank_on() and drm_vblank_off().
230 * drm_update_vblank_count() which can cause off-by-one
231 * reinitialization of software vblank counter. If gpu
232 * vblank counter doesn't increment exactly at the leading
233 * edge of a vblank interval, then we can lose 1 count if
234 * we happen to execute between start of vblank and the
235 * delayed gpu counter increment.
236 */
237 do {
238 vblank->last = dev->driver->get_vblank_counter(dev, pipe);
239 vblrc = drm_get_last_vbltimestamp(dev, pipe, &tvblank, 0);
240 } while (vblank->last != dev->driver->get_vblank_counter(dev, pipe) && (--count) && vblrc);
241
242 if (!count)
243 vblrc = 0;
244
245 /* Compute time difference to stored timestamp of last vblank
246 * as updated by last invocation of drm_handle_vblank() in vblank irq.
247 */
248 vblcount = vblank->count;
249 diff_ns = timeval_to_ns(&tvblank) -
250 timeval_to_ns(&vblanktimestamp(dev, pipe, vblcount));
251
252 /* If there is at least 1 msec difference between the last stored
253 * timestamp and tvblank, then we are currently executing our
254 * disable inside a new vblank interval, the tvblank timestamp
255 * corresponds to this new vblank interval and the irq handler
256 * for this vblank didn't run yet and won't run due to our disable.
257 * Therefore we need to do the job of drm_handle_vblank() and
258 * increment the vblank counter by one to account for this vblank.
259 *
260 * Skip this step if there isn't any high precision timestamp
261 * available. In that case we can't account for this and just
262 * hope for the best.
263 */ 276 */
264 if (vblrc && (abs64(diff_ns) > 1000000)) 277 drm_update_vblank_count(dev, pipe, 0);
265 store_vblank(dev, pipe, 1, &tvblank);
266 278
267 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); 279 spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags);
268} 280}
@@ -603,7 +615,8 @@ int drm_control(struct drm_device *dev, void *data,
603void drm_calc_timestamping_constants(struct drm_crtc *crtc, 615void drm_calc_timestamping_constants(struct drm_crtc *crtc,
604 const struct drm_display_mode *mode) 616 const struct drm_display_mode *mode)
605{ 617{
606 int linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; 618 struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
619 int linedur_ns = 0, framedur_ns = 0;
607 int dotclock = mode->crtc_clock; 620 int dotclock = mode->crtc_clock;
608 621
609 /* Valid dotclock? */ 622 /* Valid dotclock? */
@@ -612,10 +625,9 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
612 625
613 /* 626 /*
614 * Convert scanline length in pixels and video 627 * Convert scanline length in pixels and video
615 * dot clock to line duration, frame duration 628 * dot clock to line duration and frame duration
616 * and pixel duration in nanoseconds: 629 * in nanoseconds:
617 */ 630 */
618 pixeldur_ns = 1000000 / dotclock;
619 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock); 631 linedur_ns = div_u64((u64) mode->crtc_htotal * 1000000, dotclock);
620 framedur_ns = div_u64((u64) frame_size * 1000000, dotclock); 632 framedur_ns = div_u64((u64) frame_size * 1000000, dotclock);
621 633
@@ -628,16 +640,14 @@ void drm_calc_timestamping_constants(struct drm_crtc *crtc,
628 DRM_ERROR("crtc %u: Can't calculate constants, dotclock = 0!\n", 640 DRM_ERROR("crtc %u: Can't calculate constants, dotclock = 0!\n",
629 crtc->base.id); 641 crtc->base.id);
630 642
631 crtc->pixeldur_ns = pixeldur_ns; 643 vblank->linedur_ns = linedur_ns;
632 crtc->linedur_ns = linedur_ns; 644 vblank->framedur_ns = framedur_ns;
633 crtc->framedur_ns = framedur_ns;
634 645
635 DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n", 646 DRM_DEBUG("crtc %u: hwmode: htotal %d, vtotal %d, vdisplay %d\n",
636 crtc->base.id, mode->crtc_htotal, 647 crtc->base.id, mode->crtc_htotal,
637 mode->crtc_vtotal, mode->crtc_vdisplay); 648 mode->crtc_vtotal, mode->crtc_vdisplay);
638 DRM_DEBUG("crtc %u: clock %d kHz framedur %d linedur %d, pixeldur %d\n", 649 DRM_DEBUG("crtc %u: clock %d kHz framedur %d linedur %d\n",
639 crtc->base.id, dotclock, framedur_ns, 650 crtc->base.id, dotclock, framedur_ns, linedur_ns);
640 linedur_ns, pixeldur_ns);
641} 651}
642EXPORT_SYMBOL(drm_calc_timestamping_constants); 652EXPORT_SYMBOL(drm_calc_timestamping_constants);
643 653
@@ -651,7 +661,6 @@ EXPORT_SYMBOL(drm_calc_timestamping_constants);
651 * @flags: Flags to pass to driver: 661 * @flags: Flags to pass to driver:
652 * 0 = Default, 662 * 0 = Default,
653 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler 663 * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl IRQ handler
654 * @refcrtc: CRTC which defines scanout timing
655 * @mode: mode which defines the scanout timings 664 * @mode: mode which defines the scanout timings
656 * 665 *
657 * Implements calculation of exact vblank timestamps from given drm_display_mode 666 * Implements calculation of exact vblank timestamps from given drm_display_mode
@@ -692,15 +701,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
692 int *max_error, 701 int *max_error,
693 struct timeval *vblank_time, 702 struct timeval *vblank_time,
694 unsigned flags, 703 unsigned flags,
695 const struct drm_crtc *refcrtc,
696 const struct drm_display_mode *mode) 704 const struct drm_display_mode *mode)
697{ 705{
698 struct timeval tv_etime; 706 struct timeval tv_etime;
699 ktime_t stime, etime; 707 ktime_t stime, etime;
700 int vbl_status; 708 unsigned int vbl_status;
709 int ret = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
701 int vpos, hpos, i; 710 int vpos, hpos, i;
702 int framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; 711 int delta_ns, duration_ns;
703 bool invbl;
704 712
705 if (pipe >= dev->num_crtcs) { 713 if (pipe >= dev->num_crtcs) {
706 DRM_ERROR("Invalid crtc %u\n", pipe); 714 DRM_ERROR("Invalid crtc %u\n", pipe);
@@ -713,15 +721,10 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
713 return -EIO; 721 return -EIO;
714 } 722 }
715 723
716 /* Durations of frames, lines, pixels in nanoseconds. */
717 framedur_ns = refcrtc->framedur_ns;
718 linedur_ns = refcrtc->linedur_ns;
719 pixeldur_ns = refcrtc->pixeldur_ns;
720
721 /* If mode timing undefined, just return as no-op: 724 /* If mode timing undefined, just return as no-op:
722 * Happens during initial modesetting of a crtc. 725 * Happens during initial modesetting of a crtc.
723 */ 726 */
724 if (framedur_ns == 0) { 727 if (mode->crtc_clock == 0) {
725 DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe); 728 DRM_DEBUG("crtc %u: Noop due to uninitialized mode.\n", pipe);
726 return -EAGAIN; 729 return -EAGAIN;
727 } 730 }
@@ -738,12 +741,14 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
738 * Get vertical and horizontal scanout position vpos, hpos, 741 * Get vertical and horizontal scanout position vpos, hpos,
739 * and bounding timestamps stime, etime, pre/post query. 742 * and bounding timestamps stime, etime, pre/post query.
740 */ 743 */
741 vbl_status = dev->driver->get_scanout_position(dev, pipe, flags, &vpos, 744 vbl_status = dev->driver->get_scanout_position(dev, pipe, flags,
742 &hpos, &stime, &etime); 745 &vpos, &hpos,
746 &stime, &etime,
747 mode);
743 748
744 /* Return as no-op if scanout query unsupported or failed. */ 749 /* Return as no-op if scanout query unsupported or failed. */
745 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { 750 if (!(vbl_status & DRM_SCANOUTPOS_VALID)) {
746 DRM_DEBUG("crtc %u : scanoutpos query failed [%d].\n", 751 DRM_DEBUG("crtc %u : scanoutpos query failed [0x%x].\n",
747 pipe, vbl_status); 752 pipe, vbl_status);
748 return -EIO; 753 return -EIO;
749 } 754 }
@@ -770,13 +775,15 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
770 * within vblank area, counting down the number of lines until 775 * within vblank area, counting down the number of lines until
771 * start of scanout. 776 * start of scanout.
772 */ 777 */
773 invbl = vbl_status & DRM_SCANOUTPOS_IN_VBLANK; 778 if (vbl_status & DRM_SCANOUTPOS_IN_VBLANK)
779 ret |= DRM_VBLANKTIME_IN_VBLANK;
774 780
775 /* Convert scanout position into elapsed time at raw_time query 781 /* Convert scanout position into elapsed time at raw_time query
776 * since start of scanout at first display scanline. delta_ns 782 * since start of scanout at first display scanline. delta_ns
777 * can be negative if start of scanout hasn't happened yet. 783 * can be negative if start of scanout hasn't happened yet.
778 */ 784 */
779 delta_ns = vpos * linedur_ns + hpos * pixeldur_ns; 785 delta_ns = div_s64(1000000LL * (vpos * mode->crtc_htotal + hpos),
786 mode->crtc_clock);
780 787
781 if (!drm_timestamp_monotonic) 788 if (!drm_timestamp_monotonic)
782 etime = ktime_mono_to_real(etime); 789 etime = ktime_mono_to_real(etime);
@@ -792,17 +799,13 @@ int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev,
792 etime = ktime_sub_ns(etime, delta_ns); 799 etime = ktime_sub_ns(etime, delta_ns);
793 *vblank_time = ktime_to_timeval(etime); 800 *vblank_time = ktime_to_timeval(etime);
794 801
795 DRM_DEBUG("crtc %u : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n", 802 DRM_DEBUG("crtc %u : v 0x%x p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
796 pipe, (int)vbl_status, hpos, vpos, 803 pipe, vbl_status, hpos, vpos,
797 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec, 804 (long)tv_etime.tv_sec, (long)tv_etime.tv_usec,
798 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec, 805 (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
799 duration_ns/1000, i); 806 duration_ns/1000, i);
800 807
801 vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; 808 return ret;
802 if (invbl)
803 vbl_status |= DRM_VBLANKTIME_IN_VBLANK;
804
805 return vbl_status;
806} 809}
807EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); 810EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos);
808 811
@@ -914,11 +917,14 @@ EXPORT_SYMBOL(drm_crtc_vblank_count);
914 * vblank events since the system was booted, including lost events due to 917 * vblank events since the system was booted, including lost events due to
915 * modesetting activity. Returns corresponding system timestamp of the time 918 * modesetting activity. Returns corresponding system timestamp of the time
916 * of the vblank interval that corresponds to the current vblank counter value. 919 * of the vblank interval that corresponds to the current vblank counter value.
920 *
921 * This is the legacy version of drm_crtc_vblank_count_and_time().
917 */ 922 */
918u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe, 923u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
919 struct timeval *vblanktime) 924 struct timeval *vblanktime)
920{ 925{
921 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 926 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
927 int count = DRM_TIMESTAMP_MAXRETRIES;
922 u32 cur_vblank; 928 u32 cur_vblank;
923 929
924 if (WARN_ON(pipe >= dev->num_crtcs)) 930 if (WARN_ON(pipe >= dev->num_crtcs))
@@ -934,12 +940,33 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, unsigned int pipe,
934 smp_rmb(); 940 smp_rmb();
935 *vblanktime = vblanktimestamp(dev, pipe, cur_vblank); 941 *vblanktime = vblanktimestamp(dev, pipe, cur_vblank);
936 smp_rmb(); 942 smp_rmb();
937 } while (cur_vblank != vblank->count); 943 } while (cur_vblank != vblank->count && --count > 0);
938 944
939 return cur_vblank; 945 return cur_vblank;
940} 946}
941EXPORT_SYMBOL(drm_vblank_count_and_time); 947EXPORT_SYMBOL(drm_vblank_count_and_time);
942 948
949/**
950 * drm_crtc_vblank_count_and_time - retrieve "cooked" vblank counter value
951 * and the system timestamp corresponding to that vblank counter value
952 * @crtc: which counter to retrieve
953 * @vblanktime: Pointer to struct timeval to receive the vblank timestamp.
954 *
955 * Fetches the "cooked" vblank count value that represents the number of
956 * vblank events since the system was booted, including lost events due to
957 * modesetting activity. Returns corresponding system timestamp of the time
958 * of the vblank interval that corresponds to the current vblank counter value.
959 *
960 * This is the native KMS version of drm_vblank_count_and_time().
961 */
962u32 drm_crtc_vblank_count_and_time(struct drm_crtc *crtc,
963 struct timeval *vblanktime)
964{
965 return drm_vblank_count_and_time(crtc->dev, drm_crtc_index(crtc),
966 vblanktime);
967}
968EXPORT_SYMBOL(drm_crtc_vblank_count_and_time);
969
943static void send_vblank_event(struct drm_device *dev, 970static void send_vblank_event(struct drm_device *dev,
944 struct drm_pending_vblank_event *e, 971 struct drm_pending_vblank_event *e,
945 unsigned long seq, struct timeval *now) 972 unsigned long seq, struct timeval *now)
@@ -1033,7 +1060,7 @@ static int drm_vblank_enable(struct drm_device *dev, unsigned int pipe)
1033 atomic_dec(&vblank->refcount); 1060 atomic_dec(&vblank->refcount);
1034 else { 1061 else {
1035 vblank->enabled = true; 1062 vblank->enabled = true;
1036 drm_update_vblank_count(dev, pipe); 1063 drm_update_vblank_count(dev, pipe, 0);
1037 } 1064 }
1038 } 1065 }
1039 1066
@@ -1154,8 +1181,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_put);
1154 * @dev: DRM device 1181 * @dev: DRM device
1155 * @pipe: CRTC index 1182 * @pipe: CRTC index
1156 * 1183 *
1157 * This waits for one vblank to pass on @crtc, using the irq driver interfaces. 1184 * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
1158 * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. 1185 * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
1159 * due to lack of driver support or because the crtc is off. 1186 * due to lack of driver support or because the crtc is off.
1160 */ 1187 */
1161void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe) 1188void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
@@ -1276,7 +1303,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
1276 1303
1277/** 1304/**
1278 * drm_crtc_vblank_reset - reset vblank state to off on a CRTC 1305 * drm_crtc_vblank_reset - reset vblank state to off on a CRTC
1279 * @drm_crtc: CRTC in question 1306 * @crtc: CRTC in question
1280 * 1307 *
1281 * Drivers can use this function to reset the vblank state to off at load time. 1308 * Drivers can use this function to reset the vblank state to off at load time.
1282 * Drivers should use this together with the drm_crtc_vblank_off() and 1309 * Drivers should use this together with the drm_crtc_vblank_off() and
@@ -1284,12 +1311,12 @@ EXPORT_SYMBOL(drm_crtc_vblank_off);
1284 * drm_crtc_vblank_off() is that this function doesn't save the vblank counter 1311 * drm_crtc_vblank_off() is that this function doesn't save the vblank counter
1285 * and hence doesn't need to call any driver hooks. 1312 * and hence doesn't need to call any driver hooks.
1286 */ 1313 */
1287void drm_crtc_vblank_reset(struct drm_crtc *drm_crtc) 1314void drm_crtc_vblank_reset(struct drm_crtc *crtc)
1288{ 1315{
1289 struct drm_device *dev = drm_crtc->dev; 1316 struct drm_device *dev = crtc->dev;
1290 unsigned long irqflags; 1317 unsigned long irqflags;
1291 int crtc = drm_crtc_index(drm_crtc); 1318 unsigned int pipe = drm_crtc_index(crtc);
1292 struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; 1319 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1293 1320
1294 spin_lock_irqsave(&dev->vbl_lock, irqflags); 1321 spin_lock_irqsave(&dev->vbl_lock, irqflags);
1295 /* 1322 /*
@@ -1333,16 +1360,8 @@ void drm_vblank_on(struct drm_device *dev, unsigned int pipe)
1333 vblank->inmodeset = 0; 1360 vblank->inmodeset = 0;
1334 } 1361 }
1335 1362
1336 /* 1363 drm_reset_vblank_timestamp(dev, pipe);
1337 * sample the current counter to avoid random jumps 1364
1338 * when drm_vblank_enable() applies the diff
1339 *
1340 * -1 to make sure user will never see the same
1341 * vblank counter value before and after a modeset
1342 */
1343 vblank->last =
1344 (dev->driver->get_vblank_counter(dev, pipe) - 1) &
1345 dev->max_vblank_count;
1346 /* 1365 /*
1347 * re-enable interrupts if there are users left, or the 1366 * re-enable interrupts if there are users left, or the
1348 * user wishes vblank interrupts to be enabled all the time. 1367 * user wishes vblank interrupts to be enabled all the time.
@@ -1725,9 +1744,6 @@ static void drm_handle_vblank_events(struct drm_device *dev, unsigned int pipe)
1725bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe) 1744bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1726{ 1745{
1727 struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 1746 struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
1728 u32 vblcount;
1729 s64 diff_ns;
1730 struct timeval tvblank;
1731 unsigned long irqflags; 1747 unsigned long irqflags;
1732 1748
1733 if (WARN_ON_ONCE(!dev->num_crtcs)) 1749 if (WARN_ON_ONCE(!dev->num_crtcs))
@@ -1751,32 +1767,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe)
1751 return false; 1767 return false;
1752 } 1768 }
1753 1769
1754 /* Fetch corresponding timestamp for this vblank interval from 1770 drm_update_vblank_count(dev, pipe, DRM_CALLED_FROM_VBLIRQ);
1755 * driver and store it in proper slot of timestamp ringbuffer.
1756 */
1757
1758 /* Get current timestamp and count. */
1759 vblcount = vblank->count;
1760 drm_get_last_vbltimestamp(dev, pipe, &tvblank, DRM_CALLED_FROM_VBLIRQ);
1761
1762 /* Compute time difference to timestamp of last vblank */
1763 diff_ns = timeval_to_ns(&tvblank) -
1764 timeval_to_ns(&vblanktimestamp(dev, pipe, vblcount));
1765
1766 /* Update vblank timestamp and count if at least
1767 * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds
1768 * difference between last stored timestamp and current
1769 * timestamp. A smaller difference means basically
1770 * identical timestamps. Happens if this vblank has
1771 * been already processed and this is a redundant call,
1772 * e.g., due to spurious vblank interrupts. We need to
1773 * ignore those for accounting.
1774 */
1775 if (abs64(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS)
1776 store_vblank(dev, pipe, 1, &tvblank);
1777 else
1778 DRM_DEBUG("crtc %u: Redundant vblirq ignored. diff_ns = %d\n",
1779 pipe, (int) diff_ns);
1780 1771
1781 spin_unlock(&dev->vblank_time_lock); 1772 spin_unlock(&dev->vblank_time_lock);
1782 1773