aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/display/dc/core
diff options
context:
space:
mode:
authorGravatar Alvin Lee <alvin.lee2@amd.com> 2023-12-12 12:17:31 -0500
committerGravatar Alex Deucher <alexander.deucher@amd.com> 2024-01-29 15:42:02 -0500
commitfc9f47455ae143e8831415a46eab3fbc69e408aa (patch)
treeaff69bf0d05fdfdbeefdb08705363e70c3b34950 /drivers/gpu/drm/amd/display/dc/core
parentdrm/amd/display: Unify optimize_required flags and VRR adjustments (diff)
downloadlinux-fc9f47455ae143e8831415a46eab3fbc69e408aa.tar.gz
linux-fc9f47455ae143e8831415a46eab3fbc69e408aa.tar.bz2
linux-fc9f47455ae143e8831415a46eab3fbc69e408aa.zip
drm/amd/display: For FPO and SubVP/DRR configs program vmin/max sel
[Why & How] For FPO and SubVP/DRR cases we need to ensure to program OTG_V_TOTAL_MIN/MAX_SEL, otherwise stretching the vblank in FPO / SubVP / DRR cases will not have any effect and we could hit underflow / corruption. Reviewed-by: Alvin Lee <alvin.lee2@amd.com> Acked-by: Tom Chung <chiahsuan.chung@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/amd/display/dc/core')
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c31
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_resource.c14
2 files changed, 45 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 186d54205bcc..2db361aeaf25 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3481,6 +3481,33 @@ static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state
}
}
+static void update_drr_for_full_update(struct dc *dc, struct dc_state *context)
+{
+ uint32_t i;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+ struct dc_stream_state *stream = pipe->stream;
+ struct timing_generator *tg = pipe->stream_res.tg;
+ struct drr_params params = {0};
+
+ /* pipe not in use */
+ if (!resource_is_pipe_type(pipe, OTG_MASTER))
+ continue;
+
+ /* skip phantom pipes */
+ if (dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_PHANTOM)
+ continue;
+
+ params.vertical_total_min = stream->adjust.v_total_min;
+ params.vertical_total_max = stream->adjust.v_total_max;
+ params.vertical_total_mid = stream->adjust.v_total_mid;
+ params.vertical_total_mid_frame_num = stream->adjust.v_total_mid_frame_num;
+ if (pipe->stream_res.tg->funcs->set_drr)
+ tg->funcs->set_drr(pipe->stream_res.tg, &params);
+ }
+}
+
static void commit_planes_for_stream(struct dc *dc,
struct dc_surface_update *srf_updates,
int surface_count,
@@ -3848,6 +3875,10 @@ static void commit_planes_for_stream(struct dc *dc,
pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg);
}
+ // Update DRR for all pipes
+ if (update_type != UPDATE_TYPE_FAST)
+ update_drr_for_full_update(dc, context);
+
current_stream_mask = get_stream_mask(dc, context);
if (current_stream_mask != context->stream_mask) {
context->stream_mask = current_stream_mask;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
index 9fbdb09697fd..259ccbe858b4 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c
@@ -4990,6 +4990,20 @@ enum dc_status update_dp_encoder_resources_for_test_harness(const struct dc *dc,
return DC_OK;
}
+bool resource_subvp_in_use(struct dc *dc,
+ struct dc_state *context)
+{
+ uint32_t i;
+
+ for (i = 0; i < dc->res_pool->pipe_count; i++) {
+ struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+ if (dc_state_get_pipe_subvp_type(context, pipe) != SUBVP_NONE)
+ return true;
+ }
+ return false;
+}
+
bool check_subvp_sw_cursor_fallback_req(const struct dc *dc, struct dc_stream_state *stream)
{
if (!dc->debug.disable_subvp_high_refresh && is_subvp_high_refresh_candidate(stream))