aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-03-04 08:15:08 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-05 15:30:05 -0500
commit7d5e379989f46d80617709d4c45947136c50b2c6 (patch)
treef4137105bed19e62bc967896b6724081231639e2 /drivers/gpu/drm/i915/intel_display.c
parent227213438aff3050f2dd2be92dc48c8370d445a2 (diff)
drm/i915: Reject changes of fb base when we have a flip pending
This should be impossible due to the wait for outstanding flips that the caller is meant to perform prior to updating the scanout base. Paranoia tells me to check anyway. References: https://bugs.freedesktop.org/show_bug.cgi?id=75502 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 924f3cee4bad..7f92b039191b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2321,6 +2321,25 @@ intel_finish_fb(struct drm_framebuffer *old_fb)
2321 return ret; 2321 return ret;
2322} 2322}
2323 2323
2324static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
2325{
2326 struct drm_device *dev = crtc->dev;
2327 struct drm_i915_private *dev_priv = dev->dev_private;
2328 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2329 unsigned long flags;
2330 bool pending;
2331
2332 if (i915_reset_in_progress(&dev_priv->gpu_error) ||
2333 intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
2334 return false;
2335
2336 spin_lock_irqsave(&dev->event_lock, flags);
2337 pending = to_intel_crtc(crtc)->unpin_work != NULL;
2338 spin_unlock_irqrestore(&dev->event_lock, flags);
2339
2340 return pending;
2341}
2342
2324static int 2343static int
2325intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, 2344intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
2326 struct drm_framebuffer *fb) 2345 struct drm_framebuffer *fb)
@@ -2331,6 +2350,11 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
2331 struct drm_framebuffer *old_fb; 2350 struct drm_framebuffer *old_fb;
2332 int ret; 2351 int ret;
2333 2352
2353 if (intel_crtc_has_pending_flip(crtc)) {
2354 DRM_ERROR("pipe is still busy with an old pageflip\n");
2355 return -EBUSY;
2356 }
2357
2334 /* no fb bound */ 2358 /* no fb bound */
2335 if (!fb) { 2359 if (!fb) {
2336 DRM_ERROR("No FB bound\n"); 2360 DRM_ERROR("No FB bound\n");
@@ -2956,25 +2980,6 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc)
2956 udelay(100); 2980 udelay(100);
2957} 2981}
2958 2982
2959static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc)
2960{
2961 struct drm_device *dev = crtc->dev;
2962 struct drm_i915_private *dev_priv = dev->dev_private;
2963 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2964 unsigned long flags;
2965 bool pending;
2966
2967 if (i915_reset_in_progress(&dev_priv->gpu_error) ||
2968 intel_crtc->reset_counter != atomic_read(&dev_priv->gpu_error.reset_counter))
2969 return false;
2970
2971 spin_lock_irqsave(&dev->event_lock, flags);
2972 pending = to_intel_crtc(crtc)->unpin_work != NULL;
2973 spin_unlock_irqrestore(&dev->event_lock, flags);
2974
2975 return pending;
2976}
2977
2978bool intel_has_pending_fb_unpin(struct drm_device *dev) 2983bool intel_has_pending_fb_unpin(struct drm_device *dev)
2979{ 2984{
2980 struct intel_crtc *crtc; 2985 struct intel_crtc *crtc;