All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Update to GuC version 69.0.0
@ 2021-12-03 18:33 ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: John Harrison, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

Update to the latest GuC version. This includes a suite of interface
changes and new features with corresponding i915 side changes.

Also, fix/improve a bunch of other things while at it.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>



John Harrison (5):
  drm/i915/uc: Allow platforms to have GuC but not HuC
  drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
  drm/i915/guc: Don't go bang in GuC log if no GuC
  drm/i915/guc: Update to GuC version 69.0.0
  drm/i915/guc: Improve GuC loading status check/error reports

 Documentation/gpu/i915.rst                    |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  23 +++
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     |  17 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   8 +-
 .../drm/i915/gt/uc/intel_guc_log_debugfs.c    |   4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |   4 -
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c        |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c         |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  93 ++++++++----
 18 files changed, 536 insertions(+), 210 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h

-- 
2.25.1


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

* [Intel-gfx] [PATCH 0/5] Update to GuC version 69.0.0
@ 2021-12-03 18:33 ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

Update to the latest GuC version. This includes a suite of interface
changes and new features with corresponding i915 side changes.

Also, fix/improve a bunch of other things while at it.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>



John Harrison (5):
  drm/i915/uc: Allow platforms to have GuC but not HuC
  drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
  drm/i915/guc: Don't go bang in GuC log if no GuC
  drm/i915/guc: Update to GuC version 69.0.0
  drm/i915/guc: Improve GuC loading status check/error reports

 Documentation/gpu/i915.rst                    |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  23 +++
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     |  17 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   8 +-
 .../drm/i915/gt/uc/intel_guc_log_debugfs.c    |   4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |   4 -
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
 drivers/gpu/drm/i915/gt/uc/intel_huc.c        |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c         |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  93 ++++++++----
 18 files changed, 536 insertions(+), 210 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h

-- 
2.25.1


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

* [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 18:33   ` John.C.Harrison
  -1 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: John Harrison, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

It is possible for platforms to require GuC but not HuC firmware.
Also, the firmware versions for GuC and HuC advance independently. So
split the macros up to allow the lists to be maintained separately.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 93 ++++++++++++++++--------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 3aa87be4f2e4..a7788ce50736 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -48,22 +48,39 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
  * firmware as TGL.
  */
-#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
-	fw_def(ALDERLAKE_P, 0, guc_def(adlp, 62, 0, 3), huc_def(tgl, 7, 9, 3)) \
-	fw_def(ALDERLAKE_S, 0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(DG1,         0, guc_def(dg1, 62, 0, 0), huc_def(dg1,  7, 9, 3)) \
-	fw_def(ROCKETLAKE,  0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(TIGERLAKE,   0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(JASPERLAKE,  0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
-	fw_def(ELKHARTLAKE, 0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
-	fw_def(ICELAKE,     0, guc_def(icl, 62, 0, 0), huc_def(icl,  9, 0, 0)) \
-	fw_def(COMETLAKE,   5, guc_def(cml, 62, 0, 0), huc_def(cml,  4, 0, 0)) \
-	fw_def(COMETLAKE,   0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(COFFEELAKE,  0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(GEMINILAKE,  0, guc_def(glk, 62, 0, 0), huc_def(glk,  4, 0, 0)) \
-	fw_def(KABYLAKE,    0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(BROXTON,     0, guc_def(bxt, 62, 0, 0), huc_def(bxt,  2, 0, 0)) \
-	fw_def(SKYLAKE,     0, guc_def(skl, 62, 0, 0), huc_def(skl,  2, 0, 0))
+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
+
+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))
 
 #define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
 	"i915/" \
@@ -79,11 +96,11 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 	__MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
 
 /* All blobs need to be declared via MODULE_FIRMWARE() */
-#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
-	MODULE_FIRMWARE(guc_); \
-	MODULE_FIRMWARE(huc_);
+#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
+	MODULE_FIRMWARE(uc_);
 
-INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
+INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH)
+INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH)
 
 /* The below structs and macros are used to iterate across the list of blobs */
 struct __packed uc_fw_blob {
@@ -106,31 +123,47 @@ struct __packed uc_fw_blob {
 struct __packed uc_fw_platform_requirement {
 	enum intel_platform p;
 	u8 rev; /* first platform rev using this FW */
-	const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
+	const struct uc_fw_blob blob;
 };
 
-#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
+#define MAKE_FW_LIST(platform_, revid_, uc_) \
 { \
 	.p = INTEL_##platform_, \
 	.rev = revid_, \
-	.blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
-	.blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
+	.blob = uc_, \
 },
 
+struct fw_blobs_by_type {
+	const struct uc_fw_platform_requirement *blobs;
+	u32 count;
+};
+
 static void
 __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 {
-	static const struct uc_fw_platform_requirement fw_blobs[] = {
-		INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
+	static const struct uc_fw_platform_requirement blobs_guc[] = {
+		INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
+	};
+	static const struct uc_fw_platform_requirement blobs_huc[] = {
+		INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB)
 	};
+	static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
+		[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+		[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+	};
+	static const struct uc_fw_platform_requirement *fw_blobs;
 	enum intel_platform p = INTEL_INFO(i915)->platform;
+	u32 fw_count;
 	u8 rev = INTEL_REVID(i915);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
+	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
+	fw_blobs = blobs_all[uc_fw->type].blobs;
+	fw_count = blobs_all[uc_fw->type].count;
+
+	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
 		if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
-			const struct uc_fw_blob *blob =
-					&fw_blobs[i].blobs[uc_fw->type];
+			const struct uc_fw_blob *blob = &fw_blobs[i].blob;
 			uc_fw->path = blob->path;
 			uc_fw->major_ver_wanted = blob->major;
 			uc_fw->minor_ver_wanted = blob->minor;
@@ -140,7 +173,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 
 	/* make sure the list is ordered as expected */
 	if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
-		for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
+		for (i = 1; i < fw_count; i++) {
 			if (fw_blobs[i].p < fw_blobs[i - 1].p)
 				continue;
 
-- 
2.25.1


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

* [Intel-gfx] [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC
@ 2021-12-03 18:33   ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

It is possible for platforms to require GuC but not HuC firmware.
Also, the firmware versions for GuC and HuC advance independently. So
split the macros up to allow the lists to be maintained separately.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 93 ++++++++++++++++--------
 1 file changed, 63 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index 3aa87be4f2e4..a7788ce50736 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -48,22 +48,39 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
  * firmware as TGL.
  */
-#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
-	fw_def(ALDERLAKE_P, 0, guc_def(adlp, 62, 0, 3), huc_def(tgl, 7, 9, 3)) \
-	fw_def(ALDERLAKE_S, 0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(DG1,         0, guc_def(dg1, 62, 0, 0), huc_def(dg1,  7, 9, 3)) \
-	fw_def(ROCKETLAKE,  0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(TIGERLAKE,   0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
-	fw_def(JASPERLAKE,  0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
-	fw_def(ELKHARTLAKE, 0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
-	fw_def(ICELAKE,     0, guc_def(icl, 62, 0, 0), huc_def(icl,  9, 0, 0)) \
-	fw_def(COMETLAKE,   5, guc_def(cml, 62, 0, 0), huc_def(cml,  4, 0, 0)) \
-	fw_def(COMETLAKE,   0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(COFFEELAKE,  0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(GEMINILAKE,  0, guc_def(glk, 62, 0, 0), huc_def(glk,  4, 0, 0)) \
-	fw_def(KABYLAKE,    0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
-	fw_def(BROXTON,     0, guc_def(bxt, 62, 0, 0), huc_def(bxt,  2, 0, 0)) \
-	fw_def(SKYLAKE,     0, guc_def(skl, 62, 0, 0), huc_def(skl,  2, 0, 0))
+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
+
+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))
 
 #define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
 	"i915/" \
@@ -79,11 +96,11 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
 	__MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
 
 /* All blobs need to be declared via MODULE_FIRMWARE() */
-#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
-	MODULE_FIRMWARE(guc_); \
-	MODULE_FIRMWARE(huc_);
+#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
+	MODULE_FIRMWARE(uc_);
 
-INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
+INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH)
+INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH)
 
 /* The below structs and macros are used to iterate across the list of blobs */
 struct __packed uc_fw_blob {
@@ -106,31 +123,47 @@ struct __packed uc_fw_blob {
 struct __packed uc_fw_platform_requirement {
 	enum intel_platform p;
 	u8 rev; /* first platform rev using this FW */
-	const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
+	const struct uc_fw_blob blob;
 };
 
-#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
+#define MAKE_FW_LIST(platform_, revid_, uc_) \
 { \
 	.p = INTEL_##platform_, \
 	.rev = revid_, \
-	.blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
-	.blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
+	.blob = uc_, \
 },
 
+struct fw_blobs_by_type {
+	const struct uc_fw_platform_requirement *blobs;
+	u32 count;
+};
+
 static void
 __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 {
-	static const struct uc_fw_platform_requirement fw_blobs[] = {
-		INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
+	static const struct uc_fw_platform_requirement blobs_guc[] = {
+		INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
+	};
+	static const struct uc_fw_platform_requirement blobs_huc[] = {
+		INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB)
 	};
+	static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
+		[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
+		[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
+	};
+	static const struct uc_fw_platform_requirement *fw_blobs;
 	enum intel_platform p = INTEL_INFO(i915)->platform;
+	u32 fw_count;
 	u8 rev = INTEL_REVID(i915);
 	int i;
 
-	for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
+	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
+	fw_blobs = blobs_all[uc_fw->type].blobs;
+	fw_count = blobs_all[uc_fw->type].count;
+
+	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
 		if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
-			const struct uc_fw_blob *blob =
-					&fw_blobs[i].blobs[uc_fw->type];
+			const struct uc_fw_blob *blob = &fw_blobs[i].blob;
 			uc_fw->path = blob->path;
 			uc_fw->major_ver_wanted = blob->major;
 			uc_fw->minor_ver_wanted = blob->minor;
@@ -140,7 +173,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 
 	/* make sure the list is ordered as expected */
 	if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
-		for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
+		for (i = 1; i < fw_count; i++) {
 			if (fw_blobs[i].p < fw_blobs[i - 1].p)
 				continue;
 
-- 
2.25.1


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

* [PATCH 2/5] drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 18:33   ` John.C.Harrison
  -1 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: John Harrison, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

Lots of testing is done with the DEBUG_GEM config option enabled but
not the DEBUG_GUC option. That means we only get teeny-tiny GuC logs
which are not hugely useful. Enabling full DEBUG_GUC also spews lots
of other detailed output that is not generally desired. However,
bigger GuC logs are extremely useful for almost any regression debug.
So enable bigger logs for DEBUG_GEM builds as well.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index ac1ee1d5ce10..fe6ab7550a14 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -15,9 +15,12 @@
 
 struct intel_guc;
 
-#ifdef CONFIG_DRM_I915_DEBUG_GUC
+#if defined(CONFIG_DRM_I915_DEBUG_GUC)
 #define CRASH_BUFFER_SIZE	SZ_2M
 #define DEBUG_BUFFER_SIZE	SZ_16M
+#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define CRASH_BUFFER_SIZE	SZ_1M
+#define DEBUG_BUFFER_SIZE	SZ_2M
 #else
 #define CRASH_BUFFER_SIZE	SZ_8K
 #define DEBUG_BUFFER_SIZE	SZ_64K
-- 
2.25.1


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

* [Intel-gfx] [PATCH 2/5] drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
@ 2021-12-03 18:33   ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

Lots of testing is done with the DEBUG_GEM config option enabled but
not the DEBUG_GUC option. That means we only get teeny-tiny GuC logs
which are not hugely useful. Enabling full DEBUG_GUC also spews lots
of other detailed output that is not generally desired. However,
bigger GuC logs are extremely useful for almost any regression debug.
So enable bigger logs for DEBUG_GEM builds as well.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index ac1ee1d5ce10..fe6ab7550a14 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -15,9 +15,12 @@
 
 struct intel_guc;
 
-#ifdef CONFIG_DRM_I915_DEBUG_GUC
+#if defined(CONFIG_DRM_I915_DEBUG_GUC)
 #define CRASH_BUFFER_SIZE	SZ_2M
 #define DEBUG_BUFFER_SIZE	SZ_16M
+#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define CRASH_BUFFER_SIZE	SZ_1M
+#define DEBUG_BUFFER_SIZE	SZ_2M
 #else
 #define CRASH_BUFFER_SIZE	SZ_8K
 #define DEBUG_BUFFER_SIZE	SZ_64K
-- 
2.25.1


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

* [PATCH 3/5] drm/i915/guc: Don't go bang in GuC log if no GuC
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 18:33   ` John.C.Harrison
  -1 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: Lucas De Marchi, John Harrison, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

If the GuC has failed to load for any reason and then the user pokes
the debugfs GuC log interface, a BUG and/or null pointer deref can
occur. Don't let that happen.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
index 46026c2c1722..8fd068049376 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
@@ -31,7 +31,7 @@ static int guc_log_level_get(void *data, u64 *val)
 {
 	struct intel_guc_log *log = data;
 
-	if (!intel_guc_is_used(log_to_guc(log)))
+	if (!log->vma)
 		return -ENODEV;
 
 	*val = intel_guc_log_get_level(log);
@@ -43,7 +43,7 @@ static int guc_log_level_set(void *data, u64 val)
 {
 	struct intel_guc_log *log = data;
 
-	if (!intel_guc_is_used(log_to_guc(log)))
+	if (!log->vma)
 		return -ENODEV;
 
 	return intel_guc_log_set_level(log, val);
-- 
2.25.1


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

* [Intel-gfx] [PATCH 3/5] drm/i915/guc: Don't go bang in GuC log if no GuC
@ 2021-12-03 18:33   ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: Lucas De Marchi, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

If the GuC has failed to load for any reason and then the user pokes
the debugfs GuC log interface, a BUG and/or null pointer deref can
occur. Don't let that happen.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
index 46026c2c1722..8fd068049376 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log_debugfs.c
@@ -31,7 +31,7 @@ static int guc_log_level_get(void *data, u64 *val)
 {
 	struct intel_guc_log *log = data;
 
-	if (!intel_guc_is_used(log_to_guc(log)))
+	if (!log->vma)
 		return -ENODEV;
 
 	*val = intel_guc_log_get_level(log);
@@ -43,7 +43,7 @@ static int guc_log_level_set(void *data, u64 val)
 {
 	struct intel_guc_log *log = data;
 
-	if (!intel_guc_is_used(log_to_guc(log)))
+	if (!log->vma)
 		return -ENODEV;
 
 	return intel_guc_log_set_level(log, val);
-- 
2.25.1


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

* [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 18:33   ` John.C.Harrison
  -1 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: John Harrison, DRI-Devel, Michal Wajdeczko

From: John Harrison <John.C.Harrison@Intel.com>

Update to the latest GuC release.

The latest GuC firmware introduces a number of interface changes:

GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
Add support for this reply and try resending the request again as a
new CTB message.

A KLV (key-length-value) mechanism is now used for passing
configuration data such as CTB management.

With the new KLV scheme, the old CTB management actions are no longer
used and are removed.

Register capture on hang is now supported by GuC. Full i915 support
for this will be added by a later patch. A minimum support of
providing capture memory and register lists is required though, so add
that in.

The device id of the current platform needs to be provided at init time.

The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
versions of GuC. It must now be explicitly requested by the KMD. So,
add in the code to turn it on when relevant.

The GuC log entry format has changed. This requires adding a new field
to the log header structure to mark the wrap point at the end of the
buffer (as the buffer size is no longer a multiple of the log entry
size).

New CTB notification messages are now sent for some things that were
previously only sent via MMIO notifications.

Of these, the crash dump notification was not really being handled by
i915. It called the log flush code but that only flushed the regular
debug log and then only if relay logging was enabled. So just report
an error message instead.

The 'exception' notification was just being ignored completely. So add
an error message for that as well.

Note that in either the crash dump or the exception case, the GuC is
basically dead. The KMD will detect this via the heartbeat and trigger
both an error log (which will include the crash dump as part of the
GuC log) and a GT reset. So no other processing is really required.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
 Documentation/gpu/i915.rst                    |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
 12 files changed, 434 insertions(+), 164 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index b7d801993bfa..bcaefc952764 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -539,6 +539,7 @@ GuC ABI
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
 
 HuC
 ---
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index fe5d7d261797..7afdadc7656f 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -7,9 +7,9 @@
 #define _ABI_GUC_ACTIONS_ABI_H
 
 /**
- * DOC: HOST2GUC_REGISTER_CTB
+ * DOC: HOST2GUC_SELF_CFG
  *
- * This message is used as part of the `CTB based communication`_ setup.
+ * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
  *
  * This message must be sent as `MMIO HXG Message`_.
  *
@@ -22,20 +22,18 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 27:16 | DATA0 = MBZ                                                  |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
+ *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
  *  +---+-------+--------------------------------------------------------------+
- *  | 1 | 31:12 | RESERVED = MBZ                                               |
+ *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
+ *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
  *  |   |       |                                                              |
- *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
- *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
+ *  |   |       |   - 32 bit KLV = 1                                           |
+ *  |   |       |   - 64 bit KLV = 2                                           |
  *  +---+-------+--------------------------------------------------------------+
- *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
+ *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
  *  +---+-------+--------------------------------------------------------------+
- *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
+ *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
  *  +---+-------+--------------------------------------------------------------+
  *
  *  +---+-------+--------------------------------------------------------------+
@@ -45,28 +43,25 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  27:0 | DATA0 = MBZ                                                  |
+ *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
  *  +---+-------+--------------------------------------------------------------+
  */
-#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
+#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
 
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
-#define   GUC_CTB_TYPE_HOST2GUC				0u
-#define   GUC_CTB_TYPE_GUC2HOST				1u
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
 
-#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
-#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
+#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
+#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
 
 /**
- * DOC: HOST2GUC_DEREGISTER_CTB
+ * DOC: HOST2GUC_CONTROL_CTB
  *
- * This message is used as part of the `CTB based communication`_ teardown.
+ * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
  *
  * This message must be sent as `MMIO HXG Message`_.
  *
@@ -79,15 +74,12 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 27:16 | DATA0 = MBZ                                                  |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
+ *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
  *  +---+-------+--------------------------------------------------------------+
- *  | 1 | 31:12 | RESERVED = MBZ                                               |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
+ *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
  *  |   |       |                                                              |
- *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |   7:0 | RESERVED = MBZ                                               |
+ *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
+ *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
  *  +---+-------+--------------------------------------------------------------+
  *
  *  +---+-------+--------------------------------------------------------------+
@@ -100,16 +92,16 @@
  *  |   |  27:0 | DATA0 = MBZ                                                  |
  *  +---+-------+--------------------------------------------------------------+
  */
-#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
+#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
 
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
+#define   GUC_CTB_CONTROL_DISABLE			0u
+#define   GUC_CTB_CONTROL_ENABLE			1u
 
-#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
-#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
+#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
+#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
 
 /* legacy definitions */
 
@@ -143,8 +135,12 @@ enum intel_guc_action {
 	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
 	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
 	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
-	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
+	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
 	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
+	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
+	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
+	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
+	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
 	INTEL_GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
new file mode 100644
index 000000000000..3dda88a44fc6
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef _ABI_GUC_KLVS_ABI_H
+#define _ABI_GUC_KLVS_ABI_H
+
+/**
+ * DOC: GuC KLV
+ *
+ *  +---+-------+--------------------------------------------------------------+
+ *  |   | Bits  | Description                                                  |
+ *  +===+=======+==============================================================+
+ *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
+ *  |   |       |   - `GuC Self Config KLVs`_                                  |
+ *  |   |       |                                                              |
+ *  |   +-------+--------------------------------------------------------------+
+ *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
+ *  +---+-------+--------------------------------------------------------------+
+ *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
+ *  +---+-------+                                                              |
+ *  |...|       |                                                              |
+ *  +---+-------+                                                              |
+ *  | n |  31:0 |                                                              |
+ *  +---+-------+--------------------------------------------------------------+
+ */
+
+#define GUC_KLV_LEN_MIN				1u
+#define GUC_KLV_0_KEY				(0xffff << 16)
+#define GUC_KLV_0_LEN				(0xffff << 0)
+#define GUC_KLV_n_VALUE				(0xffffffff << 0)
+
+/**
+ * DOC: GuC Self Config KLVs
+ *
+ * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
+ *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
+ *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
+ *      Refers to size of H2G `CT Buffer`_ in bytes.
+ *      Should be a multiple of 4K.
+ *
+ * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
+ *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
+ *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
+ *      Refers to size of G2H `CT Buffer`_ in bytes.
+ *      Should be a multiple of 4K.
+ */
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
+#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
+#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
+#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
+#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
+#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
+#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
+
+#endif /* _ABI_GUC_KLVS_ABI_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 6e228343e8cb..cbec51f4dec3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
 		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
 		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
 	}
+
+	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
+				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
 }
 
 void intel_guc_init_late(struct intel_guc *guc)
@@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
 	u32 flags;
 
 	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
-	#define UNIT SZ_1M
-	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
+	#define LOG_UNIT SZ_1M
+	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
 	#else
-	#define UNIT SZ_4K
-	#define FLAG 0
+	#define LOG_UNIT SZ_4K
+	#define LOG_FLAG 0
+	#endif
+
+	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
+	#define CAPTURE_UNIT SZ_1M
+	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
+	#else
+	#define CAPTURE_UNIT SZ_4K
+	#define CAPTURE_FLAG 0
 	#endif
 
 	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
-	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
+	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
 	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
-	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
+	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
+	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
+	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
 
-	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
+	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
 			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
-	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
+	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
 			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
+	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
+			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
 
 	flags = GUC_LOG_VALID |
 		GUC_LOG_NOTIFY_ON_HALF_FULL |
-		FLAG |
-		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
-		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+		CAPTURE_FLAG |
+		LOG_FLAG |
+		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
+		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
 		(offset << GUC_LOG_BUF_ADDR_SHIFT);
 
-	#undef UNIT
-	#undef FLAG
+	#undef LOG_UNIT
+	#undef LOG_FLAG
+	#undef CAPTURE_UNIT
+	#undef CAPTURE_FLAG
 
 	return flags;
 }
@@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
 	return flags;
 }
 
+static u32 guc_ctl_wa_flags(struct intel_guc *guc)
+{
+	struct intel_gt *gt = guc_to_gt(guc);
+	u32 flags = 0;
+
+	/* Wa_22012773006:gen11,gen12 < XeHP */
+	if (GRAPHICS_VER(gt->i915) >= 11 &&
+	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
+		flags |= GUC_WA_POLLCS;
+
+	return flags;
+}
+
+static u32 guc_ctl_devid(struct intel_guc *guc)
+{
+	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+
+	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
+}
+
 /*
  * Initialise the GuC parameter block before starting the firmware
  * transfer. These parameters are read by the firmware on startup
@@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
 	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
 	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
 	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
+	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
+	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
 
 	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
 		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
@@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
 	/* Make sure to handle only enabled messages */
 	msg = payload[0] & guc->msg_enabled_mask;
 
-	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
-		intel_guc_log_handle_flush_event(&guc->log);
+	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
+		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
+	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
+		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
 
 	return 0;
 }
@@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
 {
 	int ret;
 	u32 action[] = {
-		INTEL_GUC_ACTION_RESET_CLIENT,
+		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
 	};
 
 	if (!intel_guc_is_ready(guc))
@@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
 	return 0;
 }
 
+static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
+{
+	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
+		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
+		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
+		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
+	};
+	int ret;
+
+	GEM_BUG_ON(len > 2);
+	GEM_BUG_ON(len == 1 && upper_32_bits(value));
+
+	/* Self config must go over MMIO */
+	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
+
+	if (unlikely(ret < 0))
+		return ret;
+	if (unlikely(ret > 1))
+		return -EPROTO;
+	if (unlikely(!ret))
+		return -ENOKEY;
+
+	return 0;
+}
+
+static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
+{
+	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+	int err = __guc_action_self_cfg(guc, key, len, value);
+
+	if (unlikely(err))
+		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
+				 ERR_PTR(err), key, value);
+	return err;
+}
+
+int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
+{
+	return __guc_self_cfg(guc, key, 1, value);
+}
+
+int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
+{
+	return __guc_self_cfg(guc, key, 2, value);
+}
+
 /**
  * intel_guc_load_status - dump information about GuC load status
  * @guc: the GuC
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 1cb46098030d..eaa1a85a2f01 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
 struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
 int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
 				   struct i915_vma **out_vma, void **out_vaddr);
+int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
+int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
 
 static inline bool intel_guc_is_supported(struct intel_guc *guc)
 {
@@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
 					const u32 *msg, u32 len);
 int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
 					 const u32 *msg, u32 len);
+int intel_guc_error_capture_process_msg(struct intel_guc *guc,
+					const u32 *msg, u32 len);
 
 void intel_guc_find_hung_context(struct intel_engine_cs *engine);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 1a1edae67e4e..aa767540ca2a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -40,6 +40,10 @@
  *      +---------------------------------------+
  *      | padding                               |
  *      +---------------------------------------+ <== 4K aligned
+ *      | capture lists                         |
+ *      +---------------------------------------+
+ *      | padding                               |
+ *      +---------------------------------------+ <== 4K aligned
  *      | private data                          |
  *      +---------------------------------------+
  *      | padding                               |
@@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
 	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_capture_size(struct intel_guc *guc)
+{
+	/* FIXME: Allocate a proper capture list */
+	return PAGE_ALIGN(PAGE_SIZE);
+}
+
 static u32 guc_ads_private_data_size(struct intel_guc *guc)
 {
 	return PAGE_ALIGN(guc->fw.private_data_size);
@@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
 	return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_private_data_offset(struct intel_guc *guc)
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
 {
 	u32 offset;
 
@@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 	return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_private_data_offset(struct intel_guc *guc)
+{
+	u32 offset;
+
+	offset = guc_ads_capture_offset(guc) +
+		 guc_ads_capture_size(guc);
+
+	return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_blob_size(struct intel_guc *guc)
 {
 	return guc_ads_private_data_offset(guc) +
@@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 }
 
+static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
+{
+	int i, j;
+	u32 addr_ggtt, offset;
+
+	offset = guc_ads_capture_offset(guc);
+	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+	/* FIXME: Populate a proper capture list */
+
+	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
+		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
+			blob->ads.capture_instance[i][j] = addr_ggtt;
+			blob->ads.capture_class[i][j] = addr_ggtt;
+		}
+
+		blob->ads.capture_global[i] = addr_ggtt;
+	}
+}
+
 static void __guc_ads_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
@@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
 
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
+	/* Capture list for hang debug */
+	guc_capture_list_init(guc, blob);
+
 	/* ADS */
 	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
 	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index a0cc34be7b56..eba03e4c815b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
 	init_waitqueue_head(&ct->wq);
 }
 
-static inline const char *guc_ct_buffer_type_to_str(u32 type)
-{
-	switch (type) {
-	case GUC_CTB_TYPE_HOST2GUC:
-		return "SEND";
-	case GUC_CTB_TYPE_GUC2HOST:
-		return "RECV";
-	default:
-		return "<invalid>";
-	}
-}
-
 static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
 {
 	memset(desc, 0, sizeof(*desc));
@@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
 	guc_ct_buffer_reset(ctb);
 }
 
-static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
-					 u32 desc_addr, u32 buff_addr, u32 size)
+static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
 {
-	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
+	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
-		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
+		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
+		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
 	};
 	int ret;
 
-	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
-	GEM_BUG_ON(size % SZ_4K);
+	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
 
-	/* CT registration must go over MMIO */
+	/* CT control must go over MMIO */
 	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
 
 	return ret > 0 ? -EPROTO : ret;
 }
 
-static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
-			      u32 desc_addr, u32 buff_addr, u32 size)
+static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
 {
 	int err;
 
-	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
+	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
+				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
 	if (unlikely(err))
-		return err;
+		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
+			       enabledisable(enable), ERR_PTR(err));
 
-	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
-					    desc_addr, buff_addr, size);
-	if (unlikely(err))
-		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
-			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
 	return err;
 }
 
-static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
+static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
+			      u32 desc_addr, u32 buff_addr, u32 size)
 {
-	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
-		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
-		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
-		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
-		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
-	};
-	int ret;
-
-	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
-
-	/* CT deregistration must go over MMIO */
-	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
+	int err;
 
-	return ret > 0 ? -EPROTO : ret;
-}
+	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
+				   desc_addr);
+	if (unlikely(err))
+		goto failed;
 
-static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
-{
-	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
+	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
+				   buff_addr);
+	if (unlikely(err))
+		goto failed;
 
+	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
+				   size);
 	if (unlikely(err))
-		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
-			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
+failed:
+		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
+			       send ? "SEND" : "RECV", ERR_PTR(err));
+
 	return err;
 }
 
@@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
 int intel_guc_ct_enable(struct intel_guc_ct *ct)
 {
 	struct intel_guc *guc = ct_to_guc(ct);
-	u32 base, desc, cmds;
+	u32 base, desc, cmds, size;
 	void *blob;
 	int err;
 
@@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
 	 */
 	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
 	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
-	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
-				 desc, cmds, ct->ctbs.recv.size * 4);
-
+	size = ct->ctbs.recv.size * 4;
+	err = ct_register_buffer(ct, false, desc, cmds, size);
 	if (unlikely(err))
 		goto err_out;
 
 	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
 	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
-	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
-				 desc, cmds, ct->ctbs.send.size * 4);
+	size = ct->ctbs.send.size * 4;
+	err = ct_register_buffer(ct, true, desc, cmds, size);
+	if (unlikely(err))
+		goto err_out;
 
+	err = ct_control_enable(ct, true);
 	if (unlikely(err))
-		goto err_deregister;
+		goto err_out;
 
 	ct->enabled = true;
 	ct->stall_time = KTIME_MAX;
 
 	return 0;
 
-err_deregister:
-	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
 err_out:
 	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
 	return err;
@@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
 	ct->enabled = false;
 
 	if (intel_guc_is_fw_running(guc)) {
-		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
-		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
+		ct_control_enable(ct, false);
 	}
 }
 
@@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
 	struct ct_request request;
 	unsigned long flags;
 	unsigned int sleep_period_ms = 1;
+	bool send_again;
 	u32 fence;
 	int err;
 
@@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
 	GEM_BUG_ON(!response_buf && response_buf_size);
 	might_sleep();
 
+resend:
+	send_again = false;
+
 	/*
 	 * We use a lazy spin wait loop here as we believe that if the CT
 	 * buffers are sized correctly the flow control condition should be
@@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
 		goto unlink;
 	}
 
+	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
+		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
+			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
+		send_again = true;
+		goto unlink;
+	}
+
 	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
 		err = -EIO;
 		goto unlink;
@@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
 	list_del(&request.link);
 	spin_unlock_irqrestore(&ct->requests.lock, flags);
 
+	if (unlikely(send_again))
+		goto resend;
+
 	return err;
 }
 
@@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
 	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
 	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
 	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
+		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
 		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
 
 	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
@@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
 	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
 		ret = intel_guc_context_reset_process_msg(guc, payload, len);
 		break;
+	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
+		ret = intel_guc_error_capture_process_msg(guc, payload, len);
+		if (unlikely(ret))
+			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
+				 action, 4 * len, payload);
+		break;
 	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
 		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
 		break;
+	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
+		intel_guc_log_handle_flush_event(&guc->log);
+		ret = 0;
+		break;
+	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
+		CT_ERROR(ct, "Received GuC crash dump notification!\n");
+		ret = 0;
+		break;
+	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
+		CT_ERROR(ct, "Received GuC exception notification!\n");
+		ret = 0;
+		break;
 	default:
 		ret = -EOPNOTSUPP;
 		break;
@@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
 		break;
 	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
 	case GUC_HXG_TYPE_RESPONSE_FAILURE:
+	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
 		err = ct_handle_response(ct, msg);
 		break;
 	default:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 7072e30e99f4..6a4612a852e2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -16,6 +16,7 @@
 #include "abi/guc_errors_abi.h"
 #include "abi/guc_communication_mmio_abi.h"
 #include "abi/guc_communication_ctb_abi.h"
+#include "abi/guc_klvs_abi.h"
 #include "abi/guc_messages_abi.h"
 
 /* Payload length only i.e. don't include G2H header length */
@@ -84,19 +85,24 @@
 #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
 
 #define GUC_CTL_LOG_PARAMS		0
-#define   GUC_LOG_VALID			(1 << 0)
-#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
-#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
+#define   GUC_LOG_VALID			BIT(0)
+#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
+#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
+#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
 #define   GUC_LOG_CRASH_SHIFT		4
 #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
 #define   GUC_LOG_DEBUG_SHIFT		6
 #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
+#define   GUC_LOG_CAPTURE_SHIFT		10
+#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
 #define   GUC_LOG_BUF_ADDR_SHIFT	12
 
 #define GUC_CTL_WA			1
+#define   GUC_WA_POLLCS                 BIT(18)
+
 #define GUC_CTL_FEATURE			2
-#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
 #define   GUC_CTL_ENABLE_SLPC		BIT(2)
+#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
 
 #define GUC_CTL_DEBUG			3
 #define   GUC_LOG_VERBOSITY_SHIFT	0
@@ -116,6 +122,8 @@
 #define   GUC_ADS_ADDR_SHIFT		1
 #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
 
+#define GUC_CTL_DEVID			5
+
 #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
 
 /* Generic GT SysInfo data types */
@@ -263,7 +271,10 @@ struct guc_mmio_reg {
 	u32 offset;
 	u32 value;
 	u32 flags;
-#define GUC_REGSET_MASKED		(1 << 0)
+	u32 mask;
+#define GUC_REGSET_MASKED		BIT(0)
+#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
+#define GUC_REGSET_RESTORE_ONLY		BIT(3)
 } __packed;
 
 /* GuC register sets */
@@ -280,6 +291,12 @@ struct guc_gt_system_info {
 	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
 } __packed;
 
