diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 52 |
1 files changed, 26 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e3c02655d36f..2b6ce9b2674a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2806,13 +2806,34 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) | |||
2806 | udelay(100); | 2806 | udelay(100); |
2807 | } | 2807 | } |
2808 | 2808 | ||
2809 | static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) | ||
2810 | { | ||
2811 | struct drm_device *dev = crtc->dev; | ||
2812 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2813 | unsigned long flags; | ||
2814 | bool pending; | ||
2815 | |||
2816 | if (atomic_read(&dev_priv->mm.wedged)) | ||
2817 | return false; | ||
2818 | |||
2819 | spin_lock_irqsave(&dev->event_lock, flags); | ||
2820 | pending = to_intel_crtc(crtc)->unpin_work != NULL; | ||
2821 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
2822 | |||
2823 | return pending; | ||
2824 | } | ||
2825 | |||
2809 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) | 2826 | static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) |
2810 | { | 2827 | { |
2811 | struct drm_device *dev = crtc->dev; | 2828 | struct drm_device *dev = crtc->dev; |
2829 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2812 | 2830 | ||
2813 | if (crtc->fb == NULL) | 2831 | if (crtc->fb == NULL) |
2814 | return; | 2832 | return; |
2815 | 2833 | ||
2834 | wait_event(dev_priv->pending_flip_queue, | ||
2835 | !intel_crtc_has_pending_flip(crtc)); | ||
2836 | |||
2816 | mutex_lock(&dev->struct_mutex); | 2837 | mutex_lock(&dev->struct_mutex); |
2817 | intel_finish_fb(crtc->fb); | 2838 | intel_finish_fb(crtc->fb); |
2818 | mutex_unlock(&dev->struct_mutex); | 2839 | mutex_unlock(&dev->struct_mutex); |
@@ -4370,7 +4391,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, | |||
4370 | /* default to 8bpc */ | 4391 | /* default to 8bpc */ |
4371 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); | 4392 | pipeconf &= ~(PIPECONF_BPP_MASK | PIPECONF_DITHER_EN); |
4372 | if (is_dp) { | 4393 | if (is_dp) { |
4373 | if (mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { | 4394 | if (adjusted_mode->private_flags & INTEL_MODE_DP_FORCE_6BPC) { |
4374 | pipeconf |= PIPECONF_BPP_6 | | 4395 | pipeconf |= PIPECONF_BPP_6 | |
4375 | PIPECONF_DITHER_EN | | 4396 | PIPECONF_DITHER_EN | |
4376 | PIPECONF_DITHER_TYPE_SP; | 4397 | PIPECONF_DITHER_TYPE_SP; |
@@ -4802,7 +4823,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, | |||
4802 | target_clock = adjusted_mode->clock; | 4823 | target_clock = adjusted_mode->clock; |
4803 | 4824 | ||
4804 | /* determine panel color depth */ | 4825 | /* determine panel color depth */ |
4805 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, mode); | 4826 | dither = intel_choose_pipe_bpp_dither(crtc, fb, &pipe_bpp, |
4827 | adjusted_mode); | ||
4806 | if (is_lvds && dev_priv->lvds_dither) | 4828 | if (is_lvds && dev_priv->lvds_dither) |
4807 | dither = true; | 4829 | dither = true; |
4808 | 4830 | ||
@@ -6159,15 +6181,13 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
6159 | struct intel_unpin_work *work; | 6181 | struct intel_unpin_work *work; |
6160 | struct drm_i915_gem_object *obj; | 6182 | struct drm_i915_gem_object *obj; |
6161 | struct drm_pending_vblank_event *e; | 6183 | struct drm_pending_vblank_event *e; |
6162 | struct timeval tnow, tvbl; | 6184 | struct timeval tvbl; |
6163 | unsigned long flags; | 6185 | unsigned long flags; |
6164 | 6186 | ||
6165 | /* Ignore early vblank irqs */ | 6187 | /* Ignore early vblank irqs */ |
6166 | if (intel_crtc == NULL) | 6188 | if (intel_crtc == NULL) |
6167 | return; | 6189 | return; |
6168 | 6190 | ||
6169 | do_gettimeofday(&tnow); | ||
6170 | |||
6171 | spin_lock_irqsave(&dev->event_lock, flags); | 6191 | spin_lock_irqsave(&dev->event_lock, flags); |
6172 | work = intel_crtc->unpin_work; | 6192 | work = intel_crtc->unpin_work; |
6173 | if (work == NULL || !work->pending) { | 6193 | if (work == NULL || !work->pending) { |
@@ -6181,25 +6201,6 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
6181 | e = work->event; | 6201 | e = work->event; |
6182 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); | 6202 | e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); |
6183 | 6203 | ||
6184 | /* Called before vblank count and timestamps have | ||
6185 | * been updated for the vblank interval of flip | ||
6186 | * completion? Need to increment vblank count and | ||
6187 | * add one videorefresh duration to returned timestamp | ||
6188 | * to account for this. We assume this happened if we | ||
6189 | * get called over 0.9 frame durations after the last | ||
6190 | * timestamped vblank. | ||
6191 | * | ||
6192 | * This calculation can not be used with vrefresh rates | ||
6193 | * below 5Hz (10Hz to be on the safe side) without | ||
6194 | * promoting to 64 integers. | ||
6195 | */ | ||
6196 | if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) > | ||
6197 | 9 * crtc->framedur_ns) { | ||
6198 | e->event.sequence++; | ||
6199 | tvbl = ns_to_timeval(timeval_to_ns(&tvbl) + | ||
6200 | crtc->framedur_ns); | ||
6201 | } | ||
6202 | |||
6203 | e->event.tv_sec = tvbl.tv_sec; | 6204 | e->event.tv_sec = tvbl.tv_sec; |
6204 | e->event.tv_usec = tvbl.tv_usec; | 6205 | e->event.tv_usec = tvbl.tv_usec; |
6205 | 6206 | ||
@@ -6216,9 +6217,8 @@ static void do_intel_finish_page_flip(struct drm_device *dev, | |||
6216 | 6217 | ||
6217 | atomic_clear_mask(1 << intel_crtc->plane, | 6218 | atomic_clear_mask(1 << intel_crtc->plane, |
6218 | &obj->pending_flip.counter); | 6219 | &obj->pending_flip.counter); |
6219 | if (atomic_read(&obj->pending_flip) == 0) | ||
6220 | wake_up(&dev_priv->pending_flip_queue); | ||
6221 | 6220 | ||
6221 | wake_up(&dev_priv->pending_flip_queue); | ||
6222 | schedule_work(&work->work); | 6222 | schedule_work(&work->work); |
6223 | 6223 | ||
6224 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); | 6224 | trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); |