From: Dillon Varone <dillon.var...@amd.com>

[Why?]
Some code still expected bpp to be used in whole bits, not 16ths.  dsc.c uses
redundant function now found in dc to calculate stream bandwidth from timing.

[How?]
Fix code to work with 16ths instead of whole bits for dsc bpp.
Refactor get_dsc_bandwidth to accept inputs in 16ths of a bit.
Use dc function to calculate bandwidth from timing, and make dsc bw calculation
a part of dsc.c.

Signed-off-by: Dillon Varone <dillon.var...@amd.com>
Reviewed-by: Wenjing Liu <wenjing....@amd.com>
Acked-by: Solomon Chiu <solomon.c...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/core/dc_link.c |   9 +-
 drivers/gpu/drm/amd/display/dc/dc_dsc.h       |   9 +-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c   | 105 ++++++------------
 3 files changed, 43 insertions(+), 80 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 9337e87a73e7..30263009851e 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3497,19 +3497,16 @@ void dc_link_enable_hpd_filter(struct dc_link *link, 
bool enable)
        }
 }
 
+uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t 
bpp_x16);
+
 uint32_t dc_bandwidth_in_kbps_from_timing(
        const struct dc_crtc_timing *timing)
 {
        uint32_t bits_per_channel = 0;
        uint32_t kbps;
-       struct fixed31_32 link_bw_kbps;
 
        if (timing->flags.DSC) {
-               link_bw_kbps = dc_fixpt_from_int(timing->pix_clk_100hz);
-               link_bw_kbps = dc_fixpt_div_int(link_bw_kbps, 160);
-               link_bw_kbps = dc_fixpt_mul_int(link_bw_kbps, 
timing->dsc_cfg.bits_per_pixel);
-               kbps = dc_fixpt_ceil(link_bw_kbps);
-               return kbps;
+               return dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, 
timing->dsc_cfg.bits_per_pixel);
        }
 
        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 ec55b77727d5..0c5d98524536 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -51,6 +51,7 @@ struct dc_dsc_policy {
        int min_slice_height; // Must not be less than 8
        uint32_t max_target_bpp;
        uint32_t min_target_bpp;
+       uint32_t preferred_bpp_x16;
        bool enable_dsc_when_not_needed;
 };
 
@@ -62,8 +63,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
 bool dc_dsc_compute_bandwidth_range(
                const struct display_stream_compressor *dsc,
                uint32_t dsc_min_slice_height_override,
-               uint32_t min_bpp,
-               uint32_t max_bpp,
+               uint32_t min_bpp_x16,
+               uint32_t max_bpp_x16,
                const struct dsc_dec_dpcd_caps *dsc_sink_caps,
                const struct dc_crtc_timing *timing,
                struct dc_dsc_bw_range *range);
@@ -77,8 +78,10 @@ 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);
+
 void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
-               uint32_t max_target_bpp_limit_override,
+               uint32_t max_target_bpp_limit_override_x16,
                struct dc_dsc_policy *policy);
 
 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
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 c62d0eddc9c6..be57088d185d 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -37,59 +37,6 @@ static uint32_t dsc_policy_max_target_bpp_limit = 16;
 /* default DSC policy enables DSC only when needed */
 static bool dsc_policy_enable_dsc_when_not_needed;
 
-static uint32_t dc_dsc_bandwidth_in_kbps_from_timing(
-       const struct dc_crtc_timing *timing)
-{
-       uint32_t bits_per_channel = 0;
-       uint32_t kbps;
-
-       if (timing->flags.DSC) {
-               kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel);
-               kbps = kbps / 160 + ((kbps % 160) ? 1 : 0);
-               return 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 bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int 
*buff_block_size)
 {
 
@@ -315,18 +262,18 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t 
value)
  * and uncompressed bandwidth.
  */
 static void get_dsc_bandwidth_range(
-               const uint32_t min_bpp,
-               const uint32_t max_bpp,
+               const uint32_t min_bpp_x16,
+               const uint32_t max_bpp_x16,
                const struct dsc_enc_caps *dsc_caps,
                const struct dc_crtc_timing *timing,
                struct dc_dsc_bw_range *range)
 {
        /* native stream bandwidth */
-       range->stream_kbps = dc_dsc_bandwidth_in_kbps_from_timing(timing);
+       range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing);
 
        /* max dsc target bpp */
-       range->max_kbps = dsc_div_by_10_round_up(max_bpp * 
timing->pix_clk_100hz);
-       range->max_target_bpp_x16 = max_bpp * 16;
+       range->max_kbps = 
dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, max_bpp_x16);
+       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;
@@ -334,8 +281,8 @@ static void get_dsc_bandwidth_range(
        }
 
        /* min dsc target bpp */
