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

drm/amd/display: Wait for all pending cleared before full update



[Description]
Before every full update we must wait for all pending updates to be
cleared - this is particularly important for minimal transitions
because if we don't wait for pending cleared, it will be as if
there was no minimal transition at all. In OTG we must read 3 different
status registers for pending cleared, one specifically for OTG updates,
one specifically for OPTC updates, and the last for surface related
updates

Reviewed-by: default avatarDillon Varone <dillon.varone@amd.com>
Signed-off-by: default avatarAlvin Lee <Alvin.Lee2@amd.com>
Signed-off-by: default avatarZaeem Mohamed <zaeem.mohamed@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 5d666496
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -1071,8 +1071,13 @@ void hwss_wait_for_outstanding_hw_updates(struct dc *dc, struct dc_state *dc_con
		if (!pipe_ctx->stream)
			continue;

		if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear)
			pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg);
		/* For full update we must wait for all double buffer updates, not just DRR updates. This
		 * is particularly important for minimal transitions. Only check for OTG_MASTER pipes,
		 * as non-OTG Master pipes share the same OTG as
		 */
		if (resource_is_pipe_type(pipe_ctx, OTG_MASTER) && dc->hwss.wait_for_all_pending_updates) {
			dc->hwss.wait_for_all_pending_updates(pipe_ctx);
		}

		hubp = pipe_ctx->plane_res.hubp;
		if (!hubp)
+2 −2
Original line number Diff line number Diff line
@@ -2255,9 +2255,9 @@ void dcn20_post_unlock_program_front_end(
			struct timing_generator *tg = pipe->stream_res.tg;


			if (tg->funcs->get_double_buffer_pending) {
			if (tg->funcs->get_optc_double_buffer_pending) {
				for (j = 0; j < TIMEOUT_FOR_PIPE_ENABLE_US / polling_interval_us
				&& tg->funcs->get_double_buffer_pending(tg); j++)
				&& tg->funcs->get_optc_double_buffer_pending(tg); j++)
					udelay(polling_interval_us);
			}
		}
+27 −0
Original line number Diff line number Diff line
@@ -1185,3 +1185,30 @@ void dcn30_prepare_bandwidth(struct dc *dc,
	if (!dc->clk_mgr->clks.fw_based_mclk_switching)
		dc_dmub_srv_p_state_delegate(dc, false, context);
}

void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx)
{
	struct timing_generator *tg = pipe_ctx->stream_res.tg;
	bool pending_updates = false;
	unsigned int i;

	if (tg && tg->funcs->is_tg_enabled(tg)) {
		// Poll for 100ms maximum
		for (i = 0; i < 100000; i++) {
			pending_updates = false;
			if (tg->funcs->get_optc_double_buffer_pending)
				pending_updates |= tg->funcs->get_optc_double_buffer_pending(tg);

			if (tg->funcs->get_otg_double_buffer_pending)
				pending_updates |= tg->funcs->get_otg_double_buffer_pending(tg);

			if (tg->funcs->get_pipe_update_pending)
				pending_updates |= tg->funcs->get_pipe_update_pending(tg);

			if (!pending_updates)
				break;

			udelay(1);
		}
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -96,4 +96,6 @@ void dcn30_set_hubp_blank(const struct dc *dc,
void dcn30_prepare_bandwidth(struct dc *dc,
	struct dc_state *context);

void dcn30_wait_for_all_pending_updates(const struct pipe_ctx *pipe_ctx);

#endif /* __DC_HWSS_DCN30_H__ */
+2 −1
Original line number Diff line number Diff line
@@ -108,7 +108,8 @@ static const struct hw_sequencer_funcs dcn30_funcs = {
	.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
	.get_dcc_en_bits = dcn10_get_dcc_en_bits,
	.update_visual_confirm_color = dcn10_update_visual_confirm_color,
	.is_abm_supported = dcn21_is_abm_supported
	.is_abm_supported = dcn21_is_abm_supported,
	.wait_for_all_pending_updates = dcn30_wait_for_all_pending_updates,
};

static const struct hwseq_private_funcs dcn30_private_funcs = {
Loading