Skip to content

Commit

Permalink
drm/i915: clear error registers after error capture
Browse files Browse the repository at this point in the history
We need to clear the register in order to get correct value after the
next potential hang.

v2: Centralize error register clearing in i915_irq.c (Chris)

v3: Don't read gen8 register on < gen6 (Chris)

v4: Don't swap gen8+ & gen6+ code... (Chris)

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20180830132424.21940-1-lionel.g.landwerlin@intel.com
  • Loading branch information
Lionel Landwerlin committed Aug 30, 2018
1 parent 381116d commit 0960554
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 13 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2807,6 +2807,8 @@ extern void intel_irq_fini(struct drm_i915_private *dev_priv);
int intel_irq_install(struct drm_i915_private *dev_priv);
void intel_irq_uninstall(struct drm_i915_private *dev_priv);

void i915_clear_error_registers(struct drm_i915_private *dev_priv);

static inline bool intel_gvt_active(struct drm_i915_private *dev_priv)
{
return dev_priv->gvt;
Expand Down
18 changes: 6 additions & 12 deletions drivers/gpu/drm/i915/i915_gem_gtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2337,7 +2337,7 @@ static bool needs_idle_maps(struct drm_i915_private *dev_priv)
return IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_vtd_active();
}

static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv)
static void gen6_check_faults(struct drm_i915_private *dev_priv)
{
struct intel_engine_cs *engine;
enum intel_engine_id id;
Expand All @@ -2355,15 +2355,11 @@ static void gen6_check_and_clear_faults(struct drm_i915_private *dev_priv)
fault & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
RING_FAULT_SRCID(fault),
RING_FAULT_FAULT_TYPE(fault));
I915_WRITE(RING_FAULT_REG(engine),
fault & ~RING_FAULT_VALID);
}
}

POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
}

static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv)
static void gen8_check_faults(struct drm_i915_private *dev_priv)
{
u32 fault = I915_READ(GEN8_RING_FAULT_REG);

Expand All @@ -2388,22 +2384,20 @@ static void gen8_check_and_clear_faults(struct drm_i915_private *dev_priv)
GEN8_RING_FAULT_ENGINE_ID(fault),
RING_FAULT_SRCID(fault),
RING_FAULT_FAULT_TYPE(fault));
I915_WRITE(GEN8_RING_FAULT_REG,
fault & ~RING_FAULT_VALID);
}

POSTING_READ(GEN8_RING_FAULT_REG);
}

void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
{
/* From GEN8 onwards we only have one 'All Engine Fault Register' */
if (INTEL_GEN(dev_priv) >= 8)
gen8_check_and_clear_faults(dev_priv);
gen8_check_faults(dev_priv);
else if (INTEL_GEN(dev_priv) >= 6)
gen6_check_and_clear_faults(dev_priv);
gen6_check_faults(dev_priv);
else
return;

i915_clear_error_registers(dev_priv);
}

void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
Expand Down
18 changes: 17 additions & 1 deletion drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -3215,7 +3215,7 @@ static void i915_reset_device(struct drm_i915_private *dev_priv,
kobject_uevent_env(kobj, KOBJ_CHANGE, reset_done_event);
}

static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
void i915_clear_error_registers(struct drm_i915_private *dev_priv)
{
u32 eir;

Expand All @@ -3238,6 +3238,22 @@ static void i915_clear_error_registers(struct drm_i915_private *dev_priv)
I915_WRITE(EMR, I915_READ(EMR) | eir);
I915_WRITE(IIR, I915_MASTER_ERROR_INTERRUPT);
}

if (INTEL_GEN(dev_priv) >= 8) {
I915_WRITE(GEN8_RING_FAULT_REG,
I915_READ(GEN8_RING_FAULT_REG) & ~RING_FAULT_VALID);
POSTING_READ(GEN8_RING_FAULT_REG);
} else if (INTEL_GEN(dev_priv) >= 6) {
struct intel_engine_cs *engine;
enum intel_engine_id id;

for_each_engine(engine, dev_priv, id) {
I915_WRITE(RING_FAULT_REG(engine),
I915_READ(RING_FAULT_REG(engine)) &
~RING_FAULT_VALID);
}
POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
}
}

/**
Expand Down

0 comments on commit 0960554

Please sign in to comment.