]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
accel/amdxdna: Get device revision to derive VBNV string
authorMax Zhen <max.zhen@amd.com>
Thu, 16 Apr 2026 19:01:50 +0000 (12:01 -0700)
committerLizhi Hou <lizhi.hou@amd.com>
Fri, 17 Apr 2026 16:13:40 +0000 (09:13 -0700)
Add support for querying the device revision from firmware.

Use the returned revision to look up the VBNV string during device
initialization, and fall back to the default VBNV when the revision
query is not supported or no mapping is found.

This allows the driver to report the accurate VBNV for devices that
share the same vendor/device ID but differ by hardware revision.

Signed-off-by: Max Zhen <max.zhen@amd.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
[Lizhi: Revise amdxdna_vbnv_init()]
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260416190150.1040067-1-lizhi.hou@amd.com
14 files changed:
drivers/accel/amdxdna/aie.c
drivers/accel/amdxdna/aie.h
drivers/accel/amdxdna/aie2_message.c
drivers/accel/amdxdna/aie2_msg_priv.h
drivers/accel/amdxdna/aie2_pci.c
drivers/accel/amdxdna/aie2_pci.h
drivers/accel/amdxdna/aie4_pci.c
drivers/accel/amdxdna/amdxdna_pci_drv.h
drivers/accel/amdxdna/amdxdna_sysfs.c
drivers/accel/amdxdna/npu1_regs.c
drivers/accel/amdxdna/npu3_regs.c
drivers/accel/amdxdna/npu4_regs.c
drivers/accel/amdxdna/npu5_regs.c
drivers/accel/amdxdna/npu6_regs.c

index 4b3d4493128e9e7571a5e90720831d3a7e1f0f78..66849ba9026ae165e157ddf362211218fa8980e0 100644 (file)
@@ -87,3 +87,33 @@ int aie_check_protocol(struct aie_device *aie, u32 fw_major, u32 fw_minor)
 
        return found ? 0 : -EOPNOTSUPP;
 }
+
+static void amdxdna_update_vbnv(struct amdxdna_dev *xdna,
+                               const struct amdxdna_rev_vbnv *tbl,
+                               u32 rev)
+{
+       int i;
+
+       for (i = 0; tbl[i].vbnv; i++) {
+               if (tbl[i].revision == rev) {
+                       xdna->vbnv = tbl[i].vbnv;
+                       break;
+               }
+       }
+}
+
+void amdxdna_vbnv_init(struct amdxdna_dev *xdna)
+{
+       const struct amdxdna_dev_info *info = xdna->dev_info;
+       u32 rev;
+
+       xdna->vbnv = info->default_vbnv;
+
+       if (!info->ops->get_dev_revision || !info->rev_vbnv_tbl)
+               return;
+
+       if (info->ops->get_dev_revision(xdna, &rev))
+               return;
+
+       amdxdna_update_vbnv(xdna, info->rev_vbnv_tbl, rev);
+}
index ba4c9ee21823daa77da7d3af5bcacd041cf1d8ce..7a68b114f2358e918acc41cec5570c94e131e368 100644 (file)
@@ -82,11 +82,18 @@ struct psp_config {
        u32                     notify_val;
 };
 
+/* Device revision to VBNV string mapping table entry */
+struct amdxdna_rev_vbnv {
+       u32             revision;
+       const char      *vbnv;
+};
+
 /* aie.c */
 void aie_dump_mgmt_chann_debug(struct aie_device *aie);
 void aie_destroy_chann(struct aie_device *aie, struct mailbox_channel **chann);
 int aie_send_mgmt_msg_wait(struct aie_device *aie, struct xdna_mailbox_msg *msg);
 int aie_check_protocol(struct aie_device *aie, u32 fw_major, u32 fw_minor);
+void amdxdna_vbnv_init(struct amdxdna_dev *xdna);
 
 /* aie_psp.c */
 struct psp_device *aiem_psp_create(struct drm_device *ddev, struct psp_config *conf);
index 976ad628107803fca46c716827ad5f8935ca09dc..6e98af7b74db2705eef9d362914041d961146e2c 100644 (file)
@@ -1244,3 +1244,28 @@ int aie2_update_prop_time_quota(struct amdxdna_dev_hdl *ndev, u32 us)
        }
        return ret;
 }
