Commit f3f48d6c authored by Chuntao Tso's avatar Chuntao Tso Committed by Alex Deucher
Browse files

drm/amd/display: To support Replay frame skip mode



[Why & How]
The change is to optimize the Replay power saving by
reducing the refresh rate with frame skipping mode

Reviewed-by: default avatarRobin Chen <robin.chen@amd.com>
Signed-off-by: default avatarChuntao Tso <chunttso@amd.com>
Signed-off-by: default avatarFangzhi Zuo <jerry.zuo@amd.com>
Tested-by: default avatarDan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 45de10d2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ bool amdgpu_dm_replay_enable(struct dc_stream_state *stream, bool wait)

	if (link) {
		link->dc->link_srv->edp_setup_replay(link, stream);
		link->dc->link_srv->edp_set_coasting_vtotal(link, stream->timing.v_total);
		link->dc->link_srv->edp_set_coasting_vtotal(link, stream->timing.v_total, 0);
		DRM_DEBUG_DRIVER("Enabling replay...\n");
		link->dc->link_srv->edp_set_replay_allow_active(link, &replay_active, wait, false, NULL);
		return true;
+6 −0
Original line number Diff line number Diff line
@@ -1184,6 +1184,10 @@ struct replay_settings {
	uint32_t coasting_vtotal_table[PR_COASTING_TYPE_NUM];
	/* Defer Update Coasting vtotal table */
	uint32_t defer_update_coasting_vtotal_table[PR_COASTING_TYPE_NUM];
	/* Skip frame number table */
	uint32_t frame_skip_number_table[PR_COASTING_TYPE_NUM];
	/* Defer skip frame number table */
	uint32_t defer_frame_skip_number_table[PR_COASTING_TYPE_NUM];
	/* Maximum link off frame count */
	uint32_t link_off_frame_count;
	/* Replay pseudo vtotal for low refresh rate*/
@@ -1192,6 +1196,8 @@ struct replay_settings {
	uint16_t last_pseudo_vtotal;
	/* Replay desync error */
	uint32_t replay_desync_error_fail_count;
	/* The frame skip number dal send to DMUB */
	uint16_t frame_skip_number;
};

/* To split out "global" and "per-panel" config settings.
+5 −2
Original line number Diff line number Diff line
@@ -213,7 +213,8 @@ static bool dmub_replay_copy_settings(struct dmub_replay *dmub,
 */
static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub,
		uint32_t coasting_vtotal,
		uint8_t panel_inst)
		uint8_t panel_inst,
		uint16_t frame_skip_number)
{
	union dmub_rb_cmd cmd;
	struct dc_context *dc = dmub->ctx;
@@ -227,6 +228,7 @@ static void dmub_replay_set_coasting_vtotal(struct dmub_replay *dmub,
	pCmd->header.payload_bytes = sizeof(struct dmub_cmd_replay_set_coasting_vtotal_data);
	pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF);
	pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16;
	pCmd->replay_set_coasting_vtotal_data.frame_skip_number = frame_skip_number;

	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
@@ -283,7 +285,7 @@ static void dmub_replay_residency(struct dmub_replay *dmub, uint8_t panel_inst,
 * Set REPLAY power optimization flags and coasting vtotal.
 */
static void dmub_replay_set_power_opt_and_coasting_vtotal(struct dmub_replay *dmub,
		unsigned int power_opt, uint8_t panel_inst, uint32_t coasting_vtotal)
		unsigned int power_opt, uint8_t panel_inst, uint32_t coasting_vtotal, uint16_t frame_skip_number)
{
	union dmub_rb_cmd cmd;
	struct dc_context *dc = dmub->ctx;
@@ -301,6 +303,7 @@ static void dmub_replay_set_power_opt_and_coasting_vtotal(struct dmub_replay *dm
	pCmd->replay_set_power_opt_data.panel_inst = panel_inst;
	pCmd->replay_set_coasting_vtotal_data.coasting_vtotal = (coasting_vtotal & 0xFFFF);
	pCmd->replay_set_coasting_vtotal_data.coasting_vtotal_high = (coasting_vtotal & 0xFFFF0000) >> 16;
	pCmd->replay_set_coasting_vtotal_data.frame_skip_number = frame_skip_number;

	dc_wake_and_execute_dmub_cmd(dc, &cmd, DM_DMUB_WAIT_TYPE_WAIT);
}
+3 −2
Original line number Diff line number Diff line
@@ -27,11 +27,12 @@ struct dmub_replay_funcs {
	void (*replay_send_cmd)(struct dmub_replay *dmub,
		enum replay_FW_Message_type msg, union dmub_replay_cmd_set *cmd_element);
	void (*replay_set_coasting_vtotal)(struct dmub_replay *dmub, uint32_t coasting_vtotal,
		uint8_t panel_inst);
		uint8_t panel_inst, uint16_t frame_skip_number);
	void (*replay_residency)(struct dmub_replay *dmub,
		uint8_t panel_inst, uint32_t *residency, const bool is_start, const enum pr_residency_mode mode);
	void (*replay_set_power_opt_and_coasting_vtotal)(struct dmub_replay *dmub,
		unsigned int power_opt, uint8_t panel_inst, uint32_t coasting_vtotal);
		unsigned int power_opt, uint8_t panel_inst, uint32_t coasting_vtotal,
		uint16_t frame_skip_number);
};

struct dmub_replay *dmub_replay_create(struct dc_context *ctx);
+2 −2
Original line number Diff line number Diff line
@@ -292,12 +292,12 @@ struct link_service {
			enum replay_FW_Message_type msg,
			union dmub_replay_cmd_set *cmd_data);
	bool (*edp_set_coasting_vtotal)(
			struct dc_link *link, uint32_t coasting_vtotal);
			struct dc_link *link, uint32_t coasting_vtotal, uint16_t frame_skip_number);
	bool (*edp_replay_residency)(const struct dc_link *link,
			unsigned int *residency, const bool is_start,
			const enum pr_residency_mode mode);
	bool (*edp_set_replay_power_opt_and_coasting_vtotal)(struct dc_link *link,
			const unsigned int *power_opts, uint32_t coasting_vtotal);
			const unsigned int *power_opts, uint32_t coasting_vtotal, uint16_t frame_skip_number);

	bool (*edp_wait_for_t12)(struct dc_link *link);
	bool (*edp_is_ilr_optimization_required)(struct dc_link *link,
Loading