Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ff047a87 authored by Oscar Mateo's avatar Oscar Mateo Committed by Chris Wilson
Browse files

drm/i915/icl: Correctly clear lost ctx-switch interrupts across reset for Gen11



Interrupt handling in Gen11 is quite different from previous platforms.

v2: Rebased (Michel)
v3: Rebased with wiggle
v4: Rebased, remove TODO warning correctly (Daniele)
v5: Rebased, made gen11_gtiir const while at it (Michel)
v6: Rebased
v7: Adapt to the style currently in upstream

Suggested-by: default avatarMichel Thierry <michel.thierry@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: default avatarMichel Thierry <michel.thierry@intel.com>
Signed-off-by: default avatarOscar Mateo <oscar.mateo@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: default avatarMichel Thierry <michel.thierry@intel.com>
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/1524605995-22324-1-git-send-email-oscar.mateo@intel.com
parent f6f10915
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ static u32
gen11_gt_engine_identity(struct drm_i915_private * const i915,
			 const unsigned int bank, const unsigned int bit);

static bool gen11_reset_one_iir(struct drm_i915_private * const i915,
bool gen11_reset_one_iir(struct drm_i915_private * const i915,
			 const unsigned int bank,
			 const unsigned int bit)
{
+3 −0
Original line number Diff line number Diff line
@@ -1333,6 +1333,9 @@ void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv);
void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv);

/* i915_irq.c */
bool gen11_reset_one_iir(struct drm_i915_private * const i915,
			 const unsigned int bank,
			 const unsigned int bit);
void gen5_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void gen5_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask);
void gen6_mask_pm_irq(struct drm_i915_private *dev_priv, u32 mask);
+42 −18
Original line number Diff line number Diff line
@@ -789,22 +789,9 @@ execlists_cancel_port_requests(struct intel_engine_execlists * const execlists)

static void clear_gtiir(struct intel_engine_cs *engine)
{
	static const u8 gtiir[] = {
		[RCS]  = 0,
		[BCS]  = 0,
		[VCS]  = 1,
		[VCS2] = 1,
		[VECS] = 3,
	};
	struct drm_i915_private *dev_priv = engine->i915;
	int i;

	/* TODO: correctly reset irqs for gen11 */
	if (WARN_ON_ONCE(INTEL_GEN(engine->i915) >= 11))
		return;

	GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));

	/*
	 * Clear any pending interrupt state.
	 *
@@ -812,6 +799,42 @@ static void clear_gtiir(struct intel_engine_cs *engine)
	 * double buffered, and so if we only reset it once there may
	 * still be an interrupt pending.
	 */
	if (INTEL_GEN(dev_priv) >= 11) {
		static const struct {
			u8 bank;
			u8 bit;
		} gen11_gtiir[] = {
			[RCS] = {0, GEN11_RCS0},
			[BCS] = {0, GEN11_BCS},
			[_VCS(0)] = {1, GEN11_VCS(0)},
			[_VCS(1)] = {1, GEN11_VCS(1)},
			[_VCS(2)] = {1, GEN11_VCS(2)},
			[_VCS(3)] = {1, GEN11_VCS(3)},
			[_VECS(0)] = {1, GEN11_VECS(0)},
			[_VECS(1)] = {1, GEN11_VECS(1)},
		};
		unsigned long irqflags;

		GEM_BUG_ON(engine->id >= ARRAY_SIZE(gen11_gtiir));

		spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
		for (i = 0; i < 2; i++) {
			gen11_reset_one_iir(dev_priv,
					    gen11_gtiir[engine->id].bank,
					    gen11_gtiir[engine->id].bit);
		}
		spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
	} else {
		static const u8 gtiir[] = {
			[RCS]  = 0,
			[BCS]  = 0,
			[VCS]  = 1,
			[VCS2] = 1,
			[VECS] = 3,
		};

		GEM_BUG_ON(engine->id >= ARRAY_SIZE(gtiir));

		for (i = 0; i < 2; i++) {
			I915_WRITE(GEN8_GT_IIR(gtiir[engine->id]),
				   engine->irq_keep_mask);
@@ -820,6 +843,7 @@ static void clear_gtiir(struct intel_engine_cs *engine)
		GEM_BUG_ON(I915_READ(GEN8_GT_IIR(gtiir[engine->id])) &
			   engine->irq_keep_mask);
	}
}

static void reset_irq(struct intel_engine_cs *engine)
{