Commit 253a5591 authored by Guo, Bing's avatar Guo, Bing Committed by Alex Deucher
Browse files

drm/amd/display: Fix issue with dynamic bpp change for DCN3x



Why:
Screen sometimes would have artifacts or blink once at the time when bpp
is dynamically changed.

How:
1. Changed to update PPS infopacket in frame mode instead of immediate mode
   since other updates for bpp change are double-buffered.
2. Changed double-buffering enablement programming for DCN30 as advised by
ASIC team

Reviewed-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarBing Guo <Bing.Guo@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 808643ea
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3554,7 +3554,7 @@ static void fpga_dp_hpo_enable_link_and_stream(struct dc_state *state, struct pi

	/* Set DPS PPS SDP (AKA "info frames") */
	if (pipe_ctx->stream->timing.flags.DSC) {
		dp_set_dsc_pps_sdp(pipe_ctx, true);
		dp_set_dsc_pps_sdp(pipe_ctx, true, true);
	}

	/* Allocate Payload */
@@ -3803,7 +3803,7 @@ void core_link_enable_stream(
			if (dc_is_dp_signal(pipe_ctx->stream->signal) ||
					dc_is_virtual_signal(pipe_ctx->stream->signal)) {
				dp_set_dsc_on_rx(pipe_ctx, true);
				dp_set_dsc_pps_sdp(pipe_ctx, true);
				dp_set_dsc_pps_sdp(pipe_ctx, true, true);
			}
		}

+21 −8
Original line number Diff line number Diff line
@@ -607,7 +607,8 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
										pipe_ctx->stream_res.hpo_dp_stream_enc,
										false,
										NULL);
										NULL,
										true);
			else
#endif
				if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
@@ -615,7 +616,7 @@ void dp_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
							pipe_ctx->stream_res.stream_enc,
							OPTC_DSC_DISABLED, 0, 0);
					pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
								pipe_ctx->stream_res.stream_enc, false, NULL);
								pipe_ctx->stream_res.stream_enc, false, NULL, true);
				}
		}

@@ -650,7 +651,16 @@ bool dp_set_dsc_enable(struct pipe_ctx *pipe_ctx, bool enable)
	return result;
}

bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
/*
 * For dynamic bpp change case, dsc is programmed with MASTER_UPDATE_LOCK enabled;
 * hence PPS info packet update need to use frame update instead of immediate update.
 * Added parameter immediate_update for this purpose.
 * The decision to use frame update is hard-coded in function dp_update_dsc_config(),
 * which is the only place where a "false" would be passed in for param immediate_update.
 *
 * immediate_update is only applicable when DSC is enabled.
 */
bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable, bool immediate_update)
{
	struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc;
	struct dc_stream_state *stream = pipe_ctx->stream;
@@ -682,13 +692,15 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
										pipe_ctx->stream_res.hpo_dp_stream_enc,
										true,
										&dsc_packed_pps[0]);
										&dsc_packed_pps[0],
										immediate_update);
			else
#endif
				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
										pipe_ctx->stream_res.stream_enc,
										true,
										&dsc_packed_pps[0]);
										&dsc_packed_pps[0],
										immediate_update);
		}
	} else {
		/* disable DSC PPS in stream encoder */
@@ -698,11 +710,12 @@ bool dp_set_dsc_pps_sdp(struct pipe_ctx *pipe_ctx, bool enable)
				pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->dp_set_dsc_pps_info_packet(
										pipe_ctx->stream_res.hpo_dp_stream_enc,
										false,
										NULL);
										NULL,
										true);
			else
#endif
				pipe_ctx->stream_res.stream_enc->funcs->dp_set_dsc_pps_info_packet(
							pipe_ctx->stream_res.stream_enc, false, NULL);
							pipe_ctx->stream_res.stream_enc, false, NULL, true);
		}
	}

@@ -720,7 +733,7 @@ bool dp_update_dsc_config(struct pipe_ctx *pipe_ctx)
		return false;

	dp_set_dsc_on_stream(pipe_ctx, true);
	dp_set_dsc_pps_sdp(pipe_ctx, true);
	dp_set_dsc_pps_sdp(pipe_ctx, true, false);
	return true;
}

+2 −1
Original line number Diff line number Diff line
@@ -292,7 +292,8 @@ static void enc2_dp_set_dsc_config(struct stream_encoder *enc,

static void enc2_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
					bool enable,
					uint8_t *dsc_packed_pps)
					uint8_t *dsc_packed_pps,
					bool immediate_update)
{
	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);

+12 −6
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ static void enc3_update_hdmi_info_packet(
		enc1->base.vpg->funcs->update_generic_info_packet(
				enc1->base.vpg,
				packet_index,
				info_packet);
				info_packet,
				true);

		/* enable transmission of packet(s) -
		 * packet transmission begins on the next frame */
@@ -335,7 +336,8 @@ static void enc3_dp_set_dsc_config(struct stream_encoder *enc,

static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
					bool enable,
					uint8_t *dsc_packed_pps)
					uint8_t *dsc_packed_pps,
					bool immediate_update)
{
	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc);

@@ -365,7 +367,8 @@ static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,
			enc1->base.vpg->funcs->update_generic_info_packet(
							enc1->base.vpg,
							11 + i,
							&pps_sdp);
							&pps_sdp,
							immediate_update);
		}

		/* SW should make sure VBID[6] update line number is bigger
@@ -429,19 +432,22 @@ static void enc3_stream_encoder_update_dp_info_packets(
		enc->vpg->funcs->update_generic_info_packet(
				enc->vpg,
				0,  /* packetIndex */
				&info_frame->vsc);
				&info_frame->vsc,
				true);
	}
	if (info_frame->spd.valid) {
		enc->vpg->funcs->update_generic_info_packet(
				enc->vpg,
				2,  /* packetIndex */
				&info_frame->spd);
				&info_frame->spd,
				true);
	}
	if (info_frame->hdrsmd.valid) {
		enc->vpg->funcs->update_generic_info_packet(
				enc->vpg,
				3,  /* packetIndex */
				&info_frame->hdrsmd);
				&info_frame->hdrsmd,
				true);
	}
	/* packetIndex 4 is used for send immediate sdp message, and please
	 * use other packetIndex (such as 5,6) for other info packet
+12 −5
Original line number Diff line number Diff line
@@ -73,16 +73,23 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc)
		OTG_H_BLANK_END, &h_blank_end);

	REG_UPDATE_2(OTG_GLOBAL_CONTROL1,
		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start,
		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_end);
		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start - 1,
		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_start);
	REG_UPDATE_2(OTG_GLOBAL_CONTROL4,
		DIG_UPDATE_POSITION_X, 20,
		DIG_UPDATE_POSITION_Y, v_blank_start);
		DIG_UPDATE_POSITION_X, h_blank_start - 180 - 1,
		DIG_UPDATE_POSITION_Y, v_blank_start - 1);
	// there is a DIG_UPDATE_VCOUNT_MODE and it is 0.

	REG_UPDATE_3(OTG_GLOBAL_CONTROL0,
		MASTER_UPDATE_LOCK_DB_START_X, h_blank_start - 200 - 1,
		MASTER_UPDATE_LOCK_DB_END_X, h_blank_end,
		MASTER_UPDATE_LOCK_DB_END_X, h_blank_start - 180,
		MASTER_UPDATE_LOCK_DB_EN, 1);
	REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1);

	REG_SET_3(OTG_VUPDATE_KEEPOUT, 0,
		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0,
		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100,
		OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1);
}

void optc3_lock_doublebuffer_disable(struct timing_generator *optc)
Loading