Commit ba578afd authored by Chiawen Huang's avatar Chiawen Huang Committed by Alex Deucher
Browse files

drm/amd/display: disable stream if pixel clock changed with link active



[Why]
Vbios uses preferred timing to turn on edp but OS could use other
timing. If change pixel clock when link active, there is unexpected
garbage on monitor.

[How]
Once pixel clock changed, the driver needs to disable stream.

Signed-off-by: default avatarChiawen Huang <chiawen.huang@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 89b151ad
Loading
Loading
Loading
Loading
+59 −3
Original line number Diff line number Diff line
@@ -842,6 +842,61 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
	dc_release_state(current_ctx);
}

static void disable_vbios_mode_if_required(
		struct dc *dc,
		struct dc_state *context)
{
	unsigned int i;

	/* check if timing_changed, disable stream*/
	for (i = 0; i < dc->res_pool->pipe_count; i++) {
		struct dc_stream_state *stream = NULL;
		struct dc_link *link = NULL;
		struct pipe_ctx *pipe = NULL;

		pipe = &context->res_ctx.pipe_ctx[i];
		stream = pipe->stream;
		if (stream == NULL)
			continue;

		if (stream->link->local_sink &&
			stream->link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {
			link = stream->link;
			break;
		}

		if (link != NULL) {
			unsigned int enc_inst, tg_inst = 0;
			unsigned int pix_clk_100hz;

			enc_inst = link->link_enc->funcs->get_dig_frontend(link->link_enc);
			if (enc_inst != ENGINE_ID_UNKNOWN) {
				for (i = 0; i < dc->res_pool->stream_enc_count; i++) {
					if (dc->res_pool->stream_enc[i]->id == enc_inst) {
						tg_inst = dc->res_pool->stream_enc[i]->funcs->dig_source_otg(
							dc->res_pool->stream_enc[i]);
						break;
					}
				}

				dc->res_pool->dp_clock_source->funcs->get_pixel_clk_frequency_100hz(
					dc->res_pool->dp_clock_source,
					tg_inst, &pix_clk_100hz);

				if (link->link_status.link_active) {
					uint32_t requested_pix_clk_100hz =
						pipe->stream_res.pix_clk_params.requested_pix_clk_100hz;

					if (pix_clk_100hz != requested_pix_clk_100hz) {
						core_link_disable_stream(pipe);
						pipe->stream->dpms_off = false;
					}
				}
			}
		}
	}
}

static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
{
	int i;
@@ -1278,13 +1333,14 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
	for (i = 0; i < context->stream_count; i++)
		dc_streams[i] =  context->streams[i];

	if (!dcb->funcs->is_accelerated_mode(dcb))
	if (!dcb->funcs->is_accelerated_mode(dcb)) {
		disable_vbios_mode_if_required(dc, context);
		dc->hwss.enable_accelerated_mode(dc, context);
	}

	for (i = 0; i < context->stream_count; i++) {
	for (i = 0; i < context->stream_count; i++)
		if (context->streams[i]->apply_seamless_boot_optimization)
			dc->optimize_seamless_boot_streams++;
	}

	if (context->stream_count > dc->optimize_seamless_boot_streams ||
		context->stream_count == 0)
+1 −1
Original line number Diff line number Diff line
@@ -1654,7 +1654,7 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
		// enable fastboot if backend is enabled on eDP
		if (edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc)) {
			/* Set optimization flag on eDP stream*/
			if (edp_stream) {
			if (edp_stream && edp_link->link_status.link_active) {
				edp_stream->apply_edp_fast_boot_optimization = true;
				can_apply_edp_fast_boot = true;
			}