]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Correct slice width calculation for YCbCr420
authorRelja Vojvodic <rvojvodi@amd.com>
Wed, 17 Sep 2025 16:30:51 +0000 (12:30 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 13 Oct 2025 18:14:31 +0000 (14:14 -0400)
[Why]
-OVT compliance testing for 5120x2880p300Hz YCbCr420 was failing due to
incorrect slice width being calculated

[How]
-Ensure slice width is divisible by 2 for 420 to comply with spec

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Relja Vojvodic <rvojvodi@amd.com>
Signed-off-by: Roman Li <roman.li@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dsc/dcn20/dcn20_dsc.c
drivers/gpu/drm/amd/display/dc/dsc/dsc.h
drivers/gpu/drm/amd/display/dc/hwss/dcn314/dcn314_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/link/link_dpms.c
drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c

index 89f0d999bf35aeb7ab7459600a46e00d71241d83..ee8c11e085cd2bbfd067c30ba56257a8abcfbe6c 100644 (file)
@@ -407,7 +407,7 @@ bool dsc_prepare_config(const struct dsc_config *dsc_cfg, struct dsc_reg_values
        dsc_reg_vals->ich_reset_at_eol = (dsc_cfg->is_odm || dsc_reg_vals->num_slices_h > 1) ? 0xF : 0;
 
        // Need to find the ceiling value for the slice width
-       dsc_reg_vals->pps.slice_width = (dsc_cfg->pic_width + dsc_cfg->dc_dsc_cfg.num_slices_h - 1) / dsc_cfg->dc_dsc_cfg.num_slices_h;
+       dsc_reg_vals->pps.slice_width = (dsc_cfg->pic_width + dsc_cfg->dsc_padding + dsc_cfg->dc_dsc_cfg.num_slices_h - 1) / dsc_cfg->dc_dsc_cfg.num_slices_h;
        // TODO: in addition to validating slice height (pic height must be divisible by slice height),
        // see what happens when the same condition doesn't apply for slice_width/pic_width.
        dsc_reg_vals->pps.slice_height = dsc_cfg->pic_height / dsc_cfg->dc_dsc_cfg.num_slices_v;
index b0bd1f9425b5c31c1bb9643d8684e7be55d69b26..b433e16842bf69d99fe38153c9df145124ab836e 100644 (file)
@@ -41,6 +41,7 @@ struct dsc_config {
        enum dc_color_depth color_depth;  /* Bits per component */
        bool is_odm;
        struct dc_dsc_config dc_dsc_cfg;
+       uint32_t dsc_padding;
 };
 
 
index f925f669f2a4da26a56f42c2e4c1cd3f7baca801..4ee6ed610de0b99270a0abd931fa5d1ae8f0429d 100644 (file)
@@ -108,6 +108,7 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
                ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
                dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
index f39292952702fab9903f39c7871543671f3b26a9..bf19ba65d09aa2d068c883912ecc1dc11e68afeb 100644 (file)
@@ -1061,6 +1061,7 @@ void dcn32_update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
                ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                if (should_use_dto_dscclk)
                        dccg->funcs->set_dto_dscclk(dccg, dsc->inst, dsc_cfg.dc_dsc_cfg.num_slices_h);
index 05011061822cf0f2a36dd898985809f9a10b3283..7ea3fe48b329e9484337660240545d800e7e4a15 100644 (file)
@@ -364,6 +364,7 @@ static void update_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
                ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                dsc->funcs->dsc_set_config(dsc, &dsc_cfg, &dsc_optc_cfg);
                dsc->funcs->dsc_enable(dsc, pipe_ctx->stream_res.opp->inst);
index 83419e1a90367c60d466eb8fb713f24d9d2b0606..dba8ec0988a1779510944e66ad938c13b14494c0 100644 (file)
@@ -841,6 +841,7 @@ void link_set_dsc_on_stream(struct pipe_ctx *pipe_ctx, bool enable)
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
                ASSERT(dsc_cfg.dc_dsc_cfg.num_slices_h % opp_cnt == 0);
                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                if (should_use_dto_dscclk)
                        dccg->funcs->set_dto_dscclk(dccg, dsc->inst, dsc_cfg.dc_dsc_cfg.num_slices_h);
@@ -970,6 +971,7 @@ bool link_set_dsc_pps_packet(struct pipe_ctx *pipe_ctx, bool enable, bool immedi
                dsc_cfg.color_depth = stream->timing.display_color_depth;
                dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                dsc->funcs->dsc_get_packed_pps(dsc, &dsc_cfg, &dsc_packed_pps[0]);
                memcpy(&stream->dsc_packed_pps[0], &dsc_packed_pps[0], sizeof(stream->dsc_packed_pps));
index 84b38d2d6967e2e8a852a5a952fa40637452cf11..f4d3ff79717fe03e39c1c7fae7d850a8da0ccaa5 100644 (file)
@@ -1668,6 +1668,7 @@ bool dcn20_validate_dsc(struct dc *dc, struct dc_state *new_ctx)
                dsc_cfg.is_odm = pipe_ctx->next_odm_pipe ? true : false;
                dsc_cfg.dc_dsc_cfg = stream->timing.dsc_cfg;
                dsc_cfg.dc_dsc_cfg.num_slices_h /= opp_cnt;
+               dsc_cfg.dsc_padding = pipe_ctx->dsc_padding_params.dsc_hactive_padding;
 
                if (!pipe_ctx->stream_res.dsc->funcs->dsc_validate_stream(pipe_ctx->stream_res.dsc, &dsc_cfg))
                        return false;