drm/amd/display: Add height granularity limitation for dsc slice height calculation
authorMike Hsieh <Mike.Hsieh@amd.com>
Tue, 10 Jan 2023 02:52:03 +0000 (10:52 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 7 Mar 2023 19:22:39 +0000 (14:22 -0500)
[WHY]
eDP add new limitation for Y granularity for selected update feature.
DSC does not include this limitation while calculating slice height.

[HOW]
Add new limitation while looking for DSC slice height.

Reviewed-by: Cruise Hung <Cruise.Hung@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Mike Hsieh <Mike.Hsieh@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/dc_dsc.h
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

index 824cfc4a0293fa4dfe82f18cc7352c0a54b0922d..7f627ab43a2934060509fdc728b5f4202fa6d71b 100644 (file)
@@ -5786,6 +5786,10 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
        struct dc *dc = sink->ctx->dc;
        struct dc_dsc_bw_range bw_range = {0};
        struct dc_dsc_config dsc_cfg = {0};
+       struct dc_dsc_config_options dsc_options = {0};
+
+       dc_dsc_get_default_config_option(dc, &dsc_options);
+       dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;
 
        verified_link_cap = dc_link_get_link_cap(stream->link);
        link_bw_in_kbps = dc_link_bandwidth_kbps(stream->link, verified_link_cap);
@@ -5808,8 +5812,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
                if (bw_range.max_kbps < link_bw_in_kbps) {
                        if (dc_dsc_compute_config(dc->res_pool->dscs[0],
                                        dsc_caps,
-                                       dc->debug.dsc_min_slice_height_override,
-                                       max_dsc_target_bpp_limit_override,
+                                       &dsc_options,
                                        0,
                                        &stream->timing,
                                        &dsc_cfg)) {
@@ -5823,8 +5826,7 @@ static void apply_dsc_policy_for_edp(struct amdgpu_dm_connector *aconnector,
 
        if (dc_dsc_compute_config(dc->res_pool->dscs[0],
                                dsc_caps,
-                               dc->debug.dsc_min_slice_height_override,
-                               max_dsc_target_bpp_limit_override,
+                               &dsc_options,
                                link_bw_in_kbps,
                                &stream->timing,
                                &dsc_cfg)) {
@@ -5845,6 +5847,10 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
        u32 dsc_max_supported_bw_in_kbps;
        u32 max_dsc_target_bpp_limit_override =
                drm_connector->display_info.max_dsc_bpp;
+       struct dc_dsc_config_options dsc_options = {0};
+
+       dc_dsc_get_default_config_option(dc, &dsc_options);
+       dsc_options.max_target_bpp_limit_override_x16 = max_dsc_target_bpp_limit_override * 16;
 
        link_bandwidth_kbps = dc_link_bandwidth_kbps(aconnector->dc_link,
                                                        dc_link_get_link_cap(aconnector->dc_link));
@@ -5863,8 +5869,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
                if (sink->link->dpcd_caps.dongle_type == DISPLAY_DONGLE_NONE) {
                        if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
                                                dsc_caps,
-                                               aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
-                                               max_dsc_target_bpp_limit_override,
+                                               &dsc_options,
                                                link_bandwidth_kbps,
                                                &stream->timing,
                                                &stream->timing.dsc_cfg)) {
@@ -5881,8 +5886,7 @@ static void apply_dsc_policy_for_stream(struct amdgpu_dm_connector *aconnector,
                                        dsc_max_supported_bw_in_kbps > 0)
                                if (dc_dsc_compute_config(aconnector->dc_link->ctx->dc->res_pool->dscs[0],
                                                dsc_caps,
-                                               aconnector->dc_link->ctx->dc->debug.dsc_min_slice_height_override,
-                                               max_dsc_target_bpp_limit_override,
+                                               &dsc_options,
                                                dsc_max_supported_bw_in_kbps,
                                                &stream->timing,
                                                &stream->timing.dsc_cfg)) {
index e25e1b2bf19493b747a623269bb6b967936592d7..e10ed293597124ddb9fff043ebac6d9a28fe2765 100644 (file)
@@ -678,16 +678,19 @@ static void set_dsc_configs_from_fairness_vars(struct dsc_mst_fairness_params *p
 {
        struct drm_connector *drm_connector;
        int i;
+       struct dc_dsc_config_options dsc_options = {0};
 
        for (i = 0; i < count; i++) {
                drm_connector = &params[i].aconnector->base;
 
+               dc_dsc_get_default_config_option(params[i].sink->ctx->dc, &dsc_options);
+               dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
+
                memset(&params[i].timing->dsc_cfg, 0, sizeof(params[i].timing->dsc_cfg));
                if (vars[i + k].dsc_enabled && dc_dsc_compute_config(
                                        params[i].sink->ctx->dc->res_pool->dscs[0],
                                        &params[i].sink->dsc_caps.dsc_dec_caps,
-                                       params[i].sink->ctx->dc->debug.dsc_min_slice_height_override,
-                                       drm_connector->display_info.max_dsc_bpp,
+                                       &dsc_options,
                                        0,
                                        params[i].timing,
                                        &params[i].timing->dsc_cfg)) {
@@ -730,15 +733,16 @@ static int bpp_x16_from_pbn(struct dsc_mst_fairness_params param, int pbn)
        u64 kbps;
 
        struct drm_connector *drm_connector = &param.aconnector->base;
-       uint32_t max_dsc_target_bpp_limit_override =
-               drm_connector->display_info.max_dsc_bpp;
+       struct dc_dsc_config_options dsc_options = {0};
+
+       dc_dsc_get_default_config_option(param.sink->ctx->dc, &dsc_options);
+       dsc_options.max_target_bpp_limit_override_x16 = drm_connector->display_info.max_dsc_bpp * 16;
 
        kbps = div_u64((u64)pbn * 994 * 8 * 54, 64);
        dc_dsc_compute_config(
                        param.sink->ctx->dc->res_pool->dscs[0],
                        &param.sink->dsc_caps.dsc_dec_caps,
-                       param.sink->ctx->dc->debug.dsc_min_slice_height_override,
-                       max_dsc_target_bpp_limit_override,
+                       &dsc_options,
                        (int) kbps, param.timing, &dsc_config);
 
        return dsc_config.bits_per_pixel;
index 684713b2cff7433c7ea424cb419f2564a3c658f6..81e62a630d78bc34bebadff0e0987ea8837c5956 100644 (file)
@@ -54,6 +54,12 @@ struct dc_dsc_policy {
        bool enable_dsc_when_not_needed;
 };
 
+struct dc_dsc_config_options {
+       uint32_t dsc_min_slice_height_override;
+       uint32_t max_target_bpp_limit_override_x16;
+       uint32_t slight_height_granularity;
+};
+
 bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
                const uint8_t *dpcd_dsc_basic_data,
                const uint8_t *dpcd_dsc_ext_data,
@@ -71,8 +77,7 @@ bool dc_dsc_compute_bandwidth_range(
 bool dc_dsc_compute_config(
                const struct display_stream_compressor *dsc,
                const struct dsc_dec_dpcd_caps *dsc_sink_caps,
-               uint32_t dsc_min_slice_height_override,
-               uint32_t max_target_bpp_limit_override,
+               const struct dc_dsc_config_options *options,
                uint32_t target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
                struct dc_dsc_config *dsc_cfg);
@@ -100,4 +105,6 @@ void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);
 
 void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable);
 
+void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options);
+
 #endif
index d52cbc0e9b6799047eeff793974e8b136332f59b..8b5663853efb6fbcff9204d75057c44f926dafa6 100644 (file)
@@ -79,8 +79,7 @@ static bool setup_dsc_config(
                const struct dsc_enc_caps *dsc_enc_caps,
                int target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
-               int min_slice_height_override,
-               int max_dsc_target_bpp_limit_override_x16,
+               const struct dc_dsc_config_options *options,
                struct dc_dsc_config *dsc_cfg);
 
 static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size)
@@ -352,6 +351,11 @@ bool dc_dsc_compute_bandwidth_range(
        struct dsc_enc_caps dsc_enc_caps;
        struct dsc_enc_caps dsc_common_caps;
        struct dc_dsc_config config;
+       struct dc_dsc_config_options options = {0};
+
+       options.dsc_min_slice_height_override = dsc_min_slice_height_override;
+       options.max_target_bpp_limit_override_x16 = max_bpp_x16;
+       options.slight_height_granularity = 1;
 
        get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz);
 
@@ -360,7 +364,7 @@ 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_x16, &config);
+                               &options, &config);
 
        if (is_dsc_possible)
                is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
@@ -740,8 +744,7 @@ static bool setup_dsc_config(
                const struct dsc_enc_caps *dsc_enc_caps,
                int target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
-               int min_slice_height_override,
-               int max_dsc_target_bpp_limit_override_x16,
+               const struct dc_dsc_config_options *options,
                struct dc_dsc_config *dsc_cfg)
 {
        struct dsc_enc_caps dsc_common_caps;
@@ -760,7 +763,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_x16, &policy);
+       dc_dsc_get_policy_for_timing(timing, options->max_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;
 
@@ -909,12 +912,13 @@ 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)
+       if (options->dsc_min_slice_height_override == 0)
                slice_height = min(policy.min_slice_height, pic_height);
        else
-               slice_height = min(min_slice_height_override, pic_height);
+               slice_height = min((int)(options->dsc_min_slice_height_override), pic_height);
 
        while (slice_height < pic_height && (pic_height % slice_height != 0 ||
+               slice_height % options->slight_height_granularity != 0 ||
                (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0)))
                slice_height++;
 
@@ -958,8 +962,7 @@ done:
 bool dc_dsc_compute_config(
                const struct display_stream_compressor *dsc,
                const struct dsc_dec_dpcd_caps *dsc_sink_caps,
-               uint32_t dsc_min_slice_height_override,
-               uint32_t max_target_bpp_limit_override,
+               const struct dc_dsc_config_options *options,
                uint32_t target_bandwidth_kbps,
                const struct dc_crtc_timing *timing,
                struct dc_dsc_config *dsc_cfg)
@@ -971,8 +974,7 @@ bool dc_dsc_compute_config(
        is_dsc_possible = setup_dsc_config(dsc_sink_caps,
                &dsc_enc_caps,
                target_bandwidth_kbps,
-               timing, dsc_min_slice_height_override,
-               max_target_bpp_limit_override * 16, dsc_cfg);
+               timing, options, dsc_cfg);
        return is_dsc_possible;
 }
 
@@ -1104,3 +1106,10 @@ void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
 {
        dsc_policy_disable_dsc_stream_overhead = disable;
 }
+
+void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options)
+{
+       options->dsc_min_slice_height_override = dc->debug.dsc_min_slice_height_override;
+       options->max_target_bpp_limit_override_x16 = 0;
+       options->slight_height_granularity = 1;
+}