Commit e5fc7825 authored by Gabe Teeger's avatar Gabe Teeger Committed by Alex Deucher
Browse files

drm/amd/display: Add support for zstate during extended vblank



[why]
When we enter FREESYNC_STATE_VIDEO, we want to use the extra vblank
portion to enter zstate if possible.

[how]
When we enter freesync, a full update is triggered and the new vtotal
with extra lines is passed to dml in a stream update. The time gained
from extra vblank lines is calculated in microseconds. We allow zstate
entry if the time gained is greater than 5 ms, which is the current
policy. Furthermore, an optimized value for min_dst_y_next_start is
calculated and written to its register. When exiting freesync, another
full update is triggered and default values are restored.

Reviewed-by: default avatarNicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarGabe Teeger <gabe.teeger@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 02fc996d
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2393,6 +2393,8 @@ static enum surface_update_type check_update_surfaces_for_stream(

		if (stream_update->mst_bw_update)
			su_flags->bits.mst_bw = 1;
		if (stream_update->crtc_timing_adjust && dc_extended_blank_supported(dc))
			su_flags->bits.crtc_timing_adjust = 1;

		if (su_flags->raw != 0)
			overall_type = UPDATE_TYPE_FULL;
@@ -2654,6 +2656,9 @@ static void copy_stream_update_to_stream(struct dc *dc,
	if (update->vrr_infopacket)
		stream->vrr_infopacket = *update->vrr_infopacket;

	if (update->crtc_timing_adjust)
		stream->adjust = *update->crtc_timing_adjust;

	if (update->dpms_off)
		stream->dpms_off = *update->dpms_off;

@@ -4055,3 +4060,17 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
	if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause)
		pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst);
}
/*
 * dc_extended_blank_supported: Decide whether extended blank is supported
 *
 * Extended blank is a freesync optimization feature to be enabled in the future.
 * During the extra vblank period gained from freesync, we have the ability to enter z9/z10.
 *
 * @param [in] dc: Current DC state
 * @return: Indicate whether extended blank is supported (true or false)
 */
bool dc_extended_blank_supported(struct dc *dc)
{
	return dc->debug.extended_blank_optimization && !dc->debug.disable_z10
		&& dc->caps.zstate_support && dc->caps.is_apu;
}
+5 −1
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ struct dc_caps {
	bool psp_setup_panel_mode;
	bool extended_aux_timeout_support;
	bool dmcub_support;
	bool zstate_support;
	uint32_t num_of_internal_disp;
	enum dp_protocol_version max_dp_protocol_version;
	unsigned int mall_size_per_mem_channel;
@@ -703,13 +704,14 @@ struct dc_debug_options {
	bool enable_driver_sequence_debug;
	enum det_size crb_alloc_policy;
	int crb_alloc_policy_min_disp_count;
#if defined(CONFIG_DRM_AMD_DC_DCN)
	bool disable_z10;
#if defined(CONFIG_DRM_AMD_DC_DCN)
	bool enable_z9_disable_interface;
	bool enable_sw_cntl_psr;
	union dpia_debug_options dpia_debug;
#endif
	bool apply_vendor_specific_lttpr_wa;
	bool extended_blank_optimization;
	bool ignore_dpref_ss;
	uint8_t psr_power_use_phy_fsm;
};
@@ -1369,6 +1371,8 @@ struct dc_sink_init_data {
	bool converter_disable_audio;
};

bool dc_extended_blank_supported(struct dc *dc);

struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);

/* Newer interfaces  */
+2 −0
Original line number Diff line number Diff line
@@ -131,6 +131,7 @@ union stream_update_flags {
		uint32_t wb_update:1;
		uint32_t dsc_changed : 1;
		uint32_t mst_bw : 1;
		uint32_t crtc_timing_adjust : 1;
	} bits;

	uint32_t raw;
@@ -289,6 +290,7 @@ struct dc_stream_update {
	struct dc_3dlut *lut3d_func;

	struct test_pattern *pending_test_pattern;
	struct dc_crtc_timing_adjust *crtc_timing_adjust;
};

bool dc_is_stream_unchanged(
+12 −0
Original line number Diff line number Diff line
@@ -1857,6 +1857,7 @@ void dcn20_optimize_bandwidth(
		struct dc_state *context)
{
	struct hubbub *hubbub = dc->res_pool->hubbub;
	int i;

	/* program dchubbub watermarks */
	hubbub->funcs->program_watermarks(hubbub,
@@ -1873,6 +1874,17 @@ void dcn20_optimize_bandwidth(
			dc->clk_mgr,
			context,
			true);
	if (dc_extended_blank_supported(dc) && context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {
		for (i = 0; i < dc->res_pool->pipe_count; ++i) {
			struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];

			if (pipe_ctx->stream && pipe_ctx->plane_res.hubp->funcs->program_extended_blank
				&& pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
				&& pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
					pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,
						pipe_ctx->dlg_regs.optimized_min_dst_y_next_start);
		}
	}
	/* increase compbuf size */
	if (hubbub->funcs->program_compbuf_size)
		hubbub->funcs->program_compbuf_size(hubbub, context->bw_ctx.bw.dcn.compbuf_size_kb, true);
+8 −0
Original line number Diff line number Diff line
@@ -54,6 +54,13 @@ void hubp31_soft_reset(struct hubp *hubp, bool reset)
	REG_UPDATE(DCHUBP_CNTL, HUBP_SOFT_RESET, reset);
}

void hubp31_program_extended_blank(struct hubp *hubp, unsigned int min_dst_y_next_start_optimized)
{
	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp);

	REG_SET(BLANK_OFFSET_1, 0, MIN_DST_Y_NEXT_START, min_dst_y_next_start_optimized);
}

static struct hubp_funcs dcn31_hubp_funcs = {
	.hubp_enable_tripleBuffer = hubp2_enable_triplebuffer,
	.hubp_is_triplebuffer_enabled = hubp2_is_triplebuffer_enabled,
@@ -80,6 +87,7 @@ static struct hubp_funcs dcn31_hubp_funcs = {
	.set_unbounded_requesting = hubp31_set_unbounded_requesting,
	.hubp_soft_reset = hubp31_soft_reset,
	.hubp_in_blank = hubp1_in_blank,
	.program_extended_blank = hubp31_program_extended_blank,
};

bool hubp31_construct(
Loading