Skip to content

Commit

Permalink
drm/amdgpu: support to convert dedicated umc mca address
Browse files Browse the repository at this point in the history
Update umc error address query interface, the mca address can be read
from register or input from parameter.

TODO: define a common address conversion function to simplify the code.

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>
  • Loading branch information
Tao Zhou authored and Alex Deucher committed Sep 29, 2022
1 parent c19a5f3 commit 1014bd1
Showing 1 changed file with 27 additions and 18 deletions.
45 changes: 27 additions & 18 deletions drivers/gpu/drm/amd/amdgpu/umc_v6_7.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,32 +460,39 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
uint64_t mc_umc_status, mc_umc_addrt0;
uint64_t err_addr, soc_pa, retired_page, column;

mc_umc_status_addr =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
mc_umc_addrt0 =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);
if (mca_addr == UMC_INVALID_ADDR) {
mc_umc_status_addr =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_STATUST0);
mc_umc_addrt0 =
SOC15_REG_OFFSET(UMC, 0, regMCA_UMC_UMC0_MCUMC_ADDRT0);

mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);
mc_umc_status = RREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4);

if (mc_umc_status == 0)
return;
if (mc_umc_status == 0)
return;

if (!err_data->err_addr) {
/* clear umc status */
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
return;
if (!err_data->err_addr) {
/* clear umc status */
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
return;
}
}

channel_index =
adev->umc.channel_idx_tbl[umc_inst * adev->umc.channel_inst_num + ch_inst];

/* calculate error address if ue/ce error is detected */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
if ((REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, Val) == 1 &&
(REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC) == 1 ||
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) {

err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
err_addr = REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, CECC) == 1)) ||
mca_addr != UMC_INVALID_ADDR) {
if (mca_addr == UMC_INVALID_ADDR) {
err_addr = RREG64_PCIE((mc_umc_addrt0 + umc_reg_offset) * 4);
err_addr =
REG_GET_FIELD(err_addr, MCA_UMC_UMC0_MCUMC_ADDRT0, ErrorAddr);
} else {
err_addr = mca_addr;
}

/* translate umc channel address to soc pa, 3 parts are included */
soc_pa = ADDR_OF_8KB_BLOCK(err_addr) |
Expand All @@ -500,7 +507,8 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,

/* we only save ue error information currently, ce is skipped */
if (REG_GET_FIELD(mc_umc_status, MCA_UMC_UMC0_MCUMC_STATUST0, UECC)
== 1) {
== 1 ||
mca_addr != UMC_INVALID_ADDR) {
/* loop for all possibilities of [C4 C3 C2] */
for (column = 0; column < UMC_V6_7_NA_MAP_PA_NUM; column++) {
retired_page = soc_pa | (column << UMC_V6_7_PA_C2_BIT);
Expand All @@ -518,7 +526,8 @@ static void umc_v6_7_query_error_address(struct amdgpu_device *adev,
}

/* clear umc status */
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
if (mca_addr == UMC_INVALID_ADDR)
WREG64_PCIE((mc_umc_status_addr + umc_reg_offset) * 4, 0x0ULL);
}

static void umc_v6_7_query_ras_error_address(struct amdgpu_device *adev,
Expand Down

0 comments on commit 1014bd1

Please sign in to comment.