Commit ad4455c6 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher
Browse files

drm/amd/display: Update DPG test pattern programming



[Why]
Last ODM slice could be slightly larger than other slice because it can be
including the residual.

[How]
Update DPG pattern programming sequence to use a different width for
last odm slice.

Reviewed-by: default avatarChris Park <chris.park@amd.com>
Acked-by: default avatarAlex Hung <alex.hung@amd.com>
Signed-off-by: default avatarWenjing Liu <wenjing.liu@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent dbd29029
Loading
Loading
Loading
Loading
+24 −21
Original line number Diff line number Diff line
@@ -1054,9 +1054,9 @@ void dcn20_blank_pixel_data(
	enum controller_dp_color_space test_pattern_color_space = CONTROLLER_DP_COLOR_SPACE_UDEFINED;
	struct pipe_ctx *odm_pipe;
	int odm_cnt = 1;

	int width = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
	int height = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
	int h_active = stream->timing.h_addressable + stream->timing.h_border_left + stream->timing.h_border_right;
	int v_active = stream->timing.v_addressable + stream->timing.v_border_bottom + stream->timing.v_border_top;
	int odm_slice_width, last_odm_slice_width, offset = 0;

	if (stream->link->test_pattern_enabled)
		return;
@@ -1066,8 +1066,8 @@ void dcn20_blank_pixel_data(

	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
		odm_cnt++;

	width = width / odm_cnt;
	odm_slice_width = h_active / odm_cnt;
	last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);

	if (blank) {
		dc->hwss.set_abm_immediate_disable(pipe_ctx);
@@ -1080,28 +1080,31 @@ void dcn20_blank_pixel_data(
		test_pattern = CONTROLLER_DP_TEST_PATTERN_VIDEOMODE;
	}

	odm_pipe = pipe_ctx;

	while (odm_pipe->next_odm_pipe) {
		dc->hwss.set_disp_pattern_generator(dc,
				pipe_ctx,
				test_pattern,
				test_pattern_color_space,
				stream->timing.display_color_depth,
				&black_color,
			width,
			height,
			0);
				odm_slice_width,
				v_active,
				offset);
		offset += odm_slice_width;
		odm_pipe = odm_pipe->next_odm_pipe;
	}

	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
	dc->hwss.set_disp_pattern_generator(dc,
			odm_pipe,
				dc->debug.visual_confirm != VISUAL_CONFIRM_DISABLE && blank ?
						CONTROLLER_DP_TEST_PATTERN_COLORRAMP : test_pattern,
			test_pattern,
			test_pattern_color_space,
			stream->timing.display_color_depth,
			&black_color,
				width,
				height,
				0);
	}
			last_odm_slice_width,
			v_active,
			offset);

	if (!blank && dc->debug.enable_single_display_2to1_odm_policy) {
		/* when exiting dynamic ODM need to reinit DPG state for unused pipes */
+54 −53
Original line number Diff line number Diff line
@@ -428,15 +428,24 @@ static void set_crtc_test_pattern(struct dc_link *link,
		stream->timing.display_color_depth;
	struct bit_depth_reduction_params params;
	struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;
	int width = pipe_ctx->stream->timing.h_addressable +
	struct pipe_ctx *odm_pipe;
	int odm_cnt = 1;
	int h_active = pipe_ctx->stream->timing.h_addressable +
		pipe_ctx->stream->timing.h_border_left +
		pipe_ctx->stream->timing.h_border_right;
	int height = pipe_ctx->stream->timing.v_addressable +
	int v_active = pipe_ctx->stream->timing.v_addressable +
		pipe_ctx->stream->timing.v_border_bottom +
		pipe_ctx->stream->timing.v_border_top;
	int odm_slice_width, last_odm_slice_width, offset = 0;

	memset(&params, 0, sizeof(params));

	for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
		odm_cnt++;

	odm_slice_width = h_active / odm_cnt;
	last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);

	switch (test_pattern) {
	case DP_TEST_PATTERN_COLOR_SQUARES:
		controller_test_pattern =
@@ -473,16 +482,13 @@ static void set_crtc_test_pattern(struct dc_link *link,
	{
		/* disable bit depth reduction */
		pipe_ctx->stream->bit_depth_params = params;
		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
			opp->funcs->opp_program_bit_depth_reduction(opp, &params);
		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
				controller_test_pattern, color_depth);
		else if (link->dc->hwss.set_disp_pattern_generator) {
			struct pipe_ctx *odm_pipe;
		} else if (link->dc->hwss.set_disp_pattern_generator) {
			enum controller_dp_color_space controller_color_space;
			int opp_cnt = 1;
			int offset = 0;
			int dpg_width = width;
			struct output_pixel_processor *odm_opp;

			switch (test_pattern_color_space) {
			case DP_TEST_PATTERN_COLOR_SPACE_RGB:
@@ -502,24 +508,23 @@ static void set_crtc_test_pattern(struct dc_link *link,
				break;
			}

			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
				opp_cnt++;
			dpg_width = width / opp_cnt;
			offset = dpg_width;

			odm_pipe = pipe_ctx;
			while (odm_pipe->next_odm_pipe) {
				odm_opp = odm_pipe->stream_res.opp;
				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
				link->dc->hwss.set_disp_pattern_generator(link->dc,
						pipe_ctx,
						controller_test_pattern,
						controller_color_space,
						color_depth,
						NULL,
					dpg_width,
					height,
					0);

			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;

						odm_slice_width,
						v_active,
						offset);
				offset += odm_slice_width;
				odm_pipe = odm_pipe->next_odm_pipe;
			}
			odm_opp = odm_pipe->stream_res.opp;
			odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
			link->dc->hwss.set_disp_pattern_generator(link->dc,
					odm_pipe,
@@ -527,11 +532,9 @@ static void set_crtc_test_pattern(struct dc_link *link,
					controller_color_space,
					color_depth,
					NULL,
						dpg_width,
						height,
					last_odm_slice_width,
					v_active,
					offset);
				offset += offset;
			}
		}
	}
	break;
@@ -540,23 +543,17 @@ static void set_crtc_test_pattern(struct dc_link *link,
		/* restore bitdepth reduction */
		resource_build_bit_depth_reduction_params(pipe_ctx->stream, &params);
		pipe_ctx->stream->bit_depth_params = params;
		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern) {
			opp->funcs->opp_program_bit_depth_reduction(opp, &params);
		if (pipe_ctx->stream_res.tg->funcs->set_test_pattern)
			pipe_ctx->stream_res.tg->funcs->set_test_pattern(pipe_ctx->stream_res.tg,
					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
					color_depth);
		else if (link->dc->hwss.set_disp_pattern_generator) {
			struct pipe_ctx *odm_pipe;
			int opp_cnt = 1;
			int dpg_width;

			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe)
				opp_cnt++;

			dpg_width = width / opp_cnt;
			for (odm_pipe = pipe_ctx->next_odm_pipe; odm_pipe; odm_pipe = odm_pipe->next_odm_pipe) {
				struct output_pixel_processor *odm_opp = odm_pipe->stream_res.opp;
		} else if (link->dc->hwss.set_disp_pattern_generator) {
			struct output_pixel_processor *odm_opp;

			odm_pipe = pipe_ctx;
			while (odm_pipe->next_odm_pipe) {
				odm_opp = odm_pipe->stream_res.opp;
				odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
				link->dc->hwss.set_disp_pattern_generator(link->dc,
						odm_pipe,
@@ -564,19 +561,23 @@ static void set_crtc_test_pattern(struct dc_link *link,
						CONTROLLER_DP_COLOR_SPACE_UDEFINED,
						color_depth,
						NULL,
						dpg_width,
						height,
						0);
						odm_slice_width,
						v_active,
						offset);
				offset += odm_slice_width;
				odm_pipe = odm_pipe->next_odm_pipe;
			}
			odm_opp = odm_pipe->stream_res.opp;
			odm_opp->funcs->opp_program_bit_depth_reduction(odm_opp, &params);
			link->dc->hwss.set_disp_pattern_generator(link->dc,
					pipe_ctx,
					odm_pipe,
					CONTROLLER_DP_TEST_PATTERN_VIDEOMODE,
					CONTROLLER_DP_COLOR_SPACE_UDEFINED,
					color_depth,
					NULL,
					dpg_width,
					height,
					0);
					last_odm_slice_width,
					v_active,
					offset);
		}
	}
	break;