All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wayne Lin <Wayne.Lin@amd.com>
To: <amd-gfx@lists.freedesktop.org>
Cc: Eryk.Brol@amd.com, Sunpeng.Li@amd.com, Harry.Wentland@amd.com,
	Qingqing.Zhuo@amd.com, Rodrigo.Siqueira@amd.com,
	Wenjing Liu <wenjing.liu@amd.com>,
	Anson.Jacob@amd.com, Aurabindo.Pillai@amd.com,
	Bhawanpreet.Lakha@amd.com, bindu.r@amd.com
Subject: [PATCH 12/16] drm/amd/display: take max dsc stream bandwidth overhead into account
Date: Fri, 23 Apr 2021 10:37:10 +0800	[thread overview]
Message-ID: <20210423023714.22044-13-Wayne.Lin@amd.com> (raw)
In-Reply-To: <20210423023714.22044-1-Wayne.Lin@amd.com>

From: Wenjing Liu <wenjing.liu@amd.com>

[why]
As hardware team suggested that we need to add a max dsc bw overhead
into existing stream bandwidth when DSC is used.
The formula as below:

max_dsc_bw_overhead =
v_addressable * slice_count * 256 bit * pixel clock / v_total / h_total

effective stream bandwidth = pixel clock * bpp

stream bandwidth = effective stream bandwidth + dsc stream overhead

Signed-off-by: Wenjing Liu <wenjing.liu@amd.com>
Reviewed-by: Eric Bernstein <Eric.Bernstein@amd.com>
Acked-by: Wayne Lin <waynelin@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |   7 +-
 drivers/gpu/drm/amd/display/dc/dc_dsc.h       |   5 +-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c   | 113 ++++++++++++++----
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c  |  43 -------
 drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h  |   2 -
 5 files changed, 94 insertions(+), 76 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 931fbb4d6169..8bbed9c90c5d 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3486,9 +3486,10 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
 	uint32_t kbps;
 
 #if defined(CONFIG_DRM_AMD_DC_DCN)
-	if (timing->flags.DSC) {
-		return dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, timing->dsc_cfg.bits_per_pixel);
-	}
+	if (timing->flags.DSC)
+		return dc_dsc_stream_bandwidth_in_kbps(timing,
+				timing->dsc_cfg.bits_per_pixel,
+				timing->dsc_cfg.num_slices_h);
 #endif
 
 	switch (timing->display_color_depth) {
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
index c51d2d961b7a..afddb8b7d3e4 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -78,7 +78,8 @@ bool dc_dsc_compute_config(
 		const struct dc_crtc_timing *timing,
 		struct dc_dsc_config *dsc_cfg);
 
-uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16);
+uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
+		uint32_t bpp_x16, uint32_t num_slices_h);
 
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
 		uint32_t max_target_bpp_limit_override_x16,
@@ -88,6 +89,4 @@ void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
 
 void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);
 
-uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16);
-
 #endif
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
index be57088d185d..bfe3ad58070a 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -258,12 +258,58 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
 	return (value + 9) / 10;
 }
 
