Resetting VCN resets the entire tile, including JPEG hardware.
When we reset VCN, we need to ensure the JPEG block is accessible
for proper reset handling and queue recovery.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c 
b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
index 0dd841c2b0e5..9d9dd8cdaa27 100644
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
+++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c
@@ -1335,9 +1335,18 @@ static int vcn_v5_0_1_ring_reset(struct amdgpu_ring 
*ring,
        int vcn_inst;
        struct amdgpu_device *adev = ring->adev;
        struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me];
+       bool pg_state = false;
 
        /* take the vcn reset mutex here because resetting VCN will reset jpeg 
as well */
        mutex_lock(&vinst->engine_reset_mutex);
+       mutex_lock(&adev->jpeg.jpeg_pg_lock);
+        /* Ensure JPEG is powered on during reset if currently gated */
+       if (adev->jpeg.cur_state == AMD_PG_STATE_GATE) {
+               amdgpu_device_ip_set_powergating_state(adev, 
AMD_IP_BLOCK_TYPE_JPEG,
+                                                      AMD_PG_STATE_UNGATE);
+               pg_state = true;
+       }
+
        amdgpu_ring_reset_helper_begin(ring, timedout_fence);
 
        vcn_inst = GET_INST(VCN, ring->me);
@@ -1345,6 +1354,11 @@ static int vcn_v5_0_1_ring_reset(struct amdgpu_ring 
*ring,
 
        if (r) {
                DRM_DEV_ERROR(adev->dev, "VCN reset fail : %d\n", r);
+               /* Restore JPEG power gating state if it was originally gated */
+               if (pg_state)
+                       amdgpu_device_ip_set_powergating_state(adev, 
AMD_IP_BLOCK_TYPE_JPEG,
+                                                              
AMD_PG_STATE_GATE);
+               mutex_unlock(&adev->jpeg.jpeg_pg_lock);
                goto unlock;
        }
 
@@ -1352,9 +1366,18 @@ static int vcn_v5_0_1_ring_reset(struct amdgpu_ring 
*ring,
        vcn_v5_0_1_start_dpg_mode(vinst, vinst->indirect_sram);
 
        r = amdgpu_ring_reset_helper_end(ring, timedout_fence);
-       if (r)
+       if (r) {
+               if (pg_state)
+                       amdgpu_device_ip_set_powergating_state(adev, 
AMD_IP_BLOCK_TYPE_JPEG,
+                                                              
AMD_PG_STATE_GATE);
+               mutex_unlock(&adev->jpeg.jpeg_pg_lock);
                goto unlock;
+       }
 
+       if (pg_state)
+               amdgpu_device_ip_set_powergating_state(adev, 
AMD_IP_BLOCK_TYPE_JPEG,
+                                                      AMD_PG_STATE_GATE);
+       mutex_unlock(&adev->jpeg.jpeg_pg_lock);
        r = vcn_v4_0_3_reset_jpeg_helper(adev, ring->me);
 
 unlock:
-- 
2.49.0

Reply via email to