summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMuaaz Nisar <muanisar@amd.com>2025-12-19 00:03:44 +0300
committerAlex Deucher <alexander.deucher@amd.com>2026-02-23 22:39:31 +0300
commit29c9087b96c6dc92660f0dcff4e7e67eda40cf46 (patch)
treeb2a8ef36fd7257f0375b5a4694a86fab1ddacd96
parentff374446c18fc564a0850d9207f23eee6b39e478 (diff)
downloadlinux-29c9087b96c6dc92660f0dcff4e7e67eda40cf46.tar.xz
drm/amd/display: Add Visual Confirm Support for Testing
[WHY+HOW] Adding visual confirm to visually track changes in refresh rate. Reviewed-by: Aric Cyr <aric.cyr@amd.com> Signed-off-by: Muaaz Nisar <muanisar@amd.com> Signed-off-by: Ivan Lipski <ivan.lipski@amd.com> Tested-by: Dan Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc.c148
-rw-r--r--drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c21
-rw-r--r--drivers/gpu/drm/amd/display/dc/dc.h1
-rw-r--r--drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h4
4 files changed, 105 insertions, 69 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c
index 76b5be1371ed..615bf2a01389 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -443,75 +443,6 @@ static bool set_long_vtotal(struct dc *dc, struct dc_stream_state *stream, struc
}
/**
- * dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
- * @dc: dc reference
- * @stream: Initial dc stream state
- * @adjust: Updated parameters for vertical_total_min and vertical_total_max
- *
- * Looks up the pipe context of dc_stream_state and updates the
- * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
- * Rate, which is a power-saving feature that targets reducing panel
- * refresh rate while the screen is static
- *
- * Return: %true if the pipe context is found and adjusted;
- * %false if the pipe context is not found.
- */
-bool dc_stream_adjust_vmin_vmax(struct dc *dc,
- struct dc_stream_state *stream,
- struct dc_crtc_timing_adjust *adjust)
-{
- int i;
-
- /*
- * Don't adjust DRR while there's bandwidth optimizations pending to
- * avoid conflicting with firmware updates.
- */
- if (dc->ctx->dce_version > DCE_VERSION_MAX) {
- if (dc->optimized_required &&
- (stream->adjust.v_total_max != adjust->v_total_max ||
- stream->adjust.v_total_min != adjust->v_total_min)) {
- stream->adjust.timing_adjust_pending = true;
- return false;
- }
- }
-
- dc_exit_ips_for_hw_access(dc);
-
- stream->adjust.v_total_max = adjust->v_total_max;
- stream->adjust.v_total_mid = adjust->v_total_mid;
- stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
- stream->adjust.v_total_min = adjust->v_total_min;
- stream->adjust.allow_otg_v_count_halt = adjust->allow_otg_v_count_halt;
-
- if (dc->caps.max_v_total != 0 &&
- (adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) {
- stream->adjust.timing_adjust_pending = false;
- if (adjust->allow_otg_v_count_halt)
- return set_long_vtotal(dc, stream, adjust);
- else
- return false;
- }
-
- for (i = 0; i < MAX_PIPES; i++) {
- struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
-
- if (pipe->stream == stream && pipe->stream_res.tg) {
- dc->hwss.set_drr(&pipe,
- 1,
- *adjust);
- stream->adjust.timing_adjust_pending = false;
-
- if (dc->hwss.notify_cursor_offload_drr_update)
- dc->hwss.notify_cursor_offload_drr_update(dc, dc->current_state, stream);
-
- return true;
- }
- }
-
- return false;
-}
-
-/**
* dc_stream_get_last_used_drr_vtotal - Looks up the pipe context of
* dc_stream_state and gets the last VTOTAL used by DRR (Dynamic Refresh Rate)
*
@@ -1274,6 +1205,8 @@ static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *conte
get_fams2_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));
else if (dc->debug.visual_confirm == VISUAL_CONFIRM_VABC)
get_vabc_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
+ else if (dc->debug.visual_confirm == VISUAL_CONFIRM_BOOSTED_REFRESH_RATE)
+ get_refresh_rate_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
}
}
}
@@ -1323,6 +1256,83 @@ void dc_get_visual_confirm_for_stream(
}
}
+/**
+ * dc_stream_adjust_vmin_vmax - look up pipe context & update parts of DRR
+ * @dc: dc reference
+ * @stream: Initial dc stream state
+ * @adjust: Updated parameters for vertical_total_min and vertical_total_max
+ *
+ * Looks up the pipe context of dc_stream_state and updates the
+ * vertical_total_min and vertical_total_max of the DRR, Dynamic Refresh
+ * Rate, which is a power-saving feature that targets reducing panel
+ * refresh rate while the screen is static
+ *
+ * Return: %true if the pipe context is found and adjusted;
+ * %false if the pipe context is not found.
+ */
+bool dc_stream_adjust_vmin_vmax(struct dc *dc,
+ struct dc_stream_state *stream,
+ struct dc_crtc_timing_adjust *adjust)
+{
+ int i;
+
+ /*
+ * Don't adjust DRR while there's bandwidth optimizations pending to
+ * avoid conflicting with firmware updates.
+ */
+ if (dc->ctx->dce_version > DCE_VERSION_MAX) {
+ if (dc->optimized_required &&
+ (stream->adjust.v_total_max != adjust->v_total_max ||
+ stream->adjust.v_total_min != adjust->v_total_min)) {
+ stream->adjust.timing_adjust_pending = true;
+ return false;
+ }
+ }
+
+ dc_exit_ips_for_hw_access(dc);
+
+ stream->adjust.v_total_max = adjust->v_total_max;
+ stream->adjust.v_total_mid = adjust->v_total_mid;
+ stream->adjust.v_total_mid_frame_num = adjust->v_total_mid_frame_num;
+ stream->adjust.v_total_min = adjust->v_total_min;
+ stream->adjust.allow_otg_v_count_halt = adjust->allow_otg_v_count_halt;
+
+ if (dc->caps.max_v_total != 0 &&
+ (adjust->v_total_max > dc->caps.max_v_total || adjust->v_total_min > dc->caps.max_v_total)) {
+ stream->adjust.timing_adjust_pending = false;
+ if (adjust->allow_otg_v_count_halt)
+ return set_long_vtotal(dc, stream, adjust);
+ else
+ return false;
+ }
+
+ for (i = 0; i < MAX_PIPES; i++) {
+ struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i];
+
+ if (pipe->stream == stream && pipe->stream_res.tg) {
+ dc->hwss.set_drr(&pipe,
+ 1,
+ *adjust);
+ stream->adjust.timing_adjust_pending = false;
+
+ if (dc->debug.visual_confirm == VISUAL_CONFIRM_BOOSTED_REFRESH_RATE) {
+ if (pipe->stream && pipe->plane_state) {
+ dc_update_visual_confirm_color(dc, dc->current_state, pipe);
+ dc->hwss.update_visual_confirm_color(dc, pipe, pipe->plane_res.hubp->mpcc_id);
+
+ }
+ }
+
+ if (dc->hwss.notify_cursor_offload_drr_update)
+ dc->hwss.notify_cursor_offload_drr_update(dc, dc->current_state, stream);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
{
int i, j;
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
index b38004441616..5b3695e72e19 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
@@ -4108,3 +4108,24 @@ void hwss_add_tg_get_frame_count(struct block_sequence_state *seq_state,
(*seq_state->num_steps)++;
}
}
+
+
+void get_refresh_rate_confirm_color(struct pipe_ctx *pipe_ctx, struct tg_color *color)
+{
+ uint32_t color_value = MAX_TG_COLOR_VALUE;
+ unsigned int refresh_rate = 0;
+ uint32_t scaling_factor = 0;
+ if (pipe_ctx && pipe_ctx->stream && color) {
+ refresh_rate = (pipe_ctx->stream->timing.pix_clk_100hz * 100) / (pipe_ctx->stream->adjust.v_total_max * pipe_ctx->stream->timing.h_total);
+
+ uint32_t min_refresh_rate = pipe_ctx->stream->timing.min_refresh_in_uhz / 1000000;
+ uint32_t max_refresh_rate = pipe_ctx->stream->timing.max_refresh_in_uhz / 1000000;
+
+ if (max_refresh_rate - min_refresh_rate)
+ scaling_factor = MAX_TG_COLOR_VALUE * (refresh_rate - min_refresh_rate) / (max_refresh_rate - min_refresh_rate);
+
+ pipe_ctx->visual_confirm_color.color_r_cr = color_value;
+ pipe_ctx->visual_confirm_color.color_g_y = scaling_factor;
+ pipe_ctx->visual_confirm_color.color_b_cb = color_value;
+ }
+}
diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h
index d2ea4e03c963..7126dc278a53 100644
--- a/drivers/gpu/drm/amd/display/dc/dc.h
+++ b/drivers/gpu/drm/amd/display/dc/dc.h
@@ -581,6 +581,7 @@ enum visual_confirm {
VISUAL_CONFIRM_HW_CURSOR = 20,
VISUAL_CONFIRM_VABC = 21,
VISUAL_CONFIRM_DCC = 22,
+ VISUAL_CONFIRM_BOOSTED_REFRESH_RATE = 23,
VISUAL_CONFIRM_EXPLICIT = 0x80000000,
};
diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
index d699640ba5b4..d1dba7ffcd9b 100644
--- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
+++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
@@ -1365,6 +1365,10 @@ void get_dcc_visual_confirm_color(
struct pipe_ctx *pipe_ctx,
struct tg_color *color);
+void get_refresh_rate_confirm_color(
+ struct pipe_ctx *pipe_ctx,
+ struct tg_color *color);
+
void set_p_state_switch_method(
struct dc *dc,
struct dc_state *context,