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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
Extension
.c
Size
60220 bytes
Lines
1942
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 (req) {
			if (val == tmp)
				break;
		} else {
			tmp = REG_SET_FIELD(tmp, CP_GFX_INDEX_MUTEX,
					    REQUEST, 1);

			/* unlocked or locked by firmware */
			if (val != tmp)
				break;
		}
		udelay(1);
	}

	if (i >= adev->usec_timeout)
		return -EINVAL;

	return 0;
}

static int mes_v12_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_type,
				      uint32_t me_id, uint32_t pipe_id,
				      uint32_t queue_id, uint32_t vmid)
{
	struct amdgpu_device *adev = mes->adev;
	uint32_t value, reg;
	int i, r = 0;

	amdgpu_gfx_rlc_enter_safe_mode(adev, 0);

	if (queue_type == AMDGPU_RING_TYPE_GFX) {
		dev_info(adev->dev, "reset gfx queue (%d:%d:%d: vmid:%d)\n",
			 me_id, pipe_id, queue_id, vmid);

		mutex_lock(&adev->gfx.reset_sem_mutex);
		gfx_v12_0_request_gfx_index_mutex(adev, true);
		/* all se allow writes */
		WREG32_SOC15(GC, 0, regGRBM_GFX_INDEX,
			     (uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT));
		value = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
		if (pipe_id == 0)
			value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id);
		else
			value = REG_SET_FIELD(value, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id);
		WREG32_SOC15(GC, 0, regCP_VMID_RESET, value);
		gfx_v12_0_request_gfx_index_mutex(adev, false);
		mutex_unlock(&adev->gfx.reset_sem_mutex);

		mutex_lock(&adev->srbm_mutex);
		soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
		/* wait till dequeue take effects */
		for (i = 0; i < adev->usec_timeout; i++) {
			if (!(RREG32_SOC15(GC, 0, regCP_GFX_HQD_ACTIVE) & 1))
				break;
			udelay(1);
		}
		if (i >= adev->usec_timeout) {
			dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n");
			r = -ETIMEDOUT;
		}

		soc21_grbm_select(adev, 0, 0, 0, 0);
		mutex_unlock(&adev->srbm_mutex);
	} else if (queue_type == AMDGPU_RING_TYPE_COMPUTE) {
		dev_info(adev->dev, "reset compute queue (%d:%d:%d)\n",
			 me_id, pipe_id, queue_id);
		mutex_lock(&adev->srbm_mutex);
		soc21_grbm_select(adev, me_id, pipe_id, queue_id, 0);
		WREG32_SOC15(GC, 0, regCP_HQD_DEQUEUE_REQUEST, 0x2);
		WREG32_SOC15(GC, 0, regSPI_COMPUTE_QUEUE_RESET, 0x1);

		/* wait till dequeue take effects */
		for (i = 0; i < adev->usec_timeout; i++) {
			if (!(RREG32_SOC15(GC, 0, regCP_HQD_ACTIVE) & 1))
				break;
			udelay(1);
		}
		if (i >= adev->usec_timeout) {
			dev_err(adev->dev, "failed to wait on hqd deactivate\n");
			r = -ETIMEDOUT;
		}
		soc21_grbm_select(adev, 0, 0, 0, 0);
		mutex_unlock(&adev->srbm_mutex);
	} else if (queue_type == AMDGPU_RING_TYPE_SDMA) {
		dev_info(adev->dev, "reset sdma queue (%d:%d:%d)\n",
			 me_id, pipe_id, queue_id);
		switch (me_id) {
		case 1:
			reg = SOC15_REG_OFFSET(GC, 0, regSDMA1_QUEUE_RESET_REQ);
			break;

Annotation

Implementation Notes