drm/amd/display: Allow asic specific FSFT timing optimization
authorReza Amini <Reza.Amini@amd.com>
Wed, 15 Jul 2020 15:33:23 +0000 (11:33 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 6 Aug 2020 20:40:18 +0000 (16:40 -0400)
[Why]
Each asic can optimize best based on its capabilities

[How]
Optimizing timing for a new pixel clock

Signed-off-by: Reza Amini <Reza.Amini@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Acked-by: Eryk Brol <eryk.brol@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc_stream.c
drivers/gpu/drm/amd/display/dc/dc_stream.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
drivers/gpu/drm/amd/display/modules/freesync/freesync.c

index 10d69ad..0257a90 100644 (file)
@@ -246,20 +246,18 @@ struct dc_stream_status *dc_stream_get_status(
 
 #ifndef TRIM_FSFT
 /**
- * dc_optimize_timing() - dc to optimize timing
+ * dc_optimize_timing_for_fsft() - dc to optimize timing
  */
-bool dc_optimize_timing(
-       struct dc_crtc_timing *timing,
+bool dc_optimize_timing_for_fsft(
+       struct dc_stream_state *pStream,
        unsigned int max_input_rate_in_khz)
 {
-       //optimization is expected to assing a value to these:
-       //timing->pix_clk_100hz
-       //timing->v_front_porch
-       //timing->v_total
-       //timing->fast_transport_output_rate_100hz;
-       timing->fast_transport_output_rate_100hz = timing->pix_clk_100hz;
+       struct dc  *dc;
 
-       return true;
+       dc = pStream->ctx->dc;
+
+       return (dc->hwss.optimize_timing_for_fsft &&
+               dc->hwss.optimize_timing_for_fsft(dc, &pStream->timing, max_input_rate_in_khz));
 }
 #endif
 
index e4e85a1..633442b 100644 (file)
@@ -424,8 +424,8 @@ struct dc_stream_status *dc_stream_get_status(
        struct dc_stream_state *dc_stream);
 
 #ifndef TRIM_FSFT
-bool dc_optimize_timing(
-       struct dc_crtc_timing *timing,
+bool dc_optimize_timing_for_fsft(
+       struct dc_stream_state *pStream,
        unsigned int max_input_rate_in_khz);
 #endif
 
index 7725a40..66180b4 100644 (file)
@@ -2498,3 +2498,30 @@ void dcn20_fpga_init_hw(struct dc *dc)
                tg->funcs->tg_init(tg);
        }
 }
+#ifndef TRIM_FSFT
+bool dcn20_optimize_timing_for_fsft(struct dc *dc,
+               struct dc_crtc_timing *timing,
+               unsigned int max_input_rate_in_khz)
+{
+       unsigned int old_v_front_porch;
+       unsigned int old_v_total;
+       unsigned int max_input_rate_in_100hz;
+       unsigned long long new_v_total;
+
+       max_input_rate_in_100hz = max_input_rate_in_khz * 10;
+       if (max_input_rate_in_100hz < timing->pix_clk_100hz)
+               return false;
+
+       old_v_total = timing->v_total;
+       old_v_front_porch = timing->v_front_porch;
+
+       timing->fast_transport_output_rate_100hz = timing->pix_clk_100hz;
+       timing->pix_clk_100hz = max_input_rate_in_100hz;
+
+       new_v_total = div_u64((unsigned long long)old_v_total * max_input_rate_in_100hz, timing->pix_clk_100hz);
+
+       timing->v_total = new_v_total;
+       timing->v_front_porch = old_v_front_porch + (timing->v_total - old_v_total);
+       return true;
+}
+#endif
index 63ce763..83220e3 100644 (file)
@@ -132,5 +132,10 @@ int dcn20_init_sys_ctx(struct dce_hwseq *hws,
                struct dc *dc,
                struct dc_phy_addr_space_config *pa_config);
 
+#ifndef TRIM_FSFT
+bool dcn20_optimize_timing_for_fsft(struct dc *dc,
+               struct dc_crtc_timing *timing,
+               unsigned int max_input_rate_in_khz);
+#endif
 #endif /* __DC_HWSS_DCN20_H__ */
 
index 2380392..3dde6f2 100644 (file)
@@ -88,6 +88,9 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
        .set_backlight_level = dce110_set_backlight_level,
        .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
        .set_pipe = dce110_set_pipe,
+#ifndef TRIM_FSFT
+       .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
+#endif
 };
 
 static const struct hwseq_private_funcs dcn20_private_funcs = {
index 177d0dc..b187f71 100644 (file)
@@ -92,6 +92,9 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
        .set_backlight_level = dcn21_set_backlight_level,
        .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
        .set_pipe = dcn21_set_pipe,
+#ifndef TRIM_FSFT
+       .optimize_timing_for_fsft = dcn20_optimize_timing_for_fsft,
+#endif
 };
 
 static const struct hwseq_private_funcs dcn21_private_funcs = {
index 720ce5e..3c98671 100644 (file)
@@ -116,6 +116,11 @@ struct hw_sequencer_funcs {
        void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
                        int num_pipes,
                        const struct dc_static_screen_params *events);
+#ifndef TRIM_FSFT
+       bool (*optimize_timing_for_fsft)(struct dc *dc,
+                       struct dc_crtc_timing *timing,
+                       unsigned int max_input_rate_in_khz);
+#endif
 
        /* Stream Related */
        void (*enable_stream)(struct pipe_ctx *pipe_ctx);
index 7a2500f..81820f3 100644 (file)
@@ -829,10 +829,13 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
        switch (packet_type) {
        case PACKET_TYPE_FS_V3:
 #ifndef TRIM_FSFT
+               // always populate with pixel rate.
                build_vrr_infopacket_v3(
                                stream->signal, vrr,
                                stream->timing.flags.FAST_TRANSPORT,
-                               stream->timing.fast_transport_output_rate_100hz,
+                               (stream->timing.flags.FAST_TRANSPORT) ?
+                                               stream->timing.fast_transport_output_rate_100hz :
+                                               stream->timing.pix_clk_100hz,
                                app_tf, infopacket);
 #else
                build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket);