summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTao Zhou <tao.zhou1@amd.com>2025-04-02 16:06:58 +0800
committerAlex Deucher <alexander.deucher@amd.com>2025-05-13 09:31:46 -0400
commit4ce5b991284ee423f602ccce84fc8bf2d273c757 (patch)
treed54794d9e31d44f3c69f1397949de5028657dbb5
parent1df57411a658fd8b411323f8dd0d67e789b9c777 (diff)
drm/amdgpu: adjust high bits for RAS retired page
Per UMC address conversion algorithm, the high row bits of UMC MCA address are changed when they're converted into normalized address on specific ASICs. Signed-off-by: Tao Zhou <tao.zhou1@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/umc_v12_0.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
index da00d6b3b6a3..5201c106e369 100644
--- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c
@@ -180,7 +180,7 @@ static int umc_v12_0_convert_error_address(struct amdgpu_device *adev,
struct ta_ras_query_address_output *addr_out,
bool dump_addr)
{
- uint32_t col, col_lower, row, row_lower, bank;
+ uint32_t col, col_lower, row, row_lower, row_high, bank;
uint32_t channel_index = 0, umc_inst = 0;
uint32_t i, loop_bits[UMC_V12_0_RETIRE_LOOP_BITS];
uint64_t soc_pa, column, err_addr;
@@ -243,9 +243,18 @@ static int umc_v12_0_convert_error_address(struct amdgpu_device *adev,
paddr_out->pa.pa = soc_pa;
/* get column bit 0 and 1 in mca address */
col_lower = (err_addr >> 1) & 0x3ULL;
- /* MA_R13_BIT will be handled later */
+ /* extra row bit will be handled later */
row_lower = (err_addr >> UMC_V12_0_MA_R0_BIT) & 0x1fffULL;
+ if (amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(9, 5, 0)) {
+ row_high = (soc_pa >> UMC_V12_0_PA_R13_BIT) & 0x3ULL;
+ /* it's 2.25GB in each channel, from MCA address to PA
+ * [R14 R13] is converted if the two bits value are 0x3,
+ * get them from PA instead of MCA address.
+ */
+ row_lower |= (row_high << 13);
+ }
+
if (!err_data && !dump_addr)
goto out;