[PATCH 058/109] drm/amdgpu/ras: reload RAS TA from ras mgr resume

Alex Deucher <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
From: Xiang Liu <[email protected]>

When uniras owns the RAS TA, rascore can no longer rely on the legacy
PSP context to keep TA session state alive across reset or suspend.
The manager has to provide enough metadata to reload the TA and rebuild
its shared buffer after PSP reinitialization.

Source TA firmware metadata from adev->psp.ras_context.context.bin_desc,
allocate and free the shared buffer on demand, and hand the fini
cleanup back to rascore through a put_ras_ta_fini_param callback. Add a
resume hook that reloads the TA with skip_lock set so the reload can
run after GPU reset.

Export thin ras_mgr helpers for feature toggles and deferred replay so
higher layers can use the rascore-owned TA path without depending on
legacy PSP-managed TA session state directly.

Signed-off-by: Jinzhou Su <[email protected]>
Signed-off-by: Xiang Liu <[email protected]>
Reviewed-by: Hawking Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
---
 .../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c  | 74 +++++++++++++++++++
 1 file changed, 74 insertions(+)

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 29558888832c1..3abd33796c032 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
@@ -198,6 +198,14 @@ static int amdgpu_ras_mgr_get_ras_ta_init_param(struct ras_core_context *ras_cor
 	struct ras_ta_init_param *ras_ta_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 (!adev->gmc.xgmi.connected_to_cpu && !adev->gmc.is_app_apu)
 		ras_ta_param->dgpu_mode = 1;
@@ -207,13 +215,51 @@ static int amdgpu_ras_mgr_get_ras_ta_init_param(struct ras_core_context *ras_cor
 
 	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);
+		}
+	}
 
 	return 0;
 }
 
+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;
+
+	if (mem_ctx->shared_buf) {
+		amdgpu_bo_free_kernel(&mem_ctx->shared_bo,
+				      &mem_ctx->shared_mc_addr,
+				      &mem_ctx->shared_buf);
+	}
+}
+
 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,
 };
 
 static int amdgpu_ras_mgr_init_psp_config(struct amdgpu_device *adev,
@@ -457,10 +503,38 @@ struct amdgpu_ras_mgr *amdgpu_ras_mgr_get_context(struct amdgpu_device *adev)
 	return (struct amdgpu_ras_mgr *)adev->psp.ras_context.ras->ras_mgr;
 }
 
+static int amdgpu_ras_mgr_suspend(struct amdgpu_ip_block *ip_block)
+{
+	return 0;
+}
+
+static int amdgpu_ras_mgr_resume(struct amdgpu_ip_block *ip_block)
+{
+	struct amdgpu_device *adev = ip_block->adev;
+	struct amdgpu_ras_mgr *ras_mgr = amdgpu_ras_mgr_get_context(adev);
+	int ret;
+
+	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);
+	if (ret)
+		RAS_DEV_ERR(adev,
+			    "Failed to reload RAS TA on resume, ret:%d\n", ret);
+
+	return ret;
+}
+
 static const struct amd_ip_funcs __maybe_unused ras_v1_0_ip_funcs = {
 	.name = "ras_v1_0",
 	.hw_init = amdgpu_ras_mgr_hw_init,
 	.hw_fini = amdgpu_ras_mgr_hw_fini,
+	.suspend = amdgpu_ras_mgr_suspend,
+	.resume = amdgpu_ras_mgr_resume,
 };
 
 const struct amdgpu_ip_block_version ras_v1_0_ip_block = {
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.