Allocate a DRAM buffer for firmware logging, and also set the log level to less verbose. This will give the best performance numbers.
Signed-off-by: David Zhang <[email protected]> --- drivers/accel/amdxdna/aie4_message.c | 20 ++++++++++ drivers/accel/amdxdna/aie4_msg_priv.h | 24 ++++++++++++ drivers/accel/amdxdna/aie4_pci.c | 54 +++++++++++++++++++++++++++ drivers/accel/amdxdna/aie4_pci.h | 5 +++ 4 files changed, 103 insertions(+) diff --git a/drivers/accel/amdxdna/aie4_message.c b/drivers/accel/amdxdna/aie4_message.c index 1bddcb183db6..936fa2f43d91 100644 --- a/drivers/accel/amdxdna/aie4_message.c +++ b/drivers/accel/amdxdna/aie4_message.c @@ -232,6 +232,26 @@ int aie4_attach_work_buffer(struct amdxdna_dev_hdl *ndev) return ret; } +int aie4_start_fw_log(struct amdxdna_dev_hdl *ndev, u32 level) +{ + DECLARE_AIE_MSG(aie4_msg_start_fw_log, AIE4_MSG_OP_START_FW_LOG); + struct amdxdna_dev *xdna = ndev->aie.xdna; + int ret; + + req.buff_addr = ndev->fw_log_buf_addr; + req.buff_size = ndev->fw_log_buf_size; + req.log_level = level; + + ret = aie_send_mgmt_msg_wait(&ndev->aie, &msg); + if (ret) + XDNA_WARN(xdna, "Failed to start fw log, ret %d", ret); + else + XDNA_DBG(xdna, "Started fw log, level %u size 0x%x", + level, ndev->fw_log_buf_size); + + return ret; +} + int aie4_msg_set_power_mode(struct amdxdna_dev_hdl *ndev, u8 power_mode) { DECLARE_AIE_MSG(aie4_msg_power_override, AIE4_MSG_OP_POWER_OVERRIDE); diff --git a/drivers/accel/amdxdna/aie4_msg_priv.h b/drivers/accel/amdxdna/aie4_msg_priv.h index 77984683a7b6..51e7f4b5ed53 100644 --- a/drivers/accel/amdxdna/aie4_msg_priv.h +++ b/drivers/accel/amdxdna/aie4_msg_priv.h @@ -29,6 +29,7 @@ enum aie4_msg_opcode { AIE4_MSG_OP_GET_CURRENT_DPM_LEVEL = 0x30013, AIE4_MSG_OP_ATTACH_WORK_BUFFER = 0x40001, + AIE4_MSG_OP_START_FW_LOG = 0x40003, }; enum aie4_msg_status { @@ -275,4 +276,27 @@ struct aie4_msg_attach_work_buffer_resp { enum aie4_msg_status status; } __packed; +/* Dynamic firmware log levels. */ +enum aie4_fw_log_level { + AIE4_FW_LOG_LEVEL_OFF, + AIE4_FW_LOG_LEVEL_ERR, + AIE4_FW_LOG_LEVEL_WRN, + AIE4_FW_LOG_LEVEL_INF, + AIE4_FW_LOG_LEVEL_DBG, + AIE4_FW_LOG_LEVEL_MAX, +}; + +#define AIE4_FW_LOG_BUF_SIZE SZ_1M + +struct aie4_msg_start_fw_log_req { + __u64 buff_addr; + __u32 buff_size; + __u32 log_level; + __u32 reserved; +} __packed; + +struct aie4_msg_start_fw_log_resp { + enum aie4_msg_status status; +} __packed; + #endif /* _AIE4_MSG_PRIV_H_ */ diff --git a/drivers/accel/amdxdna/aie4_pci.c b/drivers/accel/amdxdna/aie4_pci.c index 62ee7dfc7bd3..480bd64b0020 100644 --- a/drivers/accel/amdxdna/aie4_pci.c +++ b/drivers/accel/amdxdna/aie4_pci.c @@ -404,6 +404,13 @@ static int aie4_config_fw(struct amdxdna_dev_hdl *ndev) /* Best-effort tuning knob; failure is warned inside and does not fail hw start */ aie4_set_ctx_hysteresis(ndev, ndev->ctx_switch_hysteresis_us); + /* + * Give the firmware high performance DRAM to log into with less + * verbose level. + */ + if (ndev->fw_log_buf) + aie4_start_fw_log(ndev, AIE4_FW_LOG_LEVEL_ERR); + return 0; } @@ -960,6 +967,45 @@ static void aie4_free_work_buffer(struct amdxdna_dev_hdl *ndev) ndev->work_buf = NULL; } +/* + * Firmware logging is best effort: a device that cannot spare the buffer still + * runs, it just does not log. Never fail hw start or probe on this. + */ +static void aie4_alloc_fw_log_buffer(struct amdxdna_dev_hdl *ndev) +{ + struct amdxdna_dev *xdna = ndev->aie.xdna; + u32 buf_size = AIE4_FW_LOG_BUF_SIZE; + + ndev->fw_log_buf = amdxdna_alloc_msg_buffer(xdna, &buf_size, + &ndev->fw_log_buf_addr); + if (IS_ERR(ndev->fw_log_buf)) { + XDNA_WARN(xdna, "Failed to alloc fw log buffer, size 0x%x", + AIE4_FW_LOG_BUF_SIZE); + ndev->fw_log_buf = NULL; + return; + } + + ndev->fw_log_buf_size = buf_size; + XDNA_DBG(xdna, "FW log buffer allocated: size 0x%x", buf_size); +} + +/* + * Only called from the fini paths, after hw stop has already stopped the + * firmware, so the firmware cannot still be writing into the buffer. This + * mirrors the work buffer, which has no detach message either. + */ +static void aie4_free_fw_log_buffer(struct amdxdna_dev_hdl *ndev) +{ + struct amdxdna_dev *xdna = ndev->aie.xdna; + + if (!ndev->fw_log_buf) + return; + + amdxdna_free_msg_buffer(xdna, ndev->fw_log_buf_size, ndev->fw_log_buf, + ndev->fw_log_buf_addr); + ndev->fw_log_buf = NULL; +} + static int aie4_pf_init(struct amdxdna_dev *xdna) { int ret; @@ -972,6 +1018,8 @@ static int aie4_pf_init(struct amdxdna_dev *xdna) if (ret) return ret; + aie4_alloc_fw_log_buffer(xdna->dev_handle); + ret = aie4_pf_hw_start(xdna->dev_handle); if (ret) goto free_work_buf; @@ -979,6 +1027,7 @@ static int aie4_pf_init(struct amdxdna_dev *xdna) return 0; free_work_buf: + aie4_free_fw_log_buffer(xdna->dev_handle); aie4_free_work_buffer(xdna->dev_handle); return ret; } @@ -1006,6 +1055,8 @@ static int aie4_classic_init(struct amdxdna_dev *xdna) if (ret) return ret; + aie4_alloc_fw_log_buffer(xdna->dev_handle); + ret = aie4_classic_hw_start(xdna->dev_handle); if (ret) goto free_work_buf; @@ -1013,6 +1064,7 @@ static int aie4_classic_init(struct amdxdna_dev *xdna) return 0; free_work_buf: + aie4_free_fw_log_buffer(xdna->dev_handle); aie4_free_work_buffer(xdna->dev_handle); return ret; } @@ -1021,6 +1073,7 @@ static void aie4_pf_fini(struct amdxdna_dev *xdna) { aie4_sriov_stop(xdna->dev_handle); aie4_pf_hw_stop(xdna->dev_handle); + aie4_free_fw_log_buffer(xdna->dev_handle); aie4_free_work_buffer(xdna->dev_handle); } @@ -1032,6 +1085,7 @@ static void aie4_vf_fini(struct amdxdna_dev *xdna) static void aie4_classic_fini(struct amdxdna_dev *xdna) { aie4_classic_hw_stop(xdna->dev_handle); + aie4_free_fw_log_buffer(xdna->dev_handle); aie4_free_work_buffer(xdna->dev_handle); } diff --git a/drivers/accel/amdxdna/aie4_pci.h b/drivers/accel/amdxdna/aie4_pci.h index 062275be7ee7..18d1f03247d3 100644 --- a/drivers/accel/amdxdna/aie4_pci.h +++ b/drivers/accel/amdxdna/aie4_pci.h @@ -120,6 +120,10 @@ struct amdxdna_dev_hdl { dma_addr_t work_buf_addr; u32 work_buf_size; + void *fw_log_buf; + dma_addr_t fw_log_buf_addr; + u32 fw_log_buf_size; + u8 pw_mode; /* @@ -143,6 +147,7 @@ int aie4_query_aie_version(struct amdxdna_dev_hdl *ndev, struct amdxdna_drm_query_aie_version *version); int aie4_suspend_fw(struct amdxdna_dev_hdl *ndev); int aie4_attach_work_buffer(struct amdxdna_dev_hdl *ndev); +int aie4_start_fw_log(struct amdxdna_dev_hdl *ndev, u32 level); int aie4_query_npu_firmware_version(struct amdxdna_dev_hdl *ndev, struct amdxdna_drm_query_firmware_version *fw_version); int aie4_query_cert_firmware_version(struct amdxdna_dev_hdl *ndev, -- 2.34.1