-       range->min_kbps = dsc_div_by_10_round_up(min_bpp * 
timing->pix_clk_100hz);
-       range->min_target_bpp_x16 = min_bpp * 16;
+       range->min_kbps = 
dc_dsc_stream_bandwidth_in_kbps(timing->pix_clk_100hz, min_bpp_x16);
+       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*/
                range->min_kbps = range->max_kbps;
@@ -363,12 +310,17 @@ static bool decide_dsc_target_bpp_x16(
 
        memset(&range, 0, sizeof(range));
 
-       get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp,
+       get_dsc_bandwidth_range(policy->min_target_bpp * 16, 
policy->max_target_bpp * 16,
                        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;
                should_use_dsc = false;
+       } else if (policy->preferred_bpp_x16 > 0 &&
+                       policy->preferred_bpp_x16 <= range.max_target_bpp_x16 &&
+                       policy->preferred_bpp_x16 >= range.min_target_bpp_x16) {
+               *target_bpp_x16 = policy->preferred_bpp_x16;
+               should_use_dsc = true;
        } else if (target_bandwidth_kbps >= range.max_kbps) {
                /* use max target bpp allowed */
                *target_bpp_x16 = range.max_target_bpp_x16;
@@ -545,7 +497,7 @@ static bool setup_dsc_config(
                int target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
                int min_slice_height_override,
-               int max_dsc_target_bpp_limit_override,
+               int max_dsc_target_bpp_limit_override_x16,
                struct dc_dsc_config *dsc_cfg)
 {
        struct dsc_enc_caps dsc_common_caps;
@@ -564,7 +516,7 @@ static bool setup_dsc_config(
 
        memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
 
-       dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override, 
&policy);
+       dc_dsc_get_policy_for_timing(timing, 
max_dsc_target_bpp_limit_override_x16, &policy);
        pic_width = timing->h_addressable + timing->h_border_left + 
timing->h_border_right;
        pic_height = timing->v_addressable + timing->v_border_top + 
timing->v_border_bottom;
 
@@ -865,8 +817,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const 
uint8_t *dpcd_dsc_basic_da
 bool dc_dsc_compute_bandwidth_range(
                const struct display_stream_compressor *dsc,
                uint32_t dsc_min_slice_height_override,
-               uint32_t min_bpp,
-               uint32_t max_bpp,
+               uint32_t min_bpp_x16,
+               uint32_t max_bpp_x16,
                const struct dsc_dec_dpcd_caps *dsc_sink_caps,
                const struct dc_crtc_timing *timing,
                struct dc_dsc_bw_range *range)
@@ -883,10 +835,10 @@ bool dc_dsc_compute_bandwidth_range(
 
        if (is_dsc_possible)
                is_dsc_possible = setup_dsc_config(dsc_sink_caps, 
&dsc_enc_caps, 0, timing,
-                               dsc_min_slice_height_override, max_bpp, 
&config);
+                               dsc_min_slice_height_override, max_bpp_x16, 
&config);
 
        if (is_dsc_possible)
-               get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, 
timing, range);
+               get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, 
&dsc_common_caps, timing, range);
 
        return is_dsc_possible;
 }
@@ -908,11 +860,20 @@ bool dc_dsc_compute_config(
                        &dsc_enc_caps,
                        target_bandwidth_kbps,
                        timing, dsc_min_slice_height_override,
-                       max_target_bpp_limit_override, dsc_cfg);
+                       max_target_bpp_limit_override * 16, dsc_cfg);
        return is_dsc_possible;
 }
 
-void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, 
uint32_t max_target_bpp_limit_override, struct dc_dsc_policy *policy)
+uint32_t dc_dsc_stream_bandwidth_in_kbps(uint32_t pix_clk_100hz, uint32_t 
bpp_x16)
+{
+       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);
+}
+
+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)
 {
        uint32_t bpc = 0;
 
@@ -967,13 +928,15 @@ void dc_dsc_get_policy_for_timing(const struct 
dc_crtc_timing *timing, uint32_t
                return;
        }
 
+       policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16;
+
        /* internal upper limit, default 16 bpp */
        if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit)
                policy->max_target_bpp = dsc_policy_max_target_bpp_limit;
 
        /* apply override */
-       if (max_target_bpp_limit_override && policy->max_target_bpp > 
max_target_bpp_limit_override)
-               policy->max_target_bpp = max_target_bpp_limit_override;
+       if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > 
max_target_bpp_limit_override_x16 / 16)
+               policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16;
 
        /* enable DSC when not needed, default false */
        if (dsc_policy_enable_dsc_when_not_needed)
-- 
2.29.0

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

Reply via email to