diff options
author | Ben Widawsky | 2016-09-20 15:54:33 +0200 |
---|---|---|
committer | Imre Deak | 2016-09-21 14:33:29 +0200 |
commit | f9e613728090e7fe4e755bf56df17cbc277bac3f (patch) | |
tree | 1fb481bdef33d219a757edb03d78c638c5354a78 /drivers/gpu/drm/i915/i915_gpu_error.c | |
parent | drm/i915: Cleanup instdone collection (diff) | |
download | kernel-qcow2-linux-f9e613728090e7fe4e755bf56df17cbc277bac3f.tar.gz kernel-qcow2-linux-f9e613728090e7fe4e755bf56df17cbc277bac3f.tar.xz kernel-qcow2-linux-f9e613728090e7fe4e755bf56df17cbc277bac3f.zip |
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.c | 76 |
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: |