Commit 7c161b85 authored by Akeem G Abodunrin's avatar Akeem G Abodunrin Committed by Ramalingam C
Browse files

drm/i915/xehpsdv/dg1/tgl: Fix issue with LRI relative addressing



When bit 19 of MI_LOAD_REGISTER_IMM instruction opcode is set on tgl+
devices, HW does not care about certain register address offsets, but
instead check the following for valid address ranges on specific engines:
	RCS && CCS: BITS(0 - 10)
	BCS: BITS(0 - 11)
	VECS && VCS: BITS(0 - 13)
Also, tgl+ now support relative addressing for BCS engine - So, this
patch fixes issue with live_gt_lrc selftest that is failing where there is
mismatch between LRC register layout generated during init and HW
default register offsets.

Signed-off-by: default avatarAkeem G Abodunrin <akeem.g.abodunrin@intel.com>
cc: Prathap Kumar Valsan <prathap.kumar.valsan@intel.com>
Signed-off-by: default avatarRamalingam C <ramalingam.c@intel.com>
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220425152317.4275-2-ramalingam.c@intel.com
parent 59a47528
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -128,6 +128,27 @@ static int context_flush(struct intel_context *ce, long timeout)
	return err;
}

static int get_lri_mask(struct intel_engine_cs *engine, u32 lri)
{
	if ((lri & MI_LRI_LRM_CS_MMIO) == 0)
		return ~0u;

	if (GRAPHICS_VER(engine->i915) < 12)
		return 0xfff;

	switch (engine->class) {
	default:
	case RENDER_CLASS:
	case COMPUTE_CLASS:
		return 0x07ff;
	case COPY_ENGINE_CLASS:
		return 0x0fff;
	case VIDEO_DECODE_CLASS:
	case VIDEO_ENHANCEMENT_CLASS:
		return 0x3fff;
	}
}

static int live_lrc_layout(void *arg)
{
	struct intel_gt *gt = arg;
@@ -167,6 +188,7 @@ static int live_lrc_layout(void *arg)
		dw = 0;
		do {
			u32 lri = READ_ONCE(hw[dw]);
			u32 lri_mask;

			if (lri == 0) {
				dw++;
@@ -194,6 +216,18 @@ static int live_lrc_layout(void *arg)
				break;
			}

			/*
			 * When bit 19 of MI_LOAD_REGISTER_IMM instruction
			 * opcode is set on Gen12+ devices, HW does not
			 * care about certain register address offsets, and
			 * instead check the following for valid address
			 * ranges on specific engines:
			 * RCS && CCS: BITS(0 - 10)
			 * BCS: BITS(0 - 11)
			 * VECS && VCS: BITS(0 - 13)
			 */
			lri_mask = get_lri_mask(engine, lri);

			lri &= 0x7f;
			lri++;
			dw++;
@@ -201,7 +235,7 @@ static int live_lrc_layout(void *arg)
			while (lri) {
				u32 offset = READ_ONCE(hw[dw]);

				if (offset != lrc[dw]) {
				if ((offset ^ lrc[dw]) & lri_mask) {
					pr_err("%s: Different registers found at dword %d, expected %x, found %x\n",
					       engine->name, dw, offset, lrc[dw]);
					err = -EINVAL;