+
+int aie2_get_dev_revision(struct amdxdna_dev_hdl *ndev, enum aie2_dev_revision *rev)
+{
+       DECLARE_AIE_MSG(get_dev_revision, MSG_OP_GET_DEV_REVISION);
+       struct amdxdna_dev *xdna = ndev->aie.xdna;
+       int ret;
+
+       if (!AIE_FEATURE_ON(&ndev->aie, AIE2_GET_DEV_REVISION))
+               return -EOPNOTSUPP;
+
+       ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg);
+       if (ret)
+               return ret;
+
+       *rev = resp.rev;
+
+       if (*rev < AIE2_DEV_REVISION_STXA || *rev >= AIE2_DEV_REVISION_UNKN) {
+               XDNA_ERR(xdna, "Unknown device revision: %d (raw fuse: 0x%x)",
+                        *rev, resp.raw_fuse_data);
+               return -EINVAL;
+       }
+
+       XDNA_DBG(xdna, "Device revision: %d (raw fuse: 0x%x)", *rev, resp.raw_fuse_data);
+       return 0;
+}
index b10552c627ee8506ce4e4ff19f2ccc95a048cbf3..a41c9797e265da58445388930eb22d8903a36c51 100644 (file)
@@ -33,6 +33,7 @@ enum aie2_msg_opcode {
        MSG_OP_REGISTER_ASYNC_EVENT_MSG    = 0x10C,
        MSG_OP_UPDATE_PROPERTY             = 0x113,
        MSG_OP_GET_APP_HEALTH              = 0x114,
+       MSG_OP_GET_DEV_REVISION            = 0x117,
        MSG_OP_MAX_DRV_OPCODE,
        MSG_OP_GET_PROTOCOL_VERSION        = 0x301,
        MSG_OP_MAX_OPCODE
@@ -519,4 +520,26 @@ struct update_property_resp {
        enum aie2_msg_status status;
 } __packed;
 
+enum aie2_dev_revision {
+       AIE2_DEV_REVISION_STXA = 1,
+       AIE2_DEV_REVISION_STXB,
+       AIE2_DEV_REVISION_KRK1,
+       AIE2_DEV_REVISION_KRK2,
+       AIE2_DEV_REVISION_HALO,
+       AIE2_DEV_REVISION_GPT1,
+       AIE2_DEV_REVISION_GPT2,
+       AIE2_DEV_REVISION_GPT3,
+       AIE2_DEV_REVISION_UNKN,
+};
+
+struct get_dev_revision_req {
+       __u32                   place_holder;
+} __packed;
+
+struct get_dev_revision_resp {
+       enum aie2_msg_status    status;
+       enum aie2_dev_revision  rev;
+       __u32                   raw_fuse_data;
+} __packed;
+
 #endif /* _AIE2_MSG_PRIV_H_ */
index afbe3f8f67ce4d453826444856e7590ea2a8de68..1d1fb012294af803e91e83dc3999723eb99ac0a1 100644 (file)
@@ -608,6 +608,7 @@ static int aie2_init(struct amdxdna_dev *xdna)
 
        release_firmware(fw);
        aie2_msg_init(ndev);
+       amdxdna_vbnv_init(xdna);
        amdxdna_pm_init(xdna);
        return 0;
 
@@ -1255,6 +1256,21 @@ dev_exit:
        return ret;
 }
 
+static int aie2_get_dev_rev(struct amdxdna_dev *xdna, u32 *rev)
+{
+       struct amdxdna_dev_hdl *ndev = xdna->dev_handle;
+       enum aie2_dev_revision aie2_rev;
+       int ret;
+
+       drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock));
+       ret = aie2_get_dev_revision(ndev, &aie2_rev);
+
+       if (!ret)
+               *rev = (u32)aie2_rev;
+
+       return ret;
+}
+
 const struct amdxdna_dev_ops aie2_ops = {
        .init = aie2_init,
        .fini = aie2_fini,
@@ -1269,4 +1285,5 @@ const struct amdxdna_dev_ops aie2_ops = {
        .cmd_submit = aie2_cmd_submit,
        .hmm_invalidate = aie2_hmm_invalidate,
        .get_array = aie2_get_array,
+       .get_dev_revision = aie2_get_dev_rev,
 };
index 69b53c7bcb86a06b457cc7355f8171a8998bf4ce..c44616065058e6e3670b5040e509bfabdcdcaf0f 100644 (file)
@@ -223,6 +223,7 @@ enum aie2_fw_feature {
        AIE2_TEMPORAL_ONLY,
        AIE2_APP_HEALTH,
        AIE2_UPDATE_PROPERTY,
+       AIE2_GET_DEV_REVISION,
        AIE2_FEATURE_MAX
 };
 
@@ -258,6 +259,7 @@ extern const struct dpm_clk_freq npu4_dpm_clk_table[];
 extern const struct rt_config npu1_default_rt_cfg[];
 extern const struct rt_config npu4_default_rt_cfg[];
 extern const struct amdxdna_fw_feature_tbl npu4_fw_feature_table[];
+extern const struct amdxdna_rev_vbnv npu4_rev_vbnv_tbl[];
 extern const struct aie2_hw_ops npu4_hw_ops;
 
 /* aie2_pm.c */
@@ -286,6 +288,7 @@ int aie2_query_firmware_version(struct amdxdna_dev_hdl *ndev,
                                struct amdxdna_fw_ver *fw_ver);
 int aie2_query_app_health(struct amdxdna_dev_hdl *ndev, u32 context_id,
                          struct app_health_report *report);
+int aie2_get_dev_revision(struct amdxdna_dev_hdl *ndev, enum aie2_dev_revision *rev);
 int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
 int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwctx);
 int aie2_map_host_buf(struct amdxdna_dev_hdl *ndev, u32 context_id, u64 addr, u64 size);
