drm/amd/display: Fix possible underflow for displays with large vblank
authorjsg <jsg@openbsd.org>
Fri, 4 Aug 2023 09:10:24 +0000 (09:10 +0000)
committerjsg <jsg@openbsd.org>
Fri, 4 Aug 2023 09:10:24 +0000 (09:10 +0000)
From Daniel Miess
d5741133e6e2f304b40ca1da0e16f62af06f4d22 in linux-6.1.y/6.1.43
1a4bcdbea4319efeb26cc4b05be859a7867e02dc in mainline linux

sys/dev/pci/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c

index 395eed9..a2a32cb 100644 (file)
@@ -32,7 +32,7 @@
 #include "dml/display_mode_vba.h"
 
 struct _vcs_dpi_ip_params_st dcn3_14_ip = {
-       .VBlankNomDefaultUS = 668,
+       .VBlankNomDefaultUS = 800,
        .gpuvm_enable = 1,
        .gpuvm_max_page_table_levels = 1,
        .hostvm_enable = 1,
@@ -288,7 +288,7 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
        struct resource_context *res_ctx = &context->res_ctx;
        struct pipe_ctx *pipe;
        bool upscaled = false;
-       bool isFreesyncVideo = false;
+       const unsigned int max_allowed_vblank_nom = 1023;
 
        dc_assert_fp_enabled();
 
@@ -302,16 +302,11 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
                pipe = &res_ctx->pipe_ctx[i];
                timing = &pipe->stream->timing;
 
-               isFreesyncVideo = pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min;
-               isFreesyncVideo = isFreesyncVideo && pipe->stream->adjust.v_total_min > timing->v_total;
-
-               if (!isFreesyncVideo) {
-                       pipes[pipe_cnt].pipe.dest.vblank_nom =
-                               dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz / 10000.0));
-               } else {
-                       pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
-                       pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
-               }
+               pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
+               pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
+               pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, dcn3_14_ip.VBlankNomDefaultUS);
+               pipes[pipe_cnt].pipe.dest.vblank_nom = max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width);
+               pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom);
 
                if (pipe->plane_state &&
                                (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||