Commit af42cf30 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-xe-next-2025-07-15' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-next



Driver Changes:
 - Create and use XE_DEVICE_WA infrastructure (Atwood)
 - SRIOV: Mark BMG as SR-IOV capable (Michal)
 - Dont skip TLB invalidations on VF (Tejas)
 - Fix migration copy direction in access_memory (Auld)
 - General code clean-up (Lucas, Brost, Dr. David, Xin)
 - More missing XeLP workarounds (Tvrtko)
 - SRIOV: Relax VF/PF version negotiation (Michal)
 - SRIOV: LMTT invalidation (Michal)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://lore.kernel.org/r/aHacDvF9IaVHI61C@intel.com
parents 7e11e01d a8164876
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -21,6 +21,13 @@ $(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \
		 $(src)/xe_wa_oob.rules
	$(call cmd,wa_oob)

generated_device_oob := $(obj)/generated/xe_device_wa_oob.c $(obj)/generated/xe_device_wa_oob.h
quiet_cmd_device_wa_oob = GEN	$(notdir $(generated_device_oob))
      cmd_device_wa_oob = mkdir -p $(@D); $^ $(generated_device_oob)
$(obj)/generated/%_device_wa_oob.c $(obj)/generated/%_device_wa_oob.h: $(obj)/xe_gen_wa_oob \
		 $(src)/xe_device_wa_oob.rules
	$(call cmd,device_wa_oob)

# Please keep these build lists sorted!

# core driver code
@@ -156,7 +163,8 @@ xe-$(CONFIG_PCI_IOV) += \
	xe_lmtt_2l.o \
	xe_lmtt_ml.o \
	xe_pci_sriov.o \
	xe_sriov_pf.o
	xe_sriov_pf.o \
	xe_sriov_pf_service.o

# include helpers for tests even when XE is built-in
ifdef CONFIG_DRM_XE_KUNIT_TEST
@@ -341,4 +349,4 @@ $(obj)/%.hdrtest: $(src)/%.h FORCE
	$(call if_changed_dep,hdrtest)

uses_generated_oob := $(addprefix $(obj)/, $(xe-y))
$(uses_generated_oob): $(obj)/generated/xe_wa_oob.h
$(uses_generated_oob): $(obj)/generated/xe_wa_oob.h $(obj)/generated/xe_device_wa_oob.h
+7 −0
Original line number Diff line number Diff line
@@ -12,9 +12,13 @@
#define CTX_RING_START			(0x08 + 1)
#define CTX_RING_CTL			(0x0a + 1)
#define CTX_BB_PER_CTX_PTR		(0x12 + 1)
#define CTX_CS_INDIRECT_CTX		(0x14 + 1)
#define CTX_CS_INDIRECT_CTX_OFFSET	(0x16 + 1)
#define CTX_TIMESTAMP			(0x22 + 1)
#define CTX_TIMESTAMP_UDW		(0x24 + 1)
#define CTX_INDIRECT_RING_STATE		(0x26 + 1)
#define CTX_ACC_CTR_THOLD		(0x2a + 1)
#define CTX_ASID			(0x2e + 1)
#define CTX_PDP0_UDW			(0x30 + 1)
#define CTX_PDP0_LDW			(0x32 + 1)

@@ -36,4 +40,7 @@
#define INDIRECT_CTX_RING_START_UDW	(0x08 + 1)
#define INDIRECT_CTX_RING_CTL		(0x0a + 1)

#define CTX_INDIRECT_CTX_OFFSET_MASK	REG_GENMASK(15, 6)
#define CTX_INDIRECT_CTX_OFFSET_DEFAULT	REG_FIELD_PREP(CTX_INDIRECT_CTX_OFFSET_MASK, 0xd)

#endif
+227 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0 AND MIT
/*
 * Copyright © 2024 Intel Corporation
 * Copyright © 2024-2025 Intel Corporation
 */

#include <kunit/test.h>
@@ -17,7 +17,6 @@ static int pf_service_test_init(struct kunit *test)
		.subplatform = XE_SUBPLATFORM_NONE,
	};
	struct xe_device *xe;
	struct xe_gt *gt;

	test->priv = &fake;
	xe_kunit_helper_xe_device_test_init(test);
