Commit 2d7a1f71 authored by Le Ma's avatar Le Ma Committed by Alex Deucher
Browse files

drm/amdgpu/mes: ring aggregatged doorbell when mes queue is unmapped



Ring aggregated doorbel to make unmapped queue scheduled in mes firmware.

Signed-off-by: default avatarLe Ma <le.ma@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Reviewed-by: default avatarJack Xiao <Jack.Xiao@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b7320117
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -725,6 +725,7 @@ int amdgpu_mes_add_hw_queue(struct amdgpu_device *adev, int gang_id,
	queue->queue_type = qprops->queue_type;
	queue->paging = qprops->paging;
	queue->gang = gang;
	queue->ring->mqd_ptr = queue->mqd_cpu_ptr;
	list_add_tail(&queue->list, &gang->queue_list);

	amdgpu_mes_unlock(&adev->mes);
@@ -1081,6 +1082,12 @@ void amdgpu_mes_remove_ring(struct amdgpu_device *adev,
	kfree(ring);
}

uint32_t amdgpu_mes_get_aggregated_doorbell_index(struct amdgpu_device *adev,
						   enum amdgpu_mes_priority_level prio)
{
	return adev->mes.aggregated_doorbells[prio];
}

int amdgpu_mes_ctx_alloc_meta_data(struct amdgpu_device *adev,
				   struct amdgpu_mes_ctx_data *ctx_data)
{
+3 −0
Original line number Diff line number Diff line
@@ -347,6 +347,9 @@ int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id,
void amdgpu_mes_remove_ring(struct amdgpu_device *adev,
			    struct amdgpu_ring *ring);

uint32_t amdgpu_mes_get_aggregated_doorbell_index(struct amdgpu_device *adev,
						   enum amdgpu_mes_priority_level prio);

int amdgpu_mes_ctx_alloc_meta_data(struct amdgpu_device *adev,
				   struct amdgpu_mes_ctx_data *ctx_data);
void amdgpu_mes_ctx_free_meta_data(struct amdgpu_mes_ctx_data *ctx_data);
+71 −11
Original line number Diff line number Diff line
@@ -8525,14 +8525,45 @@ static u64 gfx_v10_0_ring_get_wptr_gfx(struct amdgpu_ring *ring)
static void gfx_v10_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->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,
			AMDGPU_MES_PRIORITY_LEVEL_NORMAL);

		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 {
		if (ring->use_doorbell) {
			/* XXX check if swapping is necessary on BE */
		atomic64_set((atomic64_t *)ring->wptr_cpu_addr, ring->wptr);
			atomic64_set((atomic64_t *)ring->wptr_cpu_addr,
				     ring->wptr);
			WDOORBELL64(ring->doorbell_index, ring->wptr);
		} else {
		WREG32_SOC15(GC, 0, mmCP_RB0_WPTR, lower_32_bits(ring->wptr));
		WREG32_SOC15(GC, 0, mmCP_RB0_WPTR_HI, upper_32_bits(ring->wptr));
			WREG32_SOC15(GC, 0, mmCP_RB0_WPTR,
				     lower_32_bits(ring->wptr));
			WREG32_SOC15(GC, 0, mmCP_RB0_WPTR_HI,
				     upper_32_bits(ring->wptr));
		}
	}
}

@@ -8557,15 +8588,44 @@ static u64 gfx_v10_0_ring_get_wptr_compute(struct amdgpu_ring *ring)
static void gfx_v10_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;

	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,
			AMDGPU_MES_PRIORITY_LEVEL_NORMAL);

		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 {
		/* XXX check if swapping is necessary on BE */
		if (ring->use_doorbell) {
		atomic64_set((atomic64_t *)ring->wptr_cpu_addr, ring->wptr);
			atomic64_set((atomic64_t *)ring->wptr_cpu_addr,
				     ring->wptr);
			WDOORBELL64(ring->doorbell_index, ring->wptr);
		} else {
			BUG(); /* only DOORBELL method supported on gfx10 now */
		}
	}
}

static void gfx_v10_0_ring_emit_hdp_flush(struct amdgpu_ring *ring)
{
+56 −23
Original line number Diff line number Diff line
@@ -389,13 +389,43 @@ static uint64_t sdma_v5_0_ring_get_wptr(struct amdgpu_ring *ring)
static void sdma_v5_0_ring_set_wptr(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_DMA].mqd_size;

	DRM_DEBUG("Setting write pointer\n");
	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,
			AMDGPU_MES_PRIORITY_LEVEL_NORMAL);

		atomic64_set((atomic64_t *)ring->wptr_cpu_addr,
			     ring->wptr << 2);
		*wptr_saved = ring->wptr << 2;
		if (*is_queue_unmap) {
			WDOORBELL64(aggregated_db_index, ring->wptr << 2);
			DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
					ring->doorbell_index, ring->wptr << 2);
			WDOORBELL64(ring->doorbell_index, ring->wptr << 2);
		} else {
			DRM_DEBUG("calling WDOORBELL64(0x%08x, 0x%016llx)\n",
					ring->doorbell_index, ring->wptr << 2);
			WDOORBELL64(ring->doorbell_index, ring->wptr << 2);

			if (*is_queue_unmap)
				WDOORBELL64(aggregated_db_index,
					    ring->wptr << 2);
		}
	} else {
		if (ring->use_doorbell) {
			DRM_DEBUG("Using doorbell -- "
				  "wptr_offs == 0x%08x "
				"lower_32_bits(ring->wptr << 2) == 0x%08x "
				"upper_32_bits(ring->wptr << 2) == 0x%08x\n",
				  "lower_32_bits(ring->wptr) << 2 == 0x%08x "
				  "upper_32_bits(ring->wptr) << 2 == 0x%08x\n",
				  ring->wptr_offs,
				  lower_32_bits(ring->wptr << 2),
				  upper_32_bits(ring->wptr << 2));
@@ -413,12 +443,15 @@ static void sdma_v5_0_ring_set_wptr(struct amdgpu_ring *ring)
				  lower_32_bits(ring->wptr << 2),
				  ring->me,
				  upper_32_bits(ring->wptr << 2));
		WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR),
			WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev,
					     ring->me, mmSDMA0_GFX_RB_WPTR),
					lower_32_bits(ring->wptr << 2));
		WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, ring->me, mmSDMA0_GFX_RB_WPTR_HI),
			WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev,
					     ring->me, mmSDMA0_GFX_RB_WPTR_HI),
					upper_32_bits(ring->wptr << 2));
		}
	}
}

static void sdma_v5_0_ring_insert_nop(struct amdgpu_ring *ring, uint32_t count)
{