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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/sdma_v7_0.c
Extension
.c
Size
58035 bytes
Lines
1849
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 (r) {
			dev_err(adev->dev, "(%d) failed to create sdma ucode bo\n", r);
			return r;
		}

		memcpy(adev->sdma.instance[i].sdma_fw_ptr, fw_data, fw_size);

		amdgpu_bo_kunmap(adev->sdma.instance[i].sdma_fw_obj);
		amdgpu_bo_unreserve(adev->sdma.instance[i].sdma_fw_obj);

		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_CNTL));
		tmp = REG_SET_FIELD(tmp, SDMA0_IC_CNTL, GPA, 0);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_CNTL), tmp);

		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_BASE_LO),
			lower_32_bits(adev->sdma.instance[i].sdma_fw_gpu_addr));
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_BASE_HI),
			upper_32_bits(adev->sdma.instance[i].sdma_fw_gpu_addr));

		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_OP_CNTL));
		tmp = REG_SET_FIELD(tmp, SDMA0_IC_OP_CNTL, PRIME_ICACHE, 1);
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_OP_CNTL), tmp);

		/* Wait for sdma ucode init complete */
		for (j = 0; j < adev->usec_timeout; j++) {
			ic_op_cntl = RREG32_SOC15_IP(GC,
					sdma_v7_0_get_reg_offset(adev, i, regSDMA0_IC_OP_CNTL));
			sdma_status = RREG32_SOC15_IP(GC,
					sdma_v7_0_get_reg_offset(adev, i, regSDMA0_STATUS_REG));
			if ((REG_GET_FIELD(ic_op_cntl, SDMA0_IC_OP_CNTL, ICACHE_PRIMED) == 1) &&
			    (REG_GET_FIELD(sdma_status, SDMA0_STATUS_REG, UCODE_INIT_DONE) == 1))
				break;
			udelay(1);
		}

		if (j >= adev->usec_timeout) {
			dev_err(adev->dev, "failed to init sdma ucode\n");
			return -EINVAL;
		}
	}

	return 0;
}

static int sdma_v7_0_soft_reset(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	u32 tmp;
	int i;

	sdma_v7_0_gfx_stop(adev);

	for (i = 0; i < adev->sdma.num_instances; i++) {
		//tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_FREEZE));
		//tmp |= SDMA0_FREEZE__FREEZE_MASK;
		//WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_FREEZE), tmp);
		tmp = RREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL));
		tmp |= SDMA0_MCU_CNTL__HALT_MASK;
		tmp |= SDMA0_MCU_CNTL__RESET_MASK;
		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_MCU_CNTL), tmp);

		WREG32_SOC15_IP(GC, sdma_v7_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_PREEMPT), 0);

		udelay(100);

		tmp = GRBM_SOFT_RESET__SOFT_RESET_SDMA0_MASK << i;
		WREG32_SOC15(GC, 0, regGRBM_SOFT_RESET, tmp);
		tmp = RREG32_SOC15(GC, 0, regGRBM_SOFT_RESET);

		udelay(100);

		WREG32_SOC15(GC, 0, regGRBM_SOFT_RESET, 0);
		tmp = RREG32_SOC15(GC, 0, regGRBM_SOFT_RESET);

		udelay(100);
	}

	return sdma_v7_0_start(adev);
}

static bool sdma_v7_0_check_soft_reset(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	struct amdgpu_ring *ring;
	int i, r;
	long tmo = msecs_to_jiffies(1000);

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

Annotation

Implementation Notes