All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver.
@ 2026-07-30 16:30 Danayer
  0 siblings, 0 replies; 3+ messages in thread
From: Danayer @ 2026-07-30 16:30 UTC (permalink / raw)
  To: intel-gfx; +Cc: Seliverstov Daniil Denisovich

From: Seliverstov Daniil Denisovich <daniil.seliverstov2003@gmail.com>

* drm/xe: add DG2 HuC GSC support and MEI integration

Add DG2-specific GSC/MEI handling for Xe driver.

Changes include:
- add DG2 MEI GSC interface support
- add HuC firmware parsing for GSC BPDT/CPD layout
- improve HuC loading and authentication handling
- add GSC register definitions and firmware ABI updates
- add Xe MEI DG2 module support
- update Xe workarounds and engine handling for HuC/GSC
- update MEI GSC support for DG2

Signed-off-by: Seliverstov Daniil Denisovich <daniil.seliverstov2003@gmail.com>
---
 drivers/gpu/drm/xe/Makefile           |   1 +
 drivers/gpu/drm/xe/regs/xe_gsc_regs.h |   1 +
 drivers/gpu/drm/xe/xe_gsc.c           |   5 +-
 drivers/gpu/drm/xe/xe_heci_gsc.c      | 213 ++++++++++++++++----------
 drivers/gpu/drm/xe/xe_heci_gsc.h      |  12 +-
 drivers/gpu/drm/xe/xe_huc.c           |  65 ++++++++
 drivers/gpu/drm/xe/xe_huc_types.h     |   3 +
 drivers/gpu/drm/xe/xe_mei_dg2.c       | 121 +++++++++++++++
 drivers/gpu/drm/xe/xe_mei_dg2.h       |  14 ++
 drivers/gpu/drm/xe/xe_uc_fw.c         |  44 +++++-
 drivers/gpu/drm/xe/xe_wa.c            |   3 +-
 drivers/misc/mei/gsc-me.c             |   5 +
 12 files changed, 391 insertions(+), 96 deletions(-)
 create mode 100644 drivers/gpu/drm/xe/xe_mei_dg2.c
 create mode 100644 drivers/gpu/drm/xe/xe_mei_dg2.h

diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 6d728f8c4c392b..596669e2b55364 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -53,6 +53,7 @@ xe-y += xe_bb.o \
 	xe_gsc_debugfs.o \
 	xe_gsc_proxy.o \
 	xe_gsc_submit.o \
+	xe_mei_dg2.o \
 	xe_gt.o \
 	xe_gt_ccs_mode.o \
 	xe_gt_clock.o \
diff --git a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
index 180be82672ab59..6b7551bcfb7abc 100644
--- a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
@@ -20,6 +20,7 @@
 
 #define DG1_GSC_HECI2_BASE	0x00259000
 #define PVC_GSC_HECI2_BASE	0x00285000
+#define DG2_GSC_HECI1_BASE	0x00373000
 #define DG2_GSC_HECI2_BASE	0x00374000
 
 #define HECI_H_CSR(base)	XE_REG((base) + 0x4)
diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c
index aab59dc647fbd1..ef3647a57d4432 100644
--- a/drivers/gpu/drm/xe/xe_gsc.c
+++ b/drivers/gpu/drm/xe/xe_gsc.c
@@ -467,8 +467,11 @@ int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc)
 	if (!xe_uc_fw_is_available(&gsc->fw))
 		return 0;
 
