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