Commit 8a4c6fc8 authored by Jesse.zhang@amd.com's avatar Jesse.zhang@amd.com Committed by Alex Deucher
Browse files

drm/amdgpu/sdma7: Implement resume function for each instance



Extracts the resume sequence for per sdma instance from sdma_v7_0_gfx_resume.
This function can be used in start or restart scenarios of specific instances.

Signed-off-by: default avatarJesse Zhang <jesse.zhang@amd.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 7ecc7329
Loading
Loading
Loading
Loading
+141 −118
Original line number Diff line number Diff line
@@ -490,30 +490,28 @@ static void sdma_v7_0_enable(struct amdgpu_device *adev, bool enable)
}

/**
 * sdma_v7_0_gfx_resume - setup and start the async dma engines
 * sdma_v7_0_gfx_resume_instance - start/restart a certain sdma engine
 *
 * @adev: amdgpu_device pointer
 * @i: instance
 * @restore: used to restore wptr when restart
 *
 * Set up the gfx DMA ring buffers and enable them.
 * Returns 0 for success, error for failure.
 * Set up the gfx DMA ring buffers and enable them. On restart, we will restore wptr and rptr.
 * Return 0 for success.
 */
static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
static int sdma_v7_0_gfx_resume_instance(struct amdgpu_device *adev, int i, bool restore)
{
	struct amdgpu_ring *ring;
	u32 rb_cntl, ib_cntl;
	u32 rb_bufsz;
	u32 doorbell;
	u32 doorbell_offset;
	u32 tmp;
	u32 temp;
	u64 wptr_gpu_addr;
	int i, r;
	int r;

	for (i = 0; i < adev->sdma.num_instances; i++) {
	ring = &adev->sdma.instance[i].ring;

		//if (!amdgpu_sriov_vf(adev))
		//	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_SEM_WAIT_FAIL_TIMER_CNTL), 0);

	/* Set ring buffer size in dwords */
	rb_bufsz = order_base_2(ring->ring_size / 4);
	rb_cntl = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL));
@@ -527,11 +525,17 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL), rb_cntl);

	/* Initialize the ring buffer's read and write pointers */
	if (restore) {
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_RPTR), lower_32_bits(ring->wptr << 2));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_RPTR_HI), upper_32_bits(ring->wptr << 2));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_WPTR), lower_32_bits(ring->wptr << 2));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_WPTR_HI), upper_32_bits(ring->wptr << 2));
	} else {
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_RPTR), 0);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_RPTR_HI), 0);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_WPTR), 0);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_WPTR_HI), 0);

	}
	/* setup the wptr shadow polling */
	wptr_gpu_addr = ring->wptr_gpu_addr;
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_WPTR_POLL_ADDR_LO),
@@ -550,11 +554,13 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 1);
	else
		rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, WPTR_POLL_ENABLE, 0);

	rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, MCU_WPTR_POLL_ENABLE, 1);

	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_BASE_HI), ring->gpu_addr >> 40);

	if (!restore)
		ring->wptr = 0;

	/* before programing wptr to a less value, need set minor_ptr_update first */
@@ -590,32 +596,32 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_MINOR_PTR_UPDATE), 0);

	/* Set up sdma hang watchdog */
		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_WATCHDOG_CNTL));
	temp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_WATCHDOG_CNTL));
	/* 100ms per unit */
		tmp = REG_SET_FIELD(tmp, SDMA0_WATCHDOG_CNTL, QUEUE_HANG_COUNT,
	temp = REG_SET_FIELD(temp, SDMA0_WATCHDOG_CNTL, QUEUE_HANG_COUNT,
			     max(adev->usec_timeout/100000, 1));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_WATCHDOG_CNTL), tmp);
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_WATCHDOG_CNTL), temp);

	/* Set up RESP_MODE to non-copy addresses */
		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_CNTL));
		tmp = REG_SET_FIELD(tmp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
		tmp = REG_SET_FIELD(tmp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_CNTL), tmp);
	temp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_CNTL));
	temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, RESP_MODE, 3);
	temp = REG_SET_FIELD(temp, SDMA0_UTCL1_CNTL, REDO_DELAY, 9);
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_CNTL), temp);

	/* program default cache read and write policy */
		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_PAGE));
	temp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_PAGE));
	/* clean read policy and write policy bits */
		tmp &= 0xFF0FFF;
		tmp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) |
	temp &= 0xFF0FFF;
	temp |= ((CACHE_READ_POLICY_L2__DEFAULT << 12) |
		 (CACHE_WRITE_POLICY_L2__DEFAULT << 14));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_PAGE), tmp);
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_UTCL1_PAGE), temp);

	if (!amdgpu_sriov_vf(adev)) {
		/* unhalt engine */
			tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL));
			tmp = REG_SET_FIELD(tmp, SDMA0_MCU_CNTL, HALT, 0);
			tmp = REG_SET_FIELD(tmp, SDMA0_MCU_CNTL, RESET, 0);
			WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL), tmp);
		temp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL));
		temp = REG_SET_FIELD(temp, SDMA0_MCU_CNTL, HALT, 0);
		temp = REG_SET_FIELD(temp, SDMA0_MCU_CNTL, RESET, 0);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL), temp);
	}

	/* enable DMA RB */
@@ -629,7 +635,6 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
#endif
	/* enable DMA IBs */
	WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_IB_CNTL), ib_cntl);

	ring->sched.ready = true;

	if (amdgpu_sriov_vf(adev)) { /* bare-metal sequence doesn't need below to lines */
@@ -638,14 +643,32 @@ static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
	}

	r = amdgpu_ring_test_helper(ring);
		if (r) {
	if (r)
		ring->sched.ready = false;

	return r;
}

/**
 * sdma_v7_0_gfx_resume - setup and start the async dma engines
 *
 * @adev: amdgpu_device pointer
 *
 * Set up the gfx DMA ring buffers and enable them.
 * Returns 0 for success, error for failure.
 */
static int sdma_v7_0_gfx_resume(struct amdgpu_device *adev)
{
	int i, r;

	for (i = 0; i < adev->sdma.num_instances; i++) {
		r = sdma_v7_0_gfx_resume_instance(adev, i, false);
		if (r)
			return r;
	}

	return 0;

}

/**