summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorAlvin Lee <Alvin.Lee2@amd.com>2023-04-27 02:33:16 +0300
committerAlex Deucher <alexander.deucher@amd.com>2023-06-09 16:34:57 +0300
commit62cc621604a466ede81a125a2ed63e05695a48cc (patch)
treed903cd08f7e3afccf25963154c44237867f5cd35 /drivers/gpu/drm
parent273f47997718fc72d96e5a4a640538c00575fa7e (diff)
downloadlinux-62cc621604a466ede81a125a2ed63e05695a48cc.tar.xz
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 <Jun.Lei@amd.com> Acked-by: Alex Hung <alex.hung@amd.com> Signed-off-by: Alvin Lee <Alvin.Lee2@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c5
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc_stream.h2
-rw-r--r--drivers/gpu/drm/amd/display/dc/dml/dcn32/dcn32_fpu.c7
3 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 965b348dc8f1..c26dfdd48dd9 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 0add5ecc895f..d5b3e3a32cc6 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 826059d5b367..46fd7b68857c 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;
}