From: "Alex Deucher" <[email protected]> Resetting VCN resets the entire tile, including jpeg. When we reset VCN, we also need to handle the jpeg queues. Add a helper to handle recovering the jpeg queues when VCN is reset.
Signed-off-by: Alex Deucher <[email protected]> --- drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c | 11 ++++++- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 41 ++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c index ab0bf880d3d8..edecbfe66c79 100644 --- a/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c @@ -844,10 +844,19 @@ static int jpeg_v5_0_1_ring_reset(struct amdgpu_ring *ring, unsigned int vmid, struct amdgpu_fence *timedout_fence) { + struct amdgpu_device *adev = ring->adev; + struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; + int r; + + /* take the vcn reset mutex here because resetting VCN will reset jpeg as well */ + mutex_lock(&vinst->engine_reset_mutex); + amdgpu_ring_reset_helper_begin(ring, timedout_fence); jpeg_v5_0_1_core_stall_reset(ring); jpeg_v5_0_1_init_jrbc(ring); - return amdgpu_ring_reset_helper_end(ring, timedout_fence); + r = amdgpu_ring_reset_helper_end(ring, timedout_fence); + mutex_unlock(&vinst->engine_reset_mutex); + return r; } static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = { 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 8bd457dea4cf..0dd841c2b0e5 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -609,6 +609,32 @@ static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst) { } +static int vcn_v4_0_3_reset_jpeg_helper(struct amdgpu_device *adev, + int inst) +{ + struct amdgpu_ring *ring; + int i, r; + + for (i = 0; i < adev->jpeg.num_jpeg_rings; ++i) { + ring = &adev->jpeg.inst[inst].ring_dec[i]; + drm_sched_wqueue_stop(&ring->sched); + amdgpu_fence_driver_force_completion(ring); + if (ring->use_doorbell) + WREG32_SOC15_OFFSET( + VCN, GET_INST(VCN, inst), + regVCN_JPEG_DB_CTRL, + (ring->pipe ? (ring->pipe - 0x15) : 0), + ring->doorbell_index + << VCN_JPEG_DB_CTRL__OFFSET__SHIFT | + VCN_JPEG_DB_CTRL__EN_MASK); + r = amdgpu_ring_test_helper(ring); + if (r) + return r; + drm_sched_wqueue_start(&ring->sched); + } + return 0; +} + /** * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode * @@ -1310,6 +1336,8 @@ static int vcn_v5_0_1_ring_reset(struct amdgpu_ring *ring, struct amdgpu_device *adev = ring->adev; struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me]; + /* take the vcn reset mutex here because resetting VCN will reset jpeg as well */ + mutex_lock(&vinst->engine_reset_mutex); amdgpu_ring_reset_helper_begin(ring, timedout_fence); vcn_inst = GET_INST(VCN, ring->me); @@ -1317,13 +1345,22 @@ 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); - return r; + goto unlock; } vcn_v5_0_1_hw_init_inst(adev, ring->me); vcn_v5_0_1_start_dpg_mode(vinst, vinst->indirect_sram); - return amdgpu_ring_reset_helper_end(ring, timedout_fence); + r = amdgpu_ring_reset_helper_end(ring, timedout_fence); + if (r) + goto unlock; + + r = vcn_v4_0_3_reset_jpeg_helper(adev, ring->me); + +unlock: + mutex_unlock(&vinst->engine_reset_mutex); + + return r; } static const struct amdgpu_ring_funcs vcn_v5_0_1_unified_ring_vm_funcs = { -- 2.49.0