index f50e0bc566e43d7921b10b9754f2cd43e79f9d05..87f80f804f917e3a0dd535da71d208b6f05ce5fb 100644 (file)
@@ -471,6 +471,7 @@ static int aie4_init(struct amdxdna_dev *xdna)
                return ret;
        }
 
+       amdxdna_vbnv_init(xdna);
        XDNA_DBG(xdna, "aie4 init finished");
        return 0;
 }
index eabbf57f2b388fc20f0d222c7c38e992a27e9847..bdd0dc83f92e84e7959c3843b22b6bb4c6473699 100644 (file)
@@ -65,6 +65,7 @@ struct amdxdna_dev_ops {
        int (*get_aie_info)(struct amdxdna_client *client, struct amdxdna_drm_get_info *args);
        int (*set_aie_state)(struct amdxdna_client *client, struct amdxdna_drm_set_state *args);
        int (*get_array)(struct amdxdna_client *client, struct amdxdna_drm_get_array *args);
+       int (*get_dev_revision)(struct amdxdna_dev *xdna, u32 *rev);
 };
 
 struct amdxdna_fw_feature_tbl {
@@ -89,7 +90,8 @@ struct amdxdna_dev_info {
        u32                             dev_mem_buf_shift;
        u64                             dev_mem_base;
        size_t                          dev_mem_size;
-       char                            *vbnv;
+       const char                      *default_vbnv;
+       const struct amdxdna_rev_vbnv   *rev_vbnv_tbl;
        const struct amdxdna_dev_priv   *dev_priv;
        const struct amdxdna_fw_feature_tbl *fw_feature_tbl;
        const struct amdxdna_dev_ops    *ops;
@@ -117,6 +119,8 @@ struct amdxdna_dev {
        struct iommu_group              *group;
        struct iommu_domain             *domain;
        struct iova_domain              iovad;
+       /* Accurate board name queried from firmware, or default_vbnv as fallback */
+       const char                      *vbnv;
 };
 
 /*
index f27e4ee960a0cdb9821649545ed1447f4c0499e9..d9e359ee8182c7667924b69c2f40e3fa919f2be6 100644 (file)
@@ -17,7 +17,10 @@ static ssize_t vbnv_show(struct device *dev, struct device_attribute *attr, char
 {
        struct amdxdna_dev *xdna = dev_get_drvdata(dev);
 
-       return sprintf(buf, "%s\n", xdna->dev_info->vbnv);
+       if (!xdna->vbnv)
+               return sprintf(buf, "\n");
+
+       return sprintf(buf, "%s\n", xdna->vbnv);
 }
 static DEVICE_ATTR_RO(vbnv);
 
index f1141a65e64de2b387082498de6d49134272fb85..d7e50c6b06efdfea60bbcd7f1b0a077e6007310a 100644 (file)
@@ -137,7 +137,7 @@ const struct amdxdna_dev_info dev_npu1_info = {
        .dev_mem_buf_shift = 15, /* 32 KiB aligned */
        .dev_mem_base      = AIE2_DEVM_BASE,
        .dev_mem_size      = AIE2_DEVM_SIZE,
-       .vbnv              = "RyzenAI-npu1",
+       .default_vbnv      = "RyzenAI-npu1",
        .device_type       = AMDXDNA_DEV_TYPE_KMQ,
        .dev_priv          = &npu1_dev_priv,
        .fw_feature_tbl    = npu1_fw_feature_table,
index 5a0bbc916094d822b538fcf4017e1e24368b69ba..acece0faddf2a43db7693de2bafb596d749c329d 100644 (file)
@@ -69,7 +69,7 @@ const struct amdxdna_dev_info dev_npu3_pf_info = {
        .sram_bar               = NPU3_MBOX_BUFFER_BAR,
        .psp_bar                = NPU3_PSP_BAR_INDEX,
        .smu_bar                = NPU3_SMU_BAR_INDEX,
-       .vbnv                   = "RyzenAI-npu3-pf",
+       .default_vbnv           = "RyzenAI-npu3-pf",
        .device_type            = AMDXDNA_DEV_TYPE_PF,
        .dev_priv               = &npu3_dev_priv,
        .fw_feature_tbl         = npu3_fw_feature_table,
index 6ebf75ad5fb474c6e0a7a2cba8a7a5e514096a00..935999ced70fd9a2f826911f9a843f1e9c9fbd8a 100644 (file)
@@ -98,6 +98,7 @@ const struct amdxdna_fw_feature_tbl npu4_fw_feature_table[] = {
        { .features = BIT_U64(AIE2_NPU_COMMAND), .major = 6, .min_minor = 15 },
        { .features = BIT_U64(AIE2_UPDATE_PROPERTY), .major = 6, .min_minor = 15 },
        { .features = BIT_U64(AIE2_APP_HEALTH), .major = 6, .min_minor = 18 },
+       { .features = BIT_U64(AIE2_GET_DEV_REVISION), .major = 6, .min_minor = 24 },
        { .features = AIE2_ALL_FEATURES, .major = 7 },
        { 0 }
 };
@@ -142,6 +143,18 @@ const struct aie2_hw_ops npu4_hw_ops = {
        .update_counters = npu4_update_counters,
 };
 
+const struct amdxdna_rev_vbnv npu4_rev_vbnv_tbl[] = {
+       { AIE2_DEV_REVISION_STXA, "NPU Strix" },
+       { AIE2_DEV_REVISION_STXB, "NPU Strix" },
+       { AIE2_DEV_REVISION_KRK1, "NPU Krackan 1" },
+       { AIE2_DEV_REVISION_KRK2, "NPU Krackan 2" },
+       { AIE2_DEV_REVISION_HALO, "NPU Strix Halo" },
+       { AIE2_DEV_REVISION_GPT1, "NPU Gorgon Point 1" },
+       { AIE2_DEV_REVISION_GPT2, "NPU Gorgon Point 2" },
+       { AIE2_DEV_REVISION_GPT3, "NPU Gorgon Point 3" },
+       { 0 }
+};
+
 static const struct amdxdna_dev_priv npu4_dev_priv = {
        .fw_path        = "amdnpu/17f0_10/",
        .rt_config      = npu4_default_rt_cfg,
@@ -185,8 +198,9 @@ const struct amdxdna_dev_info dev_npu4_info = {
        .dev_mem_buf_shift = 15, /* 32 KiB aligned */
        .dev_mem_base      = AIE2_DEVM_BASE,
        .dev_mem_size      = AIE2_DEVM_SIZE,
-       .vbnv              = "RyzenAI-npu4",
+       .default_vbnv      = "RyzenAI-npu4",
        .device_type       = AMDXDNA_DEV_TYPE_KMQ,
+       .rev_vbnv_tbl      = npu4_rev_vbnv_tbl,
        .dev_priv          = &npu4_dev_priv,
        .fw_feature_tbl    = npu4_fw_feature_table,
        .ops               = &aie2_ops, /* NPU4 can share NPU1's callback */
index 6d4596b9e61e74b85d7062eddeae81756c38417f..795bd19968457058870199f0b98df588822edaa8 100644 (file)
@@ -105,8 +105,9 @@ const struct amdxdna_dev_info dev_npu5_info = {
        .dev_mem_buf_shift = 15, /* 32 KiB aligned */
        .dev_mem_base      = AIE2_DEVM_BASE,
        .dev_mem_size      = AIE2_DEVM_SIZE,
-       .vbnv              = "RyzenAI-npu5",
+       .default_vbnv      = "RyzenAI-npu5",
        .device_type       = AMDXDNA_DEV_TYPE_KMQ,
+       .rev_vbnv_tbl      = npu4_rev_vbnv_tbl,
        .dev_priv          = &npu5_dev_priv,
        .fw_feature_tbl    = npu4_fw_feature_table,
        .ops               = &aie2_ops,
index 76181345b6d1c0879665f36b97094552b906d71f..3125d1ce45ab0c61e730e21c395911c312d64c98 100644 (file)
@@ -106,8 +106,9 @@ const struct amdxdna_dev_info dev_npu6_info = {
        .dev_mem_buf_shift = 15, /* 32 KiB aligned */
        .dev_mem_base      = AIE2_DEVM_BASE,
        .dev_mem_size      = AIE2_DEVM_SIZE,
-       .vbnv              = "RyzenAI-npu6",
+       .default_vbnv      = "RyzenAI-npu6",
        .device_type       = AMDXDNA_DEV_TYPE_KMQ,
+       .rev_vbnv_tbl      = npu4_rev_vbnv_tbl,
        .dev_priv          = &npu6_dev_priv,
        .fw_feature_tbl    = npu4_fw_feature_table,
        .ops               = &aie2_ops,