[PATCH v2] drm/i915/guc: Enable w/a 16021333562 for DG2, MTL and ARL

2024-05-28 Thread John . C . Harrison
From: John Harrison 

Enable another workaround that is implemented inside the GuC.

v2: Use the correct Gen12 w/a id rather than the Xe version (review
feedback from Matthew R) also extend to include ARL.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 32 ---
 2 files changed, 21 insertions(+), 12 deletions(-)

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 525587cfe1af9..37ff539a6963d 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
@@ -106,6 +106,7 @@ enum {
  */
 enum {
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+   GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED   = 
0x9002,
 };
 
 #endif /* _ABI_GUC_KLVS_ABI_H */
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 c606bb5e3b7b0..7995f059f30df 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -815,23 +815,23 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
-/* Wa_14019159160 */
-static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+static void guc_waklv_enable_simple(struct intel_guc *guc,
+   u32 klv_id, u32 *offset, u32 *remain)
 {
u32 size;
u32 klv_entry[] = {
/* 16:16 key/length */
-   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
FIELD_PREP(GUC_KLV_0_LEN, 0),
/* 0 dwords data */
};
 
size = sizeof(klv_entry);
-   GEM_BUG_ON(remain < size);
+   GEM_BUG_ON(*remain < size);
 
-   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
-
-   return size;
+   iosys_map_memcpy_to(>ads_map, *offset, klv_entry, size);
+   *offset += size;
+   *remain -= size;
 }
 
 static void guc_waklv_init(struct intel_guc *guc)
@@ -850,11 +850,19 @@ static void guc_waklv_init(struct intel_guc *guc)
remain = guc_ads_waklv_size(guc);
 
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
-   size = guc_waklv_ra_mode(guc, offset, remain);
-   offset += size;
-   remain -= size;
-   }
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   guc_waklv_enable_simple(guc,
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE,
+   , );
+
+   /* Wa_16021333562 */
+   if ((GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 21, 1)) &&
+   (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) ||
+IS_MEDIA_GT_IP_RANGE(gt, IP_VER(13, 0), IP_VER(13, 0)) ||
+IS_DG2(gt->i915)))
+   guc_waklv_enable_simple(guc,
+   
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
+   , );
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
-- 
2.43.2



[PATCH] drm/i915/guc: Enable w/a 14019882105 for DG2 and MTL

2024-05-24 Thread John . C . Harrison
From: John Harrison 

Enable another workaround that is implemented inside the GuC.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 32 ---
 2 files changed, 21 insertions(+), 12 deletions(-)

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 525587cfe1af9..37ff539a6963d 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
@@ -106,6 +106,7 @@ enum {
  */
 enum {
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+   GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED   = 
0x9002,
 };
 
 #endif /* _ABI_GUC_KLVS_ABI_H */
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 c606bb5e3b7b0..6c382785bc60b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -815,23 +815,23 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
-/* Wa_14019159160 */
-static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+static void guc_waklv_enable_simple(struct intel_guc *guc,
+   u32 klv_id, u32 *offset, u32 *remain)
 {
u32 size;
u32 klv_entry[] = {
/* 16:16 key/length */
-   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
FIELD_PREP(GUC_KLV_0_LEN, 0),
/* 0 dwords data */
};
 
size = sizeof(klv_entry);
-   GEM_BUG_ON(remain < size);
+   GEM_BUG_ON(*remain < size);
 
-   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
-
-   return size;
+   iosys_map_memcpy_to(>ads_map, *offset, klv_entry, size);
+   *offset += size;
+   *remain -= size;
 }
 
 static void guc_waklv_init(struct intel_guc *guc)
@@ -850,11 +850,19 @@ static void guc_waklv_init(struct intel_guc *guc)
remain = guc_ads_waklv_size(guc);
 
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
-   size = guc_waklv_ra_mode(guc, offset, remain);
-   offset += size;
-   remain -= size;
-   }
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   guc_waklv_enable_simple(guc,
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE,
+   , );
+
+   /* Wa_14019882105 */
+   if ((GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 21, 1)) &&
+   (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) ||
+IS_MEDIA_GT_IP_RANGE(gt, IP_VER(13, 0), IP_VER(13, 0)) ||
+IS_DG2(gt->i915)))
+   guc_waklv_enable_simple(guc,
+   
GUC_WORKAROUND_KLV_BLOCK_INTERRUPTS_WHEN_MGSR_BLOCKED,
+   , );
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
-- 
2.43.2



[PATCH] drm/i915/guc: Fix the fix for reset lock confusion

2024-03-29 Thread John . C . Harrison
From: John Harrison 

The previous fix for the circlular lock splat about the busyness
worker wasn't quite complete. Even though the reset-in-progress flag
is cleared at the start of intel_uc_reset_finish, the entire function
is still inside the reset mutex lock. Not sure why the patch appeared
to fix the issue both locally and in CI. However, it is now back
again.

There is a further complication the wedge code path within
intel_gt_reset() jumps around so much it results in nested
reset_prepare/_finish calls. That is, the call sequence is:
  intel_gt_reset
  | reset_prepare
  | __intel_gt_set_wedged
  | | reset_prepare
  | | reset_finish
  | reset_finish

The nested finish means that even if the clear of the in-progress flag
was moved to the end of _finish, it would still be clear for the
entire second call. Surprisingly, this does not seem to be causing any
other problems at present.

As an aside, a wedge on fini does not call the finish functions at
all. The reset_in_progress flag is left set (twice).

So instead of trying to cancel the worker anywhere at all in the reset
path, just add a cancel to intel_guc_submission_fini instead. Note
that it is not a problem if the worker is still active during a reset.
Either it will run before the reset path starts locking things and
will simply block the reset code for a tiny amount of time. Or it will
run after the locks have been acquired and will early exit due to the
try-lock.

Also, do not use the reset-in-progress flag to decide whether a
synchronous cancel is safe (from a lockdep perspective) or not.
Instead, use the actual reset mutex state (both the genuine one and
the custom rolled BACKOFF one).

Fixes: 0e00a8814eec ("drm/i915/guc: Avoid circular locking issue on busyness 
flush")
Signed-off-by: John Harrison 
Cc: Zhanjun Dong 
Cc: John Harrison 
Cc: Andi Shyti 
Cc: Daniel Vetter 
Cc: Daniel Vetter 
Cc: Rodrigo Vivi 
Cc: Nirmoy Das 
Cc: Tvrtko Ursulin 
Cc: Umesh Nerlige Ramappa 
Cc: Andrzej Hajda 
Cc: Matt Roper 
Cc: Jonathan Cavitt 
Cc: Prathap Kumar Valsan 
Cc: Alan Previn 
Cc: Madhumitha Tolakanahalli Pradeep 

Cc: Daniele Ceraolo Spurio 
Cc: Ashutosh Dixit 
Cc: Dnyaneshwar Bhadane 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 23 ---
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  4 
 2 files changed, 13 insertions(+), 14 deletions(-)

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 16640d6dd0589..00757d6333e88 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1403,14 +1403,17 @@ static void guc_cancel_busyness_worker(struct intel_guc 
*guc)
 * Trying to pass a 'need_sync' or 'in_reset' flag all the way down 
through
 * every possible call stack is unfeasible. It would be too intrusive 
to many
 * areas that really don't care about the GuC backend. However, there 
is the
-* 'reset_in_progress' flag available, so just use that.
+* I915_RESET_BACKOFF flag and the gt->reset.mutex can be tested for 
is_locked.
+* So just use those. Note that testing both is required due to the 
hideously
+* complex nature of the i915 driver's reset code paths.
 *
 * And note that in the case of a reset occurring during driver unload
-* (wedge_on_fini), skipping the cancel in _prepare (when the reset 
flag is set
-* is fine because there is another cancel in _finish (when the reset 
flag is
-* not).
+* (wedged_on_fini), skipping the cancel in reset_prepare/reset_fini 
(when the
+* reset flag/mutex are set) is fine because there is another explicit 
cancel in
+* intel_guc_submission_fini (when the reset flag/mutex are not).
 */
-   if (guc_to_gt(guc)->uc.reset_in_progress)
+   if (mutex_is_locked(_to_gt(guc)->reset.mutex) ||
+   test_bit(I915_RESET_BACKOFF, _to_gt(guc)->reset.flags))
cancel_delayed_work(>timestamp.work);
else
cancel_delayed_work_sync(>timestamp.work);
@@ -1424,8 +1427,6 @@ static void __reset_guc_busyness_stats(struct intel_guc 
*guc)
unsigned long flags;
ktime_t unused;
 
-   guc_cancel_busyness_worker(guc);
-
spin_lock_irqsave(>timestamp.lock, flags);
 
guc_update_pm_timestamp(guc, );
@@ -2004,13 +2005,6 @@ void intel_guc_submission_cancel_requests(struct 
intel_guc *guc)
 
 void intel_guc_submission_reset_finish(struct intel_guc *guc)
 {
-   /*
-* Ensure the busyness worker gets cancelled even on a fatal wedge.
-* Note that reset_prepare is not allowed to because it confuses 
lockdep.
-*/
-   if (guc_submission_initialized(guc))
-   guc_cancel_busyness_worker(guc);
-
/* Reset called during driver load or during wedge? */
if (unlikely(!guc_submission_initialized(guc) ||
 

[PATCH] drm/i915/guc: Update w/a 14019159160

2024-03-07 Thread John . C . Harrison
From: John Harrison 

An existing workaround has been extended in both platforms affected
and implementation complexity.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 21 ++-
 3 files changed, 15 insertions(+), 12 deletions(-)

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 bebf28e3c4794..3e7060e859794 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
@@ -105,7 +105,8 @@ enum {
  * Workaround keys:
  */
 enum {
-   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,   /* Wa_14019159160 */
+   GUC_WORKAROUND_KLV_AVOID_GFX_CLEAR_WHILE_ACTIVE = 
0x9006,   /* Wa_14019159160 */
 };
 
 #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 0c67d674c94de..4c3dae98656af 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -296,7 +296,8 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
 
/* Wa_16019325821 */
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) ||
+   IS_DG2(gt->i915))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
/*
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 5c9908b56616e..00fe3c21a9b1c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -815,23 +815,23 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
-/* Wa_14019159160 */
-static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+static void guc_waklv_enable_simple(struct intel_guc *guc, u32 *offset, u32 
*remain, u32 klv_id)
 {
u32 size;
u32 klv_entry[] = {
/* 16:16 key/length */
-   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_KEY, klv_id) |
FIELD_PREP(GUC_KLV_0_LEN, 0),
/* 0 dwords data */
};
 
size = sizeof(klv_entry);
-   GEM_BUG_ON(remain < size);
+   GEM_BUG_ON(*remain < size);
 
-   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+   iosys_map_memcpy_to(>ads_map, *offset, klv_entry, size);
 
-   return size;
+   *offset += size;
+   *remain -= size;
 }
 
 static void guc_waklv_init(struct intel_guc *guc)
@@ -850,10 +850,11 @@ static void guc_waklv_init(struct intel_guc *guc)
remain = guc_ads_waklv_size(guc);
 
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
-   size = guc_waklv_ra_mode(guc, offset, remain);
-   offset += size;
-   remain -= size;
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) || 
IS_DG2(gt->i915)) {
+   guc_waklv_enable_simple(guc, , ,
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE);
+   guc_waklv_enable_simple(guc, , ,
+   
GUC_WORKAROUND_KLV_AVOID_GFX_CLEAR_WHILE_ACTIVE);
}
 
size = guc_ads_waklv_size(guc) - remain;
-- 
2.43.0



[PATCH v3 0/3] Enable Wa_14019159160 and Wa_16019325821 for MTL

2024-02-23 Thread John . C . Harrison
From: John Harrison 

Enable Wa_14019159160 and  Wa_16019325821 for MTL

RCS/CCS workarounds for MTL.

v2: Fix bug in WA KLV implementation (offset not being reset to start
of list). Add better comment to prep patch about how KLVs can be added.
Add a module parameter override and disable the w/a by default as it
causes performance regressions and is only required by very specific
workloads.
v3: Rebase to latest tree. Drop module parameter as performance
regression is apparently not detectable after all and a bunch of more
common workloads have been seen to hit the issue.

Signed-off-by: John Harrison 


John Harrison (3):
  drm/i915: Enable Wa_16019325821
  drm/i915/guc: Add support for w/a KLVs
  drm/i915/guc: Enable Wa_14019159160

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 22 +++--
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  8 +-
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  5 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 89 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 +-
 10 files changed, 141 insertions(+), 15 deletions(-)

-- 
2.43.0



[PATCH v3 2/3] drm/i915/guc: Add support for w/a KLVs

2024-02-23 Thread John . C . Harrison
From: John Harrison 

To prevent running out of bits, new w/a enable flags are being added
via a KLV system instead of a 32 bit flags word.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 73 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  5 +-
 5 files changed, 85 insertions(+), 2 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 dabeaf4f245f3..00d6402333f8e 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
@@ -36,6 +36,7 @@ enum intel_guc_load_status {
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_KLV_WORKAROUND_INIT_ERROR= 0x75,
INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index be70c46604b49..57b9031327767 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -204,6 +204,8 @@ struct intel_guc {
struct guc_mmio_reg *ads_regset;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
u32 ads_golden_ctxt_size;
+   /** @ads_waklv_size: size of workaround KLVs */
+   u32 ads_waklv_size;
/** @ads_capture_size: size of register lists in the ADS used for error 
capture */
u32 ads_capture_size;
 
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 f7372f736a776..6af3fa8b92e34 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *  +---+
  *  | padding   |
  *  +---+ <== 4K aligned
+ *  | w/a KLVs  |
+ *  +---+
+ *  | padding   |
+ *  +---+ <== 4K aligned
  *  | capture lists |
  *  +---+
  *  | padding   |
@@ -88,6 +92,11 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+   return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
u32 offset;
 
@@ -123,6 +132,16 @@ static u32 guc_ads_capture_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+   u32 offset;
+
+   offset = guc_ads_waklv_offset(guc) +
+guc_ads_waklv_size(guc);
+
+   return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
u32 offset;
@@ -796,6 +815,49 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+static void guc_waklv_init(struct intel_guc *guc)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   u32 offset, addr_ggtt, remain, size;
+
+   if (!intel_uc_uses_guc_submission(>uc))
+   return;
+
+   if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+   return;
+
+   GEM_BUG_ON(iosys_map_is_null(>ads_map));
+   offset = guc_ads_waklv_offset(guc);
+   remain = guc_ads_waklv_size(guc);
+
+   /*
+* Add workarounds here:
+*
+* if (want_wa_) {
+*  size = guc_waklv_(guc, offset, remain);
+*  offset += size;
+*  remain -= size;
+* }
+*/
+
+   size = guc_ads_waklv_size(guc) - remain;
+   if (!size)
+   return;
+
+   offset = guc_ads_waklv_offset(guc);
+   addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+   ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt);
+   ads_blob_write(guc, ads.wa_klv_addr_hi, 0);
+   ads_blob_write(guc, ads.wa_klv_size, size);
+}
+
+static int guc_prep_waklv(struct intel_guc *guc)
+{
+   /* Fudge something chunky for now: */
+   

[PATCH v3 1/3] drm/i915: Enable Wa_16019325821

2024-02-23 Thread John . C . Harrison
From: John Harrison 

Some platforms require holding RCS context switches until CCS is idle
(the reverse w/a of Wa_14014475959). Some platforms require both
versions.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 19 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  7 ++-
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index e1bf13e3d3070..bb8e4c151a026 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -743,21 +743,23 @@ static u32 *gen12_emit_preempt_busywait(struct 
i915_request *rq, u32 *cs)
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
return i915_ggtt_offset(rq->context->state) +
-   (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+   (LRC_PPHWSP_PN * PAGE_SIZE) + 
HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
 
*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
MI_ATOMIC_MOVE;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
*cs++ = 1;
 
@@ -773,7 +775,7 @@ static u32 *ccs_emit_wa_busywait(struct i915_request *rq, 
u32 *cs)
MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_EQ_SDD;
*cs++ = 0;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
 
return cs;
@@ -790,8 +792,9 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
cs = gen12_emit_preempt_busywait(rq, cs);
 
/* Wa_14014475959:dg2 */
-   if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-   cs = ccs_emit_wa_busywait(rq, cs);
+   /* Wa_16019325821 */
+   if (intel_engine_uses_wa_hold_switchout(rq->engine))
+   cs = hold_switchout_emit_wa_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
assert_ring_tail_valid(rq->ring, rq->tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 960e6be2042fe..b519812ba120d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -586,7 +586,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
unsigned int flags;
 
/*
@@ -696,10 +696,11 @@ intel_engine_has_relative_mmio(const struct 
intel_engine_cs * const engine)
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-   return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+   return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2b450c43bbd7f..d5c856be31491 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+   /* Wa_16019325821 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
/*
 * Wa_14012197797
 * Wa_22011391025
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 8ae1846431da7..48863188a130e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -96,8 +96,9 @@
 #define   GUC_WA_GAM_CREDITS   BIT(10)
 #define   GUC_WA_DUAL_QUEUEBIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6  BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
 #define   GUC_WA_PRE_PARSERBIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
+#define  

[PATCH v3 3/3] drm/i915/guc: Enable Wa_14019159160

2024-02-23 Thread John . C . Harrison
From: John Harrison 

Use the new w/a KLV support to enable a MTL w/a. Note, this w/a is a
super-set of Wa_16019325821, so requires turning that one as well as
setting the new flag for Wa_14019159160 itself.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  3 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 34 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  1 +
 6 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index bb8e4c151a026..8cf58b29410bc 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -744,6 +744,7 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request 
*rq, u32 *cs)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 #define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
 static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
@@ -753,6 +754,7 @@ static u32 hold_switchout_semaphore_offset(struct 
i915_request *rq)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
@@ -793,6 +795,7 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
 
/* Wa_14014475959:dg2 */
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (intel_engine_uses_wa_hold_switchout(rq->engine))
cs = hold_switchout_emit_wa_busywait(rq, cs);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index b519812ba120d..ba55c059063db 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -697,6 +697,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs 
* const engine)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
 intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
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 58012edd4eb0e..bebf28e3c4794 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
@@ -101,4 +101,11 @@ enum {
GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+};
+
 #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 d5c856be31491..db3cb628f40dc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -295,6 +295,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
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 6af3fa8b92e34..68d9e277eca8b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -815,6 +815,25 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+   u32 size;
+   u32 klv_entry[] = {
+   /* 16:16 key/length */
+   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_LEN, 0),
+   /* 0 dwords data */
+   };
+
+   size = sizeof(klv_entry);
+   GEM_BUG_ON(remain < size);
+
+   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+
+   return size;
+}
+
 static void guc_waklv_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -830,15 +849,12 @@ static void guc_waklv_init(struct intel_guc *guc)
offset = guc_ads_waklv_offset(guc);
remain = guc_ads_waklv_size(guc);
 
-   /*
-* Add workarounds here:
-*
-* if (want_wa_) {
-*  size = guc_waklv_(guc, offset, remain);
-*  offset += size;
-*  remain -= size;
-* }
-*/
+   /* Wa_14019159160 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   size = guc_waklv_ra_mode(guc, offset, remain);
+   offset += size;
+   remain -= size;
+   }
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
diff --git 

[PATCH] drm/i915/guc: Correct capture of EIR register on hang

2024-02-23 Thread John . C . Harrison
From: John Harrison 

The EIR register (0x20B0) was being included in the engine class list
for render and compute as the absolute register address. However, it
is actually a ring register available on all engines at an offset of
(base) + 0xB0. As it was included as an RCS engine but with the
absolute address, GuC was adding on another 0x2000 and coming out at
an invalid location. Thus it would reject the register and complain
about only managing a partial capture.

So update the list to use the RING_EIR version of the register and
include it for all engines.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index a1cd40d805178..0cb5f22a173cb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -51,6 +51,7 @@
{ RING_ESR(0),  0,  0, "ESR" }, \
{ RING_DMA_FADD(0), 0,  0, "RING_DMA_FADD_LDW" }, \
{ RING_DMA_FADD_UDW(0), 0,  0, "RING_DMA_FADD_UDW" }, \
+   { RING_EIR(0),  0,  0, "EIR" }, \
{ RING_IPEIR(0),0,  0, "IPEIR" }, \
{ RING_IPEHR(0),0,  0, "IPEHR" }, \
{ RING_INSTPS(0),   0,  0, "INSTPS" }, \
@@ -80,9 +81,6 @@
{ GEN8_RING_PDP_LDW(0, 3),  0,  0, "PDP3_LDW" }, \
{ GEN8_RING_PDP_UDW(0, 3),  0,  0, "PDP3_UDW" }
 
-#define COMMON_BASE_HAS_EU \
-   { EIR,  0,  0, "EIR" }
-
 #define COMMON_BASE_RENDER \
{ GEN7_SC_INSTDONE, 0,  0, "GEN7_SC_INSTDONE" }
 
@@ -105,7 +103,6 @@ static const struct __guc_mmio_reg_descr 
xe_lp_global_regs[] = {
 
 /* XE_LP Render / Compute Per-Class */
 static const struct __guc_mmio_reg_descr xe_lp_rc_class_regs[] = {
-   COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
COMMON_GEN12BASE_RENDER,
 };
@@ -148,7 +145,6 @@ static const struct __guc_mmio_reg_descr gen8_global_regs[] 
= {
 };
 
 static const struct __guc_mmio_reg_descr gen8_rc_class_regs[] = {
-   COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
 };
 
-- 
2.43.0



[PATCH v3] drm/i915/guc: Simplify/extend platform check for Wa_14018913170

2024-02-23 Thread John . C . Harrison
From: John Harrison 

The above w/a is required for every platform that the i915 driver
supports. It is fixed on the latest platforms but they are only
supported by Xe instead of i915. So just remove the platform check
completely and keep the code simple.

v2: Add extra comment (review feedback from Rodrigo).

Signed-off-by: John Harrison 
Reviewed-by: Rodrigo Vivi 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2b450c43bbd7f..d2b7425bbdcc2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -319,10 +319,12 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
if (!RCS_MASK(gt))
flags |= GUC_WA_RCS_REGS_IN_CCS_REGS_LIST;
 
-   /* Wa_14018913170 */
+   /*
+* Wa_14018913170: Applicable to all platforms supported by i915 so
+* don't bother testing for all X/Y/Z platforms explicitly.
+*/
if (GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 7, 0)) {
-   if (IS_DG2(gt->i915) || IS_METEORLAKE(gt->i915) || 
IS_PONTEVECCHIO(gt->i915))
-   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
+   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
}
 
return flags;
-- 
2.43.0



PR for new GuC v70.20.0 binaries

2024-02-16 Thread John . C . Harrison
The following changes since commit fbef4d381e3d0143427e1a8c924be8e738c0fc2d:

  Merge branch 'main' into 'main' (2024-02-08 12:24:01 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.20.0

for you to fetch changes up to 28c2472d37d089edb56c75e3af83511babaa756c:

  xe: First GuC release for LNL and Xe (2024-02-14 16:28:32 -0800)


John Harrison (2):
  i915: Add GuC v70.20.0 for ADL-P, DG1, DG2, MTL and TGL
  xe: First GuC release for LNL and Xe

 LICENSE.xe   |  39 +++
 WHENCE   |  20 ++--
 i915/adlp_guc_70.bin | Bin 342848 -> 347584 bytes
 i915/dg1_guc_70.bin  | Bin 272512 -> 321472 bytes
 i915/dg2_guc_70.bin  | Bin 443200 -> 410368 bytes
 i915/mtl_guc_70.bin  | Bin 365376 -> 332544 bytes
 i915/tgl_guc_70.bin  | Bin 330304 -> 335168 bytes
 xe/lnl_guc_70.bin| Bin 0 -> 336640 bytes
 8 files changed, 53 insertions(+), 6 deletions(-)
 create mode 100644 LICENSE.xe
 create mode 100644 xe/lnl_guc_70.bin


[PATCH v3] drm/i915/guc: Simplify/extend platform check for Wa_14018913170

2024-02-16 Thread John . C . Harrison
From: John Harrison 

The above w/a is required for every platform that the i915 driver
supports. It is fixed on the latest platforms but they are only
supported by Xe instead of i915. So just remove the platform check
completely and keep the code simple.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2b450c43bbd7f..a3662edb42032 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -321,8 +321,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
 
/* Wa_14018913170 */
if (GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 7, 0)) {
-   if (IS_DG2(gt->i915) || IS_METEORLAKE(gt->i915) || 
IS_PONTEVECCHIO(gt->i915))
-   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
+   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
}
 
return flags;
-- 
2.43.0



[CI] PR for new GuC v70.20.0

2024-02-14 Thread John . C . Harrison
The following changes since commit fbef4d381e3d0143427e1a8c924be8e738c0fc2d:

  Merge branch 'main' into 'main' (2024-02-08 12:24:01 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.20.0_with_pvc

for you to fetch changes up to 609c1c4654f7f5f0c96f737679a823a29e44ca1e:

  xe: Add GuC 70.20.0 for PVC (2024-02-14 16:34:11 -0800)


Daniele Ceraolo Spurio (1):
  xe: Add GuC 70.20.0 for PVC

John Harrison (2):
  i915: Add GuC v70.20.0 for ADL-P, DG1, DG2, MTL and TGL
  xe: First GuC release for LNL and Xe

 LICENSE.xe |  39 +++
 WHENCE |  23 +--
 i915/adlp_guc_70.bin   | Bin 342848 -> 347584 bytes
 i915/dg1_guc_70.bin| Bin 272512 -> 321472 bytes
 i915/dg2_guc_70.bin| Bin 443200 -> 410368 bytes
 i915/mtl_guc_70.bin| Bin 365376 -> 332544 bytes
 i915/tgl_guc_70.bin| Bin 330304 -> 335168 bytes
 xe/lnl_guc_70.bin  | Bin 0 -> 336640 bytes
 xe/pvc_guc_70.20.0.bin | Bin 0 -> 553728 bytes
 9 files changed, 56 insertions(+), 6 deletions(-)
 create mode 100644 LICENSE.xe
 create mode 100644 xe/lnl_guc_70.bin
 create mode 100644 xe/pvc_guc_70.20.0.bin


PR for new GuC v70.19.2

2024-02-01 Thread John . C . Harrison
The following changes since commit 1a9518c73c4b54854c9cd8f416fd3b8f8e3456e7:

  Merge branch 'mlimonci/amd-2024-01-30.2' into 'main' (2024-01-30 15:55:30 
+)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.19.2

for you to fetch changes up to 92c06b3c1b4b93ccd9953825cfd4e6ab56e03f16:

  xe: First GuC release for LNL and Xe (2024-01-30 09:23:50 -0800)


John Harrison (2):
  i915: Add GuC v70.19.2 for ADL-P, DG1, DG2, MTL and TGL
  xe: First GuC release for LNL and Xe

 LICENSE.xe   |  39 +++
 WHENCE   |  20 ++--
 i915/adlp_guc_70.bin | Bin 342848 -> 347264 bytes
 i915/dg1_guc_70.bin  | Bin 272512 -> 321088 bytes
 i915/dg2_guc_70.bin  | Bin 443200 -> 406336 bytes
 i915/mtl_guc_70.bin  | Bin 365376 -> 332608 bytes
 i915/tgl_guc_70.bin  | Bin 330304 -> 334784 bytes
 xe/lnl_guc_70.bin| Bin 0 -> 336704 bytes
 8 files changed, 53 insertions(+), 6 deletions(-)
 create mode 100644 LICENSE.xe
 create mode 100644 xe/lnl_guc_70.bin


[CI] PR for new GuC v70.19.2

2024-01-30 Thread John . C . Harrison
The following changes since commit 1a9518c73c4b54854c9cd8f416fd3b8f8e3456e7:

  Merge branch 'mlimonci/amd-2024-01-30.2' into 'main' (2024-01-30 15:55:30 
+)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.19.2

for you to fetch changes up to 92c06b3c1b4b93ccd9953825cfd4e6ab56e03f16:

  xe: First GuC release for LNL and Xe (2024-01-30 09:23:50 -0800)


John Harrison (2):
  i915: Add GuC v70.19.2 for ADL-P, DG1, DG2, MTL and TGL
  xe: First GuC release for LNL and Xe

 LICENSE.xe   |  39 +++
 WHENCE   |  20 ++--
 i915/adlp_guc_70.bin | Bin 342848 -> 347264 bytes
 i915/dg1_guc_70.bin  | Bin 272512 -> 321088 bytes
 i915/dg2_guc_70.bin  | Bin 443200 -> 406336 bytes
 i915/mtl_guc_70.bin  | Bin 365376 -> 332608 bytes
 i915/tgl_guc_70.bin  | Bin 330304 -> 334784 bytes
 xe/lnl_guc_70.bin| Bin 0 -> 336704 bytes
 8 files changed, 53 insertions(+), 6 deletions(-)
 create mode 100644 LICENSE.xe
 create mode 100644 xe/lnl_guc_70.bin


[PATCH] drm/i915/gt: Restart the heartbeat timer when forcing a pulse

2024-01-10 Thread John . C . Harrison
From: John Harrison 

The context persistence code does things like send super high priority
heartbeat pulses to ensure any leaked context can still be pre-empted
and thus isn't a total denial of service but only a minor denial of
service. Unfortunately, it wasn't bothering to restart the heatbeat
worker with a fresh timeout. Thus, if a persistent context happened to
be closed just before the heartbeat was going to go ping anyway then
the forced pulse would get a negligble execution time. And as the
forced pulse is super high priority, the worker thread's next step is
a reset. Which means a potentially innocent system randomly goes boom
when attempting to close a context. So, force a re-schedule of the
worker thread with the appropriate timeout.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c 
b/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
index 1a8e2b7db0138..4ae2fa0b61dd4 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_heartbeat.c
@@ -290,6 +290,9 @@ static int __intel_engine_pulse(struct intel_engine_cs 
*engine)
heartbeat_commit(rq, );
GEM_BUG_ON(rq->sched.attr.priority < I915_PRIORITY_BARRIER);
 
+   /* Ensure the forced pulse gets a full period to execute */
+   next_heartbeat(engine);
+
return 0;
 }
 
