drm/amd/display: Avoid setting pixel rate divider to N/A
authorTaimur Hassan <Syed.Hassan@amd.com>
Fri, 11 Nov 2022 19:11:00 +0000 (14:11 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 23 Nov 2022 14:01:53 +0000 (09:01 -0500)
[Why]
Pixel rate divider values should never be set to N/A (0xF) as the K1/K2
field is only 1/2 bits wide.

[How]
Set valid divider values for virtual and FRL/DP2 cases.

Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Brian Chang <Brian.Chang@amd.com>
Signed-off-by: Taimur Hassan <Syed.Hassan@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_dccg.c
drivers/gpu/drm/amd/display/dc/dcn314/dcn314_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c

index 1bd7e0f..389a893 100644 (file)
@@ -96,6 +96,13 @@ static void dccg314_set_pixel_rate_div(
        struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg);
        enum pixel_rate_div cur_k1 = PIXEL_RATE_DIV_NA, cur_k2 = PIXEL_RATE_DIV_NA;
 
+       // Don't program 0xF into the register field. Not valid since
+       // K1 / K2 field is only 1 / 2 bits wide
+       if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
+               BREAK_TO_DEBUGGER();
+               return;
+       }
+
        dccg314_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
        if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA || (k1 == cur_k1 && k2 == cur_k2))
                return;
index 588c1c7..a074179 100644 (file)
@@ -348,10 +348,8 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
        two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
        odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
-       if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
-               return odm_combine_factor;
-
        if (is_dp_128b_132b_signal(pipe_ctx)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
                *k2_div = PIXEL_RATE_DIV_BY_1;
        } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
                *k1_div = PIXEL_RATE_DIV_BY_1;
@@ -359,7 +357,7 @@ unsigned int dcn314_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsig
                        *k2_div = PIXEL_RATE_DIV_BY_2;
                else
                        *k2_div = PIXEL_RATE_DIV_BY_4;
-       } else if (dc_is_dp_signal(pipe_ctx->stream->signal)) {
+       } else if (dc_is_dp_signal(pipe_ctx->stream->signal) || dc_is_virtual_signal(pipe_ctx->stream->signal)) {
                if (two_pix_per_container) {
                        *k1_div = PIXEL_RATE_DIV_BY_1;
                        *k2_div = PIXEL_RATE_DIV_BY_2;
index e4daed4..df4f251 100644 (file)
@@ -96,8 +96,10 @@ static void dccg32_set_pixel_rate_div(
 
        // Don't program 0xF into the register field. Not valid since
        // K1 / K2 field is only 1 / 2 bits wide
-       if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA)
+       if (k1 == PIXEL_RATE_DIV_NA || k2 == PIXEL_RATE_DIV_NA) {
+               BREAK_TO_DEBUGGER();
                return;
+       }
 
        dccg32_get_pixel_rate_div(dccg, otg_inst, &cur_k1, &cur_k2);
        if (k1 == cur_k1 && k2 == cur_k2)
index ac41a76..d0b46a3 100644 (file)
@@ -1171,10 +1171,8 @@ unsigned int dcn32_calculate_dccg_k1_k2_values(struct pipe_ctx *pipe_ctx, unsign
        two_pix_per_container = optc2_is_two_pixels_per_containter(&stream->timing);
        odm_combine_factor = get_odm_config(pipe_ctx, NULL);
 
-       if (pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
-               return odm_combine_factor;
-
        if (is_dp_128b_132b_signal(pipe_ctx)) {
+               *k1_div = PIXEL_RATE_DIV_BY_1;
                *k2_div = PIXEL_RATE_DIV_BY_1;
        } else if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal) || dc_is_dvi_signal(pipe_ctx->stream->signal)) {
                *k1_div = PIXEL_RATE_DIV_BY_1;