[PATCH 03/10] drm/amdgpu/gfx11: implement compute and GFX update_mqd

Jesse Zhang <[email protected]>
Newsgroups org.freedesktop.lists.amd-gfx
Message-ID <[email protected]>
Implement the update_mqd callback for gfx11 compute and GFX user queues.
It patches only the fields a MODIFY can change (compute: queue_size, CU
mask, priority; GFX: queue_size, priority, shadow/CSA) and forwards the
write pointer to the user wptr while keeping the firmware-saved read
pointer, so a re-enabled queue resumes at the first un-consumed packet
rather than replaying the ring from 0.

Signed-off-by: Jesse Zhang <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 69 ++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
index a447562977ab..2e25ffdb7f12 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c
@@ -4256,6 +4256,39 @@ static int gfx_v11_0_gfx_mqd_init(struct amdgpu_device *adev, void *m,
 	return 0;
 }
 
+/*
+ * GFX update_mqd: patch queue_size, ring base, priority and shadow/CSA in place
+ * and forward the write pointer, keeping the firmware-saved rptr.
+ */
+static int gfx_v11_0_gfx_mqd_update(struct amdgpu_device *adev, void *m,
+				    struct amdgpu_mqd_prop *prop,
+				    u64 user_wptr)
+{
+	struct v11_gfx_mqd *mqd = m;
+	uint32_t rb_bufsz, tmp;
+
+	rb_bufsz = order_base_2(prop->queue_size / 4) - 1;
+	tmp = mqd->cp_gfx_hqd_cntl;
+	tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BUFSZ, rb_bufsz);
+	tmp = REG_SET_FIELD(tmp, CP_GFX_HQD_CNTL, RB_BLKSZ, rb_bufsz - 2);
+	mqd->cp_gfx_hqd_cntl = tmp;
+
+	mqd->cp_gfx_hqd_base = prop->hqd_base_gpu_addr >> 8;
+	mqd->cp_gfx_hqd_base_hi = upper_32_bits(prop->hqd_base_gpu_addr >> 8);
+
+	gfx_v11_0_gfx_mqd_set_priority(adev, mqd, prop);
+
+	mqd->shadow_base_lo = lower_32_bits(prop->shadow_addr);
+	mqd->shadow_base_hi = upper_32_bits(prop->shadow_addr);
+	mqd->fw_work_area_base_lo = lower_32_bits(prop->csa_addr);
+	mqd->fw_work_area_base_hi = upper_32_bits(prop->csa_addr);
+
+	mqd->cp_gfx_hqd_wptr = lower_32_bits(user_wptr);
+	mqd->cp_gfx_hqd_wptr_hi = upper_32_bits(user_wptr);
+
+	return 0;
+}
+
 static int gfx_v11_0_kgq_init_queue(struct amdgpu_ring *ring)
 {
 	struct amdgpu_device *adev = ring->adev;
@@ -4477,6 +4510,38 @@ static int gfx_v11_0_compute_mqd_init(struct amdgpu_device *adev, void *m,
 	return 0;
 }
 
+/*
+ * Compute update_mqd: patch queue_size, ring/EOP base, CU mask and priority in
+ * place and forward the write pointer, keeping the firmware-saved rptr.
+ */
+static int gfx_v11_0_compute_mqd_update(struct amdgpu_device *adev, void *m,
+					struct amdgpu_mqd_prop *prop,
+					u64 user_wptr)
+{
+	struct v11_compute_mqd *mqd = m;
+
+	mqd->cp_hqd_pq_control &= ~CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK;
+	mqd->cp_hqd_pq_control |=
+		(order_base_2(prop->queue_size / 4) - 1)
+		<< CP_HQD_PQ_CONTROL__QUEUE_SIZE__SHIFT;
+
+	mqd->cp_hqd_pq_base_lo = prop->hqd_base_gpu_addr >> 8;
+	mqd->cp_hqd_pq_base_hi = upper_32_bits(prop->hqd_base_gpu_addr >> 8);
+
+	mqd->cp_hqd_eop_base_addr_lo = prop->eop_gpu_addr >> 8;
+	mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(prop->eop_gpu_addr >> 8);
+
+	mqd->cp_hqd_pipe_priority = prop->hqd_pipe_priority;
+	mqd->cp_hqd_queue_priority = prop->hqd_queue_priority;
+
+	gfx_v11_0_compute_mqd_set_cu_mask(adev, mqd, prop);
+
+	mqd->cp_hqd_pq_wptr_lo = lower_32_bits(user_wptr);
+	mqd->cp_hqd_pq_wptr_hi = upper_32_bits(user_wptr);
+
+	return 0;
+}
+
 static int gfx_v11_0_kiq_init_register(struct amdgpu_ring *ring)
 {
 	struct amdgpu_device *adev = ring->adev;
@@ -7271,11 +7336,15 @@ static void gfx_v11_0_set_mqd_funcs(struct amdgpu_device *adev)
 		sizeof(struct v11_gfx_mqd);
 	adev->mqds[AMDGPU_HW_IP_GFX].init_mqd =
 		gfx_v11_0_gfx_mqd_init;
+	adev->mqds[AMDGPU_HW_IP_GFX].update_mqd =
+		gfx_v11_0_gfx_mqd_update;
 	/* set compute eng mqd */
 	adev->mqds[AMDGPU_HW_IP_COMPUTE].mqd_size =
 		sizeof(struct v11_compute_mqd);
 	adev->mqds[AMDGPU_HW_IP_COMPUTE].init_mqd =
 		gfx_v11_0_compute_mqd_init;
+	adev->mqds[AMDGPU_HW_IP_COMPUTE].update_mqd =
+		gfx_v11_0_compute_mqd_update;
 }
 
 static void gfx_v11_0_set_user_wgp_inactive_bitmap_per_sh(struct amdgpu_device *adev,
-- 
2.49.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.