This prepares the code for implementing recovery for SDMA 2.4. Reorganize the SDMA 2.4 code so that the functions that are responsible for managing the SDMA engines take an instance ID as an argument.
This makes it possible to manage the SDMA instances independently of each other, which will enable us to also use these functions to implement resetting and recovering them independently. Signed-off-by: Timur Kristóf <[email protected]> --- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 189 +++++++++++++------------ 1 file changed, 100 insertions(+), 89 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 7c8acdf73d44..0743b782527a 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -331,163 +331,168 @@ static void sdma_v2_4_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 se * sdma_v2_4_gfx_stop - stop the gfx async dma engines * * @adev: amdgpu_device pointer + * @instance_id: SDMA engine instance ID * * Stop the gfx async dma ring buffers (VI). */ -static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev) +static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev, const u32 instance_id) { + const u32 reg_offset = sdma_offsets[instance_id]; u32 rb_cntl, ib_cntl; - int i; - for (i = 0; i < adev->sdma.num_instances; i++) { - rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); - WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); - ib_cntl = RREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i]); - ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); - WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); - } + rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + reg_offset); + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); + WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); + ib_cntl = RREG32(mmSDMA0_GFX_IB_CNTL + reg_offset); + ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 0); + WREG32(mmSDMA0_GFX_IB_CNTL + reg_offset, ib_cntl); } /** * sdma_v2_4_enable - stop the async dma engines * * @adev: amdgpu_device pointer + * @instance_id: SDMA engine instance ID * @enable: enable/disable the DMA MEs. * * Halt or unhalt the async dma engines (VI). */ -static void sdma_v2_4_enable(struct amdgpu_device *adev, bool enable) +static void sdma_v2_4_enable(struct amdgpu_device *adev, + const u32 instance_id, + const bool enable) { + const u32 reg_offset = sdma_offsets[instance_id]; u32 f32_cntl; - int i; if (!enable) { - sdma_v2_4_gfx_stop(adev); + sdma_v2_4_gfx_stop(adev, instance_id); } - for (i = 0; i < adev->sdma.num_instances; i++) { - f32_cntl = RREG32(mmSDMA0_F32_CNTL + sdma_offsets[i]); - if (enable) - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 0); - else - f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 1); - WREG32(mmSDMA0_F32_CNTL + sdma_offsets[i], f32_cntl); - } + f32_cntl = RREG32(mmSDMA0_F32_CNTL + reg_offset); + if (enable) + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 0); + else + f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, 1); + WREG32(mmSDMA0_F32_CNTL + reg_offset, f32_cntl); } /** * sdma_v2_4_gfx_resume - setup and start the async dma engines * * @adev: amdgpu_device pointer + * @instance_id: SDMA engine instance ID * * Set up the gfx DMA ring buffers and enable them (VI). * Returns 0 for success, error for failure. */ -static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) +static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev, const u32 instance_id) { - struct amdgpu_ring *ring; + struct amdgpu_ring *const ring = &adev->sdma.instance[instance_id].ring; + const u32 reg_offset = sdma_offsets[instance_id]; u32 rb_cntl, ib_cntl; u32 rb_bufsz; - int i, j, r; - - for (i = 0; i < adev->sdma.num_instances; i++) { - ring = &adev->sdma.instance[i].ring; - - mutex_lock(&adev->srbm_mutex); - for (j = 0; j < 16; j++) { - vi_srbm_select(adev, 0, 0, 0, j); - /* SDMA GFX */ - WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + sdma_offsets[i], 0); - WREG32(mmSDMA0_GFX_APE1_CNTL + sdma_offsets[i], 0); - } - vi_srbm_select(adev, 0, 0, 0, 0); - mutex_unlock(&adev->srbm_mutex); + int j; + + mutex_lock(&adev->srbm_mutex); + for (j = 0; j < 16; j++) { + vi_srbm_select(adev, 0, 0, 0, j); + /* SDMA GFX */ + WREG32(mmSDMA0_GFX_VIRTUAL_ADDR + reg_offset, 0); + WREG32(mmSDMA0_GFX_APE1_CNTL + reg_offset, 0); + } + vi_srbm_select(adev, 0, 0, 0, 0); + mutex_unlock(&adev->srbm_mutex); - WREG32(mmSDMA0_TILING_CONFIG + sdma_offsets[i], - adev->gfx.config.gb_addr_config & 0x70); + WREG32(mmSDMA0_TILING_CONFIG + reg_offset, + adev->gfx.config.gb_addr_config & 0x70); - WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + sdma_offsets[i], 0); + WREG32(mmSDMA0_SEM_WAIT_FAIL_TIMER_CNTL + reg_offset, 0); - /* Set ring buffer size in dwords */ - rb_bufsz = order_base_2(ring->ring_size / 4); - rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SIZE, rb_bufsz); + /* Set ring buffer size in dwords */ + rb_bufsz = order_base_2(ring->ring_size / 4); + rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + reg_offset); + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SIZE, rb_bufsz); #ifdef __BIG_ENDIAN - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SWAP_ENABLE, 1); - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, - RPTR_WRITEBACK_SWAP_ENABLE, 1); + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_SWAP_ENABLE, 1); + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, + RPTR_WRITEBACK_SWAP_ENABLE, 1); #endif - WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); + WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); - /* Initialize the ring buffer's read and write pointers */ - WREG32(mmSDMA0_GFX_RB_RPTR + sdma_offsets[i], 0); - WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], 0); - WREG32(mmSDMA0_GFX_IB_RPTR + sdma_offsets[i], 0); - WREG32(mmSDMA0_GFX_IB_OFFSET + sdma_offsets[i], 0); + /* Initialize the ring buffer's read and write pointers */ + WREG32(mmSDMA0_GFX_RB_RPTR + reg_offset, 0); + WREG32(mmSDMA0_GFX_RB_WPTR + reg_offset, 0); + WREG32(mmSDMA0_GFX_IB_RPTR + reg_offset, 0); + WREG32(mmSDMA0_GFX_IB_OFFSET + reg_offset, 0); - /* set the wb address whether it's enabled or not */ - WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + sdma_offsets[i], - upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF); - WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + sdma_offsets[i], - lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC); + /* set the wb address whether it's enabled or not */ + WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_HI + reg_offset, + upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF); + WREG32(mmSDMA0_GFX_RB_RPTR_ADDR_LO + reg_offset, + lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC); - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1); + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1); - WREG32(mmSDMA0_GFX_RB_BASE + sdma_offsets[i], ring->gpu_addr >> 8); - WREG32(mmSDMA0_GFX_RB_BASE_HI + sdma_offsets[i], ring->gpu_addr >> 40); + WREG32(mmSDMA0_GFX_RB_BASE + reg_offset, ring->gpu_addr >> 8); + WREG32(mmSDMA0_GFX_RB_BASE_HI + reg_offset, ring->gpu_addr >> 40); - ring->wptr = 0; - WREG32(mmSDMA0_GFX_RB_WPTR + sdma_offsets[i], ring->wptr << 2); + ring->wptr = 0; + WREG32(mmSDMA0_GFX_RB_WPTR + reg_offset, ring->wptr << 2); - /* enable DMA RB */ - rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); - WREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i], rb_cntl); + /* enable DMA RB */ + rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 1); + WREG32(mmSDMA0_GFX_RB_CNTL + reg_offset, rb_cntl); - ib_cntl = RREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i]); - ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 1); + ib_cntl = RREG32(mmSDMA0_GFX_IB_CNTL + reg_offset); + ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_ENABLE, 1); #ifdef __BIG_ENDIAN - ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_SWAP_ENABLE, 1); + ib_cntl = REG_SET_FIELD(ib_cntl, SDMA0_GFX_IB_CNTL, IB_SWAP_ENABLE, 1); #endif - /* enable DMA IBs */ - WREG32(mmSDMA0_GFX_IB_CNTL + sdma_offsets[i], ib_cntl); - } + /* enable DMA IBs */ + WREG32(mmSDMA0_GFX_IB_CNTL + reg_offset, ib_cntl); - sdma_v2_4_enable(adev, true); - for (i = 0; i < adev->sdma.num_instances; i++) { - ring = &adev->sdma.instance[i].ring; - r = amdgpu_ring_test_helper(ring); - if (r) - return r; - } + sdma_v2_4_enable(adev, instance_id, true); - return 0; + return amdgpu_ring_test_helper(ring); } - /** * sdma_v2_4_start - setup and start the async dma engines * * @adev: amdgpu_device pointer + * @instance_id: SDMA engine instance ID * * Set up the DMA engines and enable them (VI). * Returns 0 for success, error for failure. */ -static int sdma_v2_4_start(struct amdgpu_device *adev) +static int sdma_v2_4_start(struct amdgpu_device *adev, const u32 instance_id) { int r; /* halt the engine before programing */ - sdma_v2_4_enable(adev, false); + sdma_v2_4_enable(adev, instance_id, false); /* start the gfx rings and rlc compute queues */ - r = sdma_v2_4_gfx_resume(adev); + r = sdma_v2_4_gfx_resume(adev, instance_id); if (r) return r; return 0; } +/** + * sdma_v2_4_stop() - Stop an SDMA engine + * + * @adev: amdgpu_device pointer + * @instance_id: SDMA engine instance ID + * + * Stop the given SDMA engine instance (VI). + */ +static void sdma_v2_4_stop(struct amdgpu_device *adev, const u32 instance_id) +{ + sdma_v2_4_enable(adev, instance_id, false); +} + /** * sdma_v2_4_ring_test_ring - simple async dma engine test * @@ -863,14 +868,16 @@ static int sdma_v2_4_sw_fini(struct amdgpu_ip_block *ip_block) static int sdma_v2_4_hw_init(struct amdgpu_ip_block *ip_block) { - int r; struct amdgpu_device *adev = ip_block->adev; + int i, r; sdma_v2_4_init_golden_registers(adev); - r = sdma_v2_4_start(adev); - if (r) - return r; + for (i = 0; i < adev->sdma.num_instances; ++i) { + r = sdma_v2_4_start(adev, i); + if (r) + return r; + } sdma_v2_4_set_buffer_funcs(adev); @@ -879,7 +886,11 @@ static int sdma_v2_4_hw_init(struct amdgpu_ip_block *ip_block) static int sdma_v2_4_hw_fini(struct amdgpu_ip_block *ip_block) { - sdma_v2_4_enable(ip_block->adev, false); + struct amdgpu_device *adev = ip_block->adev; + int i; + + for (i = 0; i < adev->sdma.num_instances; ++i) + sdma_v2_4_stop(adev, i); return 0; } -- 2.55.0
