On a queue MODIFY (prop->modify) the gfx12 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 gfx12 update_mqd callback, per review.

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

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
index a434b665d913..86fa31bfdad4 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3006,9 +3006,14 @@ static int gfx_v12_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;
@@ -3079,8 +3084,9 @@ static int gfx_v12_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 - but 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;
@@ -3212,10 +3218,15 @@ static int gfx_v12_0_compute_mqd_init(struct 
amdgpu_device *adev, void *m,
 
        /* disable the queue if it's active */
        mqd->cp_hqd_dequeue_request = 0;
-       /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
-       mqd->cp_hqd_pq_rptr = regCP_HQD_PQ_RPTR_DEFAULT;
-       mqd->cp_hqd_pq_wptr_lo = 0;
-       mqd->cp_hqd_pq_wptr_hi = 0;
+       /* reset read/write pointers - on a MODIFY keep rptr, use 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 = regCP_HQD_PQ_RPTR_DEFAULT;
+               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;
-- 
2.49.0

Reply via email to