drm/amdgpu: make gfx9 enter into rlc safe mode when set MGCG
[linux-2.6-microblaze.git] / drivers / gpu / drm / amd / amdgpu / vcn_v1_0.c
index 4f83520..89bb2fe 100644 (file)
@@ -214,7 +214,8 @@ static int vcn_v1_0_hw_fini(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        struct amdgpu_ring *ring = &adev->vcn.ring_dec;
 
-       if (RREG32_SOC15(VCN, 0, mmUVD_STATUS))
+       if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
+               RREG32_SOC15(VCN, 0, mmUVD_STATUS))
                vcn_v1_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
 
        ring->sched.ready = false;
@@ -1087,7 +1088,8 @@ static int vcn_v1_0_start_dpg_mode(struct amdgpu_device *adev)
        WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_RBC_RB_CNTL), 0,
                        ~UVD_RBC_RB_CNTL__RB_NO_FETCH_MASK);
 
-       /* initialize wptr */
+       /* initialize JPEG wptr */
+       ring = &adev->vcn.ring_jpeg;
        ring->wptr = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
 
        /* copy patch commands to the jpeg ring */
@@ -1159,21 +1161,29 @@ static int vcn_v1_0_stop_spg_mode(struct amdgpu_device *adev)
 static int vcn_v1_0_stop_dpg_mode(struct amdgpu_device *adev)
 {
        int ret_code = 0;
+       uint32_t tmp;
 
        /* Wait for power status to be UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF */
        SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
                        UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
                        UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
 
-       if (!ret_code) {
-               int tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
-               /* wait for read ptr to be equal to write ptr */
-               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
+       /* wait for read ptr to be equal to write ptr */
+       tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR);
+       SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
 
-               SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
-                       UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
-                       UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
-       }
+       tmp = RREG32_SOC15(UVD, 0, mmUVD_RB_WPTR2);
+       SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF, ret_code);
+
+       tmp = RREG32_SOC15(UVD, 0, mmUVD_JRBC_RB_WPTR);
+       SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_JRBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
+
+       tmp = RREG32_SOC15(UVD, 0, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
+       SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF, ret_code);
+
+       SOC15_WAIT_ON_RREG(UVD, 0, mmUVD_POWER_STATUS,
+               UVD_POWER_STATUS__UVD_POWER_STATUS_TILES_OFF,
+               UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ret_code);
 
        /* disable dynamic power gating mode */
        WREG32_P(SOC15_REG_OFFSET(UVD, 0, mmUVD_POWER_STATUS), 0,