-	if (!hwe)
+	if (!hwe) {
+		if (xe->info.platform == XE_DG2)
+			return 0;
 		return -ENODEV;
+	}
 
 	bo = xe_managed_bo_create_pin_map(xe, tile, SZ_4M,
 					  XE_BO_FLAG_STOLEN |
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.c b/drivers/gpu/drm/xe/xe_heci_gsc.c
index 5af8903e10af2e..69414e9510f2e0 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.c
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.c
@@ -15,8 +15,14 @@
 #include "regs/xe_gsc_regs.h"
 #include "xe_platform_types.h"
 #include "xe_survivability_mode.h"
+#include "xe_gt.h"
+#include "xe_gt_printk.h"
+#include "xe_mmio.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_force_wake.h"
 
-#define GSC_BAR_LENGTH  0x00000FFC
+#define GSC_BAR_LENGTH 0x00000FFC
 
 static void heci_gsc_irq_mask(struct irq_data *d)
 {
@@ -37,7 +43,8 @@ static const struct irq_chip heci_gsc_irq_chip = {
 static int heci_gsc_irq_init(int irq)
 {
 	irq_set_chip_and_handler_name(irq, &heci_gsc_irq_chip,
-				      handle_simple_irq, "heci_gsc_irq_handler");
+				      handle_simple_irq,
+				      "heci_gsc_irq_handler");
 
 	return irq_set_chip_data(irq, NULL);
 }
@@ -57,6 +64,7 @@ struct heci_gsc_def {
 	size_t bar_size;
 	bool use_polling;
 	bool slow_firmware;
+	size_t lmem_size;
 };
 
 /* gsc resources and definitions */
@@ -66,10 +74,19 @@ static const struct heci_gsc_def heci_gsc_def_dg1 = {
 	.bar_size = GSC_BAR_LENGTH,
 };
 
-static const struct heci_gsc_def heci_gsc_def_dg2 = {
-	.name = "mei-gscfi",
-	.bar = DG2_GSC_HECI2_BASE,
-	.bar_size = GSC_BAR_LENGTH,
+static const struct heci_gsc_def heci_gsc_def_dg2[] = {
+	{
+		.name = "mei-gsc",
+		.bar = DG2_GSC_HECI1_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+		.use_polling = true, /* Bypass broken HECI1 interrupts on DG2 */
+		.lmem_size = SZ_4M,
+	},
+	{
+		.name = "mei-gscfi",
+		.bar = DG2_GSC_HECI2_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+	}
 };
 
 static const struct heci_gsc_def heci_gsc_def_pvc = {
@@ -82,6 +99,7 @@ static const struct heci_gsc_def heci_gsc_def_pvc = {
 static void heci_gsc_release_dev(struct device *dev)
 {
 	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
+
 	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
 
 	kfree(adev);
@@ -90,51 +108,59 @@ static void heci_gsc_release_dev(struct device *dev)
 static void xe_heci_gsc_fini(void *arg)
 {
 	struct xe_heci_gsc *heci_gsc = arg;
-
-	if (heci_gsc->adev) {
-		struct auxiliary_device *aux_dev = &heci_gsc->adev->aux_dev;
-
-		auxiliary_device_delete(aux_dev);
-		auxiliary_device_uninit(aux_dev);
-		heci_gsc->adev = NULL;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (heci_gsc->adev[i]) {
+			struct auxiliary_device *aux_dev =
+				&heci_gsc->adev[i]->aux_dev;
+			auxiliary_device_delete(aux_dev);
+			auxiliary_device_uninit(aux_dev);
+			heci_gsc->adev[i] = NULL;
+		}
+		if (heci_gsc->irq[i] >= 0)
+			irq_free_desc(heci_gsc->irq[i]);
+		heci_gsc->irq[i] = -1;
+
+		if (heci_gsc->gem_obj[i]) {
+			xe_bo_unpin_map_no_vm(heci_gsc->gem_obj[i]);
+			heci_gsc->gem_obj[i] = NULL;
+		}
 	}
-
-	if (heci_gsc->irq >= 0)
-		irq_free_desc(heci_gsc->irq);
-
-	heci_gsc->irq = -1;
 }
 
 static int heci_gsc_irq_setup(struct xe_device *xe)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
-	int ret;
-
-	heci_gsc->irq = irq_alloc_desc(0);
-	if (heci_gsc->irq < 0) {
-		drm_err(&xe->drm, "gsc irq error %d\n", heci_gsc->irq);
-		return heci_gsc->irq;
+	int i, ret;
+
+	for (i = 0; i < 2; i++) {
+		heci_gsc->irq[i] = irq_alloc_desc(0);
+		if (heci_gsc->irq[i] < 0) {
+			drm_err(&xe->drm, "gsc irq error %d\n",
+				heci_gsc->irq[i]);
+			return heci_gsc->irq[i];
+		}
+		ret = heci_gsc_irq_init(heci_gsc->irq[i]);
+		if (ret < 0)
+			drm_err(&xe->drm, "gsc irq init failed %d\n", ret);
 	}
-
-	ret = heci_gsc_irq_init(heci_gsc->irq);
-	if (ret < 0)
-		drm_err(&xe->drm, "gsc irq init failed %d\n", ret);
-
-	return ret;
+	return 0;
 }
 
-static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *def)
+static int heci_gsc_add_device(struct xe_device *xe,
+			       const struct heci_gsc_def *def, int intf_id)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
 	struct auxiliary_device *aux_dev;
 	struct mei_aux_device *adev;
 	int ret;
-
 	adev = kzalloc_obj(*adev);
 	if (!adev)
 		return -ENOMEM;
-	adev->irq = heci_gsc->irq;
+
+	adev->irq = def->use_polling ? -1 : heci_gsc->irq[intf_id];
 	adev->bar.parent = &pdev->resource[0];
 	adev->bar.start = def->bar + pdev->resource[0].start;
 	adev->bar.end = adev->bar.start + def->bar_size - 1;
@@ -142,10 +168,35 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 	adev->bar.desc = IORES_DESC_NONE;
 	adev->slow_firmware = def->slow_firmware;
 
+	if (def->lmem_size) {
+		struct xe_tile *tile = xe_device_get_root_tile(xe);
+		struct xe_bo *bo;
+
+		bo = xe_bo_create_pin_map_novm(xe, tile, def->lmem_size,
+					       ttm_bo_type_kernel,
+					       XE_BO_FLAG_VRAM0, false);
+		if (!IS_ERR(bo)) {
+			xe_map_memset(xe, &bo->vmap, 0, 0, def->lmem_size);
+			heci_gsc->gem_obj[intf_id] = bo;
+			adev->ext_op_mem.start = xe_bo_main_addr(bo, PAGE_SIZE);
+			adev->ext_op_mem.end =
+				adev->ext_op_mem.start + def->lmem_size;
+			xe_gt_dbg(tile->primary_gt,
+				  "GSC HECI%d: VRAM at DPA 0x%llx\n",
+				  intf_id + 1,
+				  (unsigned long long)adev->ext_op_mem.start);
+		} else {
+			drm_warn(&xe->drm, "GSC HECI%d: Failed to alloc LMEM\n",
+				 intf_id + 1);
+		}
+	}
+
 	aux_dev = &adev->aux_dev;
 	aux_dev->name = def->name;
+	/* Add intf_id to ensure unique device IDs */
 	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
-		      PCI_DEVID(pdev->bus->number, pdev->devfn);
+		      PCI_DEVID(pdev->bus->number, pdev->devfn) |
+		      (intf_id << 8);
 	aux_dev->dev.parent = &pdev->dev;
 	aux_dev->dev.release = heci_gsc_release_dev;
 
@@ -156,13 +207,11 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 		return ret;
 	}
 
-	heci_gsc->adev = adev; /* needed by the notifier */
+	heci_gsc->adev[intf_id] = adev;
 	ret = auxiliary_device_add(aux_dev);
 	if (ret < 0) {
 		drm_err(&xe->drm, "gsc aux add failed %d\n", ret);
-		heci_gsc->adev = NULL;
-
-		/* adev will be freed with the put_device() and .release sequence */
+		heci_gsc->adev[intf_id] = NULL;
 		auxiliary_device_uninit(aux_dev);
 	}
 	return ret;
@@ -171,78 +220,74 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 int xe_heci_gsc_init(struct xe_device *xe)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
-	const struct heci_gsc_def *def = NULL;
 	int ret;
 
 	if (!xe->info.has_heci_gscfi && !xe->info.has_heci_cscfi)
 		return 0;
 
-	heci_gsc->irq = -1;
-
-	if (xe->info.platform == XE_BATTLEMAGE) {
-		def = &heci_gsc_def_dg2;
-	} else if (xe->info.platform == XE_PVC) {
-		def = &heci_gsc_def_pvc;
-	} else if (xe->info.platform == XE_DG2) {
-		def = &heci_gsc_def_dg2;
-	} else if (xe->info.platform == XE_DG1) {
-		def = &heci_gsc_def_dg1;
-	}
-
-	if (!def || !def->name) {
-		drm_warn(&xe->drm, "HECI is not implemented!\n");
-		return 0;
-	}
+	heci_gsc->irq[0] = -1;
+	heci_gsc->irq[1] = -1;
+	heci_gsc->gem_obj[0] = NULL;
+	heci_gsc->gem_obj[1] = NULL;
 
 	ret = devm_add_action_or_reset(xe->drm.dev, xe_heci_gsc_fini, heci_gsc);
 	if (ret)
 		return ret;
 
-	if (!def->use_polling && !xe_survivability_mode_is_boot_enabled(xe)) {
+	if (!xe_survivability_mode_is_boot_enabled(xe)) {
 		ret = heci_gsc_irq_setup(xe);
 		if (ret)
 			return ret;
 	}
 
-	return heci_gsc_add_device(xe, def);
-}
+	if (xe->info.platform == XE_DG2) {
+		struct xe_gt *gt = xe->tiles[0].primary_gt;
+		u32 val;
 
-void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
-{
-	int ret;
+		/* Wake up GSC to unmask HECI1 interrupts and clock gating */
+		if (xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC) == 0) {
+			val = xe_mmio_read32(&gt->mmio, XE_REG(0x1900f4));
+			val &= ~(BIT(15) | BIT(14));
+			xe_mmio_write32(&gt->mmio, XE_REG(0x1900f4), val);
 
-	if ((iir & GSC_IRQ_INTF(1)) == 0)
-		return;
+			val = xe_mmio_read32(&gt->mmio, XE_REG(0x190044));
+			val |= BIT(15) | BIT(14);
+			xe_mmio_write32(&gt->mmio, XE_REG(0x190044), val);
 
-	if (!xe->info.has_heci_gscfi) {
-		drm_warn_once(&xe->drm, "GSC irq: not supported");
-		return;
-	}
+			xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);
+		}
 
-	if (xe->heci_gsc.irq < 0)
-		return;
+		heci_gsc_add_device(xe, &heci_gsc_def_dg2[0], 0);
+		heci_gsc_add_device(xe, &heci_gsc_def_dg2[1], 1);
+		return 0;
+	} else if (xe->info.platform == XE_BATTLEMAGE) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_dg2[1], 1);
+	} else if (xe->info.platform == XE_PVC) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_pvc, 1);
+	} else if (xe->info.platform == XE_DG1) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_dg1, 1);
+	}
 
-	ret = generic_handle_irq_safe(xe->heci_gsc.irq);
-	if (ret)
-		drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+	return 0;
 }
 
-void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
+void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
 {
-	int ret;
-
-	if ((iir & CSC_IRQ_INTF(1)) == 0)
+	if (!xe->info.has_heci_gscfi)
 		return;
 
-	if (!xe->info.has_heci_cscfi) {
-		drm_warn_once(&xe->drm, "CSC irq: not supported");
-		return;
-	}
+	if ((iir & GSC_IRQ_INTF(0)) && xe->heci_gsc.irq[0] >= 0)
+		generic_handle_irq_safe(xe->heci_gsc.irq[0]);
+
+	if ((iir & GSC_IRQ_INTF(1)) && xe->heci_gsc.irq[1] >= 0)
+		generic_handle_irq_safe(xe->heci_gsc.irq[1]);
+}
 
-	if (xe->heci_gsc.irq < 0)
+void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
+{
+	if ((iir & CSC_IRQ_INTF(1)) == 0 || !xe->info.has_heci_cscfi ||
+	    xe->heci_gsc.irq[1] < 0)
 		return;
 
-	ret = generic_handle_irq_safe(xe->heci_gsc.irq);
-	if (ret)
-		drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+	generic_handle_irq_safe(xe->heci_gsc.irq[1]);
 }
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.h b/drivers/gpu/drm/xe/xe_heci_gsc.h
index a76f4122b7788a..80efc20922032b 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.h
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.h
@@ -9,6 +9,7 @@
 
 struct xe_device;
 struct mei_aux_device;
+struct xe_bo;
 
 /*
  * GSC HECI1 bit corresponds to bit15 and HECI2 to bit14.
@@ -24,13 +25,14 @@ struct mei_aux_device;
 /**
  * struct xe_heci_gsc - graphics security controller for xe, HECI interface
  *
- * @adev : pointer to mei auxiliary device structure
- * @irq : irq number
- *
+ * @adev: array of pointers to mei auxiliary device structures
+ * @irq: array of irq numbers
+ * @gem_obj: array of pointers to allocated VRAM memory objects
  */
 struct xe_heci_gsc {
-	struct mei_aux_device *adev;
-	int irq;
+	struct mei_aux_device *adev[2];
+	int irq[2];
+	struct xe_bo *gem_obj[2];
 };
 
 int xe_heci_gsc_init(struct xe_device *xe);