-- 
2.43.0



[PATCH v3 3/3] drm/i915/guc: Enable Wa_14019159160

2024-01-04 Thread John . C . Harrison
From: John Harrison 

Use the new w/a KLV support to enable a MTL w/a. Note, this w/a is a
super-set of Wa_16019325821, so requires turning that one as well as
setting the new flag for Wa_14019159160 itself.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  3 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 34 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  1 +
 6 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 9cccd60a5c41d..359b21fb02ab2 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -744,6 +744,7 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request 
*rq, u32 *cs)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 #define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
 static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
@@ -753,6 +754,7 @@ static u32 hold_switchout_semaphore_offset(struct 
i915_request *rq)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
@@ -793,6 +795,7 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
 
/* Wa_14014475959:dg2 */
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (intel_engine_uses_wa_hold_switchout(rq->engine))
cs = hold_switchout_emit_wa_busywait(rq, cs);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index b519812ba120d..ba55c059063db 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -697,6 +697,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs 
* const engine)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
 intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
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 58012edd4eb0e..bebf28e3c4794 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
@@ -101,4 +101,11 @@ enum {
GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+};
+
 #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 d5c856be31491..db3cb628f40dc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -295,6 +295,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
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 6af3fa8b92e34..68d9e277eca8b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -815,6 +815,25 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+   u32 size;
+   u32 klv_entry[] = {
+   /* 16:16 key/length */
+   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_LEN, 0),
+   /* 0 dwords data */
+   };
+
+   size = sizeof(klv_entry);
+   GEM_BUG_ON(remain < size);
+
+   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+
+   return size;
+}
+
 static void guc_waklv_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -830,15 +849,12 @@ static void guc_waklv_init(struct intel_guc *guc)
offset = guc_ads_waklv_offset(guc);
remain = guc_ads_waklv_size(guc);
 
-   /*
-* Add workarounds here:
-*
-* if (want_wa_) {
-*  size = guc_waklv_(guc, offset, remain);
-*  offset += size;
-*  remain -= size;
-* }
-*/
+   /* Wa_14019159160 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   size = guc_waklv_ra_mode(guc, offset, remain);
+   offset += size;
+   remain -= size;
+   }
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
diff --git 

[PATCH v3 2/3] drm/i915/guc: Add support for w/a KLVs

2024-01-04 Thread John . C . Harrison
From: John Harrison 

To prevent running out of bits, new w/a enable flags are being added
via a KLV system instead of a 32 bit flags word.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 73 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  5 +-
 5 files changed, 85 insertions(+), 2 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 dabeaf4f245f3..00d6402333f8e 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
@@ -36,6 +36,7 @@ enum intel_guc_load_status {
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_KLV_WORKAROUND_INIT_ERROR= 0x75,
INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 813cc888e6fae..b572fc10fd24d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -204,6 +204,8 @@ struct intel_guc {
struct guc_mmio_reg *ads_regset;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
u32 ads_golden_ctxt_size;
+   /** @ads_waklv_size: size of workaround KLVs */
+   u32 ads_waklv_size;
/** @ads_capture_size: size of register lists in the ADS used for error 
capture */
u32 ads_capture_size;
/** @ads_engine_usage_size: size of engine usage in the ADS */
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 f7372f736a776..6af3fa8b92e34 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *  +---+
  *  | padding   |
  *  +---+ <== 4K aligned
+ *  | w/a KLVs  |
+ *  +---+
+ *  | padding   |
+ *  +---+ <== 4K aligned
  *  | capture lists |
  *  +---+
  *  | padding   |
@@ -88,6 +92,11 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+   return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
u32 offset;
 
@@ -123,6 +132,16 @@ static u32 guc_ads_capture_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+   u32 offset;
+
+   offset = guc_ads_waklv_offset(guc) +
+guc_ads_waklv_size(guc);
+
+   return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
u32 offset;
@@ -796,6 +815,49 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+static void guc_waklv_init(struct intel_guc *guc)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   u32 offset, addr_ggtt, remain, size;
+
+   if (!intel_uc_uses_guc_submission(>uc))
+   return;
+
+   if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+   return;
+
+   GEM_BUG_ON(iosys_map_is_null(>ads_map));
+   offset = guc_ads_waklv_offset(guc);
+   remain = guc_ads_waklv_size(guc);
+
+   /*
+* Add workarounds here:
+*
+* if (want_wa_) {
+*  size = guc_waklv_(guc, offset, remain);
+*  offset += size;
+*  remain -= size;
+* }
+*/
+
+   size = guc_ads_waklv_size(guc) - remain;
+   if (!size)
+   return;
+
+   offset = guc_ads_waklv_offset(guc);
+   addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+   ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt);
+   ads_blob_write(guc, ads.wa_klv_addr_hi, 0);
+   ads_blob_write(guc, ads.wa_klv_size, size);
+}
+
+static int guc_prep_waklv(struct intel_guc 

[PATCH v3 0/3] Enable Wa_14019159160 and Wa_16019325821 for MTL

2024-01-04 Thread John . C . Harrison
From: John Harrison 

Enable Wa_14019159160 and  Wa_16019325821 for MTL

RCS/CCS workarounds for MTL.

v2: Fix bug in WA KLV implementation (offset not being reset to start
of list). Add better comment to prep patch about how KLVs can be added.
Add a module parameter override and disable the w/a by default as it
causes performance regressions and is only required by very specific
workloads.
v3: Rebase to latest tree. Drop module parameter as performance
regression is apparently not detectable after all and a bunch of more
common workloads have been seen to hit the issue.

Signed-off-by: John Harrison 


John Harrison (3):
  drm/i915: Enable Wa_16019325821
  drm/i915/guc: Add support for w/a KLVs
  drm/i915/guc: Enable Wa_14019159160

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 22 +++--
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  8 +-
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  5 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 89 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 +-
 10 files changed, 141 insertions(+), 15 deletions(-)

-- 
2.41.0



[PATCH v3 1/3] drm/i915: Enable Wa_16019325821

2024-01-04 Thread John . C . Harrison
From: John Harrison 

Some platforms require holding RCS context switches until CCS is idle
(the reverse w/a of Wa_14014475959). Some platforms require both
versions.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 19 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  7 ++-
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 86a04afff64b3..9cccd60a5c41d 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -743,21 +743,23 @@ static u32 *gen12_emit_preempt_busywait(struct 
i915_request *rq, u32 *cs)
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
return i915_ggtt_offset(rq->context->state) +
-   (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+   (LRC_PPHWSP_PN * PAGE_SIZE) + 
HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
 
*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
MI_ATOMIC_MOVE;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
*cs++ = 1;
 
@@ -773,7 +775,7 @@ static u32 *ccs_emit_wa_busywait(struct i915_request *rq, 
u32 *cs)
MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_EQ_SDD;
*cs++ = 0;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
 
return cs;
@@ -790,8 +792,9 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
cs = gen12_emit_preempt_busywait(rq, cs);
 
/* Wa_14014475959:dg2 */
-   if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-   cs = ccs_emit_wa_busywait(rq, cs);
+   /* Wa_16019325821 */
+   if (intel_engine_uses_wa_hold_switchout(rq->engine))
+   cs = hold_switchout_emit_wa_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
assert_ring_tail_valid(rq->ring, rq->tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 960e6be2042fe..b519812ba120d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -586,7 +586,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
unsigned int flags;
 
/*
@@ -696,10 +696,11 @@ intel_engine_has_relative_mmio(const struct 
intel_engine_cs * const engine)
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-   return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+   return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2b450c43bbd7f..d5c856be31491 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+   /* Wa_16019325821 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
/*
 * Wa_14012197797
 * Wa_22011391025
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 8ae1846431da7..48863188a130e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -96,8 +96,9 @@
 #define   GUC_WA_GAM_CREDITS   BIT(10)
 #define   GUC_WA_DUAL_QUEUEBIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6  BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
 #define   GUC_WA_PRE_PARSERBIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
+#define  

[PATCH] drm/i915/huc: Allow for very slow HuC loading

2024-01-02 Thread John . C . Harrison
From: John Harrison 

A failure to load the HuC is occasionally observed where the cause is
believed to be a low GT frequency leading to very long load times.

So a) increase the timeout so that the user still gets a working
system even in the case of slow load. And b) report the frequency
during the load to see if that is the cause of the slow down.

Also update the similar code on the GuC load to not use uncore->gt
when there is a local gt available. The two should match, but no need
for unnecessary de-referencing.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 10 ++--
 drivers/gpu/drm/i915/gt/uc/intel_huc.c| 64 ---
 2 files changed, 63 insertions(+), 11 deletions(-)

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 0f79cb6585182..52332bb143395 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -184,7 +184,7 @@ static int guc_wait_ucode(struct intel_guc *guc)
 * in the seconds range. However, there is a limit on how long an
 * individual wait_for() can wait. So wrap it in a loop.
 */
-   before_freq = intel_rps_read_actual_frequency(>gt->rps);
+   before_freq = intel_rps_read_actual_frequency(>rps);
before = ktime_get();
for (count = 0; count < GUC_LOAD_RETRY_LIMIT; count++) {
ret = wait_for(guc_load_done(uncore, , ), 1000);
@@ -192,7 +192,7 @@ static int guc_wait_ucode(struct intel_guc *guc)
break;
 
guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, 
status = 0x%08X [0x%02X/%02X]\n",
-   count, 
intel_rps_read_actual_frequency(>gt->rps), status,
+   count, intel_rps_read_actual_frequency(>rps), 
status,
REG_FIELD_GET(GS_BOOTROM_MASK, status),
REG_FIELD_GET(GS_UKERNEL_MASK, status));
}
@@ -204,7 +204,7 @@ static int guc_wait_ucode(struct intel_guc *guc)
u32 bootrom = REG_FIELD_GET(GS_BOOTROM_MASK, status);
 
guc_info(guc, "load failed: status = 0x%08X, time = %lldms, 
freq = %dMHz, ret = %d\n",
-status, delta_ms, 
intel_rps_read_actual_frequency(>gt->rps), ret);
+status, delta_ms, 
intel_rps_read_actual_frequency(>rps), ret);
guc_info(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),
 bootrom, ukernel,
@@ -254,11 +254,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_warn(guc, "excessive init time: %lldms! [status = 0x%08X, 
count = %d, ret = %d]\n",
 delta_ms, status, count, ret);
guc_warn(guc, "excessive init time: [freq = %dMHz, before = 
%dMHz, perf_limit_reasons = 0x%08X]\n",
-intel_rps_read_actual_frequency(>gt->rps), 
before_freq,
+intel_rps_read_actual_frequency(>rps), before_freq,
 intel_uncore_read(uncore, 
intel_gt_perf_limit_reasons_reg(gt)));
} else {
guc_dbg(guc, "init took %lldms, freq = %dMHz, before = %dMHz, 
status = 0x%08X, count = %d, ret = %d\n",
-   delta_ms, 
intel_rps_read_actual_frequency(>gt->rps),
+   delta_ms, intel_rps_read_actual_frequency(>rps),
before_freq, status, count, ret);
}
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
index ba9e07fc2b577..9ccec7de9628a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
@@ -6,6 +6,7 @@
 #include 
 
 #include "gt/intel_gt.h"
+#include "gt/intel_rps.h"
 #include "intel_guc_reg.h"
 #include "intel_huc.h"
 #include "intel_huc_print.h"
@@ -447,17 +448,68 @@ static const char *auth_mode_string(struct intel_huc *huc,
return partial ? "clear media" : "all workloads";
 }
 
+/*
+ * Use a longer timeout for debug builds so that problems can be detected
+ * and analysed. But a shorter timeout for releases so that user's don't
+ * wait forever to find out there is a problem. Note that the only reason
+ * an end user should hit the timeout is in case of extreme thermal throttling.
+ * And a system that is that hot during boot is probably dead anyway!
+ */
+#if defined(CONFIG_DRM_I915_DEBUG_GEM)
+#define HUC_LOAD_RETRY_LIMIT   20
+#else
+#define HUC_LOAD_RETRY_LIMIT   3
+#endif
+
 int intel_huc_wait_for_auth_complete(struct intel_huc *huc,
 enum intel_huc_authentication_type type)
 {
struct intel_gt *gt = huc_to_gt(huc);
-   int ret;
+   struct intel_uncore *uncore = gt->uncore;
+   ktime_t before, after, delta;
+   int ret, count;
+   u64 

[PATCH v3 3/3] drm/i915/guc: Enable Wa_14019159160

2023-12-20 Thread John . C . Harrison
From: John Harrison 

Use the new w/a KLV support to enable a MTL w/a. Note, this w/a is a
super-set of Wa_16019325821, so requires turning that one as well as
setting the new flag for Wa_14019159160 itself.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  3 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 34 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  1 +
 6 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 9cccd60a5c41d..359b21fb02ab2 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -744,6 +744,7 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request 
*rq, u32 *cs)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 #define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
 static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
@@ -753,6 +754,7 @@ static u32 hold_switchout_semaphore_offset(struct 
i915_request *rq)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
@@ -793,6 +795,7 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
 
/* Wa_14014475959:dg2 */
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (intel_engine_uses_wa_hold_switchout(rq->engine))
cs = hold_switchout_emit_wa_busywait(rq, cs);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index b519812ba120d..ba55c059063db 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -697,6 +697,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs 
* const engine)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
 intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
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 58012edd4eb0e..bebf28e3c4794 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
@@ -101,4 +101,11 @@ enum {
GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+};
+
 #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 d5c856be31491..db3cb628f40dc 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -295,6 +295,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
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 251e7a7a05cb8..8f7298cbbc322 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -810,6 +810,25 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+   u32 size;
+   u32 klv_entry[] = {
+   /* 16:16 key/length */
+   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_LEN, 0),
+   /* 0 dwords data */
+   };
+
+   size = sizeof(klv_entry);
+   GEM_BUG_ON(remain < size);
+
+   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+
+   return size;
+}
+
 static void guc_waklv_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -825,15 +844,12 @@ static void guc_waklv_init(struct intel_guc *guc)
offset = guc_ads_waklv_offset(guc);
remain = guc_ads_waklv_size(guc);
 
