The MQD structure matches the reg layout. Take advantage of this to
simplify HQD programming.

Note that the ACTIVE field still needs to be programmed last.

Suggested-by: Felix Kuehling <felix.kuehl...@amd.com>
Reviewed-by: Felix Kuehling <felix.kuehl...@amd.com>
Signed-off-by: Andres Rodriguez <andre...@gmail.com>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 44 +++++-------------
 drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 84 +++++------------------------------
 2 files changed, 23 insertions(+), 105 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index d5209d0..e621372 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -3120,81 +3120,59 @@ static void gfx_v7_0_mqd_init(struct amdgpu_device 
*adev,
        mqd->cp_hqd_ib_rptr = RREG32(mmCP_HQD_IB_RPTR);
        mqd->cp_hqd_persistent_state = RREG32(mmCP_HQD_PERSISTENT_STATE);
        mqd->cp_hqd_sema_cmd = RREG32(mmCP_HQD_SEMA_CMD);
        mqd->cp_hqd_msg_type = RREG32(mmCP_HQD_MSG_TYPE);
        mqd->cp_hqd_atomic0_preop_lo = RREG32(mmCP_HQD_ATOMIC0_PREOP_LO);
        mqd->cp_hqd_atomic0_preop_hi = RREG32(mmCP_HQD_ATOMIC0_PREOP_HI);
        mqd->cp_hqd_atomic1_preop_lo = RREG32(mmCP_HQD_ATOMIC1_PREOP_LO);
        mqd->cp_hqd_atomic1_preop_hi = RREG32(mmCP_HQD_ATOMIC1_PREOP_HI);
        mqd->cp_hqd_pq_rptr = RREG32(mmCP_HQD_PQ_RPTR);
        mqd->cp_hqd_quantum = RREG32(mmCP_HQD_QUANTUM);
        mqd->cp_hqd_pipe_priority = RREG32(mmCP_HQD_PIPE_PRIORITY);
        mqd->cp_hqd_queue_priority = RREG32(mmCP_HQD_QUEUE_PRIORITY);
        mqd->cp_hqd_iq_rptr = RREG32(mmCP_HQD_IQ_RPTR);
 
        /* activate the queue */
        mqd->cp_hqd_active = 1;
 }
 
 int gfx_v7_0_mqd_commit(struct amdgpu_device *adev, struct cik_mqd *mqd)
 {
-       u32 tmp;
+       uint32_t tmp;
+       uint32_t mqd_reg;
+       uint32_t *mqd_data;
+
+       /* HQD registers extend from mmCP_MQD_BASE_ADDR to mmCP_MQD_CONTROL */
+       mqd_data = &mqd->cp_mqd_base_addr_lo;
 
        /* disable wptr polling */
        tmp = RREG32(mmCP_PQ_WPTR_POLL_CNTL);
        tmp = REG_SET_FIELD(tmp, CP_PQ_WPTR_POLL_CNTL, EN, 0);
        WREG32(mmCP_PQ_WPTR_POLL_CNTL, tmp);
 
-       /* program MQD field to HW */
-       WREG32(mmCP_MQD_BASE_ADDR, mqd->cp_mqd_base_addr_lo);
-       WREG32(mmCP_MQD_BASE_ADDR_HI, mqd->cp_mqd_base_addr_hi);
-       WREG32(mmCP_MQD_CONTROL, mqd->cp_mqd_control);
-       WREG32(mmCP_HQD_PQ_BASE, mqd->cp_hqd_pq_base_lo);
-       WREG32(mmCP_HQD_PQ_BASE_HI, mqd->cp_hqd_pq_base_hi);
-       WREG32(mmCP_HQD_PQ_CONTROL, mqd->cp_hqd_pq_control);
-       WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->cp_hqd_pq_wptr_poll_addr_lo);
-       WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI, mqd->cp_hqd_pq_wptr_poll_addr_hi);
-       WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR, 
mqd->cp_hqd_pq_rptr_report_addr_lo);
-       WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI, 
mqd->cp_hqd_pq_rptr_report_addr_hi);
-       WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->cp_hqd_pq_doorbell_control);
-       WREG32(mmCP_HQD_PQ_WPTR, mqd->cp_hqd_pq_wptr);
-       WREG32(mmCP_HQD_VMID, mqd->cp_hqd_vmid);
-
-       WREG32(mmCP_HQD_IB_CONTROL, mqd->cp_hqd_ib_control);
-       WREG32(mmCP_HQD_IB_BASE_ADDR, mqd->cp_hqd_ib_base_addr_lo);
-       WREG32(mmCP_HQD_IB_BASE_ADDR_HI, mqd->cp_hqd_ib_base_addr_hi);
-       WREG32(mmCP_HQD_IB_RPTR, mqd->cp_hqd_ib_rptr);
-       WREG32(mmCP_HQD_PERSISTENT_STATE, mqd->cp_hqd_persistent_state);
-       WREG32(mmCP_HQD_SEMA_CMD, mqd->cp_hqd_sema_cmd);
-       WREG32(mmCP_HQD_MSG_TYPE, mqd->cp_hqd_msg_type);
-       WREG32(mmCP_HQD_ATOMIC0_PREOP_LO, mqd->cp_hqd_atomic0_preop_lo);
-       WREG32(mmCP_HQD_ATOMIC0_PREOP_HI, mqd->cp_hqd_atomic0_preop_hi);
-       WREG32(mmCP_HQD_ATOMIC1_PREOP_LO, mqd->cp_hqd_atomic1_preop_lo);
-       WREG32(mmCP_HQD_ATOMIC1_PREOP_HI, mqd->cp_hqd_atomic1_preop_hi);
-       WREG32(mmCP_HQD_PQ_RPTR, mqd->cp_hqd_pq_rptr);
-       WREG32(mmCP_HQD_QUANTUM, mqd->cp_hqd_quantum);
-       WREG32(mmCP_HQD_PIPE_PRIORITY, mqd->cp_hqd_pipe_priority);
-       WREG32(mmCP_HQD_QUEUE_PRIORITY, mqd->cp_hqd_queue_priority);
-       WREG32(mmCP_HQD_IQ_RPTR, mqd->cp_hqd_iq_rptr);
+       /* program all HQD registers */
+       for (mqd_reg = mmCP_HQD_VMID; mqd_reg <= mmCP_MQD_CONTROL; mqd_reg++)
+               WREG32(mqd_reg, mqd_data[mqd_reg - mmCP_MQD_BASE_ADDR]);
 
        /* activate the HQD */
-       WREG32(mmCP_HQD_ACTIVE, mqd->cp_hqd_active);
+       for (mqd_reg = mmCP_MQD_BASE_ADDR; mqd_reg <= mmCP_HQD_ACTIVE; 
mqd_reg++)
+               WREG32(mqd_reg, mqd_data[mqd_reg - mmCP_MQD_BASE_ADDR]);
 
        return 0;
 }
 
 static int gfx_v7_0_compute_queue_init(struct amdgpu_device *adev, int ring_id)
 {
        int r;
        u64 mqd_gpu_addr;
        struct cik_mqd *mqd;
        struct amdgpu_ring *ring = &adev->gfx.compute_ring[ring_id];
 
        if (ring->mqd_obj == NULL) {
                r = amdgpu_bo_create(adev,
                                sizeof(struct cik_mqd),
                                PAGE_SIZE, true,
                                AMDGPU_GEM_DOMAIN_GTT, 0, NULL, NULL,
                                &ring->mqd_obj);
                if (r) {
                        dev_warn(adev->dev, "(%d) create MQD bo failed\n", r);
                        return r;
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 11e6d47c..89626bc 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -5024,116 +5024,56 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
        mqd->cp_hqd_ctx_save_base_addr_lo = 
RREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_LO);
        mqd->cp_hqd_ctx_save_base_addr_hi = 
RREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_HI);
        mqd->cp_hqd_cntl_stack_offset = RREG32(mmCP_HQD_CNTL_STACK_OFFSET);
        mqd->cp_hqd_cntl_stack_size = RREG32(mmCP_HQD_CNTL_STACK_SIZE);
        mqd->cp_hqd_wg_state_offset = RREG32(mmCP_HQD_WG_STATE_OFFSET);
        mqd->cp_hqd_ctx_save_size = RREG32(mmCP_HQD_CTX_SAVE_SIZE);
        mqd->cp_hqd_eop_done_events = RREG32(mmCP_HQD_EOP_EVENTS);
        mqd->cp_hqd_error = RREG32(mmCP_HQD_ERROR);
        mqd->cp_hqd_eop_wptr_mem = RREG32(mmCP_HQD_EOP_WPTR_MEM);
        mqd->cp_hqd_eop_dones = RREG32(mmCP_HQD_EOP_DONES);
 
        /* activate the queue */
        mqd->cp_hqd_active = 1;
 
        return 0;
 }
 
 int gfx_v8_0_mqd_commit(struct amdgpu_device *adev,
                        struct vi_mqd *mqd)
 {
-       /* disable wptr polling */
-       WREG32_FIELD(CP_PQ_WPTR_POLL_CNTL, EN, 0);
-
-       WREG32(mmCP_HQD_EOP_BASE_ADDR, mqd->cp_hqd_eop_base_addr_lo);
-       WREG32(mmCP_HQD_EOP_BASE_ADDR_HI, mqd->cp_hqd_eop_base_addr_hi);
-
-       /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
-       WREG32(mmCP_HQD_EOP_CONTROL, mqd->cp_hqd_eop_control);
-
-       /* enable doorbell? */
-       WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->cp_hqd_pq_doorbell_control);
+       uint32_t mqd_reg;
+       uint32_t *mqd_data;
 
-       /* set pq read/write pointers */
-       WREG32(mmCP_HQD_DEQUEUE_REQUEST, mqd->cp_hqd_dequeue_request);
-       WREG32(mmCP_HQD_PQ_RPTR, mqd->cp_hqd_pq_rptr);
-       WREG32(mmCP_HQD_PQ_WPTR, mqd->cp_hqd_pq_wptr);
+       /* HQD registers extend from mmCP_MQD_BASE_ADDR to mmCP_HQD_ERROR */
+       mqd_data = &mqd->cp_mqd_base_addr_lo;
 
-       /* set the pointer to the MQD */
-       WREG32(mmCP_MQD_BASE_ADDR, mqd->cp_mqd_base_addr_lo);
-       WREG32(mmCP_MQD_BASE_ADDR_HI, mqd->cp_mqd_base_addr_hi);
-
-       /* set MQD vmid to 0 */
-       WREG32(mmCP_MQD_CONTROL, mqd->cp_mqd_control);
-
-       /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */
-       WREG32(mmCP_HQD_PQ_BASE, mqd->cp_hqd_pq_base_lo);
-       WREG32(mmCP_HQD_PQ_BASE_HI, mqd->cp_hqd_pq_base_hi);
-
-       /* set up the HQD, this is similar to CP_RB0_CNTL */
-       WREG32(mmCP_HQD_PQ_CONTROL, mqd->cp_hqd_pq_control);
-
-       /* set the wb address whether it's enabled or not */
-       WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR,
-                               mqd->cp_hqd_pq_rptr_report_addr_lo);
-       WREG32(mmCP_HQD_PQ_RPTR_REPORT_ADDR_HI,
-                               mqd->cp_hqd_pq_rptr_report_addr_hi);
-
-       /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */
-       WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR, mqd->cp_hqd_pq_wptr_poll_addr_lo);
-       WREG32(mmCP_HQD_PQ_WPTR_POLL_ADDR_HI, mqd->cp_hqd_pq_wptr_poll_addr_hi);
-
-       /* enable the doorbell if requested */
-       WREG32(mmCP_HQD_PQ_DOORBELL_CONTROL, mqd->cp_hqd_pq_doorbell_control);
-
-       /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
-       WREG32(mmCP_HQD_PQ_WPTR, mqd->cp_hqd_pq_wptr);
-       WREG32(mmCP_HQD_EOP_RPTR, mqd->cp_hqd_eop_rptr);
-       WREG32(mmCP_HQD_EOP_WPTR, mqd->cp_hqd_eop_wptr);
-
-       /* set the HQD priority */
-       WREG32(mmCP_HQD_PIPE_PRIORITY, mqd->cp_hqd_pipe_priority);
-       WREG32(mmCP_HQD_QUEUE_PRIORITY, mqd->cp_hqd_queue_priority);
-       WREG32(mmCP_HQD_QUANTUM, mqd->cp_hqd_quantum);
-
-       /* set cwsr save area */
-       WREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_LO, 
mqd->cp_hqd_ctx_save_base_addr_lo);
-       WREG32(mmCP_HQD_CTX_SAVE_BASE_ADDR_HI, 
mqd->cp_hqd_ctx_save_base_addr_hi);
-       WREG32(mmCP_HQD_CTX_SAVE_CONTROL, mqd->cp_hqd_ctx_save_control);
-       WREG32(mmCP_HQD_CNTL_STACK_OFFSET, mqd->cp_hqd_cntl_stack_offset);
-       WREG32(mmCP_HQD_CNTL_STACK_SIZE, mqd->cp_hqd_cntl_stack_size);
-       WREG32(mmCP_HQD_WG_STATE_OFFSET, mqd->cp_hqd_wg_state_offset);
-       WREG32(mmCP_HQD_CTX_SAVE_SIZE, mqd->cp_hqd_ctx_save_size);
-
-       WREG32(mmCP_HQD_IB_CONTROL, mqd->cp_hqd_ib_control);
-       WREG32(mmCP_HQD_EOP_EVENTS, mqd->cp_hqd_eop_done_events);
-       WREG32(mmCP_HQD_ERROR, mqd->cp_hqd_error);
-       WREG32(mmCP_HQD_EOP_WPTR_MEM, mqd->cp_hqd_eop_wptr_mem);
-       WREG32(mmCP_HQD_EOP_DONES, mqd->cp_hqd_eop_dones);
-
-       /* set the vmid for the queue */
-       WREG32(mmCP_HQD_VMID, mqd->cp_hqd_vmid);
+       /* disable wptr polling */
+       WREG32_FIELD(CP_PQ_WPTR_POLL_CNTL, EN, 0);
 
-       WREG32(mmCP_HQD_PERSISTENT_STATE, mqd->cp_hqd_persistent_state);
+       /* program all HQD registers */
+       for (mqd_reg = mmCP_HQD_VMID; mqd_reg <= mmCP_HQD_ERROR; mqd_reg++)
+               WREG32(mqd_reg, mqd_data[mqd_reg - mmCP_MQD_BASE_ADDR]);
 
-       /* activate the queue */
-       WREG32(mmCP_HQD_ACTIVE, mqd->cp_hqd_active);
+       /* activate the HQD */
+       for (mqd_reg = mmCP_MQD_BASE_ADDR; mqd_reg <= mmCP_HQD_ACTIVE; 
mqd_reg++)
+               WREG32(mqd_reg, mqd_data[mqd_reg - mmCP_MQD_BASE_ADDR]);
 
        return 0;
 }
 
 static int gfx_v8_0_kiq_init_queue(struct amdgpu_ring *ring)
 {
        int r = 0;
        struct amdgpu_device *adev = ring->adev;
        struct vi_mqd *mqd = ring->mqd_ptr;
        int mqd_idx = AMDGPU_MAX_COMPUTE_RINGS;
 
        gfx_v8_0_kiq_setting(ring);
 
        if (adev->gfx.in_reset) { /* for GPU_RESET case */
                /* reset MQD to a clean status */
                if (adev->gfx.mec.mqd_backup[mqd_idx])
                        memcpy(mqd, adev->gfx.mec.mqd_backup[mqd_idx], 
sizeof(*mqd));
 
                /* reset ring buffer */
                ring->wptr = 0;
-- 
2.9.3

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to