@@ -25,187 +24,183 @@ static int pf_service_test_init(struct kunit *test)
	xe = test->priv;
	KUNIT_ASSERT_EQ(test, xe_sriov_init(xe), 0);

	gt = xe_device_get_gt(xe, 0);
	pf_init_versions(gt);

	xe_sriov_pf_service_init(xe);
	/*
	 * sanity check:
	 * - all supported platforms VF/PF ABI versions must be defined
	 * - base version can't be newer than latest
	 */
	KUNIT_ASSERT_NE(test, 0, gt->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_NE(test, 0, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_LE(test, gt->sriov.pf.service.version.base.major,
			gt->sriov.pf.service.version.latest.major);
	if (gt->sriov.pf.service.version.base.major == gt->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, gt->sriov.pf.service.version.base.minor,
				gt->sriov.pf.service.version.latest.minor);

	test->priv = gt;
	KUNIT_ASSERT_NE(test, 0, xe->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_NE(test, 0, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_LE(test, xe->sriov.pf.service.version.base.major,
			xe->sriov.pf.service.version.latest.major);
	if (xe->sriov.pf.service.version.base.major == xe->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, xe->sriov.pf.service.version.base.minor,
				xe->sriov.pf.service.version.latest.minor);
	return 0;
}

static void pf_negotiate_any(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt, VF2PF_HANDSHAKE_MAJOR_ANY,
			pf_negotiate_version(xe, VF2PF_HANDSHAKE_MAJOR_ANY,
					     VF2PF_HANDSHAKE_MINOR_ANY,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.latest.minor);
}

static void pf_negotiate_base_match(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.base.major,
					     gt->sriov.pf.service.version.base.minor,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.base.major,
					     xe->sriov.pf.service.version.base.minor,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.base.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.base.minor);
}

static void pf_negotiate_base_newer(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.base.major,
					     gt->sriov.pf.service.version.base.minor + 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.base.major,
					     xe->sriov.pf.service.version.base.minor + 1,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_GE(test, minor, gt->sriov.pf.service.version.base.minor);
	if (gt->sriov.pf.service.version.base.major == gt->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_GE(test, minor, xe->sriov.pf.service.version.base.minor);
	if (xe->sriov.pf.service.version.base.major == xe->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, minor, xe->sriov.pf.service.version.latest.minor);
	else
		KUNIT_FAIL(test, "FIXME: don't know how to test multi-version yet!\n");
}

static void pf_negotiate_base_next(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.base.major + 1, 0,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.base.major + 1, 0,
					     &major, &minor));
	KUNIT_ASSERT_GE(test, major, gt->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_LE(test, major, gt->sriov.pf.service.version.latest.major);
	if (major == gt->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_GE(test, major, xe->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_LE(test, major, xe->sriov.pf.service.version.latest.major);
	if (major == xe->sriov.pf.service.version.latest.major)
		KUNIT_ASSERT_LE(test, minor, xe->sriov.pf.service.version.latest.minor);
	else
		KUNIT_FAIL(test, "FIXME: don't know how to test multi-version yet!\n");
}

static void pf_negotiate_base_older(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	if (!gt->sriov.pf.service.version.base.minor)
	if (!xe->sriov.pf.service.version.base.minor)
		kunit_skip(test, "no older minor\n");

	KUNIT_ASSERT_NE(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.base.major,
					     gt->sriov.pf.service.version.base.minor - 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.base.major,
					     xe->sriov.pf.service.version.base.minor - 1,
					     &major, &minor));
}

static void pf_negotiate_base_prev(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_NE(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.base.major - 1, 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.base.major - 1, 1,
					     &major, &minor));
}

static void pf_negotiate_latest_match(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.latest.major,
					     gt->sriov.pf.service.version.latest.minor,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.latest.major,
					     xe->sriov.pf.service.version.latest.minor,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.latest.minor);
}

static void pf_negotiate_latest_newer(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.latest.major,
					     gt->sriov.pf.service.version.latest.minor + 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.latest.major,
					     xe->sriov.pf.service.version.latest.minor + 1,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.latest.minor);
}

static void pf_negotiate_latest_next(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.latest.major + 1, 0,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.latest.major + 1, 0,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.latest.minor);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.latest.minor);
}

static void pf_negotiate_latest_older(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	if (!gt->sriov.pf.service.version.latest.minor)
	if (!xe->sriov.pf.service.version.latest.minor)
		kunit_skip(test, "no older minor\n");

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.latest.major,
					     gt->sriov.pf.service.version.latest.minor - 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.latest.major,
					     xe->sriov.pf.service.version.latest.minor - 1,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, gt->sriov.pf.service.version.latest.minor - 1);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major);
	KUNIT_ASSERT_EQ(test, minor, xe->sriov.pf.service.version.latest.minor - 1);
}

static void pf_negotiate_latest_prev(struct kunit *test)
{
	struct xe_gt *gt = test->priv;
	struct xe_device *xe = test->priv;
	u32 major, minor;

	if (gt->sriov.pf.service.version.base.major == gt->sriov.pf.service.version.latest.major)
	if (xe->sriov.pf.service.version.base.major == xe->sriov.pf.service.version.latest.major)
		kunit_skip(test, "no prev major");

	KUNIT_ASSERT_EQ(test, 0,
			pf_negotiate_version(gt,
					     gt->sriov.pf.service.version.latest.major - 1,
					     gt->sriov.pf.service.version.base.minor + 1,
			pf_negotiate_version(xe,
					     xe->sriov.pf.service.version.latest.major - 1,
					     xe->sriov.pf.service.version.base.minor + 1,
					     &major, &minor));
	KUNIT_ASSERT_EQ(test, major, gt->sriov.pf.service.version.latest.major - 1);
	KUNIT_ASSERT_GE(test, major, gt->sriov.pf.service.version.base.major);
	KUNIT_ASSERT_EQ(test, major, xe->sriov.pf.service.version.latest.major - 1);
	KUNIT_ASSERT_GE(test, major, xe->sriov.pf.service.version.base.major);
}

static struct kunit_case pf_service_test_cases[] = {
+1 −1
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@ static int bb_prefetch(struct xe_gt *gt)
{
	struct xe_device *xe = gt_to_xe(gt);

	if (GRAPHICS_VERx100(xe) >= 1250 && !xe_gt_is_media_type(gt))
	if (GRAPHICS_VERx100(xe) >= 1250 && xe_gt_is_main_type(gt))
		/*
		 * RCS and CCS require 1K, although other engines would be
		 * okay with 512.
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct xe_gt;
struct xe_exec_queue;
struct xe_sched_job;

struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 size, bool usm);
struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm);
struct xe_sched_job *xe_bb_create_job(struct xe_exec_queue *q,
				      struct xe_bb *bb);
struct xe_sched_job *xe_bb_create_migration_job(struct xe_exec_queue *q,
Loading