[PATCH 1/3] drm/amd/ras: request GFX RAS features through ras_mgr
Xiang Liu <[email protected]>
| Newsgroups | org.freedesktop.lists.amd-gfx |
|---|---|
| Message-ID | <[email protected]> |
psp_ras_enable_features() returns 0 without sending anything once the
RAS TA is loaded by ras_mgr, and nothing on that path sends
ENABLE_FEATURES either. GFX RAS features therefore end up enabled by no
one, silently, because the helper still reports success.
This is harmless at boot, where the TA is loaded with poison_mode_en set
while GFX is freshly initialized. It is not harmless across a reset: a
mode2 reset clears the GFX side, amdgpu_gfx_ras_late_init() re-runs from
the reset handler but its enable request goes nowhere, and GFX stops
raising SQ EDC_FED. The visible effect is that only the first poison
injection after boot is ever consumed. Every later one creates the
poison in HBM and is never reported, since the first injection triggers
the reset that breaks reporting.
Add ras_psp_enable_features() to send ENABLE_FEATURES/DISABLE_FEATURES
to the TA owned by ras_mgr, and route amdgpu_ras_feature_enable()
through it. Newer parts arm RAS features inside the TA and must not be
toggled by the driver, so restrict the request to GFX IP versions below
12.1.0.
Fixes: c8a0dcadcec6 ("drm/amdgpu: add switch to select firmware loading path for RAS RL and TA")
Signed-off-by: Xiang Liu <[email protected]>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c | 9 ++++++-
drivers/gpu/drm/amd/ras/core/ras_psp.c | 19 +++++++++++++
drivers/gpu/drm/amd/ras/core/ras_psp.h | 2 ++
.../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c | 27 +++++++++++++++++++
.../gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h | 2 ++
5 files changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
index 572403cb6121..d168e5d54d87 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
@@ -933,7 +933,14 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev,
};
}
- ret = psp_ras_enable_features(&adev->psp, info, enable);
+ if (amdgpu_uniras_enabled(adev))
+ ret = amdgpu_ras_mgr_enable_feature(adev,
+ amdgpu_ras_block_to_ta(head->block),
+ amdgpu_ras_error_to_ta(head->type),
+ enable);
+ else
+ ret = psp_ras_enable_features(&adev->psp, info, enable);
+
if (ret) {
dev_err(adev->dev, "ras %s %s failed poison:%d ret:%d\n",
enable ? "enable":"disable",
diff --git a/drivers/gpu/drm/amd/ras/core/ras_psp.c b/drivers/gpu/drm/amd/ras/core/ras_psp.c
index 102dffe9d498..ed53cd25d6bd 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_psp.c
+++ b/drivers/gpu/drm/amd/ras/core/ras_psp.c
@@ -797,6 +797,25 @@ int ras_psp_reload_firmwares(struct ras_core_context *ras_core,
return load_ras_all_fw(ras_core);
}
+int ras_psp_enable_features(struct ras_core_context *ras_core,
+ struct ras_ta_enable_features_input *info, bool enable)
+{
+ struct ras_ta_ctx *ta_ctx = &ras_core->ras_psp.ta_ctx;
+
+ if (!info)
+ return -EINVAL;
+
+ if (!ta_ctx->ras_ta_initialized) {
+ RAS_DEV_ERR(ras_core->dev, "RAS: ras firmware not initialized!");
+ return -ENOEXEC;
+ }
+
+ return send_ras_ta_runtime_cmd(ras_core,
+ enable ? RAS_TA_CMD_ID__ENABLE_FEATURES :
+ RAS_TA_CMD_ID__DISABLE_FEATURES,
+ info, sizeof(*info), NULL, 0);
+}
+
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/core/ras_psp.h b/drivers/gpu/drm/amd/ras/core/ras_psp.h
index 041d46eee3f4..4cc133c6a6d3 100644
--- a/drivers/gpu/drm/amd/ras/core/ras_psp.h
+++ b/drivers/gpu/drm/amd/ras/core/ras_psp.h
@@ -196,6 +196,8 @@ 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_enable_features(struct ras_core_context *ras_core,
+ struct ras_ta_enable_features_input *info, bool enable);
int ras_psp_trigger_error(struct ras_core_context *ras_core,
struct ras_ta_trigger_error_input *info, uint32_t instance_mask);
int ras_psp_query_address(struct ras_core_context *ras_core,
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 e6941de46787..3d806e35382a 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
@@ -772,6 +772,33 @@ int amdgpu_ras_mgr_post_reset(struct amdgpu_device *adev)
return 0;
}
+int amdgpu_ras_mgr_enable_feature(struct amdgpu_device *adev,
+ uint32_t ta_block_id, uint32_t ta_error_type, bool enable)
+{
+ struct amdgpu_ras_mgr *ras_mgr = amdgpu_ras_mgr_get_context(adev);
+ struct ras_ta_enable_features_input info = {
+ .block_id = (enum ras_ta_block)ta_block_id,
+ .error_type = (enum ras_ta_error_type)ta_error_type,
+ };
+ uint32_t gfx_ip_version;
+
+ if (!ras_mgr || !ras_mgr->ras_core)
+ return -EINVAL;
+
+ if (ras_core_get_ip_version(ras_mgr->ras_core,
+ RAS_UNIT_ID_GFX, &gfx_ip_version))
+ return -EPERM;
+
+ /* Newer parts arm RAS features inside the TA, so the driver must not
+ * toggle them. Older ones still need an explicit request after every
+ * GPU reset, otherwise GFX stops reporting poison consumption.
+ */
+ if (gfx_ip_version >= IP_VERSION(12, 1, 0))
+ return 0;
+
+ return ras_psp_enable_features(ras_mgr->ras_core, &info, enable);
+}
+
int amdgpu_ras_mgr_lookup_bad_pages_in_a_row(struct amdgpu_device *adev,
uint64_t addr, uint64_t *nps_page_addr, uint32_t max_page_count)
{
diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
index 442d628ccfec..99b3e6995e12 100644
--- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
+++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.h
@@ -85,6 +85,8 @@ int amdgpu_ras_mgr_handle_ras_cmd(struct amdgpu_device *adev,
void *output, uint32_t out_size);
int amdgpu_ras_mgr_pre_reset(struct amdgpu_device *adev);
int amdgpu_ras_mgr_post_reset(struct amdgpu_device *adev);
+int amdgpu_ras_mgr_enable_feature(struct amdgpu_device *adev,
+ uint32_t ta_block_id, uint32_t ta_error_type, bool enable);
int amdgpu_ras_mgr_resume_after_reset(struct amdgpu_device *adev);
int amdgpu_ras_mgr_lookup_bad_pages_in_a_row(struct amdgpu_device *adev,
uint64_t addr, uint64_t *nps_page_addr, uint32_t max_page_count);
--
2.34.1