drm/amdgpu: Program xcp_ctl registers as needed
authorLijo Lazar <lijo.lazar@amd.com>
Thu, 20 Jul 2023 05:50:43 +0000 (11:20 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 21 Jul 2023 20:52:25 +0000 (16:52 -0400)
XCP_CTL register is expected to be programmed by firmware. Under certain
conditions FW may not have programmed it correctly. As a workaround,
program it when FW has not programmed the right values.

Signed-off-by: Lijo Lazar <lijo.lazar@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c

index b594d5c05149654000a5b7d1206e576a0bd56763..9053435488c5c9f2349f260fa9656f303c77267e 100644 (file)
@@ -621,7 +621,7 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev,
                                                int num_xccs_per_xcp)
 {
        int ret, i, num_xcc;
-       u32 tmp = 0;
+       u32 tmp = 0, regval;
 
        if (adev->psp.funcs) {
                ret = psp_spatial_partition(&adev->psp,
@@ -629,23 +629,24 @@ static int gfx_v9_4_3_switch_compute_partition(struct amdgpu_device *adev,
                                                    num_xccs_per_xcp);
                if (ret)
                        return ret;
-       } else {
-               num_xcc = NUM_XCC(adev->gfx.xcc_mask);
+       }
+
+       num_xcc = NUM_XCC(adev->gfx.xcc_mask);
 
-               for (i = 0; i < num_xcc; i++) {
-                       tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP,
-                                           num_xccs_per_xcp);
-                       tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID,
-                                           i % num_xccs_per_xcp);
+       for (i = 0; i < num_xcc; i++) {
+               tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, NUM_XCC_IN_XCP,
+                                   num_xccs_per_xcp);
+               tmp = REG_SET_FIELD(tmp, CP_HYP_XCP_CTL, VIRTUAL_XCC_ID,
+                                   i % num_xccs_per_xcp);
+               regval = RREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL);
+               if (regval != tmp)
                        WREG32_SOC15(GC, GET_INST(GC, i), regCP_HYP_XCP_CTL,
                                     tmp);
-               }
-               ret = 0;
        }
 
        adev->gfx.num_xcc_per_xcp = num_xccs_per_xcp;
 
-       return ret;
+       return 0;
 }
 
 static int gfx_v9_4_3_ih_to_xcc_inst(struct amdgpu_device *adev, int ih_node)