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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/mes_v12_1.c
Extension
.c
Size
72945 bytes
Lines
2332
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 (adev->enable_uni_mes && num_xcc > 1) {
				r = mes_v12_1_allocate_shared_cmd_buf(adev,
							      pipe, xcc_id);
				if (r)
					return r;
			}
		}
	}

	return 0;
}

static int mes_v12_1_sw_fini(struct amdgpu_ip_block *ip_block)
{
	struct amdgpu_device *adev = ip_block->adev;
	int pipe, inst, xcc_id, num_xcc = NUM_XCC(adev->gfx.xcc_mask);

	for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) {
		for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++) {
			inst = MES_PIPE_INST(xcc_id, pipe);

			amdgpu_bo_free_kernel(&adev->mes.shared_cmd_buf_obj[inst],
					      &adev->mes.shared_cmd_buf_gpu_addr[inst],
					      NULL);

			kfree(adev->mes.mqd_backup[inst]);

			amdgpu_bo_free_kernel(&adev->mes.eop_gpu_obj[inst],
					      &adev->mes.eop_gpu_addr[inst],
					      NULL);

			if (adev->enable_uni_mes || pipe == AMDGPU_MES_SCHED_PIPE) {
				amdgpu_bo_free_kernel(&adev->mes.ring[inst].mqd_obj,
						      &adev->mes.ring[inst].mqd_gpu_addr,
						      &adev->mes.ring[inst].mqd_ptr);
				amdgpu_ring_fini(&adev->mes.ring[inst]);
			}
		}
	}

	for (pipe = 0; pipe < AMDGPU_MAX_MES_PIPES; pipe++)
		amdgpu_ucode_release(&adev->mes.fw[pipe]);

	for (xcc_id = 0; xcc_id < num_xcc; xcc_id++) {
		if (!adev->enable_uni_mes) {
			amdgpu_bo_free_kernel(&adev->gfx.kiq[xcc_id].ring.mqd_obj,
				      &adev->gfx.kiq[xcc_id].ring.mqd_gpu_addr,
				      &adev->gfx.kiq[xcc_id].ring.mqd_ptr);
			amdgpu_ring_fini(&adev->gfx.kiq[xcc_id].ring);
		}

		if (adev->firmware.load_type == AMDGPU_FW_LOAD_DIRECT) {
			mes_v12_1_free_ucode_buffers(adev,
				       AMDGPU_MES_KIQ_PIPE, xcc_id);
			mes_v12_1_free_ucode_buffers(adev,
				       AMDGPU_MES_SCHED_PIPE, xcc_id);
		}
	}

	amdgpu_mes_fini(adev);
	return 0;
}

static void mes_v12_1_kiq_dequeue_sched(struct amdgpu_device *adev,
					  int xcc_id)
{
	uint32_t data;
	int i;

	mutex_lock(&adev->srbm_mutex);
	soc_v1_0_grbm_select(adev, 3, AMDGPU_MES_SCHED_PIPE, 0, 0,
			     GET_INST(GC, xcc_id));

	/* disable the queue if it's active */
	if (RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_ACTIVE) & 1) {
		WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_DEQUEUE_REQUEST, 1);
		for (i = 0; i < adev->usec_timeout; i++) {
			if (!(RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_ACTIVE) & 1))
				break;
			udelay(1);
		}
	}
	data = RREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL);
	data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
				DOORBELL_EN, 0);
	data = REG_SET_FIELD(data, CP_HQD_PQ_DOORBELL_CONTROL,
				DOORBELL_HIT, 1);
	WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, data);

	WREG32_SOC15(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, 0);

Annotation

Implementation Notes