diff --git a/drivers/gpu/drm/xe/xe_huc.c b/drivers/gpu/drm/xe/xe_huc.c
index 57afe21444b183..fde982431ccaa2 100644
--- a/drivers/gpu/drm/xe/xe_huc.c
+++ b/drivers/gpu/drm/xe/xe_huc.c
@@ -12,6 +12,8 @@
 #include "abi/gsc_pxp_commands_abi.h"
 #include "regs/xe_gsc_regs.h"
 #include "regs/xe_guc_regs.h"
+#include "xe_pm.h"
+#include "xe_mei_dg2.h"
 #include "xe_bo.h"
 #include "xe_device.h"
 #include "xe_force_wake.h"
@@ -42,6 +44,8 @@ huc_to_guc(struct xe_huc *huc)
 	return &container_of(huc, struct xe_uc, huc)->guc;
 }
 
+static void xe_huc_auth_work(struct work_struct *work);
+
 #define PXP43_HUC_AUTH_INOUT_SIZE SZ_4K
 static int huc_alloc_gsc_pkt(struct xe_huc *huc)
 {
@@ -67,6 +71,7 @@ int xe_huc_init(struct xe_huc *huc)
 	struct xe_gt *gt = huc_to_gt(huc);
 	struct xe_device *xe = gt_to_xe(gt);
 	int ret;
+	INIT_DELAYED_WORK(&huc->auth_work, xe_huc_auth_work);
 
 	huc->fw.type = XE_UC_FW_TYPE_HUC;
 
@@ -228,6 +233,39 @@ static const struct {
 				  HECI1_FWSTS5_HUC_AUTH_DONE },
 };
 