-   /*
-* Add workarounds here:
-*
-* if (want_wa_) {
-*  size = guc_waklv_(guc, offset, remain);
-*  offset += size;
-*  remain -= size;
-* }
-*/
+   /* Wa_14019159160 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   size = guc_waklv_ra_mode(guc, offset, remain);
+   offset += size;
+   remain -= size;
+   }
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
diff --git 

[PATCH v3 1/3] drm/i915: Enable Wa_16019325821

2023-12-20 Thread John . C . Harrison
From: John Harrison 

Some platforms require holding RCS context switches until CCS is idle
(the reverse w/a of Wa_14014475959). Some platforms require both
versions.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 19 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  7 ++-
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 86a04afff64b3..9cccd60a5c41d 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -743,21 +743,23 @@ static u32 *gen12_emit_preempt_busywait(struct 
i915_request *rq, u32 *cs)
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
return i915_ggtt_offset(rq->context->state) +
-   (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+   (LRC_PPHWSP_PN * PAGE_SIZE) + 
HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
 
*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
MI_ATOMIC_MOVE;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
*cs++ = 1;
 
@@ -773,7 +775,7 @@ static u32 *ccs_emit_wa_busywait(struct i915_request *rq, 
u32 *cs)
MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_EQ_SDD;
*cs++ = 0;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
 
return cs;
@@ -790,8 +792,9 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
cs = gen12_emit_preempt_busywait(rq, cs);
 
/* Wa_14014475959:dg2 */
-   if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-   cs = ccs_emit_wa_busywait(rq, cs);
+   /* Wa_16019325821 */
+   if (intel_engine_uses_wa_hold_switchout(rq->engine))
+   cs = hold_switchout_emit_wa_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
assert_ring_tail_valid(rq->ring, rq->tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 960e6be2042fe..b519812ba120d 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -586,7 +586,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
unsigned int flags;
 
/*
@@ -696,10 +696,11 @@ intel_engine_has_relative_mmio(const struct 
intel_engine_cs * const engine)
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-   return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+   return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2b450c43bbd7f..d5c856be31491 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+   /* Wa_16019325821 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
/*
 * Wa_14012197797
 * Wa_22011391025
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 8ae1846431da7..48863188a130e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -96,8 +96,9 @@
 #define   GUC_WA_GAM_CREDITS   BIT(10)
 #define   GUC_WA_DUAL_QUEUEBIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6  BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
 #define   GUC_WA_PRE_PARSERBIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
+#define  

[PATCH v3 2/3] drm/i915/guc: Add support for w/a KLVs

2023-12-20 Thread John . C . Harrison
From: John Harrison 

To prevent running out of bits, new w/a enable flags are being added
via a KLV system instead of a 32 bit flags word.

Signed-off-by: John Harrison 
Reviewed-by: Vinay Belgaumkar 
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 73 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  5 +-
 5 files changed, 85 insertions(+), 2 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 dabeaf4f245f3..00d6402333f8e 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
@@ -36,6 +36,7 @@ enum intel_guc_load_status {
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_KLV_WORKAROUND_INIT_ERROR= 0x75,
INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index e22c12ce245ad..46b2d0e80b993 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -198,6 +198,8 @@ struct intel_guc {
struct guc_mmio_reg *ads_regset;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
u32 ads_golden_ctxt_size;
+   /** @ads_waklv_size: size of workaround KLVs */
+   u32 ads_waklv_size;
/** @ads_capture_size: size of register lists in the ADS used for error 
capture */
u32 ads_capture_size;
/** @ads_engine_usage_size: size of engine usage in the ADS */
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 63724e17829a7..251e7a7a05cb8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *  +---+
  *  | padding   |
  *  +---+ <== 4K aligned
+ *  | w/a KLVs  |
+ *  +---+
+ *  | padding   |
+ *  +---+ <== 4K aligned
  *  | capture lists |
  *  +---+
  *  | padding   |
@@ -88,6 +92,11 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+   return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
u32 offset;
 
@@ -123,6 +132,16 @@ static u32 guc_ads_capture_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+   u32 offset;
+
+   offset = guc_ads_waklv_offset(guc) +
+guc_ads_waklv_size(guc);
+
+   return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
u32 offset;
@@ -791,6 +810,49 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+static void guc_waklv_init(struct intel_guc *guc)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   u32 offset, addr_ggtt, remain, size;
+
+   if (!intel_uc_uses_guc_submission(>uc))
+   return;
+
+   if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+   return;
+
+   GEM_BUG_ON(iosys_map_is_null(>ads_map));
+   offset = guc_ads_waklv_offset(guc);
+   remain = guc_ads_waklv_size(guc);
+
+   /*
+* Add workarounds here:
+*
+* if (want_wa_) {
+*  size = guc_waklv_(guc, offset, remain);
+*  offset += size;
+*  remain -= size;
+* }
+*/
+
+   size = guc_ads_waklv_size(guc) - remain;
+   if (!size)
+   return;
+
+   offset = guc_ads_waklv_offset(guc);
+   addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+   ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt);
+   ads_blob_write(guc, ads.wa_klv_addr_hi, 0);
+   ads_blob_write(guc, ads.wa_klv_size, size);
+}
+
+static int guc_prep_waklv(struct intel_guc 

[PATCH v3 0/3] Enable Wa_14019159160 and Wa_16019325821 for MTL

2023-12-20 Thread John . C . Harrison
From: John Harrison 

Enable Wa_14019159160 and  Wa_16019325821 for MTL

RCS/CCS workarounds for MTL.

v2: Fix bug in WA KLV implementation (offset not being reset to start
of list). Add better comment to prep patch about how KLVs can be added.
Add a module parameter override and disable the w/a by default as it
causes performance regressions and is only required by very specific
workloads.
v3: Rebase to latest tree. Drop module parameter as performance
regression is apparently not detectable after all and a bunch of more
common workloads have been seen to hit the issue.

Signed-off-by: John Harrison 


John Harrison (3):
  drm/i915: Enable Wa_16019325821
  drm/i915/guc: Add support for w/a KLVs
  drm/i915/guc: Enable Wa_14019159160

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 22 +++--
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  8 +-
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  5 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 89 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 +-
 10 files changed, 141 insertions(+), 15 deletions(-)

-- 
2.41.0



[PATCH] drm/i915/guc: Avoid circular locking issue on busyness flush

2023-12-19 Thread John . C . Harrison
From: John Harrison 

Avoid the following lockdep complaint:
<4> [298.856498] ==
<4> [298.856500] WARNING: possible circular locking dependency detected
<4> [298.856503] 6.7.0-rc5-CI_DRM_14017-g58ac4ffc75b6+ #1 Tainted: G
N
<4> [298.856505] --
<4> [298.856507] kworker/4:1H/190 is trying to acquire lock:
<4> [298.856509] 8881103e9978 (>reset.backoff_srcu){}-{0:0}, at:
_intel_gt_reset_lock+0x35/0x380 [i915]
<4> [298.856661]
but task is already holding lock:
<4> [298.856663] c900013f7e58
((work_completion)(&(>timestamp.work)->work)){+.+.}-{0:0}, at:
process_scheduled_works+0x264/0x530
<4> [298.856671]
which lock already depends on the new lock.

The complaint is not actually valid. The busyness worker thread does
indeed hold the worker lock and then attempt to acquire the reset lock
(which may have happened in reverse order elsewhere). However, it does
so with a trylock that exits if the reset lock is not available
(specifically to prevent this and other similar deadlocks).
Unfortunately, lockdep does not understand the trylock semantics (the
lock is an i915 specific custom implementation for resets).

Not doing a synchronous flush of the worker thread when a reset is in
progress resolves the lockdep splat by never even attempting to grab
the lock in this particular scenario.

There are situatons where a synchronous cancel is required, however.
So, always do the synchronous cancel if not in reset. And add an extra
synchronous cancel to the end of the reset flow to account for when a
reset is occurring at driver shutdown and the cancel is no longer
synchronous but could lead to unallocated memory accesses if the
worker is not stopped.

Signed-off-by: Zhanjun Dong 
Signed-off-by: John Harrison 
Cc: Andi Shyti 
Cc: Daniel Vetter 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 48 ++-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |  2 +-
 2 files changed, 48 insertions(+), 2 deletions(-)

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 a259f1118c5ab..0228a77d456ed 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1362,7 +1362,45 @@ static void guc_enable_busyness_worker(struct intel_guc 
*guc)
 
 static void guc_cancel_busyness_worker(struct intel_guc *guc)
 {
-   cancel_delayed_work_sync(>timestamp.work);
+   /*
+* There are many different call stacks that can get here. Some of them
+* hold the reset mutex. The busyness worker also attempts to acquire 
the
+* reset mutex. Synchronously flushing a worker thread requires 
acquiring
+* the worker mutex. Lockdep sees this as a conflict. It thinks that the
+* flush can deadlock because it holds the worker mutex while waiting 
for
+* the reset mutex, but another thread is holding the reset mutex and 
might
+* attempt to use other worker functions.
+*
+* In practice, this scenario does not exist because the busyness worker
+* does not block waiting for the reset mutex. It does a try-lock on it 
and
+* immediately exits if the lock is already held. Unfortunately, the 
mutex
+* in question (I915_RESET_BACKOFF) is an i915 implementation which has 
lockdep
+* annotation but not to the extent of explaining the 'might lock' is 
also a
+* 'does not need to lock'. So one option would be to add more complex 
lockdep
+* annotations to ignore the issue (if at all possible). A simpler 
option is to
+* just not flush synchronously when a rest in progress. Given that the 
worker
+* will just early exit and re-schedule itself anyway, there is no 
advantage
+* to running it immediately.
+*
+* If a reset is not in progress, then the synchronous flush may be 
required.
+* As noted many call stacks lead here, some during suspend and driver 
unload
+* which do require a synchronous flush to make sure the worker is 
stopped
+* before memory is freed.
+*
+* Trying to pass a 'need_sync' or 'in_reset' flag all the way down 
through
+* every possible call stack is unfeasible. It would be too intrusive 
to many
+* areas that really don't care about the GuC backend. However, there 
is the
+* 'reset_in_progress' flag available, so just use that.
+*
+* And note that in the case of a reset occurring during driver unload
+* (wedge_on_fini), skipping the cancel in _prepare (when the reset 
flag is set
+* is fine because there is another cancel in _finish (when the reset 
flag is
+* not).
+*/
+   if (guc_to_gt(guc)->uc.reset_in_progress)
+   cancel_delayed_work(>timestamp.work);
+   else
+   

[Intel-gfx] [PATCH v2 1/2] drm/i915/guc: Fix for potential false positives in GuC hang selftest

2023-11-13 Thread John . C . Harrison
From: John Harrison 

Noticed that the hangcheck selftest is submitting a non-preemptoble
spinner. That means that even if the GuC does not die, the heartbeat
will still kick in and trigger a reset. Which is rather defeating the
purpose of the test - to verify that the heartbeat will kick in if the
GuC itself has died. The test is deliberately killing the GuC, so it
should never hit the case of a non-dead GuC. But it is not impossible
that the kill might fail at some future point due to other driver
re-work.

So, make the spinner pre-emptible. That way the heartbeat can get
through if the GuC is alive and context switching. Thus a reset only
happens if the GuC dies. Thus, if the kill should stop working the
test will now fail rather than claim to pass.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
index 34b5d952e2bcb..26fdc392fce6c 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
@@ -74,7 +74,7 @@ static int intel_hang_guc(void *arg)
goto err;
}
 
-   rq = igt_spinner_create_request(, ce, MI_NOOP);
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
intel_context_put(ce);
if (IS_ERR(rq)) {
ret = PTR_ERR(rq);
-- 
2.41.0



[Intel-gfx] [PATCH v2 2/2] drm/i915/guc: Add a selftest for FAST_REQUEST errors

2023-11-13 Thread John . C . Harrison
From: John Harrison 

There is a mechanism for reporting errors from fire and forget H2G
messages. This is the only way to find out about almost any error in
the GuC backend submission path. So it would be useful to know that it
is working.

v2: Fix some dumb over-complications and a couple of typos - review
feedback from Daniele.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 115 ++
 3 files changed, 128 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..e22c12ce245ad 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -297,6 +297,10 @@ struct intel_guc {
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
 */
int number_guc_id_stolen;
+   /**
+* @fast_response_selftest: Backdoor to CT handler for fast response 
selftest
+*/
+   u32 fast_response_selftest;
 #endif
 };
 
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 89e314b3756bb..ed6ce73ef3b07 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1076,6 +1076,15 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
found = true;
break;
}
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (!found && ct_to_guc(ct)->fast_response_selftest) {
+   CT_DEBUG(ct, "Assuming unsolicited response due to FAST_REQUEST 
selftest\n");
+   ct_to_guc(ct)->fast_response_selftest++;
+   found = true;
+   }
+#endif
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x 
(fence %u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index bfb72143566f6..c900aac85adba 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -286,11 +286,126 @@ static int intel_guc_steal_guc_ids(void *arg)
return ret;
 }
 
+/*
+ * Send a context schedule H2G message with an invalid context id.
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
+ */
+static int bad_h2g(struct intel_guc *guc)
+{
+   u32 action[] = {
+  INTEL_GUC_ACTION_SCHED_CONTEXT,
+  0x12345678,
+   };
+
+   return intel_guc_send_nb(guc, action, ARRAY_SIZE(action), 0);
+}
+
+/*
+ * Set a spinner running to make sure the system is alive and active,
+ * then send a bad but asynchronous H2G command and wait to see if an
+ * error response is returned. If no response is received or if the
+ * spinner dies then the test will fail.
+ */
+#define FAST_RESPONSE_TIMEOUT_MS   1000
+static int intel_guc_fast_request(void *arg)
+{
+   struct intel_gt *gt = arg;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct intel_engine_cs *engine = intel_selftest_find_any_engine(gt);
+   bool spinning = false;
+   int ret = 0;
+
+   if (!engine)
+   return 0;
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   gt_err(gt, "Failed to create spinner request: %pe\n", ce);
+   goto err_pm;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   gt_err(gt, "Failed to create spinner: %pe\n", ERR_PTR(ret));
+   goto err_pm;
+   }
+   spinning = true;
+
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   gt_err(gt, "Failed to create spinner request: %pe\n", rq);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   gt_err(gt, "Failed to add Spinner request: %pe\n", 
ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   gt->uc.guc.fast_response_selftest = 1;
+
+   ret = bad_h2g(>uc.guc);
+   if (ret) {
+   gt_err(gt, "Failed to send H2G: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   ret = wait_for(gt->uc.guc.fast_response_selftest != 1 || 
i915_request_completed(rq),
+  FAST_RESPONSE_TIMEOUT_MS);
+   if (ret) {
+   gt_err(gt, "Request wait failed: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   if (i915_request_completed(rq)) {
+   gt_err(gt, "Spinner died waiting for fast request error!\n");
+   

[Intel-gfx] [PATCH v2 0/2] Selftest for FAST_REQUEST feature

2023-11-13 Thread John . C . Harrison
From: John Harrison 

Add a selftest to verify that the FAST_REQUEST mechanism (getting
errors back from fire-and-forget H2G commands) is functional.

Also fix up a potential false positive in the GuC hang selftest.

v2: Fix some dumb over-complications and typos - review feedback from
Daniele.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/guc: Fix for potential false positives in GuC hang selftest
  drm/i915/guc: Add a selftest for FAST_REQUEST errors

 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 115 ++
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   |   2 +-
 4 files changed, 129 insertions(+), 1 deletion(-)

-- 
2.41.0



[Intel-gfx] [PATCH 1/2] drm/i915/guc: Don't double enable a context

2023-11-09 Thread John . C . Harrison
From: John Harrison 

If a context is blocked, unblocked and subitted repeatedly in rapid
succession, the driver can end up trying to enable the context while
the previous enable request is still in flight. This can lead to much
confusion in the state tracking.

Prevent that by checking the pending enable flag before trying to
enable a context.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 d37698bd6b91a..d399e4d238c10 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -720,7 +720,7 @@ static int __guc_add_request(struct intel_guc *guc, struct 
i915_request *rq)
if (unlikely(context_blocked(ce) && !intel_context_is_parent(ce)))
goto out;
 
-   enabled = context_enabled(ce) || context_blocked(ce);
+   enabled = context_enabled(ce) || context_blocked(ce) || 
context_pending_enable(ce);
 
if (!enabled) {
action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_SET;
-- 
2.41.0



[Intel-gfx] [PATCH 2/2] drm/i915/guc: Don't disable a context whose enable is still pending

2023-11-09 Thread John . C . Harrison
From: John Harrison 

Various processes involve requesting GuC to disable a given context.
However context enable/disable is an asynchronous process in the GuC.
Thus, it is possible the previous enable request is still being
processed when the disable request is triggered. Having both enable
and disable in flight concurrently is illegal - GuC will return an
error and fail the second operation. The KMD side handler for the
completion message also can't cope with having both pending flags set.
So delay the disable request until it is safe to send.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 31 +++
 1 file changed, 25 insertions(+), 6 deletions(-)

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 d399e4d238c10..8c34b0a5abf9a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -3150,7 +3150,8 @@ guc_context_revoke(struct intel_context *ce, struct 
i915_request *rq,
guc_cancel_context_requests(ce);
intel_engine_signal_breadcrumbs(ce->engine);
} else if (!context_pending_disable(ce)) {
-   u16 guc_id;
+   u16 guc_id = ~0;
+   bool pending_enable = context_pending_enable(ce);
 
/*
 * We add +2 here as the schedule disable complete CTB handler
@@ -3158,7 +3159,11 @@ guc_context_revoke(struct intel_context *ce, struct 
i915_request *rq,
 */
atomic_add(2, >pin_count);
 
-   guc_id = prep_context_pending_disable(ce);
+   if (pending_enable)
+   guc_id = ce->guc_id.id;
+   else
+   guc_id = prep_context_pending_disable(ce);
+
spin_unlock_irqrestore(>guc_state.lock, flags);
 
/*
@@ -3169,7 +3174,15 @@ guc_context_revoke(struct intel_context *ce, struct 
i915_request *rq,
with_intel_runtime_pm(runtime_pm, wakeref) {
__guc_context_set_preemption_timeout(guc, guc_id,
 
preempt_timeout_ms);
-   __guc_context_sched_disable(guc, ce, guc_id);
+   if (!pending_enable)
+   __guc_context_sched_disable(guc, ce, guc_id);
+   }
+
+   if (pending_enable) {
+   /* Can't have both in flight concurrently, so try again 
later... */
+   mod_delayed_work(system_unbound_wq,
+
>guc_state.sched_disable_delay_work,
+msecs_to_jiffies(1));
}
} else {
if (!context_guc_id_invalid(ce))
@@ -3222,7 +3235,13 @@ static void __delay_sched_disable(struct work_struct 
*wrk)
 
spin_lock_irqsave(>guc_state.lock, flags);
 
-   if (bypass_sched_disable(guc, ce)) {
+   if (context_pending_enable(ce)) {
+   spin_unlock_irqrestore(>guc_state.lock, flags);
+   /* Can't have both in flight concurrently, so try again 
later... */
+   mod_delayed_work(system_unbound_wq,
+>guc_state.sched_disable_delay_work,
+msecs_to_jiffies(1));
+   } else if (bypass_sched_disable(guc, ce)) {
spin_unlock_irqrestore(>guc_state.lock, flags);
intel_context_sched_disable_unpin(ce);
} else {
@@ -3257,8 +3276,8 @@ static void guc_context_sched_disable(struct 
intel_context *ce)
if (bypass_sched_disable(guc, ce)) {
spin_unlock_irqrestore(>guc_state.lock, flags);
intel_context_sched_disable_unpin(ce);
-   } else if (!intel_context_is_closed(ce) && !guc_id_pressure(guc, ce) &&
-  delay) {
+   } else if ((!intel_context_is_closed(ce) && !guc_id_pressure(guc, ce) &&
+   delay) || context_pending_enable(ce)) {
spin_unlock_irqrestore(>guc_state.lock, flags);
mod_delayed_work(system_unbound_wq,
 >guc_state.sched_disable_delay_work,
-- 
2.41.0



[Intel-gfx] [PATCH 0/2] Don't send double context enable/disable requests

2023-11-09 Thread John . C . Harrison
From: John Harrison 

The driver could sometimes send context enable/disable requests when a
previous request was still pending. This is not allowed. So stop doing
it.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/guc: Don't double enable a context
  drm/i915/guc: Don't disable a context whose enable is still pending

 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 33 +++
 1 file changed, 26 insertions(+), 7 deletions(-)

-- 
2.41.0



[Intel-gfx] [PATCH 2/2] drm/i915/guc: Add a selftest for FAST_REQUEST errors

2023-11-06 Thread John . C . Harrison
From: John Harrison 

There is a mechanism for reporting errors from fire and forget H2G
messages. This is the only way to find out about almost any error in
the GuC backend submission path. So it would be useful to know that it
is working.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 122 ++
 3 files changed, 135 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..e22c12ce245ad 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -297,6 +297,10 @@ struct intel_guc {
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
 */
int number_guc_id_stolen;
+   /**
+* @fast_response_selftest: Backdoor to CT handler for fast response 
selftest
+*/
+   u32 fast_response_selftest;
 #endif
 };
 
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 89e314b3756bb..9d958afb78b7f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1076,6 +1076,15 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
found = true;
break;
}
+
+#ifdef CONFIG_DRM_I915_SELFTEST
+   if (!found && ct_to_guc(ct)->fast_response_selftest) {
+   CT_DEBUG(ct, "Assuming unsolicited response due to FAST_REQUEST 
selftest\n");
+   ct_to_guc(ct)->fast_response_selftest++;
+   found = 1;
+   }
+#endif
+
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x 
(fence %u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index bfb72143566f6..97fbbb396336c 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -286,11 +286,133 @@ static int intel_guc_steal_guc_ids(void *arg)
return ret;
 }
 
+/*
+ * Send a context schedule H2G message with an invalid context id.
+ * This should generate a GUC_RESULT_INVALID_CONTEXT response.
+ */
+static int bad_h2g(struct intel_guc *guc)
+{
+   u32 action[3], len = 0;
+
+   action[len++] = INTEL_GUC_ACTION_SCHED_CONTEXT;
+   action[len++] = 0x12345678;
+
+   return intel_guc_send_nb(guc, action, len, 0);
+}
+
+/*
+ * Set a spinner running to make sure the system is alive and active,
+ * then send a bad but asynchronous H2G command and wait to see if an
+ * error response is returned. If no response is received or if the
+ * spinner dies then the test will fail.
+ */
+#define FAST_RESPONSE_TIMEOUT_MS   1000
+static int intel_guc_fast_request(void *arg)
+{
+   struct intel_gt *gt = arg;
+   struct intel_context *ce;
+   struct igt_spinner spin;
+   struct i915_request *rq;
+   intel_wakeref_t wakeref;
+   struct intel_engine_cs *engine = intel_selftest_find_any_engine(gt);
+   ktime_t before, now, delta;
+   bool spinning = false;
+   u64 delta_ms;
+   int ret = 0;
+
+   if (!engine)
+   return 0;
+
+   wakeref = intel_runtime_pm_get(gt->uncore->rpm);
+
+   ce = intel_context_create(engine);
+   if (IS_ERR(ce)) {
+   ret = PTR_ERR(ce);
+   gt_err(gt, "Failed to create spinner request: %pe\n", ce);
+   goto err_pm;
+   }
+
+   ret = igt_spinner_init(, engine->gt);
+   if (ret) {
+   gt_err(gt, "Failed to create spinner: %pe\n", ERR_PTR(ret));
+   goto err_pm;
+   }
+   spinning = true;
+
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
+   intel_context_put(ce);
+   if (IS_ERR(rq)) {
+   ret = PTR_ERR(rq);
+   gt_err(gt, "Failed to create spinner request: %pe\n", rq);
+   goto err_spin;
+   }
+
+   ret = request_add_spin(rq, );
+   if (ret) {
+   gt_err(gt, "Failed to add Spinner request: %pe\n", 
ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   gt->uc.guc.fast_response_selftest = 1;
+
+   ret = bad_h2g(>uc.guc);
+   if (ret) {
+   gt_err(gt, "Failed to send H2G: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+
+   before = ktime_get();
+   while (gt->uc.guc.fast_response_selftest == 1) {
+   ret = i915_request_wait(rq, 0, 1);
+   if (ret != -ETIME) {
+   gt_err(gt, "Request wait failed: %pe\n", ERR_PTR(ret));
+   goto err_rq;
+   }
+   now = ktime_get();
+   delta = ktime_sub(now, before);
+   delta_ms = ktime_to_ms(delta);
+

[Intel-gfx] [PATCH 1/2] drm/i915/guc: Fix for potential false positives in GuC hang selftest

2023-11-06 Thread John . C . Harrison
From: John Harrison 

Noticed that the hangcheck selftest is submitting a non-preemptoble
spinner. That means that even if the GuC does not die, the heartbeat
will still kick in and trigger a reset. Which is rather defeating the
purpose of the test - to verify that the heartbeat will kick in if the
GuC itself has died. The test is deliberately killing the GuC, so it
should never hit the case of a non-dead GuC. But it is not impossible
that the kill might fail at some future point due to other driver
re-work.

So, make the spinner pre-emptible. That way the heartbeat can get
through if the GuC is alive and context switching. Thus a reset only
happens if the GuC dies. Thus, if the kill should stop working the
test will now fail rather than claim to pass.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
index 34b5d952e2bcb..26fdc392fce6c 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc_hangcheck.c
@@ -74,7 +74,7 @@ static int intel_hang_guc(void *arg)
goto err;
}
 
-   rq = igt_spinner_create_request(, ce, MI_NOOP);
+   rq = igt_spinner_create_request(, ce, MI_ARB_CHECK);
intel_context_put(ce);
if (IS_ERR(rq)) {
ret = PTR_ERR(rq);
-- 
2.41.0



[Intel-gfx] [PATCH 0/2] Selftest for FAST_REQUEST feature

2023-11-06 Thread John . C . Harrison
From: John Harrison 

Add a selftest to verify that the FAST_REQUEST mechanism (getting
errors back from fire-and-forget H2G commands) is functional.

Also fix up a potential false positive in the GuC hang selftest.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/guc: Fix for potential false positives in GuC hang selftest
  drm/i915/guc: Add a selftest for FAST_REQUEST errors

 drivers/gpu/drm/i915/gt/uc/intel_guc.h|   4 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |   9 ++
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 122 ++
 .../drm/i915/gt/uc/selftest_guc_hangcheck.c   |   2 +-
 4 files changed, 136 insertions(+), 1 deletion(-)

-- 
2.41.0



[Intel-gfx] [PATCH v2 2/4] drm/i915/guc: Add support for w/a KLVs

2023-10-27 Thread John . C . Harrison
From: John Harrison 

To prevent running out of bits, new w/a enable flags are being added
via a KLV system instead of a 32 bit flags word.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 73 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  5 +-
 5 files changed, 85 insertions(+), 2 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 dabeaf4f245f3..00d6402333f8e 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
@@ -36,6 +36,7 @@ enum intel_guc_load_status {
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_KLV_WORKAROUND_INIT_ERROR= 0x75,
INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 2b6dfe62c8f2a..4113776ff3e19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -198,6 +198,8 @@ struct intel_guc {
struct guc_mmio_reg *ads_regset;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
u32 ads_golden_ctxt_size;
+   /** @ads_waklv_size: size of workaround KLVs */
+   u32 ads_waklv_size;
/** @ads_capture_size: size of register lists in the ADS used for error 
capture */
u32 ads_capture_size;
/** @ads_engine_usage_size: size of engine usage in the ADS */
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 63724e17829a7..251e7a7a05cb8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *  +---+
  *  | padding   |
  *  +---+ <== 4K aligned
+ *  | w/a KLVs  |
+ *  +---+
+ *  | padding   |
+ *  +---+ <== 4K aligned
  *  | capture lists |
  *  +---+
  *  | padding   |
@@ -88,6 +92,11 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+   return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
u32 offset;
 
@@ -123,6 +132,16 @@ static u32 guc_ads_capture_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+   u32 offset;
+
+   offset = guc_ads_waklv_offset(guc) +
+guc_ads_waklv_size(guc);
+
+   return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
u32 offset;
@@ -791,6 +810,49 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+static void guc_waklv_init(struct intel_guc *guc)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   u32 offset, addr_ggtt, remain, size;
+
+   if (!intel_uc_uses_guc_submission(>uc))
+   return;
+
+   if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+   return;
+
+   GEM_BUG_ON(iosys_map_is_null(>ads_map));
+   offset = guc_ads_waklv_offset(guc);
+   remain = guc_ads_waklv_size(guc);
+
+   /*
+* Add workarounds here:
+*
+* if (want_wa_) {
+*  size = guc_waklv_(guc, offset, remain);
+*  offset += size;
+*  remain -= size;
+* }
+*/
+
+   size = guc_ads_waklv_size(guc) - remain;
+   if (!size)
+   return;
+
+   offset = guc_ads_waklv_offset(guc);
+   addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+   ads_blob_write(guc, ads.wa_klv_addr_lo, addr_ggtt);
+   ads_blob_write(guc, ads.wa_klv_addr_hi, 0);
+   ads_blob_write(guc, ads.wa_klv_size, size);
+}
+
+static int guc_prep_waklv(struct intel_guc *guc)
+{
+   /* Fudge 

[Intel-gfx] [PATCH v2 4/4] drm/i915/mtl: Add module parameter override for Wa_16019325821/Wa_14019159160

2023-10-27 Thread John . C . Harrison
From: John Harrison 

These w/a's can have signficant performance implications for any
workload which uses both RCS and CCS. On the other hand, the hang
itself is only seen in one or two very specific workloads. So add a
module parameter to control whether the w/a's are enabled or not and
default to not.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 3 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 3 ++-
 drivers/gpu/drm/i915/i915_params.c| 3 +++
 drivers/gpu/drm/i915/i915_params.h| 1 +
 5 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 6252f32d67011..4c89983b1e907 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -296,7 +296,8 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
 
/* Wa_16019325821 */
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   if (gt->i915->params.enable_mtl_rcs_ccs_wa &&
+   IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
/*
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 8f7298cbbc322..78757e78bce88 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -845,7 +845,8 @@ static void guc_waklv_init(struct intel_guc *guc)
remain = guc_ads_waklv_size(guc);
 
/* Wa_14019159160 */
-   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   if (gt->i915->params.enable_mtl_rcs_ccs_wa &&
+   IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
size = guc_waklv_ra_mode(guc, offset, remain);
offset += size;
remain -= size;
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 225812b299524..4de54a100c451 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4384,7 +4384,8 @@ static void guc_default_vfuncs(struct intel_engine_cs 
*engine)
 
/* Wa_16019325821 */
/* Wa_14019159160 */
-   if ((engine->class == COMPUTE_CLASS || engine->class == RENDER_CLASS) &&
+   if (engine->i915->params.enable_mtl_rcs_ccs_wa &&
+   (engine->class == COMPUTE_CLASS || engine->class == RENDER_CLASS) &&
IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 71)))
engine->flags |= I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 
diff --git a/drivers/gpu/drm/i915/i915_params.c 
b/drivers/gpu/drm/i915/i915_params.c
index de43048543e8b..1004171d99943 100644
--- a/drivers/gpu/drm/i915/i915_params.c
+++ b/drivers/gpu/drm/i915/i915_params.c
@@ -134,6 +134,9 @@ i915_param_named_unsafe(lmem_size, uint, 0400,
 i915_param_named_unsafe(lmem_bar_size, uint, 0400,
"Set the lmem bar size(in MiB).");
 
+i915_param_named(enable_mtl_rcs_ccs_wa, bool, 0400,
+   "Enable the RCS/CCS switchout hold workaround for MTL (only some 
workloads are affected by issue and w/a has a performance penalty) 
(default:false)");
+
 static void _param_print_bool(struct drm_printer *p, const char *name,
  bool val)
 {
diff --git a/drivers/gpu/drm/i915/i915_params.h 
b/drivers/gpu/drm/i915/i915_params.h
index 1315d7fac850f..971a765d74f56 100644
--- a/drivers/gpu/drm/i915/i915_params.h
+++ b/drivers/gpu/drm/i915/i915_params.h
@@ -62,6 +62,7 @@ struct drm_printer;
param(unsigned int, lmem_size, 0, 0400) \
param(unsigned int, lmem_bar_size, 0, 0400) \
/* leave bools at the end to not create holes */ \
+   param(bool, enable_mtl_rcs_ccs_wa, false, 0x400) \
param(bool, enable_hangcheck, true, 0600) \
param(bool, error_capture, true, 
IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR) ? 0600 : 0) \
param(bool, enable_gvt, false, IS_ENABLED(CONFIG_DRM_I915_GVT) ? 0400 : 
0)
-- 
2.41.0



[Intel-gfx] [PATCH v2 3/4] drm/i915/guc: Enable Wa_14019159160

2023-10-27 Thread John . C . Harrison
From: John Harrison 

Use the new w/a KLV support to enable a MTL w/a. Note, this w/a is a
super-set of Wa_16019325821, so requires turning that one as well as
setting the new flag for Wa_14019159160 itself.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  3 ++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 34 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  1 +
 6 files changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 9cccd60a5c41d..359b21fb02ab2 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -744,6 +744,7 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request 
*rq, u32 *cs)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 #define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
 static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
@@ -753,6 +754,7 @@ static u32 hold_switchout_semaphore_offset(struct 
i915_request *rq)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
@@ -793,6 +795,7 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
 
/* Wa_14014475959:dg2 */
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (intel_engine_uses_wa_hold_switchout(rq->engine))
cs = hold_switchout_emit_wa_busywait(rq, cs);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index f08739d020332..3b4993955a4b6 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -695,6 +695,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs 
* const engine)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
 intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
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 58012edd4eb0e..bebf28e3c4794 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
@@ -101,4 +101,11 @@ enum {
GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+};
+
 #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 0e6c160de3315..6252f32d67011 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -295,6 +295,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
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 251e7a7a05cb8..8f7298cbbc322 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -810,6 +810,25 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+   u32 size;
+   u32 klv_entry[] = {
+   /* 16:16 key/length */
+   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_LEN, 0),
+   /* 0 dwords data */
+   };
+
+   size = sizeof(klv_entry);
+   GEM_BUG_ON(remain < size);
+
+   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+
+   return size;
+}
+
 static void guc_waklv_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -825,15 +844,12 @@ static void guc_waklv_init(struct intel_guc *guc)
offset = guc_ads_waklv_offset(guc);
remain = guc_ads_waklv_size(guc);
 
-   /*
-* Add workarounds here:
-*
-* if (want_wa_) {
-*  size = guc_waklv_(guc, offset, remain);
-*  offset += size;
-*  remain -= size;
-* }
-*/
+   /* Wa_14019159160 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   size = guc_waklv_ra_mode(guc, offset, remain);
+   offset += size;
+   remain -= size;
+   }
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
diff --git 

[Intel-gfx] [PATCH v2 1/4] drm/i915: Enable Wa_16019325821

2023-10-27 Thread John . C . Harrison
From: John Harrison 

Some platforms require holding RCS context switches until CCS is idle
(the reverse w/a of Wa_14014475959). Some platforms require both
versions.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 19 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  7 ++-
 5 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 86a04afff64b3..9cccd60a5c41d 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -743,21 +743,23 @@ static u32 *gen12_emit_preempt_busywait(struct 
i915_request *rq, u32 *cs)
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
return i915_ggtt_offset(rq->context->state) +
-   (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+   (LRC_PPHWSP_PN * PAGE_SIZE) + 
HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
 
*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
MI_ATOMIC_MOVE;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
*cs++ = 1;
 
@@ -773,7 +775,7 @@ static u32 *ccs_emit_wa_busywait(struct i915_request *rq, 
u32 *cs)
MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_EQ_SDD;
*cs++ = 0;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
 
return cs;
@@ -790,8 +792,9 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
cs = gen12_emit_preempt_busywait(rq, cs);
 
/* Wa_14014475959:dg2 */
-   if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-   cs = ccs_emit_wa_busywait(rq, cs);
+   /* Wa_16019325821 */
+   if (intel_engine_uses_wa_hold_switchout(rq->engine))
+   cs = hold_switchout_emit_wa_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
assert_ring_tail_valid(rq->ring, rq->tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 8769760257fd9..f08739d020332 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -584,7 +584,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
unsigned int flags;
 
/*
@@ -694,10 +694,11 @@ intel_engine_has_relative_mmio(const struct 
intel_engine_cs * const engine)
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-   return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+   return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 3f3df1166b860..0e6c160de3315 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+   /* Wa_16019325821 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
/*
 * Wa_14012197797
 * Wa_22011391025
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 8ae1846431da7..48863188a130e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -96,8 +96,9 @@
 #define   GUC_WA_GAM_CREDITS   BIT(10)
 #define   GUC_WA_DUAL_QUEUEBIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6  BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
 #define   GUC_WA_PRE_PARSERBIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
+#define   GUC_WA_RCS_CCS_SWITCHOUT 

[Intel-gfx] [PATCH v2 0/4] Enable Wa_14019159160 and Wa_16019325821 for MTL

2023-10-27 Thread John . C . Harrison
From: John Harrison 

Enable Wa_14019159160 and  Wa_16019325821 for MTL

RCS/CCS workarounds for MTL.

v2: Fix bug in WA KLV implementation (offset not being reset to start
of list). Add better comment to prep patch about how KLVs can be added.
Add a module parameter override and disable the w/a by default as it
causes performance regressions and is only required by very specific
workloads.

Signed-off-by: John Harrison 


John Harrison (4):
  drm/i915: Enable Wa_16019325821
  drm/i915/guc: Add support for w/a KLVs
  drm/i915/guc: Enable Wa_14019159160
  drm/i915/mtl: Add module parameter override for
Wa_16019325821/Wa_14019159160

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 22 +++--
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  8 +-
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  2 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 90 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  9 +-
 drivers/gpu/drm/i915/i915_params.c|  3 +
 drivers/gpu/drm/i915/i915_params.h|  1 +
 12 files changed, 148 insertions(+), 15 deletions(-)

-- 
2.41.0



[Intel-gfx] PR for new GuC v70.13.1

2023-10-18 Thread John . C . Harrison
The following changes since commit 7727f7e3b3358713c7c91c64a835e80c331a6b8b:

  Merge branch 'patch-1696561325' into 'main' (2023-10-06 03:04:57 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.13.1

for you to fetch changes up to 44a9510c94ac0334931b6c89dd240ffe5bf1e5fa:

  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL (2023-10-13 11:34:26 -0700)


John Harrison (1):
  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL

 WHENCE   |   8 
 i915/adlp_guc_70.bin | Bin 297984 -> 342848 bytes
 i915/dg2_guc_70.bin  | Bin 385856 -> 443200 bytes
 i915/mtl_guc_70.bin  | Bin 308032 -> 365376 bytes
 i915/tgl_guc_70.bin  | Bin 285888 -> 330304 bytes
 5 files changed, 4 insertions(+), 4 deletions(-)


[Intel-gfx] [CI] PR for new GuC v70.13.1

2023-10-18 Thread John . C . Harrison
The following changes since commit 7727f7e3b3358713c7c91c64a835e80c331a6b8b:

  Merge branch 'patch-1696561325' into 'main' (2023-10-06 03:04:57 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.13.1

for you to fetch changes up to 44a9510c94ac0334931b6c89dd240ffe5bf1e5fa:

  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL (2023-10-13 11:34:26 -0700)


John Harrison (1):
  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL

 WHENCE   |   8 
 i915/adlp_guc_70.bin | Bin 297984 -> 342848 bytes
 i915/dg2_guc_70.bin  | Bin 385856 -> 443200 bytes
 i915/mtl_guc_70.bin  | Bin 308032 -> 365376 bytes
 i915/tgl_guc_70.bin  | Bin 285888 -> 330304 bytes
 5 files changed, 4 insertions(+), 4 deletions(-)


[Intel-gfx] [CI] PR for new GuC v70.13.1

2023-10-13 Thread John . C . Harrison
The following changes since commit 7727f7e3b3358713c7c91c64a835e80c331a6b8b:

  Merge branch 'patch-1696561325' into 'main' (2023-10-06 03:04:57 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.13.1

for you to fetch changes up to 44a9510c94ac0334931b6c89dd240ffe5bf1e5fa:

  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL (2023-10-13 11:34:26 -0700)


John Harrison (1):
  i915: Add GuC v70.13.1 for DG2, TGL, ADL-P and MTL

 WHENCE   |   8 
 i915/adlp_guc_70.bin | Bin 297984 -> 342848 bytes
 i915/dg2_guc_70.bin  | Bin 385856 -> 443200 bytes
 i915/mtl_guc_70.bin  | Bin 308032 -> 365376 bytes
 i915/tgl_guc_70.bin  | Bin 285888 -> 330304 bytes
 5 files changed, 4 insertions(+), 4 deletions(-)


[Intel-gfx] [PATCH 2/2] drm/i915: More use of GT specific print helpers

2023-10-09 Thread John . C . Harrison
From: John Harrison 

Update a bunch of GT related print messages in non-GT files to use the
GT specific helpers.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c | 8 +++-
 drivers/gpu/drm/i915/i915_driver.c| 3 ++-
 drivers/gpu/drm/i915/i915_perf.c  | 8 
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
index 0d3b22a743659..453d855dd1de7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c
@@ -68,8 +68,7 @@ static void gsc_work(struct work_struct *work)
 * A proxy failure right after firmware load 
means the proxy-init
 * step has failed so mark GSC as not usable 
after this
 */
-   drm_err(>i915->drm,
-   "GSC proxy handler failed to init\n");
+   gt_err(gt, "GSC proxy handler failed to 
init\n");
intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_LOAD_FAIL);
}
goto out_put;
@@ -83,11 +82,10 @@ static void gsc_work(struct work_struct *work)
 * status register to check if the proxy init was 
actually successful
 */
if (intel_gsc_uc_fw_proxy_init_done(gsc, false)) {
-   drm_dbg(>i915->drm, "GSC Proxy 
initialized\n");
+   gt_dbg(gt, "GSC Proxy initialized\n");
intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_RUNNING);
} else {
-   drm_err(>i915->drm,
-   "GSC status reports proxy init not 
complete\n");
+   gt_err(gt, "GSC status reports proxy init not 
complete\n");
intel_uc_fw_change_status(>fw, 
INTEL_UC_FIRMWARE_LOAD_FAIL);
}
}
diff --git a/drivers/gpu/drm/i915/i915_driver.c 
b/drivers/gpu/drm/i915/i915_driver.c
index e5a94b08d5efe..944ab895da72e 100644
--- a/drivers/gpu/drm/i915/i915_driver.c
+++ b/drivers/gpu/drm/i915/i915_driver.c
@@ -71,6 +71,7 @@
 #include "gem/i915_gem_pm.h"
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_pm.h"
+#include "gt/intel_gt_print.h"
 #include "gt/intel_rc6.h"
 
 #include "pxp/intel_pxp.h"
@@ -429,7 +430,7 @@ static int i915_pcode_init(struct drm_i915_private *i915)
for_each_gt(gt, i915, id) {
ret = intel_pcode_init(gt->uncore);
if (ret) {
-   drm_err(>i915->drm, "gt%d: intel_pcode_init failed 
%d\n", id, ret);
+   gt_err(gt, "intel_pcode_init failed %d\n", ret);
return ret;
}
}
diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c
index 1347e4ec9dd5a..8f7ab64feec0d 100644
--- a/drivers/gpu/drm/i915/i915_perf.c
+++ b/drivers/gpu/drm/i915/i915_perf.c
@@ -206,6 +206,7 @@
 #include "gt/intel_gt.h"
 #include "gt/intel_gt_clock_utils.h"
 #include "gt/intel_gt_mcr.h"
+#include "gt/intel_gt_print.h"
 #include "gt/intel_gt_regs.h"
 #include "gt/intel_lrc.h"
 #include "gt/intel_lrc_reg.h"
@@ -1659,9 +1660,8 @@ static void i915_oa_stream_destroy(struct 
i915_perf_stream *stream)
free_noa_wait(stream);
 
if (perf->spurious_report_rs.missed) {
-   drm_notice(>i915->drm,
-  "%d spurious OA report notices suppressed due to 
ratelimiting\n",
-  perf->spurious_report_rs.missed);
+   gt_notice(gt, "%d spurious OA report notices suppressed due to 
ratelimiting\n",
+ perf->spurious_report_rs.missed);
}
 }
 
@@ -1852,7 +1852,7 @@ static int alloc_oa_buffer(struct i915_perf_stream 
*stream)
 */
ret = i915_vma_pin(vma, 0, SZ_16M, PIN_GLOBAL | PIN_HIGH);
if (ret) {
-   drm_err(>i915->drm, "Failed to pin OA buffer %d\n", ret);
+   gt_err(gt, "Failed to pin OA buffer %d\n", ret);
goto err_unref;
}
 
-- 
2.41.0



[Intel-gfx] [PATCH 1/2] drm/i915/gt: More use of GT specific print helpers

2023-10-09 Thread John . C . Harrison
From: John Harrison 

A bunch of print messages got missed in the update to using sub-system
specific helpers. So update those.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 29 +
 drivers/gpu/drm/i915/gt/intel_gsc.c | 11 
 drivers/gpu/drm/i915/gt/intel_gt_print.h|  3 +++
 drivers/gpu/drm/i915/gt/intel_reset.c   | 26 --
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 13 -
 5 files changed, 39 insertions(+), 43 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index b1a1d07e2e217..179d9546865b0 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -316,10 +316,9 @@ u32 intel_engine_context_size(struct intel_gt *gt, u8 
class)
 * out in the wash.
 */
cxt_size = intel_uncore_read(uncore, CXT_SIZE) + 1;
-   drm_dbg(>i915->drm,
-   "graphics_ver = %d CXT_SIZE = %d bytes 
[0x%08x]\n",
-   GRAPHICS_VER(gt->i915), cxt_size * 64,
-   cxt_size - 1);
+   gt_dbg(gt, "graphics_ver = %d CXT_SIZE = %d bytes 
[0x%08x]\n",
+  GRAPHICS_VER(gt->i915), cxt_size * 64,
+  cxt_size - 1);
return round_up(cxt_size * 64, PAGE_SIZE);
case 3:
case 2:
@@ -788,7 +787,7 @@ static void engine_mask_apply_media_fuses(struct intel_gt 
*gt)
 
if (!(BIT(i) & vdbox_mask)) {
gt->info.engine_mask &= ~BIT(_VCS(i));
-   drm_dbg(>drm, "vcs%u fused off\n", i);
+   gt_dbg(gt, "vcs%u fused off\n", i);
continue;
}
 
@@ -796,8 +795,7 @@ static void engine_mask_apply_media_fuses(struct intel_gt 
*gt)
gt->info.vdbox_sfc_access |= BIT(i);
logical_vdbox++;
}
-   drm_dbg(>drm, "vdbox enable: %04x, instances: %04lx\n",
-   vdbox_mask, VDBOX_MASK(gt));
+   gt_dbg(gt, "vdbox enable: %04x, instances: %04lx\n", vdbox_mask, 
VDBOX_MASK(gt));
GEM_BUG_ON(vdbox_mask != VDBOX_MASK(gt));
 
for (i = 0; i < I915_MAX_VECS; i++) {
@@ -808,11 +806,10 @@ static void engine_mask_apply_media_fuses(struct intel_gt 
*gt)
 
if (!(BIT(i) & vebox_mask)) {
gt->info.engine_mask &= ~BIT(_VECS(i));
-   drm_dbg(>drm, "vecs%u fused off\n", i);
+   gt_dbg(gt, "vecs%u fused off\n", i);
}
}
-   drm_dbg(>drm, "vebox enable: %04x, instances: %04lx\n",
-   vebox_mask, VEBOX_MASK(gt));
+   gt_dbg(gt, "vebox enable: %04x, instances: %04lx\n", vebox_mask, 
VEBOX_MASK(gt));
GEM_BUG_ON(vebox_mask != VEBOX_MASK(gt));
 }
 
@@ -838,7 +835,7 @@ static void engine_mask_apply_compute_fuses(struct intel_gt 
*gt)
 */
for_each_clear_bit(i, _mask, I915_MAX_CCS) {
info->engine_mask &= ~BIT(_CCS(i));
-   drm_dbg(>drm, "ccs%u fused off\n", i);
+   gt_dbg(gt, "ccs%u fused off\n", i);
}
 }
 
@@ -866,8 +863,8 @@ static void engine_mask_apply_copy_fuses(struct intel_gt 
*gt)
   _BCS(instance));
 
if (mask & info->engine_mask) {
-   drm_dbg(>drm, "bcs%u fused off\n", instance);
-   drm_dbg(>drm, "bcs%u fused off\n", instance + 1);
+   gt_dbg(gt, "bcs%u fused off\n", instance);
+   gt_dbg(gt, "bcs%u fused off\n", instance + 1);
 
info->engine_mask &= ~mask;
}
@@ -907,8 +904,7 @@ static intel_engine_mask_t init_engine_mask(struct intel_gt 
*gt)
 *submission, which will wake up the GSC power well.
 */
if (__HAS_ENGINE(info->engine_mask, GSC0) && 
!intel_uc_wants_gsc_uc(>uc)) {
-   drm_notice(>i915->drm,
-  "No GSC FW selected, disabling GSC CS and media 
C6\n");
+   gt_notice(gt, "No GSC FW selected, disabling GSC CS and media 
C6\n");
info->engine_mask &= ~BIT(GSC0);
}
 
@@ -1097,8 +1093,7 @@ static int init_status_page(struct intel_engine_cs 
*engine)
 */
obj = i915_gem_object_create_internal(engine->i915, PAGE_SIZE);
if (IS_ERR(obj)) {
-   drm_err(>i915->drm,
-   "Failed to allocate status page\n");
+   gt_err(engine->gt, "Failed to allocate status page\n");
return PTR_ERR(obj);
}
 
diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c 
b/drivers/gpu/drm/i915/gt/intel_gsc.c
index bcc3605158dbd..6d440de8ba017 100644
--- 

[Intel-gfx] [PATCH 0/2] More print message helper updates

2023-10-09 Thread John . C . Harrison
From: John Harrison 

There was an update a while back to use sub-system specific print
helpers that implicitly add sub-system specific information to the
print. It seems a bunch of GT related messages got missed in that
update. So update them now.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/gt: More use of GT specific print helpers
  drm/i915: More use of GT specific print helpers

 drivers/gpu/drm/i915/gt/intel_engine_cs.c   | 29 +
 drivers/gpu/drm/i915/gt/intel_gsc.c | 11 
 drivers/gpu/drm/i915/gt/intel_gt_print.h|  3 +++
 drivers/gpu/drm/i915/gt/intel_reset.c   | 26 --
 drivers/gpu/drm/i915/gt/intel_workarounds.c | 13 -
 drivers/gpu/drm/i915/gt/uc/intel_gsc_uc.c   |  8 +++---
 drivers/gpu/drm/i915/i915_driver.c  |  3 ++-
 drivers/gpu/drm/i915/i915_perf.c|  8 +++---
 8 files changed, 48 insertions(+), 53 deletions(-)

-- 
2.41.0



[Intel-gfx] [PATCH] drm/i915/guc: Update 'recommended' version to 70.12.1 for DG2/ADL-S/ADL-P/MTL

2023-10-06 Thread John . C . Harrison
From: John Harrison 

The latest GuC has new features and new workarounds that we wish to
enable. So let the universe know that it is useful to update their
firmware.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 8 
 1 file changed, 4 insertions(+), 4 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 32e27e9a2490f..362639162ed60 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -88,12 +88,12 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * security fixes, etc. to be enabled.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
-   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 6, 6)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
+   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 12, 1)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 12, 1)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 12, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 12, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
fw_def(DG1,  0, guc_maj(dg1,  70, 5, 1)) \
-- 
2.41.0



[Intel-gfx] [CI] PR for new GuC v70.12.1

2023-10-06 Thread John . C . Harrison
The following changes since commit 5105ff4b9f43ba08d0a22260d670120e53c4b667:

  Merge branch 'mlimonci/upstream-packaging' into 'main' (2023-10-04 12:35:17 
+)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.12.1

for you to fetch changes up to 22fb3576f39769162c5da556159b72745b8570a8:

  i915: Add GuC v70.12.1 for DG2, TGL, ADL-P and MTL (2023-10-06 01:52:14 -0700)


John Harrison (1):
  i915: Add GuC v70.12.1 for DG2, TGL, ADL-P and MTL

 WHENCE   |   8 
 i915/adlp_guc_70.bin | Bin 297984 -> 342528 bytes
 i915/dg2_guc_70.bin  | Bin 385856 -> 443200 bytes
 i915/mtl_guc_70.bin  | Bin 308032 -> 365376 bytes
 i915/tgl_guc_70.bin  | Bin 285888 -> 329984 bytes
 5 files changed, 4 insertions(+), 4 deletions(-)


[Intel-gfx] [PATCH] drm/i915/guc: Enable WA 14018913170

2023-10-05 Thread John . C . Harrison
From: Daniele Ceraolo Spurio 

The GuC handles the WA, the KMD just needs to set the flag to enable
it on the appropriate platforms.

Signed-off-by: John Harrison 
Signed-off-by: Daniele Ceraolo Spurio 
Reviewed-by: Vinay Belgaumkar 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c  | 6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h  | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 1 +
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 27df41c53b890..3f3df1166b860 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -319,6 +319,12 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
if (!RCS_MASK(gt))
flags |= GUC_WA_RCS_REGS_IN_CCS_REGS_LIST;
 
+   /* Wa_14018913170 */
+   if (GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 7, 0)) {
+   if (IS_DG2(gt->i915) || IS_METEORLAKE(gt->i915) || 
IS_PONTEVECCHIO(gt->i915))
+   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
+   }
+
return flags;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 6c392bad29c19..818c8c146fd47 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -295,6 +295,7 @@ struct intel_guc {
 #define MAKE_GUC_VER(maj, min, pat)(((maj) << 16) | ((min) << 8) | (pat))
 #define MAKE_GUC_VER_STRUCT(ver)   MAKE_GUC_VER((ver).major, (ver).minor, 
(ver).patch)
 #define GUC_SUBMIT_VER(guc)
MAKE_GUC_VER_STRUCT((guc)->submission_version)
+#define GUC_FIRMWARE_VER(guc)  
MAKE_GUC_VER_STRUCT((guc)->fw.file_selected.ver)
 
 static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
 {
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 b4d56eccfb1f0..123ad75d2eb28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -100,6 +100,7 @@
 #define   GUC_WA_HOLD_CCS_SWITCHOUTBIT(17)
 #define   GUC_WA_POLLCSBIT(18)
 #define   GUC_WA_RCS_REGS_IN_CCS_REGS_LIST BIT(21)
+#define   GUC_WA_ENABLE_TSC_CHECK_ON_RC6   BIT(22)
 
 #define GUC_CTL_FEATURE2
 #define   GUC_CTL_ENABLE_SLPC  BIT(2)
-- 
2.41.0



[Intel-gfx] [PATCH 3/3] drm/i915/mtl: Add counters for engine busyness ticks

2023-09-22 Thread John . C . Harrison
From: Umesh Nerlige Ramappa 

In new version of GuC engine busyness, GuC provides engine busyness
ticks as a 64 bit counter. Add a new counter to relay this value to the
user as is.

Signed-off-by: Umesh Nerlige Ramappa 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_engine.h|  1 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c | 16 +
 drivers/gpu/drm/i915/gt/intel_engine_types.h  | 12 
 drivers/gpu/drm/i915/gt/intel_engine_user.c   |  1 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 67 ++-
 drivers/gpu/drm/i915/i915_pmu.c   | 25 ++-
 drivers/gpu/drm/i915/i915_pmu.h   |  2 +-
 include/uapi/drm/i915_drm.h   | 13 +++-
 8 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h 
b/drivers/gpu/drm/i915/gt/intel_engine.h
index b58c30ac8ef02..57af7ec8ecd82 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine.h
@@ -249,6 +249,7 @@ void intel_engine_dump_active_requests(struct list_head 
*requests,
 
 ktime_t intel_engine_get_busy_time(struct intel_engine_cs *engine,
   ktime_t *now);
+u64 intel_engine_get_busy_ticks(struct intel_engine_cs *engine);
 
 void intel_engine_get_hung_entity(struct intel_engine_cs *engine,
  struct intel_context **ce, struct 
i915_request **rq);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c 
b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
index 84a75c95f3f7d..1c9ffb1ae9889 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c
@@ -2426,6 +2426,22 @@ ktime_t intel_engine_get_busy_time(struct 
intel_engine_cs *engine, ktime_t *now)
return engine->busyness(engine, now);
 }
 
+/**
+ * intel_engine_get_busy_ticks() - Return current accumulated engine busyness
+ * ticks
+ * @engine: engine to report on
+ *
+ * Returns accumulated ticks @engine was busy since engine stats were enabled.
+ */
+u64 intel_engine_get_busy_ticks(struct intel_engine_cs *engine)
+{
+   if (!engine->busyness_ticks ||
+   !(engine->flags & I915_ENGINE_SUPPORTS_TICKS_STATS))
+   return 0;
+
+   return engine->busyness_ticks(engine);
+}
+
 struct intel_context *
 intel_engine_create_virtual(struct intel_engine_cs **siblings,
unsigned int count, unsigned long flags)
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 40fd8f984d64b..a88d40c74d604 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -548,6 +548,11 @@ struct intel_engine_cs {
ktime_t (*busyness)(struct intel_engine_cs *engine,
ktime_t *now);
 
+   /*
+* Get engine busyness ticks
+*/
+   u64 (*busyness_ticks)(struct intel_engine_cs *engine);
+
struct intel_engine_execlists execlists;
 
/*
@@ -574,6 +579,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
 #define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_SUPPORTS_TICKS_STATS   BIT(13)
unsigned int flags;
 
/*
@@ -649,6 +655,12 @@ intel_engine_supports_stats(const struct intel_engine_cs 
*engine)
return engine->flags & I915_ENGINE_SUPPORTS_STATS;
 }
 
+static inline bool
+intel_engine_supports_tick_stats(const struct intel_engine_cs *engine)
+{
+   return engine->flags & I915_ENGINE_SUPPORTS_TICKS_STATS;
+}
+
 static inline bool
 intel_engine_has_preemption(const struct intel_engine_cs *engine)
 {
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_user.c 
b/drivers/gpu/drm/i915/gt/intel_engine_user.c
index dcedff41a825f..69eb610b5ab0a 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_user.c
+++ b/drivers/gpu/drm/i915/gt/intel_engine_user.c
@@ -100,6 +100,7 @@ static void set_scheduler_caps(struct drm_i915_private 
*i915)
MAP(HAS_PREEMPTION, PREEMPTION),
MAP(HAS_SEMAPHORES, SEMAPHORES),
MAP(SUPPORTS_STATS, ENGINE_BUSY_STATS),
+   MAP(SUPPORTS_TICKS_STATS, ENGINE_BUSY_TICKS_STATS),
 #undef MAP
};
struct intel_engine_cs *engine;
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 0c1fee5360777..71749fb9ad35b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1289,12 +1289,7 @@ static void busy_v1_guc_update_pm_timestamp(struct 
intel_guc *guc, ktime_t *now)
guc->busy.v1.gt_stamp = ((u64)gt_stamp_hi << 32) | gt_stamp_lo;
 }
 
-/*
- * Unlike the execlist mode of submission total and active times are in terms 
of
- * gt clocks. The *now parameter is retained to return the cpu time at which 

[Intel-gfx] [PATCH 1/3] drm/i915/guc: Support new and improved engine busyness

2023-09-22 Thread John . C . Harrison
From: John Harrison 

The GuC has been extended to support a much more friendly engine
busyness interface. So partition the old interface into a 'busy_v1'
space and add 'busy_v2' support alongside. And if v2 is available, use
that in preference to v1. Note that v2 provides extra features over
and above v1 which will be exposed via PMU in subsequent patches.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |   4 +-
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  82 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  55 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h|   9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  23 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 381 ++
 7 files changed, 427 insertions(+), 131 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index a7e6775980043..40fd8f984d64b 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -323,7 +323,7 @@ struct intel_engine_execlists_stats {
ktime_t start;
 };
 
-struct intel_engine_guc_stats {
+struct intel_engine_guc_stats_v1 {
/**
 * @running: Active state of the engine when busyness was last sampled.
 */
@@ -603,7 +603,7 @@ struct intel_engine_cs {
struct {
union {
struct intel_engine_execlists_stats execlists;
-   struct intel_engine_guc_stats guc;
+   struct intel_engine_guc_stats_v1 guc_v1;
};
 
/**
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 f359bef046e0b..c190a99a36c38 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
@@ -137,7 +137,9 @@ enum intel_guc_action {
INTEL_GUC_ACTION_DEREGISTER_CONTEXT_DONE = 0x4600,
INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC = 0x4601,
INTEL_GUC_ACTION_CLIENT_SOFT_RESET = 0x5507,
-   INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF = 0x550A,
+   INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF_V1 = 0x550A,
+   INTEL_GUC_ACTION_SET_DEVICE_ENGINE_UTILIZATION_V2 = 0x550C,
+   INTEL_GUC_ACTION_SET_FUNCTION_ENGINE_UTILIZATION_V2 = 0x550D,
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,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 6c392bad29c19..e6502ab5f049f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -226,45 +226,61 @@ struct intel_guc {
struct mutex send_mutex;
 
/**
-* @timestamp: GT timestamp object that stores a copy of the timestamp
-* and adjusts it for overflow using a worker.
+* @busy: Data used by the different versions of engine busyness 
implementations.
 */
-   struct {
-   /**
-* @lock: Lock protecting the below fields and the engine stats.
-*/
-   spinlock_t lock;
-
-   /**
-* @gt_stamp: 64 bit extended value of the GT timestamp.
-*/
-   u64 gt_stamp;
-
-   /**
-* @ping_delay: Period for polling the GT timestamp for
-* overflow.
-*/
-   unsigned long ping_delay;
-
-   /**
-* @work: Periodic work to adjust GT timestamp, engine and
-* context usage for overflows.
-*/
-   struct delayed_work work;
-
+   union {
/**
-* @shift: Right shift value for the gpm timestamp
+* @v1: Data used by v1 engine busyness implementation. Mostly 
a copy
+* of the GT timestamp extended to 64 bits and the worker for 
maintaining it.
 */
-   u32 shift;
+   struct {
+   /**
+* @lock: Lock protecting the below fields and the 
engine stats.
+*/
+   spinlock_t lock;
+
+   /**
+* @gt_stamp: 64 bit extended value of the GT timestamp.
+*/
+   u64 gt_stamp;
+
+   /**
+* @ping_delay: Period for polling the GT timestamp for
+* overflow.
+*/
+   unsigned long ping_delay;
+
+   /**
+* @work: Periodic work to adjust GT timestamp, engine 
and
+* context usage for overflows.
+

[Intel-gfx] [PATCH 0/3] Engine busyness v2

2023-09-22 Thread John . C . Harrison
From: John Harrison 

The latest GuC implements a new and improved scheme for tracking
engine busyness. So make use of it.

Note that this change comes along with a new set of PMU counters. The
old counters have a fundamental problem that they are defined in terms
of wall time but the sampling is now all done by the GPU in terms of
clock ticks. This leads to issues with timebase conversion, some of
which are non-trivial.

For existing platforms, the old counters will still be updated by the
new scheme and will still suffer all the same issues. For newer
platforms (MTL onwards), the old counters are no longer supported.

Instead, there is a new set of tick based counters. These include the
actual busyness count per engine plus a total ticks count. The
intention is that they should be queried as an atomic pair and used
together to determine a busyness percentage. No assumptions may be made
about tick frequencies or relations to wall time.

Test-with: 20230922215233.2438200-1-umesh.nerlige.rama...@intel.com
Signed-off-by: John Harrison 


John Harrison (1):
  drm/i915/guc: Support new and improved engine busyness

Umesh Nerlige Ramappa (2):
  drm/i915/mtl: Add a PMU counter for total active ticks
  drm/i915/mtl: Add counters for engine busyness ticks

 drivers/gpu/drm/i915/gt/intel_engine.h|   1 +
 drivers/gpu/drm/i915/gt/intel_engine_cs.c |  16 +
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  16 +-
 drivers/gpu/drm/i915/gt/intel_engine_user.c   |   1 +
 .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   4 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  82 ++--
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c|  55 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.h|   9 +-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  23 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 460 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |   1 +
 drivers/gpu/drm/i915/i915_pmu.c   |  31 +-
 drivers/gpu/drm/i915/i915_pmu.h   |   2 +-
 include/uapi/drm/i915_drm.h   |  15 +-
 14 files changed, 570 insertions(+), 146 deletions(-)

-- 
2.41.0



[Intel-gfx] [PATCH 2/3] drm/i915/mtl: Add a PMU counter for total active ticks

2023-09-22 Thread John . C . Harrison
From: Umesh Nerlige Ramappa 

Current engine busyness interface exposed by GuC has a few issues:

- The busyness of active engine is calculated using 2 values provided by
  GuC and is prone to race between CPU reading those values and GuC
  updating them. Any sort of HW synchronization would be at the cost of
  scheduling latencies.

- GuC provides only 32 bit values for busyness and KMD has to run a
  worker to extend the values to 64 bit. In addition KMD also needs to
  extend the GT timestamp to 64 bits so that it can be used to calculate
  active busyness for an engine.

To address these issues, GuC provides a new interface to calculate
engine busyness. GuC accumulates the busyness ticks in a 64 bit value
and also internally updates the busyness for an active context using a
periodic timer. This simplifies the KMD implementation such that KMD
only needs to relay the busyness value to the user.

In addition to fixing the interface, GuC also provides a periodically
total active ticks that the GT has been running for. This counter is
exposed to the user so that the % busyness can be calculated as follows:

busyness % = (engine active ticks/total active ticks) * 100.

Implement the new interface and start by adding a new counter for total
active ticks.

Signed-off-by: Umesh Nerlige Ramappa 
Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 24 +++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.h |  1 +
 drivers/gpu/drm/i915/i915_pmu.c   |  6 +
 include/uapi/drm/i915_drm.h   |  2 ++
 4 files changed, 33 insertions(+)

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 88465d701c278..0c1fee5360777 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1607,6 +1607,30 @@ static ktime_t busy_v2_guc_engine_busyness(struct 
intel_engine_cs *engine, ktime
return ns_to_ktime(total);
 }
 
+static u64 busy_v1_intel_guc_total_active_ticks(struct intel_guc *guc)
+{
+   return guc->busy.v1.gt_stamp;
+}
+
+static u64 busy_v2_intel_guc_total_active_ticks(struct intel_guc *guc)
+{
+   u64 ticks_gt;
+
+   __busy_v2_get_engine_usage_record(guc, NULL, NULL, NULL, _gt);
+
+   return ticks_gt;
+}
+
+u64 intel_guc_total_active_ticks(struct intel_gt *gt)
+{
+   struct intel_guc *guc = >uc.guc;
+
+   if (GUC_SUBMIT_VER(guc) < MAKE_GUC_VER(1, 3, 1))
+   return busy_v1_intel_guc_total_active_ticks(guc);
+   else
+   return busy_v2_intel_guc_total_active_ticks(guc);
+}
+
 static int busy_v2_guc_action_enable_usage_stats_device(struct intel_guc *guc)
 {
u32 offset = guc_engine_usage_offset_v2_device(guc);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
index c57b29cdb1a64..f6d42838825f2 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.h
@@ -30,6 +30,7 @@ void intel_guc_dump_active_requests(struct intel_engine_cs 
*engine,
struct drm_printer *m);
 void intel_guc_busyness_park(struct intel_gt *gt);
 void intel_guc_busyness_unpark(struct intel_gt *gt);
+u64 intel_guc_total_active_ticks(struct intel_gt *gt);
 
 bool intel_guc_virtual_engine_has_heartbeat(const struct intel_engine_cs *ve);
 
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c
index d35973b411863..4f52636eb4a80 100644
--- a/drivers/gpu/drm/i915/i915_pmu.c
+++ b/drivers/gpu/drm/i915/i915_pmu.c
@@ -563,6 +563,8 @@ config_status(struct drm_i915_private *i915, u64 config)
break;
case I915_PMU_SOFTWARE_GT_AWAKE_TIME:
break;
+   case I915_PMU_TOTAL_ACTIVE_TICKS:
+   break;
default:
return -ENOENT;
}
@@ -678,6 +680,9 @@ static u64 __i915_pmu_event_read(struct perf_event *event)
case I915_PMU_SOFTWARE_GT_AWAKE_TIME:
val = ktime_to_ns(intel_gt_get_awake_time(to_gt(i915)));
break;
+   case I915_PMU_TOTAL_ACTIVE_TICKS:
+   val = intel_guc_total_active_ticks(i915->gt[gt_id]);
+   break;
}
}
 
@@ -986,6 +991,7 @@ create_event_attributes(struct i915_pmu *pmu)
__global_event(2, "interrupts", NULL),
__event(3, "rc6-residency", "ns"),
__event(4, "software-gt-awake-time", "ns"),
+   __event(5, "total-active-ticks", NULL),
};
static const struct {
enum drm_i915_pmu_engine_sample sample;
diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h
index 7000e5910a1d7..e26dd27ff4a5f 100644
--- a/include/uapi/drm/i915_drm.h
+++ b/include/uapi/drm/i915_drm.h
@@ -296,6 +296,7 @@ enum 

[Intel-gfx] [PATCH] drm/i915/guc: Suppress 'ignoring reset notification' message

2023-09-21 Thread John . C . Harrison
From: John Harrison 

If an active context has been banned (e.g. Ctrl+C killed) then it is
likely to be reset as part of evicting it from the hardware. That
results in a 'ignoring context reset notification: banned = 1'
message at info level. This confuses/concerns people and makes them
thing something has gone wrong when it hasn't.

There is already a debug level message with essentially the same
information. So drop the 'ignore' info level one and just add the
'ignore' flag to the debug level one instead (which will therefore not
appear by default but will still show up in CI runs).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

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 cabdc645fcddb..da7331346df1f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4770,19 +4770,19 @@ static void guc_context_replay(struct intel_context *ce)
 static void guc_handle_context_reset(struct intel_guc *guc,
 struct intel_context *ce)
 {
+   bool capture = intel_context_is_schedulable(ce);
+
trace_intel_context_reset(ce);
 
-   guc_dbg(guc, "Got context reset notification: 0x%04X on %s, exiting = 
%s, banned = %s\n",
+   guc_dbg(guc, "%s context reset notification: 0x%04X on %s, exiting = 
%s, banned = %s\n",
+   capture ? "Got" : "Ignoring",
ce->guc_id.id, ce->engine->name,
str_yes_no(intel_context_is_exiting(ce)),
str_yes_no(intel_context_is_banned(ce)));
 
-   if (likely(intel_context_is_schedulable(ce))) {
+   if (capture) {
capture_error_state(guc, ce);
guc_context_replay(ce);
-   } else {
-   guc_info(guc, "Ignoring context reset notification of exiting 
context 0x%04X on %s",
-ce->guc_id.id, ce->engine->name);
}
 }
 
-- 
2.41.0



[Intel-gfx] [PATCH 3/4] drm/i915/guc: Add support for w/a KLVs

2023-09-15 Thread John . C . Harrison
From: John Harrison 

To prevent running out of bits, new w/a enable flags are being added
via a KLV system instead of a 32 bit flags word.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  3 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 64 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  5 +-
 5 files changed, 77 insertions(+), 2 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 dabeaf4f245f3..00d6402333f8e 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
@@ -36,6 +36,7 @@ enum intel_guc_load_status {
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_KLV_WORKAROUND_INIT_ERROR= 0x75,
INTEL_GUC_LOAD_STATUS_INVALID_INIT_DATA_RANGE_END,
 
INTEL_GUC_LOAD_STATUS_READY= 0xF0,
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 6c392bad29c19..3b1fc5f96306b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -186,6 +186,8 @@ struct intel_guc {
struct guc_mmio_reg *ads_regset;
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
u32 ads_golden_ctxt_size;
+   /** @ads_waklv_size: size of workaround KLVs */
+   u32 ads_waklv_size;
/** @ads_capture_size: size of register lists in the ADS used for error 
capture */
u32 ads_capture_size;
/** @ads_engine_usage_size: size of engine usage in the ADS */
@@ -295,6 +297,7 @@ struct intel_guc {
 #define MAKE_GUC_VER(maj, min, pat)(((maj) << 16) | ((min) << 8) | (pat))
 #define MAKE_GUC_VER_STRUCT(ver)   MAKE_GUC_VER((ver).major, (ver).minor, 
(ver).patch)
 #define GUC_SUBMIT_VER(guc)
MAKE_GUC_VER_STRUCT((guc)->submission_version)
+#define GUC_FIRMWARE_VER(guc)  
MAKE_GUC_VER_STRUCT((guc)->fw.file_selected.ver)
 
 static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
 {
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 63724e17829a7..792910af3a481 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -46,6 +46,10 @@
  *  +---+
  *  | padding   |
  *  +---+ <== 4K aligned
+ *  | w/a KLVs  |
+ *  +---+
+ *  | padding   |
+ *  +---+ <== 4K aligned
  *  | capture lists |
  *  +---+
  *  | padding   |
@@ -88,6 +92,11 @@ static u32 guc_ads_golden_ctxt_size(struct intel_guc *guc)
return PAGE_ALIGN(guc->ads_golden_ctxt_size);
 }
 
+static u32 guc_ads_waklv_size(struct intel_guc *guc)
+{
+   return PAGE_ALIGN(guc->ads_waklv_size);
+}
+
 static u32 guc_ads_capture_size(struct intel_guc *guc)
 {
return PAGE_ALIGN(guc->ads_capture_size);
@@ -113,7 +122,7 @@ static u32 guc_ads_golden_ctxt_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
-static u32 guc_ads_capture_offset(struct intel_guc *guc)
+static u32 guc_ads_waklv_offset(struct intel_guc *guc)
 {
u32 offset;
 
@@ -123,6 +132,16 @@ static u32 guc_ads_capture_offset(struct intel_guc *guc)
return PAGE_ALIGN(offset);
 }
 
+static u32 guc_ads_capture_offset(struct intel_guc *guc)
+{
+   u32 offset;
+
+   offset = guc_ads_waklv_offset(guc) +
+guc_ads_waklv_size(guc);
+
+   return PAGE_ALIGN(offset);
+}
+
 static u32 guc_ads_private_data_offset(struct intel_guc *guc)
 {
u32 offset;
@@ -791,6 +810,40 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+static void guc_waklv_init(struct intel_guc *guc)
+{
+   struct intel_gt *gt = guc_to_gt(guc);
+   u32 offset, addr_ggtt, remain, size;
+
+   if (!intel_uc_uses_guc_submission(>uc))
+   return;
+
+   if (GUC_FIRMWARE_VER(guc) < MAKE_GUC_VER(70, 10, 0))
+   return;
+
+   GEM_BUG_ON(iosys_map_is_null(>ads_map));
+   offset = guc_ads_waklv_offset(guc);
+   remain = guc_ads_waklv_size(guc);
+
+   /* Add workarounds here */
+
+   size = guc_ads_waklv_size(guc) - remain;
+   if (!size)
+   return;
+
+   addr_ggtt = intel_guc_ggtt_offset(guc, guc->ads_vma) + offset;
+
+   

[Intel-gfx] [PATCH 4/4] drm/i915/guc: Enable Wa_14019159160

2023-09-15 Thread John . C . Harrison
From: John Harrison 

Use the new w/a KLV support to enable a MTL w/a. Note, this w/a is a
super-set of Wa_16019325821, so requires turning that one as well as
setting the new flag for Wa_14019159160 itself.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  |  3 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 +
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 26 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  1 +
 6 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 8b494825c55f2..d31c405b095b7 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -734,6 +734,7 @@ static u32 *gen12_emit_preempt_busywait(struct i915_request 
*rq, u32 *cs)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 #define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
 static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
@@ -743,6 +744,7 @@ static u32 hold_switchout_semaphore_offset(struct 
i915_request *rq)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
@@ -783,6 +785,7 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
 
/* Wa_14014475959:dg2 */
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (intel_engine_uses_wa_hold_switchout(rq->engine))
cs = hold_switchout_emit_wa_busywait(rq, cs);
 
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index 68fe1cef9cd94..9b3051600856e 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -684,6 +684,7 @@ intel_engine_has_relative_mmio(const struct intel_engine_cs 
* const engine)
 
 /* Wa_14014475959:dg2 */
 /* Wa_16019325821 */
+/* Wa_14019159160 */
 static inline bool
 intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
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 58012edd4eb0e..bebf28e3c4794 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
@@ -101,4 +101,11 @@ enum {
GUC_CONTEXT_POLICIES_KLV_NUM_IDS = 5,
 };
 
+/*
+ * Workaround keys:
+ */
+enum {
+   GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE   = 
0x9001,
+};
+
 #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 4001679ba0793..e74590a71d113 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -295,6 +295,7 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
/* Wa_16019325821 */
+   /* Wa_14019159160 */
if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
flags |= GUC_WA_RCS_CCS_SWITCHOUT;
 
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 792910af3a481..a9fd2e96f27f5 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -810,6 +810,25 @@ guc_capture_prep_lists(struct intel_guc *guc)
return PAGE_ALIGN(total_size);
 }
 
+/* Wa_14019159160 */
+static u32 guc_waklv_ra_mode(struct intel_guc *guc, u32 offset, u32 remain)
+{
+   u32 size;
+   u32 klv_entry[] = {
+   /* 16:16 key/length */
+   FIELD_PREP(GUC_KLV_0_KEY, 
GUC_WORKAROUND_KLV_SERIALIZED_RA_MODE) |
+   FIELD_PREP(GUC_KLV_0_LEN, 0),
+   /* 0 dwords data */
+   };
+
+   size = sizeof(klv_entry);
+   GEM_BUG_ON(remain < size);
+
+   iosys_map_memcpy_to(>ads_map, offset, klv_entry, size);
+
+   return size;
+}
+
 static void guc_waklv_init(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -825,7 +844,12 @@ static void guc_waklv_init(struct intel_guc *guc)
offset = guc_ads_waklv_offset(guc);
remain = guc_ads_waklv_size(guc);
 
-   /* Add workarounds here */
+   /* Wa_14019159160 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71))) {
+   size = guc_waklv_ra_mode(guc, offset, remain);
+   offset += size;
+   remain -= size;
+   }
 
size = guc_ads_waklv_size(guc) - remain;
if (!size)
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 ff38a815701ce..c8428e4b03592 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ 

[Intel-gfx] [PATCH 2/4] drm/i915: Enable Wa_16019325821

2023-09-15 Thread John . C . Harrison
From: John Harrison 

Some platforms require holding RCS context switches until CCS is idle
(the reverse w/a of Wa_14014475959). Some platforms require both
versions.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 19 +++
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  7 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  4 
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  3 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  8 +++-
 5 files changed, 28 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c 
b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
index 0143445dba830..8b494825c55f2 100644
--- a/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
+++ b/drivers/gpu/drm/i915/gt/gen8_engine_cs.c
@@ -733,21 +733,23 @@ static u32 *gen12_emit_preempt_busywait(struct 
i915_request *rq, u32 *cs)
 }
 
 /* Wa_14014475959:dg2 */
-#define CCS_SEMAPHORE_PPHWSP_OFFSET0x540
-static u32 ccs_semaphore_offset(struct i915_request *rq)
+/* Wa_16019325821 */
+#define HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET 0x540
+static u32 hold_switchout_semaphore_offset(struct i915_request *rq)
 {
return i915_ggtt_offset(rq->context->state) +
-   (LRC_PPHWSP_PN * PAGE_SIZE) + CCS_SEMAPHORE_PPHWSP_OFFSET;
+   (LRC_PPHWSP_PN * PAGE_SIZE) + 
HOLD_SWITCHOUT_SEMAPHORE_PPHWSP_OFFSET;
 }
 
 /* Wa_14014475959:dg2 */
-static u32 *ccs_emit_wa_busywait(struct i915_request *rq, u32 *cs)
+/* Wa_16019325821 */
+static u32 *hold_switchout_emit_wa_busywait(struct i915_request *rq, u32 *cs)
 {
int i;
 
*cs++ = MI_ATOMIC_INLINE | MI_ATOMIC_GLOBAL_GTT | MI_ATOMIC_CS_STALL |
MI_ATOMIC_MOVE;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
*cs++ = 1;
 
@@ -763,7 +765,7 @@ static u32 *ccs_emit_wa_busywait(struct i915_request *rq, 
u32 *cs)
MI_SEMAPHORE_POLL |
MI_SEMAPHORE_SAD_EQ_SDD;
*cs++ = 0;
-   *cs++ = ccs_semaphore_offset(rq);
+   *cs++ = hold_switchout_semaphore_offset(rq);
*cs++ = 0;
 
return cs;
@@ -780,8 +782,9 @@ gen12_emit_fini_breadcrumb_tail(struct i915_request *rq, 
u32 *cs)
cs = gen12_emit_preempt_busywait(rq, cs);
 
/* Wa_14014475959:dg2 */
-   if (intel_engine_uses_wa_hold_ccs_switchout(rq->engine))
-   cs = ccs_emit_wa_busywait(rq, cs);
+   /* Wa_16019325821 */
+   if (intel_engine_uses_wa_hold_switchout(rq->engine))
+   cs = hold_switchout_emit_wa_busywait(rq, cs);
 
rq->tail = intel_ring_offset(rq, cs);
assert_ring_tail_valid(rq->ring, rq->tail);
diff --git a/drivers/gpu/drm/i915/gt/intel_engine_types.h 
b/drivers/gpu/drm/i915/gt/intel_engine_types.h
index a7e6775980043..68fe1cef9cd94 100644
--- a/drivers/gpu/drm/i915/gt/intel_engine_types.h
+++ b/drivers/gpu/drm/i915/gt/intel_engine_types.h
@@ -573,7 +573,7 @@ struct intel_engine_cs {
 #define I915_ENGINE_HAS_RCS_REG_STATE  BIT(9)
 #define I915_ENGINE_HAS_EU_PRIORITYBIT(10)
 #define I915_ENGINE_FIRST_RENDER_COMPUTE BIT(11)
-#define I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT BIT(12)
+#define I915_ENGINE_USES_WA_HOLD_SWITCHOUT BIT(12)
unsigned int flags;
 
/*
@@ -683,10 +683,11 @@ intel_engine_has_relative_mmio(const struct 
intel_engine_cs * const engine)
 }
 
 /* Wa_14014475959:dg2 */
+/* Wa_16019325821 */
 static inline bool
-intel_engine_uses_wa_hold_ccs_switchout(struct intel_engine_cs *engine)
+intel_engine_uses_wa_hold_switchout(struct intel_engine_cs *engine)
 {
-   return engine->flags & I915_ENGINE_USES_WA_HOLD_CCS_SWITCHOUT;
+   return engine->flags & I915_ENGINE_USES_WA_HOLD_SWITCHOUT;
 }
 
 #endif /* __INTEL_ENGINE_TYPES_H__ */
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 27df41c53b890..4001679ba0793 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -294,6 +294,10 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
IS_DG2(gt->i915))
flags |= GUC_WA_HOLD_CCS_SWITCHOUT;
 
+   /* Wa_16019325821 */
+   if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)))
+   flags |= GUC_WA_RCS_CCS_SWITCHOUT;
+
/*
 * Wa_14012197797
 * Wa_22011391025
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 b4d56eccfb1f0..f97af0168a66b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -95,8 +95,9 @@
 #define   GUC_WA_GAM_CREDITS   BIT(10)
 #define   GUC_WA_DUAL_QUEUEBIT(11)
 #define   GUC_WA_RCS_RESET_BEFORE_RC6  BIT(13)
-#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
 #define   GUC_WA_PRE_PARSERBIT(14)
+#define   GUC_WA_CONTEXT_ISOLATION BIT(15)
+#define   GUC_WA_RCS_CCS_SWITCHOUT 

[Intel-gfx] [PATCH 1/4] drm/i915/guc: Update 'recommended' version to 70.11.0 for DG2/ADL-P/MTL

2023-09-15 Thread John . C . Harrison
From: John Harrison 

The latest GuC has new features and new workarounds that we wish to
enable. So let the universe know that it is useful to update their
firmware.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 6 +++---
 1 file changed, 3 insertions(+), 3 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 32e27e9a2490f..a40f96c98308b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -88,9 +88,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * security fixes, etc. to be enabled.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
-   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 6, 6)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
+   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 11, 0)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 11, 0)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 11, 0)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
-- 
2.41.0



[Intel-gfx] [PATCH 0/4] Enable Wa_14019159160 and Wa_16019325821 for MTL

2023-09-15 Thread John . C . Harrison
From: John Harrison 

Enable Wa_14019159160 and  Wa_16019325821 for MTL

RCS/CCS workarounds for MTL.

Signed-off-by: John Harrison 


John Harrison (4):
  drm/i915/guc: Update 'recommended' version to 70.11.0 for
DG2/ADL-P/MTL
  drm/i915: Enable Wa_16019325821
  drm/i915/guc: Add support for w/a KLVs
  drm/i915/guc: Enable Wa_14019159160

 drivers/gpu/drm/i915/gt/gen8_engine_cs.c  | 22 +++--
 drivers/gpu/drm/i915/gt/intel_engine_types.h  |  8 +-
 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |  1 +
 drivers/gpu/drm/i915/gt/uc/abi/guc_klvs_abi.h |  7 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.c|  5 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  3 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 88 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  8 +-
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  9 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  |  6 +-
 11 files changed, 145 insertions(+), 18 deletions(-)

-- 
2.41.0



[Intel-gfx] [PATCH 0/2] Enable Wa_14018913170 on DG2/MTL/PVD

2023-09-14 Thread John . C . Harrison
From: John Harrison 

Enable a WA on the latest platforms. Also update the recommended GuC
version for those platforms to the latest available. Further patches
will follow to make use of other features in the latest GuC firmware,
but the w/a at least requires something newer than what was previously
in use.

Signed-off-by: John Harrison 


Daniele Ceraolo Spurio (1):
  drm/i915/guc: Enable WA 14018913170

John Harrison (1):
  drm/i915/guc: Update 'recommended' version to 70.11.0 for
DG2/ADL-P/MTL

 drivers/gpu/drm/i915/gt/uc/intel_guc.c  | 6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h  | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c| 6 +++---
 4 files changed, 11 insertions(+), 3 deletions(-)

-- 
2.41.0



[Intel-gfx] [PATCH 2/2] drm/i915/guc: Enable WA 14018913170

2023-09-14 Thread John . C . Harrison
From: Daniele Ceraolo Spurio 

The GuC handles the WA, the KMD just needs to set the flag to enable
it on the appropriate platforms.

Signed-off-by: John Harrison 
Signed-off-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c  | 6 ++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h  | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 1 +
 3 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 27df41c53b890..3f3df1166b860 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -319,6 +319,12 @@ static u32 guc_ctl_wa_flags(struct intel_guc *guc)
if (!RCS_MASK(gt))
flags |= GUC_WA_RCS_REGS_IN_CCS_REGS_LIST;
 
+   /* Wa_14018913170 */
+   if (GUC_FIRMWARE_VER(guc) >= MAKE_GUC_VER(70, 7, 0)) {
+   if (IS_DG2(gt->i915) || IS_METEORLAKE(gt->i915) || 
IS_PONTEVECCHIO(gt->i915))
+   flags |= GUC_WA_ENABLE_TSC_CHECK_ON_RC6;
+   }
+
return flags;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 6c392bad29c19..818c8c146fd47 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -295,6 +295,7 @@ struct intel_guc {
 #define MAKE_GUC_VER(maj, min, pat)(((maj) << 16) | ((min) << 8) | (pat))
 #define MAKE_GUC_VER_STRUCT(ver)   MAKE_GUC_VER((ver).major, (ver).minor, 
(ver).patch)
 #define GUC_SUBMIT_VER(guc)
MAKE_GUC_VER_STRUCT((guc)->submission_version)
+#define GUC_FIRMWARE_VER(guc)  
MAKE_GUC_VER_STRUCT((guc)->fw.file_selected.ver)
 
 static inline struct intel_guc *log_to_guc(struct intel_guc_log *log)
 {
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 b4d56eccfb1f0..123ad75d2eb28 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -100,6 +100,7 @@
 #define   GUC_WA_HOLD_CCS_SWITCHOUTBIT(17)
 #define   GUC_WA_POLLCSBIT(18)
 #define   GUC_WA_RCS_REGS_IN_CCS_REGS_LIST BIT(21)
+#define   GUC_WA_ENABLE_TSC_CHECK_ON_RC6   BIT(22)
 
 #define GUC_CTL_FEATURE2
 #define   GUC_CTL_ENABLE_SLPC  BIT(2)
-- 
2.41.0



[Intel-gfx] [PATCH 1/2] drm/i915/guc: Update 'recommended' version to 70.11.0 for DG2/ADL-P/MTL

2023-09-14 Thread John . C . Harrison
From: John Harrison 

The latest GuC has new features and new workarounds that we wish to
enable. So let the universe know that it is useful to update their
firmware.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 6 +++---
 1 file changed, 3 insertions(+), 3 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 32e27e9a2490f..a40f96c98308b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -88,9 +88,9 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * security fixes, etc. to be enabled.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
-   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 6, 6)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
+   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 11, 0)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 11, 0)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 11, 0)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
-- 
2.41.0



[Intel-gfx] [CI] PR for new GuC v70.11.0

2023-09-14 Thread John . C . Harrison
The following changes since commit dfa11466cf000120d1551146fd5bf78c44941eda:

  Merge branch 'main' into 'main' (2023-09-07 11:36:57 +)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware guc_70.11.0

for you to fetch changes up to af0fdbdde5b3e2318aefa4db00115c808a9cfe2d:

  i915: Add GuC v70.11.0 for DG2, ADL-P and MTL (2023-09-14 14:25:18 -0700)


John Harrison (1):
  i915: Add GuC v70.11.0 for DG2, ADL-P and MTL

 WHENCE   |   6 +++---
 i915/adlp_guc_70.bin | Bin 297984 -> 341696 bytes
 i915/dg2_guc_70.bin  | Bin 385856 -> 443200 bytes
 i915/mtl_guc_70.bin  | Bin 308032 -> 365376 bytes
 4 files changed, 3 insertions(+), 3 deletions(-)


[Intel-gfx] [PATCH v2] drm/i915/guc: Force a reset on internal GuC error

2023-08-15 Thread John . C . Harrison
From: John Harrison 

If GuC hits an internal error (and survives long enough to report it
to the KMD), it is basically toast and will stop until a GT reset and
subsequent GuC reload is performed. Previously, the KMD just printed
an error message and then waited for the heartbeat to eventually kick
in and trigger a reset (assuming the heartbeat had not been disabled).
Instead, force the reset immediately to guarantee that it happens and
to eliminate the very long heartbeat delay. The captured error state
is also more likely to be useful if captured at the time of the error
rather than many seconds later.

Note that it is not possible to trigger a reset from with the G2H
handler itself. The reset prepare process involves flushing
outstanding G2H contents. So a deadlock could result. Instead, the G2H
handler queues a worker thread to do the reset asynchronously.

v2: Flush the worker on suspend and shutdown. Add rate limiting to
prevent spam from a totally dead system (review feedback from Daniele).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 38 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h| 15 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  6 +---
 3 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 569b5fe94c416..12a817b762334 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -159,6 +159,21 @@ static void gen11_disable_guc_interrupts(struct intel_guc 
*guc)
gen11_reset_guc_interrupts(guc);
 }
 
+static void guc_dead_worker_func(struct work_struct *w)
+{
+   struct intel_guc *guc = container_of(w, struct intel_guc, 
dead_guc_worker);
+   struct intel_gt *gt = guc_to_gt(guc);
+   unsigned long last = guc->last_dead_guc_jiffies;
+   unsigned long delta = jiffies_to_msecs(jiffies - last);
+
+   if (delta < 500) {
+   intel_gt_set_wedged(gt);
+   } else {
+   intel_gt_handle_error(gt, ALL_ENGINES, I915_ERROR_CAPTURE, 
"dead GuC");
+   guc->last_dead_guc_jiffies = jiffies;
+   }
+}
+
 void intel_guc_init_early(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -171,6 +186,8 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_slpc_init_early(>slpc);
intel_guc_rc_init_early(guc);
 
+   INIT_WORK(>dead_guc_worker, guc_dead_worker_func);
+
mutex_init(>send_mutex);
spin_lock_init(>irq_lock);
if (GRAPHICS_VER(i915) >= 11) {
@@ -461,6 +478,8 @@ void intel_guc_fini(struct intel_guc *guc)
if (!intel_uc_fw_is_loadable(>fw))
return;
 
+   flush_work(>dead_guc_worker);
+
if (intel_guc_slpc_is_used(guc))
intel_guc_slpc_fini(>slpc);
 
@@ -585,6 +604,20 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
return ret;
 }
 
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action)
+{
+   if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED)
+   guc_err(guc, "Crash dump notification\n");
+   else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION)
+   guc_err(guc, "Exception notification\n");
+   else
+   guc_err(guc, "Unknown crash notification: 0x%04X\n", action);
+
+   queue_work(system_unbound_wq, >dead_guc_worker);
+
+   return 0;
+}
+
 int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
   const u32 *payload, u32 len)
 {
@@ -601,6 +634,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
guc_err(guc, "Received early exception notification!\n");
 
+   if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | 
INTEL_GUC_RECV_MSG_EXCEPTION))
+   queue_work(system_unbound_wq, >dead_guc_worker);
+
return 0;
 }
 
@@ -640,6 +676,8 @@ int intel_guc_suspend(struct intel_guc *guc)
return 0;
 
if (intel_guc_submission_is_used(guc)) {
+   flush_work(>dead_guc_worker);
+
/*
 * This H2G MMIO command tears down the GuC in two steps. First 
it will
 * generate a G2H CTB for every active context indicating a 
reset. In
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 8dc291ff00935..6c392bad29c19 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -266,6 +266,20 @@ struct intel_guc {
unsigned long last_stat_jiffies;
} timestamp;
 
+   /**
+* @dead_guc_worker: Asynchronous worker thread for forcing a GuC reset.
+* Specifically used when the G2H handler wants to issue a reset. Resets
+* require flushing the G2H queue. So, the G2H processing itself must 
not
+

[Intel-gfx] [PATCH] drm/i915/guc: Fix potential null pointer deref in GuC 'steal id' test

2023-08-02 Thread John . C . Harrison
From: John Harrison 

It was noticed that if the very first 'stealing' request failed to
create for some reason then the 'steal all ids' loop would immediately
exit with 'last' still being NULL. The test would attempt to continue
but using a null pointer. Fix that by aborting the test if it fails to
create any requests at all.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/selftest_guc.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c 
b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
index 1fd760539f77b..bfb72143566f6 100644
--- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c
@@ -204,9 +204,9 @@ static int intel_guc_steal_guc_ids(void *arg)
if (IS_ERR(rq)) {
ret = PTR_ERR(rq);
rq = NULL;
-   if (ret != -EAGAIN) {
-   guc_err(guc, "Failed to create request %d: 
%pe\n",
-   context_index, ERR_PTR(ret));
+   if ((ret != -EAGAIN) || !last) {
+   guc_err(guc, "Failed to create %srequest %d: 
%pe\n",
+   last ? "" : "first ", context_index, 
ERR_PTR(ret));
goto err_spin_rq;
}
} else {
-- 
2.39.1



[Intel-gfx] [PATCH] drm/i915/guc: Force a reset on internal GuC error

2023-06-05 Thread John . C . Harrison
From: John Harrison 

If GuC hits an internal error (and survives long enough to report it
to the KMD), it is basically toast and will stop until a GT reset and
subsequent GuC reload is performed. Previously, the KMD just printed
an error message and then waited for the heartbeat to eventually kick
in and trigger a reset (assuming the heartbeat had not been disabled).
Instead, force the reset immediately to guarantee that it happens and
to eliminate the very long heartbeat delay. The captured error state
is also more likely to be useful if captured at the time of the error
rather than many seconds later.

Note that it is not possible to trigger a reset from with the G2H
handler itself. The reset prepare process involves flushing
outstanding G2H contents. So a deadlock could result. Instead, the G2H
handler queues a worker thread to do the reset asynchronously.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc.c| 26 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc.h|  9 
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  6 +-
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
index 2eb891b270aec..c35cf10f52b56 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.c
@@ -159,6 +159,13 @@ static void gen11_disable_guc_interrupts(struct intel_guc 
*guc)
gen11_reset_guc_interrupts(guc);
 }
 
+static void guc_dead_worker_func(struct work_struct *w)
+{
+   struct intel_guc *guc = container_of(w, struct intel_guc, 
dead_guc_worker);
+
+   intel_gt_handle_error(guc_to_gt(guc), ALL_ENGINES, I915_ERROR_CAPTURE, 
"dead GuC");
+}
+
 void intel_guc_init_early(struct intel_guc *guc)
 {
struct intel_gt *gt = guc_to_gt(guc);
@@ -171,6 +178,8 @@ void intel_guc_init_early(struct intel_guc *guc)
intel_guc_slpc_init_early(>slpc);
intel_guc_rc_init_early(guc);
 
+   INIT_WORK(>dead_guc_worker, guc_dead_worker_func);
+
mutex_init(>send_mutex);
spin_lock_init(>irq_lock);
if (GRAPHICS_VER(i915) >= 11) {
@@ -585,6 +594,20 @@ int intel_guc_send_mmio(struct intel_guc *guc, const u32 
*request, u32 len,
return ret;
 }
 
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action)
+{
+   if (action == INTEL_GUC_ACTION_NOTIFY_CRASH_DUMP_POSTED)
+   guc_err(guc, "Crash dump notification\n");
+   else if (action == INTEL_GUC_ACTION_NOTIFY_EXCEPTION)
+   guc_err(guc, "Exception notification\n");
+   else
+   guc_err(guc, "Unknown crash notification\n");
+
+   queue_work(system_unbound_wq, >dead_guc_worker);
+
+   return 0;
+}
+
 int intel_guc_to_host_process_recv_msg(struct intel_guc *guc,
   const u32 *payload, u32 len)
 {
@@ -601,6 +624,9 @@ int intel_guc_to_host_process_recv_msg(struct intel_guc 
*guc,
if (msg & INTEL_GUC_RECV_MSG_EXCEPTION)
guc_err(guc, "Received early exception notification!\n");
 
+   if (msg & (INTEL_GUC_RECV_MSG_CRASH_DUMP_POSTED | 
INTEL_GUC_RECV_MSG_EXCEPTION))
+   queue_work(system_unbound_wq, >dead_guc_worker);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
index 8dc291ff00935..0b54eec95fc00 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h
@@ -266,6 +266,14 @@ struct intel_guc {
unsigned long last_stat_jiffies;
} timestamp;
 
+   /**
+* @dead_guc_worker: Asynchronous worker thread for forcing a GuC reset.
+* Specifically used when the G2H handler wants to issue a reset. Resets
+* require flushing the G2H queue. So, the G2H processing itself must 
not
+* trigger a reset directly. Instead, go via this worker.
+*/
+   struct work_struct dead_guc_worker;
+
 #ifdef CONFIG_DRM_I915_SELFTEST
/**
 * @number_guc_id_stolen: The number of guc_ids that have been stolen
@@ -476,6 +484,7 @@ 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);
+int intel_guc_crash_process_msg(struct intel_guc *guc, u32 action);
 
 struct intel_engine_cs *
 intel_guc_lookup_engine(struct intel_guc *guc, u8 guc_class, u8 instance);
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 f28a3a83742dc..7b09ad6931021 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -1116,12 +1116,8 @@ static int ct_process_request(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
ret = 0;
break;
case 

[Intel-gfx] [PATCH] drm/i915/guc: Remove some obsolete definitions

2023-05-31 Thread John . C . Harrison
From: John Harrison 

There were a bunch of defines and structures left over from an API
update a very long time ago. Remove them.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h | 33 -
 1 file changed, 33 deletions(-)

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 4e57bd09d50d9..b4d56eccfb1f0 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h
@@ -35,13 +35,6 @@
 #define GUC_MAX_CONTEXT_ID 65535
 #defineGUC_INVALID_CONTEXT_ID  GUC_MAX_CONTEXT_ID
 
-#define GUC_RENDER_ENGINE  0
-#define GUC_VIDEO_ENGINE   1
-#define GUC_BLITTER_ENGINE 2
-#define GUC_VIDEOENHANCE_ENGINE3
-#define GUC_VIDEO_ENGINE2  4
-#define GUC_MAX_ENGINES_NUM(GUC_VIDEO_ENGINE2 + 1)
-
 #define GUC_RENDER_CLASS   0
 #define GUC_VIDEO_CLASS1
 #define GUC_VIDEOENHANCE_CLASS 2
@@ -499,32 +492,6 @@ struct guc_log_buffer_state {
u32 version;
 } __packed;
 
-struct guc_ctx_report {
-   u32 report_return_status;
-   u32 reserved1[64];
-   u32 affected_count;
-   u32 reserved2[2];
-} __packed;
-
-/* GuC Shared Context Data Struct */
-struct guc_shared_ctx_data {
-   u32 addr_of_last_preempted_data_low;
-   u32 addr_of_last_preempted_data_high;
-   u32 addr_of_last_preempted_data_high_tmp;
-   u32 padding;
-   u32 is_mapped_to_proxy;
-   u32 proxy_ctx_id;
-   u32 engine_reset_ctx_id;
-   u32 media_reset_count;
-   u32 reserved1[8];
-   u32 uk_last_ctx_switch_reason;
-   u32 was_reset;
-   u32 lrca_gpu_addr;
-   u64 execlist_ctx;
-   u32 reserved2[66];
-   struct guc_ctx_report preempt_ctx_report[GUC_MAX_ENGINES_NUM];
-} __packed;
-
 /* 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),
-- 
2.39.1



[Intel-gfx] [PATCH 3/3] drm/i915/guc: Track all sent actions to GuC

2023-05-26 Thread John . C . Harrison
From: Michal Wajdeczko 

For easier debug of any unexpected error responses from GuC that
might be related to non-blocking fast requests, track action code (and
stack if under DEBUG_GUC config) for every H2G request.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/Kconfig.debug|  1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 68 ++-
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 11 
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/Kconfig.debug 
b/drivers/gpu/drm/i915/Kconfig.debug
index 47e845353ffad..2d21930d55015 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -157,6 +157,7 @@ config DRM_I915_SW_FENCE_CHECK_DAG
 config DRM_I915_DEBUG_GUC
bool "Enable additional driver debugging for GuC"
depends on DRM_I915
+   select STACKDEPOT
default n
help
  Choose this option to turn on extra driver debugging that may affect
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 3a71bb582089e..4aa903be1317b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -376,6 +376,24 @@ void intel_guc_ct_disable(struct intel_guc_ct *ct)
}
 }
 
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+static void ct_track_lost_and_found(struct intel_guc_ct *ct, u32 fence, u32 
action)
+{
+   unsigned int lost = fence % ARRAY_SIZE(ct->requests.lost_and_found);
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+   unsigned long entries[SZ_32];
+   unsigned int n;
+
+   n = stack_trace_save(entries, ARRAY_SIZE(entries), 1);
+
+   /* May be called under spinlock, so avoid sleeping */
+   ct->requests.lost_and_found[lost].stack = stack_depot_save(entries, n, 
GFP_NOWAIT);
+#endif
+   ct->requests.lost_and_found[lost].fence = fence;
+   ct->requests.lost_and_found[lost].action = action;
+}
+#endif
+
 static u32 ct_get_next_fence(struct intel_guc_ct *ct)
 {
/* For now it's trivial */
@@ -447,6 +465,11 @@ static int ct_write(struct intel_guc_ct *ct,
}
GEM_BUG_ON(tail > size);
 
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+   ct_track_lost_and_found(ct, fence,
+   FIELD_GET(GUC_HXG_EVENT_MSG_0_ACTION, 
action[0]));
+#endif
+
/*
 * make sure H2G buffer update and LRC tail update (if this triggering a
 * submission) are visible before updating the descriptor tail
@@ -953,6 +976,43 @@ static int ct_read(struct intel_guc_ct *ct, struct 
ct_incoming_msg **msg)
return -EPIPE;
 }
 
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+static bool ct_check_lost_and_found(struct intel_guc_ct *ct, u32 fence)
+{
+   unsigned int n;
+   char *buf = NULL;
+   bool found = false;
+
+   lockdep_assert_held(>requests.lock);
+
+   for (n = 0; n < ARRAY_SIZE(ct->requests.lost_and_found); n++) {
+   if (ct->requests.lost_and_found[n].fence != fence)
+   continue;
+   found = true;
+
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GUC)
+   buf = kmalloc(SZ_4K, GFP_NOWAIT);
+   if (buf && 
stack_depot_snprint(ct->requests.lost_and_found[n].stack,
+  buf, SZ_4K, 0)) {
+   CT_ERROR(ct, "Fence %u was used by action %#04x sent 
at\n%s",
+fence, ct->requests.lost_and_found[n].action, 
buf);
+   break;
+   }
+#endif
+   CT_ERROR(ct, "Fence %u was used by action %#04x\n",
+fence, ct->requests.lost_and_found[n].action);
+   break;
+   }
+   kfree(buf);
+   return found;
+}
+#else
+static bool ct_check_lost_and_found(struct intel_guc_ct *ct, u32 fence)
+{
+   return false;
+}
+#endif
+
 static int ct_handle_response(struct intel_guc_ct *ct, struct ct_incoming_msg 
*response)
 {
u32 len = FIELD_GET(GUC_CTB_MSG_0_NUM_DWORDS, response->msg[0]);
@@ -996,9 +1056,11 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
if (!found) {
CT_ERROR(ct, "Unsolicited response message: len %u, data %#x 
(fence %u, last %u)\n",
 len, hxg[0], fence, ct->requests.last_fence);
-   list_for_each_entry(req, >requests.pending, link)
-   CT_ERROR(ct, "request %u awaits response\n",
-req->fence);
+   if (!ct_check_lost_and_found(ct, fence)) {
+   list_for_each_entry(req, >requests.pending, link)
+   CT_ERROR(ct, "request %u awaits response\n",
+req->fence);
+   }
err = -ENOKEY;
}
spin_unlock_irqrestore(>requests.lock, flags);
diff --git 

[Intel-gfx] [PATCH 2/3] drm/i915/guc: Update log for unsolicited CTB response

2023-05-26 Thread John . C . Harrison
From: Michal Wajdeczko 

Instead of printing message fence twice, include HXG header of the
unexpected message and its len.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

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 af52ed4ffc7fb..3a71bb582089e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -994,9 +994,8 @@ static int ct_handle_response(struct intel_guc_ct *ct, 
struct ct_incoming_msg *r
break;
}
if (!found) {
-   CT_ERROR(ct, "Unsolicited response (fence %u)\n", fence);
-   CT_ERROR(ct, "Could not find fence=%u, last_fence=%u\n", fence,
-ct->requests.last_fence);
+   CT_ERROR(ct, "Unsolicited response message: len %u, data %#x 
(fence %u, last %u)\n",
+len, hxg[0], fence, ct->requests.last_fence);
list_for_each_entry(req, >requests.pending, link)
CT_ERROR(ct, "request %u awaits response\n",
 req->fence);
-- 
2.39.1



[Intel-gfx] [PATCH 0/3] Use FAST_REQUEST mechanism for non-blocking H2G calls

2023-05-26 Thread John . C . Harrison
From: John Harrison 

The GuC interface supports a mechanism for returning errors against
non-blocking H2G calls. This is called FAST_REQUEST. Given that the
call is asynchronous, matching the returned error up is difficult.
However, getting any error at all back is better than no error.

If any such errors are reported, then extra tracking support can be
compiled in for manual debug.

Signed-off-by: John Harrison 


Michal Wajdeczko (3):
  drm/i915/guc: Use FAST_REQUEST for non-blocking H2G calls
  drm/i915/guc: Update log for unsolicited CTB response
  drm/i915/guc: Track all sent actions to GuC

 drivers/gpu/drm/i915/Kconfig.debug|  1 +
 .../gpu/drm/i915/gt/uc/abi/guc_messages_abi.h | 30 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c | 79 ---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.h | 11 +++
 4 files changed, 112 insertions(+), 9 deletions(-)

-- 
2.39.1



[Intel-gfx] [PATCH 1/3] drm/i915/guc: Use FAST_REQUEST for non-blocking H2G calls

2023-05-26 Thread John . C . Harrison
From: Michal Wajdeczko 

In addition to the already defined REQUEST HXG message format,
which is used when sender expects some confirmation or data,
HXG protocol includes definition of the FAST REQUEST message,
that may be used when sender does not expect any useful data
to be returned.

Using this instead of GUC_HXG_TYPE_EVENT for non-blocking CTB requests
will allow GuC to send back GUC_HXG_TYPE_RESPONSE_FAILURE in case of
errors.

Note that it is not possible to return such errors to the caller,
since this is for non-blocking calls and the related fence is not
stored. Instead such messages are treated as unexpected, which will
give an indication of potential GuC misprogramming that warrants extra
debugging effort.

Signed-off-by: Michal Wajdeczko 
Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/abi/guc_messages_abi.h | 30 +++
 drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c |  6 ++--
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h 
b/drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
index 7d5ba4d97d708..98eb4f46572b9 100644
--- a/drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
+++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_messages_abi.h
@@ -24,6 +24,7 @@
  *  |   | 30:28 | **TYPE** - message type  
|
  *  |   |   |   - _`GUC_HXG_TYPE_REQUEST` = 0  
|
  *  |   |   |   - _`GUC_HXG_TYPE_EVENT` = 1
|
+ *  |   |   |   - _`GUC_HXG_TYPE_FAST_REQUEST` = 2 
|
  *  |   |   |   - _`GUC_HXG_TYPE_NO_RESPONSE_BUSY` = 3 
|
  *  |   |   |   - _`GUC_HXG_TYPE_NO_RESPONSE_RETRY` = 5
|
  *  |   |   |   - _`GUC_HXG_TYPE_RESPONSE_FAILURE` = 6 
|
@@ -46,6 +47,7 @@
 #define GUC_HXG_MSG_0_TYPE (0x7 << 28)
 #define   GUC_HXG_TYPE_REQUEST 0u
 #define   GUC_HXG_TYPE_EVENT   1u
+#define   GUC_HXG_TYPE_FAST_REQUEST2u
 #define   GUC_HXG_TYPE_NO_RESPONSE_BUSY3u
 #define   GUC_HXG_TYPE_NO_RESPONSE_RETRY   5u
 #define   GUC_HXG_TYPE_RESPONSE_FAILURE6u
@@ -89,6 +91,34 @@
 #define GUC_HXG_REQUEST_MSG_0_ACTION   (0x << 0)
 #define GUC_HXG_REQUEST_MSG_n_DATAnGUC_HXG_MSG_n_PAYLOAD
 
+/**
+ * DOC: HXG Fast Request
+ *
+ * The `HXG Request`_ message should be used to initiate asynchronous activity
+ * for which confirmation or return data is not expected.
+ *
+ * If confirmation is required then `HXG Request`_ shall be used instead.
+ *
+ * The recipient of this message may only use `HXG Failure`_ message if it was
+ * unable to accept this request (like invalid data).
+ *
+ * Format of `HXG Fast Request`_ message is same as `HXG Request`_ except 
@TYPE.
+ *
+ *  
+---+---+--+
+ *  |   | Bits  | Description  
|
+ *  
+===+===+==+
+ *  | 0 |31 | ORIGIN - see `HXG Message`_  
|
+ *  |   
+---+--+
+ *  |   | 30:28 | TYPE = `GUC_HXG_TYPE_FAST_REQUEST`_  
|
+ *  |   
+---+--+
+ *  |   | 27:16 | DATA0 - see `HXG Request`_   
|
+ *  |   
+---+--+
+ *  |   |  15:0 | ACTION - see `HXG Request`_  
|
+ *  
+---+---+--+
+ *  |...|   | DATAn - see `HXG Request`_   
|
+ *  
+---+---+--+
+ */
+
 /**
  * DOC: HXG Event
  *
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 a22e33f37cae6..af52ed4ffc7fb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c
@@ -426,11 +426,11 @@ static int ct_write(struct intel_guc_ct *ct,
 FIELD_PREP(GUC_CTB_MSG_0_NUM_DWORDS, len) |
 FIELD_PREP(GUC_CTB_MSG_0_FENCE, fence);
 
-   type = (flags & INTEL_GUC_CT_SEND_NB) ? GUC_HXG_TYPE_EVENT :
+   type = (flags & INTEL_GUC_CT_SEND_NB) ? GUC_HXG_TYPE_FAST_REQUEST :
GUC_HXG_TYPE_REQUEST;
hxg = FIELD_PREP(GUC_HXG_MSG_0_TYPE, type) |
-   FIELD_PREP(GUC_HXG_EVENT_MSG_0_ACTION |
-  GUC_HXG_EVENT_MSG_0_DATA0, action[0]);
+   FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION |
+  GUC_HXG_REQUEST_MSG_0_DATA0, action[0]);
 
CT_DEBUG(ct, "writing (tail %u) %*ph %*ph %*ph\n",
 tail, 4, , 4, , 

[Intel-gfx] [PATCH] drm/i915/guc: Fix confused register capture list creation

2023-05-11 Thread John . C . Harrison
From: John Harrison 

The GuC has a completely separate engine class enum when referring to
register capture lists, which combines render and compute. The driver
was using the 'normal' GuC specific engine class enum instead. That
meant that it thought it was defining a capture list for compute
engines, the list was actually being applied to the GSC engine. And if
a platform didn't have a render engine, then it would get no compute
register captures at all.

Fix that.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c| 36 ++-
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 61 +--
 drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  9 +++
 3 files changed, 72 insertions(+), 34 deletions(-)

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 69ce06faf8cda..63724e17829a7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c
@@ -643,6 +643,39 @@ static void guc_init_golden_context(struct intel_guc *guc)
GEM_BUG_ON(guc->ads_golden_ctxt_size != total_size);
 }
 
+static u32 guc_get_capture_engine_mask(struct iosys_map *info_map, u32 
capture_class)
+{
+   u32 mask;
+
+   switch (capture_class) {
+   case GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE:
+   mask = info_map_read(info_map, 
engine_enabled_masks[GUC_RENDER_CLASS]);
+   mask |= info_map_read(info_map, 
engine_enabled_masks[GUC_COMPUTE_CLASS]);
+   break;
+
+   case GUC_CAPTURE_LIST_CLASS_VIDEO:
+   mask = info_map_read(info_map, 
engine_enabled_masks[GUC_VIDEO_CLASS]);
+   break;
+
+   case GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE:
+   mask = info_map_read(info_map, 
engine_enabled_masks[GUC_VIDEOENHANCE_CLASS]);
+   break;
+
+   case GUC_CAPTURE_LIST_CLASS_BLITTER:
+   mask = info_map_read(info_map, 
engine_enabled_masks[GUC_BLITTER_CLASS]);
+   break;
+
+   case GUC_CAPTURE_LIST_CLASS_GSC_OTHER:
+   mask = info_map_read(info_map, 
engine_enabled_masks[GUC_GSC_OTHER_CLASS]);
+   break;
+
+   default:
+   mask = 0;
+   }
+
+   return mask;
+}
+
 static int
 guc_capture_prep_lists(struct intel_guc *guc)
 {
@@ -678,9 +711,10 @@ guc_capture_prep_lists(struct intel_guc *guc)
 
for (i = 0; i < GUC_CAPTURE_LIST_INDEX_MAX; i++) {
for (j = 0; j < GUC_MAX_ENGINE_CLASSES; j++) {
+   u32 engine_mask = 
guc_get_capture_engine_mask(_map, j);
 
/* null list if we dont have said engine or list */
-   if (!info_map_read(_map, engine_enabled_masks[j])) 
{
+   if (!engine_mask) {
if (ads_is_mapped) {
ads_blob_write(guc, 
ads.capture_class[i][j], null_ggtt);
ads_blob_write(guc, 
ads.capture_instance[i][j], null_ggtt);
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 1def0b6467c79..0ff864da92dfe 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -174,35 +174,31 @@ static const struct __guc_mmio_reg_descr 
empty_regs_list[] = {
 /* List of lists */
 static const struct __guc_mmio_reg_descr_group gen8_lists[] = {
MAKE_REGLIST(gen8_global_regs, PF, GLOBAL, 0),
-   MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
-   MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
-   MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, GUC_COMPUTE_CLASS),
-   MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_COMPUTE_CLASS),
-   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
-   MAKE_REGLIST(gen8_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEO_CLASS),
-   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEOENHANCE_CLASS),
-   MAKE_REGLIST(gen8_vec_inst_regs, PF, ENGINE_INSTANCE, 
GUC_VIDEOENHANCE_CLASS),
-   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_BLITTER_CLASS),
-   MAKE_REGLIST(gen8_blt_inst_regs, PF, ENGINE_INSTANCE, 
GUC_BLITTER_CLASS),
-   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_GSC_OTHER_CLASS),
-   MAKE_REGLIST(empty_regs_list, PF, ENGINE_INSTANCE, GUC_GSC_OTHER_CLASS),
+   MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, 
GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+   MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, 
GUC_CAPTURE_LIST_CLASS_RENDER_COMPUTE),
+   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, 
GUC_CAPTURE_LIST_CLASS_VIDEO),
+   MAKE_REGLIST(gen8_vd_inst_regs, PF, ENGINE_INSTANCE, 
GUC_CAPTURE_LIST_CLASS_VIDEO),
+   MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, 
GUC_CAPTURE_LIST_CLASS_VIDEOENHANCE),
+   

[Intel-gfx] [PATCH] drm/i1915/guc: Fix probe injection CI failures after recent change

2023-05-10 Thread John . C . Harrison
From: John Harrison 

A recent change bumped a 'notice' message up to 'error' level for
debug builds to help trap incorrect configurations in CI systems.
Unfortunaetly, tha error condition in question is triggered by the
error injection probe test. So change the message again to be 'probe
error' level instead.

Signed-off-by: John Harrison 
Fixes: 760133d42f0a ("drm/i915/uc: Make unexpected firmware versions an error 
in debug builds")
Cc: John Harrison 
Cc: Daniele Ceraolo Spurio 
Cc: Rodrigo Vivi 
Cc: Alan Previn 
Cc: Lucas De Marchi 
Cc: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 4ec7df9ed5ff3..e467d9af61876 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -18,7 +18,7 @@
 #include "i915_reg.h"
 
 #if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
-#define UNEXPECTED gt_err
+#define UNEXPECTED gt_probe_error
 #else
 #define UNEXPECTED gt_notice
 #endif
-- 
2.39.1



[Intel-gfx] [PATCH 1/2] drm/i915/uc: Track patch level versions on reduced version firmware files

2023-05-04 Thread John . C . Harrison
From: John Harrison 

When reduced version firmware files were added (matching major
component being the only strict requirement), the minor version was
still tracked and a notification reported if it was older. However,
the patch version should really be tracked as well for the same
reasons. The KMD can work without the change but if the effort has
been taken to release a new firmware with the change then there must
be a valid reason for doing so - important bug fix, security fix, etc.
And in that case it would be good to alert the user if they are
missing out on that new fix.

v2: Use correct patch version number and drop redunant debug print
(review by Daniele / CI results).

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++-
 1 file changed, 19 insertions(+), 11 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 6b71b9febd74c..55e50bd08d7ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -80,14 +80,14 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
-   fw_def(DG1,  0, guc_maj(dg1,  70, 5)) \
+   fw_def(DG1,  0, guc_maj(dg1,  70, 5, 1)) \
fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(TIGERLAKE,0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \
@@ -141,7 +141,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
 
 /* Minor for internal driver use, not part of file name */
-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
 
 #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
@@ -197,9 +197,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
  .legacy = true }
 
-#define GUC_FW_BLOB(prefix_, major_, minor_) \
-   UC_FW_BLOB_NEW(major_, minor_, 0, false, \
-  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+   UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
 
 #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -296,6 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
uc_fw->file_wanted.path = blob->path;
uc_fw->file_wanted.ver.major = blob->major;
uc_fw->file_wanted.ver.minor = blob->minor;
+   uc_fw->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -794,6 +795,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
} else {
if (uc_fw->file_selected.ver.minor < 
uc_fw->file_wanted.ver.minor)
old_ver = true;
+   else if ((uc_fw->file_selected.ver.minor == 
uc_fw->file_wanted.ver.minor) &&
+(uc_fw->file_selected.ver.patch < 
uc_fw->file_wanted.ver.patch))
+   old_ver = true;
}
}
 
@@ -801,12 +805,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
 
-   gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only 
%s (%d.%d) was found\n",
+   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
  intel_uc_fw_type_repr(uc_fw->type),
  uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.major,
+ uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.patch,

[Intel-gfx] [PATCH 2/2] drm/i915/mtl: Update GuC firmware version for MTL to 70.6.6

2023-05-04 Thread John . C . Harrison
From: John Harrison 

Also switch to using reduced version file naming as it is no longer
such a work-in-progress and likely to change.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 55e50bd08d7ff..10e48cbcf494a 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -79,7 +79,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  * security fixes, etc. to be enabled.
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
-   fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
+   fw_def(METEORLAKE,   0, guc_maj(mtl,  70, 6, 6)) \
fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
-- 
2.39.1



[Intel-gfx] [PATCH 0/2] Update MTL GuC firmware

2023-05-04 Thread John . C . Harrison
From: John Harrison 

Update MTL to the latest GuC release and switch to using reduced
version file names. Also, pull in a patch from an earlier series that
is waiting to merge to prevent merge conflicts later.

Signed-off-by: John Harrison 


John Harrison (2):
  drm/i915/uc: Track patch level versions on reduced version firmware
files
  drm/i915/mtl: Update GuC firmware version for MTL to 70.6.6

 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 32 +++-
 1 file changed, 20 insertions(+), 12 deletions(-)

-- 
2.39.1



[Intel-gfx] PR for new GuC v70.6.6 for MTL

2023-05-03 Thread John . C . Harrison
The following changes since commit 312c61f5a6c9c6a313383a8f0c2b02711ec15262:

  amdgpu: update DCN 3.1.6 DMCUB firmware (2023-05-03 09:11:02 -0400)

are available in the Git repository at:

  git://anongit.freedesktop.org/drm/drm-firmware mtl_guc_70.6.6

for you to fetch changes up to 192ee6d1a7806620eeb6f8478e6a3ec6ea44821c:

  i915: Add GuC v70.6.6 for MTL (2023-05-03 06:45:11 -0700)


John Harrison (1):
  i915: Add GuC v70.6.6 for MTL

 WHENCE  |   3 +++
 i915/mtl_guc_70.bin | Bin 0 -> 303936 bytes
 2 files changed, 3 insertions(+)
 create mode 100644 i915/mtl_guc_70.bin


[Intel-gfx] [PATCH v3 6/6] drm/i915/uc: Make unexpected firmware versions an error in debug builds

2023-05-02 Thread John . C . Harrison
From: John Harrison 

If the DEBUG_GEM config option is set then escalate the 'unexpected
firmware version' message from a notice to an error. This will ensure
that the CI system treats such occurences as a failure and logs a bug
about it (or fails the pre-merge testing).

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 34 ++--
 1 file changed, 20 insertions(+), 14 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 010c049609102..41ebd0ee0bb5e 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -17,6 +17,12 @@
 #include "i915_drv.h"
 #include "i915_reg.h"
 
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+#define UNEXPECTED gt_err
+#else
+#define UNEXPECTED gt_notice
+#endif
+
 static inline struct intel_gt *
 uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
 {
@@ -833,10 +839,10 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
if (uc_fw->file_selected.ver.major != 
uc_fw->file_wanted.ver.major) {
-   gt_notice(gt, "%s firmware %s: unexpected version: 
%u.%u != %u.%u\n",
- intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
+   UNEXPECTED(gt, "%s firmware %s: unexpected version: 
%u.%u != %u.%u\n",
+  intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
+  uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
if (!intel_uc_fw_is_overridden(uc_fw)) {
err = -ENOEXEC;
goto fail;
@@ -854,16 +860,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
 
-   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
- intel_uc_fw_type_repr(uc_fw->type),
- uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major,
- uc_fw->file_wanted.ver.minor,
- uc_fw->file_wanted.ver.patch,
- uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major,
- uc_fw->file_selected.ver.minor,
- uc_fw->file_selected.ver.patch);
+   UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
+  intel_uc_fw_type_repr(uc_fw->type),
+  uc_fw->file_wanted.path,
+  uc_fw->file_wanted.ver.major,
+  uc_fw->file_wanted.ver.minor,
+  uc_fw->file_wanted.ver.patch,
+  uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major,
+  uc_fw->file_selected.ver.minor,
+  uc_fw->file_selected.ver.patch);
gt_info(gt, "Consider updating your linux-firmware pkg or 
downloading from %s\n",
INTEL_UC_FIRMWARE_URL);
}
-- 
2.39.1



[Intel-gfx] [PATCH v3 2/6] drm/i915/guc: Print status register when waiting for GuC to load

2023-05-02 Thread John . C . Harrison
From: John Harrison 

If the GuC load is taking an excessively long time, the wait loop
currently prints the GT frequency. Extend that to include the GuC
status as well so we can see if the GuC is actually making progress or
not.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

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 0ff088a5e51a8..364d0d546ec82 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -191,8 +191,10 @@ static int guc_wait_ucode(struct intel_guc *guc)
if (!ret || !success)
break;
 
-   guc_dbg(guc, "load still in progress, count = %d, freq = 
%dMHz\n",
-   count, 
intel_rps_read_actual_frequency(>gt->rps));
+   guc_dbg(guc, "load still in progress, count = %d, freq = %dMHz, 
status = 0x%08X [0x%02X/%02X]\n",
+   count, 
intel_rps_read_actual_frequency(>gt->rps), status,
+   REG_FIELD_GET(GS_BOOTROM_MASK, status),
+   REG_FIELD_GET(GS_UKERNEL_MASK, status));
}
after = ktime_get();
delta = ktime_sub(after, before);
-- 
2.39.1



[Intel-gfx] [PATCH v3 5/6] drm/i915/uc: Reject duplicate entries in firmware table

2023-05-02 Thread John . C . Harrison
From: John Harrison 

It was noticed that duplicate entries in the firmware table could cause
an infinite loop in the firmware loading code if that entry failed to
load. Duplicate entries are a bug anyway and so should never happen.
Ensure they don't by tweaking the table validation code to reject
duplicates.

For full m/m/p files, that can be done by simply tweaking the patch
level check to reject matching values. For reduced version entries,
the filename itself must be compared.

v2: Improve comment (review by Daniele)

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 26 +---
 1 file changed, 23 insertions(+), 3 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 64e19688788d1..010c049609102 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -319,7 +319,7 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
 {
const struct uc_fw_platform_requirement *fw_blobs;
u32 fw_count;
-   int i;
+   int i, j;
 
if (type >= ARRAY_SIZE(blobs_all)) {
drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
@@ -334,6 +334,26 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
 
/* make sure the list is ordered as expected */
for (i = 1; i < fw_count; i++) {
+   /* Versionless file names must be unique per platform: */
+   for (j = i + 1; j < fw_count; j++) {
+   /* Same platform? */
+   if (fw_blobs[i].p != fw_blobs[j].p)
+   continue;
+
+   if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
+   continue;
+
+   drm_err(>drm, "Duplicate %s blobs: %s r%u 
%s%d.%d.%d [%s] matches %s%d.%d.%d [%s]\n",
+   intel_uc_fw_type_repr(type),
+   intel_platform_name(fw_blobs[j].p), 
fw_blobs[j].rev,
+   fw_blobs[j].blob.legacy ? "L" : "v",
+   fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+   fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+   fw_blobs[i].blob.legacy ? "L" : "v",
+   fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+   fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+   }
+
/* Next platform is good: */
if (fw_blobs[i].p < fw_blobs[i - 1].p)
continue;
@@ -377,8 +397,8 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
goto bad;
 
-   /* Patch versions must be in order: */
-   if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+   /* Patch versions must be in order and unique: */
+   if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
continue;
 
 bad:
-- 
2.39.1



[Intel-gfx] [PATCH v3 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-05-02 Thread John . C . Harrison
From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. Which is
unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver load
on detecting of a problem ensures that such backports will also be
validated correctly.

This requires adding a firmware global flag to indicate an issue with
any of the per firmware tables. This is done rather than adding a new
state enum as a new enum value would be a much more invasive change -
lots of places would need updating to support the new error state.

Note also that this change means that a table error will cause the
driver to wedge even on platforms that don't require firmware files.
This is intentional as per the above backport concern - someone doing
backports is not guaranteed to test on every platform that they may
potential affect. So forcing a failure on all platforms ensures that
the problem will be noticed and corrected immediately.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).
v3: Add a new flag to track table validation errors (review
feedback/discussion with Daniele).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc.c|   3 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.h|   1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 161 +--
 3 files changed, 99 insertions(+), 66 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
index 996168312340e..1381943b8973d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
@@ -432,6 +432,9 @@ static bool uc_is_wopcm_locked(struct intel_uc *uc)
 
 static int __uc_check_hw(struct intel_uc *uc)
 {
+   if (uc->fw_table_invalid)
+   return -EIO;
+
if (!intel_uc_supports_guc(uc))
return 0;
 
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.h 
b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
index 5d0f1bcc381e8..d585524d94deb 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.h
@@ -36,6 +36,7 @@ struct intel_uc {
struct drm_i915_gem_object *load_err_log;
 
bool reset_in_progress;
+   bool fw_table_invalid;
 };
 
 void intel_uc_init_early(struct intel_uc *uc);
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 55e50bd08d7ff..64e19688788d1 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
u32 count;
 };
 
+static const struct uc_fw_platform_requirement blobs_guc[] = {
+   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
+};
+
+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 void
 __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 {
-   static const struct uc_fw_platform_requirement blobs_guc[] = {
-   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)
-   };
-   static const struct uc_fw_platform_requirement blobs_huc[] = {
-   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
-   };
-   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 bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
continue;
 
if (uc_fw->file_selected.path) {
+   /*
+* Continuing an earlier search after a found blob 
failed to load.
+* Once the previously chosen path has been found, 
clear it out
+* and let the search continue from there.
+*/
if (uc_fw->file_selected.path == blob->path)
 

[Intel-gfx] [PATCH v3 3/6] drm/i915/uc: Track patch level versions on reduced version firmware files

2023-05-02 Thread John . C . Harrison
From: John Harrison 

When reduced version firmware files were added (matching major
component being the only strict requirement), the minor version was
still tracked and a notification reported if it was older. However,
the patch version should really be tracked as well for the same
reasons. The KMD can work without the change but if the effort has
been taken to release a new firmware with the change then there must
be a valid reason for doing so - important bug fix, security fix, etc.
And in that case it would be good to alert the user if they are
missing out on that new fix.

v2: Use correct patch version number and drop redunant debug print
(review by Daniele / CI results).

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++-
 1 file changed, 19 insertions(+), 11 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 6b71b9febd74c..55e50bd08d7ff 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -80,14 +80,14 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
-   fw_def(DG1,  0, guc_maj(dg1,  70, 5)) \
+   fw_def(DG1,  0, guc_maj(dg1,  70, 5, 1)) \
fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(TIGERLAKE,0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \
@@ -141,7 +141,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
 
 /* Minor for internal driver use, not part of file name */
-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
 
 #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
@@ -197,9 +197,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
  .legacy = true }
 
-#define GUC_FW_BLOB(prefix_, major_, minor_) \
-   UC_FW_BLOB_NEW(major_, minor_, 0, false, \
-  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+   UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
 
 #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -296,6 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
uc_fw->file_wanted.path = blob->path;
uc_fw->file_wanted.ver.major = blob->major;
uc_fw->file_wanted.ver.minor = blob->minor;
+   uc_fw->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -794,6 +795,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
} else {
if (uc_fw->file_selected.ver.minor < 
uc_fw->file_wanted.ver.minor)
old_ver = true;
+   else if ((uc_fw->file_selected.ver.minor == 
uc_fw->file_wanted.ver.minor) &&
+(uc_fw->file_selected.ver.patch < 
uc_fw->file_wanted.ver.patch))
+   old_ver = true;
}
}
 
@@ -801,12 +805,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
 
-   gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only 
%s (%d.%d) was found\n",
+   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
  intel_uc_fw_type_repr(uc_fw->type),
  uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.major,
+ uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.patch,

[Intel-gfx] [PATCH v3 0/6] Improvements to uc firmare management

2023-05-02 Thread John . C . Harrison
From: John Harrison 

Enhance the firmware table verification code to catch more potential
errors and to generally improve the code itself.

Track patch level version even on reduced version files to allow user
notification of missing bug fixes.

Detect another immediate failure case when loading GuC firmware.

Treat more problems as fatal errors, at least for DEBUG builds.

v2: Use correct patch version number, drop redundant debug print
fail load on table validation error (review by Daniele / CI results).
v3: Fix spelling typos, use a new bool for invalid firmware tables
rather than a status enum (review feedback from Daniele).

Signed-off-by: John Harrison 


John Harrison (6):
  drm/i915/guc: Decode another GuC load failure case
  drm/i915/guc: Print status register when waiting for GuC to load
  drm/i915/uc: Track patch level versions on reduced version firmware
files
  drm/i915/uc: Enhancements to firmware table validation
  drm/i915/uc: Reject duplicate entries in firmware table
  drm/i915/uc: Make unexpected firmware versions an error in debug
builds

 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  12 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc.c |   3 +
 drivers/gpu/drm/i915/gt/uc/intel_uc.h |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 227 +++---
 5 files changed, 160 insertions(+), 84 deletions(-)

-- 
2.39.1



[Intel-gfx] [PATCH v3 1/6] drm/i915/guc: Decode another GuC load failure case

2023-05-02 Thread John . C . Harrison
From: John Harrison 

Explain another potential firmware failure mode and early exit the
long wait if hit.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c   | 6 ++
 2 files changed, 7 insertions(+)

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 bcb1129b36102..dabeaf4f245f3 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
@@ -44,6 +44,7 @@ enum intel_guc_load_status {
 enum intel_bootrom_load_status {
INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND   = 0x1A,
+   INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE   = 0x2B,
INTEL_BOOTROM_STATUS_RSA_FAILED   = 0x50,
INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
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 6fda3aec5c66a..0ff088a5e51a8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -129,6 +129,7 @@ static inline bool guc_load_done(struct intel_uncore 
*uncore, u32 *status, bool
case INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED:
case INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT:
case INTEL_BOOTROM_STATUS_EXCEPTION:
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
*success = false;
return true;
}
@@ -219,6 +220,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_info(guc, "firmware signature verification 
failed\n");
ret = -ENOEXEC;
break;
+
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
+   guc_info(guc, "firmware production part check 
failure\n");
+   ret = -ENOEXEC;
+   break;
}
 
switch (ukernel) {
-- 
2.39.1



[Intel-gfx] [PATCH v2 3/4] drm/i915/guc: Capture list naming clean up

2023-04-28 Thread John . C . Harrison
From: John Harrison 

Don't use 'xe_lp*' prefixes for register lists that are common with
Gen8.

Don't add Xe only GSC registers to pre-Xe devices that don't
even have a GSC engine.

Fix Xe_LP name.

Don't use GEN9 as a prefix for register lists that contain all GEN8
registers.

Rename the 'default_' register list prefix to 'gen8_' as that is the
more accurate name.

Signed-off-by: John Harrison 
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 100 +-
 1 file changed, 49 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 9184d2595e4ce..729a8fcf20dda 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -30,12 +30,12 @@
 #define COMMON_BASE_GLOBAL \
{ FORCEWAKE_MT, 0,  0, "FORCEWAKE" }
 
-#define COMMON_GEN9BASE_GLOBAL \
+#define COMMON_GEN8BASE_GLOBAL \
{ ERROR_GEN6,   0,  0, "ERROR_GEN6" }, \
{ DONE_REG, 0,  0, "DONE_REG" }, \
{ HSW_GTT_CACHE_EN, 0,  0, "HSW_GTT_CACHE_EN" }
 
-#define GEN9_GLOBAL \
+#define GEN8_GLOBAL \
{ GEN8_FAULT_TLB_DATA0, 0,  0, "GEN8_FAULT_TLB_DATA0" }, \
{ GEN8_FAULT_TLB_DATA1, 0,  0, "GEN8_FAULT_TLB_DATA1" }
 
@@ -96,67 +96,65 @@
{ GEN12_SFC_DONE(2),0,  0, "SFC_DONE[2]" }, \
{ GEN12_SFC_DONE(3),0,  0, "SFC_DONE[3]" }
 
-/* XE_LPD - Global */
-static const struct __guc_mmio_reg_descr xe_lpd_global_regs[] = {
+/* XE_LP Global */
+static const struct __guc_mmio_reg_descr xe_lp_global_regs[] = {
COMMON_BASE_GLOBAL,
-   COMMON_GEN9BASE_GLOBAL,
+   COMMON_GEN8BASE_GLOBAL,
COMMON_GEN12BASE_GLOBAL,
 };
 
-/* XE_LPD - Render / Compute Per-Class */
-static const struct __guc_mmio_reg_descr xe_lpd_rc_class_regs[] = {
+/* XE_LP Render / Compute Per-Class */
+static const struct __guc_mmio_reg_descr xe_lp_rc_class_regs[] = {
COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
COMMON_GEN12BASE_RENDER,
 };
 
-/* GEN9/XE_LPD - Render / Compute Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_rc_inst_regs[] = {
+/* GEN8+ Render / Compute Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_rc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
 };
 
-/* GEN9/XE_LPD - Media Decode/Encode Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_vd_inst_regs[] = {
+/* GEN8+ Media Decode/Encode Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_vd_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
 };
 
-/* XE_LPD - Video Enhancement Per-Class */
-static const struct __guc_mmio_reg_descr xe_lpd_vec_class_regs[] = {
+/* XE_LP Video Enhancement Per-Class */
+static const struct __guc_mmio_reg_descr xe_lp_vec_class_regs[] = {
COMMON_GEN12BASE_VEC,
 };
 
-/* GEN9/XE_LPD - Video Enhancement Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_vec_inst_regs[] = {
+/* GEN8+ Video Enhancement Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_vec_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
 };
 
-/* GEN9/XE_LPD - Blitter Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_blt_inst_regs[] = {
+/* GEN8+ Blitter Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr gen8_blt_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
 };
 
-/* XE_LPD - GSC Per-Engine-Instance */
-static const struct __guc_mmio_reg_descr xe_lpd_gsc_inst_regs[] = {
+/* XE_LP - GSC Per-Engine-Instance */
+static const struct __guc_mmio_reg_descr xe_lp_gsc_inst_regs[] = {
COMMON_BASE_ENGINE_INSTANCE,
 };
 
-/* GEN9 - Global */
-static const struct __guc_mmio_reg_descr default_global_regs[] = {
+/* GEN8 - Global */
+static const struct __guc_mmio_reg_descr gen8_global_regs[] = {
COMMON_BASE_GLOBAL,
-   COMMON_GEN9BASE_GLOBAL,
-   GEN9_GLOBAL,
+   COMMON_GEN8BASE_GLOBAL,
+   GEN8_GLOBAL,
 };
 
-static const struct __guc_mmio_reg_descr default_rc_class_regs[] = {
+static const struct __guc_mmio_reg_descr gen8_rc_class_regs[] = {
COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
 };
 
 /*
- * Empty lists:
- * GEN9/XE_LPD - Blitter Per-Class
- * GEN9/XE_LPD - Media Decode/Encode Per-Class
- * GEN9 - VEC Class
+ * Empty list to prevent warnings about unknown class/instance types
+ * as not all class/instanace types have entries on all platforms.
  */
 static const struct __guc_mmio_reg_descr empty_regs_list[] = {
 };
@@ -174,37 +172,37 @@ static const struct __guc_mmio_reg_descr 
empty_regs_list[] = {
}
 
 /* List of lists */
-static const struct __guc_mmio_reg_descr_group default_lists[] = {
-   MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
-   MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
-   

[Intel-gfx] [PATCH v2 0/4] Improvements to GuC error capture

2023-04-28 Thread John . C . Harrison
From: John Harrison 

The GuC error capture list creation was including Gen8 registers on Xe
platforms. While fixing that, it was noticed that there were other
issues. The platform naming was wrong, the naming of lists was
misleading, the steered register code was duplicated and steered
registers were not included on all supported platforms.

Separately, it was noticed that the capture list search was broken for
virtual engines. So fix that up too.

v2: Swuash the split patches into a single patch ready for merge.
Also include an extra patch about capture lists and virtual engines.

Signed-off-by: John Harrison 


John Harrison (4):
  drm/i915/guc: Don't capture Gen8 regs on Xe devices
  drm/i915/guc: Consolidate duplicated capture list code
  drm/i915/guc: Capture list naming clean up
  drm/i915/guc: Fix error capture for virtual engines

 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 242 --
 .../gpu/drm/i915/gt/uc/intel_guc_capture.h|   3 +
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c |  32 ++-
 drivers/gpu/drm/i915/i915_gpu_error.c |  11 +-
 4 files changed, 149 insertions(+), 139 deletions(-)

-- 
2.39.1



[Intel-gfx] [PATCH v2 1/4] drm/i915/guc: Don't capture Gen8 regs on Xe devices

2023-04-28 Thread John . C . Harrison
From: John Harrison 

A pair of pre-Xe registers were being included in the Xe capture list.
GuC was rejecting those as being invalid and logging errors about
them. So, stop doing it.

Signed-off-by: John Harrison 
Reviewed-by: Alan Previn 
Fixes: dce2bd542337 ("drm/i915/guc: Add Gen9 registers for GuC error state 
capture.")
Cc: Alan Previn 
Cc: Umesh Nerlige Ramappa 
Cc: Lucas De Marchi 
Cc: John Harrison 
Cc: Jani Nikula 
Cc: Matt Roper 
Cc: Balasubramani Vivekanandan 
Cc: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index cf49188db6a6e..e0e793167d61b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -31,12 +31,14 @@
{ FORCEWAKE_MT, 0,  0, "FORCEWAKE" }
 
 #define COMMON_GEN9BASE_GLOBAL \
-   { GEN8_FAULT_TLB_DATA0, 0,  0, "GEN8_FAULT_TLB_DATA0" }, \
-   { GEN8_FAULT_TLB_DATA1, 0,  0, "GEN8_FAULT_TLB_DATA1" }, \
{ ERROR_GEN6,   0,  0, "ERROR_GEN6" }, \
{ DONE_REG, 0,  0, "DONE_REG" }, \
{ HSW_GTT_CACHE_EN, 0,  0, "HSW_GTT_CACHE_EN" }
 
+#define GEN9_GLOBAL \
+   { GEN8_FAULT_TLB_DATA0, 0,  0, "GEN8_FAULT_TLB_DATA0" }, \
+   { GEN8_FAULT_TLB_DATA1, 0,  0, "GEN8_FAULT_TLB_DATA1" }
+
 #define COMMON_GEN12BASE_GLOBAL \
{ GEN12_FAULT_TLB_DATA0,0,  0, "GEN12_FAULT_TLB_DATA0" }, \
{ GEN12_FAULT_TLB_DATA1,0,  0, "GEN12_FAULT_TLB_DATA1" }, \
@@ -142,6 +144,7 @@ static const struct __guc_mmio_reg_descr 
xe_lpd_gsc_inst_regs[] = {
 static const struct __guc_mmio_reg_descr default_global_regs[] = {
COMMON_BASE_GLOBAL,
COMMON_GEN9BASE_GLOBAL,
+   GEN9_GLOBAL,
 };
 
 static const struct __guc_mmio_reg_descr default_rc_class_regs[] = {
-- 
2.39.1



[Intel-gfx] [PATCH v2 2/4] drm/i915/guc: Consolidate duplicated capture list code

2023-04-28 Thread John . C . Harrison
From: John Harrison 

Remove 99% duplicated steered register list code. Also, include the
pre-Xe steered registers in the pre-Xe list generation.

Signed-off-by: John Harrison 
Reviewed-by: Alan Previn 
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 112 +-
 1 file changed, 29 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index e0e793167d61b..9184d2595e4ce 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -260,11 +260,15 @@ struct __ext_steer_reg {
i915_mcr_reg_t reg;
 };
 
-static const struct __ext_steer_reg xe_extregs[] = {
+static const struct __ext_steer_reg gen8_extregs[] = {
{"GEN8_SAMPLER_INSTDONE", GEN8_SAMPLER_INSTDONE},
{"GEN8_ROW_INSTDONE", GEN8_ROW_INSTDONE}
 };
 
+static const struct __ext_steer_reg xehpg_extregs[] = {
+   {"XEHPG_INSTDONE_GEOM_SVG", XEHPG_INSTDONE_GEOM_SVG}
+};
+
 static void __fill_ext_reg(struct __guc_mmio_reg_descr *ext,
   const struct __ext_steer_reg *extlist,
   int slice_id, int subslice_id)
@@ -295,8 +299,8 @@ __alloc_ext_regs(struct __guc_mmio_reg_descr_group *newlist,
 }
 
 static void
-guc_capture_alloc_steered_lists_xe_lpd(struct intel_guc *guc,
-  const struct __guc_mmio_reg_descr_group 
*lists)
+guc_capture_alloc_steered_lists(struct intel_guc *guc,
+   const struct __guc_mmio_reg_descr_group *lists)
 {
struct intel_gt *gt = guc_to_gt(guc);
int slice, subslice, iter, i, num_steer_regs, num_tot_regs = 0;
@@ -304,74 +308,19 @@ guc_capture_alloc_steered_lists_xe_lpd(struct intel_guc 
*guc,
struct __guc_mmio_reg_descr_group *extlists;
struct __guc_mmio_reg_descr *extarray;
struct sseu_dev_info *sseu;
+   bool has_xehpg_extregs;
 
-   /* In XE_LPD we only have steered registers for the render-class */
+   /* steered registers currently only exist for the render-class */
list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF,
GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, 
GUC_RENDER_CLASS);
/* skip if extlists was previously allocated */
if (!list || guc->capture->extlists)
return;
 
-   num_steer_regs = ARRAY_SIZE(xe_extregs);
-
-   sseu = >info.sseu;
-   for_each_ss_steering(iter, gt, slice, subslice)
-   num_tot_regs += num_steer_regs;
-
-   if (!num_tot_regs)
-   return;
-
-   /* allocate an extra for an end marker */
-   extlists = kcalloc(2, sizeof(struct __guc_mmio_reg_descr_group), 
GFP_KERNEL);
-   if (!extlists)
-   return;
-
-   if (__alloc_ext_regs([0], list, num_tot_regs)) {
-   kfree(extlists);
-   return;
-   }
-
-   extarray = extlists[0].extlist;
-   for_each_ss_steering(iter, gt, slice, subslice) {
-   for (i = 0; i < num_steer_regs; ++i) {
-   __fill_ext_reg(extarray, _extregs[i], slice, 
subslice);
-   ++extarray;
-   }
-   }
-
-   guc->capture->extlists = extlists;
-}
-
-static const struct __ext_steer_reg xehpg_extregs[] = {
-   {"XEHPG_INSTDONE_GEOM_SVG", XEHPG_INSTDONE_GEOM_SVG}
-};
-
-static bool __has_xehpg_extregs(u32 ipver)
-{
-   return (ipver >= IP_VER(12, 55));
-}
-
-static void
-guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc *guc,
-  const struct __guc_mmio_reg_descr_group 
*lists,
-  u32 ipver)
-{
-   struct intel_gt *gt = guc_to_gt(guc);
-   struct sseu_dev_info *sseu;
-   int slice, subslice, i, iter, num_steer_regs, num_tot_regs = 0;
-   const struct __guc_mmio_reg_descr_group *list;
-   struct __guc_mmio_reg_descr_group *extlists;
-   struct __guc_mmio_reg_descr *extarray;
-
-   /* In XE_LP / HPG we only have render-class steering registers during 
error-capture */
-   list = guc_capture_get_one_list(lists, GUC_CAPTURE_LIST_INDEX_PF,
-   GUC_CAPTURE_LIST_TYPE_ENGINE_CLASS, 
GUC_RENDER_CLASS);
-   /* skip if extlists was previously allocated */
-   if (!list || guc->capture->extlists)
-   return;
+   has_xehpg_extregs = GRAPHICS_VER_FULL(gt->i915) >= IP_VER(12, 55);
 
-   num_steer_regs = ARRAY_SIZE(xe_extregs);
-   if (__has_xehpg_extregs(ipver))
+   num_steer_regs = ARRAY_SIZE(gen8_extregs);
+   if (has_xehpg_extregs)
num_steer_regs += ARRAY_SIZE(xehpg_extregs);
 
sseu = >info.sseu;
@@ -393,11 +342,12 @@ guc_capture_alloc_steered_lists_xe_hpg(struct intel_guc 
*guc,
 
extarray = extlists[0].extlist;
for_each_ss_steering(iter, gt, slice, subslice) {
-   for (i = 0; i 

[Intel-gfx] [PATCH v2 4/4] drm/i915/guc: Fix error capture for virtual engines

2023-04-28 Thread John . C . Harrison
From: John Harrison 

GuC based register dumps in error capture logs were basically broken
for virtual engines. This can be seen in igt@gem_exec_balancer@hang:
  [IGT] gem_exec_balancer: starting subtest hang
  [drm] GPU HANG: ecode 12:4:e1524110, in gem_exec_balanc [6388]
  [drm] GT0: GUC: No register capture node found for 0x1005 / 0xFEDC311D
  [drm] GPU HANG: ecode 12:4:, in gem_exec_balanc [6388]
  [IGT] gem_exec_balancer: exiting, ret=0

The test causes a hang on both engines of a virtual engine context.
The engine instance zero hang gets a valid error capture but the
non-instance-zero hang does not.

Fix that by scanning through the list of pending register captures
when a hang notification for a virtual engine is received. That way,
the hang can be assigned to the correct physical engine prior to
starting the error capture process. So later on, when the error capture
handler tries to find the engine register list, it looks for one on
the correct engine.

Also, sneak in a missing blank line before a comment in the node
search code.

v2: Fix null pointer deref on non-GuC platforms.

Signed-off-by: John Harrison 
Reviewed-by: Alan Previn 
---
 .../gpu/drm/i915/gt/uc/intel_guc_capture.c| 31 ++
 .../gpu/drm/i915/gt/uc/intel_guc_capture.h|  3 ++
 .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 32 ---
 drivers/gpu/drm/i915/i915_gpu_error.c | 11 +--
 4 files changed, 70 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index 729a8fcf20dda..1def0b6467c79 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -1540,6 +1540,36 @@ void intel_guc_capture_free_node(struct 
intel_engine_coredump *ee)
ee->guc_capture_node = NULL;
 }
 
+bool intel_guc_capture_is_matching_engine(struct intel_gt *gt,
+ struct intel_context *ce,
+ struct intel_engine_cs *engine)
+{
+   struct __guc_capture_parsed_output *n;
+   struct intel_guc *guc;
+
+   if (!gt || !ce || !engine)
+   return false;
+
+   guc = >uc.guc;
+   if (!guc->capture)
+   return false;
+
+   /*
+* Look for a matching GuC reported error capture node from
+* the internal output link-list based on lrca, guc-id and engine
+* identification.
+*/
+   list_for_each_entry(n, >capture->outlist, link) {
+   if (n->eng_inst == GUC_ID_TO_ENGINE_INSTANCE(engine->guc_id) &&
+   n->eng_class == GUC_ID_TO_ENGINE_CLASS(engine->guc_id) &&
+   n->guc_id == ce->guc_id.id &&
+   (n->lrca & CTX_GTT_ADDRESS_MASK) == (ce->lrc.lrca & 
CTX_GTT_ADDRESS_MASK))
+   return true;
+   }
+
+   return false;
+}
+
 void intel_guc_capture_get_matching_node(struct intel_gt *gt,
 struct intel_engine_coredump *ee,
 struct intel_context *ce)
@@ -1555,6 +1585,7 @@ void intel_guc_capture_get_matching_node(struct intel_gt 
*gt,
return;
 
GEM_BUG_ON(ee->guc_capture_node);
+
/*
 * Look for a matching GuC reported error capture node from
 * the internal output link-list based on lrca, guc-id and engine
diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
index fbd3713c7832d..302256d45431d 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.h
@@ -11,6 +11,7 @@
 struct drm_i915_error_state_buf;
 struct guc_gt_system_info;
 struct intel_engine_coredump;
+struct intel_engine_cs;
 struct intel_context;
 struct intel_gt;
 struct intel_guc;
@@ -20,6 +21,8 @@ int intel_guc_capture_print_engine_node(struct 
drm_i915_error_state_buf *m,
const struct intel_engine_coredump *ee);
 void intel_guc_capture_get_matching_node(struct intel_gt *gt, struct 
intel_engine_coredump *ee,
 struct intel_context *ce);
+bool intel_guc_capture_is_matching_engine(struct intel_gt *gt, struct 
intel_context *ce,
+ struct intel_engine_cs *engine);
 void intel_guc_capture_process(struct intel_guc *guc);
 int intel_guc_capture_getlist(struct intel_guc *guc, u32 owner, u32 type, u32 
classid,
  void **outptr);
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 ee3e8352637f2..b93fe27b4eaae 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -4697,13 +4697,37 @@ static void capture_error_state(struct intel_guc *guc,
 {
struct intel_gt *gt = 

[Intel-gfx] [PATCH 6/6] drm/i915/guc: Capture list clean up - 5

2023-04-26 Thread John . C . Harrison
From: John Harrison 

Rename the 'default_' register list prefix to 'gen8_' as that is the
more accurate name.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c 
b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
index c1a75a2d17f1e..729a8fcf20dda 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c
@@ -141,13 +141,13 @@ static const struct __guc_mmio_reg_descr 
xe_lp_gsc_inst_regs[] = {
 };
 
 /* GEN8 - Global */
-static const struct __guc_mmio_reg_descr default_global_regs[] = {
+static const struct __guc_mmio_reg_descr gen8_global_regs[] = {
COMMON_BASE_GLOBAL,
COMMON_GEN8BASE_GLOBAL,
GEN8_GLOBAL,
 };
 
-static const struct __guc_mmio_reg_descr default_rc_class_regs[] = {
+static const struct __guc_mmio_reg_descr gen8_rc_class_regs[] = {
COMMON_BASE_HAS_EU,
COMMON_BASE_RENDER,
 };
@@ -172,11 +172,11 @@ static const struct __guc_mmio_reg_descr 
empty_regs_list[] = {
}
 
 /* List of lists */
-static const struct __guc_mmio_reg_descr_group default_lists[] = {
-   MAKE_REGLIST(default_global_regs, PF, GLOBAL, 0),
-   MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
+static const struct __guc_mmio_reg_descr_group gen8_lists[] = {
+   MAKE_REGLIST(gen8_global_regs, PF, GLOBAL, 0),
+   MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, GUC_RENDER_CLASS),
MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_RENDER_CLASS),
-   MAKE_REGLIST(default_rc_class_regs, PF, ENGINE_CLASS, 
GUC_COMPUTE_CLASS),
+   MAKE_REGLIST(gen8_rc_class_regs, PF, ENGINE_CLASS, GUC_COMPUTE_CLASS),
MAKE_REGLIST(gen8_rc_inst_regs, PF, ENGINE_INSTANCE, GUC_COMPUTE_CLASS),
MAKE_REGLIST(empty_regs_list, PF, ENGINE_CLASS, GUC_VIDEO_CLASS),
MAKE_REGLIST(gen8_vd_inst_regs, PF, ENGINE_INSTANCE, GUC_VIDEO_CLASS),
@@ -366,7 +366,7 @@ guc_capture_get_device_reglist(struct intel_guc *guc)
if (GRAPHICS_VER(i915) >= 12)
lists = xe_lp_lists;
else
-   lists = default_lists;
+   lists = gen8_lists;
 
/*
 * For certain engine classes, there are slice and subslice
-- 
2.39.1



[Intel-gfx] [PATCH i-g-t 1/2] lib/intel_decode: Decode Gen12 ring/batch instructions correctly

2023-04-25 Thread John . C . Harrison
From: John Harrison 

Some MI_ instructions have changed (or are just new) for Gen12. So
update the decoder code to match.

Signed-off-by: John Harrison 
---
 lib/i915/intel_decode.c | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/lib/i915/intel_decode.c b/lib/i915/intel_decode.c
index 80b92d90c61c..1b6de5edafad 100644
--- a/lib/i915/intel_decode.c
+++ b/lib/i915/intel_decode.c
@@ -236,7 +236,7 @@ decode_mi(struct intel_decode *ctx)
{ 0x08, 0, 1, 1, "MI_ARB_ON_OFF" },
{ 0x0a, 0, 1, 1, "MI_BATCH_BUFFER_END" },
{ 0x30, 0x3f, 3, 3, "MI_BATCH_BUFFER" },
-   { 0x31, 0x3f, 2, 2, "MI_BATCH_BUFFER_START" },
+   { 0x31, 0x3f, 2, 3, "MI_BATCH_BUFFER_START" },
{ 0x14, 0x3f, 3, 3, "MI_DISPLAY_BUFFER_INFO" },
{ 0x04, 0, 1, 1, "MI_FLUSH" },
{ 0x22, 0x1f, 3, 3, "MI_LOAD_REGISTER_IMM" },
@@ -256,6 +256,7 @@ decode_mi(struct intel_decode *ctx)
{ 0x28, 0x3f, 3, 3, "MI_REPORT_PERF_COUNT" },
{ 0x29, 0xff, 3, 3, "MI_LOAD_REGISTER_MEM" },
{ 0x0b, 0, 1, 1, "MI_SUSPEND_FLUSH"},
+   { 0x05, 0, 1, 1, "MI_ARB_CHECK"},
}, *opcode_mi = NULL;
 
/* check instruction length */
@@ -3623,7 +3624,17 @@ decode_3d_965(struct intel_decode *ctx)
return len;
 
case 0x7a00:
-   if (IS_GEN6(devid) || IS_GEN7(devid)) {
+   if (IS_GEN12(devid)) {
+   if (len != 6)
+   fprintf(out, "Bad count in PIPE_CONTROL\n");
+   instr_out(ctx, 0, "PIPE_CONTROL\n");
+   instr_out(ctx, 1, "flags\n");
+   instr_out(ctx, 2, "write address low\n");
+   instr_out(ctx, 3, "write address high\n");
+   instr_out(ctx, 4, "write data low\n");
+   instr_out(ctx, 5, "write data high\n");
+   return len;
+   } else if (IS_GEN6(devid) || IS_GEN7(devid)) {
if (len != 4 && len != 5)
fprintf(out, "Bad count in PIPE_CONTROL\n");
 
-- 
2.39.1



[Intel-gfx] [PATCH i-g-t 0/2] Update intel_error_decode for Gen12

2023-04-25 Thread John . C . Harrison
From: John Harrison 

The error capture decoder was reporting invalid errors in batch
buffers and getting confused about the prescence of the GuC CTB. So
fix those up.

Signed-off-by: John Harrison 


John Harrison (2):
  lib/intel_decode: Decode Gen12 ring/batch instructions correctly
  tools/intel_error_decode: Correctly name the GuC CT buffer

 lib/i915/intel_decode.c| 15 +--
 tools/intel_error_decode.c |  1 +
 2 files changed, 14 insertions(+), 2 deletions(-)

-- 
2.39.1



[Intel-gfx] [PATCH i-g-t 2/2] tools/intel_error_decode: Correctly name the GuC CT buffer

2023-04-25 Thread John . C . Harrison
From: John Harrison 

The buffer decoding code doesn't cope well with unknown buffers. So
add an entry for the GuC CTB so that it gets decoded correctly.

Signed-off-by: John Harrison 
---
 tools/intel_error_decode.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/intel_error_decode.c b/tools/intel_error_decode.c
index 99680bedc785..451608826be3 100644
--- a/tools/intel_error_decode.c
+++ b/tools/intel_error_decode.c
@@ -617,6 +617,7 @@ read_data_file(FILE *file)
{ "user", "user", 0 },
{ "semaphores", "semaphores", 0 },
{ "guc log buffer", "GuC log", 0 },
+   { "guc ct buffer", "GuC CTB", 0 },
{ },
}, *b;
char *new_ring_name;
-- 
2.39.1



[Intel-gfx] [PATCH] drm/i915/guc: Actually return an error if GuC version range check fails

2023-04-21 Thread John . C . Harrison
From: John Harrison 

Dan Carpenter pointed out that 'err' was not being set in the case
where the GuC firmware version range check fails. Fix that.

Note that while this is bug fix for a previous patch (see Fixes tag
below). It is an exceedingly low risk bug. The range check is
asserting that the GuC firmware version is within spec. So it should
not be possible to ever have a firmware file that fails this check. If
larger version numbers are required in the future, that would be a
backwards breaking spec change and thus require a major version bump,
in which case an old i915 driver would not load that new version anyway.

Fixes: 9bbba0667f37 ("drm/i915/guc: Use GuC submission API version number")
Reported-by: Dan Carpenter 
Signed-off-by: John Harrison 
Cc: John Harrison 
Cc: Daniele Ceraolo Spurio 
Cc: Alan Previn 
Cc: Umesh Nerlige Ramappa 
Cc: Rodrigo Vivi 
Cc: Matthew Brost 
Cc: Andi Shyti 
Cc: Matthew Auld 
Cc: Tvrtko Ursulin 
Cc: Lucas De Marchi 
Cc: Jani Nikula 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 20 
 1 file changed, 12 insertions(+), 8 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 a82a53dbbc86d..6b71b9febd74c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -636,9 +636,10 @@ static bool is_ver_8bit(struct intel_uc_fw_ver *ver)
return ver->major < 0xFF && ver->minor < 0xFF && ver->patch < 0xFF;
 }
 
-static bool guc_check_version_range(struct intel_uc_fw *uc_fw)
+static int guc_check_version_range(struct intel_uc_fw *uc_fw)
 {
struct intel_guc *guc = container_of(uc_fw, struct intel_guc, fw);
+   struct intel_gt *gt = __uc_fw_to_gt(uc_fw);
 
/*
 * GuC version number components are defined as being 8-bits.
@@ -647,24 +648,24 @@ static bool guc_check_version_range(struct intel_uc_fw 
*uc_fw)
 */
 
if (!is_ver_8bit(_fw->file_selected.ver)) {
-   gt_warn(__uc_fw_to_gt(uc_fw), "%s firmware: invalid file 
version: 0x%02X:%02X:%02X\n",
+   gt_warn(gt, "%s firmware: invalid file version: 
0x%02X:%02X:%02X\n",
intel_uc_fw_type_repr(uc_fw->type),
uc_fw->file_selected.ver.major,
uc_fw->file_selected.ver.minor,
uc_fw->file_selected.ver.patch);
-   return false;
+   return -EINVAL;
}
 
if (!is_ver_8bit(>submission_version)) {
-   gt_warn(__uc_fw_to_gt(uc_fw), "%s firmware: invalid submit 
version: 0x%02X:%02X:%02X\n",
+   gt_warn(gt, "%s firmware: invalid submit version: 
0x%02X:%02X:%02X\n",
intel_uc_fw_type_repr(uc_fw->type),
guc->submission_version.major,
guc->submission_version.minor,
guc->submission_version.patch);
-   return false;
+   return -EINVAL;
}
 
-   return true;
+   return i915_inject_probe_error(gt->i915, -EINVAL);
 }
 
 static int check_fw_header(struct intel_gt *gt,
@@ -773,8 +774,11 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (err)
goto fail;
 
-   if (uc_fw->type == INTEL_UC_FW_TYPE_GUC && 
!guc_check_version_range(uc_fw))
-   goto fail;
+   if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) {
+   err = guc_check_version_range(uc_fw);
+   if (err)
+   goto fail;
+   }
 
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
-- 
2.39.1



[Intel-gfx] [PATCH 4/6] drm/i915/uc: Enhancements to firmware table validation

2023-04-20 Thread John . C . Harrison
From: John Harrison 

The validation of the firmware table was being done inside the code
for scanning the table for the next available firmware blob. Which is
unnecessary. So pull it out into a separate function that is only
called once per blob type at init time.

Also, drop the CONFIG_SELFTEST requirement and make errors terminal.
It was mentioned that potential issues with backports would not be
caught by regular pre-merge CI as that only occurs on tip not stable
branches. Making the validation unconditional and failing driver load
on detecting of a problem ensures that such backports will also be
validated correctly.

v2: Change to unconditionally fail module load on a validation error
(review feedback/discussion with Daniele).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 157 +--
 1 file changed, 92 insertions(+), 65 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 c9cd9bb47577f..eb52e8db9ae0b 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -233,20 +233,22 @@ struct fw_blobs_by_type {
u32 count;
 };
 
+static const struct uc_fw_platform_requirement blobs_guc[] = {
+   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, GUC_FW_BLOB_MMP)
+};
+
+static const struct uc_fw_platform_requirement blobs_huc[] = {
+   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, HUC_FW_BLOB_MMP, 
HUC_FW_BLOB_GSC)
+};
+
+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 void
 __uc_fw_auto_select(struct drm_i915_private *i915, struct intel_uc_fw *uc_fw)
 {
-   static const struct uc_fw_platform_requirement blobs_guc[] = {
-   INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB, 
GUC_FW_BLOB_MMP)
-   };
-   static const struct uc_fw_platform_requirement blobs_huc[] = {
-   INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB, 
HUC_FW_BLOB_MMP, HUC_FW_BLOB_GSC)
-   };
-   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 bool verified[INTEL_UC_FW_NUM_TYPES];
const struct uc_fw_platform_requirement *fw_blobs;
enum intel_platform p = INTEL_INFO(i915)->platform;
u32 fw_count;
@@ -286,6 +288,11 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
continue;
 
if (uc_fw->file_selected.path) {
+   /*
+* Continuing an earlier search after a found blob 
failed to load.
+* Once the previously chosen path has been found, 
clear it out
+* and let the search continue from there.
+*/
if (uc_fw->file_selected.path == blob->path)
uc_fw->file_selected.path = NULL;
 
@@ -306,76 +313,91 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
/* Failed to find a match for the last attempt?! */
uc_fw->file_selected.path = NULL;
}
+}
 
-   /* make sure the list is ordered as expected */
-   if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST) && !verified[uc_fw->type]) {
-   verified[uc_fw->type] = true;
+static bool validate_fw_table_type(struct drm_i915_private *i915, enum 
intel_uc_fw_type type)
+{
+   const struct uc_fw_platform_requirement *fw_blobs;
+   u32 fw_count;
+   int i;
 
-   for (i = 1; i < fw_count; i++) {
-   /* Next platform is good: */
-   if (fw_blobs[i].p < fw_blobs[i - 1].p)
-   continue;
+   if (type >= ARRAY_SIZE(blobs_all)) {
+   drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
+   return false;
+   }
 
-   /* Next platform revision is good: */
-   if (fw_blobs[i].p == fw_blobs[i - 1].p &&
-   fw_blobs[i].rev < fw_blobs[i - 1].rev)
-   continue;
+   fw_blobs = blobs_all[type].blobs;
+   fw_count = blobs_all[type].count;
 
-   /* Platform/revision must be in order: */
-   if (fw_blobs[i].p != fw_blobs[i - 1].p ||
-   fw_blobs[i].rev != fw_blobs[i - 1].rev)
-   goto bad;
+   if (!fw_count)
+   return true;
 
-   /* Next major version is good: */
-   if (fw_blobs[i].blob.major < fw_blobs[i - 

[Intel-gfx] [PATCH 6/6] drm/i915/uc: Make unexpected firmware versions an error in debug builds

2023-04-20 Thread John . C . Harrison
From: John Harrison 

If the DEBUG_GEM config option is set then escalate the 'unexpected
firmware version' message from a notice to an error. This will ensure
that the CI system treats such occurences as a failure and logs a bug
about it (or fails the pre-merge testing).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 34 ++--
 1 file changed, 20 insertions(+), 14 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 bc4011d55667c..c5b21d17ca437 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -17,6 +17,12 @@
 #include "i915_drv.h"
 #include "i915_reg.h"
 
+#if IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)
+#define UNEXPECTED gt_err
+#else
+#define UNEXPECTED gt_notice
+#endif
+
 static inline struct intel_gt *
 uc_fw_to_gt(struct intel_uc_fw *uc_fw, enum intel_uc_fw_type type)
 {
@@ -828,10 +834,10 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
if (uc_fw->file_wanted.ver.major && uc_fw->file_selected.ver.major) {
/* Check the file's major version was as it claimed */
if (uc_fw->file_selected.ver.major != 
uc_fw->file_wanted.ver.major) {
-   gt_notice(gt, "%s firmware %s: unexpected version: 
%u.%u != %u.%u\n",
- intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
+   UNEXPECTED(gt, "%s firmware %s: unexpected version: 
%u.%u != %u.%u\n",
+  intel_uc_fw_type_repr(uc_fw->type), 
uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major, 
uc_fw->file_selected.ver.minor,
+  uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor);
if (!intel_uc_fw_is_overridden(uc_fw)) {
err = -ENOEXEC;
goto fail;
@@ -849,16 +855,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
 
-   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
- intel_uc_fw_type_repr(uc_fw->type),
- uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major,
- uc_fw->file_wanted.ver.minor,
- uc_fw->file_wanted.ver.patch,
- uc_fw->file_selected.path,
- uc_fw->file_selected.ver.major,
- uc_fw->file_selected.ver.minor,
- uc_fw->file_selected.ver.patch);
+   UNEXPECTED(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
+  intel_uc_fw_type_repr(uc_fw->type),
+  uc_fw->file_wanted.path,
+  uc_fw->file_wanted.ver.major,
+  uc_fw->file_wanted.ver.minor,
+  uc_fw->file_wanted.ver.patch,
+  uc_fw->file_selected.path,
+  uc_fw->file_selected.ver.major,
+  uc_fw->file_selected.ver.minor,
+  uc_fw->file_selected.ver.patch);
gt_info(gt, "Consider updating your linux-firmware pkg or 
downloading from %s\n",
INTEL_UC_FIRMWARE_URL);
}
-- 
2.39.1



[Intel-gfx] [PATCH 5/6] drm/i915/uc: Reject duplicate entries in firmware table

2023-04-20 Thread John . C . Harrison
From: John Harrison 

It was noticed that duplicate entries in the firmware table could cause
an infinite loop in the firmware loading code if that entry failed to
load. Duplicate entries are a bug anyway and so should never happen.
Ensure they don't by tweaking the table validation code to reject
duplicates.

For full m/m/p files, that can be done by simply tweaking the patch
level check to reject matching values. For reduced version entries,
the filename itself must be compared.

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 27 +---
 1 file changed, 24 insertions(+), 3 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 eb52e8db9ae0b..bc4011d55667c 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -319,7 +319,7 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
 {
const struct uc_fw_platform_requirement *fw_blobs;
u32 fw_count;
-   int i;
+   int i, j;
 
if (type >= ARRAY_SIZE(blobs_all)) {
drm_err(>drm, "No blob array for %s\n", 
intel_uc_fw_type_repr(type));
@@ -334,6 +334,27 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
 
/* make sure the list is ordered as expected */
for (i = 1; i < fw_count; i++) {
+   /* Versionless file names must be unique per platform: */
+   for (j = i + 1; j < fw_count; j++) {
+   /* Same platform? */
+   if (fw_blobs[i].p != fw_blobs[j].p)
+   continue;
+
+   if (fw_blobs[i].blob.path != fw_blobs[j].blob.path)
+   continue;
+
+   drm_err(>drm, "Diplicaate %s blobs: %s r%u 
%s%d.%d.%d [%s] matches %s r%u %s%d.%d.%d [%s]\n",
+   intel_uc_fw_type_repr(type),
+   intel_platform_name(fw_blobs[j].p), 
fw_blobs[j].rev,
+   fw_blobs[j].blob.legacy ? "L" : "v",
+   fw_blobs[j].blob.major, fw_blobs[j].blob.minor,
+   fw_blobs[j].blob.patch, fw_blobs[j].blob.path,
+   intel_platform_name(fw_blobs[i].p), 
fw_blobs[i].rev,
+   fw_blobs[i].blob.legacy ? "L" : "v",
+   fw_blobs[i].blob.major, fw_blobs[i].blob.minor,
+   fw_blobs[i].blob.patch, fw_blobs[i].blob.path);
+   }
+
/* Next platform is good: */
if (fw_blobs[i].p < fw_blobs[i - 1].p)
continue;
@@ -377,8 +398,8 @@ static bool validate_fw_table_type(struct drm_i915_private 
*i915, enum intel_uc_
if (fw_blobs[i].blob.minor != fw_blobs[i - 1].blob.minor)
goto bad;
 
-   /* Patch versions must be in order: */
-   if (fw_blobs[i].blob.patch <= fw_blobs[i - 1].blob.patch)
+   /* Patch versions must be in order and unique: */
+   if (fw_blobs[i].blob.patch < fw_blobs[i - 1].blob.patch)
continue;
 
 bad:
-- 
2.39.1



[Intel-gfx] [PATCH 1/6] drm/i915/guc: Decode another GuC load failure case

2023-04-20 Thread John . C . Harrison
From: John Harrison 

Explain another potential firmware failure mode and early exit the
long wait if hit.

Signed-off-by: John Harrison 
Reviewed-by: Daniele Ceraolo Spurio 
---
 drivers/gpu/drm/i915/gt/uc/abi/guc_errors_abi.h | 1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c   | 6 ++
 2 files changed, 7 insertions(+)

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 bcb1129b36102..dabeaf4f245f3 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
@@ -44,6 +44,7 @@ enum intel_guc_load_status {
 enum intel_bootrom_load_status {
INTEL_BOOTROM_STATUS_NO_KEY_FOUND = 0x13,
INTEL_BOOTROM_STATUS_AES_PROD_KEY_FOUND   = 0x1A,
+   INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE   = 0x2B,
INTEL_BOOTROM_STATUS_RSA_FAILED   = 0x50,
INTEL_BOOTROM_STATUS_PAVPC_FAILED = 0x73,
INTEL_BOOTROM_STATUS_WOPCM_FAILED = 0x74,
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 6fda3aec5c66a..0ff088a5e51a8 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c
@@ -129,6 +129,7 @@ static inline bool guc_load_done(struct intel_uncore 
*uncore, u32 *status, bool
case INTEL_BOOTROM_STATUS_RC6CTXCONFIG_FAILED:
case INTEL_BOOTROM_STATUS_MPUMAP_INCORRECT:
case INTEL_BOOTROM_STATUS_EXCEPTION:
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
*success = false;
return true;
}
@@ -219,6 +220,11 @@ static int guc_wait_ucode(struct intel_guc *guc)
guc_info(guc, "firmware signature verification 
failed\n");
ret = -ENOEXEC;
break;
+
+   case INTEL_BOOTROM_STATUS_PROD_KEY_CHECK_FAILURE:
+   guc_info(guc, "firmware production part check 
failure\n");
+   ret = -ENOEXEC;
+   break;
}
 
switch (ukernel) {
-- 
2.39.1



[Intel-gfx] [PATCH 3/6] drm/i915/uc: Track patch level versions on reduced version firmware files

2023-04-20 Thread John . C . Harrison
From: John Harrison 

When reduced version firmware files were added (matching major
component being the only strict requirement), the minor version was
still tracked and a notification reported if it was older. However,
the patch version should really be tracked as well for the same
reasons. The KMD can work without the change but if the effort has
been taken to release a new firmware with the change then there must
be a valid reason for doing so - important bug fix, security fix, etc.
And in that case it would be good to alert the user if they are
missing out on that new fix.

v2: Use correct patch version number and drop redunant debug print
(review by Daniele / CI results).

Signed-off-by: John Harrison 
---
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c | 30 +++-
 1 file changed, 19 insertions(+), 11 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 a82a53dbbc86d..c9cd9bb47577f 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c
@@ -80,14 +80,14 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
  */
 #define INTEL_GUC_FIRMWARE_DEFS(fw_def, guc_maj, guc_mmp) \
fw_def(METEORLAKE,   0, guc_mmp(mtl,  70, 6, 5)) \
-   fw_def(DG2,  0, guc_maj(dg2,  70, 5)) \
-   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5)) \
+   fw_def(DG2,  0, guc_maj(dg2,  70, 5, 1)) \
+   fw_def(ALDERLAKE_P,  0, guc_maj(adlp, 70, 5, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 70, 1, 1)) \
fw_def(ALDERLAKE_P,  0, guc_mmp(adlp, 69, 0, 3)) \
-   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5)) \
+   fw_def(ALDERLAKE_S,  0, guc_maj(tgl,  70, 5, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(ALDERLAKE_S,  0, guc_mmp(tgl,  69, 0, 3)) \
-   fw_def(DG1,  0, guc_maj(dg1,  70, 5)) \
+   fw_def(DG1,  0, guc_maj(dg1,  70, 5, 1)) \
fw_def(ROCKETLAKE,   0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(TIGERLAKE,0, guc_mmp(tgl,  70, 1, 1)) \
fw_def(JASPERLAKE,   0, guc_mmp(ehl,  70, 1, 1)) \
@@ -141,7 +141,7 @@ void intel_uc_fw_change_status(struct intel_uc_fw *uc_fw,
__stringify(patch_) ".bin"
 
 /* Minor for internal driver use, not part of file name */
-#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_) \
+#define MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_) \
__MAKE_UC_FW_PATH_MAJOR(prefix_, "guc", major_)
 
 #define MAKE_GUC_FW_PATH_MMP(prefix_, major_, minor_, patch_) \
@@ -197,9 +197,9 @@ struct __packed uc_fw_blob {
{ UC_FW_BLOB_BASE(major_, minor_, patch_, path_) \
  .legacy = true }
 
-#define GUC_FW_BLOB(prefix_, major_, minor_) \
-   UC_FW_BLOB_NEW(major_, minor_, 0, false, \
-  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_))
+#define GUC_FW_BLOB(prefix_, major_, minor_, patch_) \
+   UC_FW_BLOB_NEW(major_, minor_, patch_, false, \
+  MAKE_GUC_FW_PATH_MAJOR(prefix_, major_, minor_, patch_))
 
 #define GUC_FW_BLOB_MMP(prefix_, major_, minor_, patch_) \
UC_FW_BLOB_OLD(major_, minor_, patch_, \
@@ -296,6 +296,7 @@ __uc_fw_auto_select(struct drm_i915_private *i915, struct 
intel_uc_fw *uc_fw)
uc_fw->file_wanted.path = blob->path;
uc_fw->file_wanted.ver.major = blob->major;
uc_fw->file_wanted.ver.minor = blob->minor;
+   uc_fw->file_wanted.ver.patch = blob->patch;
uc_fw->loaded_via_gsc = blob->loaded_via_gsc;
found = true;
break;
@@ -790,6 +791,9 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
} else {
if (uc_fw->file_selected.ver.minor < 
uc_fw->file_wanted.ver.minor)
old_ver = true;
+   else if ((uc_fw->file_selected.ver.minor == 
uc_fw->file_wanted.ver.minor) &&
+(uc_fw->file_selected.ver.patch < 
uc_fw->file_wanted.ver.patch))
+   old_ver = true;
}
}
 
@@ -797,12 +801,16 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw)
/* Preserve the version that was really wanted */
memcpy(_fw->file_wanted, _ideal, 
sizeof(uc_fw->file_wanted));
 
-   gt_notice(gt, "%s firmware %s (%d.%d) is recommended, but only 
%s (%d.%d) was found\n",
+   gt_notice(gt, "%s firmware %s (%d.%d.%d) is recommended, but 
only %s (%d.%d.%d) was found\n",
  intel_uc_fw_type_repr(uc_fw->type),
  uc_fw->file_wanted.path,
- uc_fw->file_wanted.ver.major, 
uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.major,
+ uc_fw->file_wanted.ver.minor,
+ uc_fw->file_wanted.ver.patch,
  

[Intel-gfx] [PATCH 0/6] Improvements to uc firmare management

2023-04-20 Thread John . C . Harrison
From: John Harrison 

Enhance the firmware table verification code to catch more potential
errors and to generally improve the code itself.

Track patch level version even on reduced version files to allow user
notification of missing bug fixes.

Detect another immediate failure case when loading GuC firmware.

Treat more problems as fatal errors, at least for DEBUG builds.

Signed-off-by: John Harrison 


John Harrison (6):
  drm/i915/guc: Decode another GuC load failure case
  drm/i915/guc: Print status register when waiting for GuC to load
  drm/i915/uc: Track patch level versions on reduced version firmware
files
  drm/i915/uc: Enhancements to firmware table validation
  drm/i915/uc: Reject duplicate entries in firmware table
  drm/i915/uc: Make unexpected firmware versions an error in debug
builds

 .../gpu/drm/i915/gt/uc/abi/guc_errors_abi.h   |   1 +
 drivers/gpu/drm/i915/gt/uc/intel_guc_fw.c |  12 +-
 drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c  | 224 +++---
 3 files changed, 154 insertions(+), 83 deletions(-)

-- 
2.39.1



  1   2   3   4   5   6   7   8   9   10   >