Commit 7f34e01f authored by Karol Wachowski's avatar Karol Wachowski Committed by Stanislaw Gruszka
Browse files

accel/ivpu: Clear specific interrupt status bits on C0



MTL C0 stepping fixed issue related to butrress interrupt status clearing,
to clear an interrupt status it is required to write 1 to specific
status bit field. This allows to execute read, modify and write routine.

Writing 0 will not clear the interrupt and will cause interrupt storm.

Fixes: 35b13763 ("accel/ivpu: Introduce a new DRM driver for Intel VPU")
Cc: stable@vger.kernel.org # 6.3.x
Signed-off-by: default avatarKarol Wachowski <karol.wachowski@linux.intel.com>
Reviewed-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Signed-off-by: default avatarStanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230703080725.2065635-2-stanislaw.gruszka@linux.intel.com
parent 020b527b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -75,6 +75,7 @@ struct ivpu_wa_table {
	bool punit_disabled;
	bool clear_runtime_mem;
	bool d3hot_after_power_off;
	bool interrupt_clear_with_0;
};

struct ivpu_hw_info;
+12 −6
Original line number Diff line number Diff line
@@ -101,6 +101,9 @@ static void ivpu_hw_wa_init(struct ivpu_device *vdev)
	vdev->wa.punit_disabled = ivpu_is_fpga(vdev);
	vdev->wa.clear_runtime_mem = false;
	vdev->wa.d3hot_after_power_off = true;

	if (ivpu_device_id(vdev) == PCI_DEVICE_ID_MTL && ivpu_revision(vdev) < 4)
		vdev->wa.interrupt_clear_with_0 = true;
}

static void ivpu_hw_timeouts_init(struct ivpu_device *vdev)
@@ -973,12 +976,15 @@ static u32 ivpu_hw_mtl_irqb_handler(struct ivpu_device *vdev, int irq)
		schedule_recovery = true;
	}

	/* This must be done after interrupts are cleared at the source. */
	if (IVPU_WA(interrupt_clear_with_0))
		/*
	 * Clear local interrupt status by writing 0 to all bits.
	 * This must be done after interrupts are cleared at the source.
		 * Writing 1 triggers an interrupt, so we can't perform read update write.
		 * Clear local interrupt status by writing 0 to all bits.
		 */
		REGB_WR32(MTL_BUTTRESS_INTERRUPT_STAT, 0x0);
	else
		REGB_WR32(MTL_BUTTRESS_INTERRUPT_STAT, status);

	/* Re-enable global interrupt */
	REGB_WR32(MTL_BUTTRESS_GLOBAL_INT_MASK, 0x0);