drm/amdgpu/mes10.1: initialize the mqd
authorJack Xiao <Jack.Xiao@amd.com>
Tue, 30 Apr 2019 03:27:10 +0000 (11:27 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 1 Jul 2020 05:59:08 +0000 (01:59 -0400)
Initialize the mqd according to mes ring setup.

Signed-off-by: Jack Xiao <Jack.Xiao@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/mes_v10_1.c

index ace82c4..36d8314 100644 (file)
@@ -350,6 +350,136 @@ static int mes_v10_1_allocate_eop_buf(struct amdgpu_device *adev)
        return 0;
 }
 
+static int mes_v10_1_mqd_init(struct amdgpu_ring *ring)
+{
+       struct amdgpu_device *adev = ring->adev;
+       struct v10_compute_mqd *mqd = ring->mqd_ptr;
+       uint64_t hqd_gpu_addr, wb_gpu_addr, eop_base_addr;
+       uint32_t tmp;
+
+       mqd->header = 0xC0310800;
+       mqd->compute_pipelinestat_enable = 0x00000001;
+       mqd->compute_static_thread_mgmt_se0 = 0xffffffff;
+       mqd->compute_static_thread_mgmt_se1 = 0xffffffff;
+       mqd->compute_static_thread_mgmt_se2 = 0xffffffff;
+       mqd->compute_static_thread_mgmt_se3 = 0xffffffff;
+       mqd->compute_misc_reserved = 0x00000003;
+
+       eop_base_addr = ring->eop_gpu_addr >> 8;
+       mqd->cp_hqd_eop_base_addr_lo = eop_base_addr;
+       mqd->cp_hqd_eop_base_addr_hi = upper_32_bits(eop_base_addr);
+
+       /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */
+       tmp = RREG32_SOC15(GC, 0, mmCP_HQD_EOP_CONTROL);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_EOP_CONTROL, EOP_SIZE,
+                       (order_base_2(MES_EOP_SIZE / 4) - 1));
+
+       mqd->cp_hqd_eop_control = tmp;
+
+       /* enable doorbell? */
+       tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
+
+       if (ring->use_doorbell) {
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_OFFSET, ring->doorbell_index);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_EN, 1);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_SOURCE, 0);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_HIT, 0);
+       }
+       else
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_EN, 0);
+
+       mqd->cp_hqd_pq_doorbell_control = tmp;
+
+       /* disable the queue if it's active */
+       ring->wptr = 0;
+       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;
+
+       /* set the pointer to the MQD */
+       mqd->cp_mqd_base_addr_lo = ring->mqd_gpu_addr & 0xfffffffc;
+       mqd->cp_mqd_base_addr_hi = upper_32_bits(ring->mqd_gpu_addr);
+
+       /* set MQD vmid to 0 */
+       tmp = RREG32_SOC15(GC, 0, mmCP_MQD_CONTROL);
+       tmp = REG_SET_FIELD(tmp, CP_MQD_CONTROL, VMID, 0);
+       mqd->cp_mqd_control = tmp;
+
+       /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */
+       hqd_gpu_addr = ring->gpu_addr >> 8;
+       mqd->cp_hqd_pq_base_lo = hqd_gpu_addr;
+       mqd->cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr);
+
+       /* set up the HQD, this is similar to CP_RB0_CNTL */
+       tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_CONTROL);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, QUEUE_SIZE,
+                           (order_base_2(ring->ring_size / 4) - 1));
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE,
+                           ((order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1) << 8));
+#ifdef __BIG_ENDIAN
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1);
+#endif
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1);
+       mqd->cp_hqd_pq_control = tmp;
+
+       /* set the wb address whether it's enabled or not */
+       wb_gpu_addr = adev->wb.gpu_addr + (ring->rptr_offs * 4);
+       mqd->cp_hqd_pq_rptr_report_addr_lo = wb_gpu_addr & 0xfffffffc;
+       mqd->cp_hqd_pq_rptr_report_addr_hi =
+               upper_32_bits(wb_gpu_addr) & 0xffff;
+
+       /* only used if CP_PQ_WPTR_POLL_CNTL.CP_PQ_WPTR_POLL_CNTL__EN_MASK=1 */
+       wb_gpu_addr = adev->wb.gpu_addr + (ring->wptr_offs * 4);
+       mqd->cp_hqd_pq_wptr_poll_addr_lo = wb_gpu_addr & 0xfffffff8;
+       mqd->cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff;
+
+       tmp = 0;
+       /* enable the doorbell if requested */
+       if (ring->use_doorbell) {
+               tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_DOORBELL_CONTROL);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                               DOORBELL_OFFSET, ring->doorbell_index);
+
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_EN, 1);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_SOURCE, 0);
+               tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_DOORBELL_CONTROL,
+                                   DOORBELL_HIT, 0);
+       }
+
+       mqd->cp_hqd_pq_doorbell_control = tmp;
+
+       /* reset read and write pointers, similar to CP_RB0_WPTR/_RPTR */
+       ring->wptr = 0;
+       mqd->cp_hqd_pq_rptr = RREG32_SOC15(GC, 0, mmCP_HQD_PQ_RPTR);
+
+       /* set the vmid for the queue */
+       mqd->cp_hqd_vmid = 0;
+
+       tmp = RREG32_SOC15(GC, 0, mmCP_HQD_PERSISTENT_STATE);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_PERSISTENT_STATE, PRELOAD_SIZE, 0x53);
+       mqd->cp_hqd_persistent_state = tmp;
+
+       /* set MIN_IB_AVAIL_SIZE */
+       tmp = RREG32_SOC15(GC, 0, mmCP_HQD_IB_CONTROL);
+       tmp = REG_SET_FIELD(tmp, CP_HQD_IB_CONTROL, MIN_IB_AVAIL_SIZE, 3);
+       mqd->cp_hqd_ib_control = tmp;
+
+       /* activate the queue */
+       mqd->cp_hqd_active = 1;
+       return 0;
+}
+
 static int mes_v10_1_ring_init(struct amdgpu_device *adev)
 {
        struct amdgpu_ring *ring;