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

drm/amd/display: use proper formula to calculate bandwidth from timing



[why]
The existing calculation uses a wrong formula to
calculate bandwidth from timing.

[how]
Expose the existing proper function that calculates the bandwidth,
so dc_link can use it to calculate timing bandwidth correctly.

Signed-off-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e5490464
Loading
Loading
Loading
Loading
+47 −1
Original line number Diff line number Diff line
@@ -2321,7 +2321,7 @@ static struct fixed31_32 get_pbn_from_timing(struct pipe_ctx *pipe_ctx)
	uint32_t denominator;

	bpc = get_color_depth(pipe_ctx->stream_res.pix_clk_params.color_depth);
	kbps = pipe_ctx->stream_res.pix_clk_params.requested_pix_clk_100hz / 10 * bpc * 3;
	kbps = dc_bandwidth_in_kbps_from_timing(&pipe_ctx->stream->timing);

	/*
	 * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006
@@ -2736,3 +2736,49 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable)
	}
}

uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing)
{
	uint32_t bits_per_channel = 0;
	uint32_t kbps;

	switch (timing->display_color_depth) {
	case COLOR_DEPTH_666:
		bits_per_channel = 6;
		break;
	case COLOR_DEPTH_888:
		bits_per_channel = 8;
		break;
	case COLOR_DEPTH_101010:
		bits_per_channel = 10;
		break;
	case COLOR_DEPTH_121212:
		bits_per_channel = 12;
		break;
	case COLOR_DEPTH_141414:
		bits_per_channel = 14;
		break;
	case COLOR_DEPTH_161616:
		bits_per_channel = 16;
		break;
	default:
		break;
	}

	ASSERT(bits_per_channel != 0);

	kbps = timing->pix_clk_100hz / 10;
	kbps *= bits_per_channel;

	if (timing->flags.Y_ONLY != 1) {
		/*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
		kbps *= 3;
		if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
			kbps /= 2;
		else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
			kbps = kbps * 2 / 3;
	}

	return kbps;

}
+2 −49
Original line number Diff line number Diff line
@@ -1533,53 +1533,6 @@ static bool decide_fallback_link_setting(
	return true;
}

static uint32_t bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing)
{
	uint32_t bits_per_channel = 0;
	uint32_t kbps;

	switch (timing->display_color_depth) {
	case COLOR_DEPTH_666:
		bits_per_channel = 6;
		break;
	case COLOR_DEPTH_888:
		bits_per_channel = 8;
		break;
	case COLOR_DEPTH_101010:
		bits_per_channel = 10;
		break;
	case COLOR_DEPTH_121212:
		bits_per_channel = 12;
		break;
	case COLOR_DEPTH_141414:
		bits_per_channel = 14;
		break;
	case COLOR_DEPTH_161616:
		bits_per_channel = 16;
		break;
	default:
		break;
	}

	ASSERT(bits_per_channel != 0);

	kbps = timing->pix_clk_100hz / 10;
	kbps *= bits_per_channel;

	if (timing->flags.Y_ONLY != 1) {
		/*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/
		kbps *= 3;
		if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420)
			kbps /= 2;
		else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422)
			kbps = kbps * 2 / 3;
	}

	return kbps;

}

static uint32_t bandwidth_in_kbps_from_link_settings(
	const struct dc_link_settings *link_setting)
{
@@ -1620,7 +1573,7 @@ bool dp_validate_mode_timing(
		link_setting = &link->verified_link_cap;
	*/

	req_bw = bandwidth_in_kbps_from_timing(timing);
	req_bw = dc_bandwidth_in_kbps_from_timing(timing);
	max_bw = bandwidth_in_kbps_from_link_settings(link_setting);

	if (req_bw <= max_bw) {
@@ -1739,7 +1692,7 @@ void decide_link_settings(struct dc_stream_state *stream,
	struct dc_link *link;
	uint32_t req_bw;

	req_bw = bandwidth_in_kbps_from_timing(&stream->timing);
	req_bw = dc_bandwidth_in_kbps_from_timing(&stream->timing);

	link = stream->link;

+2 −0
Original line number Diff line number Diff line
@@ -252,4 +252,6 @@ bool dc_submit_i2c(
		uint32_t link_index,
		struct i2c_command *cmd);

uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing);
#endif /* DC_LINK_H_ */