On a queue MODIFY (prop->modify) the gfx11 GFX and compute init_mqd keep
the context-saved rptr and use prop->user_wptr as the wptr, so a
re-enabled queue resumes at the first un-consumed packet.

v2: rebuild the HQD via init_mqd and save/restore the rptr, matching the
    SDMA update_mqd style, instead of patching individual MQD fields in
    place. Keeps all update_mqd callbacks consistent.
v3: consume the mqd_prop modify flag inside init_mqd instead of adding a
    separate gfx11 update_mqd callback, per review.

Signed-off-by: Jesse Zhang <[email protected]>
Suggested-by: Alexander Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 33 ++++++++++++++++++--------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a447562977ab..238b8339213c 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -4167,9 +4167,14 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device 
*adev, void *m,
        uint32_t tmp;
        uint32_t rb_bufsz;
 
-       /* set up gfx hqd wptr */
-       mqd->cp_gfx_hqd_wptr = 0;
-       mqd->cp_gfx_hqd_wptr_hi = 0;
+       /* set up gfx hqd wptr - on a MODIFY use the live user wptr */
+       if (prop->modify) {
+               mqd->cp_gfx_hqd_wptr = lower_32_bits(prop->user_wptr);
+               mqd->cp_gfx_hqd_wptr_hi = upper_32_bits(prop->user_wptr);
+       } else {
+               mqd->cp_gfx_hqd_wptr = 0;
+               mqd->cp_gfx_hqd_wptr_hi = 0;
+       }
 
        /* set the pointer to the MQD */
        mqd->cp_mqd_base_addr = prop->mqd_gpu_addr & 0xfffffffc;
@@ -4237,8 +4242,9 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device 
*adev, void *m,
                                    DOORBELL_EN, 0);
        mqd->cp_rb_doorbell_control = tmp;
 
-       /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
-       mqd->cp_gfx_hqd_rptr = regCP_GFX_HQD_RPTR_DEFAULT;
+       /* reset read pointer - on a MODIFY keep the context-saved rptr */
+       if (!prop->modify)
+               mqd->cp_gfx_hqd_rptr = regCP_GFX_HQD_RPTR_DEFAULT;
 
        /* active the queue */
        mqd->cp_gfx_hqd_active = 1;
@@ -4379,9 +4385,15 @@ static int gfx_v11_0_compute_mqd_init(struct 
amdgpu_device *adev, void *m,
 
        /* disable the queue if it's active */
        mqd->cp_hqd_dequeue_request = 0;
-       mqd->cp_hqd_pq_rptr = 0;
-       mqd->cp_hqd_pq_wptr_lo = 0;
-       mqd->cp_hqd_pq_wptr_hi = 0;
+       /* on a MODIFY keep the context-saved rptr, use the live user wptr */
+       if (prop->modify) {
+               mqd->cp_hqd_pq_wptr_lo = lower_32_bits(prop->user_wptr);
+               mqd->cp_hqd_pq_wptr_hi = upper_32_bits(prop->user_wptr);
+       } else {
+               mqd->cp_hqd_pq_rptr = 0;
+               mqd->cp_hqd_pq_wptr_lo = 0;
+               mqd->cp_hqd_pq_wptr_hi = 0;
+       }
 
        /* set the pointer to the MQD */
        mqd->cp_mqd_base_addr_lo = prop->mqd_gpu_addr & 0xfffffffc;
@@ -4442,8 +4454,9 @@ static int gfx_v11_0_compute_mqd_init(struct 
amdgpu_device *adev, void *m,
 
        mqd->cp_hqd_pq_doorbell_control = tmp;
 
-       /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
-       mqd->cp_hqd_pq_rptr = regCP_HQD_PQ_RPTR_DEFAULT;
+       /* reset read pointer - but on a MODIFY keep the context-saved rptr */
+       if (!prop->modify)
+               mqd->cp_hqd_pq_rptr = regCP_HQD_PQ_RPTR_DEFAULT;
 
        /* set the vmid for the queue */
        mqd->cp_hqd_vmid = 0;
-- 
2.49.0

Reply via email to