+static struct fixed31_32 compute_dsc_max_bandwidth_overhead(
+		const struct dc_crtc_timing *timing,
+		const int num_slices_h)
+{
+	struct fixed31_32 max_dsc_overhead;
+	struct fixed31_32 refresh_rate;
+
+	/* use target bpp that can take entire target bandwidth */
+	refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz);
+	refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total);
+	refresh_rate = dc_fixpt_div_int(refresh_rate, timing->v_total);
+	refresh_rate = dc_fixpt_mul_int(refresh_rate, 100);
+
+	max_dsc_overhead = dc_fixpt_from_int(num_slices_h);
+	max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_addressable);
+	max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256);
+	max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000);
+	max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate);
+
+	return max_dsc_overhead;
+}
+
+static uint32_t compute_bpp_x16_from_target_bandwidth(
+		const uint32_t bandwidth_in_kbps,
+		const struct dc_crtc_timing *timing,
+		const uint32_t num_slices_h,
+		const uint32_t bpp_increment_div)
+{
+	struct fixed31_32 overhead_in_kbps;
+	struct fixed31_32 effective_bandwidth_in_kbps;
+	struct fixed31_32 bpp_x16;
+
+	overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
+				timing, num_slices_h);
+	effective_bandwidth_in_kbps = dc_fixpt_from_int(bandwidth_in_kbps);
+	effective_bandwidth_in_kbps = dc_fixpt_sub(effective_bandwidth_in_kbps,
+			overhead_in_kbps);
+	bpp_x16 = dc_fixpt_mul_int(effective_bandwidth_in_kbps, 10);
+	bpp_x16 = dc_fixpt_div_int(bpp_x16, timing->pix_clk_100hz);
+	bpp_x16 = dc_fixpt_from_int(dc_fixpt_floor(dc_fixpt_mul_int(bpp_x16, bpp_increment_div)));
+	bpp_x16 = dc_fixpt_div_int(bpp_x16, bpp_increment_div);
+	bpp_x16 = dc_fixpt_mul_int(bpp_x16, 16);
+	return dc_fixpt_floor(bpp_x16);
+}
+
 /* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock
  * and uncompressed bandwidth.
  */
 static void get_dsc_bandwidth_range(
 		const uint32_t min_bpp_x16,
 		const uint32_t max_bpp_x16,
+		const uint32_t num_slices_h,
 		const struct dsc_enc_caps *dsc_caps,
 		const struct dc_crtc_timing *timing,
 		struct dc_dsc_bw_range *range)
@@ -272,16 +318,20 @@ static void get_dsc_bandwidth_range(
 	range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing);
 
 	/* max dsc target bpp */
-	range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, max_bpp_x16);
+	range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
+			max_bpp_x16, num_slices_h);
 	range->max_target_bpp_x16 = max_bpp_x16;
 	if (range->max_kbps > range->stream_kbps) {
 		/* max dsc target bpp is capped to native bandwidth */
 		range->max_kbps = range->stream_kbps;
-		range->max_target_bpp_x16 = calc_dsc_bpp_x16(range->stream_kbps, timing->pix_clk_100hz, dsc_caps->bpp_increment_div);
+		range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
+				range->max_kbps, timing, num_slices_h,
+				dsc_caps->bpp_increment_div);
 	}
 
 	/* min dsc target bpp */
-	range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, min_bpp_x16);
+	range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
+			min_bpp_x16, num_slices_h);
 	range->min_target_bpp_x16 = min_bpp_x16;
 	if (range->min_kbps > range->max_kbps) {
 		/* min dsc target bpp is capped to max dsc bandwidth*/
@@ -290,7 +340,6 @@ static void get_dsc_bandwidth_range(
 	}
 }
 
-
 /* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy.
  *
  * Returns:
@@ -303,6 +352,7 @@ static bool decide_dsc_target_bpp_x16(
 		const struct dsc_enc_caps *dsc_common_caps,
 		const int target_bandwidth_kbps,
 		const struct dc_crtc_timing *timing,
+		const int num_slices_h,
 		int *target_bpp_x16)
 {
 	bool should_use_dsc = false;
@@ -311,7 +361,7 @@ static bool decide_dsc_target_bpp_x16(
 	memset(&range, 0, sizeof(range));
 
 	get_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16,
-			dsc_common_caps, timing, &range);
+			num_slices_h, dsc_common_caps, timing, &range);
 	if (!policy->enable_dsc_when_not_needed && target_bandwidth_kbps >= range.stream_kbps) {
 		/* enough bandwidth without dsc */
 		*target_bpp_x16 = 0;
