drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
Extension
.c
Size
68072 bytes
Lines
2067
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (!amdgpu_sriov_vf(adev)) {
			f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL));
			f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_CNTL,
						 AUTO_CTXSW_ENABLE, enable ? 1 : 0);
		}

		if (enable && amdgpu_sdma_phase_quantum) {
			WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE0_QUANTUM),
			       phase_quantum);
			WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE1_QUANTUM),
			       phase_quantum);
			WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_PHASE2_QUANTUM),
			       phase_quantum);
		}
		if (!amdgpu_sriov_vf(adev))
			WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_CNTL), f32_cntl);
	}

}

/**
 * sdma_v5_0_enable - stop the async dma engines
 *
 * @adev: amdgpu_device pointer
 * @enable: enable/disable the DMA MEs.
 *
 * Halt or unhalt the async dma engines (NAVI10).
 */
static void sdma_v5_0_enable(struct amdgpu_device *adev, bool enable)
{
	u32 f32_cntl;
	int i;
	uint32_t inst_mask;

	inst_mask = GENMASK(adev->sdma.num_instances - 1, 0);
	if (!enable) {
		sdma_v5_0_gfx_stop(adev, 1 << inst_mask);
		sdma_v5_0_rlc_stop(adev);
	}

	if (amdgpu_sriov_vf(adev))
		return;

	for (i = 0; i < adev->sdma.num_instances; i++) {
		f32_cntl = RREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL));
		f32_cntl = REG_SET_FIELD(f32_cntl, SDMA0_F32_CNTL, HALT, enable ? 0 : 1);
		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_F32_CNTL), f32_cntl);
	}
}

/**
 * sdma_v5_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. On restart, we will restore wptr and rptr.
 * Return 0 for success.
 */
static int sdma_v5_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 temp;
	u32 wptr_poll_cntl;
	u64 wptr_gpu_addr;

	ring = &adev->sdma.instance[i].ring;

	if (!amdgpu_sriov_vf(adev))
		WREG32(sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_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_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL));
	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);
#endif
	WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL), rb_cntl);

	/* Initialize the ring buffer's read and write pointers */
	if (restore) {
		WREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_RPTR), lower_32_bits(ring->wptr << 2));

Annotation

Implementation Notes