drm/amd/display: change static screen wait frame_count for ips
authorAllen Pan <allen.pan@amd.com>
Fri, 8 Dec 2023 23:49:19 +0000 (18:49 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 19 Dec 2023 19:59:03 +0000 (14:59 -0500)
[Why]
the original wait for 2 static frames before enter static screen
was not good enough for IPS-enabled case since enter/exit takes more time.

[How]
Changed logic for hardcoded wait frame values.

Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Allen Pan <allen.pan@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn35/dcn35_init.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c
drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.h
drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c

index a270b4bf7b95c32636fddd243d26e7290f5b77db..f622f4f0e1a0c59b829c04880acaf69de418bf9b 100644 (file)
@@ -982,6 +982,7 @@ struct dc_debug_options {
        unsigned int ips2_entry_delay_us;
        bool disable_timeout;
        bool disable_extblankadj;
+       unsigned int static_screen_wait_frames;
 };
 
 struct gpu_info_soc_bounding_box_v1_0;
index d594905eb246fd12fd15745f61201238650eccab..a630aa77dcec036c791c3ae4a75a2e3bedafe2f8 100644 (file)
@@ -68,7 +68,7 @@ static const struct hw_sequencer_funcs dcn35_funcs = {
        .prepare_bandwidth = dcn35_prepare_bandwidth,
        .optimize_bandwidth = dcn35_optimize_bandwidth,
        .update_bandwidth = dcn20_update_bandwidth,
-       .set_drr = dcn10_set_drr,
+       .set_drr = dcn35_set_drr,
        .get_position = dcn10_get_position,
        .set_static_screen_control = dcn30_set_static_screen_control,
        .setup_stereo = dcn10_setup_stereo,
index 582852ed21fbf6e7cbbfb2dd33f0c5d7157211d4..ad710b4036de0f47b92b941d7559ed47a3422996 100644 (file)
@@ -1312,3 +1312,44 @@ uint32_t dcn35_get_idle_state(const struct dc *dc)
 
        return 0;
 }
+
+void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
+               int num_pipes, struct dc_crtc_timing_adjust adjust)
+{
+       int i = 0;
+       struct drr_params params = {0};
+       // DRR set trigger event mapped to OTG_TRIG_A (bit 11) for manual control flow
+       unsigned int event_triggers = 0x800;
+       // Note DRR trigger events are generated regardless of whether num frames met.
+       unsigned int num_frames = 2;
+
+       params.vertical_total_max = adjust.v_total_max;
+       params.vertical_total_min = adjust.v_total_min;
+       params.vertical_total_mid = adjust.v_total_mid;
+       params.vertical_total_mid_frame_num = adjust.v_total_mid_frame_num;
+
+       for (i = 0; i < num_pipes; i++) {
+               if ((pipe_ctx[i]->stream_res.tg != NULL) && pipe_ctx[i]->stream_res.tg->funcs) {
+                       struct dc_crtc_timing *timing = &pipe_ctx[i]->stream->timing;
+                       struct dc *dc = pipe_ctx[i]->stream->ctx->dc;
+
+                       if (dc->debug.static_screen_wait_frames) {
+                               unsigned int frame_rate = timing->pix_clk_100hz / (timing->h_total * timing->v_total);
+
+                               if (frame_rate >= 120 && dc->caps.ips_support &&
+                                       dc->config.disable_ips != DMUB_IPS_DISABLE_ALL) {
+                                       /*ips enable case*/
+                                       num_frames = 2 * (frame_rate % 60);
+                               }
+                       }
+                       if (pipe_ctx[i]->stream_res.tg->funcs->set_drr)
+                               pipe_ctx[i]->stream_res.tg->funcs->set_drr(
+                                       pipe_ctx[i]->stream_res.tg, &params);
+                       if (adjust.v_total_max != 0 && adjust.v_total_min != 0)
+                               if (pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control)
+                                       pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(
+                                               pipe_ctx[i]->stream_res.tg,
+                                               event_triggers, num_frames);
+               }
+       }
+}
index b7bafe7fe2fdb4dda44649a785a4c87fe7065300..fd66316e33de367da8c90e3520087fce385ebb5b 100644 (file)
@@ -86,4 +86,8 @@ void dcn35_dsc_pg_control(
 
 void dcn35_set_idle_state(const struct dc *dc, bool allow_idle);
 uint32_t dcn35_get_idle_state(const struct dc *dc);
+
+void dcn35_set_drr(struct pipe_ctx **pipe_ctx,
+               int num_pipes, struct dc_crtc_timing_adjust adjust);
+
 #endif /* __DC_HWSS_DCN35_H__ */
index d0c3c5b470949a25d55c58b8094b46c467b8150f..810cfe21363223a3a70814300ace8f2087013364 100644 (file)
@@ -780,7 +780,8 @@ static const struct dc_debug_options debug_defaults_drv = {
        .ignore_pg = true,
        .psp_disabled_wa = true,
        .ips2_eval_delay_us = 200,
-       .ips2_entry_delay_us = 400
+       .ips2_entry_delay_us = 400,
+       .static_screen_wait_frames = 2,
 };
 
 static const struct dc_panel_config panel_config_defaults = {