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

dc needs to expose its internal dsc policy.

Signed-off-by: Wenjing Liu <wenjing....@amd.com>
Reviewed-by: Nikola Cornij <nikola.cor...@amd.com>
Acked-by: Leo Li <sunpeng...@amd.com>
---
 drivers/gpu/drm/amd/display/dc/dc_dsc.h     |  14 ++-
 drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 103 ++++++++++++--------
 2 files changed, 75 insertions(+), 42 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/dc/dc_dsc.h 
b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
index d98b89bad353..8ec09813ee17 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_dsc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_dsc.h
@@ -45,6 +45,14 @@ struct display_stream_compressor {
        int inst;
 };
 
+struct dc_dsc_policy {
+       bool use_min_slices_h;
+       int max_slices_h; // Maximum available if 0
+       int min_slice_height; // Must not be less than 8
+       uint32_t max_target_bpp;
+       uint32_t min_target_bpp;
+};
+
 bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data,
                const uint8_t *dpcd_dsc_ext_data,
                struct dsc_dec_dpcd_caps *dsc_sink_caps);
@@ -66,7 +74,7 @@ bool dc_dsc_compute_config(
                const struct dc_crtc_timing *timing,
                struct dc_dsc_config *dsc_cfg);
 
-bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc,
-               uint32_t *min_bpp,
-               uint32_t *max_bpp);
+void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
+               struct dc_dsc_policy *policy);
+
 #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 febae6cc7295..d2423ad1fac2 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
@@ -27,19 +27,6 @@
 #include <drm/drm_dp_helper.h>
 #include "dc.h"
 
