aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/intel_display.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0c201d684584..fe6538297872 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5252,21 +5252,22 @@ static void intel_unpin_work_fn(struct work_struct *__work)
5252} 5252}
5253 5253
5254static void do_intel_finish_page_flip(struct drm_device *dev, 5254static void do_intel_finish_page_flip(struct drm_device *dev,
5255 struct drm_crtc *crtc, 5255 struct drm_crtc *crtc)
5256 int called_before_vblirq)
5257{ 5256{
5258 drm_i915_private_t *dev_priv = dev->dev_private; 5257 drm_i915_private_t *dev_priv = dev->dev_private;
5259 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 5258 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
5260 struct intel_unpin_work *work; 5259 struct intel_unpin_work *work;
5261 struct drm_i915_gem_object *obj; 5260 struct drm_i915_gem_object *obj;
5262 struct drm_pending_vblank_event *e; 5261 struct drm_pending_vblank_event *e;
5263 struct timeval now; 5262 struct timeval tnow, tvbl;
5264 unsigned long flags; 5263 unsigned long flags;
5265 5264
5266 /* Ignore early vblank irqs */ 5265 /* Ignore early vblank irqs */
5267 if (intel_crtc == NULL) 5266 if (intel_crtc == NULL)
5268 return; 5267 return;
5269 5268
5269 do_gettimeofday(&tnow);
5270
5270 spin_lock_irqsave(&dev->event_lock, flags); 5271 spin_lock_irqsave(&dev->event_lock, flags);
5271 work = intel_crtc->unpin_work; 5272 work = intel_crtc->unpin_work;
5272 if (work == NULL || !work->pending) { 5273 if (work == NULL || !work->pending) {
@@ -5278,22 +5279,29 @@ static void do_intel_finish_page_flip(struct drm_device *dev,
5278 5279
5279 if (work->event) { 5280 if (work->event) {
5280 e = work->event; 5281 e = work->event;
5281 e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &now); 5282 e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl);
5282 5283
5283 /* Called before vblank count and timestamps have 5284 /* Called before vblank count and timestamps have
5284 * been updated for the vblank interval of flip 5285 * been updated for the vblank interval of flip
5285 * completion? Need to increment vblank count and 5286 * completion? Need to increment vblank count and
5286 * add one videorefresh duration to returned timestamp 5287 * add one videorefresh duration to returned timestamp
5287 * to account for this. 5288 * to account for this. We assume this happened if we
5289 * get called over 0.9 frame durations after the last
5290 * timestamped vblank.
5291 *
5292 * This calculation can not be used with vrefresh rates
5293 * below 5Hz (10Hz to be on the safe side) without
5294 * promoting to 64 integers.
5288 */ 5295 */
5289 if (called_before_vblirq) { 5296 if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) >
5297 9 * crtc->framedur_ns) {
5290 e->event.sequence++; 5298 e->event.sequence++;
5291 now = ns_to_timeval(timeval_to_ns(&now) + 5299 tvbl = ns_to_timeval(timeval_to_ns(&tvbl) +
5292 crtc->framedur_ns); 5300 crtc->framedur_ns);
5293 } 5301 }
5294 5302
5295 e->event.tv_sec = now.tv_sec; 5303 e->event.tv_sec = tvbl.tv_sec;
5296 e->event.tv_usec = now.tv_usec; 5304 e->event.tv_usec = tvbl.tv_usec;
5297 5305
5298 list_add_tail(&e->base.link, 5306 list_add_tail(&e->base.link,
5299 &e->base.file_priv->event_list); 5307 &e->base.file_priv->event_list);
@@ -5321,8 +5329,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe)
5321 drm_i915_private_t *dev_priv = dev->dev_private; 5329 drm_i915_private_t *dev_priv = dev->dev_private;
5322 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; 5330 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
5323 5331
5324 /* Called after drm_handle_vblank has run for finish vblank. */ 5332 do_intel_finish_page_flip(dev, crtc);
5325 do_intel_finish_page_flip(dev, crtc, 0);
5326} 5333}
5327 5334
5328void intel_finish_page_flip_plane(struct drm_device *dev, int plane) 5335void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
@@ -5330,8 +5337,7 @@ void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
5330 drm_i915_private_t *dev_priv = dev->dev_private; 5337 drm_i915_private_t *dev_priv = dev->dev_private;
5331 struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; 5338 struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
5332 5339
5333 /* Called before drm_handle_vblank has run for finish vblank. */ 5340 do_intel_finish_page_flip(dev, crtc);
5334 do_intel_finish_page_flip(dev, crtc, 1);
5335} 5341}
5336 5342
5337void intel_prepare_page_flip(struct drm_device *dev, int plane) 5343void intel_prepare_page_flip(struct drm_device *dev, int plane)