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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/mxgpu_nv.c
Extension
.c
Size
17251 bytes
Lines
616
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_dbg(adev->dev, "rcv_msg 0x%x after %llu ms\n",
					event, NV_MAILBOX_POLL_MSG_TIMEDOUT - timeout + now);
			return 0;
		} else if (r == -ENODEV) {
			if (!amdgpu_ras_is_rma(adev)) {
				ras->is_rma = true;
				dev_err(adev->dev, "VF is in an unrecoverable state. "
						"Runtime Services are halted.\n");
			}
			return r;
		}

		msleep(10);
		now = (uint64_t)ktime_to_ms(ktime_get());
	} while (timeout > now);

	dev_dbg(adev->dev, "nv_poll_msg timed out\n");

	return -ETIME;
}

static void xgpu_nv_mailbox_trans_msg (struct amdgpu_device *adev,
	      enum idh_request req, u32 data1, u32 data2, u32 data3)
{
	int r;
	uint8_t trn;

	/* IMPORTANT:
	 * clear TRN_MSG_VALID valid to clear host's RCV_MSG_ACK
	 * and with host's RCV_MSG_ACK cleared hw automatically clear host's RCV_MSG_ACK
	 * which lead to VF's TRN_MSG_ACK cleared, otherwise below xgpu_nv_poll_ack()
	 * will return immediatly
	 */
	do {
		xgpu_nv_mailbox_set_valid(adev, false);
		trn = xgpu_nv_peek_ack(adev);
		if (trn) {
			dev_err_ratelimited(adev->dev, "trn=%x ACK should not assert! wait again !\n", trn);
			msleep(1);
		}
	} while (trn);

	dev_dbg(adev->dev, "trans_msg req = 0x%x, data1 = 0x%x\n", req, data1);
	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW0, req);
	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW1, data1);
	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW2, data2);
	WREG32_NO_KIQ(mmMAILBOX_MSGBUF_TRN_DW3, data3);
	xgpu_nv_mailbox_set_valid(adev, true);

	/* start to poll ack */
	r = xgpu_nv_poll_ack(adev);
	if (r)
		dev_err(adev->dev, "Doesn't get ack from pf, continue\n");

	xgpu_nv_mailbox_set_valid(adev, false);
}

static int xgpu_nv_send_access_requests_with_param(struct amdgpu_device *adev,
			enum idh_request req, u32 data1, u32 data2, u32 data3)
{
	struct amdgpu_virt *virt = &adev->virt;
	int r = 0, retry = 1;
	enum idh_event event = -1;

	mutex_lock(&virt->access_req_mutex);
send_request:

	if (amdgpu_ras_is_rma(adev)) {
		r = -ENODEV;
		goto out;
	}

	xgpu_nv_mailbox_trans_msg(adev, req, data1, data2, data3);

	switch (req) {
	case IDH_REQ_GPU_INIT_ACCESS:
	case IDH_REQ_GPU_FINI_ACCESS:
	case IDH_REQ_GPU_RESET_ACCESS:
		event = IDH_READY_TO_ACCESS_GPU;
		break;
	case IDH_REQ_GPU_INIT_DATA:
		event = IDH_REQ_GPU_INIT_DATA_READY;
		break;
	case IDH_RAS_POISON:
		if (data1 != 0)
			event = IDH_RAS_POISON_READY;
		break;
	case IDH_REQ_RAS_ERROR_COUNT:
		event = IDH_RAS_ERROR_COUNT_READY;

Annotation

Implementation Notes