Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix possible underflow for displays with large vblank

[Why]
Underflow observed when using a display with a large vblank region
and low refresh rate

[How]
Simplify calculation of vblank_nom

Increase value for VBlankNomDefaultUS to 800us

Fixed a null pointer from previous commit of this change

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Acked-by: Tom Chung <chiahsuan.chung@amd.com>
Signed-off-by: Daniel Miess <daniel.miess@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Daniel Miess and committed by
Alex Deucher
de231189 c02b0463

+7 -12
+7 -12
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
··· 33 33 #include "dml/display_mode_vba.h" 34 34 35 35 struct _vcs_dpi_ip_params_st dcn3_14_ip = { 36 - .VBlankNomDefaultUS = 668, 36 + .VBlankNomDefaultUS = 800, 37 37 .gpuvm_enable = 1, 38 38 .gpuvm_max_page_table_levels = 1, 39 39 .hostvm_enable = 1, ··· 286 286 struct resource_context *res_ctx = &context->res_ctx; 287 287 struct pipe_ctx *pipe; 288 288 bool upscaled = false; 289 - bool isFreesyncVideo = false; 289 + const unsigned int max_allowed_vblank_nom = 1023; 290 290 291 291 dc_assert_fp_enabled(); 292 292 ··· 300 300 pipe = &res_ctx->pipe_ctx[i]; 301 301 timing = &pipe->stream->timing; 302 302 303 - isFreesyncVideo = pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min; 304 - isFreesyncVideo = isFreesyncVideo && pipe->stream->adjust.v_total_min > timing->v_total; 305 - 306 - if (!isFreesyncVideo) { 307 - pipes[pipe_cnt].pipe.dest.vblank_nom = 308 - dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz / 10000.0)); 309 - } else { 310 - pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; 311 - pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; 312 - } 303 + pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min; 304 + pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive; 305 + pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, dcn3_14_ip.VBlankNomDefaultUS); 306 + pipes[pipe_cnt].pipe.dest.vblank_nom = max(pipes[pipe_cnt].pipe.dest.vblank_nom, timing->v_sync_width); 307 + pipes[pipe_cnt].pipe.dest.vblank_nom = min(pipes[pipe_cnt].pipe.dest.vblank_nom, max_allowed_vblank_nom); 313 308 314 309 if (pipe->plane_state && 315 310 (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||