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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
Extension
.c
Size
53989 bytes
Lines
1761
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 (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;
		case 0:
		default:
			reg = SOC15_REG_OFFSET(GC, 0, regSDMA0_QUEUE_RESET_REQ);
			break;
		}

		value = 1 << queue_id;
		WREG32(reg, value);
		/* wait for queue reset done */
		for (i = 0; i < adev->usec_timeout; i++) {
			if (!(RREG32(reg) & value))
				break;
			udelay(1);
		}
		if (i >= adev->usec_timeout) {
			dev_err(adev->dev, "failed to wait on sdma queue reset done\n");
			r = -ETIMEDOUT;
		}
	}

	amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
	return r;
}

static int mes_v11_0_map_legacy_queue(struct amdgpu_mes *mes,
				      struct mes_map_legacy_queue_input *input)
{
	union MESAPI__ADD_QUEUE mes_add_queue_pkt;

	memset(&mes_add_queue_pkt, 0, sizeof(mes_add_queue_pkt));

	mes_add_queue_pkt.header.type = MES_API_TYPE_SCHEDULER;
	mes_add_queue_pkt.header.opcode = MES_SCH_API_ADD_QUEUE;
	mes_add_queue_pkt.header.dwsize = API_FRAME_SIZE_IN_DWORDS;

	mes_add_queue_pkt.pipe_id = input->pipe_id;
	mes_add_queue_pkt.queue_id = input->queue_id;
	mes_add_queue_pkt.doorbell_offset = input->doorbell_offset;
	mes_add_queue_pkt.mqd_addr = input->mqd_addr;
	mes_add_queue_pkt.wptr_addr = input->wptr_addr;
	mes_add_queue_pkt.queue_type =
		convert_to_mes_queue_type(input->queue_type);
	mes_add_queue_pkt.map_legacy_kq = 1;

	return mes_v11_0_submit_pkt_and_poll_completion(mes,
			&mes_add_queue_pkt, sizeof(mes_add_queue_pkt),
			offsetof(union MESAPI__ADD_QUEUE, api_status));
}

static int mes_v11_0_unmap_legacy_queue(struct amdgpu_mes *mes,
			struct mes_unmap_legacy_queue_input *input)
{
	union MESAPI__REMOVE_QUEUE mes_remove_queue_pkt;

	memset(&mes_remove_queue_pkt, 0, sizeof(mes_remove_queue_pkt));

Annotation

Implementation Notes