From f61f9b4df6522f1134099e5785f14bd8c3a3cd02 Mon Sep 17 00:00:00 2001 From: jsg Date: Mon, 5 Aug 2024 02:42:47 +0000 Subject: [PATCH] drm/amdgpu/sdma5.2: Update wptr registers as well as doorbell From Alex Deucher 9d74e50098492e89f319ac6922db3c2062f69340 in linux-6.6.y/6.6.44 a03ebf116303e5d13ba9a2b65726b106cb1e96f6 in mainline linux --- sys/dev/pci/drm/amd/amdgpu/sdma_v5_2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sys/dev/pci/drm/amd/amdgpu/sdma_v5_2.c b/sys/dev/pci/drm/amd/amdgpu/sdma_v5_2.c index ac3ae213155..61afab0d0fc 100644 --- a/sys/dev/pci/drm/amd/amdgpu/sdma_v5_2.c +++ b/sys/dev/pci/drm/amd/amdgpu/sdma_v5_2.c @@ -188,6 +188,14 @@ static void sdma_v5_2_ring_set_wptr(struct amdgpu_ring *ring) DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n", ring->doorbell_index, ring->wptr << 2); WDOORBELL64(ring->doorbell_index, ring->wptr << 2); + /* SDMA seems to miss doorbells sometimes when powergating kicks in. + * Updating the wptr directly will wake it. This is only safe because + * we disallow gfxoff in begin_use() and then allow it again in end_use(). + */ + WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR), + lower_32_bits(ring->wptr << 2)); + WREG32(sdma_v5_2_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI), + upper_32_bits(ring->wptr << 2)); } else { DRM_DEBUG("Not using doorbell -- " "mmSDMA%i_GFX_RB_WPTR == 0x%08x " @@ -1666,6 +1674,10 @@ static void sdma_v5_2_ring_begin_use(struct amdgpu_ring *ring) * but it shouldn't hurt for other parts since * this GFXOFF will be disallowed anyway when SDMA is * active, this just makes it explicit. + * sdma_v5_2_ring_set_wptr() takes advantage of this + * to update the wptr because sometimes SDMA seems to miss + * doorbells when entering PG. If you remove this, update + * sdma_v5_2_ring_set_wptr() as well! */ amdgpu_gfx_off_ctrl(adev, false); } -- 2.20.1