aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorSimon Farnsworth <simon.farnsworth@onelan.co.uk>2010-09-01 12:47:52 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-07 06:16:35 -0400
commit4e5359cd053bfb7d8dabe4a63624a5726848ffbc (patch)
treeea7b81407d31dc62fe495d5a5899c79ea692db33 /drivers/gpu/drm/i915/intel_display.c
parent8e647a279ca30029f19eca646de08a6338eab924 (diff)
drm/i915: Avoid pageflipping freeze when we miss the flip prepare interrupt
When we miss the flip prepare interrupt, we never get into the software state needed to restart userspace, resulting in a freeze of a full-screen OpenGL application (such as a compositor). Work around this by checking DSPxSURF/DSPxBASE to see if the page flip has actually happened. If it has, do the work we would have done when the flip prepare interrupt comes in. Also, add debugfs information to tell us what's going on (based on the patch from Chris Wilson attached to bugs.fdo bug #29798). Signed-off-by: Simon Farnsworth <simon.farnsworth@onelan.co.uk> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b90443f1eb3..1bd0c672ec90 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4864,15 +4864,6 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
4864 kfree(intel_crtc); 4864 kfree(intel_crtc);
4865} 4865}
4866 4866
4867struct intel_unpin_work {
4868 struct work_struct work;
4869 struct drm_device *dev;
4870 struct drm_gem_object *old_fb_obj;
4871 struct drm_gem_object *pending_flip_obj;
4872 struct drm_pending_vblank_event *event;
4873 int pending;
4874};
4875
4876static void intel_unpin_work_fn(struct work_struct *__work) 4867static void intel_unpin_work_fn(struct work_struct *__work)
4877{ 4868{
4878 struct intel_unpin_work *work = 4869 struct intel_unpin_work *work =
@@ -4960,7 +4951,8 @@ void intel_prepare_page_flip(struct drm_device *dev, int plane)
4960 4951
4961 spin_lock_irqsave(&dev->event_lock, flags); 4952 spin_lock_irqsave(&dev->event_lock, flags);
4962 if (intel_crtc->unpin_work) { 4953 if (intel_crtc->unpin_work) {
4963 intel_crtc->unpin_work->pending = 1; 4954 if ((++intel_crtc->unpin_work->pending) > 1)
4955 DRM_ERROR("Prepared flip multiple times\n");
4964 } else { 4956 } else {
4965 DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n"); 4957 DRM_DEBUG_DRIVER("preparing flip with no unpin work?\n");
4966 } 4958 }
@@ -5044,6 +5036,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
5044 ADVANCE_LP_RING(); 5036 ADVANCE_LP_RING();
5045 } 5037 }
5046 5038
5039 work->enable_stall_check = true;
5040
5047 /* Offset into the new buffer for cases of shared fbs between CRTCs */ 5041 /* Offset into the new buffer for cases of shared fbs between CRTCs */
5048 offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; 5042 offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
5049 5043