]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: extend delta clamping logic to CM3 LUT helper
authorMelissa Wen <mwen@igalia.com>
Mon, 8 Dec 2025 23:44:15 +0000 (22:44 -0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Feb 2026 15:31:33 +0000 (16:31 +0100)
[ Upstream commit d25b32aa829a3ed5570138e541a71fb7805faec3 ]

Commit 27fc10d1095f ("drm/amd/display: Fix the delta clamping for shaper
LUT") fixed banding when using plane shaper LUT in DCN10 CM helper.  The
problem is also present in DCN30 CM helper, fix banding by extending the
same bug delta clamping fix to CM3.

Signed-off-by: Melissa Wen <mwen@igalia.com>
Reviewed-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 0274a54897f356f9c78767c4a2a5863f7dde90c6)
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/gpu/drm/amd/display/dc/dcn30/dcn30_cm_common.c
drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_cm_common.h
drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c

index a4f14b16564c2f164ea1aad58b95215a50edf5b5..227aa8672d17ba048805dfc34c8e033d309db053 100644 (file)
@@ -105,9 +105,12 @@ void cm_helper_program_gamcor_xfer_func(
 #define NUMBER_REGIONS     32
 #define NUMBER_SW_SEGMENTS 16
 
-bool cm3_helper_translate_curve_to_hw_format(
-                               const struct dc_transfer_func *output_tf,
-                               struct pwl_params *lut_params, bool fixpoint)
+#define DC_LOGGER \
+               ctx->logger
+
+bool cm3_helper_translate_curve_to_hw_format(struct dc_context *ctx,
+                                            const struct dc_transfer_func *output_tf,
+                                            struct pwl_params *lut_params, bool fixpoint)
 {
        struct curve_points3 *corner_points;
        struct pwl_result_data *rgb_resulted;
@@ -251,6 +254,10 @@ bool cm3_helper_translate_curve_to_hw_format(
        if (fixpoint == true) {
                i = 1;
                while (i != hw_points + 2) {
+                       uint32_t red_clamp;
+                       uint32_t green_clamp;
+                       uint32_t blue_clamp;
+
                        if (i >= hw_points) {
                                if (dc_fixpt_lt(rgb_plus_1->red, rgb->red))
                                        rgb_plus_1->red = dc_fixpt_add(rgb->red,
@@ -263,9 +270,20 @@ bool cm3_helper_translate_curve_to_hw_format(
                                                        rgb_minus_1->delta_blue);
                        }
 
-                       rgb->delta_red_reg   = dc_fixpt_clamp_u0d10(rgb->delta_red);
-                       rgb->delta_green_reg = dc_fixpt_clamp_u0d10(rgb->delta_green);
-                       rgb->delta_blue_reg  = dc_fixpt_clamp_u0d10(rgb->delta_blue);
+                       rgb->delta_red   = dc_fixpt_sub(rgb_plus_1->red,   rgb->red);
+                       rgb->delta_green = dc_fixpt_sub(rgb_plus_1->green, rgb->green);
+                       rgb->delta_blue  = dc_fixpt_sub(rgb_plus_1->blue,  rgb->blue);
+
+                       red_clamp = dc_fixpt_clamp_u0d14(rgb->delta_red);
+                       green_clamp = dc_fixpt_clamp_u0d14(rgb->delta_green);
+                       blue_clamp = dc_fixpt_clamp_u0d14(rgb->delta_blue);
+
+                       if (red_clamp >> 10 || green_clamp >> 10 || blue_clamp >> 10)
+                               DC_LOG_ERROR("Losing delta precision while programming shaper LUT.");
+
+                       rgb->delta_red_reg   = red_clamp & 0x3ff;
+                       rgb->delta_green_reg = green_clamp & 0x3ff;
+                       rgb->delta_blue_reg  = blue_clamp & 0x3ff;
                        rgb->red_reg         = dc_fixpt_clamp_u0d14(rgb->red);
                        rgb->green_reg       = dc_fixpt_clamp_u0d14(rgb->green);
                        rgb->blue_reg        = dc_fixpt_clamp_u0d14(rgb->blue);
index b86347c9b0389d1ba18aace0c1785d953ecd9932..95f9318a54efcec083dadf8c1c30228a7bbe81ab 100644 (file)
@@ -59,7 +59,7 @@ void cm_helper_program_gamcor_xfer_func(
        const struct pwl_params *params,
        const struct dcn3_xfer_func_reg *reg);
 
-bool cm3_helper_translate_curve_to_hw_format(
+bool cm3_helper_translate_curve_to_hw_format(struct dc_context *ctx,
        const struct dc_transfer_func *output_tf,
        struct pwl_params *lut_params, bool fixpoint);
 
index e47ed5571dfdd842d286fd761d334d9fad2e0482..731645a2ab9aa7328b91ee48711a498c0d6a903b 100644 (file)
@@ -238,7 +238,7 @@ bool dcn30_set_blend_lut(
        if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
                blend_lut = &plane_state->blend_tf.pwl;
        else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
-               result = cm3_helper_translate_curve_to_hw_format(
+               result = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
                                &plane_state->blend_tf, &dpp_base->regamma_params, false);
                if (!result)
                        return result;
@@ -333,8 +333,9 @@ bool dcn30_set_input_transfer_func(struct dc *dc,
        if (plane_state->in_transfer_func.type == TF_TYPE_HWPWL)
                params = &plane_state->in_transfer_func.pwl;
        else if (plane_state->in_transfer_func.type == TF_TYPE_DISTRIBUTED_POINTS &&
-               cm3_helper_translate_curve_to_hw_format(&plane_state->in_transfer_func,
-                               &dpp_base->degamma_params, false))
+               cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                       &plane_state->in_transfer_func,
+                                                       &dpp_base->degamma_params, false))
                params = &dpp_base->degamma_params;
 
        result = dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
@@ -405,7 +406,7 @@ bool dcn30_set_output_transfer_func(struct dc *dc,
                                params = &stream->out_transfer_func.pwl;
                        else if (pipe_ctx->stream->out_transfer_func.type ==
                                        TF_TYPE_DISTRIBUTED_POINTS &&
-                                       cm3_helper_translate_curve_to_hw_format(
+                                       cm3_helper_translate_curve_to_hw_format(stream->ctx,
                                        &stream->out_transfer_func,
                                        &mpc->blender_params, false))
                                params = &mpc->blender_params;
index f39292952702fab9903f39c7871543671f3b26a9..30bb5d8d85dc273f12aa808c16ddc82c33ac9919 100644 (file)
@@ -486,8 +486,9 @@ bool dcn32_set_mcm_luts(
        if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
                lut_params = &plane_state->blend_tf.pwl;
        else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
-               result = cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
-                               &dpp_base->regamma_params, false);
+               result = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                                &plane_state->blend_tf,
+                                                                &dpp_base->regamma_params, false);
                if (!result)
                        return result;
 
@@ -502,8 +503,9 @@ bool dcn32_set_mcm_luts(
        else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
                // TODO: dpp_base replace
                ASSERT(false);
-               cm3_helper_translate_curve_to_hw_format(&plane_state->in_shaper_func,
-                               &dpp_base->shaper_params, true);
+               cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                       &plane_state->in_shaper_func,
+                                                       &dpp_base->shaper_params, true);
                lut_params = &dpp_base->shaper_params;
        }
 
@@ -543,8 +545,9 @@ bool dcn32_set_input_transfer_func(struct dc *dc,
        if (plane_state->in_transfer_func.type == TF_TYPE_HWPWL)
                params = &plane_state->in_transfer_func.pwl;
        else if (plane_state->in_transfer_func.type == TF_TYPE_DISTRIBUTED_POINTS &&
-               cm3_helper_translate_curve_to_hw_format(&plane_state->in_transfer_func,
-                               &dpp_base->degamma_params, false))
+               cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                       &plane_state->in_transfer_func,
+                                                       &dpp_base->degamma_params, false))
                params = &dpp_base->degamma_params;
 
        dpp_base->funcs->dpp_program_gamcor_lut(dpp_base, params);
@@ -575,7 +578,7 @@ bool dcn32_set_output_transfer_func(struct dc *dc,
                                params = &stream->out_transfer_func.pwl;
                        else if (pipe_ctx->stream->out_transfer_func.type ==
                                        TF_TYPE_DISTRIBUTED_POINTS &&
-                                       cm3_helper_translate_curve_to_hw_format(
+                                       cm3_helper_translate_curve_to_hw_format(stream->ctx,
                                        &stream->out_transfer_func,
                                        &mpc->blender_params, false))
                                params = &mpc->blender_params;
index 68e48a2492c9ee94b9d4150c0c1c9a7b09886084..77cdd02a41bdd0096549fb1ff0f39767c31d36e4 100644 (file)
@@ -427,7 +427,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
                if (mcm_luts.lut1d_func->type == TF_TYPE_HWPWL)
                        m_lut_params.pwl = &mcm_luts.lut1d_func->pwl;
                else if (mcm_luts.lut1d_func->type == TF_TYPE_DISTRIBUTED_POINTS) {
-                       rval = cm3_helper_translate_curve_to_hw_format(
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
                                        mcm_luts.lut1d_func,
                                        &dpp_base->regamma_params, false);
                        m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
@@ -447,7 +447,7 @@ void dcn401_populate_mcm_luts(struct dc *dc,
                        m_lut_params.pwl = &mcm_luts.shaper->pwl;
                else if (mcm_luts.shaper->type == TF_TYPE_DISTRIBUTED_POINTS) {
                        ASSERT(false);
-                       rval = cm3_helper_translate_curve_to_hw_format(
+                       rval = cm3_helper_translate_curve_to_hw_format(mpc->ctx,
                                        mcm_luts.shaper,
                                        &dpp_base->regamma_params, true);
                        m_lut_params.pwl = rval ? &dpp_base->regamma_params : NULL;
@@ -624,8 +624,9 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
        if (plane_state->blend_tf.type == TF_TYPE_HWPWL)
                lut_params = &plane_state->blend_tf.pwl;
        else if (plane_state->blend_tf.type == TF_TYPE_DISTRIBUTED_POINTS) {
-               rval = cm3_helper_translate_curve_to_hw_format(&plane_state->blend_tf,
-                               &dpp_base->regamma_params, false);
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                              &plane_state->blend_tf,
+                                                              &dpp_base->regamma_params, false);
                lut_params = rval ? &dpp_base->regamma_params : NULL;
        }
        result = mpc->funcs->program_1dlut(mpc, lut_params, mpcc_id);
@@ -636,8 +637,9 @@ bool dcn401_set_mcm_luts(struct pipe_ctx *pipe_ctx,
                lut_params = &plane_state->in_shaper_func.pwl;
        else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) {
                // TODO: dpp_base replace
-               rval = cm3_helper_translate_curve_to_hw_format(&plane_state->in_shaper_func,
-                               &dpp_base->shaper_params, true);
+               rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx,
+                                                              &plane_state->in_shaper_func,
+                                                              &dpp_base->shaper_params, true);
                lut_params = rval ? &dpp_base->shaper_params : NULL;
        }
        result &= mpc->funcs->program_shaper(mpc, lut_params, mpcc_id);
@@ -671,7 +673,7 @@ bool dcn401_set_output_transfer_func(struct dc *dc,
                                params = &stream->out_transfer_func.pwl;
                        else if (pipe_ctx->stream->out_transfer_func.type ==
                                        TF_TYPE_DISTRIBUTED_POINTS &&
-                                       cm3_helper_translate_curve_to_hw_format(
+                                       cm3_helper_translate_curve_to_hw_format(stream->ctx,
                                        &stream->out_transfer_func,
                                        &mpc->blender_params, false))
                                params = &mpc->blender_params;