Commit fc9f4745 authored by Alvin Lee's avatar Alvin Lee Committed by Alex Deucher
Browse files

drm/amd/display: For FPO and SubVP/DRR configs program vmin/max sel



[Why & How]
For FPO and SubVP/DRR cases we need to ensure to program
OTG_V_TOTAL_MIN/MAX_SEL, otherwise stretching the vblank
in FPO / SubVP / DRR cases will not have any effect
and we could hit underflow / corruption.

Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Acked-by: default avatarTom Chung <chiahsuan.chung@amd.com>
Signed-off-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent dcbf438d
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -3481,6 +3481,33 @@ static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state
	}
}

static void update_drr_for_full_update(struct dc *dc, struct dc_state *context)
{
	uint32_t i;

	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
		struct dc_stream_state *stream = pipe->stream;
		struct timing_generator *tg = pipe->stream_res.tg;
		struct drr_params params = {0};

		/* pipe not in use */
		if (!resource_is_pipe_type(pipe, OTG_MASTER))
			continue;

		/* skip phantom pipes */
		if (dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
			continue;

		params.vertical_total_min = stream->adjust.v_total_min;
		params.vertical_total_max = stream->adjust.v_total_max;
		params.vertical_total_mid = stream->adjust.v_total_mid;
		params.vertical_total_mid_frame_num = stream->adjust.v_total_mid_frame_num;
		if (pipe->stream_res.tg->funcs->set_drr)
			tg->funcs->set_drr(pipe->stream_res.tg, &params);
	}
}

static void commit_planes_for_stream(struct dc *dc,
		struct dc_surface_update *srf_updates,
		int surface_count,
@@ -3848,6 +3875,10 @@ static void commit_planes_for_stream(struct dc *dc,
			pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
	}

	// Update DRR for all pipes
	if (update_type != UPDATE_TYPE_FAST)
		update_drr_for_full_update(dc, context);

	current_stream_mask = get_stream_mask(dc, context);
	if (current_stream_mask != context->stream_mask) {
		context->stream_mask = current_stream_mask;
+14 −0
Original line number Diff line number Diff line
@@ -4990,6 +4990,20 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
	return DC_OK;
}

bool resource_subvp_in_use(struct dc *dc,
		struct dc_state *context)
{
	uint32_t i;

	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];

		if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
			return true;
	}
	return false;
}

bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream)
{
	if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))
+0 −14
Original line number Diff line number Diff line
@@ -183,20 +183,6 @@ bool dcn32_all_pipes_have_stream_and_plane(struct dc *dc,
	return true;
}

bool dcn32_subvp_in_use(struct dc *dc,
		struct dc_state *context)
{
	uint32_t i;

	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];

		if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
			return true;
	}
	return false;
}

bool dcn32_mpo_in_use(struct dc_state *context)
{
	uint32_t i;
+6 −5
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#include "dcn30/dcn30_resource.h"
#include "link.h"
#include "dc_state_priv.h"
#include "resource.h"

#define DC_LOGGER_INIT(logger)

@@ -291,7 +292,7 @@ int dcn32_find_dummy_latency_index_for_fw_based_mclk_switch(struct dc *dc,

		/* for subvp + DRR case, if subvp pipes are still present we support pstate */
		if (vba->DRAMClockChangeSupport[vlevel][vba->maxMpcComb] == dm_dram_clock_change_unsupported &&
				dcn32_subvp_in_use(dc, context))
				resource_subvp_in_use(dc, context))
			vba->DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] = temp_clock_change_support;

		if (vlevel < context->bw_ctx.dml.vba.soc.num_states &&
@@ -2272,7 +2273,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
	unsigned int dummy_latency_index = 0;
	int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;
	unsigned int min_dram_speed_mts = context->bw_ctx.dml.vba.DRAMSpeed;
	bool subvp_in_use = dcn32_subvp_in_use(dc, context);
	bool subvp_active = resource_subvp_in_use(dc, context);
	unsigned int min_dram_speed_mts_margin;
	bool need_fclk_lat_as_dummy = false;
	bool is_subvp_p_drr = false;
@@ -2281,7 +2282,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
	dc_assert_fp_enabled();

	/* need to find dummy latency index for subvp */
	if (subvp_in_use) {
	if (subvp_active) {
		/* Override DRAMClockChangeSupport for SubVP + DRR case where the DRR cannot switch without stretching it's VBLANK */
		if (!pstate_en) {
			context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] = dm_dram_clock_change_vblank_w_mall_sub_vp;
@@ -2467,7 +2468,7 @@ void dcn32_calculate_wm_and_dlg_fpu(struct dc *dc, struct dc_state *context,
				dc->clk_mgr->bw_params->clk_table.entries[min_dram_speed_mts_offset].memclk_mhz * 16;
		}

		if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_in_use) {
		if (!context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching && !subvp_active) {
			/* find largest table entry that is lower than dram speed,
			 * but lower than DPM0 still uses DPM0
			 */
@@ -3527,7 +3528,7 @@ void dcn32_set_clock_limits(const struct _vcs_dpi_soc_bounding_box_st *soc_bb)
void dcn32_override_min_req_memclk(struct dc *dc, struct dc_state *context)
{
	// WA: restrict FPO and SubVP to use first non-strobe mode (DCN32 BW issue)
	if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || dcn32_subvp_in_use(dc, context)) &&
	if ((context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching || resource_subvp_in_use(dc, context)) &&
			dc->dml.soc.num_chans <= 8) {
		int num_mclk_levels = dc->clk_mgr->bw_params->clk_table.num_entries_per_clk.num_memclk_levels;

+0 −1
Original line number Diff line number Diff line
@@ -2064,7 +2064,6 @@ void dcn20_program_front_end_for_ctx(
				&& context->res_ctx.pipe_ctx[i].stream)
			hws->funcs.blank_pixel_data(dc, &context->res_ctx.pipe_ctx[i], true);


	/* Disconnect mpcc */
	for (i = 0; i < dc->res_pool->pipe_count; i++)
		if (context->res_ctx.pipe_ctx[i].update_flags.bits.disable
Loading