diff options
author | Daniel Miess <daniel.miess@amd.com> | 2023-09-27 15:21:53 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2023-10-09 16:51:21 -0400 |
commit | cbe069f5e60f6c64944d65a2676fec23769bd189 (patch) | |
tree | 24b697a075abd8af5364fb69814e14e1a6f606b0 | |
parent | ba85d293a30e358abe9740ac0c945211066e4273 (diff) |
drm/amd/display: Port replay vblank logic to DML2
Update DML2 with replay vblank logic found in DML1.
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Qingqing Zhuo <qingqing.zhuo@amd.com>
Signed-off-by: Daniel Miess <daniel.miess@amd.com>
Signed-off-by: Qingqing Zhuo <Qingqing.Zhuo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c | 25 |
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c index 0d446d850313..fddd52f3f601 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/display_mode_core.c @@ -6153,6 +6153,13 @@ static void CalculateImmediateFlipBandwithSupport( #endif } +static dml_uint_t MicroSecToVertLines(dml_uint_t num_us, dml_uint_t h_total, dml_float_t pixel_clock) +{ + dml_uint_t lines_time_in_ns = 1000.0 * (h_total * 1000.0) / (pixel_clock * 1000.0); + + return dml_ceil(1000.0 * num_us / lines_time_in_ns, 1.0); +} + /// @brief Calculate the maximum vstartup for mode support and mode programming consideration /// Bounded by min of actual vblank and input vblank_nom, dont want vstartup/ready to start too early if actual vbllank is huge static dml_uint_t CalculateMaxVStartup( @@ -6164,12 +6171,24 @@ static dml_uint_t CalculateMaxVStartup( { dml_uint_t vblank_size = 0; dml_uint_t max_vstartup_lines = 0; + const dml_uint_t max_allowed_vblank_nom = 1023; dml_float_t line_time_us = (dml_float_t) timing->HTotal[plane_idx] / timing->PixelClock[plane_idx]; dml_uint_t vblank_actual = timing->VTotal[plane_idx] - timing->VActive[plane_idx]; - dml_uint_t vblank_nom_default_in_line = (dml_uint_t) dml_floor((dml_float_t) vblank_nom_default_us/line_time_us, 1.0); - dml_uint_t vblank_nom_input = (dml_uint_t) dml_min(timing->VBlankNom[plane_idx], vblank_nom_default_in_line); - dml_uint_t vblank_avail = (vblank_nom_input == 0) ? vblank_nom_default_in_line : vblank_nom_input; + + dml_uint_t vblank_nom_default_in_line = MicroSecToVertLines(vblank_nom_default_us, timing->HTotal[plane_idx], + timing->PixelClock[plane_idx]); + dml_uint_t vblank_nom_input = (dml_uint_t)dml_min(vblank_actual, vblank_nom_default_in_line); + + // vblank_nom should not be smaller than (VSync (VTotal - VActive - VFrontPorch) + 2) + // + 2 is because + // 1 -> VStartup_start should be 1 line before VSync + // 1 -> always reserve 1 line between start of VBlank to VStartup signal + dml_uint_t vblank_nom_vsync_capped = dml_max(vblank_nom_input, + timing->VTotal[plane_idx] - timing->VActive[plane_idx] - timing->VFrontPorch[plane_idx] + 2); + dml_uint_t vblank_nom_max_allowed_capped = dml_min(vblank_nom_vsync_capped, max_allowed_vblank_nom); + dml_uint_t vblank_avail = (vblank_nom_max_allowed_capped == 0) ? + vblank_nom_default_in_line : vblank_nom_max_allowed_capped; vblank_size = (dml_uint_t) dml_min(vblank_actual, vblank_avail); |