summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimur Kristóf <timur.kristof@gmail.com>2026-08-03 15:23:04 +0200
committerAlex Deucher <alexander.deucher@amd.com>2026-08-06 12:47:26 -0400
commit5e996008db32112bbf25aba39ea43cd162f4c139 (patch)
treeeb56657f0bab3ec6d79c2107b899e51e86a7d256
parentc9ddc90f91597ba06c9fcbbfd34f62d4b9b524d0 (diff)
downloadlinux-5e996008db32112bbf25aba39ea43cd162f4c139.tar.gz
linux-5e996008db32112bbf25aba39ea43cd162f4c139.zip
drm/amdgpu/gfx6: Clean up rings during reset
Clear the WPTR and RPTR at ring initialization. Additionally clear the ring contents too. This is necessary so that the IP block soft reset can bring the rings back to a clean state. After a reset, the ring contents could contain packets emitted before the reset, and thus need to be cleared to prevent the command processor from executing packets left over in the ring from before the reset. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index cd8a34d87c6d..ce63417ae17e 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -2159,8 +2159,12 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32(mmSCRATCH_ADDR, 0);
/* ring 0 - compute and gfx */
- /* Set ring buffer size */
ring = &adev->gfx.gfx_ring[0];
+ *ring->wptr_cpu_addr = 0;
+ *ring->rptr_cpu_addr = 0;
+ amdgpu_ring_clear_ring(ring);
+
+ /* Set ring buffer size */
rb_bufsz = order_base_2(ring->ring_size / 8);
tmp = (order_base_2(AMDGPU_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
@@ -2172,7 +2176,8 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
/* Initialize the ring buffer's read and write pointers */
WREG32(mmCP_RB0_CNTL, tmp | CP_RB0_CNTL__RB_RPTR_WR_ENA_MASK);
ring->wptr = 0;
- WREG32(mmCP_RB0_WPTR, ring->wptr);
+ WREG32(mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
+ WREG32(mmCP_RB0_RPTR, lower_32_bits(ring->wptr));
/* set the wb address whether it's enabled or not */
rptr_addr = ring->rptr_gpu_addr;
@@ -2189,6 +2194,9 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
/* ring 1 - compute only */
if (adev->gfx.num_compute_rings >= 1) {
ring = &adev->gfx.compute_ring[0];
+ *ring->wptr_cpu_addr = 0;
+ *ring->rptr_cpu_addr = 0;
+ amdgpu_ring_clear_ring(ring);
rb_bufsz = order_base_2(ring->ring_size / 8);
tmp = (order_base_2(AMDGPU_GPU_PAGE_SIZE / 8) << 8) | rb_bufsz;
@@ -2199,7 +2207,8 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32(mmCP_RB1_CNTL, tmp | CP_RB1_CNTL__RB_RPTR_WR_ENA_MASK);
ring->wptr = 0;
- WREG32(mmCP_RB1_WPTR, ring->wptr);
+ WREG32(mmCP_RB1_WPTR, lower_32_bits(ring->wptr));
+ WREG32(mmCP_RB1_RPTR, lower_32_bits(ring->wptr));
rptr_addr = ring->rptr_gpu_addr;
WREG32(mmCP_RB1_RPTR_ADDR, lower_32_bits(rptr_addr));
@@ -2213,6 +2222,9 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
/* ring 2 - compute only */
if (adev->gfx.num_compute_rings >= 2) {
ring = &adev->gfx.compute_ring[1];
+ *ring->wptr_cpu_addr = 0;
+ *ring->rptr_cpu_addr = 0;
+ amdgpu_ring_clear_ring(ring);
rb_bufsz = order_base_2(ring->ring_size / 8);
tmp = (order_base_2(AMDGPU_GPU_PAGE_SIZE / 8) << 8) | rb_bufsz;
@@ -2223,7 +2235,9 @@ static int gfx_v6_0_cp_gfx_resume(struct amdgpu_device *adev)
WREG32(mmCP_RB2_CNTL, tmp | CP_RB2_CNTL__RB_RPTR_WR_ENA_MASK);
ring->wptr = 0;
- WREG32(mmCP_RB2_WPTR, ring->wptr);
+ WREG32(mmCP_RB2_WPTR, lower_32_bits(ring->wptr));
+ WREG32(mmCP_RB2_RPTR, lower_32_bits(ring->wptr));
+
rptr_addr = ring->rptr_gpu_addr;
WREG32(mmCP_RB2_RPTR_ADDR, lower_32_bits(rptr_addr));
WREG32(mmCP_RB2_RPTR_ADDR_HI, upper_32_bits(rptr_addr) & 0xFF);