drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
Extension
.c
Size
89739 bytes
Lines
2431
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 (status != DMUB_STATUS_OK) {
			break;
		}
	}

	if (status != DMUB_STATUS_OK) {
		if (status != DMUB_STATUS_POWER_STATE_D3) {
			DC_ERROR("Error starting DMUB execution: status=%d\n", status);
			dc_dmub_srv_handle_failure(dc_dmub_srv);
		}
		return false;
	}

	return true;
}

static bool dc_dmub_srv_fb_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
		unsigned int count,
		union dmub_rb_cmd *cmd_list)
{
	struct dc_context *dc_ctx;
	struct dmub_srv *dmub;
	enum dmub_status status;
	unsigned int i;

	if (!dc_dmub_srv || !dc_dmub_srv->dmub)
		return false;

	dc_ctx = dc_dmub_srv->ctx;
	dmub = dc_dmub_srv->dmub;

	for (i = 0 ; i < count; i++) {
		// Queue command
		if (!cmd_list[i].cmd_common.header.multi_cmd_pending ||
				dmub_rb_num_free(&dmub->inbox1.rb) >= count - i) {
			status = dmub_srv_fb_cmd_queue(dmub, &cmd_list[i]);
		} else {
			status = DMUB_STATUS_QUEUE_FULL;
		}

		if (status == DMUB_STATUS_QUEUE_FULL) {
			/* Execute and wait for queue to become empty again. */
			status = dmub_srv_fb_cmd_execute(dmub);
			if (status == DMUB_STATUS_POWER_STATE_D3)
				return false;

			do {
					status = dmub_srv_wait_for_inbox_free(dmub, MAX_WAIT_US, count - i);
			} while (dc_dmub_srv->ctx->dc->debug.disable_timeout && status != DMUB_STATUS_OK);

			/* Requeue the command. */
			status = dmub_srv_fb_cmd_queue(dmub, &cmd_list[i]);
		}

		if (status != DMUB_STATUS_OK) {
			if (status != DMUB_STATUS_POWER_STATE_D3) {
				DC_ERROR("Error queueing DMUB command: status=%d\n", status);
				dc_dmub_srv_handle_failure(dc_dmub_srv);
			}
			return false;
		}
	}

	status = dmub_srv_fb_cmd_execute(dmub);
	if (status != DMUB_STATUS_OK) {
		if (status != DMUB_STATUS_POWER_STATE_D3) {
			DC_ERROR("Error starting DMUB execution: status=%d\n", status);
			dc_dmub_srv_handle_failure(dc_dmub_srv);
		}
		return false;
	}

	return true;
}

bool dc_dmub_srv_cmd_list_queue_execute(struct dc_dmub_srv *dc_dmub_srv,
		unsigned int count,
		union dmub_rb_cmd *cmd_list)
{
	bool res = false;

	if (dc_dmub_srv && dc_dmub_srv->dmub) {
		if (dc_dmub_srv->dmub->inbox_type == DMUB_CMD_INTERFACE_REG) {
			res = dc_dmub_srv_reg_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list);
		} else {
			res = dc_dmub_srv_fb_cmd_list_queue_execute(dc_dmub_srv, count, cmd_list);
		}

		if (res)
			res = dmub_srv_update_inbox_status(dc_dmub_srv->dmub) == DMUB_STATUS_OK;

Annotation

Implementation Notes