drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c
Extension
.c
Size
17203 bytes
Lines
511
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 (enable) {
				if (state != PSR_STATE0)
					break;
			} else {
				if (state == PSR_STATE0)
					break;
			}

			/* must *not* be fsleep - this can be called from high irq levels */
			udelay(500);
		}

		/* assert if max retry hit */
		if (retry_count >= 1000)
			ASSERT(0);
	}
}

/*
 * Set PSR level.
 */
static void dmub_psr_set_level(struct dmub_psr *dmub, uint16_t psr_level, uint8_t panel_inst)
{
	union dmub_rb_cmd cmd;
	enum dc_psr_state state = PSR_STATE0;
	struct dc_context *dc = dmub->ctx;

	dmub_psr_get_state(dmub, &state, panel_inst);

	if (state == PSR_STATE0)
		return;

	memset(&cmd, 0, sizeof(cmd));
	cmd.psr_set_level.header.type = DMUB_CMD__PSR;
	cmd.psr_set_level.header.sub_type = DMUB_CMD__PSR_SET_LEVEL;
	cmd.psr_set_level.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_level_data);
	cmd.psr_set_level.psr_set_level_data.psr_level = psr_level;
	cmd.psr_set_level.psr_set_level_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
	cmd.psr_set_level.psr_set_level_data.panel_inst = panel_inst;
	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}

/*
 * Set PSR vtotal requirement for FreeSync PSR.
 */
static void dmub_psr_set_sink_vtotal_in_psr_active(struct dmub_psr *dmub,
		uint16_t psr_vtotal_idle, uint16_t psr_vtotal_su)
{
	union dmub_rb_cmd cmd;
	struct dc_context *dc = dmub->ctx;

	memset(&cmd, 0, sizeof(cmd));
	cmd.psr_set_vtotal.header.type = DMUB_CMD__PSR;
	cmd.psr_set_vtotal.header.sub_type = DMUB_CMD__SET_SINK_VTOTAL_IN_PSR_ACTIVE;
	cmd.psr_set_vtotal.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_vtotal_data);
	cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_idle = psr_vtotal_idle;
	cmd.psr_set_vtotal.psr_set_vtotal_data.psr_vtotal_su = psr_vtotal_su;

	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}

/*
 * Set PSR power optimization flags.
 */
static void dmub_psr_set_power_opt(struct dmub_psr *dmub, unsigned int power_opt, uint8_t panel_inst)
{
	union dmub_rb_cmd cmd;
	struct dc_context *dc = dmub->ctx;

	memset(&cmd, 0, sizeof(cmd));
	cmd.psr_set_power_opt.header.type = DMUB_CMD__PSR;
	cmd.psr_set_power_opt.header.sub_type = DMUB_CMD__SET_PSR_POWER_OPT;
	cmd.psr_set_power_opt.header.payload_bytes = sizeof(struct dmub_cmd_psr_set_power_opt_data);
	cmd.psr_set_power_opt.psr_set_power_opt_data.cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1;
	cmd.psr_set_power_opt.psr_set_power_opt_data.power_opt = power_opt;
	cmd.psr_set_power_opt.psr_set_power_opt_data.panel_inst = panel_inst;

	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}

/*
 * Setup PSR by programming phy registers and sending psr hw context values to firmware.
 */
static bool dmub_psr_copy_settings(struct dmub_psr *dmub,
		struct dc_link *link,
		struct psr_context *psr_context,
		uint8_t panel_inst)
{
	union dmub_rb_cmd cmd = { 0 };
	struct dc_context *dc = dmub->ctx;

Annotation

Implementation Notes