+enum {
+	GUC_CAPTURE_LIST_INDEX_PF = 0,
+	GUC_CAPTURE_LIST_INDEX_VF = 1,
+	GUC_CAPTURE_LIST_INDEX_MAX = 2,
+};
+
 /* GuC Additional Data Struct */
 struct guc_ads {
 	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
@@ -291,7 +308,11 @@ struct guc_ads {
 	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
 	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
 	u32 private_data;
-	u32 reserved[15];
+	u32 reserved2;
+	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
+	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
+	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
+	u32 reserved[14];
 } __packed;
 
 /* Engine usage stats */
@@ -312,6 +333,7 @@ struct guc_engine_usage {
 enum guc_log_buffer_type {
 	GUC_DEBUG_LOG_BUFFER,
 	GUC_CRASH_DUMP_LOG_BUFFER,
+	GUC_CAPTURE_LOG_BUFFER,
 	GUC_MAX_LOG_BUFFER
 };
 
@@ -342,6 +364,7 @@ struct guc_log_buffer_state {
 	u32 write_ptr;
 	u32 size;
 	u32 sampled_write_ptr;
+	u32 wrap_offset;
 	union {
 		struct {
 			u32 flush_to_file:1;
@@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
 /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
 enum intel_guc_recv_message {
 	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
-	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
+	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
 };
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index ac0931f0374b..be35f0570396 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
 	return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
 
-static void guc_log_enable_flush_events(struct intel_guc_log *log)
-{
-	intel_guc_enable_msg(log_to_guc(log),
-			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
-}
-
-static void guc_log_disable_flush_events(struct intel_guc_log *log)
-{
-	intel_guc_disable_msg(log_to_guc(log),
-			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
-}
-
 /*
  * Sub buffer switch callback. Called whenever relay has to switch to a new
  * sub buffer, relay stays on the same sub buffer if 0 is returned.
@@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
 		return DEBUG_BUFFER_SIZE;
 	case GUC_CRASH_DUMP_LOG_BUFFER:
 		return CRASH_BUFFER_SIZE;
+	case GUC_CAPTURE_LOG_BUFFER:
+		return CAPTURE_BUFFER_SIZE;
 	default:
 		MISSING_CASE(type);
 	}
@@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
 	 *  +-------------------------------+ 32B
 	 *  |      Debug state header       |
 	 *  +-------------------------------+ 64B
+	 *  |     Capture state header      |
+	 *  +-------------------------------+ 96B
 	 *  |                               |
 	 *  +===============================+ PAGE_SIZE (4KB)
 	 *  |        Crash Dump logs        |
 	 *  +===============================+ + CRASH_SIZE
 	 *  |          Debug logs           |
 	 *  +===============================+ + DEBUG_SIZE
+	 *  |         Capture logs          |
+	 *  +===============================+ + CAPTURE_SIZE
 	 */
-	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
+	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
+		       CAPTURE_BUFFER_SIZE;
 
 	vma = intel_guc_allocate_vma(guc, guc_log_size);
 	if (IS_ERR(vma)) {
@@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
 	if (log->relay.started)
 		return -EEXIST;
 
-	guc_log_enable_flush_events(log);
-
 	/*
 	 * When GuC is logging without us relaying to userspace, we're ignoring
 	 * the flush notification. This means that we need to unconditionally
@@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
 	if (!log->relay.started)
 		return;
 
-	guc_log_disable_flush_events(log);
 	intel_synchronize_irq(i915);
 
 	flush_work(&log->relay.flush_work);
@@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
 
 void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
 {
-	queue_work(system_highpri_wq, &log->relay.flush_work);
+	if (log->relay.started)
+		queue_work(system_highpri_wq, &log->relay.flush_work);
 }
 
 static const char *
@@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
 		return "DEBUG";
 	case GUC_CRASH_DUMP_LOG_BUFFER:
 		return "CRASH";
+	case GUC_CAPTURE_LOG_BUFFER:
+		return "CAPTURE";
 	default:
 		MISSING_CASE(type);
 	}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index fe6ab7550a14..d7e1b6471fed 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -18,12 +18,15 @@ struct intel_guc;
 #if defined(CONFIG_DRM_I915_DEBUG_GUC)
 #define CRASH_BUFFER_SIZE	SZ_2M
 #define DEBUG_BUFFER_SIZE	SZ_16M
+#define CAPTURE_BUFFER_SIZE	SZ_4M
 #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
 #define CRASH_BUFFER_SIZE	SZ_1M
 #define DEBUG_BUFFER_SIZE	SZ_2M
+#define CAPTURE_BUFFER_SIZE	SZ_1M
 #else
 #define CRASH_BUFFER_SIZE	SZ_8K
 #define DEBUG_BUFFER_SIZE	SZ_64K
+#define CAPTURE_BUFFER_SIZE	SZ_16K
 #endif
 
 /*
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 1f9d4fde421f..4d6c1383f2eb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
 	return 0;
 }
 
+int intel_guc_error_capture_process_msg(struct intel_guc *guc,
+					const u32 *msg, u32 len)
+{
+	int status;
+
+	if (unlikely(len != 1)) {
+		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
+		return -EPROTO;
+	}
+
+	status = msg[0];
+	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
+
+	/* FIXME: Do something with the capture */
+
+	return 0;
+}
+
 static struct intel_engine_cs *
 guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
 {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index a7788ce50736..9b82a5a27f90 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * firmware as TGL.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
-	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
-	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
-	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
-	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
-	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
-	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
-	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
-	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
-	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
 
 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
 	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
-- 
2.25.1


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

* [Intel-gfx] [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
@ 2021-12-03 18:33   ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

Update to the latest GuC release.

The latest GuC firmware introduces a number of interface changes:

GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
Add support for this reply and try resending the request again as a
new CTB message.

A KLV (key-length-value) mechanism is now used for passing
configuration data such as CTB management.

With the new KLV scheme, the old CTB management actions are no longer
used and are removed.

Register capture on hang is now supported by GuC. Full i915 support
for this will be added by a later patch. A minimum support of
providing capture memory and register lists is required though, so add
that in.

The device id of the current platform needs to be provided at init time.

The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
versions of GuC. It must now be explicitly requested by the KMD. So,
add in the code to turn it on when relevant.

The GuC log entry format has changed. This requires adding a new field
to the log header structure to mark the wrap point at the end of the
buffer (as the buffer size is no longer a multiple of the log entry
size).

New CTB notification messages are now sent for some things that were
previously only sent via MMIO notifications.

Of these, the crash dump notification was not really being handled by
i915. It called the log flush code but that only flushed the regular
debug log and then only if relay logging was enabled. So just report
an error message instead.

The 'exception' notification was just being ignored completely. So add
an error message for that as well.

Note that in either the crash dump or the exception case, the GuC is
basically dead. The KMD will detect this via the heartbeat and trigger
both an error log (which will include the crash dump as part of the
GuC log) and a GT reset. So no other processing is really required.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
---
 Documentation/gpu/i915.rst                    |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
 12 files changed, 434 insertions(+), 164 deletions(-)
 create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h

diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
index b7d801993bfa..bcaefc952764 100644
--- a/Documentation/gpu/i915.rst
+++ b/Documentation/gpu/i915.rst
@@ -539,6 +539,7 @@ GuC ABI
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
 .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
 
 HuC
 ---
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
index fe5d7d261797..7afdadc7656f 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
@@ -7,9 +7,9 @@
 #define _ABI_GUC_ACTIONS_ABI_H
 
 /**
- * DOC: HOST2GUC_REGISTER_CTB
+ * DOC: HOST2GUC_SELF_CFG
  *
- * This message is used as part of the `CTB based communication`_ setup.
+ * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
  *
  * This message must be sent as `MMIO HXG Message`_.
  *
@@ -22,20 +22,18 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 27:16 | DATA0 = MBZ                                                  |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
+ *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
  *  +---+-------+--------------------------------------------------------------+
- *  | 1 | 31:12 | RESERVED = MBZ                                               |
+ *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
+ *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
  *  |   |       |                                                              |
- *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
- *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
+ *  |   |       |   - 32 bit KLV = 1                                           |
+ *  |   |       |   - 64 bit KLV = 2                                           |
  *  +---+-------+--------------------------------------------------------------+
- *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
+ *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
  *  +---+-------+--------------------------------------------------------------+
- *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
+ *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
  *  +---+-------+--------------------------------------------------------------+
  *
  *  +---+-------+--------------------------------------------------------------+
@@ -45,28 +43,25 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  27:0 | DATA0 = MBZ                                                  |
+ *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
  *  +---+-------+--------------------------------------------------------------+
  */
-#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
+#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
 
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
-#define   GUC_CTB_TYPE_HOST2GUC				0u
-#define   GUC_CTB_TYPE_GUC2HOST				1u
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
-#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
 
-#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
-#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
+#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
+#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
 
 /**
- * DOC: HOST2GUC_DEREGISTER_CTB
+ * DOC: HOST2GUC_CONTROL_CTB
  *
- * This message is used as part of the `CTB based communication`_ teardown.
+ * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
  *
  * This message must be sent as `MMIO HXG Message`_.
  *
@@ -79,15 +74,12 @@
  *  |   +-------+--------------------------------------------------------------+
  *  |   | 27:16 | DATA0 = MBZ                                                  |
  *  |   +-------+--------------------------------------------------------------+
- *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
+ *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
  *  +---+-------+--------------------------------------------------------------+
- *  | 1 | 31:12 | RESERVED = MBZ                                               |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
+ *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
  *  |   |       |                                                              |
- *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
- *  |   +-------+--------------------------------------------------------------+
- *  |   |   7:0 | RESERVED = MBZ                                               |
+ *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
+ *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
  *  +---+-------+--------------------------------------------------------------+
  *
  *  +---+-------+--------------------------------------------------------------+
@@ -100,16 +92,16 @@
  *  |   |  27:0 | DATA0 = MBZ                                                  |
  *  +---+-------+--------------------------------------------------------------+
  */
-#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
+#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
 
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
-#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
+#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
+#define   GUC_CTB_CONTROL_DISABLE			0u
+#define   GUC_CTB_CONTROL_ENABLE			1u
 
-#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
-#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
+#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
+#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
 
 /* legacy definitions */
 
@@ -143,8 +135,12 @@ enum intel_guc_action {
 	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
 	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
 	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
-	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
+	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
 	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
+	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
+	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
+	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
+	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
 	INTEL_GUC_ACTION_LIMIT
 };
 
diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
new file mode 100644
index 000000000000..3dda88a44fc6
--- /dev/null
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright © 2021 Intel Corporation
+ */
+
+#ifndef _ABI_GUC_KLVS_ABI_H
+#define _ABI_GUC_KLVS_ABI_H
+
+/**
+ * DOC: GuC KLV
+ *
+ *  +---+-------+--------------------------------------------------------------+
+ *  |   | Bits  | Description                                                  |
+ *  +===+=======+==============================================================+
+ *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
+ *  |   |       |   - `GuC Self Config KLVs`_                                  |
+ *  |   |       |                                                              |
+ *  |   +-------+--------------------------------------------------------------+
+ *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
+ *  +---+-------+--------------------------------------------------------------+
+ *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
+ *  +---+-------+                                                              |
+ *  |...|       |                                                              |
+ *  +---+-------+                                                              |
+ *  | n |  31:0 |                                                              |
+ *  +---+-------+--------------------------------------------------------------+
+ */
+
+#define GUC_KLV_LEN_MIN				1u
+#define GUC_KLV_0_KEY				(0xffff << 16)
+#define GUC_KLV_0_LEN				(0xffff << 0)
+#define GUC_KLV_n_VALUE				(0xffffffff << 0)
+
+/**
+ * DOC: GuC Self Config KLVs
+ *
+ * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
+ *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
+ *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
+ *      Refers to size of H2G `CT Buffer`_ in bytes.
+ *      Should be a multiple of 4K.
+ *
+ * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
+ *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
+ *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
+ *      Should be above WOPCM address but below APIC base address for native mode.
+ *
+ * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
+ *      Refers to size of G2H `CT Buffer`_ in bytes.
+ *      Should be a multiple of 4K.
+ */
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
+#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
+#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
+
+#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
+#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
+#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
+#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
+
+#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
+#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
+
+#endif /* _ABI_GUC_KLVS_ABI_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 6e228343e8cb..cbec51f4dec3 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
 		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
 		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
 	}
+
+	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
+				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
 }
 
 void intel_guc_init_late(struct intel_guc *guc)
@@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
 	u32 flags;
 
 	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
-	#define UNIT SZ_1M
-	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
+	#define LOG_UNIT SZ_1M
+	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
 	#else
-	#define UNIT SZ_4K
-	#define FLAG 0
+	#define LOG_UNIT SZ_4K
+	#define LOG_FLAG 0
+	#endif
+
+	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
+	#define CAPTURE_UNIT SZ_1M
+	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
+	#else
+	#define CAPTURE_UNIT SZ_4K
+	#define CAPTURE_FLAG 0
 	#endif
 
 	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
-	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
+	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
 	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
-	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
+	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
+	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
+	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
 
-	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
+	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
 			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
-	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
+	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
 			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
+	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
+			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
 
 	flags = GUC_LOG_VALID |
 		GUC_LOG_NOTIFY_ON_HALF_FULL |
-		FLAG |
-		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
-		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+		CAPTURE_FLAG |
+		LOG_FLAG |
+		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
+		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
+		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
 		(offset << GUC_LOG_BUF_ADDR_SHIFT);
 
-	#undef UNIT
-	#undef FLAG
+	#undef LOG_UNIT
+	#undef LOG_FLAG
+	#undef CAPTURE_UNIT
+	#undef CAPTURE_FLAG
 
 	return flags;
 }
@@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
 	return flags;
 }
 
+static u32 guc_ctl_wa_flags(struct intel_guc *guc)
+{
+	struct intel_gt *gt = guc_to_gt(guc);
+	u32 flags = 0;
+
+	/* Wa_22012773006:gen11,gen12 < XeHP */
+	if (GRAPHICS_VER(gt->i915) >= 11 &&
+	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
+		flags |= GUC_WA_POLLCS;
+
+	return flags;
+}
+
+static u32 guc_ctl_devid(struct intel_guc *guc)
+{
+	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+
+	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
+}
+
 /*
  * Initialise the GuC parameter block before starting the firmware
  * transfer. These parameters are read by the firmware on startup
@@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
 	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
 	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
 	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
+	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
+	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
 
 	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
 		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
@@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
 	/* Make sure to handle only enabled messages */
 	msg = payload[0] & guc->msg_enabled_mask;
 
-	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
-		intel_guc_log_handle_flush_event(&guc->log);
+	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
+		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
+	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
+		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
 
 	return 0;
 }
@@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
 {
 	int ret;
 	u32 action[] = {
-		INTEL_GUC_ACTION_RESET_CLIENT,
+		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
 	};
 
 	if (!intel_guc_is_ready(guc))
@@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
 	return 0;
 }
 
+static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
+{
+	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
+		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
+		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
+		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
+		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
+	};
+	int ret;
+
+	GEM_BUG_ON(len > 2);
+	GEM_BUG_ON(len == 1 && upper_32_bits(value));
+
+	/* Self config must go over MMIO */
+	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
+
+	if (unlikely(ret < 0))
+		return ret;
+	if (unlikely(ret > 1))
+		return -EPROTO;
+	if (unlikely(!ret))
+		return -ENOKEY;
+
+	return 0;
+}
+
+static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
+{
+	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
+	int err = __guc_action_self_cfg(guc, key, len, value);
+
+	if (unlikely(err))
+		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
+				 ERR_PTR(err), key, value);
+	return err;
+}
+
+int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
+{
+	return __guc_self_cfg(guc, key, 1, value);
+}
+
+int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
+{
+	return __guc_self_cfg(guc, key, 2, value);
+}
+
 /**
  * intel_guc_load_status - dump information about GuC load status
  * @guc: the GuC
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 1cb46098030d..eaa1a85a2f01 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
 struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
 int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
 				   struct i915_vma **out_vma, void **out_vaddr);
+int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
+int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
 
 static inline bool intel_guc_is_supported(struct intel_guc *guc)
 {
@@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
 					const u32 *msg, u32 len);
 int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
 					 const u32 *msg, u32 len);
+int intel_guc_error_capture_process_msg(struct intel_guc *guc,
+					const u32 *msg, u32 len);
 
 void intel_guc_find_hung_context(struct intel_engine_cs *engine);
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
index 1a1edae67e4e..aa767540ca2a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -40,6 +40,10 @@
  *      +---------------------------------------+
  *      | padding                               |
  *      +---------------------------------------+ <== 4K aligned
+ *      | capture lists                         |
+ *      +---------------------------------------+
+ *      | padding                               |
+ *      +---------------------------------------+ <== 4K aligned
  *      | private data                          |
  *      +---------------------------------------+
  *      | padding                               |
@@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
 	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_capture_size(struct intel_guc *guc)
+{
+	/* FIXME: Allocate a proper capture list */
+	return PAGE_ALIGN(PAGE_SIZE);
+}
+
 static u32 guc_ads_private_data_size(struct intel_guc *guc)
 {
 	return PAGE_ALIGN(guc->fw.private_data_size);
@@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
 	return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_private_data_offset(struct intel_guc *guc)
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
 {
 	u32 offset;
 
@@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 	return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_private_data_offset(struct intel_guc *guc)
+{
+	u32 offset;
+
+	offset = guc_ads_capture_offset(guc) +
+		 guc_ads_capture_size(guc);
+
+	return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_blob_size(struct intel_guc *guc)
 {
 	return guc_ads_private_data_offset(guc) +
@@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
 	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 }
 
+static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
+{
+	int i, j;
+	u32 addr_ggtt, offset;
+
+	offset = guc_ads_capture_offset(guc);
+	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+	/* FIXME: Populate a proper capture list */
+
+	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
+		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
+			blob->ads.capture_instance[i][j] = addr_ggtt;
+			blob->ads.capture_class[i][j] = addr_ggtt;
+		}
+
+		blob->ads.capture_global[i] = addr_ggtt;
+	}
+}
+
 static void __guc_ads_init(struct intel_guc *guc)
 {
 	struct intel_gt *gt = guc_to_gt(guc);
@@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
 
 	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
 
+	/* Capture list for hang debug */
+	guc_capture_list_init(guc, blob);
+
 	/* ADS */
 	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
 	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
index a0cc34be7b56..eba03e4c815b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
 	init_waitqueue_head(&ct->wq);
 }
 
-static inline const char *guc_ct_buffer_type_to_str(u32 type)
-{
-	switch (type) {
-	case GUC_CTB_TYPE_HOST2GUC:
-		return "SEND";
-	case GUC_CTB_TYPE_GUC2HOST:
-		return "RECV";
-	default:
-		return "<invalid>";
-	}
-}
-
 static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
 {
 	memset(desc, 0, sizeof(*desc));
@@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
 	guc_ct_buffer_reset(ctb);
 }
 
-static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
-					 u32 desc_addr, u32 buff_addr, u32 size)
+static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
 {
-	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
+	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
-		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
-		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
+		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
+		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
 	};
 	int ret;
 
-	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
-	GEM_BUG_ON(size % SZ_4K);
+	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
 
-	/* CT registration must go over MMIO */
+	/* CT control must go over MMIO */
 	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
 
 	return ret > 0 ? -EPROTO : ret;
 }
 
-static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
-			      u32 desc_addr, u32 buff_addr, u32 size)
+static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
 {
 	int err;
 
-	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
+	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
+				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
 	if (unlikely(err))
-		return err;
+		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
+			       enabledisable(enable), ERR_PTR(err));
 
-	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
-					    desc_addr, buff_addr, size);
-	if (unlikely(err))
-		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
-			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
 	return err;
 }
 
-static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
+static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
+			      u32 desc_addr, u32 buff_addr, u32 size)
 {
-	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
-		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
-		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
-		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
-		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
-	};
-	int ret;
-
-	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
-
-	/* CT deregistration must go over MMIO */
-	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
+	int err;
 
-	return ret > 0 ? -EPROTO : ret;
-}
+	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
+				   desc_addr);
+	if (unlikely(err))
+		goto failed;
 
-static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
-{
-	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
+	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
+				   buff_addr);
+	if (unlikely(err))
+		goto failed;
 
+	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
+				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
+				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
+				   size);
 	if (unlikely(err))
-		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
-			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
+failed:
+		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
+			       send ? "SEND" : "RECV", ERR_PTR(err));
+
 	return err;
 }
 
@@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
 int intel_guc_ct_enable(struct intel_guc_ct *ct)
 {
 	struct intel_guc *guc = ct_to_guc(ct);
-	u32 base, desc, cmds;
+	u32 base, desc, cmds, size;
 	void *blob;
 	int err;
 
@@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
 	 */
 	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
 	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
-	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
-				 desc, cmds, ct->ctbs.recv.size * 4);
-
+	size = ct->ctbs.recv.size * 4;
+	err = ct_register_buffer(ct, false, desc, cmds, size);
 	if (unlikely(err))
 		goto err_out;
 
 	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
 	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
-	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
-				 desc, cmds, ct->ctbs.send.size * 4);
+	size = ct->ctbs.send.size * 4;
+	err = ct_register_buffer(ct, true, desc, cmds, size);
+	if (unlikely(err))
+		goto err_out;
 
+	err = ct_control_enable(ct, true);
 	if (unlikely(err))
-		goto err_deregister;
+		goto err_out;
 
 	ct->enabled = true;
 	ct->stall_time = KTIME_MAX;
 
 	return 0;
 
-err_deregister:
-	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
 err_out:
 	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
 	return err;
@@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
 	ct->enabled = false;
 
 	if (intel_guc_is_fw_running(guc)) {
-		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
-		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
+		ct_control_enable(ct, false);
 	}
 }
 
@@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
 	struct ct_request request;
 	unsigned long flags;
 	unsigned int sleep_period_ms = 1;
+	bool send_again;
 	u32 fence;
 	int err;
 
@@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
 	GEM_BUG_ON(!response_buf && response_buf_size);
 	might_sleep();
 
+resend:
+	send_again = false;
+
 	/*
 	 * We use a lazy spin wait loop here as we believe that if the CT
 	 * buffers are sized correctly the flow control condition should be
@@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
 		goto unlink;
 	}
 
+	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
+		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
+			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
+		send_again = true;
+		goto unlink;
+	}
+
 	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
 		err = -EIO;
 		goto unlink;
@@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
 	list_del(&request.link);
 	spin_unlock_irqrestore(&ct->requests.lock, flags);
 
+	if (unlikely(send_again))
+		goto resend;
+
 	return err;
 }
 
@@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
 	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
 	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
 	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
+		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
 		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
 
 	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
@@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
 	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
 		ret = intel_guc_context_reset_process_msg(guc, payload, len);
 		break;
+	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
+		ret = intel_guc_error_capture_process_msg(guc, payload, len);
+		if (unlikely(ret))
+			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
+				 action, 4 * len, payload);
+		break;
 	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
 		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
 		break;
+	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
+		intel_guc_log_handle_flush_event(&guc->log);
+		ret = 0;
+		break;
+	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
+		CT_ERROR(ct, "Received GuC crash dump notification!\n");
+		ret = 0;
+		break;
+	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
+		CT_ERROR(ct, "Received GuC exception notification!\n");
+		ret = 0;
+		break;
 	default:
 		ret = -EOPNOTSUPP;
 		break;
@@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
 		break;
 	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
 	case GUC_HXG_TYPE_RESPONSE_FAILURE:
+	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
 		err = ct_handle_response(ct, msg);
 		break;
 	default:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
index 7072e30e99f4..6a4612a852e2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -16,6 +16,7 @@
 #include "abi/guc_errors_abi.h"
 #include "abi/guc_communication_mmio_abi.h"
 #include "abi/guc_communication_ctb_abi.h"
+#include "abi/guc_klvs_abi.h"
 #include "abi/guc_messages_abi.h"
 
 /* Payload length only i.e. don't include G2H header length */
@@ -84,19 +85,24 @@
 #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
 
 #define GUC_CTL_LOG_PARAMS		0
-#define   GUC_LOG_VALID			(1 << 0)
-#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
-#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
+#define   GUC_LOG_VALID			BIT(0)
+#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
+#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
+#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
 #define   GUC_LOG_CRASH_SHIFT		4
 #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
 #define   GUC_LOG_DEBUG_SHIFT		6
 #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
+#define   GUC_LOG_CAPTURE_SHIFT		10
+#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
 #define   GUC_LOG_BUF_ADDR_SHIFT	12
 
 #define GUC_CTL_WA			1
+#define   GUC_WA_POLLCS                 BIT(18)
+
 #define GUC_CTL_FEATURE			2
-#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
 #define   GUC_CTL_ENABLE_SLPC		BIT(2)
+#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
 
 #define GUC_CTL_DEBUG			3
 #define   GUC_LOG_VERBOSITY_SHIFT	0
@@ -116,6 +122,8 @@
 #define   GUC_ADS_ADDR_SHIFT		1
 #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
 
+#define GUC_CTL_DEVID			5
+
 #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
 
 /* Generic GT SysInfo data types */
@@ -263,7 +271,10 @@ struct guc_mmio_reg {
 	u32 offset;
 	u32 value;
 	u32 flags;
-#define GUC_REGSET_MASKED		(1 << 0)
+	u32 mask;
+#define GUC_REGSET_MASKED		BIT(0)
+#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
+#define GUC_REGSET_RESTORE_ONLY		BIT(3)
 } __packed;
 
 /* GuC register sets */
@@ -280,6 +291,12 @@ struct guc_gt_system_info {
 	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
 } __packed;
 
