On a queue MODIFY (prop->modify) the gfx12 GFX and compute init_mqd keep
the ring rptr/wptr that firmware context-saved into the MQD, 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.
v4: also keep the context-saved wptr instead of programming a user_wptr,
    per review.

Signed-off-by: Jesse Zhang <[email protected]>
Suggested-by: Alexander Deucher <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 23 ++++++++++++++---------
 1 file changed, 14 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..b2d210681224 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3006,9 +3006,11 @@ 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;
+       /* MODIFY keeps the firmware-saved wptr; otherwise start at 0 */
+       if (!prop->modify) {
+               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 +3081,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;
+       /* MODIFY keeps the firmware-saved rptr; otherwise reset it */
+       if (!prop->modify)
+               mqd->cp_gfx_hqd_rptr = regCP_GFX_HQD_RPTR_DEFAULT;
 
        /* active the queue */
        mqd->cp_gfx_hqd_active = 1;
@@ -3212,10 +3215,12 @@ 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;
+       /* MODIFY keeps the firmware-saved rptr/wptr; otherwise start at 0 */
+       if (!prop->modify) {
+               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