The debugger sets the CWSR grace period via AMDKFD_IOC_DBG_TRAP and may
request a value of 0. An earlier change clamped 0 to 1 unconditionally
because most firmware revisions locked up when given an infinite (0)
grace period.

Firmware has since been fixed on most ASICs, so gate the clamp on ASIC
type and MEC firmware version and allow 0 where the running firmware is
known to handle it. Navi3x always supports 0. MI100 never received the
firmware fix and is kept clamped. gfx9.5.0 and any unlisted or future
ASIC default to the safe (clamped) behaviour.

Signed-off-by: William Palacek <[email protected]>
---
 .../drm/amd/amdkfd/kfd_packet_manager_v9.c    | 66 +++++++++++++++++--
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c 
b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
index 3d2375817c3e..e4092ba81fe5 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c
@@ -309,6 +309,63 @@ static inline void 
pm_build_dequeue_wait_counts_packet_info(struct packet_manage
                reg_data);
 }
 
+/* pm_grace_period_0_supported - whether firmware tolerates a CWSR grace
+ * period of 0 on this ASIC.
+ *
+ * The debugger may request a grace period of 0 via AMDKFD_IOC_DBG_TRAP.
+ * Most firmware revisions locked up on an infinite (0) grace period, so
+ * an earlier change clamped 0 to 1 for all ASICs. Firmware has since been
+ * fixed on most ASICs; return true only where the running MEC firmware is
+ * known to handle 0. The +32768 offset on IP_VERSION(9, 0, 1) accounts for
+ * the SR-IOV firmware version encoding.
+ *
+ * Navi3x (gfx11) always supports a grace period of 0. MI100
+ * (IP_VERSION(9, 4, 1)) never received the fix and is intentionally kept
+ * clamped. gfx9.5.0 and any unlisted or future ASIC default to the safe
+ * behaviour (clamp).
+ */
+static bool pm_grace_period_0_supported(struct packet_manager *pm)
+{
+       struct kfd_node *dev = pm->dqm->dev;
+       uint32_t mec_fw_version = dev->kfd->mec_fw_version;
+
+       /* Navi3x (gfx11) always supports a grace period of 0. */
+       if (KFD_GC_VERSION(dev) >= IP_VERSION(11, 0, 0) &&
+           KFD_GC_VERSION(dev) < IP_VERSION(12, 0, 0))
+               return true;
+
+       switch (KFD_GC_VERSION(dev)) {
+       case IP_VERSION(9, 0, 1):
+               return mec_fw_version >= 461 + 32768;
+       case IP_VERSION(9, 1, 0):
+       case IP_VERSION(9, 2, 1):
+       case IP_VERSION(9, 2, 2):
+       case IP_VERSION(9, 3, 0):
+       case IP_VERSION(9, 4, 0):
+               return mec_fw_version >= 461;
+       /* MI100/Arcturus never received the firmware fix; keep clamped. */
+       case IP_VERSION(9, 4, 1):
+               return false;
+       case IP_VERSION(9, 4, 2):
+               return mec_fw_version >= 63;
+       case IP_VERSION(9, 4, 3):
+       case IP_VERSION(9, 4, 4):
+               return mec_fw_version >= 96;
+       case IP_VERSION(10, 1, 10):
+       case IP_VERSION(10, 1, 2):
+       case IP_VERSION(10, 1, 1):
+               return mec_fw_version >= 146;
+       case IP_VERSION(10, 3, 0):
+       case IP_VERSION(10, 3, 2):
+       case IP_VERSION(10, 3, 1):
+       case IP_VERSION(10, 3, 4):
+       case IP_VERSION(10, 3, 5):
+               return mec_fw_version >= 93;
+       default:
+               return false;
+       }
+}
+
 /* pm_config_dequeue_wait_counts_v9: Builds WRITE_DATA packet with
  *    register/value for configuring dequeue wait counts
  *
@@ -357,11 +414,12 @@ static int pm_config_dequeue_wait_counts_v9(struct 
packet_manager *pm,
                break;
 
        case KFD_DEQUEUE_WAIT_SET_SCH_WAVE:
-               /* The CP cannot handle value 0 and it will result in
-                * an infinite grace period being set so set to 1 to prevent 
this. Also
-                * avoid debugger API breakage as it sets 0 and expects a low 
value.
+               /* A grace period of 0 requests an infinite CWSR grace period.
+                * Older firmware locks up on this, so clamp to 1 unless the 
ASIC
+                * firmware is known to handle 0. Also avoid debugger API 
breakage
+                * as it sets 0 and expects a low value.
                 */
-               if (!value)
+               if (!value && !pm_grace_period_0_supported(pm))
                        value = 1;
                pm_build_dequeue_wait_counts_packet_info(pm, value, 0, 
&reg_offset, &reg_data);
                break;
-- 
2.34.1

Reply via email to