+enum {
+	GUC_CAPTURE_LIST_INDEX_PF = 0,
+	GUC_CAPTURE_LIST_INDEX_VF = 1,
+	GUC_CAPTURE_LIST_INDEX_MAX = 2,
+};
+
 /* GuC Additional Data Struct */
 struct guc_ads {
 	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
@@ -291,7 +308,11 @@ struct guc_ads {
 	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
 	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
 	u32 private_data;
-	u32 reserved[15];
+	u32 reserved2;
+	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
+	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
+	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
+	u32 reserved[14];
 } __packed;
 
 /* Engine usage stats */
@@ -312,6 +333,7 @@ struct guc_engine_usage {
 enum guc_log_buffer_type {
 	GUC_DEBUG_LOG_BUFFER,
 	GUC_CRASH_DUMP_LOG_BUFFER,
+	GUC_CAPTURE_LOG_BUFFER,
 	GUC_MAX_LOG_BUFFER
 };
 
@@ -342,6 +364,7 @@ struct guc_log_buffer_state {
 	u32 write_ptr;
 	u32 size;
 	u32 sampled_write_ptr;
+	u32 wrap_offset;
 	union {
 		struct {
 			u32 flush_to_file:1;
@@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
 /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
 enum intel_guc_recv_message {
 	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
-	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
+	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
 };
 
 #endif
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
index ac0931f0374b..be35f0570396 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
@@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
 	return intel_guc_send(guc, action, ARRAY_SIZE(action));
 }
 
-static void guc_log_enable_flush_events(struct intel_guc_log *log)
-{
-	intel_guc_enable_msg(log_to_guc(log),
-			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
-}
-
-static void guc_log_disable_flush_events(struct intel_guc_log *log)
-{
-	intel_guc_disable_msg(log_to_guc(log),
-			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
-			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
-}
-
 /*
  * Sub buffer switch callback. Called whenever relay has to switch to a new
  * sub buffer, relay stays on the same sub buffer if 0 is returned.
@@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
 		return DEBUG_BUFFER_SIZE;
 	case GUC_CRASH_DUMP_LOG_BUFFER:
 		return CRASH_BUFFER_SIZE;
+	case GUC_CAPTURE_LOG_BUFFER:
+		return CAPTURE_BUFFER_SIZE;
 	default:
 		MISSING_CASE(type);
 	}
@@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
 	 *  +-------------------------------+ 32B
 	 *  |      Debug state header       |
 	 *  +-------------------------------+ 64B
+	 *  |     Capture state header      |
+	 *  +-------------------------------+ 96B
 	 *  |                               |
 	 *  +===============================+ PAGE_SIZE (4KB)
 	 *  |        Crash Dump logs        |
 	 *  +===============================+ + CRASH_SIZE
 	 *  |          Debug logs           |
 	 *  +===============================+ + DEBUG_SIZE
+	 *  |         Capture logs          |
+	 *  +===============================+ + CAPTURE_SIZE
 	 */
-	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
+	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
+		       CAPTURE_BUFFER_SIZE;
 
 	vma = intel_guc_allocate_vma(guc, guc_log_size);
 	if (IS_ERR(vma)) {
@@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
 	if (log->relay.started)
 		return -EEXIST;
 
-	guc_log_enable_flush_events(log);
-
 	/*
 	 * When GuC is logging without us relaying to userspace, we're ignoring
 	 * the flush notification. This means that we need to unconditionally
@@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
 	if (!log->relay.started)
 		return;
 
-	guc_log_disable_flush_events(log);
 	intel_synchronize_irq(i915);
 
 	flush_work(&log->relay.flush_work);
@@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
 
 void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
 {
-	queue_work(system_highpri_wq, &log->relay.flush_work);
+	if (log->relay.started)
+		queue_work(system_highpri_wq, &log->relay.flush_work);
 }
 
 static const char *
@@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
 		return "DEBUG";
 	case GUC_CRASH_DUMP_LOG_BUFFER:
 		return "CRASH";
+	case GUC_CAPTURE_LOG_BUFFER:
+		return "CAPTURE";
 	default:
 		MISSING_CASE(type);
 	}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
index fe6ab7550a14..d7e1b6471fed 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
@@ -18,12 +18,15 @@ struct intel_guc;
 #if defined(CONFIG_DRM_I915_DEBUG_GUC)
 #define CRASH_BUFFER_SIZE	SZ_2M
 #define DEBUG_BUFFER_SIZE	SZ_16M
+#define CAPTURE_BUFFER_SIZE	SZ_4M
 #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
 #define CRASH_BUFFER_SIZE	SZ_1M
 #define DEBUG_BUFFER_SIZE	SZ_2M
+#define CAPTURE_BUFFER_SIZE	SZ_1M
 #else
 #define CRASH_BUFFER_SIZE	SZ_8K
 #define DEBUG_BUFFER_SIZE	SZ_64K
+#define CAPTURE_BUFFER_SIZE	SZ_16K
 #endif
 
 /*
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index 1f9d4fde421f..4d6c1383f2eb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
 	return 0;
 }
 
+int intel_guc_error_capture_process_msg(struct intel_guc *guc,
+					const u32 *msg, u32 len)
+{
+	int status;
+
+	if (unlikely(len != 1)) {
+		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
+		return -EPROTO;
+	}
+
+	status = msg[0];
+	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
+
+	/* FIXME: Do something with the capture */
+
+	return 0;
+}
+
 static struct intel_engine_cs *
 guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
 {
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
index a7788ce50736..9b82a5a27f90 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * firmware as TGL.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
-	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
-	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
-	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
-	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
-	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
-	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
-	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
-	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
-	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
-	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
-	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
 
 #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
 	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
-- 
2.25.1


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

* [PATCH 5/5] drm/i915/guc: Improve GuC loading status check/error reports
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 18:33   ` John.C.Harrison
  -1 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: John Harrison, DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

If the GuC fails to load, it is useful to know what firmware file /
version was attempted. So move the version info report to before the
load attempt rather than only after a successful load.

If the GuC does fail to load, then make the error messages visible
rather than being 'debug' prints that do not appears in dmesg output
by default.

When waiting for the GuC to load, it used to be necessary to check for
two different states - READY and (LAPIC_DONE | MIA_CORE). Apparently
the second signified init complete on RC6 exit. However, in more
recent GuC versions the RC6 exit sequence now finishes with status
READY as well. So the test can be simplified.

Also, add an enum giving all the current status codes that GuC loading
can report as a reference without having to pull and search through
the GuC source files.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 23 ++++++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     | 17 +++++-----
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |  4 ---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c        |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c         | 31 ++++++++++---------
 5 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index 488b6061ee89..c20658ee85a5 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -11,4 +11,27 @@ enum intel_guc_response_status {
 	INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
 };
 
+enum intel_guc_load_status {
+	INTEL_GUC_LOAD_STATUS_DEFAULT                          = 0x00,
+	INTEL_GUC_LOAD_STATUS_START                            = 0x01,
+	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH       = 0x02,
+	INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH       = 0x03,
+	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE      = 0x04,
+	INTEL_GUC_LOAD_STATUS_GDT_DONE                         = 0x10,
+	INTEL_GUC_LOAD_STATUS_IDT_DONE                         = 0x20,
+	INTEL_GUC_LOAD_STATUS_LAPIC_DONE                       = 0x30,
+	INTEL_GUC_LOAD_STATUS_GUCINT_DONE                      = 0x40,
+	INTEL_GUC_LOAD_STATUS_DPC_READY                        = 0x50,
+	INTEL_GUC_LOAD_STATUS_DPC_ERROR                        = 0x60,
+	INTEL_GUC_LOAD_STATUS_EXCEPTION                        = 0x70,
+	INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID                = 0x71,
+	INTEL_GUC_LOAD_STATUS_PXP_TEARDOWN_CTRL_ENABLED        = 0x72,
+	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START,
+	INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID                 = 0x73,
+	INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID   = 0x74,
+	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
+
+	INTEL_GUC_LOAD_STATUS_READY                            = 0xF0,
+};
+
 #endif /* _ABI_GUC_ERRORS_ABI_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 196424be0998..d3cee01d07e0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -70,11 +70,10 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
 static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
 {
 	u32 val = intel_uncore_read(uncore, GUC_STATUS);
-	u32 uk_val = val & GS_UKERNEL_MASK;
+	u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
 
 	*status = val;
-	return (uk_val == GS_UKERNEL_READY) ||
-		((val & GS_MIA_CORE_STATE) && (uk_val == GS_UKERNEL_LAPIC_DONE));
+	return uk_val == INTEL_GUC_LOAD_STATUS_READY;
 }
 
 static int guc_wait_ucode(struct intel_uncore *uncore)
@@ -94,8 +93,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
 	if (ret) {
 		struct drm_device *drm = &uncore->i915->drm;
 
-		drm_dbg(drm, "GuC load failed: status = 0x%08X\n", status);
-		drm_dbg(drm, "GuC load failed: status: Reset = %d, "
+		drm_info(drm, "GuC load failed: status = 0x%08X\n", status);
+		drm_info(drm, "GuC load failed: status: Reset = %d, "
 			"BootROM = 0x%02X, UKernel = 0x%02X, "
 			"MIA = 0x%02X, Auth = 0x%02X\n",
 			REG_FIELD_GET(GS_MIA_IN_RESET, status),
@@ -105,13 +104,13 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
 			REG_FIELD_GET(GS_AUTH_STATUS_MASK, status));
 
 		if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {
-			drm_dbg(drm, "GuC firmware signature verification failed\n");
+			drm_info(drm, "GuC firmware signature verification failed\n");
 			ret = -ENOEXEC;
 		}
 
-		if ((status & GS_UKERNEL_MASK) == GS_UKERNEL_EXCEPTION) {
-			drm_dbg(drm, "GuC firmware exception. EIP: %#x\n",
-				intel_uncore_read(uncore, SOFT_SCRATCH(13)));
+		if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) {
+			drm_info(drm, "GuC firmware exception. EIP: %#x\n",
+				 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
 			ret = -ENXIO;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
index b37fc2ffaef2..e6bd66d6ce5a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
@@ -22,10 +22,6 @@
 #define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
 #define   GS_UKERNEL_SHIFT		8
 #define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_DPC_ERROR		  (0x60 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_EXCEPTION		  (0x70 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
 #define   GS_MIA_SHIFT			16
 #define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
 #define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ff4b6869b80b..cef406dd937e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -195,6 +195,7 @@ int intel_huc_auth(struct intel_huc *huc)
 	}
 
 	intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
+	drm_info(&gt->i915->drm, "HuC authenticated\n");
 	return 0;
 
 fail:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 2fef3b0bbe95..27b709860afc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -431,6 +431,15 @@ static int __uc_check_hw(struct intel_uc *uc)
 	return 0;
 }
 
+static void print_fw_ver(struct intel_uc *uc, struct intel_uc_fw *fw)
+{
+	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
+
+	drm_info(&i915->drm, "%s firmware %s version %u.%u\n",
+		 intel_uc_fw_type_repr(fw->type), fw->path,
+		 fw->major_ver_found, fw->minor_ver_found);
+}
+
 static int __uc_init_hw(struct intel_uc *uc)
 {
 	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
@@ -441,6 +450,11 @@ static int __uc_init_hw(struct intel_uc *uc)
 	GEM_BUG_ON(!intel_uc_supports_guc(uc));
 	GEM_BUG_ON(!intel_uc_wants_guc(uc));
 
+	print_fw_ver(uc, &guc->fw);
+
+	if (intel_uc_uses_huc(uc))
+		print_fw_ver(uc, &huc->fw);
+
 	if (!intel_uc_fw_is_loadable(&guc->fw)) {
 		ret = __uc_check_hw(uc) ||
 		      intel_uc_fw_is_overridden(&guc->fw) ||
@@ -501,24 +515,11 @@ static int __uc_init_hw(struct intel_uc *uc)
 			goto err_submission;
 	}
 
-	drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
-		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
-		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
-		 "submission",
+	drm_info(&i915->drm, "GuC submission %s\n",
 		 enableddisabled(intel_uc_uses_guc_submission(uc)));
-
-	drm_info(&i915->drm, "GuC SLPC: %s\n",
+	drm_info(&i915->drm, "GuC SLPC %s\n",
 		 enableddisabled(intel_uc_uses_guc_slpc(uc)));
 
-	if (intel_uc_uses_huc(uc)) {
-		drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
-			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
-			 huc->fw.path,
-			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
-			 "authenticated",
-			 yesno(intel_huc_is_authenticated(huc)));
-	}
-
 	return 0;
 
 	/*
-- 
2.25.1


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

* [Intel-gfx] [PATCH 5/5] drm/i915/guc: Improve GuC loading status check/error reports
@ 2021-12-03 18:33   ` John.C.Harrison
  0 siblings, 0 replies; 29+ messages in thread
From: John.C.Harrison @ 2021-12-03 18:33 UTC (permalink / raw)
  To: Intel-GFX; +Cc: DRI-Devel

From: John Harrison <John.C.Harrison@Intel.com>

If the GuC fails to load, it is useful to know what firmware file /
version was attempted. So move the version info report to before the
load attempt rather than only after a successful load.

If the GuC does fail to load, then make the error messages visible
rather than being 'debug' prints that do not appears in dmesg output
by default.

When waiting for the GuC to load, it used to be necessary to check for
two different states - READY and (LAPIC_DONE | MIA_CORE). Apparently
the second signified init complete on RC6 exit. However, in more
recent GuC versions the RC6 exit sequence now finishes with status
READY as well. So the test can be simplified.

Also, add an enum giving all the current status codes that GuC loading
can report as a reference without having to pull and search through
the GuC source files.

Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 23 ++++++++++++++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     | 17 +++++-----
 drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |  4 ---
 drivers/gpu/drm/i915/gt/uc/intel_huc.c        |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.c         | 31 ++++++++++---------
 5 files changed, 48 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
index 488b6061ee89..c20658ee85a5 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
@@ -11,4 +11,27 @@ enum intel_guc_response_status {
 	INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
 };
 
+enum intel_guc_load_status {
+	INTEL_GUC_LOAD_STATUS_DEFAULT                          = 0x00,
+	INTEL_GUC_LOAD_STATUS_START                            = 0x01,
+	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH       = 0x02,
+	INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH       = 0x03,
+	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE      = 0x04,
+	INTEL_GUC_LOAD_STATUS_GDT_DONE                         = 0x10,
+	INTEL_GUC_LOAD_STATUS_IDT_DONE                         = 0x20,
+	INTEL_GUC_LOAD_STATUS_LAPIC_DONE                       = 0x30,
+	INTEL_GUC_LOAD_STATUS_GUCINT_DONE                      = 0x40,
+	INTEL_GUC_LOAD_STATUS_DPC_READY                        = 0x50,
+	INTEL_GUC_LOAD_STATUS_DPC_ERROR                        = 0x60,
+	INTEL_GUC_LOAD_STATUS_EXCEPTION                        = 0x70,
+	INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID                = 0x71,
+	INTEL_GUC_LOAD_STATUS_PXP_TEARDOWN_CTRL_ENABLED        = 0x72,
+	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START,
+	INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID                 = 0x73,
+	INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID   = 0x74,
+	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
+
+	INTEL_GUC_LOAD_STATUS_READY                            = 0xF0,
+};
+
 #endif /* _ABI_GUC_ERRORS_ABI_H */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
index 196424be0998..d3cee01d07e0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -70,11 +70,10 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
 static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
 {
 	u32 val = intel_uncore_read(uncore, GUC_STATUS);
-	u32 uk_val = val & GS_UKERNEL_MASK;
+	u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
 
 	*status = val;
-	return (uk_val == GS_UKERNEL_READY) ||
-		((val & GS_MIA_CORE_STATE) && (uk_val == GS_UKERNEL_LAPIC_DONE));
+	return uk_val == INTEL_GUC_LOAD_STATUS_READY;
 }
 
 static int guc_wait_ucode(struct intel_uncore *uncore)
@@ -94,8 +93,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
 	if (ret) {
 		struct drm_device *drm = &uncore->i915->drm;
 
-		drm_dbg(drm, "GuC load failed: status = 0x%08X\n", status);
-		drm_dbg(drm, "GuC load failed: status: Reset = %d, "
+		drm_info(drm, "GuC load failed: status = 0x%08X\n", status);
+		drm_info(drm, "GuC load failed: status: Reset = %d, "
 			"BootROM = 0x%02X, UKernel = 0x%02X, "
 			"MIA = 0x%02X, Auth = 0x%02X\n",
 			REG_FIELD_GET(GS_MIA_IN_RESET, status),
@@ -105,13 +104,13 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
 			REG_FIELD_GET(GS_AUTH_STATUS_MASK, status));
 
 		if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {
-			drm_dbg(drm, "GuC firmware signature verification failed\n");
+			drm_info(drm, "GuC firmware signature verification failed\n");
 			ret = -ENOEXEC;
 		}
 
-		if ((status & GS_UKERNEL_MASK) == GS_UKERNEL_EXCEPTION) {
-			drm_dbg(drm, "GuC firmware exception. EIP: %#x\n",
-				intel_uncore_read(uncore, SOFT_SCRATCH(13)));
+		if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) {
+			drm_info(drm, "GuC firmware exception. EIP: %#x\n",
+				 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
 			ret = -ENXIO;
 		}
 	}
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
index b37fc2ffaef2..e6bd66d6ce5a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
@@ -22,10 +22,6 @@
 #define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
 #define   GS_UKERNEL_SHIFT		8
 #define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_DPC_ERROR		  (0x60 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_EXCEPTION		  (0x70 << GS_UKERNEL_SHIFT)
-#define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
 #define   GS_MIA_SHIFT			16
 #define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
 #define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ff4b6869b80b..cef406dd937e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -195,6 +195,7 @@ int intel_huc_auth(struct intel_huc *huc)
 	}
 
 	intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
+	drm_info(&gt->i915->drm, "HuC authenticated\n");
 	return 0;
 
 fail:
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 2fef3b0bbe95..27b709860afc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -431,6 +431,15 @@ static int __uc_check_hw(struct intel_uc *uc)
 	return 0;
 }
 
+static void print_fw_ver(struct intel_uc *uc, struct intel_uc_fw *fw)
+{
+	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
+
+	drm_info(&i915->drm, "%s firmware %s version %u.%u\n",
+		 intel_uc_fw_type_repr(fw->type), fw->path,
+		 fw->major_ver_found, fw->minor_ver_found);
+}
+
 static int __uc_init_hw(struct intel_uc *uc)
 {
 	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
@@ -441,6 +450,11 @@ static int __uc_init_hw(struct intel_uc *uc)
 	GEM_BUG_ON(!intel_uc_supports_guc(uc));
 	GEM_BUG_ON(!intel_uc_wants_guc(uc));
 
+	print_fw_ver(uc, &guc->fw);
+
+	if (intel_uc_uses_huc(uc))
+		print_fw_ver(uc, &huc->fw);
+
 	if (!intel_uc_fw_is_loadable(&guc->fw)) {
 		ret = __uc_check_hw(uc) ||
 		      intel_uc_fw_is_overridden(&guc->fw) ||
@@ -501,24 +515,11 @@ static int __uc_init_hw(struct intel_uc *uc)
 			goto err_submission;
 	}
 
-	drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
-		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
-		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
-		 "submission",
+	drm_info(&i915->drm, "GuC submission %s\n",
 		 enableddisabled(intel_uc_uses_guc_submission(uc)));
-
-	drm_info(&i915->drm, "GuC SLPC: %s\n",
+	drm_info(&i915->drm, "GuC SLPC %s\n",
 		 enableddisabled(intel_uc_uses_guc_slpc(uc)));
 
-	if (intel_uc_uses_huc(uc)) {
-		drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
-			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
-			 huc->fw.path,
-			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
-			 "authenticated",
-			 yesno(intel_huc_is_authenticated(huc)));
-	}
-
 	return 0;
 
 	/*
-- 
2.25.1


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

* Re: [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC
  2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 19:01     ` Lucas De Marchi
  -1 siblings, 0 replies; 29+ messages in thread
From: Lucas De Marchi @ 2021-12-03 19:01 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 10:33:35AM -0800, John.C.Harrison@Intel.com wrote:
>From: John Harrison <John.C.Harrison@Intel.com>
>
>It is possible for platforms to require GuC but not HuC firmware.
>Also, the firmware versions for GuC and HuC advance independently. So
>split the macros up to allow the lists to be maintained separately.
>
>Signed-off-by: John Harrison <John.C.Harrison@Intel.com>


Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>

Lucas De Marchi

>---
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 93 ++++++++++++++++--------
> 1 file changed, 63 insertions(+), 30 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>index 3aa87be4f2e4..a7788ce50736 100644
>--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>@@ -48,22 +48,39 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>  * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
>  * firmware as TGL.
>  */
>-#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
>-	fw_def(ALDERLAKE_P, 0, guc_def(adlp, 62, 0, 3), huc_def(tgl, 7, 9, 3)) \
>-	fw_def(ALDERLAKE_S, 0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(DG1,         0, guc_def(dg1, 62, 0, 0), huc_def(dg1,  7, 9, 3)) \
>-	fw_def(ROCKETLAKE,  0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(TIGERLAKE,   0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(JASPERLAKE,  0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
>-	fw_def(ELKHARTLAKE, 0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
>-	fw_def(ICELAKE,     0, guc_def(icl, 62, 0, 0), huc_def(icl,  9, 0, 0)) \
>-	fw_def(COMETLAKE,   5, guc_def(cml, 62, 0, 0), huc_def(cml,  4, 0, 0)) \
>-	fw_def(COMETLAKE,   0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(COFFEELAKE,  0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(GEMINILAKE,  0, guc_def(glk, 62, 0, 0), huc_def(glk,  4, 0, 0)) \
>-	fw_def(KABYLAKE,    0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(BROXTON,     0, guc_def(bxt, 62, 0, 0), huc_def(bxt,  2, 0, 0)) \
>-	fw_def(SKYLAKE,     0, guc_def(skl, 62, 0, 0), huc_def(skl,  2, 0, 0))
>+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
>+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
>+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
>+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
>+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
>+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
>+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
>+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
>+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
>+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
>+
>+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
>+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
>+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
>+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
>+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
>+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
>+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
>+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
>+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))
>
> #define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
> 	"i915/" \
>@@ -79,11 +96,11 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
> 	__MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
>
> /* All blobs need to be declared via MODULE_FIRMWARE() */
>-#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
>-	MODULE_FIRMWARE(guc_); \
>-	MODULE_FIRMWARE(huc_);
>+#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
>+	MODULE_FIRMWARE(uc_);
>
>-INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
>+INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH)
>+INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH)
>
> /* The below structs and macros are used to iterate across the list of blobs */
> struct __packed uc_fw_blob {
>@@ -106,31 +123,47 @@ struct __packed uc_fw_blob {
> struct __packed uc_fw_platform_requirement {
> 	enum intel_platform p;
> 	u8 rev; /* first platform rev using this FW */
>-	const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
>+	const struct uc_fw_blob blob;
> };
>
>-#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
>+#define MAKE_FW_LIST(platform_, revid_, uc_) \
> { \
> 	.p = INTEL_##platform_, \
> 	.rev = revid_, \
>-	.blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
>-	.blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
>+	.blob = uc_, \
> },
>
>+struct fw_blobs_by_type {
>+	const struct uc_fw_platform_requirement *blobs;
>+	u32 count;
>+};
>+
> static void
> __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
> {
>-	static const struct uc_fw_platform_requirement fw_blobs[] = {
>-		INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
>+	static const struct uc_fw_platform_requirement blobs_guc[] = {
>+		INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
>+	};
>+	static const struct uc_fw_platform_requirement blobs_huc[] = {
>+		INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB)
> 	};
>+	static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
>+		[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
>+		[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
>+	};
>+	static const struct uc_fw_platform_requirement *fw_blobs;
> 	enum intel_platform p = INTEL_INFO(i915)->platform;
>+	u32 fw_count;
> 	u8 rev = INTEL_REVID(i915);
> 	int i;
>
>-	for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
>+	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
>+	fw_blobs = blobs_all[uc_fw->type].blobs;
>+	fw_count = blobs_all[uc_fw->type].count;
>+
>+	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
> 		if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
>-			const struct uc_fw_blob *blob =
>-					&fw_blobs[i].blobs[uc_fw->type];
>+			const struct uc_fw_blob *blob = &fw_blobs[i].blob;
> 			uc_fw->path = blob->path;
> 			uc_fw->major_ver_wanted = blob->major;
> 			uc_fw->minor_ver_wanted = blob->minor;
>@@ -140,7 +173,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
>
> 	/* make sure the list is ordered as expected */
> 	if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
>-		for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
>+		for (i = 1; i < fw_count; i++) {
> 			if (fw_blobs[i].p < fw_blobs[i - 1].p)
> 				continue;
>
>-- 
>2.25.1
>

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

* Re: [Intel-gfx] [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC
@ 2021-12-03 19:01     ` Lucas De Marchi
  0 siblings, 0 replies; 29+ messages in thread
From: Lucas De Marchi @ 2021-12-03 19:01 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 10:33:35AM -0800, John.C.Harrison@Intel.com wrote:
>From: John Harrison <John.C.Harrison@Intel.com>
>
>It is possible for platforms to require GuC but not HuC firmware.
>Also, the firmware versions for GuC and HuC advance independently. So
>split the macros up to allow the lists to be maintained separately.
>
>Signed-off-by: John Harrison <John.C.Harrison@Intel.com>


Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>

Lucas De Marchi

>---
> drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 93 ++++++++++++++++--------
> 1 file changed, 63 insertions(+), 30 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>index 3aa87be4f2e4..a7788ce50736 100644
>--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
>@@ -48,22 +48,39 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>  * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
>  * firmware as TGL.
>  */
>-#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
>-	fw_def(ALDERLAKE_P, 0, guc_def(adlp, 62, 0, 3), huc_def(tgl, 7, 9, 3)) \
>-	fw_def(ALDERLAKE_S, 0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(DG1,         0, guc_def(dg1, 62, 0, 0), huc_def(dg1,  7, 9, 3)) \
>-	fw_def(ROCKETLAKE,  0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(TIGERLAKE,   0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
>-	fw_def(JASPERLAKE,  0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
>-	fw_def(ELKHARTLAKE, 0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
>-	fw_def(ICELAKE,     0, guc_def(icl, 62, 0, 0), huc_def(icl,  9, 0, 0)) \
>-	fw_def(COMETLAKE,   5, guc_def(cml, 62, 0, 0), huc_def(cml,  4, 0, 0)) \
>-	fw_def(COMETLAKE,   0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(COFFEELAKE,  0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(GEMINILAKE,  0, guc_def(glk, 62, 0, 0), huc_def(glk,  4, 0, 0)) \
>-	fw_def(KABYLAKE,    0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
>-	fw_def(BROXTON,     0, guc_def(bxt, 62, 0, 0), huc_def(bxt,  2, 0, 0)) \
>-	fw_def(SKYLAKE,     0, guc_def(skl, 62, 0, 0), huc_def(skl,  2, 0, 0))
>+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
>+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
>+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
>+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
>+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
>+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
>+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
>+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
>+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
>+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
>+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
>+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
>+
>+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
>+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
>+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
>+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
>+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
>+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
>+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
>+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
>+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
>+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
>+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))
>
> #define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
> 	"i915/" \
>@@ -79,11 +96,11 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
> 	__MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
>
> /* All blobs need to be declared via MODULE_FIRMWARE() */
>-#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
>-	MODULE_FIRMWARE(guc_); \
>-	MODULE_FIRMWARE(huc_);
>+#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
>+	MODULE_FIRMWARE(uc_);
>
>-INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
>+INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH)
>+INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH)
>
> /* The below structs and macros are used to iterate across the list of blobs */
> struct __packed uc_fw_blob {
>@@ -106,31 +123,47 @@ struct __packed uc_fw_blob {
> struct __packed uc_fw_platform_requirement {
> 	enum intel_platform p;
> 	u8 rev; /* first platform rev using this FW */
>-	const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
>+	const struct uc_fw_blob blob;
> };
>
>-#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
>+#define MAKE_FW_LIST(platform_, revid_, uc_) \
> { \
> 	.p = INTEL_##platform_, \
> 	.rev = revid_, \
>-	.blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
>-	.blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
>+	.blob = uc_, \
> },
>
>+struct fw_blobs_by_type {
>+	const struct uc_fw_platform_requirement *blobs;
>+	u32 count;
>+};
>+
> static void
> __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
> {
>-	static const struct uc_fw_platform_requirement fw_blobs[] = {
>-		INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
>+	static const struct uc_fw_platform_requirement blobs_guc[] = {
>+		INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
>+	};
>+	static const struct uc_fw_platform_requirement blobs_huc[] = {
>+		INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB)
> 	};
>+	static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
>+		[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
>+		[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
>+	};
>+	static const struct uc_fw_platform_requirement *fw_blobs;
> 	enum intel_platform p = INTEL_INFO(i915)->platform;
>+	u32 fw_count;
> 	u8 rev = INTEL_REVID(i915);
> 	int i;
>
>-	for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
>+	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
>+	fw_blobs = blobs_all[uc_fw->type].blobs;
>+	fw_count = blobs_all[uc_fw->type].count;
>+
>+	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
> 		if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
>-			const struct uc_fw_blob *blob =
>-					&fw_blobs[i].blobs[uc_fw->type];
>+			const struct uc_fw_blob *blob = &fw_blobs[i].blob;
> 			uc_fw->path = blob->path;
> 			uc_fw->major_ver_wanted = blob->major;
> 			uc_fw->minor_ver_wanted = blob->minor;
>@@ -140,7 +173,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
>
> 	/* make sure the list is ordered as expected */
> 	if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
>-		for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
>+		for (i = 1; i < fw_count; i++) {
> 			if (fw_blobs[i].p < fw_blobs[i - 1].p)
> 				continue;
>
>-- 
>2.25.1
>

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

* Re: [PATCH 5/5] drm/i915/guc: Improve GuC loading status check/error reports
  2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 20:22     ` Matthew Brost
  -1 siblings, 0 replies; 29+ messages in thread
From: Matthew Brost @ 2021-12-03 20:22 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 10:33:39AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> If the GuC fails to load, it is useful to know what firmware file /
> version was attempted. So move the version info report to before the
> load attempt rather than only after a successful load.
> 
> If the GuC does fail to load, then make the error messages visible
> rather than being 'debug' prints that do not appears in dmesg output
> by default.
> 
> When waiting for the GuC to load, it used to be necessary to check for
> two different states - READY and (LAPIC_DONE | MIA_CORE). Apparently
> the second signified init complete on RC6 exit. However, in more
> recent GuC versions the RC6 exit sequence now finishes with status
> READY as well. So the test can be simplified.
> 
> Also, add an enum giving all the current status codes that GuC loading
> can report as a reference without having to pull and search through
> the GuC source files.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 23 ++++++++++++++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     | 17 +++++-----
>  drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |  4 ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c        |  1 +
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c         | 31 ++++++++++---------
>  5 files changed, 48 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> index 488b6061ee89..c20658ee85a5 100644
> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> @@ -11,4 +11,27 @@ enum intel_guc_response_status {
>  	INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
>  };
>  
> +enum intel_guc_load_status {
> +	INTEL_GUC_LOAD_STATUS_DEFAULT                          = 0x00,
> +	INTEL_GUC_LOAD_STATUS_START                            = 0x01,
> +	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH       = 0x02,
> +	INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH       = 0x03,
> +	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE      = 0x04,
> +	INTEL_GUC_LOAD_STATUS_GDT_DONE                         = 0x10,
> +	INTEL_GUC_LOAD_STATUS_IDT_DONE                         = 0x20,
> +	INTEL_GUC_LOAD_STATUS_LAPIC_DONE                       = 0x30,
> +	INTEL_GUC_LOAD_STATUS_GUCINT_DONE                      = 0x40,
> +	INTEL_GUC_LOAD_STATUS_DPC_READY                        = 0x50,
> +	INTEL_GUC_LOAD_STATUS_DPC_ERROR                        = 0x60,
> +	INTEL_GUC_LOAD_STATUS_EXCEPTION                        = 0x70,
> +	INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID                = 0x71,
> +	INTEL_GUC_LOAD_STATUS_PXP_TEARDOWN_CTRL_ENABLED        = 0x72,
> +	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START,
> +	INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID                 = 0x73,
> +	INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID   = 0x74,
> +	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
> +
> +	INTEL_GUC_LOAD_STATUS_READY                            = 0xF0,
> +};
> +
>  #endif /* _ABI_GUC_ERRORS_ABI_H */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> index 196424be0998..d3cee01d07e0 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> @@ -70,11 +70,10 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
>  static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
>  {
>  	u32 val = intel_uncore_read(uncore, GUC_STATUS);
> -	u32 uk_val = val & GS_UKERNEL_MASK;
> +	u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
>  
>  	*status = val;
> -	return (uk_val == GS_UKERNEL_READY) ||
> -		((val & GS_MIA_CORE_STATE) && (uk_val == GS_UKERNEL_LAPIC_DONE));
> +	return uk_val == INTEL_GUC_LOAD_STATUS_READY;
>  }
>  
>  static int guc_wait_ucode(struct intel_uncore *uncore)
> @@ -94,8 +93,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
>  	if (ret) {
>  		struct drm_device *drm = &uncore->i915->drm;
>  
> -		drm_dbg(drm, "GuC load failed: status = 0x%08X\n", status);
> -		drm_dbg(drm, "GuC load failed: status: Reset = %d, "
> +		drm_info(drm, "GuC load failed: status = 0x%08X\n", status);
> +		drm_info(drm, "GuC load failed: status: Reset = %d, "
>  			"BootROM = 0x%02X, UKernel = 0x%02X, "
>  			"MIA = 0x%02X, Auth = 0x%02X\n",
>  			REG_FIELD_GET(GS_MIA_IN_RESET, status),
> @@ -105,13 +104,13 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
>  			REG_FIELD_GET(GS_AUTH_STATUS_MASK, status));
>  
>  		if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {
> -			drm_dbg(drm, "GuC firmware signature verification failed\n");
> +			drm_info(drm, "GuC firmware signature verification failed\n");
>  			ret = -ENOEXEC;
>  		}
>  
> -		if ((status & GS_UKERNEL_MASK) == GS_UKERNEL_EXCEPTION) {
> -			drm_dbg(drm, "GuC firmware exception. EIP: %#x\n",
> -				intel_uncore_read(uncore, SOFT_SCRATCH(13)));
> +		if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) {
> +			drm_info(drm, "GuC firmware exception. EIP: %#x\n",
> +				 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
>  			ret = -ENXIO;
>  		}
>  	}
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> index b37fc2ffaef2..e6bd66d6ce5a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> @@ -22,10 +22,6 @@
>  #define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
>  #define   GS_UKERNEL_SHIFT		8
>  #define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_DPC_ERROR		  (0x60 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_EXCEPTION		  (0x70 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
>  #define   GS_MIA_SHIFT			16
>  #define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
>  #define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index ff4b6869b80b..cef406dd937e 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -195,6 +195,7 @@ int intel_huc_auth(struct intel_huc *huc)
>  	}
>  
>  	intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
> +	drm_info(&gt->i915->drm, "HuC authenticated\n");
>  	return 0;
>  
>  fail:
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index 2fef3b0bbe95..27b709860afc 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -431,6 +431,15 @@ static int __uc_check_hw(struct intel_uc *uc)
>  	return 0;
>  }
>  
> +static void print_fw_ver(struct intel_uc *uc, struct intel_uc_fw *fw)
> +{
> +	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
> +
> +	drm_info(&i915->drm, "%s firmware %s version %u.%u\n",
> +		 intel_uc_fw_type_repr(fw->type), fw->path,
> +		 fw->major_ver_found, fw->minor_ver_found);
> +}
> +
>  static int __uc_init_hw(struct intel_uc *uc)
>  {
>  	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
> @@ -441,6 +450,11 @@ static int __uc_init_hw(struct intel_uc *uc)
>  	GEM_BUG_ON(!intel_uc_supports_guc(uc));
>  	GEM_BUG_ON(!intel_uc_wants_guc(uc));
>  
> +	print_fw_ver(uc, &guc->fw);
> +
> +	if (intel_uc_uses_huc(uc))
> +		print_fw_ver(uc, &huc->fw);
> +
>  	if (!intel_uc_fw_is_loadable(&guc->fw)) {
>  		ret = __uc_check_hw(uc) ||
>  		      intel_uc_fw_is_overridden(&guc->fw) ||
> @@ -501,24 +515,11 @@ static int __uc_init_hw(struct intel_uc *uc)
>  			goto err_submission;
>  	}
>  
> -	drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
> -		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
> -		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
> -		 "submission",
> +	drm_info(&i915->drm, "GuC submission %s\n",
>  		 enableddisabled(intel_uc_uses_guc_submission(uc)));
> -
> -	drm_info(&i915->drm, "GuC SLPC: %s\n",
> +	drm_info(&i915->drm, "GuC SLPC %s\n",
>  		 enableddisabled(intel_uc_uses_guc_slpc(uc)));
>  
> -	if (intel_uc_uses_huc(uc)) {
> -		drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
> -			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
> -			 huc->fw.path,
> -			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
> -			 "authenticated",
> -			 yesno(intel_huc_is_authenticated(huc)));
> -	}
> -
>  	return 0;
>  
>  	/*
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [PATCH 5/5] drm/i915/guc: Improve GuC loading status check/error reports
@ 2021-12-03 20:22     ` Matthew Brost
  0 siblings, 0 replies; 29+ messages in thread
From: Matthew Brost @ 2021-12-03 20:22 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 10:33:39AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> If the GuC fails to load, it is useful to know what firmware file /
> version was attempted. So move the version info report to before the
> load attempt rather than only after a successful load.
> 
> If the GuC does fail to load, then make the error messages visible
> rather than being 'debug' prints that do not appears in dmesg output
> by default.
> 
> When waiting for the GuC to load, it used to be necessary to check for
> two different states - READY and (LAPIC_DONE | MIA_CORE). Apparently
> the second signified init complete on RC6 exit. However, in more
> recent GuC versions the RC6 exit sequence now finishes with status
> READY as well. So the test can be simplified.
> 
> Also, add an enum giving all the current status codes that GuC loading
> can report as a reference without having to pull and search through
> the GuC source files.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   | 23 ++++++++++++++
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c     | 17 +++++-----
>  drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h    |  4 ---
>  drivers/gpu/drm/i915/gt/uc/intel_huc.c        |  1 +
>  drivers/gpu/drm/i915/gt/uc/intel_uc.c         | 31 ++++++++++---------
>  5 files changed, 48 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> index 488b6061ee89..c20658ee85a5 100644
> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h
> @@ -11,4 +11,27 @@ enum intel_guc_response_status {
>  	INTEL_GUC_RESPONSE_STATUS_GENERIC_FAIL = 0xF000,
>  };
>  
> +enum intel_guc_load_status {
> +	INTEL_GUC_LOAD_STATUS_DEFAULT                          = 0x00,
> +	INTEL_GUC_LOAD_STATUS_START                            = 0x01,
> +	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_BUILD_MISMATCH       = 0x02,
> +	INTEL_GUC_LOAD_STATUS_GUC_PREPROD_BUILD_MISMATCH       = 0x03,
> +	INTEL_GUC_LOAD_STATUS_ERROR_DEVID_INVALID_GUCTYPE      = 0x04,
> +	INTEL_GUC_LOAD_STATUS_GDT_DONE                         = 0x10,
> +	INTEL_GUC_LOAD_STATUS_IDT_DONE                         = 0x20,
> +	INTEL_GUC_LOAD_STATUS_LAPIC_DONE                       = 0x30,
> +	INTEL_GUC_LOAD_STATUS_GUCINT_DONE                      = 0x40,
> +	INTEL_GUC_LOAD_STATUS_DPC_READY                        = 0x50,
> +	INTEL_GUC_LOAD_STATUS_DPC_ERROR                        = 0x60,
> +	INTEL_GUC_LOAD_STATUS_EXCEPTION                        = 0x70,
> +	INTEL_GUC_LOAD_STATUS_INIT_DATA_INVALID                = 0x71,
> +	INTEL_GUC_LOAD_STATUS_PXP_TEARDOWN_CTRL_ENABLED        = 0x72,
> +	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_START,
> +	INTEL_GUC_LOAD_STATUS_MPU_DATA_INVALID                 = 0x73,
> +	INTEL_GUC_LOAD_STATUS_INIT_MMIO_SAVE_RESTORE_INVALID   = 0x74,
> +	INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
> +
> +	INTEL_GUC_LOAD_STATUS_READY                            = 0xF0,
> +};
> +
>  #endif /* _ABI_GUC_ERRORS_ABI_H */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> index 196424be0998..d3cee01d07e0 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
> @@ -70,11 +70,10 @@ static int guc_xfer_rsa(struct intel_uc_fw *guc_fw,
>  static inline bool guc_ready(struct intel_uncore *uncore, u32 *status)
>  {
>  	u32 val = intel_uncore_read(uncore, GUC_STATUS);
> -	u32 uk_val = val & GS_UKERNEL_MASK;
> +	u32 uk_val = REG_FIELD_GET(GS_UKERNEL_MASK, val);
>  
>  	*status = val;
> -	return (uk_val == GS_UKERNEL_READY) ||
> -		((val & GS_MIA_CORE_STATE) && (uk_val == GS_UKERNEL_LAPIC_DONE));
> +	return uk_val == INTEL_GUC_LOAD_STATUS_READY;
>  }
>  
>  static int guc_wait_ucode(struct intel_uncore *uncore)
> @@ -94,8 +93,8 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
>  	if (ret) {
>  		struct drm_device *drm = &uncore->i915->drm;
>  
> -		drm_dbg(drm, "GuC load failed: status = 0x%08X\n", status);
> -		drm_dbg(drm, "GuC load failed: status: Reset = %d, "
> +		drm_info(drm, "GuC load failed: status = 0x%08X\n", status);
> +		drm_info(drm, "GuC load failed: status: Reset = %d, "
>  			"BootROM = 0x%02X, UKernel = 0x%02X, "
>  			"MIA = 0x%02X, Auth = 0x%02X\n",
>  			REG_FIELD_GET(GS_MIA_IN_RESET, status),
> @@ -105,13 +104,13 @@ static int guc_wait_ucode(struct intel_uncore *uncore)
>  			REG_FIELD_GET(GS_AUTH_STATUS_MASK, status));
>  
>  		if ((status & GS_BOOTROM_MASK) == GS_BOOTROM_RSA_FAILED) {
> -			drm_dbg(drm, "GuC firmware signature verification failed\n");
> +			drm_info(drm, "GuC firmware signature verification failed\n");
>  			ret = -ENOEXEC;
>  		}
>  
> -		if ((status & GS_UKERNEL_MASK) == GS_UKERNEL_EXCEPTION) {
> -			drm_dbg(drm, "GuC firmware exception. EIP: %#x\n",
> -				intel_uncore_read(uncore, SOFT_SCRATCH(13)));
> +		if (REG_FIELD_GET(GS_UKERNEL_MASK, status) == INTEL_GUC_LOAD_STATUS_EXCEPTION) {
> +			drm_info(drm, "GuC firmware exception. EIP: %#x\n",
> +				 intel_uncore_read(uncore, SOFT_SCRATCH(13)));
>  			ret = -ENXIO;
>  		}
>  	}
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> index b37fc2ffaef2..e6bd66d6ce5a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_reg.h
> @@ -22,10 +22,6 @@
>  #define   GS_BOOTROM_JUMP_PASSED	  (0x76 << GS_BOOTROM_SHIFT)
>  #define   GS_UKERNEL_SHIFT		8
>  #define   GS_UKERNEL_MASK		  (0xFF << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_LAPIC_DONE		  (0x30 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_DPC_ERROR		  (0x60 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_EXCEPTION		  (0x70 << GS_UKERNEL_SHIFT)
> -#define   GS_UKERNEL_READY		  (0xF0 << GS_UKERNEL_SHIFT)
>  #define   GS_MIA_SHIFT			16
>  #define   GS_MIA_MASK			  (0x07 << GS_MIA_SHIFT)
>  #define   GS_MIA_CORE_STATE		  (0x01 << GS_MIA_SHIFT)
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> index ff4b6869b80b..cef406dd937e 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
> @@ -195,6 +195,7 @@ int intel_huc_auth(struct intel_huc *huc)
>  	}
>  
>  	intel_uc_fw_change_status(&huc->fw, INTEL_UC_FIRMWARE_RUNNING);
> +	drm_info(&gt->i915->drm, "HuC authenticated\n");
>  	return 0;
>  
>  fail:
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> index 2fef3b0bbe95..27b709860afc 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
> @@ -431,6 +431,15 @@ static int __uc_check_hw(struct intel_uc *uc)
>  	return 0;
>  }
>  
> +static void print_fw_ver(struct intel_uc *uc, struct intel_uc_fw *fw)
> +{
> +	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
> +
> +	drm_info(&i915->drm, "%s firmware %s version %u.%u\n",
> +		 intel_uc_fw_type_repr(fw->type), fw->path,
> +		 fw->major_ver_found, fw->minor_ver_found);
> +}
> +
>  static int __uc_init_hw(struct intel_uc *uc)
>  {
>  	struct drm_i915_private *i915 = uc_to_gt(uc)->i915;
> @@ -441,6 +450,11 @@ static int __uc_init_hw(struct intel_uc *uc)
>  	GEM_BUG_ON(!intel_uc_supports_guc(uc));
>  	GEM_BUG_ON(!intel_uc_wants_guc(uc));
>  
> +	print_fw_ver(uc, &guc->fw);
> +
> +	if (intel_uc_uses_huc(uc))
> +		print_fw_ver(uc, &huc->fw);
> +
>  	if (!intel_uc_fw_is_loadable(&guc->fw)) {
>  		ret = __uc_check_hw(uc) ||
>  		      intel_uc_fw_is_overridden(&guc->fw) ||
> @@ -501,24 +515,11 @@ static int __uc_init_hw(struct intel_uc *uc)
>  			goto err_submission;
>  	}
>  
> -	drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
> -		 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_GUC), guc->fw.path,
> -		 guc->fw.major_ver_found, guc->fw.minor_ver_found,
> -		 "submission",
> +	drm_info(&i915->drm, "GuC submission %s\n",
>  		 enableddisabled(intel_uc_uses_guc_submission(uc)));
> -
> -	drm_info(&i915->drm, "GuC SLPC: %s\n",
> +	drm_info(&i915->drm, "GuC SLPC %s\n",
>  		 enableddisabled(intel_uc_uses_guc_slpc(uc)));
>  
> -	if (intel_uc_uses_huc(uc)) {
> -		drm_info(&i915->drm, "%s firmware %s version %u.%u %s:%s\n",
> -			 intel_uc_fw_type_repr(INTEL_UC_FW_TYPE_HUC),
> -			 huc->fw.path,
> -			 huc->fw.major_ver_found, huc->fw.minor_ver_found,
> -			 "authenticated",
> -			 yesno(intel_huc_is_authenticated(huc)));
> -	}
> -
>  	return 0;
>  
>  	/*
> -- 
> 2.25.1
> 

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

* Re: [Intel-gfx] [PATCH 2/5] drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
  2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
  (?)
@ 2021-12-03 20:25   ` Matthew Brost
  -1 siblings, 0 replies; 29+ messages in thread
From: Matthew Brost @ 2021-12-03 20:25 UTC (permalink / raw)
  To: John.C.Harrison; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 10:33:36AM -0800, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Lots of testing is done with the DEBUG_GEM config option enabled but
> not the DEBUG_GUC option. That means we only get teeny-tiny GuC logs
> which are not hugely useful. Enabling full DEBUG_GUC also spews lots
> of other detailed output that is not generally desired. However,
> bigger GuC logs are extremely useful for almost any regression debug.
> So enable bigger logs for DEBUG_GEM builds as well.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> ---
>  drivers/gpu/drm/i915/gt/uc/intel_guc_log.h | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> index ac1ee1d5ce10..fe6ab7550a14 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> @@ -15,9 +15,12 @@
>  
>  struct intel_guc;
>  
> -#ifdef CONFIG_DRM_I915_DEBUG_GUC
> +#if defined(CONFIG_DRM_I915_DEBUG_GUC)
>  #define CRASH_BUFFER_SIZE	SZ_2M
>  #define DEBUG_BUFFER_SIZE	SZ_16M
> +#elif defined(CONFIG_DRM_I915_DEBUG_GEM)
> +#define CRASH_BUFFER_SIZE	SZ_1M
> +#define DEBUG_BUFFER_SIZE	SZ_2M
>  #else
>  #define CRASH_BUFFER_SIZE	SZ_8K
>  #define DEBUG_BUFFER_SIZE	SZ_64K
> -- 
> 2.25.1
> 

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

* [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
                   ` (5 preceding siblings ...)
  (?)
@ 2021-12-03 22:22 ` Patchwork
  -1 siblings, 0 replies; 29+ messages in thread
From: Patchwork @ 2021-12-03 22:22 UTC (permalink / raw)
  To: john.c.harrison; +Cc: intel-gfx

== Series Details ==

Series: Update to GuC version 69.0.0
URL   : https://patchwork.freedesktop.org/series/97564/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
1ba090939f4f drm/i915/uc: Allow platforms to have GuC but not HuC
-:37: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#37: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:51:
+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))

-:37: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'fw_def' - possible side-effects?
#37: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:51:
+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))

-:37: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'guc_def' - possible side-effects?
#37: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:51:
+#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
+	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
+	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
+	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
+	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
+	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
+	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
+	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
+	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
+	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
+	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))

-:54: ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#54: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:68:
+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))

-:54: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'fw_def' - possible side-effects?
#54: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:68:
+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))

-:54: CHECK:MACRO_ARG_REUSE: Macro argument reuse 'huc_def' - possible side-effects?
#54: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:68:
+#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
+	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
+	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
+	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
+	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
+	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
+	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
+	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
+	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
+	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))

-:80: WARNING:TRAILING_SEMICOLON: macros should not use a trailing semicolon
#80: FILE: drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c:99:
+#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
+	MODULE_FIRMWARE(uc_);

total: 2 errors, 1 warnings, 4 checks, 134 lines checked
0c27c3d306db drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
dcbfeb6078aa drm/i915/guc: Don't go bang in GuC log if no GuC
b1173763d5c2 drm/i915/guc: Update to GuC version 69.0.0
-:135: CHECK:CAMELCASE: Avoid CamelCase: <GUC_HXG_REQUEST_MSG_n_DATAn>
#135: FILE: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h:55:
+#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn

-:212: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#212: 
new file mode 100644

total: 0 errors, 1 warnings, 1 checks, 1010 lines checked
25e36b6914e2 drm/i915/guc: Improve GuC loading status check/error reports



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

* [Intel-gfx] ✗ Fi.CI.SPARSE: warning for Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
                   ` (6 preceding siblings ...)
  (?)
@ 2021-12-03 22:23 ` Patchwork
  -1 siblings, 0 replies; 29+ messages in thread
From: Patchwork @ 2021-12-03 22:23 UTC (permalink / raw)
  To: john.c.harrison; +Cc: intel-gfx

== Series Details ==

Series: Update to GuC version 69.0.0
URL   : https://patchwork.freedesktop.org/series/97564/
State : warning

== Summary ==

$ dim sparse --fast origin/drm-tip
Sparse version: v0.6.2
Fast mode used, each commit won't be checked separately.



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

* [Intel-gfx] ✗ Fi.CI.DOCS: warning for Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
                   ` (7 preceding siblings ...)
  (?)
@ 2021-12-03 22:27 ` Patchwork
  2021-12-06 19:29   ` John Harrison
  -1 siblings, 1 reply; 29+ messages in thread
From: Patchwork @ 2021-12-03 22:27 UTC (permalink / raw)
  To: john.c.harrison; +Cc: intel-gfx

== Series Details ==

Series: Update to GuC version 69.0.0
URL   : https://patchwork.freedesktop.org/series/97564/
State : warning

== Summary ==

$ make htmldocs 2>&1 > /dev/null | grep i915
/home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:44: WARNING: Inline target start-string without end-string.
/home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:48: WARNING: Inline target start-string without end-string.
/home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:52: WARNING: Inline target start-string without end-string.



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

* Re: [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
  2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
@ 2021-12-03 22:28     ` Michal Wajdeczko
  -1 siblings, 0 replies; 29+ messages in thread
From: Michal Wajdeczko @ 2021-12-03 22:28 UTC (permalink / raw)
  To: John.C.Harrison, Intel-GFX; +Cc: DRI-Devel



On 03.12.2021 19:33, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Update to the latest GuC release.
> 
> The latest GuC firmware introduces a number of interface changes:

Why can't we review all these changes in smaller patches and squash them
in separate CI series *after* collecting all required r-b ?

Michal

> 
> GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
> Add support for this reply and try resending the request again as a
> new CTB message.
> 
> A KLV (key-length-value) mechanism is now used for passing
> configuration data such as CTB management.
> 
> With the new KLV scheme, the old CTB management actions are no longer
> used and are removed.
> 
> Register capture on hang is now supported by GuC. Full i915 support
> for this will be added by a later patch. A minimum support of
> providing capture memory and register lists is required though, so add
> that in.
> 
> The device id of the current platform needs to be provided at init time.
> 
> The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
> versions of GuC. It must now be explicitly requested by the KMD. So,
> add in the code to turn it on when relevant.
> 
> The GuC log entry format has changed. This requires adding a new field
> to the log header structure to mark the wrap point at the end of the
> buffer (as the buffer size is no longer a multiple of the log entry
> size).
> 
> New CTB notification messages are now sent for some things that were
> previously only sent via MMIO notifications.
> 
> Of these, the crash dump notification was not really being handled by
> i915. It called the log flush code but that only flushed the regular
> debug log and then only if relay logging was enabled. So just report
> an error message instead.
> 
> The 'exception' notification was just being ignored completely. So add
> an error message for that as well.
> 
> Note that in either the crash dump or the exception case, the GuC is
> basically dead. The KMD will detect this via the heartbeat and trigger
> both an error log (which will include the crash dump as part of the
> GuC log) and a GT reset. So no other processing is really required.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> ---
>  Documentation/gpu/i915.rst                    |   1 +
>  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
>  drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
>  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
>  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
>  12 files changed, 434 insertions(+), 164 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> 
> diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> index b7d801993bfa..bcaefc952764 100644
> --- a/Documentation/gpu/i915.rst
> +++ b/Documentation/gpu/i915.rst
> @@ -539,6 +539,7 @@ GuC ABI
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> +.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
>  
>  HuC
>  ---
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> index fe5d7d261797..7afdadc7656f 100644
> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> @@ -7,9 +7,9 @@
>  #define _ABI_GUC_ACTIONS_ABI_H
>  
>  /**
> - * DOC: HOST2GUC_REGISTER_CTB
> + * DOC: HOST2GUC_SELF_CFG
>   *
> - * This message is used as part of the `CTB based communication`_ setup.
> + * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
>   *
>   * This message must be sent as `MMIO HXG Message`_.
>   *
> @@ -22,20 +22,18 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 27:16 | DATA0 = MBZ                                                  |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
> + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> + *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
> + *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
>   *  |   |       |                                                              |
> - *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
> - *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
> + *  |   |       |   - 32 bit KLV = 1                                           |
> + *  |   |       |   - 64 bit KLV = 2                                           |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
> + *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
> + *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
>   *  +---+-------+--------------------------------------------------------------+
>   *
>   *  +---+-------+--------------------------------------------------------------+
> @@ -45,28 +43,25 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  27:0 | DATA0 = MBZ                                                  |
> + *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
>   *  +---+-------+--------------------------------------------------------------+
>   */
> -#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
> +#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
>  
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> -#define   GUC_CTB_TYPE_HOST2GUC				0u
> -#define   GUC_CTB_TYPE_GUC2HOST				1u
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
>  
> -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
>  
>  /**
> - * DOC: HOST2GUC_DEREGISTER_CTB
> + * DOC: HOST2GUC_CONTROL_CTB
>   *
> - * This message is used as part of the `CTB based communication`_ teardown.
> + * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
>   *
>   * This message must be sent as `MMIO HXG Message`_.
>   *
> @@ -79,15 +74,12 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 27:16 | DATA0 = MBZ                                                  |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
> + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
> + *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
>   *  |   |       |                                                              |
> - *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |   7:0 | RESERVED = MBZ                                               |
> + *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
> + *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
>   *  +---+-------+--------------------------------------------------------------+
>   *
>   *  +---+-------+--------------------------------------------------------------+
> @@ -100,16 +92,16 @@
>   *  |   |  27:0 | DATA0 = MBZ                                                  |
>   *  +---+-------+--------------------------------------------------------------+
>   */
> -#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
> +#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
>  
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
> +#define   GUC_CTB_CONTROL_DISABLE			0u
> +#define   GUC_CTB_CONTROL_ENABLE			1u
>  
> -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
> -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
>  
>  /* legacy definitions */
>  
> @@ -143,8 +135,12 @@ enum intel_guc_action {
>  	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
>  	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
>  	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
> -	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
> +	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
>  	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
> +	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
> +	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
> +	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
> +	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
>  	INTEL_GUC_ACTION_LIMIT
>  };
>  
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> new file mode 100644
> index 000000000000..3dda88a44fc6
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#ifndef _ABI_GUC_KLVS_ABI_H
> +#define _ABI_GUC_KLVS_ABI_H
> +
> +/**
> + * DOC: GuC KLV
> + *
> + *  +---+-------+--------------------------------------------------------------+
> + *  |   | Bits  | Description                                                  |
> + *  +===+=======+==============================================================+
> + *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
> + *  |   |       |   - `GuC Self Config KLVs`_                                  |
> + *  |   |       |                                                              |
> + *  |   +-------+--------------------------------------------------------------+
> + *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
> + *  +---+-------+--------------------------------------------------------------+
> + *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
> + *  +---+-------+                                                              |
> + *  |...|       |                                                              |
> + *  +---+-------+                                                              |
> + *  | n |  31:0 |                                                              |
> + *  +---+-------+--------------------------------------------------------------+
> + */
> +
> +#define GUC_KLV_LEN_MIN				1u
> +#define GUC_KLV_0_KEY				(0xffff << 16)
> +#define GUC_KLV_0_LEN				(0xffff << 0)
> +#define GUC_KLV_n_VALUE				(0xffffffff << 0)
> +
> +/**
> + * DOC: GuC Self Config KLVs
> + *
> + * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
> + *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
> + *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
> + *      Refers to size of H2G `CT Buffer`_ in bytes.
> + *      Should be a multiple of 4K.
> + *
> + * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
> + *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
> + *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
> + *      Refers to size of G2H `CT Buffer`_ in bytes.
> + *      Should be a multiple of 4K.
> + */
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
> +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
> +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
> +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
> +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
> +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
> +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
> +
> +#endif /* _ABI_GUC_KLVS_ABI_H */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> index 6e228343e8cb..cbec51f4dec3 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> @@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
>  		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
>  		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
>  	}
> +
> +	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
> +				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
>  }
>  
>  void intel_guc_init_late(struct intel_guc *guc)
> @@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
>  	u32 flags;
>  
>  	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
> -	#define UNIT SZ_1M
> -	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
> +	#define LOG_UNIT SZ_1M
> +	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
>  	#else
> -	#define UNIT SZ_4K
> -	#define FLAG 0
> +	#define LOG_UNIT SZ_4K
> +	#define LOG_FLAG 0
> +	#endif
> +
> +	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
> +	#define CAPTURE_UNIT SZ_1M
> +	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
> +	#else
> +	#define CAPTURE_UNIT SZ_4K
> +	#define CAPTURE_FLAG 0
>  	#endif
>  
>  	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
> -	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
> +	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
>  	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
> -	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
> +	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
> +	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
> +	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
>  
> -	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
> +	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
>  			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
> -	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
> +	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
>  			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
> +	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
> +			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
>  
>  	flags = GUC_LOG_VALID |
>  		GUC_LOG_NOTIFY_ON_HALF_FULL |
> -		FLAG |
> -		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> -		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> +		CAPTURE_FLAG |
> +		LOG_FLAG |
> +		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> +		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> +		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
>  		(offset << GUC_LOG_BUF_ADDR_SHIFT);
>  
> -	#undef UNIT
> -	#undef FLAG
> +	#undef LOG_UNIT
> +	#undef LOG_FLAG
> +	#undef CAPTURE_UNIT
> +	#undef CAPTURE_FLAG
>  
>  	return flags;
>  }
> @@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
>  	return flags;
>  }
>  
> +static u32 guc_ctl_wa_flags(struct intel_guc *guc)
> +{
> +	struct intel_gt *gt = guc_to_gt(guc);
> +	u32 flags = 0;
> +
> +	/* Wa_22012773006:gen11,gen12 < XeHP */
> +	if (GRAPHICS_VER(gt->i915) >= 11 &&
> +	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
> +		flags |= GUC_WA_POLLCS;
> +
> +	return flags;
> +}
> +
> +static u32 guc_ctl_devid(struct intel_guc *guc)
> +{
> +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> +
> +	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
> +}
> +
>  /*
>   * Initialise the GuC parameter block before starting the firmware
>   * transfer. These parameters are read by the firmware on startup
> @@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
>  	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
>  	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
>  	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
> +	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
> +	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
>  
>  	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
>  		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
> @@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
>  	/* Make sure to handle only enabled messages */
>  	msg = payload[0] & guc->msg_enabled_mask;
>  
> -	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
> -		intel_guc_log_handle_flush_event(&guc->log);
> +	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
> +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
> +	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
> +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
>  
>  	return 0;
>  }
> @@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
>  {
>  	int ret;
>  	u32 action[] = {
> -		INTEL_GUC_ACTION_RESET_CLIENT,
> +		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
>  	};
>  
>  	if (!intel_guc_is_ready(guc))
> @@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
>  	return 0;
>  }
>  
> +static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> +{
> +	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
> +		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> +		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
> +	};
> +	int ret;
> +
> +	GEM_BUG_ON(len > 2);
> +	GEM_BUG_ON(len == 1 && upper_32_bits(value));
> +
> +	/* Self config must go over MMIO */
> +	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +
> +	if (unlikely(ret < 0))
> +		return ret;
> +	if (unlikely(ret > 1))
> +		return -EPROTO;
> +	if (unlikely(!ret))
> +		return -ENOKEY;
> +
> +	return 0;
> +}
> +
> +static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> +{
> +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> +	int err = __guc_action_self_cfg(guc, key, len, value);
> +
> +	if (unlikely(err))
> +		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
> +				 ERR_PTR(err), key, value);
> +	return err;
> +}
> +
> +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
> +{
> +	return __guc_self_cfg(guc, key, 1, value);
> +}
> +
> +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
> +{
> +	return __guc_self_cfg(guc, key, 2, value);
> +}
> +
>  /**
>   * intel_guc_load_status - dump information about GuC load status
>   * @guc: the GuC
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index 1cb46098030d..eaa1a85a2f01 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> @@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
>  struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
>  int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
>  				   struct i915_vma **out_vma, void **out_vaddr);
> +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
> +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
>  
>  static inline bool intel_guc_is_supported(struct intel_guc *guc)
>  {
> @@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
>  					const u32 *msg, u32 len);
>  int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
>  					 const u32 *msg, u32 len);
> +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> +					const u32 *msg, u32 len);
>  
>  void intel_guc_find_hung_context(struct intel_engine_cs *engine);
>  
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index 1a1edae67e4e..aa767540ca2a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -40,6 +40,10 @@
>   *      +---------------------------------------+
>   *      | padding                               |
>   *      +---------------------------------------+ <== 4K aligned
> + *      | capture lists                         |
> + *      +---------------------------------------+
> + *      | padding                               |
> + *      +---------------------------------------+ <== 4K aligned
>   *      | private data                          |
>   *      +---------------------------------------+
>   *      | padding                               |
> @@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
>  	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
>  }
>  
> +static u32 guc_ads_capture_size(struct intel_guc *guc)
> +{
> +	/* FIXME: Allocate a proper capture list */
> +	return PAGE_ALIGN(PAGE_SIZE);
> +}
> +
>  static u32 guc_ads_private_data_size(struct intel_guc *guc)
>  {
>  	return PAGE_ALIGN(guc->fw.private_data_size);
> @@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
>  	return PAGE_ALIGN(offset);
>  }
>  
> -static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> +static u32 guc_ads_capture_offset(struct intel_guc *guc)
>  {
>  	u32 offset;
>  
> @@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
>  	return PAGE_ALIGN(offset);
>  }
>  
> +static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> +{
> +	u32 offset;
> +
> +	offset = guc_ads_capture_offset(guc) +
> +		 guc_ads_capture_size(guc);
> +
> +	return PAGE_ALIGN(offset);
> +}
> +
>  static u32 guc_ads_blob_size(struct intel_guc *guc)
>  {
>  	return guc_ads_private_data_offset(guc) +
> @@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
>  	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
>  }
>  
> +static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
> +{
> +	int i, j;
> +	u32 addr_ggtt, offset;
> +
> +	offset = guc_ads_capture_offset(guc);
> +	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
> +
> +	/* FIXME: Populate a proper capture list */
> +
> +	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
> +		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
> +			blob->ads.capture_instance[i][j] = addr_ggtt;
> +			blob->ads.capture_class[i][j] = addr_ggtt;
> +		}
> +
> +		blob->ads.capture_global[i] = addr_ggtt;
> +	}
> +}
> +
>  static void __guc_ads_init(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
> @@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
>  
>  	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
>  
> +	/* Capture list for hang debug */
> +	guc_capture_list_init(guc, blob);
> +
>  	/* ADS */
>  	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
>  	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> index a0cc34be7b56..eba03e4c815b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
>  	init_waitqueue_head(&ct->wq);
>  }
>  
> -static inline const char *guc_ct_buffer_type_to_str(u32 type)
> -{
> -	switch (type) {
> -	case GUC_CTB_TYPE_HOST2GUC:
> -		return "SEND";
> -	case GUC_CTB_TYPE_GUC2HOST:
> -		return "RECV";
> -	default:
> -		return "<invalid>";
> -	}
> -}
> -
>  static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
>  {
>  	memset(desc, 0, sizeof(*desc));
> @@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
>  	guc_ct_buffer_reset(ctb);
>  }
>  
> -static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
> -					 u32 desc_addr, u32 buff_addr, u32 size)
> +static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
>  {
> -	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
> +	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
>  		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
>  		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
> +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
> +		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
>  	};
>  	int ret;
>  
> -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> -	GEM_BUG_ON(size % SZ_4K);
> +	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
>  
> -	/* CT registration must go over MMIO */
> +	/* CT control must go over MMIO */
>  	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
>  
>  	return ret > 0 ? -EPROTO : ret;
>  }
>  
> -static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
> -			      u32 desc_addr, u32 buff_addr, u32 size)
> +static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
>  {
>  	int err;
>  
> -	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
> +	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
> +				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
>  	if (unlikely(err))
> -		return err;
> +		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
> +			       enabledisable(enable), ERR_PTR(err));
>  
> -	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
> -					    desc_addr, buff_addr, size);
> -	if (unlikely(err))
> -		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
>  	return err;
>  }
>  
> -static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
> +static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
> +			      u32 desc_addr, u32 buff_addr, u32 size)
>  {
> -	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
> -		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> -		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
> -		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> -	};
> -	int ret;
> -
> -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> -
> -	/* CT deregistration must go over MMIO */
> -	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +	int err;
>  
> -	return ret > 0 ? -EPROTO : ret;
> -}
> +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
> +				   desc_addr);
> +	if (unlikely(err))
> +		goto failed;
>  
> -static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
> -{
> -	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
> +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
> +				   buff_addr);
> +	if (unlikely(err))
> +		goto failed;
>  
> +	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
> +				   size);
>  	if (unlikely(err))
> -		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
> -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> +failed:
> +		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> +			       send ? "SEND" : "RECV", ERR_PTR(err));
> +
>  	return err;
>  }
>  
> @@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
>  int intel_guc_ct_enable(struct intel_guc_ct *ct)
>  {
>  	struct intel_guc *guc = ct_to_guc(ct);
> -	u32 base, desc, cmds;
> +	u32 base, desc, cmds, size;
>  	void *blob;
>  	int err;
>  
> @@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
>  	 */
>  	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
>  	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
> -	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
> -				 desc, cmds, ct->ctbs.recv.size * 4);
> -
> +	size = ct->ctbs.recv.size * 4;
> +	err = ct_register_buffer(ct, false, desc, cmds, size);
>  	if (unlikely(err))
>  		goto err_out;
>  
>  	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
>  	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
> -	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
> -				 desc, cmds, ct->ctbs.send.size * 4);
> +	size = ct->ctbs.send.size * 4;
> +	err = ct_register_buffer(ct, true, desc, cmds, size);
> +	if (unlikely(err))
> +		goto err_out;
>  
> +	err = ct_control_enable(ct, true);
>  	if (unlikely(err))
> -		goto err_deregister;
> +		goto err_out;
>  
>  	ct->enabled = true;
>  	ct->stall_time = KTIME_MAX;
>  
>  	return 0;
>  
> -err_deregister:
> -	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
>  err_out:
>  	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
>  	return err;
> @@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
>  	ct->enabled = false;
>  
>  	if (intel_guc_is_fw_running(guc)) {
> -		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
> -		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> +		ct_control_enable(ct, false);
>  	}
>  }
>  
> @@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
>  	struct ct_request request;
>  	unsigned long flags;
>  	unsigned int sleep_period_ms = 1;
> +	bool send_again;
>  	u32 fence;
>  	int err;
>  
> @@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
>  	GEM_BUG_ON(!response_buf && response_buf_size);
>  	might_sleep();
>  
> +resend:
> +	send_again = false;
> +
>  	/*
>  	 * We use a lazy spin wait loop here as we believe that if the CT
>  	 * buffers are sized correctly the flow control condition should be
> @@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
>  		goto unlink;
>  	}
>  
> +	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
> +		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
> +			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
> +		send_again = true;
> +		goto unlink;
> +	}
> +
>  	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
>  		err = -EIO;
>  		goto unlink;
> @@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
>  	list_del(&request.link);
>  	spin_unlock_irqrestore(&ct->requests.lock, flags);
>  
> +	if (unlikely(send_again))
> +		goto resend;
> +
>  	return err;
>  }
>  
> @@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
>  	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
>  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
>  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
> +		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
>  		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
>  
>  	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
> @@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
>  	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
>  		ret = intel_guc_context_reset_process_msg(guc, payload, len);
>  		break;
> +	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
> +		ret = intel_guc_error_capture_process_msg(guc, payload, len);
> +		if (unlikely(ret))
> +			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
> +				 action, 4 * len, payload);
> +		break;
>  	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
>  		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
>  		break;
> +	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
> +		intel_guc_log_handle_flush_event(&guc->log);
> +		ret = 0;
> +		break;
> +	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
> +		CT_ERROR(ct, "Received GuC crash dump notification!\n");
> +		ret = 0;
> +		break;
> +	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
> +		CT_ERROR(ct, "Received GuC exception notification!\n");
> +		ret = 0;
> +		break;
>  	default:
>  		ret = -EOPNOTSUPP;
>  		break;
> @@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
>  		break;
>  	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
>  	case GUC_HXG_TYPE_RESPONSE_FAILURE:
> +	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
>  		err = ct_handle_response(ct, msg);
>  		break;
>  	default:
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> index 7072e30e99f4..6a4612a852e2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> @@ -16,6 +16,7 @@
>  #include "abi/guc_errors_abi.h"
>  #include "abi/guc_communication_mmio_abi.h"
>  #include "abi/guc_communication_ctb_abi.h"
> +#include "abi/guc_klvs_abi.h"
>  #include "abi/guc_messages_abi.h"
>  
>  /* Payload length only i.e. don't include G2H header length */
> @@ -84,19 +85,24 @@
>  #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
>  
>  #define GUC_CTL_LOG_PARAMS		0
> -#define   GUC_LOG_VALID			(1 << 0)
> -#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
> -#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
> +#define   GUC_LOG_VALID			BIT(0)
> +#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
> +#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
> +#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
>  #define   GUC_LOG_CRASH_SHIFT		4
>  #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
>  #define   GUC_LOG_DEBUG_SHIFT		6
>  #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
> +#define   GUC_LOG_CAPTURE_SHIFT		10
> +#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
>  #define   GUC_LOG_BUF_ADDR_SHIFT	12
>  
>  #define GUC_CTL_WA			1
> +#define   GUC_WA_POLLCS                 BIT(18)
> +
>  #define GUC_CTL_FEATURE			2
> -#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
>  #define   GUC_CTL_ENABLE_SLPC		BIT(2)
> +#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
>  
>  #define GUC_CTL_DEBUG			3
>  #define   GUC_LOG_VERBOSITY_SHIFT	0
> @@ -116,6 +122,8 @@
>  #define   GUC_ADS_ADDR_SHIFT		1
>  #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
>  
> +#define GUC_CTL_DEVID			5
> +
>  #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
>  
>  /* Generic GT SysInfo data types */
> @@ -263,7 +271,10 @@ struct guc_mmio_reg {
>  	u32 offset;
>  	u32 value;
>  	u32 flags;
> -#define GUC_REGSET_MASKED		(1 << 0)
> +	u32 mask;
> +#define GUC_REGSET_MASKED		BIT(0)
> +#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
> +#define GUC_REGSET_RESTORE_ONLY		BIT(3)
>  } __packed;
>  
>  /* GuC register sets */
> @@ -280,6 +291,12 @@ struct guc_gt_system_info {
>  	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
>  } __packed;
>  
> +enum {
> +	GUC_CAPTURE_LIST_INDEX_PF = 0,
> +	GUC_CAPTURE_LIST_INDEX_VF = 1,
> +	GUC_CAPTURE_LIST_INDEX_MAX = 2,
> +};
> +
>  /* GuC Additional Data Struct */
>  struct guc_ads {
>  	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
> @@ -291,7 +308,11 @@ struct guc_ads {
>  	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
>  	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
>  	u32 private_data;
> -	u32 reserved[15];
> +	u32 reserved2;
> +	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> +	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> +	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
> +	u32 reserved[14];
>  } __packed;
>  
>  /* Engine usage stats */
> @@ -312,6 +333,7 @@ struct guc_engine_usage {
>  enum guc_log_buffer_type {
>  	GUC_DEBUG_LOG_BUFFER,
>  	GUC_CRASH_DUMP_LOG_BUFFER,
> +	GUC_CAPTURE_LOG_BUFFER,
>  	GUC_MAX_LOG_BUFFER
>  };
>  
> @@ -342,6 +364,7 @@ struct guc_log_buffer_state {
>  	u32 write_ptr;
>  	u32 size;
>  	u32 sampled_write_ptr;
> +	u32 wrap_offset;
>  	union {
>  		struct {
>  			u32 flush_to_file:1;
> @@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
>  /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
>  enum intel_guc_recv_message {
>  	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
> -	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
> +	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
>  };
>  
>  #endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> index ac0931f0374b..be35f0570396 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> @@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
>  	return intel_guc_send(guc, action, ARRAY_SIZE(action));
>  }
>  
> -static void guc_log_enable_flush_events(struct intel_guc_log *log)
> -{
> -	intel_guc_enable_msg(log_to_guc(log),
> -			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> -}
> -
> -static void guc_log_disable_flush_events(struct intel_guc_log *log)
> -{
> -	intel_guc_disable_msg(log_to_guc(log),
> -			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> -}
> -
>  /*
>   * Sub buffer switch callback. Called whenever relay has to switch to a new
>   * sub buffer, relay stays on the same sub buffer if 0 is returned.
> @@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
>  		return DEBUG_BUFFER_SIZE;
>  	case GUC_CRASH_DUMP_LOG_BUFFER:
>  		return CRASH_BUFFER_SIZE;
> +	case GUC_CAPTURE_LOG_BUFFER:
> +		return CAPTURE_BUFFER_SIZE;
>  	default:
>  		MISSING_CASE(type);
>  	}
> @@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
>  	 *  +-------------------------------+ 32B
>  	 *  |      Debug state header       |
>  	 *  +-------------------------------+ 64B
> +	 *  |     Capture state header      |
> +	 *  +-------------------------------+ 96B
>  	 *  |                               |
>  	 *  +===============================+ PAGE_SIZE (4KB)
>  	 *  |        Crash Dump logs        |
>  	 *  +===============================+ + CRASH_SIZE
>  	 *  |          Debug logs           |
>  	 *  +===============================+ + DEBUG_SIZE
> +	 *  |         Capture logs          |
> +	 *  +===============================+ + CAPTURE_SIZE
>  	 */
> -	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
> +	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
> +		       CAPTURE_BUFFER_SIZE;
>  
>  	vma = intel_guc_allocate_vma(guc, guc_log_size);
>  	if (IS_ERR(vma)) {
> @@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
>  	if (log->relay.started)
>  		return -EEXIST;
>  
> -	guc_log_enable_flush_events(log);
> -
>  	/*
>  	 * When GuC is logging without us relaying to userspace, we're ignoring
>  	 * the flush notification. This means that we need to unconditionally
> @@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
>  	if (!log->relay.started)
>  		return;
>  
> -	guc_log_disable_flush_events(log);
>  	intel_synchronize_irq(i915);
>  
>  	flush_work(&log->relay.flush_work);
> @@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
>  
>  void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
>  {
> -	queue_work(system_highpri_wq, &log->relay.flush_work);
> +	if (log->relay.started)
> +		queue_work(system_highpri_wq, &log->relay.flush_work);
>  }
>  
>  static const char *
> @@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
>  		return "DEBUG";
>  	case GUC_CRASH_DUMP_LOG_BUFFER:
>  		return "CRASH";
> +	case GUC_CAPTURE_LOG_BUFFER:
> +		return "CAPTURE";
>  	default:
>  		MISSING_CASE(type);
>  	}
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> index fe6ab7550a14..d7e1b6471fed 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> @@ -18,12 +18,15 @@ struct intel_guc;
>  #if defined(CONFIG_DRM_I915_DEBUG_GUC)
>  #define CRASH_BUFFER_SIZE	SZ_2M
>  #define DEBUG_BUFFER_SIZE	SZ_16M
> +#define CAPTURE_BUFFER_SIZE	SZ_4M
>  #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
>  #define CRASH_BUFFER_SIZE	SZ_1M
>  #define DEBUG_BUFFER_SIZE	SZ_2M
> +#define CAPTURE_BUFFER_SIZE	SZ_1M
>  #else
>  #define CRASH_BUFFER_SIZE	SZ_8K
>  #define DEBUG_BUFFER_SIZE	SZ_64K
> +#define CAPTURE_BUFFER_SIZE	SZ_16K
>  #endif
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index 1f9d4fde421f..4d6c1383f2eb 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
>  	return 0;
>  }
>  
> +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> +					const u32 *msg, u32 len)
> +{
> +	int status;
> +
> +	if (unlikely(len != 1)) {
> +		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
> +		return -EPROTO;
> +	}
> +
> +	status = msg[0];
> +	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
> +
> +	/* FIXME: Do something with the capture */
> +
> +	return 0;
> +}
> +
>  static struct intel_engine_cs *
>  guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
>  {
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index a7788ce50736..9b82a5a27f90 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>   * firmware as TGL.
>   */
>  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
> -	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
> -	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
> -	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
> -	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
> -	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
> -	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
> -	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
> -	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
> -	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
> +	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
> +	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
> +	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
> +	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
> +	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
> +	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
> +	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
> +	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
> +	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
>  
>  #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
>  	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
> 

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

* Re: [Intel-gfx] [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
@ 2021-12-03 22:28     ` Michal Wajdeczko
  0 siblings, 0 replies; 29+ messages in thread
From: Michal Wajdeczko @ 2021-12-03 22:28 UTC (permalink / raw)
  To: John.C.Harrison, Intel-GFX; +Cc: DRI-Devel



On 03.12.2021 19:33, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
> 
> Update to the latest GuC release.
> 
> The latest GuC firmware introduces a number of interface changes:

Why can't we review all these changes in smaller patches and squash them
in separate CI series *after* collecting all required r-b ?

Michal

> 
> GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
> Add support for this reply and try resending the request again as a
> new CTB message.
> 
> A KLV (key-length-value) mechanism is now used for passing
> configuration data such as CTB management.
> 
> With the new KLV scheme, the old CTB management actions are no longer
> used and are removed.
> 
> Register capture on hang is now supported by GuC. Full i915 support
> for this will be added by a later patch. A minimum support of
> providing capture memory and register lists is required though, so add
> that in.
> 
> The device id of the current platform needs to be provided at init time.
> 
> The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
> versions of GuC. It must now be explicitly requested by the KMD. So,
> add in the code to turn it on when relevant.
> 
> The GuC log entry format has changed. This requires adding a new field
> to the log header structure to mark the wrap point at the end of the
> buffer (as the buffer size is no longer a multiple of the log entry
> size).
> 
> New CTB notification messages are now sent for some things that were
> previously only sent via MMIO notifications.
> 
> Of these, the crash dump notification was not really being handled by
> i915. It called the log flush code but that only flushed the regular
> debug log and then only if relay logging was enabled. So just report
> an error message instead.
> 
> The 'exception' notification was just being ignored completely. So add
> an error message for that as well.
> 
> Note that in either the crash dump or the exception case, the GuC is
> basically dead. The KMD will detect this via the heartbeat and trigger
> both an error log (which will include the crash dump as part of the
> GuC log) and a GT reset. So no other processing is really required.
> 
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> ---
>  Documentation/gpu/i915.rst                    |   1 +
>  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
>  drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
>  drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
>  drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
>  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
>  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
>  drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
>  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
>  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
>  12 files changed, 434 insertions(+), 164 deletions(-)
>  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> 
> diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> index b7d801993bfa..bcaefc952764 100644
> --- a/Documentation/gpu/i915.rst
> +++ b/Documentation/gpu/i915.rst
> @@ -539,6 +539,7 @@ GuC ABI
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
>  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> +.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
>  
>  HuC
>  ---
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> index fe5d7d261797..7afdadc7656f 100644
> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> @@ -7,9 +7,9 @@
>  #define _ABI_GUC_ACTIONS_ABI_H
>  
>  /**
> - * DOC: HOST2GUC_REGISTER_CTB
> + * DOC: HOST2GUC_SELF_CFG
>   *
> - * This message is used as part of the `CTB based communication`_ setup.
> + * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
>   *
>   * This message must be sent as `MMIO HXG Message`_.
>   *
> @@ -22,20 +22,18 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 27:16 | DATA0 = MBZ                                                  |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
> + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> + *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
> + *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
>   *  |   |       |                                                              |
> - *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
> - *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
> + *  |   |       |   - 32 bit KLV = 1                                           |
> + *  |   |       |   - 64 bit KLV = 2                                           |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
> + *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
> + *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
>   *  +---+-------+--------------------------------------------------------------+
>   *
>   *  +---+-------+--------------------------------------------------------------+
> @@ -45,28 +43,25 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  27:0 | DATA0 = MBZ                                                  |
> + *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
>   *  +---+-------+--------------------------------------------------------------+
>   */
> -#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
> +#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
>  
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> -#define   GUC_CTB_TYPE_HOST2GUC				0u
> -#define   GUC_CTB_TYPE_GUC2HOST				1u
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
> +#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
>  
> -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
>  
>  /**
> - * DOC: HOST2GUC_DEREGISTER_CTB
> + * DOC: HOST2GUC_CONTROL_CTB
>   *
> - * This message is used as part of the `CTB based communication`_ teardown.
> + * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
>   *
>   * This message must be sent as `MMIO HXG Message`_.
>   *
> @@ -79,15 +74,12 @@
>   *  |   +-------+--------------------------------------------------------------+
>   *  |   | 27:16 | DATA0 = MBZ                                                  |
>   *  |   +-------+--------------------------------------------------------------+
> - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
> + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
>   *  +---+-------+--------------------------------------------------------------+
> - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
> + *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
>   *  |   |       |                                                              |
> - *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
> - *  |   +-------+--------------------------------------------------------------+
> - *  |   |   7:0 | RESERVED = MBZ                                               |
> + *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
> + *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
>   *  +---+-------+--------------------------------------------------------------+
>   *
>   *  +---+-------+--------------------------------------------------------------+
> @@ -100,16 +92,16 @@
>   *  |   |  27:0 | DATA0 = MBZ                                                  |
>   *  +---+-------+--------------------------------------------------------------+
>   */
> -#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
> +#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
>  
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
> +#define   GUC_CTB_CONTROL_DISABLE			0u
> +#define   GUC_CTB_CONTROL_ENABLE			1u
>  
> -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
> -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
>  
>  /* legacy definitions */
>  
> @@ -143,8 +135,12 @@ enum intel_guc_action {
>  	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
>  	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
>  	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
> -	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
> +	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
>  	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
> +	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
> +	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
> +	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
> +	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
>  	INTEL_GUC_ACTION_LIMIT
>  };
>  
> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> new file mode 100644
> index 000000000000..3dda88a44fc6
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> @@ -0,0 +1,82 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2021 Intel Corporation
> + */
> +
> +#ifndef _ABI_GUC_KLVS_ABI_H
> +#define _ABI_GUC_KLVS_ABI_H
> +
> +/**
> + * DOC: GuC KLV
> + *
> + *  +---+-------+--------------------------------------------------------------+
> + *  |   | Bits  | Description                                                  |
> + *  +===+=======+==============================================================+
> + *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
> + *  |   |       |   - `GuC Self Config KLVs`_                                  |
> + *  |   |       |                                                              |
> + *  |   +-------+--------------------------------------------------------------+
> + *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
> + *  +---+-------+--------------------------------------------------------------+
> + *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
> + *  +---+-------+                                                              |
> + *  |...|       |                                                              |
> + *  +---+-------+                                                              |
> + *  | n |  31:0 |                                                              |
> + *  +---+-------+--------------------------------------------------------------+
> + */
> +
> +#define GUC_KLV_LEN_MIN				1u
> +#define GUC_KLV_0_KEY				(0xffff << 16)
> +#define GUC_KLV_0_LEN				(0xffff << 0)
> +#define GUC_KLV_n_VALUE				(0xffffffff << 0)
> +
> +/**
> + * DOC: GuC Self Config KLVs
> + *
> + * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
> + *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
> + *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
> + *      Refers to size of H2G `CT Buffer`_ in bytes.
> + *      Should be a multiple of 4K.
> + *
> + * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
> + *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
> + *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
> + *      Should be above WOPCM address but below APIC base address for native mode.
> + *
> + * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
> + *      Refers to size of G2H `CT Buffer`_ in bytes.
> + *      Should be a multiple of 4K.
> + */
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
> +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
> +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
> +
> +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
> +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
> +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
> +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
> +
> +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
> +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
> +
> +#endif /* _ABI_GUC_KLVS_ABI_H */
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> index 6e228343e8cb..cbec51f4dec3 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> @@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
>  		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
>  		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
>  	}
> +
> +	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
> +				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
>  }
>  
>  void intel_guc_init_late(struct intel_guc *guc)
> @@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
>  	u32 flags;
>  
>  	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
> -	#define UNIT SZ_1M
> -	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
> +	#define LOG_UNIT SZ_1M
> +	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
>  	#else
> -	#define UNIT SZ_4K
> -	#define FLAG 0
> +	#define LOG_UNIT SZ_4K
> +	#define LOG_FLAG 0
> +	#endif
> +
> +	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
> +	#define CAPTURE_UNIT SZ_1M
> +	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
> +	#else
> +	#define CAPTURE_UNIT SZ_4K
> +	#define CAPTURE_FLAG 0
>  	#endif
>  
>  	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
> -	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
> +	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
>  	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
> -	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
> +	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
> +	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
> +	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
>  
> -	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
> +	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
>  			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
> -	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
> +	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
>  			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
> +	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
> +			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
>  
>  	flags = GUC_LOG_VALID |
>  		GUC_LOG_NOTIFY_ON_HALF_FULL |
> -		FLAG |
> -		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> -		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> +		CAPTURE_FLAG |
> +		LOG_FLAG |
> +		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> +		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> +		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
>  		(offset << GUC_LOG_BUF_ADDR_SHIFT);
>  
> -	#undef UNIT
> -	#undef FLAG
> +	#undef LOG_UNIT
> +	#undef LOG_FLAG
> +	#undef CAPTURE_UNIT
> +	#undef CAPTURE_FLAG
>  
>  	return flags;
>  }
> @@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
>  	return flags;
>  }
>  
> +static u32 guc_ctl_wa_flags(struct intel_guc *guc)
> +{
> +	struct intel_gt *gt = guc_to_gt(guc);
> +	u32 flags = 0;
> +
> +	/* Wa_22012773006:gen11,gen12 < XeHP */
> +	if (GRAPHICS_VER(gt->i915) >= 11 &&
> +	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
> +		flags |= GUC_WA_POLLCS;
> +
> +	return flags;
> +}
> +
> +static u32 guc_ctl_devid(struct intel_guc *guc)
> +{
> +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> +
> +	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
> +}
> +
>  /*
>   * Initialise the GuC parameter block before starting the firmware
>   * transfer. These parameters are read by the firmware on startup
> @@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
>  	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
>  	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
>  	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
> +	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
> +	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
>  
>  	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
>  		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
> @@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
>  	/* Make sure to handle only enabled messages */
>  	msg = payload[0] & guc->msg_enabled_mask;
>  
> -	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
> -		intel_guc_log_handle_flush_event(&guc->log);
> +	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
> +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
> +	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
> +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
>  
>  	return 0;
>  }
> @@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
>  {
>  	int ret;
>  	u32 action[] = {
> -		INTEL_GUC_ACTION_RESET_CLIENT,
> +		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
>  	};
>  
>  	if (!intel_guc_is_ready(guc))
> @@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
>  	return 0;
>  }
>  
> +static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> +{
> +	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
> +		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> +		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
> +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
> +	};
> +	int ret;
> +
> +	GEM_BUG_ON(len > 2);
> +	GEM_BUG_ON(len == 1 && upper_32_bits(value));
> +
> +	/* Self config must go over MMIO */
> +	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +
> +	if (unlikely(ret < 0))
> +		return ret;
> +	if (unlikely(ret > 1))
> +		return -EPROTO;
> +	if (unlikely(!ret))
> +		return -ENOKEY;
> +
> +	return 0;
> +}
> +
> +static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> +{
> +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> +	int err = __guc_action_self_cfg(guc, key, len, value);
> +
> +	if (unlikely(err))
> +		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
> +				 ERR_PTR(err), key, value);
> +	return err;
> +}
> +
> +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
> +{
> +	return __guc_self_cfg(guc, key, 1, value);
> +}
> +
> +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
> +{
> +	return __guc_self_cfg(guc, key, 2, value);
> +}
> +
>  /**
>   * intel_guc_load_status - dump information about GuC load status
>   * @guc: the GuC
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> index 1cb46098030d..eaa1a85a2f01 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> @@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
>  struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
>  int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
>  				   struct i915_vma **out_vma, void **out_vaddr);
> +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
> +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
>  
>  static inline bool intel_guc_is_supported(struct intel_guc *guc)
>  {
> @@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
>  					const u32 *msg, u32 len);
>  int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
>  					 const u32 *msg, u32 len);
> +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> +					const u32 *msg, u32 len);
>  
>  void intel_guc_find_hung_context(struct intel_engine_cs *engine);
>  
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> index 1a1edae67e4e..aa767540ca2a 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> @@ -40,6 +40,10 @@
>   *      +---------------------------------------+
>   *      | padding                               |
>   *      +---------------------------------------+ <== 4K aligned
> + *      | capture lists                         |
> + *      +---------------------------------------+
> + *      | padding                               |
> + *      +---------------------------------------+ <== 4K aligned
>   *      | private data                          |
>   *      +---------------------------------------+
>   *      | padding                               |
> @@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
>  	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
>  }
>  
> +static u32 guc_ads_capture_size(struct intel_guc *guc)
> +{
> +	/* FIXME: Allocate a proper capture list */
> +	return PAGE_ALIGN(PAGE_SIZE);
> +}
> +
>  static u32 guc_ads_private_data_size(struct intel_guc *guc)
>  {
>  	return PAGE_ALIGN(guc->fw.private_data_size);
> @@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
>  	return PAGE_ALIGN(offset);
>  }
>  
> -static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> +static u32 guc_ads_capture_offset(struct intel_guc *guc)
>  {
>  	u32 offset;
>  
> @@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
>  	return PAGE_ALIGN(offset);
>  }
>  
> +static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> +{
> +	u32 offset;
> +
> +	offset = guc_ads_capture_offset(guc) +
> +		 guc_ads_capture_size(guc);
> +
> +	return PAGE_ALIGN(offset);
> +}
> +
>  static u32 guc_ads_blob_size(struct intel_guc *guc)
>  {
>  	return guc_ads_private_data_offset(guc) +
> @@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
>  	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
>  }
>  
> +static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
> +{
> +	int i, j;
> +	u32 addr_ggtt, offset;
> +
> +	offset = guc_ads_capture_offset(guc);
> +	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
> +
> +	/* FIXME: Populate a proper capture list */
> +
> +	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
> +		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
> +			blob->ads.capture_instance[i][j] = addr_ggtt;
> +			blob->ads.capture_class[i][j] = addr_ggtt;
> +		}
> +
> +		blob->ads.capture_global[i] = addr_ggtt;
> +	}
> +}
> +
>  static void __guc_ads_init(struct intel_guc *guc)
>  {
>  	struct intel_gt *gt = guc_to_gt(guc);
> @@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
>  
>  	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
>  
> +	/* Capture list for hang debug */
> +	guc_capture_list_init(guc, blob);
> +
>  	/* ADS */
>  	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
>  	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> index a0cc34be7b56..eba03e4c815b 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> @@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
>  	init_waitqueue_head(&ct->wq);
>  }
>  
> -static inline const char *guc_ct_buffer_type_to_str(u32 type)
> -{
> -	switch (type) {
> -	case GUC_CTB_TYPE_HOST2GUC:
> -		return "SEND";
> -	case GUC_CTB_TYPE_GUC2HOST:
> -		return "RECV";
> -	default:
> -		return "<invalid>";
> -	}
> -}
> -
>  static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
>  {
>  	memset(desc, 0, sizeof(*desc));
> @@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
>  	guc_ct_buffer_reset(ctb);
>  }
>  
> -static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
> -					 u32 desc_addr, u32 buff_addr, u32 size)
> +static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
>  {
> -	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
> +	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
>  		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
>  		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
> -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
> +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
> +		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
>  	};
>  	int ret;
>  
> -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> -	GEM_BUG_ON(size % SZ_4K);
> +	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
>  
> -	/* CT registration must go over MMIO */
> +	/* CT control must go over MMIO */
>  	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
>  
>  	return ret > 0 ? -EPROTO : ret;
>  }
>  
> -static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
> -			      u32 desc_addr, u32 buff_addr, u32 size)
> +static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
>  {
>  	int err;
>  
> -	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
> +	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
> +				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
>  	if (unlikely(err))
> -		return err;
> +		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
> +			       enabledisable(enable), ERR_PTR(err));
>  
> -	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
> -					    desc_addr, buff_addr, size);
> -	if (unlikely(err))
> -		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
>  	return err;
>  }
>  
> -static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
> +static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
> +			      u32 desc_addr, u32 buff_addr, u32 size)
>  {
> -	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
> -		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> -		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
> -		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> -	};
> -	int ret;
> -
> -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> -
> -	/* CT deregistration must go over MMIO */
> -	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> +	int err;
>  
> -	return ret > 0 ? -EPROTO : ret;
> -}
> +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
> +				   desc_addr);
> +	if (unlikely(err))
> +		goto failed;
>  
> -static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
> -{
> -	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
> +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
> +				   buff_addr);
> +	if (unlikely(err))
> +		goto failed;
>  
> +	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
> +				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
> +				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
> +				   size);
>  	if (unlikely(err))
> -		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
> -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> +failed:
> +		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> +			       send ? "SEND" : "RECV", ERR_PTR(err));
> +
>  	return err;
>  }
>  
> @@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
>  int intel_guc_ct_enable(struct intel_guc_ct *ct)
>  {
>  	struct intel_guc *guc = ct_to_guc(ct);
> -	u32 base, desc, cmds;
> +	u32 base, desc, cmds, size;
>  	void *blob;
>  	int err;
>  
> @@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
>  	 */
>  	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
>  	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
> -	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
> -				 desc, cmds, ct->ctbs.recv.size * 4);
> -
> +	size = ct->ctbs.recv.size * 4;
> +	err = ct_register_buffer(ct, false, desc, cmds, size);
>  	if (unlikely(err))
>  		goto err_out;
>  
>  	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
>  	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
> -	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
> -				 desc, cmds, ct->ctbs.send.size * 4);
> +	size = ct->ctbs.send.size * 4;
> +	err = ct_register_buffer(ct, true, desc, cmds, size);
> +	if (unlikely(err))
> +		goto err_out;
>  
> +	err = ct_control_enable(ct, true);
>  	if (unlikely(err))
> -		goto err_deregister;
> +		goto err_out;
>  
>  	ct->enabled = true;
>  	ct->stall_time = KTIME_MAX;
>  
>  	return 0;
>  
> -err_deregister:
> -	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
>  err_out:
>  	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
>  	return err;
> @@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
>  	ct->enabled = false;
>  
>  	if (intel_guc_is_fw_running(guc)) {
> -		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
> -		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> +		ct_control_enable(ct, false);
>  	}
>  }
>  
> @@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
>  	struct ct_request request;
>  	unsigned long flags;
>  	unsigned int sleep_period_ms = 1;
> +	bool send_again;
>  	u32 fence;
>  	int err;
>  
> @@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
>  	GEM_BUG_ON(!response_buf && response_buf_size);
>  	might_sleep();
>  
> +resend:
> +	send_again = false;
> +
>  	/*
>  	 * We use a lazy spin wait loop here as we believe that if the CT
>  	 * buffers are sized correctly the flow control condition should be
> @@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
>  		goto unlink;
>  	}
>  
> +	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
> +		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
> +			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
> +		send_again = true;
> +		goto unlink;
> +	}
> +
>  	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
>  		err = -EIO;
>  		goto unlink;
> @@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
>  	list_del(&request.link);
>  	spin_unlock_irqrestore(&ct->requests.lock, flags);
>  
> +	if (unlikely(send_again))
> +		goto resend;
> +
>  	return err;
>  }
>  
> @@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
>  	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
>  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
>  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
> +		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
>  		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
>  
>  	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
> @@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
>  	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
>  		ret = intel_guc_context_reset_process_msg(guc, payload, len);
>  		break;
> +	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
> +		ret = intel_guc_error_capture_process_msg(guc, payload, len);
> +		if (unlikely(ret))
> +			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
> +				 action, 4 * len, payload);
> +		break;
>  	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
>  		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
>  		break;
> +	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
> +		intel_guc_log_handle_flush_event(&guc->log);
> +		ret = 0;
> +		break;
> +	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
> +		CT_ERROR(ct, "Received GuC crash dump notification!\n");
> +		ret = 0;
> +		break;
> +	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
> +		CT_ERROR(ct, "Received GuC exception notification!\n");
> +		ret = 0;
> +		break;
>  	default:
>  		ret = -EOPNOTSUPP;
>  		break;
> @@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
>  		break;
>  	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
>  	case GUC_HXG_TYPE_RESPONSE_FAILURE:
> +	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
>  		err = ct_handle_response(ct, msg);
>  		break;
>  	default:
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> index 7072e30e99f4..6a4612a852e2 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> @@ -16,6 +16,7 @@
>  #include "abi/guc_errors_abi.h"
>  #include "abi/guc_communication_mmio_abi.h"
>  #include "abi/guc_communication_ctb_abi.h"
> +#include "abi/guc_klvs_abi.h"
>  #include "abi/guc_messages_abi.h"
>  
>  /* Payload length only i.e. don't include G2H header length */
> @@ -84,19 +85,24 @@
>  #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
>  
>  #define GUC_CTL_LOG_PARAMS		0
> -#define   GUC_LOG_VALID			(1 << 0)
> -#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
> -#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
> +#define   GUC_LOG_VALID			BIT(0)
> +#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
> +#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
> +#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
>  #define   GUC_LOG_CRASH_SHIFT		4
>  #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
>  #define   GUC_LOG_DEBUG_SHIFT		6
>  #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
> +#define   GUC_LOG_CAPTURE_SHIFT		10
> +#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
>  #define   GUC_LOG_BUF_ADDR_SHIFT	12
>  
>  #define GUC_CTL_WA			1
> +#define   GUC_WA_POLLCS                 BIT(18)
> +
>  #define GUC_CTL_FEATURE			2
> -#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
>  #define   GUC_CTL_ENABLE_SLPC		BIT(2)
> +#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
>  
>  #define GUC_CTL_DEBUG			3
>  #define   GUC_LOG_VERBOSITY_SHIFT	0
> @@ -116,6 +122,8 @@
>  #define   GUC_ADS_ADDR_SHIFT		1
>  #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
>  
> +#define GUC_CTL_DEVID			5
> +
>  #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
>  
>  /* Generic GT SysInfo data types */
> @@ -263,7 +271,10 @@ struct guc_mmio_reg {
>  	u32 offset;
>  	u32 value;
>  	u32 flags;
> -#define GUC_REGSET_MASKED		(1 << 0)
> +	u32 mask;
> +#define GUC_REGSET_MASKED		BIT(0)
> +#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
> +#define GUC_REGSET_RESTORE_ONLY		BIT(3)
>  } __packed;
>  
>  /* GuC register sets */
> @@ -280,6 +291,12 @@ struct guc_gt_system_info {
>  	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
>  } __packed;
>  
> +enum {
> +	GUC_CAPTURE_LIST_INDEX_PF = 0,
> +	GUC_CAPTURE_LIST_INDEX_VF = 1,
> +	GUC_CAPTURE_LIST_INDEX_MAX = 2,
> +};
> +
>  /* GuC Additional Data Struct */
>  struct guc_ads {
>  	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
> @@ -291,7 +308,11 @@ struct guc_ads {
>  	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
>  	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
>  	u32 private_data;
> -	u32 reserved[15];
> +	u32 reserved2;
> +	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> +	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> +	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
> +	u32 reserved[14];
>  } __packed;
>  
>  /* Engine usage stats */
> @@ -312,6 +333,7 @@ struct guc_engine_usage {
>  enum guc_log_buffer_type {
>  	GUC_DEBUG_LOG_BUFFER,
>  	GUC_CRASH_DUMP_LOG_BUFFER,
> +	GUC_CAPTURE_LOG_BUFFER,
>  	GUC_MAX_LOG_BUFFER
>  };
>  
> @@ -342,6 +364,7 @@ struct guc_log_buffer_state {
>  	u32 write_ptr;
>  	u32 size;
>  	u32 sampled_write_ptr;
> +	u32 wrap_offset;
>  	union {
>  		struct {
>  			u32 flush_to_file:1;
> @@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
>  /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
>  enum intel_guc_recv_message {
>  	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
> -	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
> +	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
>  };
>  
>  #endif
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> index ac0931f0374b..be35f0570396 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> @@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
>  	return intel_guc_send(guc, action, ARRAY_SIZE(action));
>  }
>  
> -static void guc_log_enable_flush_events(struct intel_guc_log *log)
> -{
> -	intel_guc_enable_msg(log_to_guc(log),
> -			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> -}
> -
> -static void guc_log_disable_flush_events(struct intel_guc_log *log)
> -{
> -	intel_guc_disable_msg(log_to_guc(log),
> -			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> -			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> -}
> -
>  /*
>   * Sub buffer switch callback. Called whenever relay has to switch to a new
>   * sub buffer, relay stays on the same sub buffer if 0 is returned.
> @@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
>  		return DEBUG_BUFFER_SIZE;
>  	case GUC_CRASH_DUMP_LOG_BUFFER:
>  		return CRASH_BUFFER_SIZE;
> +	case GUC_CAPTURE_LOG_BUFFER:
> +		return CAPTURE_BUFFER_SIZE;
>  	default:
>  		MISSING_CASE(type);
>  	}
> @@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
>  	 *  +-------------------------------+ 32B
>  	 *  |      Debug state header       |
>  	 *  +-------------------------------+ 64B
> +	 *  |     Capture state header      |
> +	 *  +-------------------------------+ 96B
>  	 *  |                               |
>  	 *  +===============================+ PAGE_SIZE (4KB)
>  	 *  |        Crash Dump logs        |
>  	 *  +===============================+ + CRASH_SIZE
>  	 *  |          Debug logs           |
>  	 *  +===============================+ + DEBUG_SIZE
> +	 *  |         Capture logs          |
> +	 *  +===============================+ + CAPTURE_SIZE
>  	 */
> -	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
> +	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
> +		       CAPTURE_BUFFER_SIZE;
>  
>  	vma = intel_guc_allocate_vma(guc, guc_log_size);
>  	if (IS_ERR(vma)) {
> @@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
>  	if (log->relay.started)
>  		return -EEXIST;
>  
> -	guc_log_enable_flush_events(log);
> -
>  	/*
>  	 * When GuC is logging without us relaying to userspace, we're ignoring
>  	 * the flush notification. This means that we need to unconditionally
> @@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
>  	if (!log->relay.started)
>  		return;
>  
> -	guc_log_disable_flush_events(log);
>  	intel_synchronize_irq(i915);
>  
>  	flush_work(&log->relay.flush_work);
> @@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
>  
>  void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
>  {
> -	queue_work(system_highpri_wq, &log->relay.flush_work);
> +	if (log->relay.started)
> +		queue_work(system_highpri_wq, &log->relay.flush_work);
>  }
>  
>  static const char *
> @@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
>  		return "DEBUG";
>  	case GUC_CRASH_DUMP_LOG_BUFFER:
>  		return "CRASH";
> +	case GUC_CAPTURE_LOG_BUFFER:
> +		return "CAPTURE";
>  	default:
>  		MISSING_CASE(type);
>  	}
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> index fe6ab7550a14..d7e1b6471fed 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> @@ -18,12 +18,15 @@ struct intel_guc;
>  #if defined(CONFIG_DRM_I915_DEBUG_GUC)
>  #define CRASH_BUFFER_SIZE	SZ_2M
>  #define DEBUG_BUFFER_SIZE	SZ_16M
> +#define CAPTURE_BUFFER_SIZE	SZ_4M
>  #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
>  #define CRASH_BUFFER_SIZE	SZ_1M
>  #define DEBUG_BUFFER_SIZE	SZ_2M
> +#define CAPTURE_BUFFER_SIZE	SZ_1M
>  #else
>  #define CRASH_BUFFER_SIZE	SZ_8K
>  #define DEBUG_BUFFER_SIZE	SZ_64K
> +#define CAPTURE_BUFFER_SIZE	SZ_16K
>  #endif
>  
>  /*
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> index 1f9d4fde421f..4d6c1383f2eb 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> @@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
>  	return 0;
>  }
>  
> +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> +					const u32 *msg, u32 len)
> +{
> +	int status;
> +
> +	if (unlikely(len != 1)) {
> +		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
> +		return -EPROTO;
> +	}
> +
> +	status = msg[0];
> +	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
> +
> +	/* FIXME: Do something with the capture */
> +
> +	return 0;
> +}
> +
>  static struct intel_engine_cs *
>  guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
>  {
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index a7788ce50736..9b82a5a27f90 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>   * firmware as TGL.
>   */
>  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
> -	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
> -	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
> -	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
> -	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
> -	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
> -	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
> -	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
> -	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
> -	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
> -	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
> -	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
> +	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
> +	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
> +	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
> +	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
> +	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
> +	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
> +	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
> +	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
> +	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
> +	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
> +	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
>  
>  #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
>  	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
> 

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

* [Intel-gfx] ✓ Fi.CI.BAT: success for Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
                   ` (8 preceding siblings ...)
  (?)
@ 2021-12-03 22:50 ` Patchwork
  -1 siblings, 0 replies; 29+ messages in thread
From: Patchwork @ 2021-12-03 22:50 UTC (permalink / raw)
  To: john.c.harrison; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 4845 bytes --]

== Series Details ==

Series: Update to GuC version 69.0.0
URL   : https://patchwork.freedesktop.org/series/97564/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_10963 -> Patchwork_21752
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/index.html

Participating hosts (45 -> 34)
------------------------------

  Missing    (11): fi-ilk-m540 bat-dg1-6 bat-dg1-5 fi-hsw-4200u fi-bsw-cyan bat-adlp-6 bat-adlp-4 fi-ctg-p8600 fi-bdw-samus bat-jsl-2 bat-jsl-1 

Known issues
------------

  Here are the changes found in Patchwork_21752 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_parallel@engines@userptr:
    - fi-pnv-d510:        [PASS][1] -> [INCOMPLETE][2] ([i915#299])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-pnv-d510/igt@gem_exec_parallel@engines@userptr.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-pnv-d510/igt@gem_exec_parallel@engines@userptr.html

  * igt@gem_exec_suspend@basic-s3:
    - fi-skl-6600u:       [PASS][3] -> [INCOMPLETE][4] ([i915#4547])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-skl-6600u/igt@gem_exec_suspend@basic-s3.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-skl-6600u/igt@gem_exec_suspend@basic-s3.html

  * igt@i915_selftest@live@gt_engines:
    - fi-rkl-guc:         [PASS][5] -> [INCOMPLETE][6] ([i915#4432])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-rkl-guc/igt@i915_selftest@live@gt_engines.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-rkl-guc/igt@i915_selftest@live@gt_engines.html

  * igt@kms_frontbuffer_tracking@basic:
    - fi-cml-u2:          [PASS][7] -> [DMESG-WARN][8] ([i915#4269])
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-cml-u2/igt@kms_frontbuffer_tracking@basic.html

  * igt@runner@aborted:
    - fi-bdw-5557u:       NOTRUN -> [FAIL][9] ([i915#2426] / [i915#4312])
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-bdw-5557u/igt@runner@aborted.html
    - fi-rkl-guc:         NOTRUN -> [FAIL][10] ([i915#3928] / [i915#4312])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-rkl-guc/igt@runner@aborted.html

  
#### Possible fixes ####

  * igt@gem_exec_suspend@basic-s3:
    - fi-bdw-5557u:       [INCOMPLETE][11] ([i915#146]) -> [PASS][12]
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-bdw-5557u/igt@gem_exec_suspend@basic-s3.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-bdw-5557u/igt@gem_exec_suspend@basic-s3.html

  
#### Warnings ####

  * igt@runner@aborted:
    - fi-pnv-d510:        [FAIL][13] ([fdo#109271] / [i915#2403] / [i915#4312]) -> [FAIL][14] ([i915#2403] / [i915#2722] / [i915#4312])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/fi-pnv-d510/igt@runner@aborted.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/fi-pnv-d510/igt@runner@aborted.html

  
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [i915#146]: https://gitlab.freedesktop.org/drm/intel/issues/146
  [i915#2403]: https://gitlab.freedesktop.org/drm/intel/issues/2403
  [i915#2426]: https://gitlab.freedesktop.org/drm/intel/issues/2426
  [i915#2722]: https://gitlab.freedesktop.org/drm/intel/issues/2722
  [i915#299]: https://gitlab.freedesktop.org/drm/intel/issues/299
  [i915#3928]: https://gitlab.freedesktop.org/drm/intel/issues/3928
  [i915#4269]: https://gitlab.freedesktop.org/drm/intel/issues/4269
  [i915#4312]: https://gitlab.freedesktop.org/drm/intel/issues/4312
  [i915#4432]: https://gitlab.freedesktop.org/drm/intel/issues/4432
  [i915#4547]: https://gitlab.freedesktop.org/drm/intel/issues/4547


Build changes
-------------

  * Linux: CI_DRM_10963 -> Patchwork_21752

  CI-20190529: 20190529
  CI_DRM_10963: 2b63a468d3e3c264a3d1a4773edfe8785d45d4ec @ git://anongit.freedesktop.org/gfx-ci/linux
  IGT_6300: f69bd65fa9f72b7d5e5a5a22981f16d034334761 @ https://gitlab.freedesktop.org/drm/igt-gpu-tools.git
  Patchwork_21752: 25e36b6914e27199304dfa603366e6bc78288206 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

25e36b6914e2 drm/i915/guc: Improve GuC loading status check/error reports
b1173763d5c2 drm/i915/guc: Update to GuC version 69.0.0
dcbfeb6078aa drm/i915/guc: Don't go bang in GuC log if no GuC
0c27c3d306db drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM
1ba090939f4f drm/i915/uc: Allow platforms to have GuC but not HuC

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/index.html

[-- Attachment #2: Type: text/html, Size: 5902 bytes --]

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

* Re: [Intel-gfx] [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
  2021-12-03 22:28     ` [Intel-gfx] " Michal Wajdeczko
@ 2021-12-03 23:56       ` Matthew Brost
  -1 siblings, 0 replies; 29+ messages in thread
From: Matthew Brost @ 2021-12-03 23:56 UTC (permalink / raw)
  To: Michal Wajdeczko; +Cc: Intel-GFX, DRI-Devel, John.C.Harrison

On Fri, Dec 03, 2021 at 11:28:00PM +0100, Michal Wajdeczko wrote:
> 
> 
> On 03.12.2021 19:33, John.C.Harrison@Intel.com wrote:
> > From: John Harrison <John.C.Harrison@Intel.com>
> > 
> > Update to the latest GuC release.
> > 
> > The latest GuC firmware introduces a number of interface changes:
> 
> Why can't we review all these changes in smaller patches and squash them
> in separate CI series *after* collecting all required r-b ?
> 
> Michal
> 

I reviewed this and it seems pretty straight forward to me.

I'm giving a RB, but we can hold up merging if you have an objection.
Likely targeting an early next week merge so please raise any concerns
before then.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> > 
> > GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
> > Add support for this reply and try resending the request again as a
> > new CTB message.
> > 
> > A KLV (key-length-value) mechanism is now used for passing
> > configuration data such as CTB management.
> > 
> > With the new KLV scheme, the old CTB management actions are no longer
> > used and are removed.
> > 
> > Register capture on hang is now supported by GuC. Full i915 support
> > for this will be added by a later patch. A minimum support of
> > providing capture memory and register lists is required though, so add
> > that in.
> > 
> > The device id of the current platform needs to be provided at init time.
> > 
> > The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
> > versions of GuC. It must now be explicitly requested by the KMD. So,
> > add in the code to turn it on when relevant.
> > 
> > The GuC log entry format has changed. This requires adding a new field
> > to the log header structure to mark the wrap point at the end of the
> > buffer (as the buffer size is no longer a multiple of the log entry
> > size).
> > 
> > New CTB notification messages are now sent for some things that were
> > previously only sent via MMIO notifications.
> > 
> > Of these, the crash dump notification was not really being handled by
> > i915. It called the log flush code but that only flushed the regular
> > debug log and then only if relay logging was enabled. So just report
> > an error message instead.
> > 
> > The 'exception' notification was just being ignored completely. So add
> > an error message for that as well.
> > 
> > Note that in either the crash dump or the exception case, the GuC is
> > basically dead. The KMD will detect this via the heartbeat and trigger
> > both an error log (which will include the crash dump as part of the
> > GuC log) and a GT reset. So no other processing is really required.
> > 
> > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> > ---
> >  Documentation/gpu/i915.rst                    |   1 +
> >  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
> >  drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
> >  drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
> >  drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
> >  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
> >  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
> >  12 files changed, 434 insertions(+), 164 deletions(-)
> >  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > 
> > diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> > index b7d801993bfa..bcaefc952764 100644
> > --- a/Documentation/gpu/i915.rst
> > +++ b/Documentation/gpu/i915.rst
> > @@ -539,6 +539,7 @@ GuC ABI
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > +.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> >  
> >  HuC
> >  ---
> > diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > index fe5d7d261797..7afdadc7656f 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > @@ -7,9 +7,9 @@
> >  #define _ABI_GUC_ACTIONS_ABI_H
> >  
> >  /**
> > - * DOC: HOST2GUC_REGISTER_CTB
> > + * DOC: HOST2GUC_SELF_CFG
> >   *
> > - * This message is used as part of the `CTB based communication`_ setup.
> > + * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
> >   *
> >   * This message must be sent as `MMIO HXG Message`_.
> >   *
> > @@ -22,20 +22,18 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 27:16 | DATA0 = MBZ                                                  |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
> > + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> > + *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
> > + *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
> >   *  |   |       |                                                              |
> > - *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
> > - *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
> > + *  |   |       |   - 32 bit KLV = 1                                           |
> > + *  |   |       |   - 64 bit KLV = 2                                           |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
> > + *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
> > + *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
> >   *  +---+-------+--------------------------------------------------------------+
> >   *
> >   *  +---+-------+--------------------------------------------------------------+
> > @@ -45,28 +43,25 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  27:0 | DATA0 = MBZ                                                  |
> > + *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
> >   *  +---+-------+--------------------------------------------------------------+
> >   */
> > -#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
> > +#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
> >  
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> > -#define   GUC_CTB_TYPE_HOST2GUC				0u
> > -#define   GUC_CTB_TYPE_GUC2HOST				1u
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
> >  
> > -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> > +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
> >  
> >  /**
> > - * DOC: HOST2GUC_DEREGISTER_CTB
> > + * DOC: HOST2GUC_CONTROL_CTB
> >   *
> > - * This message is used as part of the `CTB based communication`_ teardown.
> > + * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
> >   *
> >   * This message must be sent as `MMIO HXG Message`_.
> >   *
> > @@ -79,15 +74,12 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 27:16 | DATA0 = MBZ                                                  |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
> > + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
> > + *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
> >   *  |   |       |                                                              |
> > - *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |   7:0 | RESERVED = MBZ                                               |
> > + *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
> > + *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
> >   *  +---+-------+--------------------------------------------------------------+
> >   *
> >   *  +---+-------+--------------------------------------------------------------+
> > @@ -100,16 +92,16 @@
> >   *  |   |  27:0 | DATA0 = MBZ                                                  |
> >   *  +---+-------+--------------------------------------------------------------+
> >   */
> > -#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
> > +#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
> >  
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define   GUC_CTB_CONTROL_DISABLE			0u
> > +#define   GUC_CTB_CONTROL_ENABLE			1u
> >  
> > -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
> > -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> > +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
> >  
> >  /* legacy definitions */
> >  
> > @@ -143,8 +135,12 @@ enum intel_guc_action {
> >  	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
> >  	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
> >  	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
> > -	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
> > +	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
> >  	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
> > +	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
> > +	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
> > +	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
> > +	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
> >  	INTEL_GUC_ACTION_LIMIT
> >  };
> >  
> > diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > new file mode 100644
> > index 000000000000..3dda88a44fc6
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > @@ -0,0 +1,82 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright © 2021 Intel Corporation
> > + */
> > +
> > +#ifndef _ABI_GUC_KLVS_ABI_H
> > +#define _ABI_GUC_KLVS_ABI_H
> > +
> > +/**
> > + * DOC: GuC KLV
> > + *
> > + *  +---+-------+--------------------------------------------------------------+
> > + *  |   | Bits  | Description                                                  |
> > + *  +===+=======+==============================================================+
> > + *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
> > + *  |   |       |   - `GuC Self Config KLVs`_                                  |
> > + *  |   |       |                                                              |
> > + *  |   +-------+--------------------------------------------------------------+
> > + *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
> > + *  +---+-------+--------------------------------------------------------------+
> > + *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
> > + *  +---+-------+                                                              |
> > + *  |...|       |                                                              |
> > + *  +---+-------+                                                              |
> > + *  | n |  31:0 |                                                              |
> > + *  +---+-------+--------------------------------------------------------------+
> > + */
> > +
> > +#define GUC_KLV_LEN_MIN				1u
> > +#define GUC_KLV_0_KEY				(0xffff << 16)
> > +#define GUC_KLV_0_LEN				(0xffff << 0)
> > +#define GUC_KLV_n_VALUE				(0xffffffff << 0)
> > +
> > +/**
> > + * DOC: GuC Self Config KLVs
> > + *
> > + * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
> > + *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
> > + *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
> > + *      Refers to size of H2G `CT Buffer`_ in bytes.
> > + *      Should be a multiple of 4K.
> > + *
> > + * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
> > + *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
> > + *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
> > + *      Refers to size of G2H `CT Buffer`_ in bytes.
> > + *      Should be a multiple of 4K.
> > + */
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
> > +
> > +#endif /* _ABI_GUC_KLVS_ABI_H */
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > index 6e228343e8cb..cbec51f4dec3 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > @@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
> >  		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
> >  		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
> >  	}
> > +
> > +	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
> > +				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> >  }
> >  
> >  void intel_guc_init_late(struct intel_guc *guc)
> > @@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
> >  	u32 flags;
> >  
> >  	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
> > -	#define UNIT SZ_1M
> > -	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
> > +	#define LOG_UNIT SZ_1M
> > +	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
> >  	#else
> > -	#define UNIT SZ_4K
> > -	#define FLAG 0
> > +	#define LOG_UNIT SZ_4K
> > +	#define LOG_FLAG 0
> > +	#endif
> > +
> > +	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
> > +	#define CAPTURE_UNIT SZ_1M
> > +	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
> > +	#else
> > +	#define CAPTURE_UNIT SZ_4K
> > +	#define CAPTURE_FLAG 0
> >  	#endif
> >  
> >  	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
> > -	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
> > +	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
> >  	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
> > -	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
> > +	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
> > +	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
> > +	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
> >  
> > -	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
> > +	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
> >  			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
> > -	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
> > +	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
> >  			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
> > +	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
> > +			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
> >  
> >  	flags = GUC_LOG_VALID |
> >  		GUC_LOG_NOTIFY_ON_HALF_FULL |
> > -		FLAG |
> > -		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> > -		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> > +		CAPTURE_FLAG |
> > +		LOG_FLAG |
> > +		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> > +		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> > +		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
> >  		(offset << GUC_LOG_BUF_ADDR_SHIFT);
> >  
> > -	#undef UNIT
> > -	#undef FLAG
> > +	#undef LOG_UNIT
> > +	#undef LOG_FLAG
> > +	#undef CAPTURE_UNIT
> > +	#undef CAPTURE_FLAG
> >  
> >  	return flags;
> >  }
> > @@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
> >  	return flags;
> >  }
> >  
> > +static u32 guc_ctl_wa_flags(struct intel_guc *guc)
> > +{
> > +	struct intel_gt *gt = guc_to_gt(guc);
> > +	u32 flags = 0;
> > +
> > +	/* Wa_22012773006:gen11,gen12 < XeHP */
> > +	if (GRAPHICS_VER(gt->i915) >= 11 &&
> > +	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
> > +		flags |= GUC_WA_POLLCS;
> > +
> > +	return flags;
> > +}
> > +
> > +static u32 guc_ctl_devid(struct intel_guc *guc)
> > +{
> > +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> > +
> > +	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
> > +}
> > +
> >  /*
> >   * Initialise the GuC parameter block before starting the firmware
> >   * transfer. These parameters are read by the firmware on startup
> > @@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
> >  	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
> >  	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
> >  	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
> > +	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
> > +	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
> >  
> >  	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
> >  		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
> > @@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
> >  	/* Make sure to handle only enabled messages */
> >  	msg = payload[0] & guc->msg_enabled_mask;
> >  
> > -	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
> > -		intel_guc_log_handle_flush_event(&guc->log);
> > +	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
> > +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
> > +	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
> > +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
> >  
> >  	return 0;
> >  }
> > @@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
> >  {
> >  	int ret;
> >  	u32 action[] = {
> > -		INTEL_GUC_ACTION_RESET_CLIENT,
> > +		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
> >  	};
> >  
> >  	if (!intel_guc_is_ready(guc))
> > @@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
> >  	return 0;
> >  }
> >  
> > +static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> > +{
> > +	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
> > +		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> > +		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
> > +	};
> > +	int ret;
> > +
> > +	GEM_BUG_ON(len > 2);
> > +	GEM_BUG_ON(len == 1 && upper_32_bits(value));
> > +
> > +	/* Self config must go over MMIO */
> > +	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> > +
> > +	if (unlikely(ret < 0))
> > +		return ret;
> > +	if (unlikely(ret > 1))
> > +		return -EPROTO;
> > +	if (unlikely(!ret))
> > +		return -ENOKEY;
> > +
> > +	return 0;
> > +}
> > +
> > +static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> > +{
> > +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> > +	int err = __guc_action_self_cfg(guc, key, len, value);
> > +
> > +	if (unlikely(err))
> > +		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
> > +				 ERR_PTR(err), key, value);
> > +	return err;
> > +}
> > +
> > +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
> > +{
> > +	return __guc_self_cfg(guc, key, 1, value);
> > +}
> > +
> > +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
> > +{
> > +	return __guc_self_cfg(guc, key, 2, value);
> > +}
> > +
> >  /**
> >   * intel_guc_load_status - dump information about GuC load status
> >   * @guc: the GuC
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index 1cb46098030d..eaa1a85a2f01 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
> >  struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
> >  int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
> >  				   struct i915_vma **out_vma, void **out_vaddr);
> > +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
> > +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
> >  
> >  static inline bool intel_guc_is_supported(struct intel_guc *guc)
> >  {
> > @@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
> >  					const u32 *msg, u32 len);
> >  int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
> >  					 const u32 *msg, u32 len);
> > +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> > +					const u32 *msg, u32 len);
> >  
> >  void intel_guc_find_hung_context(struct intel_engine_cs *engine);
> >  
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > index 1a1edae67e4e..aa767540ca2a 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > @@ -40,6 +40,10 @@
> >   *      +---------------------------------------+
> >   *      | padding                               |
> >   *      +---------------------------------------+ <== 4K aligned
> > + *      | capture lists                         |
> > + *      +---------------------------------------+
> > + *      | padding                               |
> > + *      +---------------------------------------+ <== 4K aligned
> >   *      | private data                          |
> >   *      +---------------------------------------+
> >   *      | padding                               |
> > @@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
> >  	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
> >  }
> >  
> > +static u32 guc_ads_capture_size(struct intel_guc *guc)
> > +{
> > +	/* FIXME: Allocate a proper capture list */
> > +	return PAGE_ALIGN(PAGE_SIZE);
> > +}
> > +
> >  static u32 guc_ads_private_data_size(struct intel_guc *guc)
> >  {
> >  	return PAGE_ALIGN(guc->fw.private_data_size);
> > @@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
> >  	return PAGE_ALIGN(offset);
> >  }
> >  
> > -static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> > +static u32 guc_ads_capture_offset(struct intel_guc *guc)
> >  {
> >  	u32 offset;
> >  
> > @@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> >  	return PAGE_ALIGN(offset);
> >  }
> >  
> > +static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> > +{
> > +	u32 offset;
> > +
> > +	offset = guc_ads_capture_offset(guc) +
> > +		 guc_ads_capture_size(guc);
> > +
> > +	return PAGE_ALIGN(offset);
> > +}
> > +
> >  static u32 guc_ads_blob_size(struct intel_guc *guc)
> >  {
> >  	return guc_ads_private_data_offset(guc) +
> > @@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
> >  	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
> >  }
> >  
> > +static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
> > +{
> > +	int i, j;
> > +	u32 addr_ggtt, offset;
> > +
> > +	offset = guc_ads_capture_offset(guc);
> > +	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
> > +
> > +	/* FIXME: Populate a proper capture list */
> > +
> > +	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
> > +		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
> > +			blob->ads.capture_instance[i][j] = addr_ggtt;
> > +			blob->ads.capture_class[i][j] = addr_ggtt;
> > +		}
> > +
> > +		blob->ads.capture_global[i] = addr_ggtt;
> > +	}
> > +}
> > +
> >  static void __guc_ads_init(struct intel_guc *guc)
> >  {
> >  	struct intel_gt *gt = guc_to_gt(guc);
> > @@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
> >  
> >  	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
> >  
> > +	/* Capture list for hang debug */
> > +	guc_capture_list_init(guc, blob);
> > +
> >  	/* ADS */
> >  	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
> >  	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > index a0cc34be7b56..eba03e4c815b 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > @@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
> >  	init_waitqueue_head(&ct->wq);
> >  }
> >  
> > -static inline const char *guc_ct_buffer_type_to_str(u32 type)
> > -{
> > -	switch (type) {
> > -	case GUC_CTB_TYPE_HOST2GUC:
> > -		return "SEND";
> > -	case GUC_CTB_TYPE_GUC2HOST:
> > -		return "RECV";
> > -	default:
> > -		return "<invalid>";
> > -	}
> > -}
> > -
> >  static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
> >  {
> >  	memset(desc, 0, sizeof(*desc));
> > @@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
> >  	guc_ct_buffer_reset(ctb);
> >  }
> >  
> > -static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
> > -					 u32 desc_addr, u32 buff_addr, u32 size)
> > +static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
> >  {
> > -	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
> > +	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
> >  		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> >  		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
> > +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
> > +		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
> >  	};
> >  	int ret;
> >  
> > -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> > -	GEM_BUG_ON(size % SZ_4K);
> > +	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
> >  
> > -	/* CT registration must go over MMIO */
> > +	/* CT control must go over MMIO */
> >  	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> >  
> >  	return ret > 0 ? -EPROTO : ret;
> >  }
> >  
> > -static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
> > -			      u32 desc_addr, u32 buff_addr, u32 size)
> > +static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
> >  {
> >  	int err;
> >  
> > -	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
> > +	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
> > +				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
> >  	if (unlikely(err))
> > -		return err;
> > +		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
> > +			       enabledisable(enable), ERR_PTR(err));
> >  
> > -	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
> > -					    desc_addr, buff_addr, size);
> > -	if (unlikely(err))
> > -		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> > -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> >  	return err;
> >  }
> >  
> > -static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
> > +static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
> > +			      u32 desc_addr, u32 buff_addr, u32 size)
> >  {
> > -	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
> > -		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> > -		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
> > -		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> > -	};
> > -	int ret;
> > -
> > -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> > -
> > -	/* CT deregistration must go over MMIO */
> > -	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> > +	int err;
> >  
> > -	return ret > 0 ? -EPROTO : ret;
> > -}
> > +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
> > +				   desc_addr);
> > +	if (unlikely(err))
> > +		goto failed;
> >  
> > -static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
> > -{
> > -	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
> > +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
> > +				   buff_addr);
> > +	if (unlikely(err))
> > +		goto failed;
> >  
> > +	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
> > +				   size);
> >  	if (unlikely(err))
> > -		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
> > -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> > +failed:
> > +		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> > +			       send ? "SEND" : "RECV", ERR_PTR(err));
> > +
> >  	return err;
> >  }
> >  
> > @@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
> >  int intel_guc_ct_enable(struct intel_guc_ct *ct)
> >  {
> >  	struct intel_guc *guc = ct_to_guc(ct);
> > -	u32 base, desc, cmds;
> > +	u32 base, desc, cmds, size;
> >  	void *blob;
> >  	int err;
> >  
> > @@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
> >  	 */
> >  	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
> >  	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
> > -	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
> > -				 desc, cmds, ct->ctbs.recv.size * 4);
> > -
> > +	size = ct->ctbs.recv.size * 4;
> > +	err = ct_register_buffer(ct, false, desc, cmds, size);
> >  	if (unlikely(err))
> >  		goto err_out;
> >  
> >  	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
> >  	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
> > -	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
> > -				 desc, cmds, ct->ctbs.send.size * 4);
> > +	size = ct->ctbs.send.size * 4;
> > +	err = ct_register_buffer(ct, true, desc, cmds, size);
> > +	if (unlikely(err))
> > +		goto err_out;
> >  
> > +	err = ct_control_enable(ct, true);
> >  	if (unlikely(err))
> > -		goto err_deregister;
> > +		goto err_out;
> >  
> >  	ct->enabled = true;
> >  	ct->stall_time = KTIME_MAX;
> >  
> >  	return 0;
> >  
> > -err_deregister:
> > -	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> >  err_out:
> >  	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
> >  	return err;
> > @@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
> >  	ct->enabled = false;
> >  
> >  	if (intel_guc_is_fw_running(guc)) {
> > -		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
> > -		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> > +		ct_control_enable(ct, false);
> >  	}
> >  }
> >  
> > @@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	struct ct_request request;
> >  	unsigned long flags;
> >  	unsigned int sleep_period_ms = 1;
> > +	bool send_again;
> >  	u32 fence;
> >  	int err;
> >  
> > @@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	GEM_BUG_ON(!response_buf && response_buf_size);
> >  	might_sleep();
> >  
> > +resend:
> > +	send_again = false;
> > +
> >  	/*
> >  	 * We use a lazy spin wait loop here as we believe that if the CT
> >  	 * buffers are sized correctly the flow control condition should be
> > @@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
> >  		goto unlink;
> >  	}
> >  
> > +	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
> > +		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
> > +			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
> > +		send_again = true;
> > +		goto unlink;
> > +	}
> > +
> >  	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
> >  		err = -EIO;
> >  		goto unlink;
> > @@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	list_del(&request.link);
> >  	spin_unlock_irqrestore(&ct->requests.lock, flags);
> >  
> > +	if (unlikely(send_again))
> > +		goto resend;
> > +
> >  	return err;
> >  }
> >  
> > @@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
> >  	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
> >  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
> >  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
> > +		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
> >  		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
> >  
> >  	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
> > @@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
> >  	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
> >  		ret = intel_guc_context_reset_process_msg(guc, payload, len);
> >  		break;
> > +	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
> > +		ret = intel_guc_error_capture_process_msg(guc, payload, len);
> > +		if (unlikely(ret))
> > +			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
> > +				 action, 4 * len, payload);
> > +		break;
> >  	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
> >  		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
> >  		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
> > +		intel_guc_log_handle_flush_event(&guc->log);
> > +		ret = 0;
> > +		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
> > +		CT_ERROR(ct, "Received GuC crash dump notification!\n");
> > +		ret = 0;
> > +		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
> > +		CT_ERROR(ct, "Received GuC exception notification!\n");
> > +		ret = 0;
> > +		break;
> >  	default:
> >  		ret = -EOPNOTSUPP;
> >  		break;
> > @@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
> >  		break;
> >  	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
> >  	case GUC_HXG_TYPE_RESPONSE_FAILURE:
> > +	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
> >  		err = ct_handle_response(ct, msg);
> >  		break;
> >  	default:
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > index 7072e30e99f4..6a4612a852e2 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > @@ -16,6 +16,7 @@
> >  #include "abi/guc_errors_abi.h"
> >  #include "abi/guc_communication_mmio_abi.h"
> >  #include "abi/guc_communication_ctb_abi.h"
> > +#include "abi/guc_klvs_abi.h"
> >  #include "abi/guc_messages_abi.h"
> >  
> >  /* Payload length only i.e. don't include G2H header length */
> > @@ -84,19 +85,24 @@
> >  #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
> >  
> >  #define GUC_CTL_LOG_PARAMS		0
> > -#define   GUC_LOG_VALID			(1 << 0)
> > -#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
> > -#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
> > +#define   GUC_LOG_VALID			BIT(0)
> > +#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
> > +#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
> > +#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
> >  #define   GUC_LOG_CRASH_SHIFT		4
> >  #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
> >  #define   GUC_LOG_DEBUG_SHIFT		6
> >  #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
> > +#define   GUC_LOG_CAPTURE_SHIFT		10
> > +#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
> >  #define   GUC_LOG_BUF_ADDR_SHIFT	12
> >  
> >  #define GUC_CTL_WA			1
> > +#define   GUC_WA_POLLCS                 BIT(18)
> > +
> >  #define GUC_CTL_FEATURE			2
> > -#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
> >  #define   GUC_CTL_ENABLE_SLPC		BIT(2)
> > +#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
> >  
> >  #define GUC_CTL_DEBUG			3
> >  #define   GUC_LOG_VERBOSITY_SHIFT	0
> > @@ -116,6 +122,8 @@
> >  #define   GUC_ADS_ADDR_SHIFT		1
> >  #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
> >  
> > +#define GUC_CTL_DEVID			5
> > +
> >  #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
> >  
> >  /* Generic GT SysInfo data types */
> > @@ -263,7 +271,10 @@ struct guc_mmio_reg {
> >  	u32 offset;
> >  	u32 value;
> >  	u32 flags;
> > -#define GUC_REGSET_MASKED		(1 << 0)
> > +	u32 mask;
> > +#define GUC_REGSET_MASKED		BIT(0)
> > +#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
> > +#define GUC_REGSET_RESTORE_ONLY		BIT(3)
> >  } __packed;
> >  
> >  /* GuC register sets */
> > @@ -280,6 +291,12 @@ struct guc_gt_system_info {
> >  	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
> >  } __packed;
> >  
> > +enum {
> > +	GUC_CAPTURE_LIST_INDEX_PF = 0,
> > +	GUC_CAPTURE_LIST_INDEX_VF = 1,
> > +	GUC_CAPTURE_LIST_INDEX_MAX = 2,
> > +};
> > +
> >  /* GuC Additional Data Struct */
> >  struct guc_ads {
> >  	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
> > @@ -291,7 +308,11 @@ struct guc_ads {
> >  	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
> >  	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
> >  	u32 private_data;
> > -	u32 reserved[15];
> > +	u32 reserved2;
> > +	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> > +	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> > +	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
> > +	u32 reserved[14];
> >  } __packed;
> >  
> >  /* Engine usage stats */
> > @@ -312,6 +333,7 @@ struct guc_engine_usage {
> >  enum guc_log_buffer_type {
> >  	GUC_DEBUG_LOG_BUFFER,
> >  	GUC_CRASH_DUMP_LOG_BUFFER,
> > +	GUC_CAPTURE_LOG_BUFFER,
> >  	GUC_MAX_LOG_BUFFER
> >  };
> >  
> > @@ -342,6 +364,7 @@ struct guc_log_buffer_state {
> >  	u32 write_ptr;
> >  	u32 size;
> >  	u32 sampled_write_ptr;
> > +	u32 wrap_offset;
> >  	union {
> >  		struct {
> >  			u32 flush_to_file:1;
> > @@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
> >  /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
> >  enum intel_guc_recv_message {
> >  	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
> > -	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
> > +	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
> >  };
> >  
> >  #endif
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > index ac0931f0374b..be35f0570396 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > @@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
> >  	return intel_guc_send(guc, action, ARRAY_SIZE(action));
> >  }
> >  
> > -static void guc_log_enable_flush_events(struct intel_guc_log *log)
> > -{
> > -	intel_guc_enable_msg(log_to_guc(log),
> > -			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> > -}
> > -
> > -static void guc_log_disable_flush_events(struct intel_guc_log *log)
> > -{
> > -	intel_guc_disable_msg(log_to_guc(log),
> > -			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> > -}
> > -
> >  /*
> >   * Sub buffer switch callback. Called whenever relay has to switch to a new
> >   * sub buffer, relay stays on the same sub buffer if 0 is returned.
> > @@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
> >  		return DEBUG_BUFFER_SIZE;
> >  	case GUC_CRASH_DUMP_LOG_BUFFER:
> >  		return CRASH_BUFFER_SIZE;
> > +	case GUC_CAPTURE_LOG_BUFFER:
> > +		return CAPTURE_BUFFER_SIZE;
> >  	default:
> >  		MISSING_CASE(type);
> >  	}
> > @@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
> >  	 *  +-------------------------------+ 32B
> >  	 *  |      Debug state header       |
> >  	 *  +-------------------------------+ 64B
> > +	 *  |     Capture state header      |
> > +	 *  +-------------------------------+ 96B
> >  	 *  |                               |
> >  	 *  +===============================+ PAGE_SIZE (4KB)
> >  	 *  |        Crash Dump logs        |
> >  	 *  +===============================+ + CRASH_SIZE
> >  	 *  |          Debug logs           |
> >  	 *  +===============================+ + DEBUG_SIZE
> > +	 *  |         Capture logs          |
> > +	 *  +===============================+ + CAPTURE_SIZE
> >  	 */
> > -	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
> > +	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
> > +		       CAPTURE_BUFFER_SIZE;
> >  
> >  	vma = intel_guc_allocate_vma(guc, guc_log_size);
> >  	if (IS_ERR(vma)) {
> > @@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
> >  	if (log->relay.started)
> >  		return -EEXIST;
> >  
> > -	guc_log_enable_flush_events(log);
> > -
> >  	/*
> >  	 * When GuC is logging without us relaying to userspace, we're ignoring
> >  	 * the flush notification. This means that we need to unconditionally
> > @@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
> >  	if (!log->relay.started)
> >  		return;
> >  
> > -	guc_log_disable_flush_events(log);
> >  	intel_synchronize_irq(i915);
> >  
> >  	flush_work(&log->relay.flush_work);
> > @@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
> >  
> >  void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
> >  {
> > -	queue_work(system_highpri_wq, &log->relay.flush_work);
> > +	if (log->relay.started)
> > +		queue_work(system_highpri_wq, &log->relay.flush_work);
> >  }
> >  
> >  static const char *
> > @@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
> >  		return "DEBUG";
> >  	case GUC_CRASH_DUMP_LOG_BUFFER:
> >  		return "CRASH";
> > +	case GUC_CAPTURE_LOG_BUFFER:
> > +		return "CAPTURE";
> >  	default:
> >  		MISSING_CASE(type);
> >  	}
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > index fe6ab7550a14..d7e1b6471fed 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > @@ -18,12 +18,15 @@ struct intel_guc;
> >  #if defined(CONFIG_DRM_I915_DEBUG_GUC)
> >  #define CRASH_BUFFER_SIZE	SZ_2M
> >  #define DEBUG_BUFFER_SIZE	SZ_16M
> > +#define CAPTURE_BUFFER_SIZE	SZ_4M
> >  #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
> >  #define CRASH_BUFFER_SIZE	SZ_1M
> >  #define DEBUG_BUFFER_SIZE	SZ_2M
> > +#define CAPTURE_BUFFER_SIZE	SZ_1M
> >  #else
> >  #define CRASH_BUFFER_SIZE	SZ_8K
> >  #define DEBUG_BUFFER_SIZE	SZ_64K
> > +#define CAPTURE_BUFFER_SIZE	SZ_16K
> >  #endif
> >  
> >  /*
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > index 1f9d4fde421f..4d6c1383f2eb 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
> >  	return 0;
> >  }
> >  
> > +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> > +					const u32 *msg, u32 len)
> > +{
> > +	int status;
> > +
> > +	if (unlikely(len != 1)) {
> > +		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
> > +		return -EPROTO;
> > +	}
> > +
> > +	status = msg[0];
> > +	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
> > +
> > +	/* FIXME: Do something with the capture */
> > +
> > +	return 0;
> > +}
> > +
> >  static struct intel_engine_cs *
> >  guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
> >  {
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > index a7788ce50736..9b82a5a27f90 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > @@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
> >   * firmware as TGL.
> >   */
> >  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
> > -	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
> > -	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
> > -	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
> > -	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
> > -	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
> > -	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
> > -	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
> > -	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
> > -	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
> > +	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
> > +	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
> > +	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
> > +	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
> > +	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
> > +	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
> > +	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
> > +	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
> > +	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
> >  
> >  #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
> >  	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
> > 

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

* Re: [Intel-gfx] [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0
@ 2021-12-03 23:56       ` Matthew Brost
  0 siblings, 0 replies; 29+ messages in thread
From: Matthew Brost @ 2021-12-03 23:56 UTC (permalink / raw)
  To: Michal Wajdeczko; +Cc: Intel-GFX, DRI-Devel

On Fri, Dec 03, 2021 at 11:28:00PM +0100, Michal Wajdeczko wrote:
> 
> 
> On 03.12.2021 19:33, John.C.Harrison@Intel.com wrote:
> > From: John Harrison <John.C.Harrison@Intel.com>
> > 
> > Update to the latest GuC release.
> > 
> > The latest GuC firmware introduces a number of interface changes:
> 
> Why can't we review all these changes in smaller patches and squash them
> in separate CI series *after* collecting all required r-b ?
> 
> Michal
> 

I reviewed this and it seems pretty straight forward to me.

I'm giving a RB, but we can hold up merging if you have an objection.
Likely targeting an early next week merge so please raise any concerns
before then.

With that:
Reviewed-by: Matthew Brost <matthew.brost@intel.com>

> > 
> > GuC may return NO_RESPONSE_RETRY message for requests sent over CTB.
> > Add support for this reply and try resending the request again as a
> > new CTB message.
> > 
> > A KLV (key-length-value) mechanism is now used for passing
> > configuration data such as CTB management.
> > 
> > With the new KLV scheme, the old CTB management actions are no longer
> > used and are removed.
> > 
> > Register capture on hang is now supported by GuC. Full i915 support
> > for this will be added by a later patch. A minimum support of
> > providing capture memory and register lists is required though, so add
> > that in.
> > 
> > The device id of the current platform needs to be provided at init time.
> > 
> > The 'poll CS' w/a (Wa_22012773006) was blanket enabled by previous
> > versions of GuC. It must now be explicitly requested by the KMD. So,
> > add in the code to turn it on when relevant.
> > 
> > The GuC log entry format has changed. This requires adding a new field
> > to the log header structure to mark the wrap point at the end of the
> > buffer (as the buffer size is no longer a multiple of the log entry
> > size).
> > 
> > New CTB notification messages are now sent for some things that were
> > previously only sent via MMIO notifications.
> > 
> > Of these, the crash dump notification was not really being handled by
> > i915. It called the log flush code but that only flushed the regular
> > debug log and then only if relay logging was enabled. So just report
> > an error message instead.
> > 
> > The 'exception' notification was just being ignored completely. So add
> > an error message for that as well.
> > 
> > Note that in either the crash dump or the exception case, the GuC is
> > basically dead. The KMD will detect this via the heartbeat and trigger
> > both an error log (which will include the crash dump as part of the
> > GuC log) and a GT reset. So no other processing is really required.
> > 
> > Signed-off-by: John Harrison <John.C.Harrison@Intel.com>
> > Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
> > ---
> >  Documentation/gpu/i915.rst                    |   1 +
> >  .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |  80 +++++-----
> >  drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  82 ++++++++++
> >  drivers/gpu/drm/i915/gt/uc/intel_guc.c        | 126 +++++++++++++---
> >  drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   4 +
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c    |  45 +++++-
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c     | 141 ++++++++++--------
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  37 ++++-
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_log.c    |  31 ++--
> >  drivers/gpu/drm/i915/gt/uc/intel_guc_log.h    |   3 +
> >  .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  18 +++
> >  drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  30 ++--
> >  12 files changed, 434 insertions(+), 164 deletions(-)
> >  create mode 100644 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > 
> > diff --git a/Documentation/gpu/i915.rst b/Documentation/gpu/i915.rst
> > index b7d801993bfa..bcaefc952764 100644
> > --- a/Documentation/gpu/i915.rst
> > +++ b/Documentation/gpu/i915.rst
> > @@ -539,6 +539,7 @@ GuC ABI
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_mmio_abi.h
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_communication_ctb_abi.h
> >  .. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > +.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> >  
> >  HuC
> >  ---
> > diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > index fe5d7d261797..7afdadc7656f 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h
> > @@ -7,9 +7,9 @@
> >  #define _ABI_GUC_ACTIONS_ABI_H
> >  
> >  /**
> > - * DOC: HOST2GUC_REGISTER_CTB
> > + * DOC: HOST2GUC_SELF_CFG
> >   *
> > - * This message is used as part of the `CTB based communication`_ setup.
> > + * This message is used by Host KMD to setup of the `GuC Self Config KLVs`_.
> >   *
> >   * This message must be sent as `MMIO HXG Message`_.
> >   *
> > @@ -22,20 +22,18 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 27:16 | DATA0 = MBZ                                                  |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_REGISTER_CTB` = 0x4505        |
> > + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_SELF_CFG` = 0x0508            |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> > + *  | 1 | 31:16 | **KLV_KEY** - KLV key, see `GuC Self Config KLVs`_           |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  11:8 | **TYPE** - type for the `CT Buffer`_                         |
> > + *  |   |  15:0 | **KLV_LEN** - KLV length                                     |
> >   *  |   |       |                                                              |
> > - *  |   |       |   - _`GUC_CTB_TYPE_HOST2GUC` = 0                             |
> > - *  |   |       |   - _`GUC_CTB_TYPE_GUC2HOST` = 1                             |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |   7:0 | **SIZE** - size of the `CT Buffer`_ in 4K units minus 1      |
> > + *  |   |       |   - 32 bit KLV = 1                                           |
> > + *  |   |       |   - 64 bit KLV = 2                                           |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 2 |  31:0 | **DESC_ADDR** - GGTT address of the `CTB Descriptor`_        |
> > + *  | 2 |  31:0 | **VALUE32** - Bits 31-0 of the KLV value                     |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 3 |  31:0 | **BUFF_ADDF** - GGTT address of the `CT Buffer`_             |
> > + *  | 3 |  31:0 | **VALUE64** - Bits 63-32 of the KLV value (**KLV_LEN** = 2)  |
> >   *  +---+-------+--------------------------------------------------------------+
> >   *
> >   *  +---+-------+--------------------------------------------------------------+
> > @@ -45,28 +43,25 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 30:28 | TYPE = GUC_HXG_TYPE_RESPONSE_SUCCESS_                        |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  27:0 | DATA0 = MBZ                                                  |
> > + *  |   |  27:0 | DATA0 = **NUM** - 1 if KLV was parsed, 0 if not recognized   |
> >   *  +---+-------+--------------------------------------------------------------+
> >   */
> > -#define GUC_ACTION_HOST2GUC_REGISTER_CTB		0x4505
> > +#define GUC_ACTION_HOST2GUC_SELF_CFG			0x0508
> >  
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_MBZ		(0xfffff << 12)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> > -#define   GUC_CTB_TYPE_HOST2GUC				0u
> > -#define   GUC_CTB_TYPE_GUC2HOST				1u
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE	(0xff << 0)
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> > -#define HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR	GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 3u)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY		(0xffff << 16)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN		(0xffff << 0)
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32		GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64		GUC_HXG_REQUEST_MSG_n_DATAn
> >  
> > -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > -#define HOST2GUC_REGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> > +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > +#define HOST2GUC_SELF_CFG_RESPONSE_MSG_0_NUM		GUC_HXG_RESPONSE_MSG_0_DATA0
> >  
> >  /**
> > - * DOC: HOST2GUC_DEREGISTER_CTB
> > + * DOC: HOST2GUC_CONTROL_CTB
> >   *
> > - * This message is used as part of the `CTB based communication`_ teardown.
> > + * This H2G action allows Vf Host to enable or disable H2G and G2H `CT Buffer`_.
> >   *
> >   * This message must be sent as `MMIO HXG Message`_.
> >   *
> > @@ -79,15 +74,12 @@
> >   *  |   +-------+--------------------------------------------------------------+
> >   *  |   | 27:16 | DATA0 = MBZ                                                  |
> >   *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_DEREGISTER_CTB` = 0x4506      |
> > + *  |   |  15:0 | ACTION = _`GUC_ACTION_HOST2GUC_CONTROL_CTB` = 0x4509         |
> >   *  +---+-------+--------------------------------------------------------------+
> > - *  | 1 | 31:12 | RESERVED = MBZ                                               |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |  11:8 | **TYPE** - type of the `CT Buffer`_                          |
> > + *  | 1 |  31:0 | **CONTROL** - control `CTB based communication`_             |
> >   *  |   |       |                                                              |
> > - *  |   |       | see `GUC_ACTION_HOST2GUC_REGISTER_CTB`_                      |
> > - *  |   +-------+--------------------------------------------------------------+
> > - *  |   |   7:0 | RESERVED = MBZ                                               |
> > + *  |   |       |   - _`GUC_CTB_CONTROL_DISABLE` = 0                           |
> > + *  |   |       |   - _`GUC_CTB_CONTROL_ENABLE` = 1                            |
> >   *  +---+-------+--------------------------------------------------------------+
> >   *
> >   *  +---+-------+--------------------------------------------------------------+
> > @@ -100,16 +92,16 @@
> >   *  |   |  27:0 | DATA0 = MBZ                                                  |
> >   *  +---+-------+--------------------------------------------------------------+
> >   */
> > -#define GUC_ACTION_HOST2GUC_DEREGISTER_CTB		0x4506
> > +#define GUC_ACTION_HOST2GUC_CONTROL_CTB			0x4509
> >  
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_0_MBZ	GUC_HXG_REQUEST_MSG_0_DATA0
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ	(0xfffff << 12)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE	(0xf << 8)
> > -#define HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_MBZ2	(0xff << 0)
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN		(GUC_HXG_REQUEST_MSG_MIN_LEN + 1u)
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_0_MBZ		GUC_HXG_REQUEST_MSG_0_DATA0
> > +#define HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL	GUC_HXG_REQUEST_MSG_n_DATAn
> > +#define   GUC_CTB_CONTROL_DISABLE			0u
> > +#define   GUC_CTB_CONTROL_ENABLE			1u
> >  
> > -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_LEN	GUC_HXG_RESPONSE_MSG_MIN_LEN
> > -#define HOST2GUC_DEREGISTER_CTB_RESPONSE_MSG_0_MBZ	GUC_HXG_RESPONSE_MSG_0_DATA0
> > +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_LEN		GUC_HXG_RESPONSE_MSG_MIN_LEN
> > +#define HOST2GUC_CONTROL_CTB_RESPONSE_MSG_0_MBZ		GUC_HXG_RESPONSE_MSG_0_DATA0
> >  
> >  /* legacy definitions */
> >  
> > @@ -143,8 +135,12 @@ enum intel_guc_action {
> >  	INTEL_GUC_ACTION_DEREGISTER_COMMAND_TRANSPORT_BUFFER = 0x4506,
> >  	INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
> >  	INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
> > -	INTEL_GUC_ACTION_RESET_CLIENT = 0x5507,
> > +	INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
> >  	INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
> > +	INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION = 0x8002,
> > +	INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE = 0x8003,
> > +	INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED = 0x8004,
> > +	INTEL_GUC_ACTION_NOTIFY_EXCEPTION = 0x8005,
> >  	INTEL_GUC_ACTION_LIMIT
> >  };
> >  
> > diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > new file mode 100644
> > index 000000000000..3dda88a44fc6
> > --- /dev/null
> > +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
> > @@ -0,0 +1,82 @@
> > +/* SPDX-License-Identifier: MIT */
> > +/*
> > + * Copyright © 2021 Intel Corporation
> > + */
> > +
> > +#ifndef _ABI_GUC_KLVS_ABI_H
> > +#define _ABI_GUC_KLVS_ABI_H
> > +
> > +/**
> > + * DOC: GuC KLV
> > + *
> > + *  +---+-------+--------------------------------------------------------------+
> > + *  |   | Bits  | Description                                                  |
> > + *  +===+=======+==============================================================+
> > + *  | 0 | 31:16 | **KEY** - KLV key identifier                                 |
> > + *  |   |       |   - `GuC Self Config KLVs`_                                  |
> > + *  |   |       |                                                              |
> > + *  |   +-------+--------------------------------------------------------------+
> > + *  |   |  15:0 | **LEN** - length of VALUE (in 32bit dwords)                  |
> > + *  +---+-------+--------------------------------------------------------------+
> > + *  | 1 |  31:0 | **VALUE** - actual value of the KLV (format depends on KEY)  |
> > + *  +---+-------+                                                              |
> > + *  |...|       |                                                              |
> > + *  +---+-------+                                                              |
> > + *  | n |  31:0 |                                                              |
> > + *  +---+-------+--------------------------------------------------------------+
> > + */
> > +
> > +#define GUC_KLV_LEN_MIN				1u
> > +#define GUC_KLV_0_KEY				(0xffff << 16)
> > +#define GUC_KLV_0_LEN				(0xffff << 0)
> > +#define GUC_KLV_n_VALUE				(0xffffffff << 0)
> > +
> > +/**
> > + * DOC: GuC Self Config KLVs
> > + *
> > + * `GuC KLV`_ keys available for use with HOST2GUC_SELF_CFG_.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_ADDR` : 0x0902
> > + *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
> > + *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
> > + *      Refers to size of H2G `CT Buffer`_ in bytes.
> > + *      Should be a multiple of 4K.
> > + *
> > + * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
> > + *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
> > + *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
> > + *      Should be above WOPCM address but below APIC base address for native mode.
> > + *
> > + * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
> > + *      Refers to size of G2H `CT Buffer`_ in bytes.
> > + *      Should be a multiple of 4K.
> > + */
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY		0x0902
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_ADDR_LEN		2u
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY	0x0903
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_LEN	2u
> > +
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY		0x0904
> > +#define GUC_KLV_SELF_CFG_H2G_CTB_SIZE_LEN		1u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY		0x0905
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_ADDR_LEN		2u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY	0x0906
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_LEN	2u
> > +
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY		0x0907
> > +#define GUC_KLV_SELF_CFG_G2H_CTB_SIZE_LEN		1u
> > +
> > +#endif /* _ABI_GUC_KLVS_ABI_H */
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > index 6e228343e8cb..cbec51f4dec3 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
> > @@ -182,6 +182,9 @@ void intel_guc_init_early(struct intel_guc *guc)
> >  		guc->send_regs.count = GUC_MAX_MMIO_MSG_LEN;
> >  		BUILD_BUG_ON(GUC_MAX_MMIO_MSG_LEN > SOFT_SCRATCH_COUNT);
> >  	}
> > +
> > +	intel_guc_enable_msg(guc, INTEL_GUC_RECV_MSG_EXCEPTION |
> > +				  INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> >  }
> >  
> >  void intel_guc_init_late(struct intel_guc *guc)
> > @@ -222,32 +225,48 @@ static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
> >  	u32 flags;
> >  
> >  	#if (((CRASH_BUFFER_SIZE) % SZ_1M) == 0)
> > -	#define UNIT SZ_1M
> > -	#define FLAG GUC_LOG_ALLOC_IN_MEGABYTE
> > +	#define LOG_UNIT SZ_1M
> > +	#define LOG_FLAG GUC_LOG_LOG_ALLOC_UNITS
> >  	#else
> > -	#define UNIT SZ_4K
> > -	#define FLAG 0
> > +	#define LOG_UNIT SZ_4K
> > +	#define LOG_FLAG 0
> > +	#endif
> > +
> > +	#if (((CAPTURE_BUFFER_SIZE) % SZ_1M) == 0)
> > +	#define CAPTURE_UNIT SZ_1M
> > +	#define CAPTURE_FLAG GUC_LOG_CAPTURE_ALLOC_UNITS
> > +	#else
> > +	#define CAPTURE_UNIT SZ_4K
> > +	#define CAPTURE_FLAG 0
> >  	#endif
> >  
> >  	BUILD_BUG_ON(!CRASH_BUFFER_SIZE);
> > -	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, UNIT));
> > +	BUILD_BUG_ON(!IS_ALIGNED(CRASH_BUFFER_SIZE, LOG_UNIT));
> >  	BUILD_BUG_ON(!DEBUG_BUFFER_SIZE);
> > -	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, UNIT));
> > +	BUILD_BUG_ON(!IS_ALIGNED(DEBUG_BUFFER_SIZE, LOG_UNIT));
> > +	BUILD_BUG_ON(!CAPTURE_BUFFER_SIZE);
> > +	BUILD_BUG_ON(!IS_ALIGNED(CAPTURE_BUFFER_SIZE, CAPTURE_UNIT));
> >  
> > -	BUILD_BUG_ON((CRASH_BUFFER_SIZE / UNIT - 1) >
> > +	BUILD_BUG_ON((CRASH_BUFFER_SIZE / LOG_UNIT - 1) >
> >  			(GUC_LOG_CRASH_MASK >> GUC_LOG_CRASH_SHIFT));
> > -	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / UNIT - 1) >
> > +	BUILD_BUG_ON((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) >
> >  			(GUC_LOG_DEBUG_MASK >> GUC_LOG_DEBUG_SHIFT));
> > +	BUILD_BUG_ON((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) >
> > +			(GUC_LOG_CAPTURE_MASK >> GUC_LOG_CAPTURE_SHIFT));
> >  
> >  	flags = GUC_LOG_VALID |
> >  		GUC_LOG_NOTIFY_ON_HALF_FULL |
> > -		FLAG |
> > -		((CRASH_BUFFER_SIZE / UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> > -		((DEBUG_BUFFER_SIZE / UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> > +		CAPTURE_FLAG |
> > +		LOG_FLAG |
> > +		((CRASH_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_CRASH_SHIFT) |
> > +		((DEBUG_BUFFER_SIZE / LOG_UNIT - 1) << GUC_LOG_DEBUG_SHIFT) |
> > +		((CAPTURE_BUFFER_SIZE / CAPTURE_UNIT - 1) << GUC_LOG_CAPTURE_SHIFT) |
> >  		(offset << GUC_LOG_BUF_ADDR_SHIFT);
> >  
> > -	#undef UNIT
> > -	#undef FLAG
> > +	#undef LOG_UNIT
> > +	#undef LOG_FLAG
> > +	#undef CAPTURE_UNIT
> > +	#undef CAPTURE_FLAG
> >  
> >  	return flags;
> >  }
> > @@ -260,6 +279,26 @@ static u32 guc_ctl_ads_flags(struct intel_guc *guc)
> >  	return flags;
> >  }
> >  
> > +static u32 guc_ctl_wa_flags(struct intel_guc *guc)
> > +{
> > +	struct intel_gt *gt = guc_to_gt(guc);
> > +	u32 flags = 0;
> > +
> > +	/* Wa_22012773006:gen11,gen12 < XeHP */
> > +	if (GRAPHICS_VER(gt->i915) >= 11 &&
> > +	    GRAPHICS_VER_FULL(gt->i915) < IP_VER(12, 50))
> > +		flags |= GUC_WA_POLLCS;
> > +
> > +	return flags;
> > +}
> > +
> > +static u32 guc_ctl_devid(struct intel_guc *guc)
> > +{
> > +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> > +
> > +	return (INTEL_DEVID(i915) << 16) | INTEL_REVID(i915);
> > +}
> > +
> >  /*
> >   * Initialise the GuC parameter block before starting the firmware
> >   * transfer. These parameters are read by the firmware on startup
> > @@ -276,6 +315,8 @@ static void guc_init_params(struct intel_guc *guc)
> >  	params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
> >  	params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);
> >  	params[GUC_CTL_ADS] = guc_ctl_ads_flags(guc);
> > +	params[GUC_CTL_WA] = guc_ctl_wa_flags(guc);
> > +	params[GUC_CTL_DEVID] = guc_ctl_devid(guc);
> >  
> >  	for (i = 0; i < GUC_CTL_MAX_DWORDS; i++)
> >  		DRM_DEBUG_DRIVER("param[%2d] = %#x\n", i, params[i]);
> > @@ -513,9 +554,10 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
> >  	/* Make sure to handle only enabled messages */
> >  	msg = payload[0] & guc->msg_enabled_mask;
> >  
> > -	if (msg & (INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -		   INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED))
> > -		intel_guc_log_handle_flush_event(&guc->log);
> > +	if (msg & INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED)
> > +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC crash dump notification!\n");
> > +	if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
> > +		drm_err(&guc_to_gt(guc)->i915->drm, "Received early GuC exception notification!\n");
> >  
> >  	return 0;
> >  }
> > @@ -549,7 +591,7 @@ int intel_guc_suspend(struct intel_guc *guc)
> >  {
> >  	int ret;
> >  	u32 action[] = {
> > -		INTEL_GUC_ACTION_RESET_CLIENT,
> > +		INTEL_GUC_ACTION_CLIENT_SOFT_RESET,
> >  	};
> >  
> >  	if (!intel_guc_is_ready(guc))
> > @@ -713,6 +755,56 @@ int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
> >  	return 0;
> >  }
> >  
> > +static int __guc_action_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> > +{
> > +	u32 request[HOST2GUC_SELF_CFG_REQUEST_MSG_LEN] = {
> > +		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> > +		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_SELF_CFG),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_KEY, key) |
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_1_KLV_LEN, len),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_2_VALUE32, lower_32_bits(value)),
> > +		FIELD_PREP(HOST2GUC_SELF_CFG_REQUEST_MSG_3_VALUE64, upper_32_bits(value)),
> > +	};
> > +	int ret;
> > +
> > +	GEM_BUG_ON(len > 2);
> > +	GEM_BUG_ON(len == 1 && upper_32_bits(value));
> > +
> > +	/* Self config must go over MMIO */
> > +	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> > +
> > +	if (unlikely(ret < 0))
> > +		return ret;
> > +	if (unlikely(ret > 1))
> > +		return -EPROTO;
> > +	if (unlikely(!ret))
> > +		return -ENOKEY;
> > +
> > +	return 0;
> > +}
> > +
> > +static int __guc_self_cfg(struct intel_guc *guc, u16 key, u16 len, u64 value)
> > +{
> > +	struct drm_i915_private *i915 = guc_to_gt(guc)->i915;
> > +	int err = __guc_action_self_cfg(guc, key, len, value);
> > +
> > +	if (unlikely(err))
> > +		i915_probe_error(i915, "Unsuccessful self-config (%pe) key %#hx value %#llx\n",
> > +				 ERR_PTR(err), key, value);
> > +	return err;
> > +}
> > +
> > +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value)
> > +{
> > +	return __guc_self_cfg(guc, key, 1, value);
> > +}
> > +
> > +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value)
> > +{
> > +	return __guc_self_cfg(guc, key, 2, value);
> > +}
> > +
> >  /**
> >   * intel_guc_load_status - dump information about GuC load status
> >   * @guc: the GuC
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > index 1cb46098030d..eaa1a85a2f01 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
> > @@ -316,6 +316,8 @@ int intel_guc_resume(struct intel_guc *guc);
> >  struct i915_vma *intel_guc_allocate_vma(struct intel_guc *guc, u32 size);
> >  int intel_guc_allocate_and_map_vma(struct intel_guc *guc, u32 size,
> >  				   struct i915_vma **out_vma, void **out_vaddr);
> > +int intel_guc_self_cfg32(struct intel_guc *guc, u16 key, u32 value);
> > +int intel_guc_self_cfg64(struct intel_guc *guc, u16 key, u64 value);
> >  
> >  static inline bool intel_guc_is_supported(struct intel_guc *guc)
> >  {
> > @@ -392,6 +394,8 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
> >  					const u32 *msg, u32 len);
> >  int intel_guc_engine_failure_process_msg(struct intel_guc *guc,
> >  					 const u32 *msg, u32 len);
> > +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> > +					const u32 *msg, u32 len);
> >  
> >  void intel_guc_find_hung_context(struct intel_engine_cs *engine);
> >  
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > index 1a1edae67e4e..aa767540ca2a 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
> > @@ -40,6 +40,10 @@
> >   *      +---------------------------------------+
> >   *      | padding                               |
> >   *      +---------------------------------------+ <== 4K aligned
> > + *      | capture lists                         |
> > + *      +---------------------------------------+
> > + *      | padding                               |
> > + *      +---------------------------------------+ <== 4K aligned
> >   *      | private data                          |
> >   *      +---------------------------------------+
> >   *      | padding                               |
> > @@ -65,6 +69,12 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
> >  	return PAGE_ALIGN(guc->ads_golden_ctxt_size);
> >  }
> >  
> > +static u32 guc_ads_capture_size(struct intel_guc *guc)
> > +{
> > +	/* FIXME: Allocate a proper capture list */
> > +	return PAGE_ALIGN(PAGE_SIZE);
> > +}
> > +
> >  static u32 guc_ads_private_data_size(struct intel_guc *guc)
> >  {
> >  	return PAGE_ALIGN(guc->fw.private_data_size);
> > @@ -85,7 +95,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
> >  	return PAGE_ALIGN(offset);
> >  }
> >  
> > -static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> > +static u32 guc_ads_capture_offset(struct intel_guc *guc)
> >  {
> >  	u32 offset;
> >  
> > @@ -95,6 +105,16 @@ static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> >  	return PAGE_ALIGN(offset);
> >  }
> >  
> > +static u32 guc_ads_private_data_offset(struct intel_guc *guc)
> > +{
> > +	u32 offset;
> > +
> > +	offset = guc_ads_capture_offset(guc) +
> > +		 guc_ads_capture_size(guc);
> > +
> > +	return PAGE_ALIGN(offset);
> > +}
> > +
> >  static u32 guc_ads_blob_size(struct intel_guc *guc)
> >  {
> >  	return guc_ads_private_data_offset(guc) +
> > @@ -499,6 +519,26 @@ static void guc_init_golden_context(struct intel_guc *guc)
> >  	GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
> >  }
> >  
> > +static void guc_capture_list_init(struct intel_guc *guc, struct __guc_ads_blob *blob)
> > +{
> > +	int i, j;
> > +	u32 addr_ggtt, offset;
> > +
> > +	offset = guc_ads_capture_offset(guc);
> > +	addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
> > +
> > +	/* FIXME: Populate a proper capture list */
> > +
> > +	for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
> > +		for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
> > +			blob->ads.capture_instance[i][j] = addr_ggtt;
> > +			blob->ads.capture_class[i][j] = addr_ggtt;
> > +		}
> > +
> > +		blob->ads.capture_global[i] = addr_ggtt;
> > +	}
> > +}
> > +
> >  static void __guc_ads_init(struct intel_guc *guc)
> >  {
> >  	struct intel_gt *gt = guc_to_gt(guc);
> > @@ -532,6 +572,9 @@ static void __guc_ads_init(struct intel_guc *guc)
> >  
> >  	base = intel_guc_ggtt_offset(guc, guc->ads_vma);
> >  
> > +	/* Capture list for hang debug */
> > +	guc_capture_list_init(guc, blob);
> > +
> >  	/* ADS */
> >  	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
> >  	blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > index a0cc34be7b56..eba03e4c815b 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
> > @@ -112,18 +112,6 @@ void intel_guc_ct_init_early(struct intel_guc_ct *ct)
> >  	init_waitqueue_head(&ct->wq);
> >  }
> >  
> > -static inline const char *guc_ct_buffer_type_to_str(u32 type)
> > -{
> > -	switch (type) {
> > -	case GUC_CTB_TYPE_HOST2GUC:
> > -		return "SEND";
> > -	case GUC_CTB_TYPE_GUC2HOST:
> > -		return "RECV";
> > -	default:
> > -		return "<invalid>";
> > -	}
> > -}
> > -
> >  static void guc_ct_buffer_desc_init(struct guc_ct_buffer_desc *desc)
> >  {
> >  	memset(desc, 0, sizeof(*desc));
> > @@ -156,71 +144,65 @@ static void guc_ct_buffer_init(struct intel_guc_ct_buffer *ctb,
> >  	guc_ct_buffer_reset(ctb);
> >  }
> >  
> > -static int guc_action_register_ct_buffer(struct intel_guc *guc, u32 type,
> > -					 u32 desc_addr, u32 buff_addr, u32 size)
> > +static int guc_action_control_ctb(struct intel_guc *guc, u32 control)
> >  {
> > -	u32 request[HOST2GUC_REGISTER_CTB_REQUEST_MSG_LEN] = {
> > +	u32 request[HOST2GUC_CONTROL_CTB_REQUEST_MSG_LEN] = {
> >  		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> >  		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_REGISTER_CTB),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_SIZE, size / SZ_4K - 1) |
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_2_DESC_ADDR, desc_addr),
> > -		FIELD_PREP(HOST2GUC_REGISTER_CTB_REQUEST_MSG_3_BUFF_ADDR, buff_addr),
> > +		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_CONTROL_CTB),
> > +		FIELD_PREP(HOST2GUC_CONTROL_CTB_REQUEST_MSG_1_CONTROL, control),
> >  	};
> >  	int ret;
> >  
> > -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> > -	GEM_BUG_ON(size % SZ_4K);
> > +	GEM_BUG_ON(control != GUC_CTB_CONTROL_DISABLE && control != GUC_CTB_CONTROL_ENABLE);
> >  
> > -	/* CT registration must go over MMIO */
> > +	/* CT control must go over MMIO */
> >  	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> >  
> >  	return ret > 0 ? -EPROTO : ret;
> >  }
> >  
> > -static int ct_register_buffer(struct intel_guc_ct *ct, u32 type,
> > -			      u32 desc_addr, u32 buff_addr, u32 size)
> > +static int ct_control_enable(struct intel_guc_ct *ct, bool enable)
> >  {
> >  	int err;
> >  
> > -	err = i915_inject_probe_error(guc_to_gt(ct_to_guc(ct))->i915, -ENXIO);
> > +	err = guc_action_control_ctb(ct_to_guc(ct), enable ?
> > +				     GUC_CTB_CONTROL_ENABLE : GUC_CTB_CONTROL_DISABLE);
> >  	if (unlikely(err))
> > -		return err;
> > +		CT_PROBE_ERROR(ct, "Failed to control/%s CTB (%pe)\n",
> > +			       enabledisable(enable), ERR_PTR(err));
> >  
> > -	err = guc_action_register_ct_buffer(ct_to_guc(ct), type,
> > -					    desc_addr, buff_addr, size);
> > -	if (unlikely(err))
> > -		CT_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> > -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> >  	return err;
> >  }
> >  
> > -static int guc_action_deregister_ct_buffer(struct intel_guc *guc, u32 type)
> > +static int ct_register_buffer(struct intel_guc_ct *ct, bool send,
> > +			      u32 desc_addr, u32 buff_addr, u32 size)
> >  {
> > -	u32 request[HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_LEN] = {
> > -		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
> > -		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
> > -		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_HOST2GUC_DEREGISTER_CTB),
> > -		FIELD_PREP(HOST2GUC_DEREGISTER_CTB_REQUEST_MSG_1_TYPE, type),
> > -	};
> > -	int ret;
> > -
> > -	GEM_BUG_ON(type != GUC_CTB_TYPE_HOST2GUC && type != GUC_CTB_TYPE_GUC2HOST);
> > -
> > -	/* CT deregistration must go over MMIO */
> > -	ret = intel_guc_send_mmio(guc, request, ARRAY_SIZE(request), NULL, 0);
> > +	int err;
> >  
> > -	return ret > 0 ? -EPROTO : ret;
> > -}
> > +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR_KEY,
> > +				   desc_addr);
> > +	if (unlikely(err))
> > +		goto failed;
> >  
> > -static int ct_deregister_buffer(struct intel_guc_ct *ct, u32 type)
> > -{
> > -	int err = guc_action_deregister_ct_buffer(ct_to_guc(ct), type);
> > +	err = intel_guc_self_cfg64(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_ADDR_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_ADDR_KEY,
> > +				   buff_addr);
> > +	if (unlikely(err))
> > +		goto failed;
> >  
> > +	err = intel_guc_self_cfg32(ct_to_guc(ct), send ?
> > +				   GUC_KLV_SELF_CFG_H2G_CTB_SIZE_KEY :
> > +				   GUC_KLV_SELF_CFG_G2H_CTB_SIZE_KEY,
> > +				   size);
> >  	if (unlikely(err))
> > -		CT_ERROR(ct, "Failed to deregister %s buffer (%pe)\n",
> > -			 guc_ct_buffer_type_to_str(type), ERR_PTR(err));
> > +failed:
> > +		CT_PROBE_ERROR(ct, "Failed to register %s buffer (%pe)\n",
> > +			       send ? "SEND" : "RECV", ERR_PTR(err));
> > +
> >  	return err;
> >  }
> >  
> > @@ -308,7 +290,7 @@ void intel_guc_ct_fini(struct intel_guc_ct *ct)
> >  int intel_guc_ct_enable(struct intel_guc_ct *ct)
> >  {
> >  	struct intel_guc *guc = ct_to_guc(ct);
> > -	u32 base, desc, cmds;
> > +	u32 base, desc, cmds, size;
> >  	void *blob;
> >  	int err;
> >  
> > @@ -333,27 +315,27 @@ int intel_guc_ct_enable(struct intel_guc_ct *ct)
> >  	 */
> >  	desc = base + ptrdiff(ct->ctbs.recv.desc, blob);
> >  	cmds = base + ptrdiff(ct->ctbs.recv.cmds, blob);
> > -	err = ct_register_buffer(ct, GUC_CTB_TYPE_GUC2HOST,
> > -				 desc, cmds, ct->ctbs.recv.size * 4);
> > -
> > +	size = ct->ctbs.recv.size * 4;
> > +	err = ct_register_buffer(ct, false, desc, cmds, size);
> >  	if (unlikely(err))
> >  		goto err_out;
> >  
> >  	desc = base + ptrdiff(ct->ctbs.send.desc, blob);
> >  	cmds = base + ptrdiff(ct->ctbs.send.cmds, blob);
> > -	err = ct_register_buffer(ct, GUC_CTB_TYPE_HOST2GUC,
> > -				 desc, cmds, ct->ctbs.send.size * 4);
> > +	size = ct->ctbs.send.size * 4;
> > +	err = ct_register_buffer(ct, true, desc, cmds, size);
> > +	if (unlikely(err))
> > +		goto err_out;
> >  
> > +	err = ct_control_enable(ct, true);
> >  	if (unlikely(err))
> > -		goto err_deregister;
> > +		goto err_out;
> >  
> >  	ct->enabled = true;
> >  	ct->stall_time = KTIME_MAX;
> >  
> >  	return 0;
> >  
> > -err_deregister:
> > -	ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> >  err_out:
> >  	CT_PROBE_ERROR(ct, "Failed to enable CTB (%pe)\n", ERR_PTR(err));
> >  	return err;
> > @@ -372,8 +354,7 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
> >  	ct->enabled = false;
> >  
> >  	if (intel_guc_is_fw_running(guc)) {
> > -		ct_deregister_buffer(ct, GUC_CTB_TYPE_HOST2GUC);
> > -		ct_deregister_buffer(ct, GUC_CTB_TYPE_GUC2HOST);
> > +		ct_control_enable(ct, false);
> >  	}
> >  }
> >  
> > @@ -646,6 +627,7 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	struct ct_request request;
> >  	unsigned long flags;
> >  	unsigned int sleep_period_ms = 1;
> > +	bool send_again;
> >  	u32 fence;
> >  	int err;
> >  
> > @@ -655,6 +637,9 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	GEM_BUG_ON(!response_buf && response_buf_size);
> >  	might_sleep();
> >  
> > +resend:
> > +	send_again = false;
> > +
> >  	/*
> >  	 * We use a lazy spin wait loop here as we believe that if the CT
> >  	 * buffers are sized correctly the flow control condition should be
> > @@ -709,6 +694,13 @@ static int ct_send(struct intel_guc_ct *ct,
> >  		goto unlink;
> >  	}
> >  
> > +	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) == GUC_HXG_TYPE_NO_RESPONSE_RETRY) {
> > +		CT_DEBUG(ct, "retrying request %#x (%u)\n", *action,
> > +			 FIELD_GET(GUC_HXG_RETRY_MSG_0_REASON, *status));
> > +		send_again = true;
> > +		goto unlink;
> > +	}
> > +
> >  	if (FIELD_GET(GUC_HXG_MSG_0_TYPE, *status) != GUC_HXG_TYPE_RESPONSE_SUCCESS) {
> >  		err = -EIO;
> >  		goto unlink;
> > @@ -731,6 +723,9 @@ static int ct_send(struct intel_guc_ct *ct,
> >  	list_del(&request.link);
> >  	spin_unlock_irqrestore(&ct->requests.lock, flags);
> >  
> > +	if (unlikely(send_again))
> > +		goto resend;
> > +
> >  	return err;
> >  }
> >  
> > @@ -902,6 +897,7 @@ static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg *r
> >  	GEM_BUG_ON(len < GUC_HXG_MSG_MIN_LEN);
> >  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_ORIGIN, hxg[0]) != GUC_HXG_ORIGIN_GUC);
> >  	GEM_BUG_ON(FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_SUCCESS &&
> > +		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_NO_RESPONSE_RETRY &&
> >  		   FIELD_GET(GUC_HXG_MSG_0_TYPE, hxg[0]) != GUC_HXG_TYPE_RESPONSE_FAILURE);
> >  
> >  	CT_DEBUG(ct, "response fence %u status %#x\n", fence, hxg[0]);
> > @@ -974,9 +970,27 @@ static int ct_process_request(struct intel_guc_ct *ct, struct ct_incoming_msg *r
> >  	case INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION:
> >  		ret = intel_guc_context_reset_process_msg(guc, payload, len);
> >  		break;
> > +	case INTEL_GUC_ACTION_STATE_CAPTURE_NOTIFICATION:
> > +		ret = intel_guc_error_capture_process_msg(guc, payload, len);
> > +		if (unlikely(ret))
> > +			CT_ERROR(ct, "error capture notification failed %x %*ph\n",
> > +				 action, 4 * len, payload);
> > +		break;
> >  	case INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION:
> >  		ret = intel_guc_engine_failure_process_msg(guc, payload, len);
> >  		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_FLUSH_LOG_BUFFER_TO_FILE:
> > +		intel_guc_log_handle_flush_event(&guc->log);
> > +		ret = 0;
> > +		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED:
> > +		CT_ERROR(ct, "Received GuC crash dump notification!\n");
> > +		ret = 0;
> > +		break;
> > +	case INTEL_GUC_ACTION_NOTIFY_EXCEPTION:
> > +		CT_ERROR(ct, "Received GuC exception notification!\n");
> > +		ret = 0;
> > +		break;
> >  	default:
> >  		ret = -EOPNOTSUPP;
> >  		break;
> > @@ -1082,6 +1096,7 @@ static int ct_handle_hxg(struct intel_guc_ct *ct, struct ct_incoming_msg *msg)
> >  		break;
> >  	case GUC_HXG_TYPE_RESPONSE_SUCCESS:
> >  	case GUC_HXG_TYPE_RESPONSE_FAILURE:
> > +	case GUC_HXG_TYPE_NO_RESPONSE_RETRY:
> >  		err = ct_handle_response(ct, msg);
> >  		break;
> >  	default:
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > index 7072e30e99f4..6a4612a852e2 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
> > @@ -16,6 +16,7 @@
> >  #include "abi/guc_errors_abi.h"
> >  #include "abi/guc_communication_mmio_abi.h"
> >  #include "abi/guc_communication_ctb_abi.h"
> > +#include "abi/guc_klvs_abi.h"
> >  #include "abi/guc_messages_abi.h"
> >  
> >  /* Payload length only i.e. don't include G2H header length */
> > @@ -84,19 +85,24 @@
> >  #define GUC_STAGE_DESC_ATTR_TERMINATED	BIT(7)
> >  
> >  #define GUC_CTL_LOG_PARAMS		0
> > -#define   GUC_LOG_VALID			(1 << 0)
> > -#define   GUC_LOG_NOTIFY_ON_HALF_FULL	(1 << 1)
> > -#define   GUC_LOG_ALLOC_IN_MEGABYTE	(1 << 3)
> > +#define   GUC_LOG_VALID			BIT(0)
> > +#define   GUC_LOG_NOTIFY_ON_HALF_FULL	BIT(1)
> > +#define   GUC_LOG_CAPTURE_ALLOC_UNITS	BIT(2)
> > +#define   GUC_LOG_LOG_ALLOC_UNITS	BIT(3)
> >  #define   GUC_LOG_CRASH_SHIFT		4
> >  #define   GUC_LOG_CRASH_MASK		(0x3 << GUC_LOG_CRASH_SHIFT)
> >  #define   GUC_LOG_DEBUG_SHIFT		6
> >  #define   GUC_LOG_DEBUG_MASK	        (0xF << GUC_LOG_DEBUG_SHIFT)
> > +#define   GUC_LOG_CAPTURE_SHIFT		10
> > +#define   GUC_LOG_CAPTURE_MASK	        (0x3 << GUC_LOG_CAPTURE_SHIFT)
> >  #define   GUC_LOG_BUF_ADDR_SHIFT	12
> >  
> >  #define GUC_CTL_WA			1
> > +#define   GUC_WA_POLLCS                 BIT(18)
> > +
> >  #define GUC_CTL_FEATURE			2
> > -#define   GUC_CTL_DISABLE_SCHEDULER	(1 << 14)
> >  #define   GUC_CTL_ENABLE_SLPC		BIT(2)
> > +#define   GUC_CTL_DISABLE_SCHEDULER	BIT(14)
> >  
> >  #define GUC_CTL_DEBUG			3
> >  #define   GUC_LOG_VERBOSITY_SHIFT	0
> > @@ -116,6 +122,8 @@
> >  #define   GUC_ADS_ADDR_SHIFT		1
> >  #define   GUC_ADS_ADDR_MASK		(0xFFFFF << GUC_ADS_ADDR_SHIFT)
> >  
> > +#define GUC_CTL_DEVID			5
> > +
> >  #define GUC_CTL_MAX_DWORDS		(SOFT_SCRATCH_COUNT - 2) /* [1..14] */
> >  
> >  /* Generic GT SysInfo data types */
> > @@ -263,7 +271,10 @@ struct guc_mmio_reg {
> >  	u32 offset;
> >  	u32 value;
> >  	u32 flags;
> > -#define GUC_REGSET_MASKED		(1 << 0)
> > +	u32 mask;
> > +#define GUC_REGSET_MASKED		BIT(0)
> > +#define GUC_REGSET_MASKED_WITH_VALUE	BIT(2)
> > +#define GUC_REGSET_RESTORE_ONLY		BIT(3)
> >  } __packed;
> >  
> >  /* GuC register sets */
> > @@ -280,6 +291,12 @@ struct guc_gt_system_info {
> >  	u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
> >  } __packed;
> >  
> > +enum {
> > +	GUC_CAPTURE_LIST_INDEX_PF = 0,
> > +	GUC_CAPTURE_LIST_INDEX_VF = 1,
> > +	GUC_CAPTURE_LIST_INDEX_MAX = 2,
> > +};
> > +
> >  /* GuC Additional Data Struct */
> >  struct guc_ads {
> >  	struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
> > @@ -291,7 +308,11 @@ struct guc_ads {
> >  	u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
> >  	u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
> >  	u32 private_data;
> > -	u32 reserved[15];
> > +	u32 reserved2;
> > +	u32 capture_instance[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> > +	u32 capture_class[GUC_CAPTURE_LIST_INDEX_MAX][GUC_MAX_ENGINE_CLASSES];
> > +	u32 capture_global[GUC_CAPTURE_LIST_INDEX_MAX];
> > +	u32 reserved[14];
> >  } __packed;
> >  
> >  /* Engine usage stats */
> > @@ -312,6 +333,7 @@ struct guc_engine_usage {
> >  enum guc_log_buffer_type {
> >  	GUC_DEBUG_LOG_BUFFER,
> >  	GUC_CRASH_DUMP_LOG_BUFFER,
> > +	GUC_CAPTURE_LOG_BUFFER,
> >  	GUC_MAX_LOG_BUFFER
> >  };
> >  
> > @@ -342,6 +364,7 @@ struct guc_log_buffer_state {
> >  	u32 write_ptr;
> >  	u32 size;
> >  	u32 sampled_write_ptr;
> > +	u32 wrap_offset;
> >  	union {
> >  		struct {
> >  			u32 flush_to_file:1;
> > @@ -382,7 +405,7 @@ struct guc_shared_ctx_data {
> >  /* This action will be programmed in C1BC - SOFT_SCRATCH_15_REG */
> >  enum intel_guc_recv_message {
> >  	INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED = BIT(1),
> > -	INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER = BIT(3)
> > +	INTEL_GUC_RECV_MSG_EXCEPTION = BIT(30),
> >  };
> >  
> >  #endif
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > index ac0931f0374b..be35f0570396 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.c
> > @@ -55,20 +55,6 @@ static int guc_action_control_log(struct intel_guc *guc, bool enable,
> >  	return intel_guc_send(guc, action, ARRAY_SIZE(action));
> >  }
> >  
> > -static void guc_log_enable_flush_events(struct intel_guc_log *log)
> > -{
> > -	intel_guc_enable_msg(log_to_guc(log),
> > -			     INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -			     INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> > -}
> > -
> > -static void guc_log_disable_flush_events(struct intel_guc_log *log)
> > -{
> > -	intel_guc_disable_msg(log_to_guc(log),
> > -			      INTEL_GUC_RECV_MSG_FLUSH_LOG_BUFFER |
> > -			      INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED);
> > -}
> > -
> >  /*
> >   * Sub buffer switch callback. Called whenever relay has to switch to a new
> >   * sub buffer, relay stays on the same sub buffer if 0 is returned.
> > @@ -201,6 +187,8 @@ static unsigned int guc_get_log_buffer_size(enum guc_log_buffer_type type)
> >  		return DEBUG_BUFFER_SIZE;
> >  	case GUC_CRASH_DUMP_LOG_BUFFER:
> >  		return CRASH_BUFFER_SIZE;
> > +	case GUC_CAPTURE_LOG_BUFFER:
> > +		return CAPTURE_BUFFER_SIZE;
> >  	default:
> >  		MISSING_CASE(type);
> >  	}
> > @@ -463,14 +451,19 @@ int intel_guc_log_create(struct intel_guc_log *log)
> >  	 *  +-------------------------------+ 32B
> >  	 *  |      Debug state header       |
> >  	 *  +-------------------------------+ 64B
> > +	 *  |     Capture state header      |
> > +	 *  +-------------------------------+ 96B
> >  	 *  |                               |
> >  	 *  +===============================+ PAGE_SIZE (4KB)
> >  	 *  |        Crash Dump logs        |
> >  	 *  +===============================+ + CRASH_SIZE
> >  	 *  |          Debug logs           |
> >  	 *  +===============================+ + DEBUG_SIZE
> > +	 *  |         Capture logs          |
> > +	 *  +===============================+ + CAPTURE_SIZE
> >  	 */
> > -	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE;
> > +	guc_log_size = PAGE_SIZE + CRASH_BUFFER_SIZE + DEBUG_BUFFER_SIZE +
> > +		       CAPTURE_BUFFER_SIZE;
> >  
> >  	vma = intel_guc_allocate_vma(guc, guc_log_size);
> >  	if (IS_ERR(vma)) {
> > @@ -592,8 +585,6 @@ int intel_guc_log_relay_start(struct intel_guc_log *log)
> >  	if (log->relay.started)
> >  		return -EEXIST;
> >  
> > -	guc_log_enable_flush_events(log);
> > -
> >  	/*
> >  	 * When GuC is logging without us relaying to userspace, we're ignoring
> >  	 * the flush notification. This means that we need to unconditionally
> > @@ -640,7 +631,6 @@ static void guc_log_relay_stop(struct intel_guc_log *log)
> >  	if (!log->relay.started)
> >  		return;
> >  
> > -	guc_log_disable_flush_events(log);
> >  	intel_synchronize_irq(i915);
> >  
> >  	flush_work(&log->relay.flush_work);
> > @@ -661,7 +651,8 @@ void intel_guc_log_relay_close(struct intel_guc_log *log)
> >  
> >  void intel_guc_log_handle_flush_event(struct intel_guc_log *log)
> >  {
> > -	queue_work(system_highpri_wq, &log->relay.flush_work);
> > +	if (log->relay.started)
> > +		queue_work(system_highpri_wq, &log->relay.flush_work);
> >  }
> >  
> >  static const char *
> > @@ -672,6 +663,8 @@ stringify_guc_log_type(enum guc_log_buffer_type type)
> >  		return "DEBUG";
> >  	case GUC_CRASH_DUMP_LOG_BUFFER:
> >  		return "CRASH";
> > +	case GUC_CAPTURE_LOG_BUFFER:
> > +		return "CAPTURE";
> >  	default:
> >  		MISSING_CASE(type);
> >  	}
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > index fe6ab7550a14..d7e1b6471fed 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_log.h
> > @@ -18,12 +18,15 @@ struct intel_guc;
> >  #if defined(CONFIG_DRM_I915_DEBUG_GUC)
> >  #define CRASH_BUFFER_SIZE	SZ_2M
> >  #define DEBUG_BUFFER_SIZE	SZ_16M
> > +#define CAPTURE_BUFFER_SIZE	SZ_4M
> >  #elif defined(CONFIG_DRM_I915_DEBUG_GEM)
> >  #define CRASH_BUFFER_SIZE	SZ_1M
> >  #define DEBUG_BUFFER_SIZE	SZ_2M
> > +#define CAPTURE_BUFFER_SIZE	SZ_1M
> >  #else
> >  #define CRASH_BUFFER_SIZE	SZ_8K
> >  #define DEBUG_BUFFER_SIZE	SZ_64K
> > +#define CAPTURE_BUFFER_SIZE	SZ_16K
> >  #endif
> >  
> >  /*
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > index 1f9d4fde421f..4d6c1383f2eb 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
> > @@ -4002,6 +4002,24 @@ int intel_guc_context_reset_process_msg(struct intel_guc *guc,
> >  	return 0;
> >  }
> >  
> > +int intel_guc_error_capture_process_msg(struct intel_guc *guc,
> > +					const u32 *msg, u32 len)
> > +{
> > +	int status;
> > +
> > +	if (unlikely(len != 1)) {
> > +		drm_dbg(&guc_to_gt(guc)->i915->drm, "Invalid length %u", len);
> > +		return -EPROTO;
> > +	}
> > +
> > +	status = msg[0];
> > +	drm_info(&guc_to_gt(guc)->i915->drm, "Got error capture: status = %d", status);
> > +
> > +	/* FIXME: Do something with the capture */
> > +
> > +	return 0;
> > +}
> > +
> >  static struct intel_engine_cs *
> >  guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance)
> >  {
> > diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > index a7788ce50736..9b82a5a27f90 100644
> > --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> > @@ -49,21 +49,21 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
> >   * firmware as TGL.
> >   */
> >  #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
> > -	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
> > -	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
> > -	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
> > -	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
> > -	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
> > -	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
> > -	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
> > -	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
> > -	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
> > -	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
> > -	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
> > +	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 0)) \
> > +	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(DG1,          0, guc_def(dg1,  69, 0, 0)) \
> > +	fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 0)) \
> > +	fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 0)) \
> > +	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 0)) \
> > +	fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 0)) \
> > +	fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 0)) \
> > +	fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 0)) \
> > +	fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 0)) \
> > +	fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 0)) \
> > +	fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 0))
> >  
> >  #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
> >  	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
> > 

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

