diff mbox series

[v2] drm/i915: Restore interrupt enabling after a reset

Message ID 20190218153106.16768-1-chris@chris-wilson.co.uk (mailing list archive)
State New, archived
Headers show
Series [v2] drm/i915: Restore interrupt enabling after a reset | expand

Commit Message

Chris Wilson Feb. 18, 2019, 3:31 p.m. UTC
At least on i965g and i965gm, performing a device reset clobbers the IER
resulting in loss of interrupts thereafter. So, run the irq_postinstall
hook to restore them.

v2: Ville pointed out that he already attempted to solve this problem by
reinstall the interrupts in intel_reset_finish() (part of the display
handling around reset). However, reinstalling the irq clobbers the
i915->irq_mask which we need for handling MI_USER_INTERRUPTS, and does
so too late to handle any interrupts generating from resuming the rings.
The simple solution to both is to pull the interrupt reenabling from
afterwards to around the device reset.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reset.c    | 6 ++++++
 drivers/gpu/drm/i915/intel_display.c | 3 ---
 2 files changed, 6 insertions(+), 3 deletions(-)

Comments

Ville Syrjälä Feb. 18, 2019, 3:38 p.m. UTC | #1
On Mon, Feb 18, 2019 at 03:31:06PM +0000, Chris Wilson wrote:
> At least on i965g and i965gm, performing a device reset clobbers the IER
> resulting in loss of interrupts thereafter. So, run the irq_postinstall
> hook to restore them.
> 
> v2: Ville pointed out that he already attempted to solve this problem by
> reinstall the interrupts in intel_reset_finish() (part of the display
> handling around reset). However, reinstalling the irq clobbers the
> i915->irq_mask which we need for handling MI_USER_INTERRUPTS, and does
> so too late to handle any interrupts generating from resuming the rings.
> The simple solution to both is to pull the interrupt reenabling from
> afterwards to around the device reset.
> 
> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  drivers/gpu/drm/i915/i915_reset.c    | 6 ++++++
>  drivers/gpu/drm/i915/intel_display.c | 3 ---
>  2 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c
> index 1911e00d2581..4df4c674223d 100644
> --- a/drivers/gpu/drm/i915/i915_reset.c
> +++ b/drivers/gpu/drm/i915/i915_reset.c
> @@ -995,11 +995,17 @@ void i915_reset(struct drm_i915_private *i915,
>  		goto error;
>  	}
>  
> +	if (INTEL_INFO(i915)->gpu_reset_clobbers_display)
> +		intel_runtime_pm_disable_interrupts(i915);
> +
>  	if (do_reset(i915, stalled_mask)) {
>  		dev_err(i915->drm.dev, "Failed to reset chip\n");
>  		goto taint;
>  	}
>  
> +	if (INTEL_INFO(i915)->gpu_reset_clobbers_display)
> +		intel_runtime_pm_enable_interrupts(i915);
> +

Looks quite sensible to me.

Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

>  	intel_overlay_reset(i915);
>  
>  	/*
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index afa21daaae51..3b4a6eeb4573 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3931,9 +3931,6 @@ void intel_finish_reset(struct drm_i915_private *dev_priv)
>  		 * The display has been reset as well,
>  		 * so need a full re-initialization.
>  		 */
> -		intel_runtime_pm_disable_interrupts(dev_priv);
> -		intel_runtime_pm_enable_interrupts(dev_priv);
> -
>  		intel_pps_unlock_regs_wa(dev_priv);
>  		intel_modeset_init_hw(dev);
>  		intel_init_clock_gating(dev_priv);
> -- 
> 2.20.1
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_reset.c b/drivers/gpu/drm/i915/i915_reset.c
index 1911e00d2581..4df4c674223d 100644
--- a/drivers/gpu/drm/i915/i915_reset.c
+++ b/drivers/gpu/drm/i915/i915_reset.c
@@ -995,11 +995,17 @@  void i915_reset(struct drm_i915_private *i915,
 		goto error;
 	}
 
+	if (INTEL_INFO(i915)->gpu_reset_clobbers_display)
+		intel_runtime_pm_disable_interrupts(i915);
+
 	if (do_reset(i915, stalled_mask)) {
 		dev_err(i915->drm.dev, "Failed to reset chip\n");
 		goto taint;
 	}
 
+	if (INTEL_INFO(i915)->gpu_reset_clobbers_display)
+		intel_runtime_pm_enable_interrupts(i915);
+
 	intel_overlay_reset(i915);
 
 	/*
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index afa21daaae51..3b4a6eeb4573 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3931,9 +3931,6 @@  void intel_finish_reset(struct drm_i915_private *dev_priv)
 		 * The display has been reset as well,
 		 * so need a full re-initialization.
 		 */
-		intel_runtime_pm_disable_interrupts(dev_priv);
-		intel_runtime_pm_enable_interrupts(dev_priv);
-
 		intel_pps_unlock_regs_wa(dev_priv);
 		intel_modeset_init_hw(dev);
 		intel_init_clock_gating(dev_priv);