drm/amdgpu: implement umc ras init function
authorTao Zhou <tao.zhou1@amd.com>
Mon, 29 Jul 2019 09:01:39 +0000 (17:01 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 2 Aug 2019 15:30:38 +0000 (10:30 -0500)
enable umc ce interrupt and initialize ecc error count

Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/umc_v6_1.c
drivers/gpu/drm/amd/amdgpu/umc_v6_1.h

index 5747a02..0ab2e96 100644 (file)
@@ -207,9 +207,41 @@ static void umc_v6_1_query_ras_error_address(struct amdgpu_device *adev,
        amdgpu_umc_for_each_channel(umc_v6_1_query_error_address);
 }
 
+static void umc_v6_1_ras_init_per_channel(struct amdgpu_device *adev,
+                                        struct ras_err_data *err_data,
+                                        uint32_t umc_reg_offset, uint32_t channel_index)
+{
+       uint32_t ecc_err_cnt_sel, ecc_err_cnt_sel_addr;
+       uint32_t ecc_err_cnt_addr;
+
+       ecc_err_cnt_sel_addr =
+               SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCntSel);
+       ecc_err_cnt_addr =
+               SOC15_REG_OFFSET(UMC, 0, mmUMCCH0_0_EccErrCnt);
+
+       /* select the lower chip and check the error count */
+       ecc_err_cnt_sel = RREG32(ecc_err_cnt_sel_addr + umc_reg_offset);
+       ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
+                                       EccErrCntCsSel, 0);
+       /* set ce error interrupt type to APIC based interrupt */
+       ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
+                                       EccErrInt, 0x1);
+       WREG32(ecc_err_cnt_sel_addr + umc_reg_offset, ecc_err_cnt_sel);
+       /* set error count to initial value */
+       WREG32(ecc_err_cnt_addr + umc_reg_offset, UMC_V6_1_CE_CNT_INIT);
+
+       /* select the higher chip and check the err counter */
+       ecc_err_cnt_sel = REG_SET_FIELD(ecc_err_cnt_sel, UMCCH0_0_EccErrCntSel,
+                                       EccErrCntCsSel, 1);
+       WREG32(ecc_err_cnt_sel_addr + umc_reg_offset, ecc_err_cnt_sel);
+       WREG32(ecc_err_cnt_addr + umc_reg_offset, UMC_V6_1_CE_CNT_INIT);
+}
+
 static void umc_v6_1_ras_init(struct amdgpu_device *adev)
 {
+       void *ras_error_status = NULL;
 
+       amdgpu_umc_for_each_channel(umc_v6_1_ras_init_per_channel);
 }
 
 const struct amdgpu_umc_funcs umc_v6_1_funcs = {
index ad4598c..dab9cbd 100644 (file)
 /* UMC regiser per channel offset */
 #define UMC_V6_1_PER_CHANNEL_OFFSET            0x800
 
+/* EccErrCnt max value */
+#define UMC_V6_1_CE_CNT_MAX            0xffff
+/* umc ce interrupt threshold */
+#define UMC_V6_1_CE_INT_THRESHOLD      0xffff
+/* umc ce count initial value */
+#define UMC_V6_1_CE_CNT_INIT   (UMC_V6_1_CE_CNT_MAX - UMC_V6_1_CE_INT_THRESHOLD)
+
 extern const struct amdgpu_umc_funcs umc_v6_1_funcs;
 extern const uint32_t
        umc_v6_1_channel_idx_tbl[UMC_V6_1_UMC_INSTANCE_NUM][UMC_V6_1_CHANNEL_INSTANCE_NUM];