This is a note to let you know that I've just added the patch titled
drm/amdgpu: use polling mem to set SDMA3 wptr for VF
to the 4.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git%3Ba=su...
The filename of the patch is: drm-amdgpu-use-polling-mem-to-set-sdma3-wptr-for-vf.patch and it can be found in the queue-4.15 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let stable@vger.kernel.org know about it.
From foo@baz Thu Mar 22 14:03:39 CET 2018
From: Pixel Ding Pixel.Ding@amd.com Date: Mon, 11 Dec 2017 16:48:33 +0800 Subject: drm/amdgpu: use polling mem to set SDMA3 wptr for VF
From: Pixel Ding Pixel.Ding@amd.com
[ Upstream commit 2ffe31deb27579e2f2c9444e01f4d8abf385d145 ]
On Tonga VF, there're 2 sources updating wptr registers for sdma3: 1) polling mem and 2) doorbell. When doorbell and polling mem are both enabled on sdma3, there will be collision hit in occasion between those two sources when ucode and h/w are doing the updating on wptr register in parallel. Issue doesn't happen on CP GFX/Compute since CP drops all doorbell writes when VF is inactive. So enable polling mem and don't use doorbell for SDMA3.
Signed-off-by: Pixel Ding Pixel.Ding@amd.com Reviewed-by: Monk Liu monk.liu@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin alexander.levin@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 1 + drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 27 +++++++++++++++++++-------- 2 files changed, 20 insertions(+), 8 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -187,6 +187,7 @@ struct amdgpu_ring { uint64_t eop_gpu_addr; u32 doorbell_index; bool use_doorbell; + bool use_pollmem; unsigned wptr_offs; unsigned fence_offs; uint64_t current_ctx; --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -355,7 +355,7 @@ static uint64_t sdma_v3_0_ring_get_wptr( struct amdgpu_device *adev = ring->adev; u32 wptr;
- if (ring->use_doorbell) { + if (ring->use_doorbell || ring->use_pollmem) { /* XXX check if swapping is necessary on BE */ wptr = ring->adev->wb.wb[ring->wptr_offs] >> 2; } else { @@ -380,10 +380,13 @@ static void sdma_v3_0_ring_set_wptr(stru
if (ring->use_doorbell) { u32 *wb = (u32 *)&adev->wb.wb[ring->wptr_offs]; - /* XXX check if swapping is necessary on BE */ WRITE_ONCE(*wb, (lower_32_bits(ring->wptr) << 2)); WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr) << 2); + } else if (ring->use_pollmem) { + u32 *wb = (u32 *)&adev->wb.wb[ring->wptr_offs]; + + WRITE_ONCE(*wb, (lower_32_bits(ring->wptr) << 2)); } else { int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1;
@@ -718,10 +721,14 @@ static int sdma_v3_0_gfx_resume(struct a WREG32(mmSDMA0_GFX_RB_WPTR_POLL_ADDR_HI + sdma_offsets[i], upper_32_bits(wptr_gpu_addr)); wptr_poll_cntl = RREG32(mmSDMA0_GFX_RB_WPTR_POLL_CNTL + sdma_offsets[i]); - if (amdgpu_sriov_vf(adev)) - wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 1); + if (ring->use_pollmem) + wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, + SDMA0_GFX_RB_WPTR_POLL_CNTL, + ENABLE, 1); else - wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, SDMA0_GFX_RB_WPTR_POLL_CNTL, F32_POLL_ENABLE, 0); + wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl, + SDMA0_GFX_RB_WPTR_POLL_CNTL, + ENABLE, 0); WREG32(mmSDMA0_GFX_RB_WPTR_POLL_CNTL + sdma_offsets[i], wptr_poll_cntl);
/* enable DMA RB */ @@ -1203,9 +1210,13 @@ static int sdma_v3_0_sw_init(void *handl for (i = 0; i < adev->sdma.num_instances; i++) { ring = &adev->sdma.instance[i].ring; ring->ring_obj = NULL; - ring->use_doorbell = true; - ring->doorbell_index = (i == 0) ? - AMDGPU_DOORBELL_sDMA_ENGINE0 : AMDGPU_DOORBELL_sDMA_ENGINE1; + if (!amdgpu_sriov_vf(adev)) { + ring->use_doorbell = true; + ring->doorbell_index = (i == 0) ? + AMDGPU_DOORBELL_sDMA_ENGINE0 : AMDGPU_DOORBELL_sDMA_ENGINE1; + } else { + ring->use_pollmem = true; + }
sprintf(ring->name, "sdma%d", i); r = amdgpu_ring_init(adev, ring, 1024,
Patches currently in stable-queue which might be from Pixel.Ding@amd.com are
queue-4.15/drm-amdgpu-use-polling-mem-to-set-sdma3-wptr-for-vf.patch
linux-stable-mirror@lists.linaro.org