Save wptr in hqd_sdma_destroy, restore it in hqd_sdma_load. Also
read updated wptr from user mode when resuming an SDMA queue.

Signed-off-by: Jay Cornwall <[email protected]>
Signed-off-by: Yong Zhao <[email protected]>
Signed-off-by: Felix Kuehling <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 30 +++++++++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c |  9 ++++---
 2 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
index a55d794..14333af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c
@@ -412,10 +412,17 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void 
*mqd,
                WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data);
        }
 
-       WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL,
-                               m->sdma_rlc_doorbell);
-       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
-       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
+       data = REG_SET_FIELD(m->sdma_rlc_doorbell, SDMA0_RLC0_DOORBELL,
+                            ENABLE, 1);
+       WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, data);
+       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, m->sdma_rlc_rb_rptr);
+
+       if (read_user_wptr(mm, wptr, data))
+               WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, data);
+       else
+               WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR,
+                      m->sdma_rlc_rb_rptr);
+
        WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR,
                                m->sdma_rlc_virtual_addr);
        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base);
@@ -425,8 +432,10 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void 
*mqd,
                        m->sdma_rlc_rb_rptr_addr_lo);
        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
                        m->sdma_rlc_rb_rptr_addr_hi);
-       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
-                       m->sdma_rlc_rb_cntl);
+
+       data = REG_SET_FIELD(m->sdma_rlc_rb_cntl, SDMA0_RLC0_RB_CNTL,
+                            RB_ENABLE, 1);
+       WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL, data);
 
        return 0;
 }
@@ -577,7 +586,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
        struct cik_sdma_rlc_registers *m;
        uint32_t sdma_base_addr;
        uint32_t temp;
-       int timeout = utimeout;
+       unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies;
 
        m = get_sdma_mqd(mqd);
        sdma_base_addr = get_sdma_base_addr(m);
@@ -590,10 +599,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
                temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
                if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
                        break;
-               if (timeout <= 0)
+               if (time_after(jiffies, end_jiffies))
                        return -ETIME;
-               msleep(20);
-               timeout -= 20;
+               usleep_range(500, 1000);
        }
 
        WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
@@ -601,6 +609,8 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
                RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
                SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
 
+       m->sdma_rlc_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
+
        return 0;
 }
 
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
index 1017ff5..03c564d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c
@@ -514,7 +514,7 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
        struct cik_sdma_rlc_registers *m;
        uint32_t sdma_base_addr;
        uint32_t temp;
-       int timeout = utimeout;
+       unsigned long end_jiffies = (utimeout * HZ / 1000) + jiffies;
 
        m = get_sdma_mqd(mqd);
        sdma_base_addr = get_sdma_base_addr(m);
@@ -527,10 +527,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
                temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
                if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT)
                        break;
-               if (timeout <= 0)
+               if (time_after(jiffies, end_jiffies))
                        return -ETIME;
-               msleep(20);
-               timeout -= 20;
+               usleep_range(500, 1000);
        }
 
        WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
@@ -538,6 +537,8 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void 
*mqd,
        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
        WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0);
 
+       m->sdmax_rlcx_rb_rptr = RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR);
+
        return 0;
 }
 
-- 
2.7.4

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to