[Intel-gfx] [PATCH 1/2] drm/i915: Stop using DC states if firmware disagrees on the state
Chris Wilson
chris at chris-wilson.co.uk
Wed Jan 20 01:36:12 PST 2016
On Tue, Jan 19, 2016 at 09:50:08PM +0200, Mika Kuoppala wrote:
> Sometimes we get dmesg warnings claiming that DC6 was already
> enabled prior to our enabling. Investigations using readback of
> the written dc state value indicate that sometimes when we disable
> the dc6, the write doesn't stick, or it does but for a very short time.
>
> This leads to state keeping confusion between firmware and driver,
> driver thinking that dc6 is off and proceeds with modesets
> while firmware still keeps/thinks dc6 is on. Evidence from logs
> suggests that the dc6 is still on as flips start to timeout,
> leading to eventual gpu hang.
>
> Further complication is that to recover the hang, we reset while
> the DC6 is enabled. With this state on the reinit of the gpu side
> won't come out clean and rings rehang right after the init.
>
> Harden the detection of this situation and immediately disable
> DC6 if we disagree on state with the firmware. This should make it
> less probable for driver to do end up in a wrong conclusion and
> let things like modeset and gpu reset proceed with dc6 still
> enabled.
>
> References: https://bugs.freedesktop.org/show_bug.cgi?id=93768
> Suggested-by: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Patrik Jakobsson <patrik.jakobsson at linux.intel.com>
> Cc: Imre Deak <imre.deak at intel.com>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Mika Kuoppala <mika.kuoppala at intel.com>
> ---
> drivers/gpu/drm/i915/intel_runtime_pm.c | 31 +++++++++++++++++++++++++++----
> 1 file changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index bbca527184d0..5a21453e38e1 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -470,9 +470,23 @@ static void gen9_set_dc_state_debugmask_memory_up(
> }
> }
>
> +static int gen9_dc_state_verified(struct drm_i915_private *dev_priv,
> + u32 mask, u32 state)
> +{
> + int i;
> +
> + /* Observe the dc state with handful of reads */
> + for (i = 0; i < 3; i++) {
> + if (wait_for((I915_READ(DC_STATE_EN) & mask) == state, 100))
> + return false;
> + }
Why two loops of reads?
Since this is equivalent to
return wait_for((I915_READ(DC_STATE_EN) & mask) == state, 300) == 0;
In this case
WRITE(DC_STATE_EN, val & ~mask | state);
if (wait_for((READ(DC_STATE_END) & mask) = state, 300) {
/* oh noes */
}
is more obvious (since we verify with a read of the same register, not
some magic ack sequence).
-Chris
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list