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

Reply via email to