Commit 4b276ed3 authored by Lucas De Marchi's avatar Lucas De Marchi

drm/i915/uncore: Warn on previous unclaimed accesses

Since gen6 we use FPGA_DBG register to detect unclaimed MMIO registers.
This register is in the display engine IP and can only ever detect
unclaimed accesses to registers in this area. However sometimes there
are reports of this triggering for registers in other areas, which
should not be possible.

Right now we always warn after the read/write of registers going through
unclaimed_reg_debug(). However places using __raw_uncore_* may be
triggering the unclaimed access and those being later accounted to a
different register. Let's warn both before and after the read/write
with a slightly different message, so it's clear if the register
reported in the warning is actually the culprit.

Commit dda96033 ("drm/i915: Just clear the mmiodebug before a
register access") attempted to solve the same issue by removing the
warning when if FPGA_DBG flags before the mmio read/write. However, it
doesn't solve it completely as FPGA_DBG may remain set when reading
registers outside display. So in the end the check after the mmio
read/write triggers the warning pointing to the wrong register.
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220405001149.2675226-1-lucas.demarchi@intel.com
parent 59207e63
...@@ -1502,11 +1502,10 @@ ilk_dummy_write(struct intel_uncore *uncore) ...@@ -1502,11 +1502,10 @@ ilk_dummy_write(struct intel_uncore *uncore)
static void static void
__unclaimed_reg_debug(struct intel_uncore *uncore, __unclaimed_reg_debug(struct intel_uncore *uncore,
const i915_reg_t reg, const i915_reg_t reg,
const bool read, const bool read)
const bool before)
{ {
if (drm_WARN(&uncore->i915->drm, if (drm_WARN(&uncore->i915->drm,
check_for_unclaimed_mmio(uncore) && !before, check_for_unclaimed_mmio(uncore),
"Unclaimed %s register 0x%x\n", "Unclaimed %s register 0x%x\n",
read ? "read from" : "write to", read ? "read from" : "write to",
i915_mmio_reg_offset(reg))) i915_mmio_reg_offset(reg)))
...@@ -1514,6 +1513,20 @@ __unclaimed_reg_debug(struct intel_uncore *uncore, ...@@ -1514,6 +1513,20 @@ __unclaimed_reg_debug(struct intel_uncore *uncore,
uncore->i915->params.mmio_debug--; uncore->i915->params.mmio_debug--;
} }
static void
__unclaimed_previous_reg_debug(struct intel_uncore *uncore,
const i915_reg_t reg,
const bool read)
{
if (drm_WARN(&uncore->i915->drm,
check_for_unclaimed_mmio(uncore),
"Unclaimed access detected before %s register 0x%x\n",
read ? "read from" : "write to",
i915_mmio_reg_offset(reg)))
/* Only report the first N failures */
uncore->i915->params.mmio_debug--;
}
static inline void static inline void
unclaimed_reg_debug(struct intel_uncore *uncore, unclaimed_reg_debug(struct intel_uncore *uncore,
const i915_reg_t reg, const i915_reg_t reg,
...@@ -1526,13 +1539,13 @@ unclaimed_reg_debug(struct intel_uncore *uncore, ...@@ -1526,13 +1539,13 @@ unclaimed_reg_debug(struct intel_uncore *uncore,
/* interrupts are disabled and re-enabled around uncore->lock usage */ /* interrupts are disabled and re-enabled around uncore->lock usage */
lockdep_assert_held(&uncore->lock); lockdep_assert_held(&uncore->lock);
if (before) if (before) {
spin_lock(&uncore->debug->lock); spin_lock(&uncore->debug->lock);
__unclaimed_previous_reg_debug(uncore, reg, read);
__unclaimed_reg_debug(uncore, reg, read, before); } else {
__unclaimed_reg_debug(uncore, reg, read);
if (!before)
spin_unlock(&uncore->debug->lock); spin_unlock(&uncore->debug->lock);
}
} }
#define __vgpu_read(x) \ #define __vgpu_read(x) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment