summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
diff options
context:
space:
mode:
authorAndres Rodriguez <andresx7@gmail.com>2017-02-24 15:28:43 -0500
committerAlex Deucher <alexander.deucher@amd.com>2017-05-31 16:48:59 -0400
commit894700f3b7e01e87954a94be6508205c7f024386 (patch)
tree1c1d577e45dd4f99147bc565d65d64ae7d126d39 /drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
parent0a281f5a2cba94a574167edadca88a3130a88612 (diff)
drm/amdgpu: condense mqd programming sequence
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.Kuehling@amd.com> Reviewed-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Andres Rodriguez <andresx7@gmail.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c84
1 files changed, 12 insertions, 72 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
index 328549e114a4..29ec429a54c5 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
@@ -5060,82 +5060,22 @@ static int gfx_v8_0_mqd_init(struct amdgpu_ring *ring)
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;
}