From: Alvin Lee Date: Wed, 26 Apr 2023 23:33:16 +0000 (-0400) Subject: drm/amd/display: Check Vactive for VRR active for FPO + Vactive X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=62cc621604a466ede81a125a2ed63e05695a48cc;p=linux.git drm/amd/display: Check Vactive for VRR active for FPO + Vactive [Description] - For FPO + Vactive cases, we rely on the Vactive display to be at it's nominal refresh rate because the Vactive pipe may not necessarily assert P-State allow while it's in VBLANK - For cases where the Vactive display has a stretched VBLANK due to VRR, we could underflow when trying to complete an FPO + Vactive MCLK switch because the FPO display has limited VBLANK time in waiting for the Vactive display to assert P-State allow naturally - Block FPO + Vactive if the Vactive display has VRR active (variable or fixed) Reviewed-by: Jun Lei Acked-by: Alex Hung Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 965b348dc8f11..c26dfdd48dd93 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2604,7 +2604,7 @@ static enum surface_update_type check_update_surfaces_for_stream( if (stream_update->stream && stream_update->stream->freesync_on_desktop && (stream_update->vrr_infopacket || stream_update->allow_freesync || - stream_update->vrr_active_variable)) + stream_update->vrr_active_variable || stream_update->vrr_active_fixed)) su_flags->bits.fams_changed = 1; if (su_flags->raw != 0) @@ -2964,6 +2964,9 @@ static void copy_stream_update_to_stream(struct dc *dc, if (update->vrr_active_variable) stream->vrr_active_variable = *update->vrr_active_variable; + if (update->vrr_active_fixed) + stream->vrr_active_fixed = *update->vrr_active_fixed; + if (update->crtc_timing_adjust) stream->adjust = *update->crtc_timing_adjust; diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 0add5ecc895fa..d5b3e3a32cc6d 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -233,6 +233,7 @@ struct dc_stream_state { */ bool vrr_active_variable; bool freesync_on_desktop; + bool vrr_active_fixed; bool converter_disable_audio; uint8_t qs_bit; @@ -326,6 +327,7 @@ struct dc_stream_update { bool integer_scaling_update; bool *allow_freesync; bool *vrr_active_variable; + bool *vrr_active_fixed; struct colorspace_transform *gamut_remap; enum dc_color_space *output_color_space; diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c index 826059d5b3675..46fd7b68857c9 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c @@ -35,6 +35,7 @@ #define DC_LOGGER_INIT(logger) +static const unsigned int MAX_FPO_VACTIVE_BLANK_US = 600; static const struct subvp_high_refresh_list subvp_high_refresh_list = { .min_refresh = 120, .max_refresh = 165, @@ -2924,6 +2925,7 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint unsigned int i, pipe_idx; const struct vba_vars_st *vba = &context->bw_ctx.dml.vba; bool vactive_found = false; + unsigned int blank_us = 0; for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { const struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -2931,7 +2933,10 @@ bool dcn32_find_vactive_pipe(struct dc *dc, const struct dc_state *context, uint if (!pipe->stream) continue; - if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] >= vactive_margin_req_us) { + blank_us = ((pipe->stream->timing.v_total - pipe->stream->timing.v_addressable) * pipe->stream->timing.h_total / + (double)(pipe->stream->timing.pix_clk_100hz * 100)) * 1000000; + if (vba->ActiveDRAMClockChangeLatencyMarginPerState[vba->VoltageLevel][vba->maxMpcComb][vba->pipe_plane[pipe_idx]] >= vactive_margin_req_us && + !(pipe->stream->vrr_active_variable || pipe->stream->vrr_active_fixed) && blank_us < MAX_FPO_VACTIVE_BLANK_US) { vactive_found = true; break; }