From e414a1a75bec36438191f5817dcb594b481a227c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 18 Feb 2013 19:08:49 +0200 Subject: [PATCH] --- yaml --- r: 371151 b: refs/heads/master c: 96a02917a0131e52efefde49c2784c0421d6c439 h: refs/heads/master i: 371149: f3dd36b8568c32fbabdfc0e3b0b6b5a109e6caf1 371147: a2149ea38288e8d5c06b4a908cf348b290dd405a 371143: 3e07bb569cac168e5f614ecc80288e47c9fa76e6 371135: 45a20ab46c071bf08e889bf5673e4fd528d26280 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_irq.c | 2 ++ trunk/drivers/gpu/drm/i915/intel_display.c | 38 ++++++++++++++++++++++ trunk/drivers/gpu/drm/i915/intel_drv.h | 2 ++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f4d06e9c52f9..9a712551e222 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4878cae22a2405b6d33318e2dc99a9c1367fee44 +refs/heads/master: 96a02917a0131e52efefde49c2784c0421d6c439 diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 2cd97d1cc920..9fde49a29999 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -915,6 +915,8 @@ static void i915_error_work_func(struct work_struct *work) for_each_ring(ring, dev_priv, i) wake_up_all(&ring->irq_queue); + intel_display_handle_reset(dev); + wake_up_all(&dev_priv->gpu_error.reset_queue); } } diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 85bf178bac75..ba8307dc03be 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2218,6 +2218,44 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, return dev_priv->display.update_plane(crtc, fb, x, y); } +void intel_display_handle_reset(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_crtc *crtc; + + /* + * Flips in the rings have been nuked by the reset, + * so complete all pending flips so that user space + * will get its events and not get stuck. + * + * Also update the base address of all primary + * planes to the the last fb to make sure we're + * showing the correct fb after a reset. + * + * Need to make two loops over the crtcs so that we + * don't try to grab a crtc mutex before the + * pending_flip_queue really got woken up. + */ + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + enum plane plane = intel_crtc->plane; + + intel_prepare_page_flip(dev, plane); + intel_finish_page_flip_plane(dev, plane); + } + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + mutex_lock(&crtc->mutex); + if (intel_crtc->active) + dev_priv->display.update_plane(crtc, crtc->fb, + crtc->x, crtc->y); + mutex_unlock(&crtc->mutex); + } +} + static int intel_finish_fb(struct drm_framebuffer *old_fb) { diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 005a91f1f8f5..febed9a010da 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -695,4 +695,6 @@ extern bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector); extern void intel_ddi_fdi_disable(struct drm_crtc *crtc); +extern void intel_display_handle_reset(struct drm_device *dev); + #endif /* __INTEL_DRV_H__ */