summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/i915_gpu_error.c
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2016-09-20 16:54:33 +0300
committerImre Deak <imre.deak@intel.com>2016-09-21 15:33:29 +0300
commitf9e613728090e7fe4e755bf56df17cbc277bac3f (patch)
tree1fb481bdef33d219a757edb03d78c638c5354a78 /drivers/gpu/drm/i915/i915_gpu_error.c
parentd636951ec01bcb2b7dee02f75ff4815714785a53 (diff)
drm/i915: Try to print INSTDONE bits for all slice/subslice
v2: (Imre) - Access only subslices that are known to exist. - Reset explicitly the MCR selector to slice/sub-slice ID 0 after the readout. - Use the subslice INSTDONE bits for the hangcheck/subunits-stuck detection too. - Take the uncore lock for the MCR-select/subslice-readout sequence. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1474379673-28326-2-git-send-email-imre.deak@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gpu_error.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gpu_error.c76
1 files changed, 70 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c
index 6a2775aad354..2bbab226a46c 100644
--- a/drivers/gpu/drm/i915/i915_gpu_error.c
+++ b/drivers/gpu/drm/i915/i915_gpu_error.c
@@ -231,6 +231,9 @@ static const char *hangcheck_action_to_str(enum intel_engine_hangcheck_action a)
static void error_print_instdone(struct drm_i915_error_state_buf *m,
struct drm_i915_error_engine *ee)
{
+ int slice;
+ int subslice;
+
err_printf(m, " INSTDONE: 0x%08x\n",
ee->instdone.instdone);
@@ -243,10 +246,15 @@ static void error_print_instdone(struct drm_i915_error_state_buf *m,
if (INTEL_GEN(m->i915) <= 6)
return;
- err_printf(m, " SAMPLER_INSTDONE: 0x%08x\n",
- ee->instdone.sampler);
- err_printf(m, " ROW_INSTDONE: 0x%08x\n",
- ee->instdone.row);
+ for_each_instdone_slice_subslice(m->i915, slice, subslice)
+ err_printf(m, " SAMPLER_INSTDONE[%d][%d]: 0x%08x\n",
+ slice, subslice,
+ ee->instdone.sampler[slice][subslice]);
+
+ for_each_instdone_slice_subslice(m->i915, slice, subslice)
+ err_printf(m, " ROW_INSTDONE[%d][%d]: 0x%08x\n",
+ slice, subslice,
+ ee->instdone.row[slice][subslice]);
}
static void error_print_engine(struct drm_i915_error_state_buf *m,
@@ -1549,12 +1557,52 @@ const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
}
}
+static inline uint32_t
+read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
+ int subslice, i915_reg_t reg)
+{
+ uint32_t mcr;
+ uint32_t ret;
+ enum forcewake_domains fw_domains;
+
+ fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
+ FW_REG_READ);
+ fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
+ GEN8_MCR_SELECTOR,
+ FW_REG_READ | FW_REG_WRITE);
+
+ spin_lock_irq(&dev_priv->uncore.lock);
+ intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
+
+ mcr = I915_READ_FW(GEN8_MCR_SELECTOR);
+ /*
+ * The HW expects the slice and sublice selectors to be reset to 0
+ * after reading out the registers.
+ */
+ WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK));
+ mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
+ mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
+ I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
+
+ ret = I915_READ_FW(reg);
+
+ mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
+ I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
+
+ intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
+ spin_unlock_irq(&dev_priv->uncore.lock);
+
+ return ret;
+}
+
/* NB: please notice the memset */
void i915_get_engine_instdone(struct drm_i915_private *dev_priv,
enum intel_engine_id engine_id,
struct intel_instdone *instdone)
{
u32 mmio_base = dev_priv->engine[engine_id].mmio_base;
+ int slice;
+ int subslice;
memset(instdone, 0, sizeof(*instdone));
@@ -1566,8 +1614,24 @@ void i915_get_engine_instdone(struct drm_i915_private *dev_priv,
break;
instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
- instdone->sampler = I915_READ(GEN7_SAMPLER_INSTDONE);
- instdone->row = I915_READ(GEN7_ROW_INSTDONE);
+ for_each_instdone_slice_subslice(dev_priv, slice, subslice) {
+ instdone->sampler[slice][subslice] =
+ read_subslice_reg(dev_priv, slice, subslice,
+ GEN7_SAMPLER_INSTDONE);
+ instdone->row[slice][subslice] =
+ read_subslice_reg(dev_priv, slice, subslice,
+ GEN7_ROW_INSTDONE);
+ }
+ break;
+ case 7:
+ instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
+
+ if (engine_id != RCS)
+ break;
+
+ instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
+ instdone->sampler[0][0] = I915_READ(GEN7_SAMPLER_INSTDONE);
+ instdone->row[0][0] = I915_READ(GEN7_ROW_INSTDONE);
break;
case 6: