]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu: Add node_id-to-die-name decoding for ih v7_1
authorHawking Zhang <Hawking.Zhang@amd.com>
Wed, 18 Mar 2026 13:09:14 +0000 (21:09 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 Apr 2026 14:58:38 +0000 (10:58 -0400)
Converts node_id values into human-readable die
names to facilitate debugging

v2: squash in fix (Alex)

Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h
drivers/gpu/drm/amd/amdgpu/gmc_v12_1.c
drivers/gpu/drm/amd/amdgpu/ih_v7_0.c

index f58b6be7fccc0cd5839d349210fe8f197e36e13f..444437c3008868c9f32cd4390712a27609dc1b25 100644 (file)
@@ -91,6 +91,12 @@ struct amdgpu_ih_funcs {
        uint64_t (*decode_iv_ts)(struct amdgpu_ih_ring *ih, u32 rptr,
                                 signed int offset);
        void (*set_rptr)(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih);
+       /* Decode IH cookie node_id into a human-readable die name string.
+        * Returns buf, or NULL if this IH version does not support node_id decoding.
+        */
+       const char *(*node_id_to_die_name)(struct amdgpu_device *adev,
+                                          unsigned int node_id,
+                                          char *buf, size_t size);
 };
 
 #define amdgpu_ih_get_wptr(adev, ih) (adev)->irq.ih_funcs->get_wptr((adev), (ih))
index 7ea7b9c30bca965fc3e9886128ea0fe741518ac7..855cd29cbffaacf96ee99c5d55702fde723510ff 100644 (file)
@@ -112,6 +112,8 @@ static int gmc_v12_1_process_interrupt(struct amdgpu_device *adev,
        const char *hub_name;
        int ret, xcc_id = 0;
        uint32_t status = 0;
+       const char *die_name;
+       char die_name_buf[32];
        u64 addr;
 
        node_id = entry->node_id;
@@ -201,6 +203,17 @@ static int gmc_v12_1_process_interrupt(struct amdgpu_device *adev,
        dev_err(adev->dev, "  in page starting at address 0x%016llx from IH client %d (%s)\n",
                addr, entry->client_id, soc_v1_0_ih_clientid_name[entry->client_id]);
 
+       if (adev->irq.ih_funcs &&
+           adev->irq.ih_funcs->node_id_to_die_name) {
+               die_name = adev->irq.ih_funcs->node_id_to_die_name(adev, node_id,
+                                                                  die_name_buf,
+                                                                  sizeof(die_name_buf));
+               if (die_name)
+                       dev_err(adev->dev,
+                               "  cookie node_id %d fault from die %s\n",
+                               node_id, die_name);
+       }
+
        if (amdgpu_sriov_vf(adev))
                return 0;
 
index 1fbe904f4223b1c8c7de7371ad29e87f854d5150..6de9e87e04e1ac6afde7d4275900a6edffef41ec 100644 (file)
@@ -798,6 +798,43 @@ static void ih_v7_0_get_clockgating_state(struct amdgpu_ip_block *ip_block, u64
        return;
 }
 
+/*
+ * ih_v7_0_node_id_to_die_name - Decode IH cookie node_id to a die name string
+ *
+ * Currently, only applies to IH v7_1. For other IH versions returns NULL.
+ *
+ * IH v7_1 node_id encoding:
+ * node_id[N:3] = MID index
+ * node_id[2:0] = sub-slot: 0=MID, 1=AID, 2-5=AID.XCD, 6-7=RSV
+ */
+static const char *ih_v7_0_node_id_to_die_name(struct amdgpu_device *adev,
+                                              unsigned int node_id,
+                                              char *buf, size_t size)
+{
+       int mid_id, sub_slot;
+
+       /* Node ID to die name decoding is only defined for IH v7_1 currenlty. */
+       if (amdgpu_ip_version(adev, OSSSYS_HWIP, 0) != IP_VERSION(7, 1, 0))
+               return NULL;
+
+       mid_id = node_id >> 3;
+       sub_slot = node_id & 0x7;
+
+       if (mid_id > 1)
+               return "UNKNOWN";
+
+       if (sub_slot == 0)
+               snprintf(buf, size, "MID%d", mid_id);
+       else if (sub_slot == 1)
+               snprintf(buf, size, "AID%d", mid_id);
+       else if (sub_slot <= 5)
+               snprintf(buf, size, "AID%d.XCD%d", mid_id, sub_slot - 2);
+       else
+               snprintf(buf, size, "RSV");
+
+       return buf;
+}
+
 static const struct amd_ip_funcs ih_v7_0_ip_funcs = {
        .name = "ih_v7_0",
        .early_init = ih_v7_0_early_init,
@@ -819,7 +856,8 @@ static const struct amdgpu_ih_funcs ih_v7_0_funcs = {
        .get_wptr = ih_v7_0_get_wptr,
        .decode_iv = amdgpu_ih_decode_iv_helper,
        .decode_iv_ts = amdgpu_ih_decode_iv_ts_helper,
-       .set_rptr = ih_v7_0_set_rptr
+       .set_rptr = ih_v7_0_set_rptr,
+       .node_id_to_die_name = ih_v7_0_node_id_to_die_name,
 };
 
 static void ih_v7_0_set_interrupt_funcs(struct amdgpu_device *adev)