Both doorbell and polling mem are working on Tonga VF. SDMA issue
happens because SDMA engine accepts doorbell writes even if it's
inactive, that introduces conflict when world switch routine update
wptr though polling memory. Use polling mem in driver too.

Signed-off-by: Pixel Ding <pixel.d...@amd.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h |  1 +
 drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c   | 20 +++++++++++++++-----
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
index 641e3fd..be09406 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h
@@ -186,6 +186,7 @@ struct amdgpu_ring {
        uint64_t                eop_gpu_addr;
        u32                     doorbell_index;
        bool                    use_doorbell;
+       bool                    use_polling_mem;
        unsigned                wptr_offs;
        unsigned                fence_offs;
        uint64_t                current_ctx;
diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c 
b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
index c8c93f9..b09562c 100644
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
@@ -380,10 +380,10 @@ static void sdma_v3_0_ring_set_wptr(struct amdgpu_ring 
*ring)
 
        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);
+               if (!ring->use_polling_mem)
+                       WDOORBELL32(ring->doorbell_index, 
lower_32_bits(ring->wptr) << 2);
        } else {
                int me = (ring == &ring->adev->sdma.instance[0].ring) ? 0 : 1;
 
@@ -718,10 +718,18 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device 
*adev)
                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_polling_mem) {
+                       wptr_poll_cntl = REG_SET_FIELD(wptr_poll_cntl,
+                                                      
SDMA0_GFX_RB_WPTR_POLL_CNTL,
+                                                      F32_POLL_ENABLE, 1);
+                       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,
+                                                      F32_POLL_ENABLE, 0);
                WREG32(mmSDMA0_GFX_RB_WPTR_POLL_CNTL + sdma_offsets[i], 
wptr_poll_cntl);
 
                /* enable DMA RB */
@@ -1204,6 +1212,8 @@ static int sdma_v3_0_sw_init(void *handle)
                ring = &adev->sdma.instance[i].ring;
                ring->ring_obj = NULL;
                ring->use_doorbell = true;
+               if (amdgpu_sriov_vf(adev))
+                       ring->use_polling_mem = true;
                ring->doorbell_index = (i == 0) ?
                        AMDGPU_DOORBELL_sDMA_ENGINE0 : 
AMDGPU_DOORBELL_sDMA_ENGINE1;
 
-- 
2.9.5

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to