-struct dc_dsc_policy {
-       bool use_min_slices_h;
-       int max_slices_h; // Maximum available if 0
-       int min_sice_height; // Must not be less than 8
-};
-
-const struct dc_dsc_policy dsc_policy = {
-       .use_min_slices_h = true, // DSC Policy: Use minimum number of slices 
that fits the pixel clock
-       .max_slices_h = 0, // DSC Policy: Use max available slices (in our case 
4 for or 8, depending on the mode)
-       .min_sice_height = 108, // DSC Policy: Use slice height recommended by 
VESA DSC Spreadsheet user guide
-};
-
-
 /* This module's internal functions */
 
 static uint32_t dc_dsc_bandwidth_in_kbps_from_timing(
@@ -370,6 +357,7 @@ static void get_dsc_bandwidth_range(
  *        or if it couldn't be applied based on DSC policy.
  */
 static bool decide_dsc_target_bpp_x16(
+               const struct dc_dsc_policy *policy,
                const struct dsc_enc_caps *dsc_common_caps,
                const int target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
@@ -377,13 +365,10 @@ static bool decide_dsc_target_bpp_x16(
 {
        bool should_use_dsc = false;
        struct dc_dsc_bw_range range;
-       uint32_t min_target_bpp = 0;
-       uint32_t max_target_bpp = 0;
 
        memset(&range, 0, sizeof(range));
 
-       dc_dsc_get_bpp_range_for_pixel_encoding(timing->pixel_encoding, 
&min_target_bpp, &max_target_bpp);
-       get_dsc_bandwidth_range(min_target_bpp, max_target_bpp,
+       get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp,
                        dsc_common_caps, timing, &range);
        if (target_bandwidth_kbps >= range.stream_kbps) {
                /* enough bandwidth without dsc */
@@ -579,9 +564,11 @@ static bool setup_dsc_config(
        bool is_dsc_possible = false;
        int pic_height;
        int slice_height;
+       struct dc_dsc_policy policy;
 
        memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
 
+       dc_dsc_get_policy_for_timing(timing, &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;
 
@@ -597,7 +584,12 @@ static bool setup_dsc_config(
                goto done;
 
        if (target_bandwidth_kbps > 0) {
-               is_dsc_possible = decide_dsc_target_bpp_x16(&dsc_common_caps, 
target_bandwidth_kbps, timing, &target_bpp);
+               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)
@@ -699,20 +691,20 @@ static bool setup_dsc_config(
        if (!is_dsc_possible)
                goto done;
 
-       if (dsc_policy.use_min_slices_h) {
+       if (policy.use_min_slices_h) {
                if (min_slices_h > 0)
                        num_slices_h = min_slices_h;
                else if (max_slices_h > 0) { // Fall back to max slices if min 
slices is not working out
-                       if (dsc_policy.max_slices_h)
-                               num_slices_h = min(dsc_policy.max_slices_h, 
max_slices_h);
+                       if (policy.max_slices_h)
+                               num_slices_h = min(policy.max_slices_h, 
max_slices_h);
                        else
                                num_slices_h = max_slices_h;
                } else
                        is_dsc_possible = false;
        } else {
                if (max_slices_h > 0) {
-                       if (dsc_policy.max_slices_h)
-                               num_slices_h = min(dsc_policy.max_slices_h, 
max_slices_h);
+                       if (policy.max_slices_h)
+                               num_slices_h = min(policy.max_slices_h, 
max_slices_h);
                        else
                                num_slices_h = max_slices_h;
                } else if (min_slices_h > 0) // Fall back to min slices if max 
slices is not possible
@@ -734,7 +726,7 @@ static bool setup_dsc_config(
        // Slice height (i.e. number of slices per column): start with policy 
and pick the first one that height is divisible by.
        // For 4:2:0 make sure the slice height is divisible by 2 as well.
        if (min_slice_height_override == 0)
-               slice_height = min(dsc_policy.min_sice_height, pic_height);
+               slice_height = min(policy.min_slice_height, pic_height);
        else
                slice_height = min(min_slice_height_override, pic_height);
 
@@ -905,28 +897,61 @@ bool dc_dsc_compute_config(
        return is_dsc_possible;
 }
 
-bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc,
-               uint32_t *min_bpp,
-               uint32_t *max_bpp)
+void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, struct 
dc_dsc_policy *policy)
 {
-       bool result = true;
+       uint32_t bpc = 0;
+
+       policy->min_target_bpp = 0;
+       policy->max_target_bpp = 0;
+
+       /* DSC Policy: Use minimum number of slices that fits the pixel clock */
+       policy->use_min_slices_h = true;
 
-       switch (pixel_enc) {
+       /* DSC Policy: Use max available slices
+        * (in our case 4 for or 8, depending on the mode)
+        */
+       policy->max_slices_h = 0;
+
+       /* DSC Policy: Use slice height recommended
+        * by VESA DSC Spreadsheet user guide
+        */
+       policy->min_slice_height = 108;
+
+       /* DSC Policy: follow DP specs with an internal upper limit to 16 bpp
+        * for better interoperability
+        */
+       switch (timing->display_color_depth) {
+       case COLOR_DEPTH_888:
+               bpc = 8;
+               break;
+       case COLOR_DEPTH_101010:
+               bpc = 10;
+               break;
+       case COLOR_DEPTH_121212:
+               bpc = 12;
+               break;
+       default:
+               return;
+       }
+       switch (timing->pixel_encoding) {
        case PIXEL_ENCODING_RGB:
        case PIXEL_ENCODING_YCBCR444:
-       case PIXEL_ENCODING_YCBCR422:
-               *min_bpp = 8;
-               *max_bpp = 16;
+       case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */
+               /* DP specs limits to 8 */
+               policy->min_target_bpp = 8;
+               /* DP specs limits to 3 x bpc */
+               policy->max_target_bpp = 3 * bpc;
                break;
        case PIXEL_ENCODING_YCBCR420:
-               *min_bpp = 6;
-               *max_bpp = 16;
+               /* DP specs limits to 6 */
+               policy->min_target_bpp = 6;
+               /* DP specs limits to 1.5 x bpc assume bpc is an even number */
+               policy->max_target_bpp = bpc * 3 / 2;
                break;
        default:
-               *min_bpp = 0;
-               *max_bpp = 0;
-               result = false;
+               return;
        }
-
-       return result;
+       /* internal upper limit to 16 bpp */
+       if (policy->max_target_bpp > 16)
+               policy->max_target_bpp = 16;
 }
-- 
2.24.0

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

Reply via email to