[PATCH 060/109] drm/amdgpu/ras: support loading RAS RL and TA firmware in RAS module
Alex Deucher <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
From: YiPeng Chai <[email protected]> Allow the RAS module to load RAS RL and TA firmware internally while maintaining backward compatibility with the system-level firmware loading path. Signed-off-by: YiPeng Chai <[email protected]> Reviewed-by: Hawking Zhang <[email protected]> Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/ras/core/ras.h | 7 +- drivers/gpu/drm/amd/ras/core/ras_psp.c | 320 +++++++++++------- drivers/gpu/drm/amd/ras/core/ras_psp.h | 47 ++- .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c | 83 ++--- .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c | 2 +- 5 files changed, 265 insertions(+), 194 deletions(-) diff --git a/drivers/gpu/drm/amd/ras/core/ras.h b/drivers/gpu/drm/amd/ras/core/ras.h index 17b1e7820855c..2311d988b3e52 100644 --- a/drivers/gpu/drm/amd/ras/core/ras.h +++ b/drivers/gpu/drm/amd/ras/core/ras.h @@ -260,7 +260,7 @@ enum gpu_mem_type { GPU_MEM_TYPE_RAS_PSP_RING, GPU_MEM_TYPE_RAS_PSP_CMD, GPU_MEM_TYPE_RAS_PSP_FENCE, - GPU_MEM_TYPE_RAS_TA_FW, + GPU_MEM_TYPE_RAS_FW_BIN, GPU_MEM_TYPE_RAS_TA_CMD, GPU_MEM_TYPE_ALLOC_MEM, GPU_MEM_TYPE_MAX @@ -269,9 +269,8 @@ enum gpu_mem_type { struct ras_psp_sys_func { int (*get_ras_psp_system_status)(struct ras_core_context *ras_core, struct ras_psp_sys_status *status); - int (*get_ras_ta_init_param)(struct ras_core_context *ras_core, - struct ras_ta_init_param *ras_ta_param); - void (*put_ras_ta_fini_param)(struct ras_core_context *ras_core); + int (*get_ras_param)(struct ras_core_context *ras_core, + struct ras_param *param); }; struct ras_sys_func { diff --git a/drivers/gpu/drm/amd/ras/core/ras_psp.c b/drivers/gpu/drm/amd/ras/core/ras_psp.c index d3cc992a462a7..36d6021afcf76 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_psp.c +++ b/drivers/gpu/drm/amd/ras/core/ras_psp.c @@ -38,6 +38,7 @@ #define RAS_PSP_FENCE_SIZE 0x1000 #define RAS_FW_BIN_SIZE 0x100000 #define RAS_TA_CMD_SIZE 0x100000 + static const struct ras_psp_ip_func *ras_psp_get_ip_funcs( struct ras_core_context *ras_core, uint32_t ip_version) { @@ -57,42 +58,41 @@ static const struct ras_psp_ip_func *ras_psp_get_ip_funcs( return NULL; } -static int ras_psp_sync_system_ras_psp_status(struct ras_core_context *ras_core) +static int ras_psp_get_system_ras_status(struct ras_core_context *ras_core, + struct ras_psp_sys_status *status) { struct ras_psp *psp = &ras_core->ras_psp; - struct ras_psp_ctx *psp_ctx = &ras_core->ras_psp.psp_ctx; - struct ras_psp_sys_status status = {0}; int ret; if (psp->sys_func && psp->sys_func->get_ras_psp_system_status) { - ret = psp->sys_func->get_ras_psp_system_status(ras_core, &status); + ret = psp->sys_func->get_ras_psp_system_status(ras_core, status); if (ret) return ret; - - psp_ctx->external_mutex = status.psp_cmd_mutex; } return 0; } -static int ras_psp_get_ras_ta_init_param(struct ras_core_context *ras_core, - struct ras_ta_init_param *ras_ta_param) +static int ras_psp_get_ras_param(struct ras_core_context *ras_core, + struct ras_param *param) { struct ras_psp *psp = &ras_core->ras_psp; + int ret; - if (psp->sys_func && psp->sys_func->get_ras_ta_init_param) - return psp->sys_func->get_ras_ta_init_param(ras_core, ras_ta_param); + if (!psp->sys_func || !psp->sys_func->get_ras_param) { + RAS_DEV_ERR(ras_core->dev, "Not config get_ras_ta_init_param API!!\n"); + return -EINVAL; + } - RAS_DEV_ERR(ras_core->dev, "Not config get_ras_ta_init_param API!!\n"); - return -EACCES; -} + ret = psp->sys_func->get_ras_param(ras_core, param); + if (ret) + return ret; -static void ras_psp_put_ras_ta_fini_param(struct ras_core_context *ras_core) -{ - struct ras_psp *psp = &ras_core->ras_psp; + param->ta_param.nps_mode = ras_core_get_curr_nps_mode(ras_core); + param->ta_param.vram_type = ras_core_get_vram_type(ras_core); + param->ta_param.poison_mode_en = ras_core_poison_supported(ras_core) ? 1 : 0; - if (psp->sys_func && psp->sys_func->put_ras_ta_fini_param) - psp->sys_func->put_ras_ta_fini_param(ras_core); + return 0; } static struct gpu_mem_block *ras_psp_alloc_mem(struct ras_core_context *ras_core, @@ -172,7 +172,7 @@ static int __ras_psp_mem_init(struct ras_core_context *ras_core) if (psp->use_dedicated_memory) { fw_bin = ras_psp_alloc_mem(ras_core, - GPU_MEM_TYPE_RAS_TA_FW, RAS_FW_BIN_SIZE); + GPU_MEM_TYPE_RAS_FW_BIN, RAS_FW_BIN_SIZE); if (!fw_bin) goto err; @@ -434,6 +434,7 @@ static int send_ras_ta_runtime_cmd(struct ras_core_context *ras_core, struct ras_ta_cmd *ras_cmd; struct psp_gfx_cmd_invoke_cmd invoke_cmd = {0}; struct psp_cmd_resp resp = {0}; + int got_reset_lock = 0; int ret = 0; if (!in || (in_size > sizeof(union ras_ta_cmd_input)) || @@ -451,8 +452,11 @@ static int send_ras_ta_runtime_cmd(struct ras_core_context *ras_core, if (!cmd_mem) return -ENOMEM; - if (!ras_core_down_trylock_gpu_reset_lock(ras_core)) - return -EACCES; + if (!ras_core_gpu_in_reset(ras_core)) { + got_reset_lock = ras_core_down_trylock_gpu_reset_lock(ras_core); + if (!got_reset_lock) + return -EACCES; + } ras_cmd = (struct ras_ta_cmd *)cmd_mem->mem_cpu_addr; @@ -497,7 +501,8 @@ static int send_ras_ta_runtime_cmd(struct ras_core_context *ras_core, unlock: mutex_unlock(&ta_ctx->ta_mutex); - ras_core_up_gpu_reset_lock(ras_core); + if (got_reset_lock) + ras_core_up_gpu_reset_lock(ras_core); return ret; } @@ -535,10 +540,57 @@ static int trigger_ras_ta_error(struct ras_core_context *ras_core, info, sizeof(*info), NULL, 0); } -static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, - struct ras_ta_ctx *ta_ctx, bool skip_lock) +static int load_ras_rl_fw(struct ras_core_context *ras_core, + struct ras_fw_bin *rl_bin) +{ + struct ras_psp *psp = &ras_core->ras_psp; + struct gpu_mem_block *fw_mem; + struct psp_gfx_cmd_load_ip_fw psp_load_rl_fw; + struct psp_cmd_resp resp = {0}; + int got_reset_lock = 0; + int ret = 0; + + fw_mem = psp->ta_ctx.fw_gpu_mem; + if (!fw_mem) + return -ENOMEM; + + if (!ras_core_gpu_in_reset(ras_core)) { + got_reset_lock = ras_core_down_trylock_gpu_reset_lock(ras_core); + if (!got_reset_lock) + return -EACCES; + } + + mutex_lock(&psp->ta_ctx.ta_mutex); + /* copy ras RL to shared gpu memory */ + memcpy(fw_mem->mem_cpu_addr, rl_bin->bin_addr, rl_bin->bin_size); + fw_mem->mem_size = rl_bin->bin_size; + + /* Setup load RL command */ + memset(&psp_load_rl_fw, 0, sizeof(psp_load_rl_fw)); + psp_load_rl_fw.fw_phy_addr_lo = lower_32_bits(fw_mem->mem_mc_addr); + psp_load_rl_fw.fw_phy_addr_hi = upper_32_bits(fw_mem->mem_mc_addr); + psp_load_rl_fw.fw_size = fw_mem->mem_size; + psp_load_rl_fw.fw_type = GFX_FW_TYPE_REG_LIST; + + ret = send_psp_cmd(ras_core, GFX_CMD_ID_LOAD_IP_FW, + &psp_load_rl_fw, sizeof(psp_load_rl_fw), &resp); + if (ret || resp.status) { + RAS_DEV_ERR(ras_core->dev, + "Failed to load RAS WL. ret:%d, status:%d\n", ret, resp.status); + ret = -EPIPE; + } + + mutex_unlock(&psp->ta_ctx.ta_mutex); + if (got_reset_lock) + ras_core_up_gpu_reset_lock(ras_core); + + return ret; +} + +static int load_ras_ta_fw(struct ras_core_context *ras_core, + struct ras_fw_bin *ta_bin, struct ras_ta_param *ta_param) { - struct ras_ta_fw_bin *fw_bin = &ta_ctx->fw_bin; + struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; struct gpu_mem_block *fw_mem = NULL; struct gpu_mem_block *cmd_mem = NULL; struct ras_ta_cmd *ta_cmd; @@ -546,41 +598,38 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, struct psp_gfx_cmd_load_ta psp_load_ta_cmd; struct psp_cmd_resp resp = {0}; struct ras_ta_image_header *fw_hdr = NULL; + int got_reset_lock = 0; int ret; - ret = ras_psp_get_ras_ta_init_param(ras_core, &ta_ctx->init_param); - if (ret) - return ret; - fw_mem = ta_ctx->fw_gpu_mem; cmd_mem = ta_ctx->cmd_gpu_mem; if (!fw_mem || !cmd_mem) return -ENOMEM; - /* - * When skip_lock is true (called from .resume), the PSP has already - * been re-initialized and it is safe to proceed without the read lock - * (GPU reset holds write lock; S3/S4 has no lock to acquire). - */ - if (!skip_lock && !ras_core_down_trylock_gpu_reset_lock(ras_core)) - return -EACCES; + if (!ras_core_gpu_in_reset(ras_core)) { + got_reset_lock = ras_core_down_trylock_gpu_reset_lock(ras_core); + if (!got_reset_lock) + return -EACCES; + } + + mutex_lock(&ta_ctx->ta_mutex); /* copy ras ta binary to shared gpu memory */ - memcpy(fw_mem->mem_cpu_addr, fw_bin->bin_addr, fw_bin->bin_size); - fw_mem->mem_size = fw_bin->bin_size; + memcpy(fw_mem->mem_cpu_addr, ta_bin->bin_addr, ta_bin->bin_size); + fw_mem->mem_size = ta_bin->bin_size; /* Initialize ras ta startup parameter */ ta_cmd = (struct ras_ta_cmd *)cmd_mem->mem_cpu_addr; ta_init_flags = &ta_cmd->ras_in_message.init_flags; - ta_init_flags->poison_mode_en = ta_ctx->init_param.poison_mode_en; - ta_init_flags->dgpu_mode = ta_ctx->init_param.dgpu_mode; - ta_init_flags->xcc_mask = ta_ctx->init_param.xcc_mask; - ta_init_flags->channel_dis_num = ta_ctx->init_param.channel_dis_num; - ta_init_flags->nps_mode = ta_ctx->init_param.nps_mode; - ta_init_flags->active_umc_mask = ta_ctx->init_param.active_umc_mask; - ta_init_flags->vram_type = ta_ctx->init_param.vram_type; - ta_init_flags->ext_umc_mask = ta_ctx->init_param.ext_umc_mask; + ta_init_flags->poison_mode_en = ta_param->poison_mode_en; + ta_init_flags->dgpu_mode = ta_param->dgpu_mode; + ta_init_flags->xcc_mask = ta_param->xcc_mask; + ta_init_flags->channel_dis_num = ta_param->channel_dis_num; + ta_init_flags->nps_mode = ta_param->nps_mode; + ta_init_flags->active_umc_mask = ta_param->active_umc_mask; + ta_init_flags->vram_type = ta_param->vram_type; + ta_init_flags->ext_umc_mask = ta_param->ext_umc_mask; /* Setup load ras ta command */ memset(&psp_load_ta_cmd, 0, sizeof(psp_load_ta_cmd)); @@ -595,7 +644,7 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, &psp_load_ta_cmd, sizeof(psp_load_ta_cmd), &resp); if (!ret && !resp.status) { /* Read TA version at FW offset 0x60 if TA version not found*/ - fw_hdr = (struct ras_ta_image_header *)fw_bin->bin_addr; + fw_hdr = (struct ras_ta_image_header *)ta_bin->bin_addr; RAS_DEV_INFO(ras_core->dev, "PSP: RAS TA(version:%X.%X.%X.%X) is loaded.\n", (fw_hdr->image_version >> 24) & 0xFF, (fw_hdr->image_version >> 16) & 0xFF, (fw_hdr->image_version >> 8) & 0xFF, fw_hdr->image_version & 0xFF); @@ -605,32 +654,27 @@ static int send_load_ta_fw_cmd(struct ras_core_context *ras_core, } else { RAS_DEV_ERR(ras_core->dev, "Failed to load RAS TA! ret:%d, status:%d\n", ret, resp.status); + ret = -EPIPE; } - if (!skip_lock) + mutex_unlock(&ta_ctx->ta_mutex); + if (got_reset_lock) ras_core_up_gpu_reset_lock(ras_core); return ret; } -static int load_ras_ta_firmware(struct ras_core_context *ras_core, bool skip_lock) -{ - struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - int ret; - - ret = send_load_ta_fw_cmd(ras_core, ta_ctx, skip_lock); - return ret; -} - -static int unload_ras_ta_firmware(struct ras_core_context *ras_core, +static int unload_ras_ta_fw(struct ras_core_context *ras_core, struct ras_psp_ta_unload *ras_ta_unload) { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; struct psp_gfx_cmd_unload_ta cmd_unload_ta = {0}; struct psp_cmd_resp resp = {0}; + int got_reset_lock = 0; int ret; - if (!ras_core_down_trylock_gpu_reset_lock(ras_core)) + got_reset_lock = ras_core_down_trylock_gpu_reset_lock(ras_core); + if (!got_reset_lock) return -EACCES; cmd_unload_ta.session_id = ta_ctx->session_id; @@ -650,52 +694,86 @@ static int unload_ras_ta_firmware(struct ras_core_context *ras_core, ta_ctx->ta_version = 0; ta_ctx->ras_ta_initialized = false; ta_ctx->session_id = 0; + unlock: - ras_core_up_gpu_reset_lock(ras_core); + if (got_reset_lock) + ras_core_up_gpu_reset_lock(ras_core); return ret; } -int ras_psp_load_firmware(struct ras_core_context *ras_core, - bool skip_lock) +static int load_ras_all_fw(struct ras_core_context *ras_core) +{ + struct ras_param ras_param = {0}; + int ret; + + ret = ras_psp_get_ras_param(ras_core, &ras_param); + if (ret) + return ret; + + ret = load_ras_rl_fw(ras_core, &ras_param.fw_param.rl_bin); + if (ret) + return ret; + + return load_ras_ta_fw(ras_core, + &ras_param.fw_param.ta_bin, &ras_param.ta_param); +} + +static int unload_ras_all_fw(struct ras_core_context *ras_core) { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - struct ras_psp_ta_unload ras_ta_unload = {0}; - int ret = 0; + struct ras_psp_ta_unload ta_unload = {0}; - if (skip_lock) { - /* - * Called from .resume: PSP has been re-initialized after a GPU - * reset or S3/S4, so any previous TA session is gone. Clear - * stale state and proceed directly to a fresh load, bypassing - * both the unload step and the reset read-lock acquisition - * (which would deadlock inside a GPU reset). - */ - ta_ctx->preload_ras_ta_enabled = false; + if (ta_ctx->ras_ta_initialized) { + ta_unload.ras_session_id = ta_ctx->session_id; + unload_ras_ta_fw(ras_core, &ta_unload); ta_ctx->ras_ta_initialized = false; ta_ctx->session_id = 0; ta_ctx->ta_version = 0; - } else { - /* - * Normal path: only skip a reload when the current TA session is - * known to be alive. Firmware metadata may already be cached even - * when the TA is not loaded, so that must not suppress a reload. - */ - if (ta_ctx->preload_ras_ta_enabled && ta_ctx->ras_ta_initialized) - return 0; + } - if (ta_ctx->ras_ta_initialized) { - ras_ta_unload.ras_session_id = ta_ctx->session_id; - ret = unload_ras_ta_firmware(ras_core, &ras_ta_unload); - if (ret) - return ret; - } + return 0; +} + +int ras_psp_sideload_ras_ta(struct ras_core_context *ras_core, + struct ras_psp_ta_load *ta_load) +{ + struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; + struct ras_psp_ta_unload ras_ta_unload = {0}; + struct ras_param ras_param = {0}; + struct ras_fw_bin ta_bin = {0}; + int ret = 0; + + if (!ta_load || !ta_load->bin_addr || !ta_load->bin_size) + return -EINVAL; + + if (ta_ctx->ras_ta_initialized) { + ras_ta_unload.ras_session_id = ta_ctx->session_id; + ret = unload_ras_ta_fw(ras_core, &ras_ta_unload); + if (ret) + return ret; } - return load_ras_ta_firmware(ras_core, skip_lock); + ret = ras_psp_get_ras_param(ras_core, &ras_param); + if (ret) + return ret; + + ta_bin.bin_addr = ta_load->bin_addr; + ta_bin.bin_size = ta_load->bin_size; + ta_bin.fw_version = ta_load->fw_version; + ta_bin.feature_version = ta_load->feature_version; + + ret = load_ras_ta_fw(ras_core, &ta_bin, &ras_param.ta_param); + if (ret) + return ret; + + ta_load->out_session_id = ta_ctx->session_id; + ta_load->out_loaded_ta_version = ta_ctx->ta_version; + + return 0; } -int ras_psp_unload_firmware(struct ras_core_context *ras_core, +int ras_psp_unsideload_ras_ta(struct ras_core_context *ras_core, struct ras_psp_ta_unload *ras_ta_unload) { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; @@ -704,7 +782,19 @@ int ras_psp_unload_firmware(struct ras_core_context *ras_core, (ras_ta_unload->ras_session_id != ta_ctx->session_id)) return -EINVAL; - return unload_ras_ta_firmware(ras_core, ras_ta_unload); + return unload_ras_ta_fw(ras_core, ras_ta_unload); +} + +int ras_psp_reload_firmwares(struct ras_core_context *ras_core, + uint32_t flags) +{ + struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; + + ta_ctx->ras_ta_initialized = false; + ta_ctx->session_id = 0; + ta_ctx->ta_version = 0; + + return load_ras_all_fw(ras_core); } int ras_psp_trigger_error(struct ras_core_context *ras_core, @@ -712,7 +802,7 @@ int ras_psp_trigger_error(struct ras_core_context *ras_core, { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - if (!ta_ctx->preload_ras_ta_enabled && !ta_ctx->ras_ta_initialized) { + if (!ta_ctx->ras_ta_initialized) { RAS_DEV_ERR(ras_core->dev, "RAS: ras firmware not initialized!"); return -ENOEXEC; } @@ -729,8 +819,7 @@ int ras_psp_query_address(struct ras_core_context *ras_core, { struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - if (!ta_ctx->preload_ras_ta_enabled && - !ta_ctx->ras_ta_initialized) { + if (!ta_ctx->ras_ta_initialized) { RAS_DEV_ERR(ras_core->dev, "RAS: ras firmware not initialized!"); return -ENOEXEC; } @@ -779,6 +868,7 @@ int ras_psp_hw_init(struct ras_core_context *ras_core) int ret = 0; struct ras_psp *psp = &ras_core->ras_psp; struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; + struct ras_psp_sys_status sys_status = {0}; psp->psp_ip_version = ras_core->config->psp_ip_version; @@ -798,36 +888,34 @@ int ras_psp_hw_init(struct ras_core_context *ras_core) /* After GPU reset, the system RAS PSP status may change. * therefore, it is necessary to synchronize the system status again. */ - ras_psp_sync_system_ras_psp_status(ras_core); + ret = ras_psp_get_system_ras_status(ras_core, &sys_status); + if (ret) + return ret; + + if (sys_status.uniras_load_fw) { + ta_ctx->ras_ta_initialized = false; + psp->load_ras_fw_internal = true; + } else { + ta_ctx->ras_ta_initialized = true; + psp->load_ras_fw_internal = false; + } + + psp->use_dedicated_memory = sys_status.use_dedicated_memory; + psp->psp_ctx.external_mutex = sys_status.psp_cmd_mutex; ret = __ras_psp_mem_init(ras_core); if (ret) return ret; - if (!ta_ctx->preload_ras_ta_enabled && !ta_ctx->ras_ta_initialized) - ret = ras_psp_load_firmware(ras_core, false); + if (psp->load_ras_fw_internal) + ret = load_ras_all_fw(ras_core); return ret; } int ras_psp_hw_fini(struct ras_core_context *ras_core) { - struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - struct ras_psp_ta_unload ras_ta_unload = {0}; - - if (ta_ctx->ras_ta_initialized) { - ras_ta_unload.ras_session_id = ta_ctx->session_id; - ras_psp_unload_firmware(ras_core, &ras_ta_unload); - } - - ta_ctx->ta_version = 0; - ta_ctx->ras_ta_initialized = false; - ta_ctx->preload_ras_ta_enabled = false; - ta_ctx->session_id = 0; - - /* Free shared BO only on hw_fini, not on suspend */ - ras_psp_put_ras_ta_fini_param(ras_core); - + unload_ras_all_fw(ras_core); return 0; } @@ -837,16 +925,12 @@ bool ras_psp_check_supported_cmd(struct ras_core_context *ras_core, struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; bool ret = false; - if (!ta_ctx->preload_ras_ta_enabled && !ta_ctx->ras_ta_initialized) + if (!ta_ctx->ras_ta_initialized) return false; switch (cmd_id) { case RAS_TA_CMD_ID__QUERY_ADDRESS: - /* Currently, querying the address from RAS TA is only supported - * when the RAS TA firmware is loaded during driver installation. - */ - if (ta_ctx->preload_ras_ta_enabled) - ret = true; + ret = true; break; case RAS_TA_CMD_ID__TRIGGER_ERROR: ret = true; diff --git a/drivers/gpu/drm/amd/ras/core/ras_psp.h b/drivers/gpu/drm/amd/ras/core/ras_psp.h index 8a483a842e04e..5e668730cf176 100644 --- a/drivers/gpu/drm/amd/ras/core/ras_psp.h +++ b/drivers/gpu/drm/amd/ras/core/ras_psp.h @@ -43,9 +43,10 @@ struct ras_ta_image_header { struct ras_psp_sys_status { void *psp_cmd_mutex; bool use_dedicated_memory; + bool uniras_load_fw; }; -struct ras_ta_init_param { +struct ras_ta_param { uint8_t poison_mode_en; uint8_t dgpu_mode; uint16_t xcc_mask; @@ -56,6 +57,23 @@ struct ras_ta_init_param { uint32_t ext_umc_mask; }; +struct ras_fw_bin { + uint32_t fw_version; + uint32_t feature_version; + uint32_t bin_size; + uint8_t *bin_addr; +}; + +struct ras_fw_param { + struct ras_fw_bin rl_bin; + struct ras_fw_bin ta_bin; +}; + +struct ras_param { + struct ras_fw_param fw_param; + struct ras_ta_param ta_param; +}; + struct gpu_mem_block { uint32_t mem_type; void *mem_bo; @@ -113,28 +131,20 @@ struct ras_psp_ctx { struct gpu_mem_block *out_fence_gpu_mem; }; -struct ras_ta_fw_bin { - uint32_t fw_version; - uint32_t feature_version; - uint32_t bin_size; - uint8_t *bin_addr; -}; - struct ras_ta_ctx { - bool preload_ras_ta_enabled; bool ras_ta_initialized; uint32_t session_id; uint32_t resp_status; uint32_t ta_version; struct mutex ta_mutex; - struct ras_ta_fw_bin fw_bin; - struct ras_ta_init_param init_param; + struct ras_fw_bin fw_bin; struct gpu_mem_block *fw_gpu_mem; struct gpu_mem_block *cmd_gpu_mem; }; struct ras_psp { bool use_dedicated_memory; + bool load_ras_fw_internal; uint32_t psp_ip_version; struct ras_block_map *blk_maps; uint32_t maps_size; @@ -146,6 +156,15 @@ struct ras_psp { const struct ras_psp_sys_func *sys_func; }; +struct ras_psp_ta_load { + uint32_t fw_version; + uint32_t feature_version; + uint32_t bin_size; + uint8_t *bin_addr; + uint64_t out_session_id; + uint32_t out_loaded_ta_version; +}; + struct ras_psp_ta_unload { uint64_t ras_session_id; }; @@ -155,8 +174,10 @@ int ras_psp_sw_fini(struct ras_core_context *ras_core); int ras_psp_hw_init(struct ras_core_context *ras_core); int ras_psp_hw_fini(struct ras_core_context *ras_core); -int ras_psp_load_firmware(struct ras_core_context *ras_core, bool skip_lock); -int ras_psp_unload_firmware(struct ras_core_context *ras_core, +int ras_psp_reload_firmwares(struct ras_core_context *ras_core, uint32_t flags); +int ras_psp_sideload_ras_ta(struct ras_core_context *ras_core, + struct ras_psp_ta_load *ta_load); +int ras_psp_unsideload_ras_ta(struct ras_core_context *ras_core, struct ras_psp_ta_unload *ras_ta_unload); int ras_psp_trigger_error(struct ras_core_context *ras_core, struct ras_ta_trigger_error_input *info, uint32_t instance_mask); diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c index 3abd33796c032..3797a17385b44 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c @@ -190,76 +190,47 @@ static int amdgpu_ras_mgr_get_ras_psp_system_status(struct ras_core_context *ras struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev; status->psp_cmd_mutex = &adev->psp.mutex; + status->uniras_load_fw = false; + + status->use_dedicated_memory = !status->uniras_load_fw; return 0; } -static int amdgpu_ras_mgr_get_ras_ta_init_param(struct ras_core_context *ras_core, - struct ras_ta_init_param *ras_ta_param) +static int amdgpu_ras_mgr_get_ras_param(struct ras_core_context *ras_core, + struct ras_param *param) { struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev; - struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx; - struct ras_ta_fw_bin *fw_bin = &ta_ctx->fw_bin; struct ta_context *context = &adev->psp.ras_context.context; - struct ta_mem_context *mem_ctx = &context->mem_context; - uint32_t nps_mode; - if (ras_core_poison_supported(ras_core)) - ras_ta_param->poison_mode_en = 1; + if (!param) + return -EINVAL; if (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu) - ras_ta_param->dgpu_mode = 1; - - ras_ta_param->xcc_mask = adev->gfx.xcc_mask; - ras_ta_param->channel_dis_num = hweight32(adev->gmc.m_half_use) * 2; - - ras_ta_param->active_umc_mask = lower_32_bits(adev->umc.active_mask); - ras_ta_param->ext_umc_mask = upper_32_bits(adev->umc.active_mask); - ras_ta_param->vram_type = (uint8_t)adev->gmc.vram_type; - - if (!amdgpu_ras_mgr_get_curr_nps_mode(adev, &nps_mode)) - ras_ta_param->nps_mode = nps_mode; - - /* If RAS TA is not initialized, it means RAS TA is not loaded. In this case, RAS module - * needs to get the FW bin info from the context and load RAS TA. - */ - if (!ta_ctx->ras_ta_initialized) { - fw_bin->fw_version = context->bin_desc.fw_version; - fw_bin->feature_version = context->bin_desc.feature_version; - fw_bin->bin_size = context->bin_desc.size_bytes; - fw_bin->bin_addr = context->bin_desc.start_addr; - - if (!mem_ctx->shared_buf) { - mem_ctx->shared_mem_size = PSP_RAS_SHARED_MEM_SIZE; - return amdgpu_bo_create_kernel(adev, mem_ctx->shared_mem_size, - PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM | - AMDGPU_GEM_DOMAIN_GTT, - &mem_ctx->shared_bo, - &mem_ctx->shared_mc_addr, - &mem_ctx->shared_buf); - } - } + param->ta_param.dgpu_mode = 1; - return 0; -} + param->ta_param.xcc_mask = adev->gfx.xcc_mask; + param->ta_param.channel_dis_num = hweight32(adev->gmc.m_half_use) * 2; -static void amdgpu_ras_mgr_put_ras_ta_fini_param(struct ras_core_context *ras_core) -{ - struct amdgpu_device *adev = (struct amdgpu_device *)ras_core->dev; - struct ta_context *context = &adev->psp.ras_context.context; - struct ta_mem_context *mem_ctx = &context->mem_context; + param->ta_param.active_umc_mask = lower_32_bits(adev->umc.active_mask); + param->ta_param.ext_umc_mask = upper_32_bits(adev->umc.active_mask); - if (mem_ctx->shared_buf) { - amdgpu_bo_free_kernel(&mem_ctx->shared_bo, - &mem_ctx->shared_mc_addr, - &mem_ctx->shared_buf); - } + param->fw_param.rl_bin.fw_version = adev->psp.rl.fw_version; + param->fw_param.rl_bin.feature_version = adev->psp.rl.feature_version; + param->fw_param.rl_bin.bin_size = adev->psp.rl.size_bytes; + param->fw_param.rl_bin.bin_addr = adev->psp.rl.start_addr; + + param->fw_param.ta_bin.fw_version = context->bin_desc.fw_version; + param->fw_param.ta_bin.feature_version = context->bin_desc.feature_version; + param->fw_param.ta_bin.bin_size = context->bin_desc.size_bytes; + param->fw_param.ta_bin.bin_addr = context->bin_desc.start_addr; + + return 0; } const struct ras_psp_sys_func amdgpu_ras_psp_sys_func = { .get_ras_psp_system_status = amdgpu_ras_mgr_get_ras_psp_system_status, - .get_ras_ta_init_param = amdgpu_ras_mgr_get_ras_ta_init_param, - .put_ras_ta_fini_param = amdgpu_ras_mgr_put_ras_ta_fini_param, + .get_ras_param = amdgpu_ras_mgr_get_ras_param, }; static int amdgpu_ras_mgr_init_psp_config(struct amdgpu_device *adev, @@ -517,11 +488,7 @@ static int amdgpu_ras_mgr_resume(struct amdgpu_ip_block *ip_block) if (!ras_mgr || !ras_mgr->ras_core) return 0; - /* - * Pass skip_lock=true: PSP is re-initialized after GPU reset or - * S3/S4, so bypass the trylock and clear stale TA session state. - */ - ret = ras_psp_load_firmware(ras_mgr->ras_core, true); + ret = ras_psp_reload_firmwares(ras_mgr->ras_core, 0); if (ret) RAS_DEV_ERR(adev, "Failed to reload RAS TA on resume, ret:%d\n", ret); diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c index 3c91aea68ebc4..7bc827cc8e9fc 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_sys.c @@ -268,7 +268,7 @@ static int amdgpu_ras_sys_get_gpu_mem(struct ras_core_context *ras_core, gpu_mem->mem_size = PSP_FENCE_BUFFER_SIZE; gpu_mem->mem_mc_addr = psp->fence_buf_mc_addr; gpu_mem->mem_cpu_addr = psp->fence_buf; - } else if (mem_type == GPU_MEM_TYPE_RAS_TA_FW) { + } else if (mem_type == GPU_MEM_TYPE_RAS_FW_BIN) { gpu_mem->mem_bo = psp->fw_pri_bo; gpu_mem->mem_size = PSP_1_MEG; gpu_mem->mem_mc_addr = psp->fw_pri_mc_addr; -- 2.55.0