drm/amdgpu/gfx11: add aggregated doorbell support
authorJack Xiao <Jack.Xiao@amd.com>
Mon, 11 Jul 2022 07:24:48 +0000 (15:24 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 13 Jul 2022 15:25:17 +0000 (11:25 -0400)
Port aggregated doorbell support to gfx11.

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

index 4e26681..0d8193b 100644 (file)
@@ -5379,14 +5379,45 @@ static u64 gfx_v11_0_ring_get_wptr_gfx(struct amdgpu_ring *ring)
 static void gfx_v11_0_ring_set_wptr_gfx(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
+       uint32_t *wptr_saved;
+       uint32_t *is_queue_unmap;
+       uint64_t aggregated_db_index;
+       uint32_t mqd_size = adev->mqds[AMDGPU_HW_IP_GFX].mqd_size;
+       uint64_t wptr_tmp;
 
-       if (ring->use_doorbell) {
-               /* XXX check if swapping is necessary on BE */
-               atomic64_set((atomic64_t *)ring->wptr_cpu_addr, ring->wptr);
-               WDOORBELL64(ring->doorbell_index, ring->wptr);
+       if (ring->is_mes_queue) {
+               wptr_saved = (uint32_t *)(ring->mqd_ptr + mqd_size);
+               is_queue_unmap = (uint32_t *)(ring->mqd_ptr + mqd_size +
+                                             sizeof(uint32_t));
+               aggregated_db_index =
+                       amdgpu_mes_get_aggregated_doorbell_index(adev,
+                                                                ring->hw_prio);
+
+               wptr_tmp = ring->wptr & ring->buf_mask;
+               atomic64_set((atomic64_t *)ring->wptr_cpu_addr, wptr_tmp);
+               *wptr_saved = wptr_tmp;
+               /* assume doorbell always being used by mes mapped queue */
+               if (*is_queue_unmap) {
+                       WDOORBELL64(aggregated_db_index, wptr_tmp);
+                       WDOORBELL64(ring->doorbell_index, wptr_tmp);
+               } else {
+                       WDOORBELL64(ring->doorbell_index, wptr_tmp);
+
+                       if (*is_queue_unmap)
+                               WDOORBELL64(aggregated_db_index, wptr_tmp);
+               }
        } else {
-               WREG32_SOC15(GC, 0, regCP_RB0_WPTR, lower_32_bits(ring->wptr));
-               WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
+               if (ring->use_doorbell) {
+                       /* XXX check if swapping is necessary on BE */
+                       atomic64_set((atomic64_t *)ring->wptr_cpu_addr,
+                                    ring->wptr);
+                       WDOORBELL64(ring->doorbell_index, ring->wptr);
+               } else {
+                       WREG32_SOC15(GC, 0, regCP_RB0_WPTR,
+                                    lower_32_bits(ring->wptr));
+                       WREG32_SOC15(GC, 0, regCP_RB0_WPTR_HI,
+                                    upper_32_bits(ring->wptr));
+               }
        }
 }
 
@@ -5411,13 +5442,42 @@ static u64 gfx_v11_0_ring_get_wptr_compute(struct amdgpu_ring *ring)
 static void gfx_v11_0_ring_set_wptr_compute(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
+       uint32_t *wptr_saved;
+       uint32_t *is_queue_unmap;
+       uint64_t aggregated_db_index;
+       uint32_t mqd_size = adev->mqds[AMDGPU_HW_IP_COMPUTE].mqd_size;
+       uint64_t wptr_tmp;
 
-       /* XXX check if swapping is necessary on BE */
-       if (ring->use_doorbell) {
-               atomic64_set((atomic64_t *)ring->wptr_cpu_addr, ring->wptr);
-               WDOORBELL64(ring->doorbell_index, ring->wptr);
+       if (ring->is_mes_queue) {
+               wptr_saved = (uint32_t *)(ring->mqd_ptr + mqd_size);
+               is_queue_unmap = (uint32_t *)(ring->mqd_ptr + mqd_size +
+                                             sizeof(uint32_t));
+               aggregated_db_index =
+                       amdgpu_mes_get_aggregated_doorbell_index(adev,
+                                                                ring->hw_prio);
+
+               wptr_tmp = ring->wptr & ring->buf_mask;
+               atomic64_set((atomic64_t *)ring->wptr_cpu_addr, wptr_tmp);
+               *wptr_saved = wptr_tmp;
+               /* assume doorbell always used by mes mapped queue */
+               if (*is_queue_unmap) {
+                       WDOORBELL64(aggregated_db_index, wptr_tmp);
+                       WDOORBELL64(ring->doorbell_index, wptr_tmp);
+               } else {
+                       WDOORBELL64(ring->doorbell_index, wptr_tmp);
+
+                       if (*is_queue_unmap)
+                               WDOORBELL64(aggregated_db_index, wptr_tmp);
+               }
        } else {
-               BUG(); /* only DOORBELL method supported on gfx11 now */
+               /* XXX check if swapping is necessary on BE */
+               if (ring->use_doorbell) {
+                       atomic64_set((atomic64_t *)ring->wptr_cpu_addr,
+                                    ring->wptr);
+                       WDOORBELL64(ring->doorbell_index, ring->wptr);
+               } else {
+                       BUG(); /* only DOORBELL method supported on gfx11 now */
+               }
        }
 }