@@ -327,7 +377,11 @@ static bool decide_dsc_target_bpp_x16(
 		should_use_dsc = true;
 	} else if (target_bandwidth_kbps >= range.min_kbps) {
 		/* use target bpp that can take entire target bandwidth */
-		*target_bpp_x16 = calc_dsc_bpp_x16(target_bandwidth_kbps, timing->pix_clk_100hz, dsc_common_caps->bpp_increment_div);
+		*target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
+				range.max_kbps, timing, num_slices_h,
+				dsc_common_caps->bpp_increment_div);
+		if (*target_bpp_x16 < range.min_kbps)
+			*target_bpp_x16 = range.min_kbps;
 		should_use_dsc = true;
 	} else {
 		/* not enough bandwidth to fulfill minimum requirement */
@@ -531,18 +585,6 @@ static bool setup_dsc_config(
 	if (!is_dsc_possible)
 		goto done;
 
-	if (target_bandwidth_kbps > 0) {
-		is_dsc_possible = decide_dsc_target_bpp_x16(
-				&policy,
-				&dsc_common_caps,
-				target_bandwidth_kbps,
-				timing,
-				&target_bpp);
-		dsc_cfg->bits_per_pixel = target_bpp;
-	}
-	if (!is_dsc_possible)
-		goto done;
-
 	sink_per_slice_throughput_mps = 0;
 
 	// Validate available DSC settings against the mode timing
@@ -690,6 +732,19 @@ static bool setup_dsc_config(
 
 	dsc_cfg->num_slices_v = pic_height/slice_height;
 
+	if (target_bandwidth_kbps > 0) {
+		is_dsc_possible = decide_dsc_target_bpp_x16(
+				&policy,
+				&dsc_common_caps,
+				target_bandwidth_kbps,
+				timing,
+				num_slices_h,
+				&target_bpp);
+		dsc_cfg->bits_per_pixel = target_bpp;
+	}
+	if (!is_dsc_possible)
+		goto done;
+
 	// Final decission: can we do DSC or not?
 	if (is_dsc_possible) {
 		// Fill out the rest of DSC settings
@@ -838,7 +893,8 @@ bool dc_dsc_compute_bandwidth_range(
 				dsc_min_slice_height_override, max_bpp_x16, &config);
 
 	if (is_dsc_possible)
-		get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, &dsc_common_caps, timing, range);
+		get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
+				config.num_slices_h, &dsc_common_caps, timing, range);
 
 	return is_dsc_possible;
 }
@@ -864,13 +920,20 @@ bool dc_dsc_compute_config(
 	return is_dsc_possible;
 }
 
-uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t bpp_x16)
+uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
+		uint32_t bpp_x16, uint32_t num_slices_h)
 {
-	struct fixed31_32 link_bw_kbps;
-	link_bw_kbps = dc_fixpt_from_int(pix_clk_100hz);
-	link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160);
-	link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, bpp_x16);
-	return dc_fixpt_ceil(link_bw_kbps);
+	struct fixed31_32 overhead_in_kbps;
+	struct fixed31_32 bpp;
+	struct fixed31_32 actual_bandwidth_in_kbps;
+
+	overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
+			timing, num_slices_h);
+	bpp = dc_fixpt_from_fraction(bpp_x16, 16);
+	actual_bandwidth_in_kbps = dc_fixpt_from_fraction(timing->pix_clk_100hz, 10);
+	actual_bandwidth_in_kbps = dc_fixpt_mul(actual_bandwidth_in_kbps, bpp);
+	actual_bandwidth_in_kbps = dc_fixpt_add(actual_bandwidth_in_kbps, overhead_in_kbps);
+	return dc_fixpt_ceil(actual_bandwidth_in_kbps);
 }
 
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy)
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
index c6a1cd80aeae..7b294f637881 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c
@@ -284,26 +284,6 @@ static u32 _do_bytes_per_pixel_calc(int slice_width, u16 drm_bpp,
 	return bytes_per_pixel;
 }
 
-static u32 _do_calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
-				u32 bpp_increment_div)
-{
-	u32 dsc_target_bpp_x16;
-	float f_dsc_target_bpp;
-	float f_stream_bandwidth_100bps;
-	// bpp_increment_div is actually precision
-	u32 precision = bpp_increment_div;
-
-	f_stream_bandwidth_100bps = stream_bandwidth_kbps * 10.0f;
-	f_dsc_target_bpp = f_stream_bandwidth_100bps / pix_clk_100hz;
-
-	// Round down to the nearest precision stop to bring it into DSC spec
-	// range
-	dsc_target_bpp_x16 = (u32)(f_dsc_target_bpp * precision);
-	dsc_target_bpp_x16 = (dsc_target_bpp_x16 * 16) / precision;
-
-	return dsc_target_bpp_x16;
-}
-
 /**
  * calc_rc_params - reads the user's cmdline mode
  * @rc: DC internal DSC parameters
@@ -367,26 +347,3 @@ u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps)
 	DC_FP_END();
 	return ret;
 }
-
-/**
- * calc_dsc_bpp_x16 - retrieve the dsc bits per pixel
- * @stream_bandwidth_kbps:
- * @pix_clk_100hz:
- * @bpp_increment_div:
- *
- * Calculate the total of bits per pixel for DSC configuration.
- *
- * @note This calculation requires float point operation, most of it executes
- * under kernel_fpu_{begin,end}.
- */
-u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
-		     u32 bpp_increment_div)
-{
-	u32 dsc_bpp;
-
-	DC_FP_START();
-	dsc_bpp =  _do_calc_dsc_bpp_x16(stream_bandwidth_kbps, pix_clk_100hz,
-					bpp_increment_div);
-	DC_FP_END();
-	return dsc_bpp;
-}
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
index 8123827840c5..262f06afcbf9 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
+++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h
@@ -79,8 +79,6 @@ typedef struct qp_entry qp_table[];
 
 void calc_rc_params(struct rc_params *rc, const struct drm_dsc_config *pps);
 u32 calc_dsc_bytes_per_pixel(const struct drm_dsc_config *pps);