+static void xe_huc_auth_work(struct work_struct *work)
+{
+	struct xe_huc *huc = container_of(work, struct xe_huc, auth_work.work);
+	struct xe_gt *gt = huc_to_gt(huc);
+	struct xe_device *xe = gt_to_xe(gt);
+	int ret;
+
+	xe_pm_runtime_get(xe);
+
+	ret = xe_mei_dg2_auth_huc(xe, huc);
+	if (ret == -EAGAIN || ret == -ENODEV) {
+		schedule_delayed_work(&huc->auth_work, msecs_to_jiffies(1000));
+		goto out;
+	}
+
+	if (ret)
+		goto fail;
+
+	ret = xe_mmio_wait32(&gt->mmio, huc_auth_modes[XE_HUC_AUTH_VIA_GUC].reg,
+			     huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		      huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		      100000, NULL, false);
+	if (ret)
+		goto fail;
+
+	xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_RUNNING);
+	goto out;
+fail:
+	xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_LOAD_FAIL);
+out:
+	xe_pm_runtime_put(xe);
+}
+
 bool xe_huc_is_authenticated(struct xe_huc *huc, enum xe_huc_auth_types type)
 {
 	struct xe_gt *gt = huc_to_gt(huc);
@@ -253,6 +291,33 @@ int xe_huc_auth(struct xe_huc *huc, enum xe_huc_auth_types type)
 	if (!xe_uc_fw_is_loaded(&huc->fw))
 		return -ENOEXEC;
 
+	if (huc_to_xe(huc)->info.platform == XE_DG2) {
+		ret = xe_mei_dg2_auth_huc(huc_to_xe(huc), huc);
+		if (ret == -EAGAIN || ret == -ENODEV) {
+			xe_gt_dbg(gt, "HuC: MEI not ready, deferring authentication\n");
+			schedule_delayed_work(&huc->auth_work, msecs_to_jiffies(1000));
+			return 0;
+		}
+
+		if (ret) {
+			xe_gt_err(gt, "HuC: failed to trigger auth via MEI: %pe\n", ERR_PTR(ret));
+			goto fail;
+		}
+
+		ret = xe_mmio_wait32(&gt->mmio, huc_auth_modes[XE_HUC_AUTH_VIA_GUC].reg,
+				     huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		       huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		       100000, NULL, false);
+		if (ret) {
+			xe_gt_err(gt, "HuC: firmware not verified by MEI: %pe\n", ERR_PTR(ret));
+			goto fail;
+		}
+
+		xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_RUNNING);
+		xe_gt_dbg(gt, "HuC: authenticated via MEI\n");
+		return 0;
+	}
+
 	switch (type) {
 	case XE_HUC_AUTH_VIA_GUC:
 		ret = xe_guc_auth_huc(guc, xe_bo_ggtt_addr(huc->fw.bo) +
diff --git a/drivers/gpu/drm/xe/xe_huc_types.h b/drivers/gpu/drm/xe/xe_huc_types.h
index cfbaa5e0dfcac6..0e97a4d087b578 100644
--- a/drivers/gpu/drm/xe/xe_huc_types.h
+++ b/drivers/gpu/drm/xe/xe_huc_types.h
@@ -19,6 +19,9 @@ struct xe_huc {
 
 	/** @gsc_pkt: bo to store the packet for auth via GSC */
 	struct xe_bo *gsc_pkt;
+
+	/** @auth_work: deferred authentication deferred work */
+	struct delayed_work auth_work;
 };
 
 #endif
diff --git a/drivers/gpu/drm/xe/xe_mei_dg2.c b/drivers/gpu/drm/xe/xe_mei_dg2.c
new file mode 100644
index 00000000000000..dee1646de83dfd
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mei_dg2.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2026 Intel Corporation. All rights reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/mei_cl_bus.h>
+#include <drm/drm_managed.h>
+#include <uapi/drm/xe_drm.h>
+
+#include "xe_mei_dg2.h"
+#include "xe_bo.h"
+#include "xe_device.h"
+#include "xe_gt.h"
+#include "xe_huc.h"
+
+#define PXP_APIVER(x, y) (((x) & 0xFFFF) << 16 | ((y) & 0xFFFF))
+#define PXP_STATUS_SUCCESS 0x0
+#define PXP_STATUS_OP_NOT_PERMITTED 0x1003
+
+struct pxp_cmd_header {
+	u32 api_version;
+	u32 command_id;
+	u32 status;
+	u32 buffer_len;
+} __packed;
+
+#define PXP43_CMDID_START_HUC_AUTH 0x0000003A
+
+struct pxp43_start_huc_auth_in {
+	struct pxp_cmd_header header;
+	__le64 huc_base_address;
+} __packed;
+
+struct pxp43_huc_auth_out {
+	struct pxp_cmd_header header;
+} __packed;
+
+static int match_pxp_client(struct device *dev, void *data)
+{
+	if (!dev->bus || !dev->bus->name || strcmp(dev->bus->name, "mei") != 0)
+		return 0;
+
+	if (strstr(dev_name(dev), "fbf6fcf1")) {
+		struct device **result = data;
+		*result = dev;
+		return 1;
+	}
+	return 0;
+}
+
+static int find_pxp_client_deep(struct device *dev, void *data)
+{
+	if (match_pxp_client(dev, data))
+		return 1;
+	return device_for_each_child(dev, data, find_pxp_client_deep);
+}
+
+int xe_mei_dg2_auth_huc(struct xe_device *xe, struct xe_huc *huc)
+{
+	struct device *cl_dev = NULL;
+	struct mei_cl_device *cldev;
+	struct pxp43_start_huc_auth_in in = { 0 };
+	struct pxp43_huc_auth_out out = { 0 };
+	ssize_t byte;
+	int ret;
+	static int retry_count;
+
+	device_for_each_child(xe->drm.dev, &cl_dev, find_pxp_client_deep);
+
+	if (!cl_dev) {
+		if (retry_count++ % 5 == 0)
+			drm_info(
+				&xe->drm,
+				"HuC auth: waiting for MEI PXP client (HECI1) to initialize...\n");
+		return -EAGAIN;
+	}
+
+	get_device(cl_dev);
+	cldev = to_mei_cl_device(cl_dev);
+
+	if (!mei_cldev_enabled(cldev)) {
+		ret = mei_cldev_enable(cldev);
+		if (ret) {
+			put_device(cl_dev);
+			return -EAGAIN;
+		}
+	}
+
+	in.header.api_version = PXP_APIVER(4, 3);
+	in.header.command_id = PXP43_CMDID_START_HUC_AUTH;
+	in.header.buffer_len = sizeof(in.huc_base_address);
+	in.huc_base_address =
+		cpu_to_le64(xe_bo_main_addr(huc->fw.bo, PAGE_SIZE));
+
+	byte = mei_cldev_send(cldev, (u8 *)&in, sizeof(in));
+	if (byte < 0) {
+		put_device(cl_dev);
+		return byte;
+	}
+
+	byte = mei_cldev_recv(cldev, (u8 *)&out, sizeof(out));
+	if (byte < 0) {
+		put_device(cl_dev);
+		return byte;
+	}
+
+	put_device(cl_dev);
+	if (out.header.status == PXP_STATUS_OP_NOT_PERMITTED) {
+		drm_info(
+			&xe->drm,
+			"HuC auth: GSC reports already authenticated (0x1003).\n");
+		return 0;
+	} else if (out.header.status != PXP_STATUS_SUCCESS) {
+		drm_err(&xe->drm, "HuC auth MEI rejected: status 0x%x\n",
+			out.header.status);
+		return -EIO;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/xe/xe_mei_dg2.h b/drivers/gpu/drm/xe/xe_mei_dg2.h
new file mode 100644
index 00000000000000..4a469fc7d8185c
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mei_dg2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2026 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __XE_MEI_DG2_H__
+#define __XE_MEI_DG2_H__
+
+#include "xe_device.h"
+#include "xe_huc.h"
+
+int xe_mei_dg2_auth_huc(struct xe_device *xe, struct xe_huc *huc);
+
+#endif /* __XE_MEI_DG2_H__ */
diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c
index a8e6f18cc9b4aa..edc8019bea9598 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.c
+++ b/drivers/gpu/drm/xe/xe_uc_fw.c
@@ -133,6 +133,7 @@ struct fw_blobs_by_type {
 	fw_def(BATTLEMAGE,	GT_TYPE_ANY,	no_ver(xe,	huc,		bmg))		\
 	fw_def(LUNARLAKE,	GT_TYPE_ANY,	no_ver(xe,	huc,		lnl))		\
 	fw_def(METEORLAKE,	GT_TYPE_ANY,	no_ver(i915,	huc_gsc,	mtl))		\
+	fw_def(DG2,		GT_TYPE_ANY,	no_ver(i915,	huc_gsc,	dg2))		\
 	fw_def(DG1,		GT_TYPE_ANY,	no_ver(i915,	huc,		dg1))		\
 	fw_def(ALDERLAKE_P,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
 	fw_def(ALDERLAKE_S,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
@@ -488,6 +489,26 @@ static u32 entry_offset(const struct gsc_cpd_header_v2 *header, const char *name
 	return 0;
 }
 
+static int parse_manifest_direct(struct xe_uc_fw *uc_fw, const void *data, size_t size)
+{
+	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
+	const struct gsc_manifest_header *manifest = data;
+	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
+
+	/* 0x4 is the expected header_type for a manifest */
+	if (size < sizeof(*manifest) || manifest->header_type != 0x4) {
+		xe_gt_err(gt, "Direct manifest too small or invalid!\n");
+		return -ENODATA;
+	}
+
+	release->major = manifest->fw_version.major;
+	release->minor = manifest->fw_version.minor;
+	release->patch = manifest->fw_version.hotfix;
+
+	uc_fw->has_gsc_headers = true;
+	return 0;
+}
+
 /* Refer to the "GSC-based Firmware Layout" documentation entry for details */
 static int parse_cpd_header(struct xe_uc_fw *uc_fw, const void *data, size_t size,
 			    const char *manifest_entry, const char *css_entry)
@@ -654,9 +675,20 @@ static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
 	case XE_UC_FW_TYPE_GSC:
 		return parse_gsc_layout(uc_fw, fw->data, fw->size);
 	case XE_UC_FW_TYPE_HUC:
-		ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
-		if (!ret || ret != -ENOENT)
-			return ret;
+		if (uc_fw_to_xe(uc_fw)->info.platform == XE_DG2) {
+			/* Check if binary starts directly with manifest */
+			if (fw->size >= sizeof(u32) && *(const u32 *)fw->data == 0x4)
+				return parse_manifest_direct(uc_fw, fw->data, fw->size);
+
+			/* DG2 HuC is loaded via MEI, so we don't need a CSS header (pass NULL) */
+			ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", NULL);
+			if (!ret || ret != -ENOENT)
+				return ret;
+		} else {
+			ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
+			if (!ret || ret != -ENOENT)
+				return ret;
+		}
 		fallthrough;
 	case XE_UC_FW_TYPE_GUC:
 		return parse_css_header(uc_fw, fw->data, fw->size);
@@ -780,12 +812,14 @@ static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmwar
 			       XE_UC_FIRMWARE_MISSING :
 			       XE_UC_FIRMWARE_ERROR);
 
-	if (err == -ENOENT)
+	if (err == -ENOENT) {
 		xe_gt_info(gt, "%s firmware %s not found\n",
 			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
-	else
+	} else {
 		xe_gt_notice(gt, "%s firmware %s: fetch failed with error %pe\n",
 			     xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, ERR_PTR(err));
+	}
+
 	xe_gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
 		   xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
 
diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
index 139434946f8f82..6ac486877e8d27 100644
--- a/drivers/gpu/drm/xe/xe_wa.c
+++ b/drivers/gpu/drm/xe/xe_wa.c
@@ -137,7 +137,8 @@ VISIBLE_IF_KUNIT const struct xe_rtp_table_sr gt_was = XE_RTP_TABLE_SR(
 	  XE_RTP_RULES(MEDIA_VERSION_RANGE(1200, 1255),
 		       ENGINE_CLASS(VIDEO_DECODE),
 		       FUNC(xe_rtp_match_even_instance)),
-	  XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), IECPUNIT_CLKGATE_DIS)),
+	  XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), IECPUNIT_CLKGATE_DIS,
+		       XE_RTP_ACTION_FLAG(ENGINE_BASE))),
 	  XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
 	},
 	{ XE_RTP_NAME("14011059788"),
diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index 73d5beeb9c3454..0741962a2e7934 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -278,6 +278,10 @@ static const struct auxiliary_device_id mei_gsc_id_table[] = {
 		.name = "xe.mei-gscfi",
 		.driver_data = MEI_ME_GSCFI_CFG,
 	},
+	{
+		.name = "xe.mei-gsc",
+		.driver_data = MEI_ME_GSC_CFG,
+	},
 	{
 		/* sentinel */
 	}
@@ -299,5 +303,6 @@ MODULE_AUTHOR("Intel Corporation");
 MODULE_ALIAS("auxiliary:i915.mei-gsc");
 MODULE_ALIAS("auxiliary:i915.mei-gscfi");
 MODULE_ALIAS("auxiliary:xe.mei-gscfi");
+MODULE_ALIAS("auxiliary:xe.mei-gsc");
 MODULE_DESCRIPTION("Intel(R) Graphics System Controller");
 MODULE_LICENSE("GPL");

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver.
@ 2026-07-30 16:43 Seliverstov Daniil Denisovich
  2026-08-01 12:34 ` kernel test robot
  0 siblings, 1 reply; 3+ messages in thread
From: Seliverstov Daniil Denisovich @ 2026-07-30 16:43 UTC (permalink / raw)
  To: intel-gfx; +Cc: Seliverstov Daniil Denisovich

* drm/xe: add DG2 HuC GSC support and MEI integration

Add DG2-specific GSC/MEI handling for Xe driver.

Changes include:
- add DG2 MEI GSC interface support
- add HuC firmware parsing for GSC BPDT/CPD layout
- improve HuC loading and authentication handling
- add GSC register definitions and firmware ABI updates
- add Xe MEI DG2 module support
- update Xe workarounds and engine handling for HuC/GSC
- update MEI GSC support for DG2

Signed-off-by: Seliverstov Daniil Denisovich <daniil.seliverstov2003@gmail.com>
---
 drivers/gpu/drm/xe/Makefile           |   1 +
 drivers/gpu/drm/xe/regs/xe_gsc_regs.h |   1 +
 drivers/gpu/drm/xe/xe_gsc.c           |   5 +-
 drivers/gpu/drm/xe/xe_heci_gsc.c      | 213 ++++++++++++++++----------
 drivers/gpu/drm/xe/xe_heci_gsc.h      |  12 +-
 drivers/gpu/drm/xe/xe_huc.c           |  65 ++++++++
 drivers/gpu/drm/xe/xe_huc_types.h     |   3 +
 drivers/gpu/drm/xe/xe_mei_dg2.c       | 121 +++++++++++++++
 drivers/gpu/drm/xe/xe_mei_dg2.h       |  14 ++
 drivers/gpu/drm/xe/xe_uc_fw.c         |  44 +++++-
 drivers/gpu/drm/xe/xe_wa.c            |   3 +-
 drivers/misc/mei/gsc-me.c             |   5 +
 12 files changed, 391 insertions(+), 96 deletions(-)
 create mode 100644 drivers/gpu/drm/xe/xe_mei_dg2.c
 create mode 100644 drivers/gpu/drm/xe/xe_mei_dg2.h

diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 6d728f8c4c392b..596669e2b55364 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -53,6 +53,7 @@ xe-y += xe_bb.o \
 	xe_gsc_debugfs.o \
 	xe_gsc_proxy.o \
 	xe_gsc_submit.o \
+	xe_mei_dg2.o \
 	xe_gt.o \
 	xe_gt_ccs_mode.o \
 	xe_gt_clock.o \
diff --git a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
index 180be82672ab59..6b7551bcfb7abc 100644
--- a/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_gsc_regs.h
@@ -20,6 +20,7 @@
 
 #define DG1_GSC_HECI2_BASE	0x00259000
 #define PVC_GSC_HECI2_BASE	0x00285000
+#define DG2_GSC_HECI1_BASE	0x00373000
 #define DG2_GSC_HECI2_BASE	0x00374000
 
 #define HECI_H_CSR(base)	XE_REG((base) + 0x4)
diff --git a/drivers/gpu/drm/xe/xe_gsc.c b/drivers/gpu/drm/xe/xe_gsc.c
index aab59dc647fbd1..ef3647a57d4432 100644
--- a/drivers/gpu/drm/xe/xe_gsc.c
+++ b/drivers/gpu/drm/xe/xe_gsc.c
@@ -467,8 +467,11 @@ int xe_gsc_init_post_hwconfig(struct xe_gsc *gsc)
 	if (!xe_uc_fw_is_available(&gsc->fw))
 		return 0;
 
-	if (!hwe)
+	if (!hwe) {
+		if (xe->info.platform == XE_DG2)
+			return 0;
 		return -ENODEV;
+	}
 
 	bo = xe_managed_bo_create_pin_map(xe, tile, SZ_4M,
 					  XE_BO_FLAG_STOLEN |
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.c b/drivers/gpu/drm/xe/xe_heci_gsc.c
index 5af8903e10af2e..69414e9510f2e0 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.c
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.c
@@ -15,8 +15,14 @@
 #include "regs/xe_gsc_regs.h"
 #include "xe_platform_types.h"
 #include "xe_survivability_mode.h"
+#include "xe_gt.h"
+#include "xe_gt_printk.h"
+#include "xe_mmio.h"
+#include "xe_bo.h"
+#include "xe_map.h"
+#include "xe_force_wake.h"
 
-#define GSC_BAR_LENGTH  0x00000FFC
+#define GSC_BAR_LENGTH 0x00000FFC
 
 static void heci_gsc_irq_mask(struct irq_data *d)
 {
@@ -37,7 +43,8 @@ static const struct irq_chip heci_gsc_irq_chip = {
 static int heci_gsc_irq_init(int irq)
 {
 	irq_set_chip_and_handler_name(irq, &heci_gsc_irq_chip,
-				      handle_simple_irq, "heci_gsc_irq_handler");
+				      handle_simple_irq,
+				      "heci_gsc_irq_handler");
 
 	return irq_set_chip_data(irq, NULL);
 }
@@ -57,6 +64,7 @@ struct heci_gsc_def {
 	size_t bar_size;
 	bool use_polling;
 	bool slow_firmware;
+	size_t lmem_size;
 };
 
 /* gsc resources and definitions */
@@ -66,10 +74,19 @@ static const struct heci_gsc_def heci_gsc_def_dg1 = {
 	.bar_size = GSC_BAR_LENGTH,
 };
 
-static const struct heci_gsc_def heci_gsc_def_dg2 = {
-	.name = "mei-gscfi",
-	.bar = DG2_GSC_HECI2_BASE,
-	.bar_size = GSC_BAR_LENGTH,
+static const struct heci_gsc_def heci_gsc_def_dg2[] = {
+	{
+		.name = "mei-gsc",
+		.bar = DG2_GSC_HECI1_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+		.use_polling = true, /* Bypass broken HECI1 interrupts on DG2 */
+		.lmem_size = SZ_4M,
+	},
+	{
+		.name = "mei-gscfi",
+		.bar = DG2_GSC_HECI2_BASE,
+		.bar_size = GSC_BAR_LENGTH,
+	}
 };
 
 static const struct heci_gsc_def heci_gsc_def_pvc = {
@@ -82,6 +99,7 @@ static const struct heci_gsc_def heci_gsc_def_pvc = {
 static void heci_gsc_release_dev(struct device *dev)
 {
 	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
+
 	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);
 
 	kfree(adev);
@@ -90,51 +108,59 @@ static void heci_gsc_release_dev(struct device *dev)
 static void xe_heci_gsc_fini(void *arg)
 {
 	struct xe_heci_gsc *heci_gsc = arg;
-
-	if (heci_gsc->adev) {
-		struct auxiliary_device *aux_dev = &heci_gsc->adev->aux_dev;
-
-		auxiliary_device_delete(aux_dev);
-		auxiliary_device_uninit(aux_dev);
-		heci_gsc->adev = NULL;
+	int i;
+
+	for (i = 0; i < 2; i++) {
+		if (heci_gsc->adev[i]) {
+			struct auxiliary_device *aux_dev =
+				&heci_gsc->adev[i]->aux_dev;
+			auxiliary_device_delete(aux_dev);
+			auxiliary_device_uninit(aux_dev);
+			heci_gsc->adev[i] = NULL;
+		}
+		if (heci_gsc->irq[i] >= 0)
+			irq_free_desc(heci_gsc->irq[i]);
+		heci_gsc->irq[i] = -1;
+
+		if (heci_gsc->gem_obj[i]) {
+			xe_bo_unpin_map_no_vm(heci_gsc->gem_obj[i]);
+			heci_gsc->gem_obj[i] = NULL;
+		}
 	}
-
-	if (heci_gsc->irq >= 0)
-		irq_free_desc(heci_gsc->irq);
-
-	heci_gsc->irq = -1;
 }
 
 static int heci_gsc_irq_setup(struct xe_device *xe)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
-	int ret;
-
-	heci_gsc->irq = irq_alloc_desc(0);
-	if (heci_gsc->irq < 0) {
-		drm_err(&xe->drm, "gsc irq error %d\n", heci_gsc->irq);
-		return heci_gsc->irq;
+	int i, ret;
+
+	for (i = 0; i < 2; i++) {
+		heci_gsc->irq[i] = irq_alloc_desc(0);
+		if (heci_gsc->irq[i] < 0) {
+			drm_err(&xe->drm, "gsc irq error %d\n",
+				heci_gsc->irq[i]);
+			return heci_gsc->irq[i];
+		}
+		ret = heci_gsc_irq_init(heci_gsc->irq[i]);
+		if (ret < 0)
+			drm_err(&xe->drm, "gsc irq init failed %d\n", ret);
 	}
-
-	ret = heci_gsc_irq_init(heci_gsc->irq);
-	if (ret < 0)
-		drm_err(&xe->drm, "gsc irq init failed %d\n", ret);
-
-	return ret;
+	return 0;
 }
 
-static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *def)
+static int heci_gsc_add_device(struct xe_device *xe,
+			       const struct heci_gsc_def *def, int intf_id)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
 	struct auxiliary_device *aux_dev;
 	struct mei_aux_device *adev;
 	int ret;
-
 	adev = kzalloc_obj(*adev);
 	if (!adev)
 		return -ENOMEM;
-	adev->irq = heci_gsc->irq;
+
+	adev->irq = def->use_polling ? -1 : heci_gsc->irq[intf_id];
 	adev->bar.parent = &pdev->resource[0];
 	adev->bar.start = def->bar + pdev->resource[0].start;
 	adev->bar.end = adev->bar.start + def->bar_size - 1;
@@ -142,10 +168,35 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 	adev->bar.desc = IORES_DESC_NONE;
 	adev->slow_firmware = def->slow_firmware;
 
+	if (def->lmem_size) {
+		struct xe_tile *tile = xe_device_get_root_tile(xe);
+		struct xe_bo *bo;
+
+		bo = xe_bo_create_pin_map_novm(xe, tile, def->lmem_size,
+					       ttm_bo_type_kernel,
+					       XE_BO_FLAG_VRAM0, false);
+		if (!IS_ERR(bo)) {
+			xe_map_memset(xe, &bo->vmap, 0, 0, def->lmem_size);
+			heci_gsc->gem_obj[intf_id] = bo;
+			adev->ext_op_mem.start = xe_bo_main_addr(bo, PAGE_SIZE);
+			adev->ext_op_mem.end =
+				adev->ext_op_mem.start + def->lmem_size;
+			xe_gt_dbg(tile->primary_gt,
+				  "GSC HECI%d: VRAM at DPA 0x%llx\n",
+				  intf_id + 1,
+				  (unsigned long long)adev->ext_op_mem.start);
+		} else {
+			drm_warn(&xe->drm, "GSC HECI%d: Failed to alloc LMEM\n",
+				 intf_id + 1);
+		}
+	}
+
 	aux_dev = &adev->aux_dev;
 	aux_dev->name = def->name;
+	/* Add intf_id to ensure unique device IDs */
 	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
-		      PCI_DEVID(pdev->bus->number, pdev->devfn);
+		      PCI_DEVID(pdev->bus->number, pdev->devfn) |
+		      (intf_id << 8);
 	aux_dev->dev.parent = &pdev->dev;
 	aux_dev->dev.release = heci_gsc_release_dev;
 
@@ -156,13 +207,11 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 		return ret;
 	}
 
-	heci_gsc->adev = adev; /* needed by the notifier */
+	heci_gsc->adev[intf_id] = adev;
 	ret = auxiliary_device_add(aux_dev);
 	if (ret < 0) {
 		drm_err(&xe->drm, "gsc aux add failed %d\n", ret);
-		heci_gsc->adev = NULL;
-
-		/* adev will be freed with the put_device() and .release sequence */
+		heci_gsc->adev[intf_id] = NULL;
 		auxiliary_device_uninit(aux_dev);
 	}
 	return ret;
@@ -171,78 +220,74 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def *
 int xe_heci_gsc_init(struct xe_device *xe)
 {
 	struct xe_heci_gsc *heci_gsc = &xe->heci_gsc;
-	const struct heci_gsc_def *def = NULL;
 	int ret;
 
 	if (!xe->info.has_heci_gscfi && !xe->info.has_heci_cscfi)
 		return 0;
 
-	heci_gsc->irq = -1;
-
-	if (xe->info.platform == XE_BATTLEMAGE) {
-		def = &heci_gsc_def_dg2;
-	} else if (xe->info.platform == XE_PVC) {
-		def = &heci_gsc_def_pvc;
-	} else if (xe->info.platform == XE_DG2) {
-		def = &heci_gsc_def_dg2;
-	} else if (xe->info.platform == XE_DG1) {
-		def = &heci_gsc_def_dg1;
-	}
-
-	if (!def || !def->name) {
-		drm_warn(&xe->drm, "HECI is not implemented!\n");
-		return 0;
-	}
+	heci_gsc->irq[0] = -1;
+	heci_gsc->irq[1] = -1;
+	heci_gsc->gem_obj[0] = NULL;
+	heci_gsc->gem_obj[1] = NULL;
 
 	ret = devm_add_action_or_reset(xe->drm.dev, xe_heci_gsc_fini, heci_gsc);
 	if (ret)
 		return ret;
 
-	if (!def->use_polling && !xe_survivability_mode_is_boot_enabled(xe)) {
+	if (!xe_survivability_mode_is_boot_enabled(xe)) {
 		ret = heci_gsc_irq_setup(xe);
 		if (ret)
 			return ret;
 	}
 
-	return heci_gsc_add_device(xe, def);
-}
+	if (xe->info.platform == XE_DG2) {
+		struct xe_gt *gt = xe->tiles[0].primary_gt;
+		u32 val;
 
-void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
-{
-	int ret;
+		/* Wake up GSC to unmask HECI1 interrupts and clock gating */
+		if (xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC) == 0) {
+			val = xe_mmio_read32(&gt->mmio, XE_REG(0x1900f4));
+			val &= ~(BIT(15) | BIT(14));
+			xe_mmio_write32(&gt->mmio, XE_REG(0x1900f4), val);
 
-	if ((iir & GSC_IRQ_INTF(1)) == 0)
-		return;
+			val = xe_mmio_read32(&gt->mmio, XE_REG(0x190044));
+			val |= BIT(15) | BIT(14);
+			xe_mmio_write32(&gt->mmio, XE_REG(0x190044), val);
 
-	if (!xe->info.has_heci_gscfi) {
-		drm_warn_once(&xe->drm, "GSC irq: not supported");
-		return;
-	}
+			xe_force_wake_put(gt_to_fw(gt), XE_FW_GSC);
+		}
 
-	if (xe->heci_gsc.irq < 0)
-		return;
+		heci_gsc_add_device(xe, &heci_gsc_def_dg2[0], 0);
+		heci_gsc_add_device(xe, &heci_gsc_def_dg2[1], 1);
+		return 0;
+	} else if (xe->info.platform == XE_BATTLEMAGE) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_dg2[1], 1);
+	} else if (xe->info.platform == XE_PVC) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_pvc, 1);
+	} else if (xe->info.platform == XE_DG1) {
+		return heci_gsc_add_device(xe, &heci_gsc_def_dg1, 1);
+	}
 
-	ret = generic_handle_irq_safe(xe->heci_gsc.irq);
-	if (ret)
-		drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+	return 0;
 }
 
-void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
+void xe_heci_gsc_irq_handler(struct xe_device *xe, u32 iir)
 {
-	int ret;
-
-	if ((iir & CSC_IRQ_INTF(1)) == 0)
+	if (!xe->info.has_heci_gscfi)
 		return;
 
-	if (!xe->info.has_heci_cscfi) {
-		drm_warn_once(&xe->drm, "CSC irq: not supported");
-		return;
-	}
+	if ((iir & GSC_IRQ_INTF(0)) && xe->heci_gsc.irq[0] >= 0)
+		generic_handle_irq_safe(xe->heci_gsc.irq[0]);
+
+	if ((iir & GSC_IRQ_INTF(1)) && xe->heci_gsc.irq[1] >= 0)
+		generic_handle_irq_safe(xe->heci_gsc.irq[1]);
+}
 
-	if (xe->heci_gsc.irq < 0)
+void xe_heci_csc_irq_handler(struct xe_device *xe, u32 iir)
+{
+	if ((iir & CSC_IRQ_INTF(1)) == 0 || !xe->info.has_heci_cscfi ||
+	    xe->heci_gsc.irq[1] < 0)
 		return;
 
-	ret = generic_handle_irq_safe(xe->heci_gsc.irq);
-	if (ret)
-		drm_err_ratelimited(&xe->drm, "error handling GSC irq: %d\n", ret);
+	generic_handle_irq_safe(xe->heci_gsc.irq[1]);
 }
diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.h b/drivers/gpu/drm/xe/xe_heci_gsc.h
index a76f4122b7788a..80efc20922032b 100644
--- a/drivers/gpu/drm/xe/xe_heci_gsc.h
+++ b/drivers/gpu/drm/xe/xe_heci_gsc.h
@@ -9,6 +9,7 @@
 
 struct xe_device;
 struct mei_aux_device;
+struct xe_bo;
 
 /*
  * GSC HECI1 bit corresponds to bit15 and HECI2 to bit14.
@@ -24,13 +25,14 @@ struct mei_aux_device;
 /**
  * struct xe_heci_gsc - graphics security controller for xe, HECI interface
  *
- * @adev : pointer to mei auxiliary device structure
- * @irq : irq number
- *
+ * @adev: array of pointers to mei auxiliary device structures
+ * @irq: array of irq numbers
+ * @gem_obj: array of pointers to allocated VRAM memory objects
  */
 struct xe_heci_gsc {
-	struct mei_aux_device *adev;
-	int irq;
+	struct mei_aux_device *adev[2];
+	int irq[2];
+	struct xe_bo *gem_obj[2];
 };
 
 int xe_heci_gsc_init(struct xe_device *xe);
diff --git a/drivers/gpu/drm/xe/xe_huc.c b/drivers/gpu/drm/xe/xe_huc.c
index 57afe21444b183..fde982431ccaa2 100644
--- a/drivers/gpu/drm/xe/xe_huc.c
+++ b/drivers/gpu/drm/xe/xe_huc.c
@@ -12,6 +12,8 @@
 #include "abi/gsc_pxp_commands_abi.h"
 #include "regs/xe_gsc_regs.h"
 #include "regs/xe_guc_regs.h"
+#include "xe_pm.h"
+#include "xe_mei_dg2.h"
 #include "xe_bo.h"
 #include "xe_device.h"
 #include "xe_force_wake.h"
@@ -42,6 +44,8 @@ huc_to_guc(struct xe_huc *huc)
 	return &container_of(huc, struct xe_uc, huc)->guc;
 }
 
+static void xe_huc_auth_work(struct work_struct *work);
+
 #define PXP43_HUC_AUTH_INOUT_SIZE SZ_4K
 static int huc_alloc_gsc_pkt(struct xe_huc *huc)
 {
@@ -67,6 +71,7 @@ int xe_huc_init(struct xe_huc *huc)
 	struct xe_gt *gt = huc_to_gt(huc);
 	struct xe_device *xe = gt_to_xe(gt);
 	int ret;
+	INIT_DELAYED_WORK(&huc->auth_work, xe_huc_auth_work);
 
 	huc->fw.type = XE_UC_FW_TYPE_HUC;
 
@@ -228,6 +233,39 @@ static const struct {
 				  HECI1_FWSTS5_HUC_AUTH_DONE },
 };
 
+static void xe_huc_auth_work(struct work_struct *work)
+{
+	struct xe_huc *huc = container_of(work, struct xe_huc, auth_work.work);
+	struct xe_gt *gt = huc_to_gt(huc);
+	struct xe_device *xe = gt_to_xe(gt);
+	int ret;
+
+	xe_pm_runtime_get(xe);
+
+	ret = xe_mei_dg2_auth_huc(xe, huc);
+	if (ret == -EAGAIN || ret == -ENODEV) {
+		schedule_delayed_work(&huc->auth_work, msecs_to_jiffies(1000));
+		goto out;
+	}
+
+	if (ret)
+		goto fail;
+
+	ret = xe_mmio_wait32(&gt->mmio, huc_auth_modes[XE_HUC_AUTH_VIA_GUC].reg,
+			     huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		      huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		      100000, NULL, false);
+	if (ret)
+		goto fail;
+
+	xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_RUNNING);
+	goto out;
+fail:
+	xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_LOAD_FAIL);
+out:
+	xe_pm_runtime_put(xe);
+}
+
 bool xe_huc_is_authenticated(struct xe_huc *huc, enum xe_huc_auth_types type)
 {
 	struct xe_gt *gt = huc_to_gt(huc);
@@ -253,6 +291,33 @@ int xe_huc_auth(struct xe_huc *huc, enum xe_huc_auth_types type)
 	if (!xe_uc_fw_is_loaded(&huc->fw))
 		return -ENOEXEC;
 
+	if (huc_to_xe(huc)->info.platform == XE_DG2) {
+		ret = xe_mei_dg2_auth_huc(huc_to_xe(huc), huc);
+		if (ret == -EAGAIN || ret == -ENODEV) {
+			xe_gt_dbg(gt, "HuC: MEI not ready, deferring authentication\n");
+			schedule_delayed_work(&huc->auth_work, msecs_to_jiffies(1000));
+			return 0;
+		}
+
+		if (ret) {
+			xe_gt_err(gt, "HuC: failed to trigger auth via MEI: %pe\n", ERR_PTR(ret));
+			goto fail;
+		}
+
+		ret = xe_mmio_wait32(&gt->mmio, huc_auth_modes[XE_HUC_AUTH_VIA_GUC].reg,
+				     huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		       huc_auth_modes[XE_HUC_AUTH_VIA_GUC].val,
+		       100000, NULL, false);
+		if (ret) {
+			xe_gt_err(gt, "HuC: firmware not verified by MEI: %pe\n", ERR_PTR(ret));
+			goto fail;
+		}
+
+		xe_uc_fw_change_status(&huc->fw, XE_UC_FIRMWARE_RUNNING);
+		xe_gt_dbg(gt, "HuC: authenticated via MEI\n");
+		return 0;
+	}
+
 	switch (type) {
 	case XE_HUC_AUTH_VIA_GUC:
 		ret = xe_guc_auth_huc(guc, xe_bo_ggtt_addr(huc->fw.bo) +
diff --git a/drivers/gpu/drm/xe/xe_huc_types.h b/drivers/gpu/drm/xe/xe_huc_types.h
index cfbaa5e0dfcac6..0e97a4d087b578 100644
--- a/drivers/gpu/drm/xe/xe_huc_types.h
+++ b/drivers/gpu/drm/xe/xe_huc_types.h
@@ -19,6 +19,9 @@ struct xe_huc {
 
 	/** @gsc_pkt: bo to store the packet for auth via GSC */
 	struct xe_bo *gsc_pkt;
+
+	/** @auth_work: deferred authentication deferred work */
+	struct delayed_work auth_work;
 };
 
 #endif
diff --git a/drivers/gpu/drm/xe/xe_mei_dg2.c b/drivers/gpu/drm/xe/xe_mei_dg2.c
new file mode 100644
index 00000000000000..dee1646de83dfd
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mei_dg2.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2026 Intel Corporation. All rights reserved.
+ */
+
+#include <linux/device.h>
+#include <linux/mei_cl_bus.h>
+#include <drm/drm_managed.h>
+#include <uapi/drm/xe_drm.h>
+
+#include "xe_mei_dg2.h"
+#include "xe_bo.h"
+#include "xe_device.h"
+#include "xe_gt.h"
+#include "xe_huc.h"
+
+#define PXP_APIVER(x, y) (((x) & 0xFFFF) << 16 | ((y) & 0xFFFF))
+#define PXP_STATUS_SUCCESS 0x0
+#define PXP_STATUS_OP_NOT_PERMITTED 0x1003
+
+struct pxp_cmd_header {
+	u32 api_version;
+	u32 command_id;
+	u32 status;
+	u32 buffer_len;
+} __packed;
+
+#define PXP43_CMDID_START_HUC_AUTH 0x0000003A
+
+struct pxp43_start_huc_auth_in {
+	struct pxp_cmd_header header;
+	__le64 huc_base_address;
+} __packed;
+
+struct pxp43_huc_auth_out {
+	struct pxp_cmd_header header;
+} __packed;
+
+static int match_pxp_client(struct device *dev, void *data)
+{
+	if (!dev->bus || !dev->bus->name || strcmp(dev->bus->name, "mei") != 0)
+		return 0;
+
+	if (strstr(dev_name(dev), "fbf6fcf1")) {
+		struct device **result = data;
+		*result = dev;
+		return 1;
+	}
+	return 0;
+}
+
+static int find_pxp_client_deep(struct device *dev, void *data)
+{
+	if (match_pxp_client(dev, data))
+		return 1;
+	return device_for_each_child(dev, data, find_pxp_client_deep);
+}
+
+int xe_mei_dg2_auth_huc(struct xe_device *xe, struct xe_huc *huc)
+{
+	struct device *cl_dev = NULL;
+	struct mei_cl_device *cldev;
+	struct pxp43_start_huc_auth_in in = { 0 };
+	struct pxp43_huc_auth_out out = { 0 };
+	ssize_t byte;
+	int ret;
+	static int retry_count;
+
+	device_for_each_child(xe->drm.dev, &cl_dev, find_pxp_client_deep);
+
+	if (!cl_dev) {
+		if (retry_count++ % 5 == 0)
+			drm_info(
+				&xe->drm,
+				"HuC auth: waiting for MEI PXP client (HECI1) to initialize...\n");
+		return -EAGAIN;
+	}
+
+	get_device(cl_dev);
+	cldev = to_mei_cl_device(cl_dev);
+
+	if (!mei_cldev_enabled(cldev)) {
+		ret = mei_cldev_enable(cldev);
+		if (ret) {
+			put_device(cl_dev);
+			return -EAGAIN;
+		}
+	}
+
+	in.header.api_version = PXP_APIVER(4, 3);
+	in.header.command_id = PXP43_CMDID_START_HUC_AUTH;
+	in.header.buffer_len = sizeof(in.huc_base_address);
+	in.huc_base_address =
+		cpu_to_le64(xe_bo_main_addr(huc->fw.bo, PAGE_SIZE));
+
+	byte = mei_cldev_send(cldev, (u8 *)&in, sizeof(in));
+	if (byte < 0) {
+		put_device(cl_dev);
+		return byte;
+	}
+
+	byte = mei_cldev_recv(cldev, (u8 *)&out, sizeof(out));
+	if (byte < 0) {
+		put_device(cl_dev);
+		return byte;
+	}
+
+	put_device(cl_dev);
+	if (out.header.status == PXP_STATUS_OP_NOT_PERMITTED) {
+		drm_info(
+			&xe->drm,
+			"HuC auth: GSC reports already authenticated (0x1003).\n");
+		return 0;
+	} else if (out.header.status != PXP_STATUS_SUCCESS) {
+		drm_err(&xe->drm, "HuC auth MEI rejected: status 0x%x\n",
+			out.header.status);
+		return -EIO;
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/xe/xe_mei_dg2.h b/drivers/gpu/drm/xe/xe_mei_dg2.h
new file mode 100644
index 00000000000000..4a469fc7d8185c
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mei_dg2.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2026 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __XE_MEI_DG2_H__
+#define __XE_MEI_DG2_H__
+
+#include "xe_device.h"
+#include "xe_huc.h"
+
+int xe_mei_dg2_auth_huc(struct xe_device *xe, struct xe_huc *huc);
+
+#endif /* __XE_MEI_DG2_H__ */
diff --git a/drivers/gpu/drm/xe/xe_uc_fw.c b/drivers/gpu/drm/xe/xe_uc_fw.c
index a8e6f18cc9b4aa..edc8019bea9598 100644
--- a/drivers/gpu/drm/xe/xe_uc_fw.c
+++ b/drivers/gpu/drm/xe/xe_uc_fw.c
@@ -133,6 +133,7 @@ struct fw_blobs_by_type {
 	fw_def(BATTLEMAGE,	GT_TYPE_ANY,	no_ver(xe,	huc,		bmg))		\
 	fw_def(LUNARLAKE,	GT_TYPE_ANY,	no_ver(xe,	huc,		lnl))		\
 	fw_def(METEORLAKE,	GT_TYPE_ANY,	no_ver(i915,	huc_gsc,	mtl))		\
+	fw_def(DG2,		GT_TYPE_ANY,	no_ver(i915,	huc_gsc,	dg2))		\
 	fw_def(DG1,		GT_TYPE_ANY,	no_ver(i915,	huc,		dg1))		\
 	fw_def(ALDERLAKE_P,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
 	fw_def(ALDERLAKE_S,	GT_TYPE_ANY,	no_ver(i915,	huc,		tgl))		\
@@ -488,6 +489,26 @@ static u32 entry_offset(const struct gsc_cpd_header_v2 *header, const char *name
 	return 0;
 }
 
+static int parse_manifest_direct(struct xe_uc_fw *uc_fw, const void *data, size_t size)
+{
+	struct xe_gt *gt = uc_fw_to_gt(uc_fw);
+	const struct gsc_manifest_header *manifest = data;
+	struct xe_uc_fw_version *release = &uc_fw->versions.found[XE_UC_FW_VER_RELEASE];
+
+	/* 0x4 is the expected header_type for a manifest */
+	if (size < sizeof(*manifest) || manifest->header_type != 0x4) {
+		xe_gt_err(gt, "Direct manifest too small or invalid!\n");
+		return -ENODATA;
+	}
+
+	release->major = manifest->fw_version.major;
+	release->minor = manifest->fw_version.minor;
+	release->patch = manifest->fw_version.hotfix;
+
+	uc_fw->has_gsc_headers = true;
+	return 0;
+}
+
 /* Refer to the "GSC-based Firmware Layout" documentation entry for details */
 static int parse_cpd_header(struct xe_uc_fw *uc_fw, const void *data, size_t size,
 			    const char *manifest_entry, const char *css_entry)
@@ -654,9 +675,20 @@ static int parse_headers(struct xe_uc_fw *uc_fw, const struct firmware *fw)
 	case XE_UC_FW_TYPE_GSC:
 		return parse_gsc_layout(uc_fw, fw->data, fw->size);
 	case XE_UC_FW_TYPE_HUC:
-		ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
-		if (!ret || ret != -ENOENT)
-			return ret;
+		if (uc_fw_to_xe(uc_fw)->info.platform == XE_DG2) {
+			/* Check if binary starts directly with manifest */
+			if (fw->size >= sizeof(u32) && *(const u32 *)fw->data == 0x4)
+				return parse_manifest_direct(uc_fw, fw->data, fw->size);
+
+			/* DG2 HuC is loaded via MEI, so we don't need a CSS header (pass NULL) */
+			ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", NULL);
+			if (!ret || ret != -ENOENT)
+				return ret;
+		} else {
+			ret = parse_cpd_header(uc_fw, fw->data, fw->size, "HUCP.man", "huc_fw");
+			if (!ret || ret != -ENOENT)
+				return ret;
+		}
 		fallthrough;
 	case XE_UC_FW_TYPE_GUC:
 		return parse_css_header(uc_fw, fw->data, fw->size);
@@ -780,12 +812,14 @@ static int uc_fw_request(struct xe_uc_fw *uc_fw, const struct firmware **firmwar
 			       XE_UC_FIRMWARE_MISSING :
 			       XE_UC_FIRMWARE_ERROR);
 
-	if (err == -ENOENT)
+	if (err == -ENOENT) {
 		xe_gt_info(gt, "%s firmware %s not found\n",
 			   xe_uc_fw_type_repr(uc_fw->type), uc_fw->path);
-	else
+	} else {
 		xe_gt_notice(gt, "%s firmware %s: fetch failed with error %pe\n",
 			     xe_uc_fw_type_repr(uc_fw->type), uc_fw->path, ERR_PTR(err));
+	}
+
 	xe_gt_info(gt, "%s firmware(s) can be downloaded from %s\n",
 		   xe_uc_fw_type_repr(uc_fw->type), XE_UC_FIRMWARE_URL);
 
diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c
index 139434946f8f82..6ac486877e8d27 100644
--- a/drivers/gpu/drm/xe/xe_wa.c
+++ b/drivers/gpu/drm/xe/xe_wa.c
@@ -137,7 +137,8 @@ VISIBLE_IF_KUNIT const struct xe_rtp_table_sr gt_was = XE_RTP_TABLE_SR(
 	  XE_RTP_RULES(MEDIA_VERSION_RANGE(1200, 1255),
 		       ENGINE_CLASS(VIDEO_DECODE),
 		       FUNC(xe_rtp_match_even_instance)),
-	  XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), IECPUNIT_CLKGATE_DIS)),
+	  XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), IECPUNIT_CLKGATE_DIS,
+		       XE_RTP_ACTION_FLAG(ENGINE_BASE))),
 	  XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
 	},
 	{ XE_RTP_NAME("14011059788"),
diff --git a/drivers/misc/mei/gsc-me.c b/drivers/misc/mei/gsc-me.c
index 73d5beeb9c3454..0741962a2e7934 100644
--- a/drivers/misc/mei/gsc-me.c
+++ b/drivers/misc/mei/gsc-me.c
@@ -278,6 +278,10 @@ static const struct auxiliary_device_id mei_gsc_id_table[] = {
 		.name = "xe.mei-gscfi",
 		.driver_data = MEI_ME_GSCFI_CFG,
 	},
+	{
+		.name = "xe.mei-gsc",
+		.driver_data = MEI_ME_GSC_CFG,
+	},
 	{
 		/* sentinel */
 	}
@@ -299,5 +303,6 @@ MODULE_AUTHOR("Intel Corporation");
 MODULE_ALIAS("auxiliary:i915.mei-gsc");
 MODULE_ALIAS("auxiliary:i915.mei-gscfi");
 MODULE_ALIAS("auxiliary:xe.mei-gscfi");
+MODULE_ALIAS("auxiliary:xe.mei-gsc");
 MODULE_DESCRIPTION("Intel(R) Graphics System Controller");
 MODULE_LICENSE("GPL");

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver.
  2026-07-30 16:43 [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver Seliverstov Daniil Denisovich
@ 2026-08-01 12:34 ` kernel test robot
  0 siblings, 0 replies; 3+ messages in thread
From: kernel test robot @ 2026-08-01 12:34 UTC (permalink / raw)
  To: Seliverstov Daniil Denisovich, intel-gfx
  Cc: llvm, oe-kbuild-all, Seliverstov Daniil Denisovich

Hi Seliverstov,

kernel test robot noticed the following build errors:

[auto build test ERROR on drm-xe/drm-xe-next]
[also build test ERROR on drm-tip/drm-tip char-misc/char-misc-testing char-misc/char-misc-next char-misc/char-misc-linus linus/master v7.2-rc5 next-20260731]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Seliverstov-Daniil-Denisovich/This-enables-HuC-firmware-initialization-and-authentication-on-DG2-hardware-when-using-the-Xe-DRM-driver/20260801-003327
base:   https://gitlab.freedesktop.org/drm/xe/kernel.git drm-xe-next
patch link:    https://lore.kernel.org/r/20260730164334.8424-1-daniil.seliverstov2003%40gmail.com
patch subject: [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver.
config: x86_64-buildonly-randconfig-005-20260801 (https://download.01.org/0day-ci/archive/20260801/202608012014.L7f9m7Nm-lkp@intel.com/config)
compiler: clang version 22.1.3 (https://github.com/llvm/llvm-project e9846648fd6183ee6d8cbdb4502213fcf902a211)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260801/202608012014.L7f9m7Nm-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608012014.L7f9m7Nm-lkp@intel.com/

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "mei_cldev_enabled" [drivers/gpu/drm/xe/xe.ko] undefined!
>> ERROR: modpost: "mei_cldev_enable" [drivers/gpu/drm/xe/xe.ko] undefined!
>> ERROR: modpost: "mei_cldev_send" [drivers/gpu/drm/xe/xe.ko] undefined!
>> ERROR: modpost: "mei_cldev_recv" [drivers/gpu/drm/xe/xe.ko] undefined!

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-08-01 12:35 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-30 16:43 [PATCH] This enables HuC firmware initialization and authentication on DG2 hardware when using the Xe DRM driver Seliverstov Daniil Denisovich
2026-08-01 12:34 ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2026-07-30 16:30 Danayer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.