* [Intel-gfx] ✗ Fi.CI.IGT: failure for Update to GuC version 69.0.0
  2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
                   ` (9 preceding siblings ...)
  (?)
@ 2021-12-04  9:55 ` Patchwork
  -1 siblings, 0 replies; 29+ messages in thread
From: Patchwork @ 2021-12-04  9:55 UTC (permalink / raw)
  To: john.c.harrison; +Cc: intel-gfx

[-- Attachment #1: Type: text/plain, Size: 30251 bytes --]

== Series Details ==

Series: Update to GuC version 69.0.0
URL   : https://patchwork.freedesktop.org/series/97564/
State : failure

== Summary ==

CI Bug Log - changes from CI_DRM_10963_full -> Patchwork_21752_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with Patchwork_21752_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in Patchwork_21752_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  

Participating hosts (10 -> 10)
------------------------------

  No changes in participating hosts

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_21752_full:

### IGT changes ###

#### Possible regressions ####

  * igt@kms_psr@cursor_mmap_gtt:
    - shard-tglb:         [PASS][1] -> [INCOMPLETE][2]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb8/igt@kms_psr@cursor_mmap_gtt.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb8/igt@kms_psr@cursor_mmap_gtt.html

  
Known issues
------------

  Here are the changes found in Patchwork_21752_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_exec_fair@basic-deadline:
    - shard-glk:          [PASS][3] -> [FAIL][4] ([i915#2846])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk3/igt@gem_exec_fair@basic-deadline.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk5/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-flow@rcs0:
    - shard-tglb:         [PASS][5] -> [FAIL][6] ([i915#2842])
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb2/igt@gem_exec_fair@basic-flow@rcs0.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb2/igt@gem_exec_fair@basic-flow@rcs0.html

  * igt@gem_exec_fair@basic-none-share:
    - shard-snb:          NOTRUN -> [SKIP][7] ([fdo#109271]) +7 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-snb7/igt@gem_exec_fair@basic-none-share.html

  * igt@gem_exec_fair@basic-pace-share@rcs0:
    - shard-glk:          [PASS][8] -> [FAIL][9] ([i915#2842])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk3/igt@gem_exec_fair@basic-pace-share@rcs0.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk7/igt@gem_exec_fair@basic-pace-share@rcs0.html

  * igt@gem_exec_fair@basic-pace@bcs0:
    - shard-iclb:         [PASS][10] -> [FAIL][11] ([i915#2842])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-iclb2/igt@gem_exec_fair@basic-pace@bcs0.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb8/igt@gem_exec_fair@basic-pace@bcs0.html

  * igt@gem_huc_copy@huc-copy:
    - shard-skl:          NOTRUN -> [SKIP][12] ([fdo#109271] / [i915#2190])
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@gem_huc_copy@huc-copy.html

  * igt@gem_lmem_swapping@parallel-multi:
    - shard-apl:          NOTRUN -> [SKIP][13] ([fdo#109271] / [i915#4613])
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl7/igt@gem_lmem_swapping@parallel-multi.html

  * igt@gem_lmem_swapping@parallel-random-verify:
    - shard-kbl:          NOTRUN -> [SKIP][14] ([fdo#109271] / [i915#4613]) +1 similar issue
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@gem_lmem_swapping@parallel-random-verify.html

  * igt@gem_pwrite@basic-exhaustion:
    - shard-kbl:          NOTRUN -> [WARN][15] ([i915#2658])
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl3/igt@gem_pwrite@basic-exhaustion.html

  * igt@gem_softpin@noreloc-s3:
    - shard-kbl:          NOTRUN -> [DMESG-WARN][16] ([i915#180])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@gem_softpin@noreloc-s3.html

  * igt@gem_spin_batch@engines@rcs0:
    - shard-apl:          [PASS][17] -> [FAIL][18] ([i915#2898])
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-apl8/igt@gem_spin_batch@engines@rcs0.html
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl2/igt@gem_spin_batch@engines@rcs0.html

  * igt@gem_userptr_blits@dmabuf-sync:
    - shard-apl:          NOTRUN -> [SKIP][19] ([fdo#109271] / [i915#3323])
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl2/igt@gem_userptr_blits@dmabuf-sync.html

  * igt@gen7_exec_parse@cmd-crossing-page:
    - shard-tglb:         NOTRUN -> [SKIP][20] ([fdo#109289])
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb1/igt@gen7_exec_parse@cmd-crossing-page.html

  * igt@i915_pm_dc@dc6-dpms:
    - shard-kbl:          NOTRUN -> [FAIL][21] ([i915#454])
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@i915_pm_dc@dc6-dpms.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-180:
    - shard-glk:          [PASS][22] -> [DMESG-WARN][23] ([i915#118])
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk7/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk3/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip:
    - shard-kbl:          NOTRUN -> [SKIP][24] ([fdo#109271] / [i915#3777]) +1 similar issue
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-0-hflip.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip:
    - shard-skl:          NOTRUN -> [FAIL][25] ([i915#3743])
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_big_fb@x-tiled-max-hw-stride-64bpp-rotate-180-async-flip.html

  * igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_mc_ccs:
    - shard-apl:          NOTRUN -> [SKIP][26] ([fdo#109271] / [i915#3886]) +1 similar issue
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl4/igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_mc_ccs.html
    - shard-tglb:         NOTRUN -> [SKIP][27] ([i915#3689] / [i915#3886])
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb1/igt@kms_ccs@pipe-a-bad-aux-stride-y_tiled_gen12_mc_ccs.html

  * igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc:
    - shard-kbl:          NOTRUN -> [SKIP][28] ([fdo#109271] / [i915#3886]) +7 similar issues
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@kms_ccs@pipe-a-crc-sprite-planes-basic-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_rc_ccs_cc:
    - shard-skl:          NOTRUN -> [SKIP][29] ([fdo#109271] / [i915#3886]) +3 similar issues
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_ccs@pipe-b-bad-aux-stride-y_tiled_gen12_rc_ccs_cc.html

  * igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_ccs:
    - shard-tglb:         NOTRUN -> [SKIP][30] ([i915#3689])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb1/igt@kms_ccs@pipe-b-ccs-on-another-bo-y_tiled_ccs.html

  * igt@kms_chamelium@vga-hpd:
    - shard-skl:          NOTRUN -> [SKIP][31] ([fdo#109271] / [fdo#111827]) +6 similar issues
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl8/igt@kms_chamelium@vga-hpd.html

  * igt@kms_color_chamelium@pipe-b-gamma:
    - shard-apl:          NOTRUN -> [SKIP][32] ([fdo#109271] / [fdo#111827]) +2 similar issues
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl4/igt@kms_color_chamelium@pipe-b-gamma.html
    - shard-tglb:         NOTRUN -> [SKIP][33] ([fdo#109284] / [fdo#111827])
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb1/igt@kms_color_chamelium@pipe-b-gamma.html

  * igt@kms_color_chamelium@pipe-c-ctm-0-25:
    - shard-kbl:          NOTRUN -> [SKIP][34] ([fdo#109271] / [fdo#111827]) +11 similar issues
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@kms_color_chamelium@pipe-c-ctm-0-25.html

  * igt@kms_content_protection@legacy:
    - shard-kbl:          NOTRUN -> [TIMEOUT][35] ([i915#1319]) +1 similar issue
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@kms_content_protection@legacy.html

  * igt@kms_cursor_crc@pipe-a-cursor-256x256-onscreen:
    - shard-glk:          [PASS][36] -> [FAIL][37] ([i915#3444])
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk6/igt@kms_cursor_crc@pipe-a-cursor-256x256-onscreen.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk5/igt@kms_cursor_crc@pipe-a-cursor-256x256-onscreen.html

  * igt@kms_cursor_crc@pipe-a-cursor-512x170-onscreen:
    - shard-iclb:         NOTRUN -> [SKIP][38] ([fdo#109278] / [fdo#109279])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@kms_cursor_crc@pipe-a-cursor-512x170-onscreen.html

  * igt@kms_cursor_crc@pipe-a-cursor-suspend:
    - shard-kbl:          [PASS][39] -> [DMESG-WARN][40] ([i915#180]) +5 similar issues
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-kbl4/igt@kms_cursor_crc@pipe-a-cursor-suspend.html
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@kms_cursor_crc@pipe-a-cursor-suspend.html

  * igt@kms_cursor_crc@pipe-b-cursor-32x32-onscreen:
    - shard-skl:          NOTRUN -> [SKIP][41] ([fdo#109271]) +117 similar issues
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_cursor_crc@pipe-b-cursor-32x32-onscreen.html

  * igt@kms_cursor_crc@pipe-c-cursor-32x10-onscreen:
    - shard-iclb:         NOTRUN -> [SKIP][42] ([fdo#109278]) +2 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@kms_cursor_crc@pipe-c-cursor-32x10-onscreen.html

  * igt@kms_cursor_edge_walk@pipe-d-64x64-left-edge:
    - shard-kbl:          NOTRUN -> [SKIP][43] ([fdo#109271]) +127 similar issues
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl1/igt@kms_cursor_edge_walk@pipe-d-64x64-left-edge.html

  * igt@kms_cursor_legacy@cursora-vs-flipb-toggle:
    - shard-iclb:         NOTRUN -> [SKIP][44] ([fdo#109274] / [fdo#109278])
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@kms_cursor_legacy@cursora-vs-flipb-toggle.html

  * igt@kms_fbcon_fbt@fbc-suspend:
    - shard-kbl:          NOTRUN -> [INCOMPLETE][45] ([i915#180] / [i915#636])
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@kms_fbcon_fbt@fbc-suspend.html

  * igt@kms_flip@plain-flip-fb-recreate@c-edp1:
    - shard-skl:          [PASS][46] -> [FAIL][47] ([i915#2122])
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl3/igt@kms_flip@plain-flip-fb-recreate@c-edp1.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl1/igt@kms_flip@plain-flip-fb-recreate@c-edp1.html

  * igt@kms_flip@plain-flip-ts-check-interruptible@c-edp1:
    - shard-skl:          NOTRUN -> [FAIL][48] ([i915#2122])
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_flip@plain-flip-ts-check-interruptible@c-edp1.html

  * igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs:
    - shard-iclb:         [PASS][49] -> [SKIP][50] ([i915#3701])
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-iclb8/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb2/igt@kms_flip_scaled_crc@flip-32bpp-ytile-to-32bpp-ytileccs.html

  * igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-shrfb-plflip-blt:
    - shard-iclb:         NOTRUN -> [SKIP][51] ([fdo#109280])
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@kms_frontbuffer_tracking@fbcpsr-2p-scndscrn-shrfb-plflip-blt.html

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-skl:          [PASS][52] -> [FAIL][53] ([fdo#108145] / [i915#265])
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl3/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl7/igt@kms_plane_alpha_blend@pipe-a-coverage-7efc.html

  * igt@kms_plane_alpha_blend@pipe-b-alpha-opaque-fb:
    - shard-kbl:          NOTRUN -> [FAIL][54] ([fdo#108145] / [i915#265]) +1 similar issue
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl1/igt@kms_plane_alpha_blend@pipe-b-alpha-opaque-fb.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-basic:
    - shard-apl:          NOTRUN -> [FAIL][55] ([fdo#108145] / [i915#265]) +1 similar issue
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl2/igt@kms_plane_alpha_blend@pipe-c-alpha-basic.html

  * igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb:
    - shard-kbl:          NOTRUN -> [FAIL][56] ([i915#265])
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@kms_plane_alpha_blend@pipe-c-alpha-transparent-fb.html

  * igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3:
    - shard-kbl:          NOTRUN -> [SKIP][57] ([fdo#109271] / [i915#658]) +3 similar issues
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl2/igt@kms_psr2_sf@overlay-primary-update-sf-dmg-area-3.html

  * igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-2:
    - shard-skl:          NOTRUN -> [SKIP][58] ([fdo#109271] / [i915#658])
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_psr2_sf@primary-plane-update-sf-dmg-area-2.html

  * igt@kms_psr2_su@page_flip-xrgb8888:
    - shard-apl:          NOTRUN -> [SKIP][59] ([fdo#109271] / [i915#658]) +1 similar issue
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl7/igt@kms_psr2_su@page_flip-xrgb8888.html

  * igt@kms_psr@psr2_sprite_mmap_gtt:
    - shard-iclb:         [PASS][60] -> [SKIP][61] ([fdo#109441]) +2 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-iclb2/igt@kms_psr@psr2_sprite_mmap_gtt.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@kms_psr@psr2_sprite_mmap_gtt.html

  * igt@kms_psr@suspend:
    - shard-skl:          [PASS][62] -> [INCOMPLETE][63] ([i915#198])
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl1/igt@kms_psr@suspend.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl10/igt@kms_psr@suspend.html

  * igt@kms_setmode@basic:
    - shard-glk:          [PASS][64] -> [FAIL][65] ([i915#31])
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk6/igt@kms_setmode@basic.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk3/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-d-wait-idle:
    - shard-kbl:          NOTRUN -> [SKIP][66] ([fdo#109271] / [i915#533]) +1 similar issue
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl2/igt@kms_vblank@pipe-d-wait-idle.html

  * igt@kms_vrr@flip-suspend:
    - shard-tglb:         NOTRUN -> [SKIP][67] ([fdo#109502])
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb1/igt@kms_vrr@flip-suspend.html

  * igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame:
    - shard-apl:          NOTRUN -> [SKIP][68] ([fdo#109271]) +83 similar issues
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl2/igt@nouveau_crc@pipe-b-ctx-flip-skip-current-frame.html

  * igt@perf@polling:
    - shard-skl:          [PASS][69] -> [FAIL][70] ([i915#1542])
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl1/igt@perf@polling.html
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl6/igt@perf@polling.html

  * igt@prime_nv_pcopy@test3_4:
    - shard-iclb:         NOTRUN -> [SKIP][71] ([fdo#109291])
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb6/igt@prime_nv_pcopy@test3_4.html

  * igt@sysfs_clients@pidname:
    - shard-apl:          NOTRUN -> [SKIP][72] ([fdo#109271] / [i915#2994]) +1 similar issue
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl2/igt@sysfs_clients@pidname.html

  * igt@sysfs_clients@split-25:
    - shard-skl:          NOTRUN -> [SKIP][73] ([fdo#109271] / [i915#2994]) +1 similar issue
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl8/igt@sysfs_clients@split-25.html

  * igt@sysfs_clients@split-50:
    - shard-kbl:          NOTRUN -> [SKIP][74] ([fdo#109271] / [i915#2994]) +2 similar issues
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl2/igt@sysfs_clients@split-50.html

  
#### Possible fixes ####

  * igt@feature_discovery@psr2:
    - {shard-rkl}:        [SKIP][75] ([i915#658]) -> [PASS][76]
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@feature_discovery@psr2.html
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@feature_discovery@psr2.html

  * igt@gem_eio@unwedge-stress:
    - shard-tglb:         [TIMEOUT][77] ([i915#3063] / [i915#3648]) -> [PASS][78]
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb3/igt@gem_eio@unwedge-stress.html
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb3/igt@gem_eio@unwedge-stress.html

  * igt@gem_exec_fair@basic-deadline:
    - shard-kbl:          [FAIL][79] ([i915#2846]) -> [PASS][80]
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-kbl6/igt@gem_exec_fair@basic-deadline.html
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl7/igt@gem_exec_fair@basic-deadline.html

  * igt@gem_exec_fair@basic-none-share@rcs0:
    - shard-iclb:         [FAIL][81] ([i915#2842]) -> [PASS][82]
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-iclb5/igt@gem_exec_fair@basic-none-share@rcs0.html
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb5/igt@gem_exec_fair@basic-none-share@rcs0.html
    - shard-tglb:         [SKIP][83] ([i915#2848]) -> [PASS][84]
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb6/igt@gem_exec_fair@basic-none-share@rcs0.html
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb5/igt@gem_exec_fair@basic-none-share@rcs0.html

  * igt@gem_exec_fair@basic-none-solo@rcs0:
    - {shard-rkl}:        [FAIL][85] ([i915#2842]) -> [PASS][86]
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@gem_exec_fair@basic-none-solo@rcs0.html
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-1/igt@gem_exec_fair@basic-none-solo@rcs0.html

  * igt@gem_exec_fair@basic-none@vecs0:
    - shard-apl:          [FAIL][87] ([i915#2842]) -> [PASS][88]
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-apl1/igt@gem_exec_fair@basic-none@vecs0.html
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl1/igt@gem_exec_fair@basic-none@vecs0.html

  * igt@gem_exec_fair@basic-pace@rcs0:
    - shard-kbl:          [FAIL][89] ([i915#2842]) -> [PASS][90]
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-kbl6/igt@gem_exec_fair@basic-pace@rcs0.html
   [90]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@gem_exec_fair@basic-pace@rcs0.html
    - shard-tglb:         [FAIL][91] ([i915#2842]) -> [PASS][92]
   [91]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb8/igt@gem_exec_fair@basic-pace@rcs0.html
   [92]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb5/igt@gem_exec_fair@basic-pace@rcs0.html

  * igt@gem_exec_whisper@basic-fds-forked:
    - shard-glk:          [DMESG-WARN][93] ([i915#118]) -> [PASS][94]
   [93]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk5/igt@gem_exec_whisper@basic-fds-forked.html
   [94]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk8/igt@gem_exec_whisper@basic-fds-forked.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [DMESG-WARN][95] ([i915#180]) -> [PASS][96] +4 similar issues
   [95]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-kbl7/igt@gem_workarounds@suspend-resume-fd.html
   [96]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-kbl4/igt@gem_workarounds@suspend-resume-fd.html

  * igt@i915_pm_backlight@fade_with_dpms:
    - {shard-rkl}:        [SKIP][97] ([i915#3012]) -> [PASS][98]
   [97]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@i915_pm_backlight@fade_with_dpms.html
   [98]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@i915_pm_backlight@fade_with_dpms.html

  * igt@i915_selftest@live@gem_contexts:
    - shard-tglb:         [DMESG-WARN][99] ([i915#2867]) -> [PASS][100] +14 similar issues
   [99]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-tglb6/igt@i915_selftest@live@gem_contexts.html
   [100]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-tglb5/igt@i915_selftest@live@gem_contexts.html

  * igt@i915_selftest@live@hangcheck:
    - shard-snb:          [INCOMPLETE][101] ([i915#3921]) -> [PASS][102]
   [101]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-snb5/igt@i915_selftest@live@hangcheck.html
   [102]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-snb7/igt@i915_selftest@live@hangcheck.html

  * igt@kms_async_flips@alternate-sync-async-flip:
    - shard-skl:          [FAIL][103] ([i915#2521]) -> [PASS][104]
   [103]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl9/igt@kms_async_flips@alternate-sync-async-flip.html
   [104]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl1/igt@kms_async_flips@alternate-sync-async-flip.html

  * igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip:
    - {shard-rkl}:        [SKIP][105] ([i915#1845]) -> [PASS][106] +6 similar issues
   [105]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html
   [106]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_big_fb@x-tiled-max-hw-stride-32bpp-rotate-180-hflip-async-flip.html

  * igt@kms_big_fb@y-tiled-32bpp-rotate-0:
    - shard-glk:          [DMESG-WARN][107] ([i915#118] / [i915#1888]) -> [PASS][108]
   [107]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-glk1/igt@kms_big_fb@y-tiled-32bpp-rotate-0.html
   [108]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-glk6/igt@kms_big_fb@y-tiled-32bpp-rotate-0.html

  * igt@kms_color@pipe-a-ctm-0-5:
    - {shard-rkl}:        [SKIP][109] ([i915#1149] / [i915#1849] / [i915#4070]) -> [PASS][110] +1 similar issue
   [109]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_color@pipe-a-ctm-0-5.html
   [110]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_color@pipe-a-ctm-0-5.html

  * igt@kms_cursor_crc@pipe-b-cursor-256x85-onscreen:
    - {shard-rkl}:        [SKIP][111] ([fdo#112022] / [i915#4070]) -> [PASS][112] +3 similar issues
   [111]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_cursor_crc@pipe-b-cursor-256x85-onscreen.html
   [112]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_cursor_crc@pipe-b-cursor-256x85-onscreen.html

  * igt@kms_cursor_edge_walk@pipe-a-128x128-top-edge:
    - {shard-rkl}:        [SKIP][113] ([i915#1849] / [i915#4070]) -> [PASS][114] +3 similar issues
   [113]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_cursor_edge_walk@pipe-a-128x128-top-edge.html
   [114]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_cursor_edge_walk@pipe-a-128x128-top-edge.html

  * igt@kms_cursor_legacy@basic-flip-before-cursor-atomic:
    - {shard-rkl}:        [SKIP][115] ([fdo#111825] / [i915#4070]) -> [PASS][116]
   [115]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html
   [116]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_cursor_legacy@basic-flip-before-cursor-atomic.html

  * igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic:
    - {shard-rkl}:        ([PASS][117], [SKIP][118]) ([fdo#111825]) -> [PASS][119]
   [117]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-6/igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic.html
   [118]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-4/igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic.html
   [119]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_cursor_legacy@long-nonblocking-modeset-vs-cursor-atomic.html

  * igt@kms_dp_aux_dev:
    - {shard-rkl}:        [SKIP][120] ([i915#1257]) -> [PASS][121]
   [120]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_dp_aux_dev.html
   [121]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_dp_aux_dev.html

  * igt@kms_draw_crc@draw-method-rgb565-blt-ytiled:
    - {shard-rkl}:        [SKIP][122] ([fdo#111314]) -> [PASS][123] +2 similar issues
   [122]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_draw_crc@draw-method-rgb565-blt-ytiled.html
   [123]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_draw_crc@draw-method-rgb565-blt-ytiled.html

  * igt@kms_flip@flip-vs-suspend-interruptible@a-dp1:
    - shard-apl:          [DMESG-WARN][124] ([i915#180]) -> [PASS][125] +2 similar issues
   [124]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-apl4/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html
   [125]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl7/igt@kms_flip@flip-vs-suspend-interruptible@a-dp1.html

  * igt@kms_flip@plain-flip-ts-check@c-edp1:
    - shard-skl:          [FAIL][126] ([i915#2122]) -> [PASS][127]
   [126]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl3/igt@kms_flip@plain-flip-ts-check@c-edp1.html
   [127]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl7/igt@kms_flip@plain-flip-ts-check@c-edp1.html

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-render:
    - {shard-rkl}:        [SKIP][128] ([i915#1849]) -> [PASS][129] +12 similar issues
   [128]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-render.html
   [129]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-shrfb-draw-render.html

  * igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt:
    - {shard-rkl}:        [SKIP][130] ([i915#4098]) -> [PASS][131] +2 similar issues
   [130]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-4/igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt.html
   [131]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_frontbuffer_tracking@psr-1p-primscrn-shrfb-pgflip-blt.html

  * igt@kms_invalid_mode@bad-vsync-start:
    - {shard-rkl}:        [SKIP][132] ([i915#4278]) -> [PASS][133]
   [132]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_invalid_mode@bad-vsync-start.html
   [133]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_invalid_mode@bad-vsync-start.html

  * igt@kms_plane@pixel-format@pipe-a-planes:
    - {shard-rkl}:        [SKIP][134] ([i915#3558]) -> [PASS][135] +1 similar issue
   [134]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-2/igt@kms_plane@pixel-format@pipe-a-planes.html
   [135]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_plane@pixel-format@pipe-a-planes.html

  * igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min:
    - shard-skl:          [FAIL][136] ([fdo#108145] / [i915#265]) -> [PASS][137]
   [136]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-skl1/igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min.html
   [137]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-skl6/igt@kms_plane_alpha_blend@pipe-b-constant-alpha-min.html

  * igt@kms_psr@cursor_render:
    - {shard-rkl}:        ([SKIP][138], [SKIP][139]) ([i915#1072]) -> [PASS][140]
   [138]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_psr@cursor_render.html
   [139]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-4/igt@kms_psr@cursor_render.html
   [140]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-rkl-6/igt@kms_psr@cursor_render.html

  * igt@kms_psr@psr2_no_drrs:
    - shard-iclb:         [SKIP][141] ([fdo#109441]) -> [PASS][142] +2 similar issues
   [141]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-iclb8/igt@kms_psr@psr2_no_drrs.html
   [142]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-iclb2/igt@kms_psr@psr2_no_drrs.html

  * igt@kms_setmode@basic:
    - shard-apl:          [FAIL][143] ([i915#31]) -> [PASS][144]
   [143]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-apl2/igt@kms_setmode@basic.html
   [144]: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/shard-apl1/igt@kms_setmode@basic.html

  * igt@kms_vblank@pipe-a-ts-continuation-dpms-rpm:
    - {shard-rkl}:        ([SKIP][145], [SKIP][146]) ([i915#1845]) -> [PASS][147] +1 similar issue
   [145]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/shard-rkl-1/igt@kms_vblank@pipe-a-ts-continuation-dpms-rpm.html
   [146]: https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_10963/s

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_21752/index.html

[-- Attachment #2: Type: text/html, Size: 33335 bytes --]

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

* Re: [Intel-gfx]  ✗ Fi.CI.DOCS: warning for Update to GuC version 69.0.0
  2021-12-03 22:27 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
@ 2021-12-06 19:29   ` John Harrison
  2021-12-06 22:34     ` Michal Wajdeczko
  0 siblings, 1 reply; 29+ messages in thread
From: John Harrison @ 2021-12-06 19:29 UTC (permalink / raw)
  To: intel-gfx, Michal Wajdeczko

Michal, do you know what this is complaining about?

John.

On 12/3/2021 14:27, Patchwork wrote:
> == Series Details ==
>
> Series: Update to GuC version 69.0.0
> URL   : https://patchwork.freedesktop.org/series/97564/
> State : warning
>
> == Summary ==
>
> $ make htmldocs 2>&1 > /dev/null | grep i915
> /home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:44: WARNING: Inline target start-string without end-string.
> /home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:48: WARNING: Inline target start-string without end-string.
> /home/cidrm/kernel/Documentation/gpu/i915:542: ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:52: WARNING: Inline target start-string without end-string.
>
>


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

* Re: [Intel-gfx] [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC
  2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
  (?)
  (?)
@ 2021-12-06 22:09   ` Daniele Ceraolo Spurio
  -1 siblings, 0 replies; 29+ messages in thread
From: Daniele Ceraolo Spurio @ 2021-12-06 22:09 UTC (permalink / raw)
  To: John.C.Harrison, Intel-GFX; +Cc: DRI-Devel



On 12/3/2021 10:33 AM, John.C.Harrison@Intel.com wrote:
> From: John Harrison <John.C.Harrison@Intel.com>
>
> It is possible for platforms to require GuC but not HuC firmware.
> Also, the firmware versions for GuC and HuC advance independently. So
> split the macros up to allow the lists to be maintained separately.
>
> Signed-off-by: John Harrison <John.C.Harrison@Intel.com>

Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>

Daniele

> ---
>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 93 ++++++++++++++++--------
>   1 file changed, 63 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> index 3aa87be4f2e4..a7788ce50736 100644
> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
> @@ -48,22 +48,39 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>    * Note that RKL and ADL-S have the same GuC/HuC device ID's and use the same
>    * firmware as TGL.
>    */
> -#define INTEL_UC_FIRMWARE_DEFS(fw_def, guc_def, huc_def) \
> -	fw_def(ALDERLAKE_P, 0, guc_def(adlp, 62, 0, 3), huc_def(tgl, 7, 9, 3)) \
> -	fw_def(ALDERLAKE_S, 0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
> -	fw_def(DG1,         0, guc_def(dg1, 62, 0, 0), huc_def(dg1,  7, 9, 3)) \
> -	fw_def(ROCKETLAKE,  0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
> -	fw_def(TIGERLAKE,   0, guc_def(tgl, 62, 0, 0), huc_def(tgl,  7, 9, 3)) \
> -	fw_def(JASPERLAKE,  0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
> -	fw_def(ELKHARTLAKE, 0, guc_def(ehl, 62, 0, 0), huc_def(ehl,  9, 0, 0)) \
> -	fw_def(ICELAKE,     0, guc_def(icl, 62, 0, 0), huc_def(icl,  9, 0, 0)) \
> -	fw_def(COMETLAKE,   5, guc_def(cml, 62, 0, 0), huc_def(cml,  4, 0, 0)) \
> -	fw_def(COMETLAKE,   0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
> -	fw_def(COFFEELAKE,  0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
> -	fw_def(GEMINILAKE,  0, guc_def(glk, 62, 0, 0), huc_def(glk,  4, 0, 0)) \
> -	fw_def(KABYLAKE,    0, guc_def(kbl, 62, 0, 0), huc_def(kbl,  4, 0, 0)) \
> -	fw_def(BROXTON,     0, guc_def(bxt, 62, 0, 0), huc_def(bxt,  2, 0, 0)) \
> -	fw_def(SKYLAKE,     0, guc_def(skl, 62, 0, 0), huc_def(skl,  2, 0, 0))
> +#define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_def) \
> +	fw_def(ALDERLAKE_P,  0, guc_def(adlp, 62, 0, 3)) \
> +	fw_def(ALDERLAKE_S,  0, guc_def(tgl,  62, 0, 0)) \
> +	fw_def(DG1,          0, guc_def(dg1,  62, 0, 0)) \
> +	fw_def(ROCKETLAKE,   0, guc_def(tgl,  62, 0, 0)) \
> +	fw_def(TIGERLAKE,    0, guc_def(tgl,  62, 0, 0)) \
> +	fw_def(JASPERLAKE,   0, guc_def(ehl,  62, 0, 0)) \
> +	fw_def(ELKHARTLAKE,  0, guc_def(ehl,  62, 0, 0)) \
> +	fw_def(ICELAKE,      0, guc_def(icl,  62, 0, 0)) \
> +	fw_def(COMETLAKE,    5, guc_def(cml,  62, 0, 0)) \
> +	fw_def(COMETLAKE,    0, guc_def(kbl,  62, 0, 0)) \
> +	fw_def(COFFEELAKE,   0, guc_def(kbl,  62, 0, 0)) \
> +	fw_def(GEMINILAKE,   0, guc_def(glk,  62, 0, 0)) \
> +	fw_def(KABYLAKE,     0, guc_def(kbl,  62, 0, 0)) \
> +	fw_def(BROXTON,      0, guc_def(bxt,  62, 0, 0)) \
> +	fw_def(SKYLAKE,      0, guc_def(skl,  62, 0, 0))
> +
> +#define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \
> +	fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \
> +	fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \
> +	fw_def(DG1,          0, huc_def(dg1,  7, 9, 3)) \
> +	fw_def(ROCKETLAKE,   0, huc_def(tgl,  7, 9, 3)) \
> +	fw_def(TIGERLAKE,    0, huc_def(tgl,  7, 9, 3)) \
> +	fw_def(JASPERLAKE,   0, huc_def(ehl,  9, 0, 0)) \
> +	fw_def(ELKHARTLAKE,  0, huc_def(ehl,  9, 0, 0)) \
> +	fw_def(ICELAKE,      0, huc_def(icl,  9, 0, 0)) \
> +	fw_def(COMETLAKE,    5, huc_def(cml,  4, 0, 0)) \
> +	fw_def(COMETLAKE,    0, huc_def(kbl,  4, 0, 0)) \
> +	fw_def(COFFEELAKE,   0, huc_def(kbl,  4, 0, 0)) \
> +	fw_def(GEMINILAKE,   0, huc_def(glk,  4, 0, 0)) \
> +	fw_def(KABYLAKE,     0, huc_def(kbl,  4, 0, 0)) \
> +	fw_def(BROXTON,      0, huc_def(bxt,  2, 0, 0)) \
> +	fw_def(SKYLAKE,      0, huc_def(skl,  2, 0, 0))
>   
>   #define __MAKE_UC_FW_PATH(prefix_, name_, major_, minor_, patch_) \
>   	"i915/" \
> @@ -79,11 +96,11 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
>   	__MAKE_UC_FW_PATH(prefix_, "_huc_", major_, minor_, bld_num_)
>   
>   /* All blobs need to be declared via MODULE_FIRMWARE() */
> -#define INTEL_UC_MODULE_FW(platform_, revid_, guc_, huc_) \
> -	MODULE_FIRMWARE(guc_); \
> -	MODULE_FIRMWARE(huc_);
> +#define INTEL_UC_MODULE_FW(platform_, revid_, uc_) \
> +	MODULE_FIRMWARE(uc_);
>   
> -INTEL_UC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH, MAKE_HUC_FW_PATH)
> +INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH)
> +INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH)
>   
>   /* The below structs and macros are used to iterate across the list of blobs */
>   struct __packed uc_fw_blob {
> @@ -106,31 +123,47 @@ struct __packed uc_fw_blob {
>   struct __packed uc_fw_platform_requirement {
>   	enum intel_platform p;
>   	u8 rev; /* first platform rev using this FW */
> -	const struct uc_fw_blob blobs[INTEL_UC_FW_NUM_TYPES];
> +	const struct uc_fw_blob blob;
>   };
>   
> -#define MAKE_FW_LIST(platform_, revid_, guc_, huc_) \
> +#define MAKE_FW_LIST(platform_, revid_, uc_) \
>   { \
>   	.p = INTEL_##platform_, \
>   	.rev = revid_, \
> -	.blobs[INTEL_UC_FW_TYPE_GUC] = guc_, \
> -	.blobs[INTEL_UC_FW_TYPE_HUC] = huc_, \
> +	.blob = uc_, \
>   },
>   
> +struct fw_blobs_by_type {
> +	const struct uc_fw_platform_requirement *blobs;
> +	u32 count;
> +};
> +
>   static void
>   __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
>   {
> -	static const struct uc_fw_platform_requirement fw_blobs[] = {
> -		INTEL_UC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, HUC_FW_BLOB)
> +	static const struct uc_fw_platform_requirement blobs_guc[] = {
> +		INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB)
> +	};
> +	static const struct uc_fw_platform_requirement blobs_huc[] = {
> +		INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB)
>   	};
> +	static const struct fw_blobs_by_type blobs_all[INTEL_UC_FW_NUM_TYPES] = {
> +		[INTEL_UC_FW_TYPE_GUC] = { blobs_guc, ARRAY_SIZE(blobs_guc) },
> +		[INTEL_UC_FW_TYPE_HUC] = { blobs_huc, ARRAY_SIZE(blobs_huc) },
> +	};
> +	static const struct uc_fw_platform_requirement *fw_blobs;
>   	enum intel_platform p = INTEL_INFO(i915)->platform;
> +	u32 fw_count;
>   	u8 rev = INTEL_REVID(i915);
>   	int i;
>   
> -	for (i = 0; i < ARRAY_SIZE(fw_blobs) && p <= fw_blobs[i].p; i++) {
> +	GEM_BUG_ON(uc_fw->type >= ARRAY_SIZE(blobs_all));
> +	fw_blobs = blobs_all[uc_fw->type].blobs;
> +	fw_count = blobs_all[uc_fw->type].count;
> +
> +	for (i = 0; i < fw_count && p <= fw_blobs[i].p; i++) {
>   		if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) {
> -			const struct uc_fw_blob *blob =
> -					&fw_blobs[i].blobs[uc_fw->type];
> +			const struct uc_fw_blob *blob = &fw_blobs[i].blob;
>   			uc_fw->path = blob->path;
>   			uc_fw->major_ver_wanted = blob->major;
>   			uc_fw->minor_ver_wanted = blob->minor;
> @@ -140,7 +173,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
>   
>   	/* make sure the list is ordered as expected */
>   	if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) {
> -		for (i = 1; i < ARRAY_SIZE(fw_blobs); i++) {
> +		for (i = 1; i < fw_count; i++) {
>   			if (fw_blobs[i].p < fw_blobs[i - 1].p)
>   				continue;
>   


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

* Re: [Intel-gfx]  ✗ Fi.CI.DOCS: warning for Update to GuC version 69.0.0
  2021-12-06 19:29   ` John Harrison
@ 2021-12-06 22:34     ` Michal Wajdeczko
  0 siblings, 0 replies; 29+ messages in thread
From: Michal Wajdeczko @ 2021-12-06 22:34 UTC (permalink / raw)
  To: John Harrison, intel-gfx



On 06.12.2021 20:29, John Harrison wrote:
> Michal, do you know what this is complaining about?

broken links definitions, fix below

Michal

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
index d09d6a5bb63b..6aa3cf7172f7 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h
@@ -40,23 +40,23 @@
  *      Refers to 64 bit Global Gfx address of H2G `CT Buffer`_.
  *      Should be above WOPCM address but below APIC base address for
native mode.
  *
- * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR : 0x0903
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_DESCRIPTOR_ADDR` : 0x0903
  *      Refers to 64 bit Global Gfx address of H2G `CTB Descriptor`_.
  *      Should be above WOPCM address but below APIC base address for
native mode.
  *
- * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE : 0x0904
+ * _`GUC_KLV_SELF_CFG_H2G_CTB_SIZE` : 0x0904
  *      Refers to size of H2G `CT Buffer`_ in bytes.
  *      Should be a multiple of 4K.
  *
- * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR : 0x0905
+ * _`GUC_KLV_SELF_CFG_G2H_CTB_ADDR` : 0x0905
  *      Refers to 64 bit Global Gfx address of G2H `CT Buffer`_.
  *      Should be above WOPCM address but below APIC base address for
native mode.
  *
- * _GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR : 0x0906
+ * _`GUC_KLV_SELF_CFG_G2H_CTB_DESCRIPTOR_ADDR` : 0x0906
  *      Refers to 64 bit Global Gfx address of G2H `CTB Descriptor`_.
  *      Should be above WOPCM address but below APIC base address for
native mode.
  *
- * _GUC_KLV_SELF_CFG_G2H_CTB_SIZE : 0x0907
+ * _`GUC_KLV_SELF_CFG_G2H_CTB_SIZE` : 0x0907
  *      Refers to size of G2H `CT Buffer`_ in bytes.
  *      Should be a multiple of 4K.
  */

> 
> John.
> 
> On 12/3/2021 14:27, Patchwork wrote:
>> == Series Details ==
>>
>> Series: Update to GuC version 69.0.0
>> URL   : https://patchwork.freedesktop.org/series/97564/
>> State : warning
>>
>> == Summary ==
>>
>> $ make htmldocs 2>&1 > /dev/null | grep i915
>> /home/cidrm/kernel/Documentation/gpu/i915:542:
>> ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:44: WARNING: Inline
>> target start-string without end-string.
>> /home/cidrm/kernel/Documentation/gpu/i915:542:
>> ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:48: WARNING: Inline
>> target start-string without end-string.
>> /home/cidrm/kernel/Documentation/gpu/i915:542:
>> ./drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h:52: WARNING: Inline
>> target start-string without end-string.
>>
>>
> 

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

end of thread, other threads:[~2021-12-06 22:34 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-03 18:33 [PATCH 0/5] Update to GuC version 69.0.0 John.C.Harrison
2021-12-03 18:33 ` [Intel-gfx] " John.C.Harrison
2021-12-03 18:33 ` [PATCH 1/5] drm/i915/uc: Allow platforms to have GuC but not HuC John.C.Harrison
2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
2021-12-03 19:01   ` Lucas De Marchi
2021-12-03 19:01     ` [Intel-gfx] " Lucas De Marchi
2021-12-06 22:09   ` Daniele Ceraolo Spurio
2021-12-03 18:33 ` [PATCH 2/5] drm/i915/guc: Increase GuC log size for CONFIG_DEBUG_GEM John.C.Harrison
2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
2021-12-03 20:25   ` Matthew Brost
2021-12-03 18:33 ` [PATCH 3/5] drm/i915/guc: Don't go bang in GuC log if no GuC John.C.Harrison
2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
2021-12-03 18:33 ` [PATCH 4/5] drm/i915/guc: Update to GuC version 69.0.0 John.C.Harrison
2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
2021-12-03 22:28   ` Michal Wajdeczko
2021-12-03 22:28     ` [Intel-gfx] " Michal Wajdeczko
2021-12-03 23:56     ` Matthew Brost
2021-12-03 23:56       ` Matthew Brost
2021-12-03 18:33 ` [PATCH 5/5] drm/i915/guc: Improve GuC loading status check/error reports John.C.Harrison
2021-12-03 18:33   ` [Intel-gfx] " John.C.Harrison
2021-12-03 20:22   ` Matthew Brost
2021-12-03 20:22     ` [Intel-gfx] " Matthew Brost
2021-12-03 22:22 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for Update to GuC version 69.0.0 Patchwork
2021-12-03 22:23 ` [Intel-gfx] ✗ Fi.CI.SPARSE: " Patchwork
2021-12-03 22:27 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2021-12-06 19:29   ` John Harrison
2021-12-06 22:34     ` Michal Wajdeczko
2021-12-03 22:50 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-12-04  9:55 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork

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.