-u32 calc_dsc_bpp_x16(u32 stream_bandwidth_kbps, u32 pix_clk_100hz,
-		     u32 bpp_increment_div);
 
 #endif
 
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2021-04-23  2:40 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-23  2:36 [PATCH 00/16] DC Patches April 23, 2021 Wayne Lin
2021-04-23  2:36 ` [PATCH 01/16] drm/amd/display: Add new case to get spread spectrum info Wayne Lin
2021-04-23  2:37 ` [PATCH 02/16] drm/amd/display: fix HDCP reset sequence on reinitialize Wayne Lin
2021-04-23  2:37 ` [PATCH 03/16] drm/amd/display: Revert wait vblank on update dpp clock Wayne Lin
2021-04-23  2:37 ` [PATCH 04/16] drm/amd/display: skip program clock when allow seamless boot Wayne Lin
2021-04-23  2:37 ` [PATCH 05/16] drm/amd/display: Expose internal display flag via debugfs Wayne Lin
2021-04-23  2:37 ` [PATCH 06/16] drm/amd/display: ddc resource data need to be initialized Wayne Lin
2021-04-23  2:37 ` [PATCH 07/16] drm/amd/display: Added multi instance support for ABM Wayne Lin
2021-04-23  2:37 ` [PATCH 08/16] drm/amd/display: Fix BSOD with NULL check Wayne Lin
2021-04-23  2:37 ` [PATCH 09/16] drm/amd/display: Add new DP_SEC registers for programming SDP Line number Wayne Lin
2021-04-23  2:37 ` [PATCH 10/16] drm/amd/display: Clear MASTER_UPDATE_LOCK_DB_EN when disable doublebuffer lock Wayne Lin
2021-04-23  2:37 ` [PATCH 11/16] drm/amd/display: fix wrong statement in mst hpd debugfs Wayne Lin
2021-04-23  2:37 ` Wayne Lin [this message]
2021-04-23  2:37 ` [PATCH 13/16] drm/amd/display: avoid to authentication when DEVICE_COUNT=0 Wayne Lin
2021-04-23  2:37 ` [PATCH 14/16] drm/amd/display: Add SE_DCN3_REG_LIST for control SDP num Wayne Lin
2021-04-23  2:37 ` [PATCH 15/16] drm/amd/display: [FW Promotion] Release 0.0.63 Wayne Lin
2021-04-23  2:37 ` [PATCH 16/16] drm/amd/display: 3.2.133 Wayne Lin
2021-04-23 19:36 ` [PATCH 00/16] DC Patches April 23, 2021 Wheeler, Daniel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210423023714.22044-13-Wayne.Lin@amd.com \
    --to=wayne.lin@amd.com \
    --cc=Anson.Jacob@amd.com \
    --cc=Aurabindo.Pillai@amd.com \
    --cc=Bhawanpreet.Lakha@amd.com \
    --cc=Eryk.Brol@amd.com \
    --cc=Harry.Wentland@amd.com \
    --cc=Qingqing.Zhuo@amd.com \
    --cc=Rodrigo.Siqueira@amd.com \
    --cc=Sunpeng.Li@amd.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=bindu.r@amd.com \
    --cc=wenjing.liu@amd.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.