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);
+}
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);
}
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;
+}
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
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_ */
release_firmware(fw);
aie2_msg_init(ndev);
+ amdxdna_vbnv_init(xdna);
amdxdna_pm_init(xdna);
return 0;
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,
.cmd_submit = aie2_cmd_submit,
.hmm_invalidate = aie2_hmm_invalidate,
.get_array = aie2_get_array,
+ .get_dev_revision = aie2_get_dev_rev,
};
AIE2_TEMPORAL_ONLY,
AIE2_APP_HEALTH,
AIE2_UPDATE_PROPERTY,
+ AIE2_GET_DEV_REVISION,
AIE2_FEATURE_MAX
};
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 */
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);
return ret;
}
+ amdxdna_vbnv_init(xdna);
XDNA_DBG(xdna, "aie4 init finished");
return 0;
}
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 {
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;
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;
};
/*
{
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);
.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,
.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,
{ .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 }
};
.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,
.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 */
.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,
.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,