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

drm/amd/display: use even ODM slice width for two pixels per container



[why]
When optc uses two pixel per container, each ODM slice width must be an
even number.

[how]
If ODM slice width is odd number increase it by 1.

Reviewed-by: default avatarDillon Varone <dillon.varone@amd.com>
Acked-by: default avatarWayne Lin <wayne.lin@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 a8baec46
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -827,6 +827,11 @@ static struct rect calculate_odm_slice_in_timing_active(struct pipe_ctx *pipe_ct
			stream->timing.h_border_right;
	int odm_slice_width = h_active / odm_slice_count;
	struct rect odm_rec;
	bool is_two_pixels_per_container =
			pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing);

	if ((odm_slice_width % 2) && is_two_pixels_per_container)
		odm_slice_width++;

	odm_rec.x = odm_slice_width * odm_slice_idx;
	odm_rec.width = is_last_odm_slice ?
@@ -1464,6 +1469,7 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx,
	int v_active = otg_master->stream->timing.v_addressable +
		otg_master->stream->timing.v_border_bottom +
		otg_master->stream->timing.v_border_top;
	bool is_two_pixels_per_container = otg_master->stream_res.tg->funcs->is_two_pixels_per_container(&otg_master->stream->timing);
	int i;

	controller_test_pattern = convert_dp_to_controller_test_pattern(
@@ -1477,6 +1483,8 @@ void resource_build_test_pattern_params(struct resource_context *res_ctx,
	odm_cnt = resource_get_opp_heads_for_otg_master(otg_master, res_ctx, opp_heads);

	odm_slice_width = h_active / odm_cnt;
	if ((odm_slice_width % 2) && is_two_pixels_per_container)
		odm_slice_width++;
	last_odm_slice_width = h_active - odm_slice_width * (odm_cnt - 1);

	for (i = 0; i < odm_cnt; i++) {
+18 −0
Original line number Diff line number Diff line
@@ -2015,6 +2015,23 @@ bool dce110_tg_validate_timing(struct timing_generator *tg,
	return dce110_timing_generator_validate_timing(tg, timing, SIGNAL_TYPE_NONE);
}

/* "Container" vs. "pixel" is a concept within HW blocks, mostly those closer to the back-end. It works like this:
 *
 * - In most of the formats (RGB or YCbCr 4:4:4, 4:2:2 uncompressed and DSC 4:2:2 Simple) pixel rate is the same as
 *   container rate.
 *
 * - In 4:2:0 (DSC or uncompressed) there are two pixels per container, hence the target container rate has to be
 *   halved to maintain the correct pixel rate.
 *
 * - Unlike 4:2:2 uncompressed, DSC 4:2:2 Native also has two pixels per container (this happens when DSC is applied
 *   to it) and has to be treated the same as 4:2:0, i.e. target containter rate has to be halved in this case as well.
 *
 */
bool dce110_is_two_pixels_per_container(const struct dc_crtc_timing *timing)
{
	return timing->pixel_encoding == PIXEL_ENCODING_YCBCR420;
}

void dce110_tg_wait_for_state(struct timing_generator *tg,
	enum crtc_state state)
{
@@ -2239,6 +2256,7 @@ static const struct timing_generator_funcs dce110_tg_funcs = {
		.is_tg_enabled = dce110_is_tg_enabled,
		.configure_crc = dce110_configure_crc,
		.get_crc = dce110_get_crc,
		.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
};

void dce110_timing_generator_construct(
+2 −0
Original line number Diff line number Diff line
@@ -288,4 +288,6 @@ bool dce110_configure_crc(struct timing_generator *tg,
bool dce110_get_crc(struct timing_generator *tg,
		    uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb);

bool dce110_is_two_pixels_per_container(const struct dc_crtc_timing *timing);

#endif /* __DC_TIMING_GENERATOR_DCE110_H__ */
+2 −1
Original line number Diff line number Diff line
@@ -682,7 +682,8 @@ static const struct timing_generator_funcs dce110_tg_v_funcs = {
		.tear_down_global_swap_lock =
				dce110_timing_generator_v_tear_down_global_swap_lock,
		.enable_advanced_request =
				dce110_timing_generator_v_enable_advanced_request
				dce110_timing_generator_v_enable_advanced_request,
		.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
};

void dce110_timing_generator_v_construct(
+1 −0
Original line number Diff line number Diff line
@@ -1197,6 +1197,7 @@ static const struct timing_generator_funcs dce120_tg_funcs = {
		.is_tg_enabled = dce120_is_tg_enabled,
		.configure_crc = dce120_configure_crc,
		.get_crc = dce120_get_crc,
		.is_two_pixels_per_container = dce110_is_two_pixels_per_container,
};


Loading