drm/amd/display: Allow asic specific FSFT timing optimization

[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>
This commit is contained in:
Reza Amini 2020-07-15 11:33:23 -04:00 committed by Alex Deucher
parent 6b6352dd1f
commit 471c1dd954
8 changed files with 57 additions and 13 deletions

View File

@ -246,20 +246,18 @@ struct dc_stream_status *dc_stream_get_status(
#ifndef TRIM_FSFT #ifndef TRIM_FSFT
/** /**
* dc_optimize_timing() - dc to optimize timing * dc_optimize_timing_for_fsft() - dc to optimize timing
*/ */
bool dc_optimize_timing( bool dc_optimize_timing_for_fsft(
struct dc_crtc_timing *timing, struct dc_stream_state *pStream,
unsigned int max_input_rate_in_khz) unsigned int max_input_rate_in_khz)
{ {
//optimization is expected to assing a value to these: struct dc *dc;
//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;
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 #endif

View File

@ -424,8 +424,8 @@ struct dc_stream_status *dc_stream_get_status(
struct dc_stream_state *dc_stream); struct dc_stream_state *dc_stream);
#ifndef TRIM_FSFT #ifndef TRIM_FSFT
bool dc_optimize_timing( bool dc_optimize_timing_for_fsft(
struct dc_crtc_timing *timing, struct dc_stream_state *pStream,
unsigned int max_input_rate_in_khz); unsigned int max_input_rate_in_khz);
#endif #endif

View File

@ -2498,3 +2498,30 @@ void dcn20_fpga_init_hw(struct dc *dc)
tg->funcs->tg_init(tg); 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

View File

@ -132,5 +132,10 @@ int dcn20_init_sys_ctx(struct dce_hwseq *hws,
struct dc *dc, struct dc *dc,
struct dc_phy_addr_space_config *pa_config); 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__ */ #endif /* __DC_HWSS_DCN20_H__ */

View File

@ -88,6 +88,9 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
.set_backlight_level = dce110_set_backlight_level, .set_backlight_level = dce110_set_backlight_level,
.set_abm_immediate_disable = dce110_set_abm_immediate_disable, .set_abm_immediate_disable = dce110_set_abm_immediate_disable,
.set_pipe = dce110_set_pipe, .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 = { static const struct hwseq_private_funcs dcn20_private_funcs = {

View File

@ -92,6 +92,9 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
.set_backlight_level = dcn21_set_backlight_level, .set_backlight_level = dcn21_set_backlight_level,
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable, .set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe, .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 = { static const struct hwseq_private_funcs dcn21_private_funcs = {

View File

@ -116,6 +116,11 @@ struct hw_sequencer_funcs {
void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx, void (*set_static_screen_control)(struct pipe_ctx **pipe_ctx,
int num_pipes, int num_pipes,
const struct dc_static_screen_params *events); 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 */ /* Stream Related */
void (*enable_stream)(struct pipe_ctx *pipe_ctx); void (*enable_stream)(struct pipe_ctx *pipe_ctx);

View File

@ -829,10 +829,13 @@ void mod_freesync_build_vrr_infopacket(struct mod_freesync *mod_freesync,
switch (packet_type) { switch (packet_type) {
case PACKET_TYPE_FS_V3: case PACKET_TYPE_FS_V3:
#ifndef TRIM_FSFT #ifndef TRIM_FSFT
// always populate with pixel rate.
build_vrr_infopacket_v3( build_vrr_infopacket_v3(
stream->signal, vrr, stream->signal, vrr,
stream->timing.flags.FAST_TRANSPORT, 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); app_tf, infopacket);
#else #else
build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket); build_vrr_infopacket_v3(stream->signal, vrr, app_tf, infopacket);