drm/amd/display: Keep clocks high before seamless boot done

[Why]
UEFI boot usually uses a boot profile that uses higher clocks
and watermark settings.
UEFI boot surface is less optimal, for example it uses linear surface

[How]
Before we finish our seamless boot sequence, keep the clock and
watermark settings from boot.
Update to optimal settings only after first flip away from UEFI
frame buffer.

Signed-off-by: Anthony Koo <Anthony.Koo@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Bhawanpreet Lakha <Bhawanpreet.Lakha@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
Anthony Koo 2019-02-08 20:50:51 -05:00 committed by Alex Deucher
parent f503100060
commit 46570f0904
6 changed files with 42 additions and 12 deletions

View File

@ -971,7 +971,7 @@ static bool context_changed(
return false; return false;
} }
bool dc_validate_seamless_boot_timing(struct dc *dc, bool dc_validate_seamless_boot_timing(const struct dc *dc,
const struct dc_sink *sink, const struct dc_sink *sink,
struct dc_crtc_timing *crtc_timing) struct dc_crtc_timing *crtc_timing)
{ {
@ -1062,6 +1062,12 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
if (!dcb->funcs->is_accelerated_mode(dcb)) if (!dcb->funcs->is_accelerated_mode(dcb))
dc->hwss.enable_accelerated_mode(dc, context); dc->hwss.enable_accelerated_mode(dc, context);
for (i = 0; i < context->stream_count; i++) {
if (context->streams[i]->apply_seamless_boot_optimization)
dc->optimize_seamless_boot = true;
}
if (!dc->optimize_seamless_boot)
dc->hwss.prepare_bandwidth(dc, context); dc->hwss.prepare_bandwidth(dc, context);
/* re-program planes for existing stream, in case we need to /* re-program planes for existing stream, in case we need to
@ -1137,6 +1143,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
dc_enable_stereo(dc, context, dc_streams, context->stream_count); dc_enable_stereo(dc, context, dc_streams, context->stream_count);
if (!dc->optimize_seamless_boot)
/* pplib is notified if disp_num changed */ /* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context); dc->hwss.optimize_bandwidth(dc, context);
@ -1181,7 +1188,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
int i; int i;
struct dc_state *context = dc->current_state; struct dc_state *context = dc->current_state;
if (dc->optimized_required == false) if (!dc->optimized_required || dc->optimize_seamless_boot)
return true; return true;
post_surface_trace(dc); post_surface_trace(dc);
@ -1699,7 +1706,16 @@ static void commit_planes_for_stream(struct dc *dc,
int i, j; int i, j;
struct pipe_ctx *top_pipe_to_program = NULL; struct pipe_ctx *top_pipe_to_program = NULL;
if (update_type == UPDATE_TYPE_FULL) { if (dc->optimize_seamless_boot && surface_count > 0) {
/* Optimize seamless boot flag keeps clocks and watermarks high until
* first flip. After first flip, optimization is required to lower
* bandwidth.
*/
dc->optimize_seamless_boot = false;
dc->optimized_required = true;
}
if (update_type == UPDATE_TYPE_FULL && !dc->optimize_seamless_boot) {
dc->hwss.prepare_bandwidth(dc, context); dc->hwss.prepare_bandwidth(dc, context);
context_clock_trace(dc, context); context_clock_trace(dc, context);
} }

View File

@ -1858,6 +1858,7 @@ enum dc_status resource_map_pool_resources(
struct dc_context *dc_ctx = dc->ctx; struct dc_context *dc_ctx = dc->ctx;
struct pipe_ctx *pipe_ctx = NULL; struct pipe_ctx *pipe_ctx = NULL;
int pipe_idx = -1; int pipe_idx = -1;
struct dc_bios *dcb = dc->ctx->dc_bios;
/* TODO Check if this is needed */ /* TODO Check if this is needed */
/*if (!resource_is_stream_unchanged(old_context, stream)) { /*if (!resource_is_stream_unchanged(old_context, stream)) {
@ -1872,6 +1873,13 @@ enum dc_status resource_map_pool_resources(
calculate_phy_pix_clks(stream); calculate_phy_pix_clks(stream);
/* TODO: Check Linux */
if (dc->config.allow_seamless_boot_optimization &&
!dcb->funcs->is_accelerated_mode(dcb)) {
if (dc_validate_seamless_boot_timing(dc, stream->sink, &stream->timing))
stream->apply_seamless_boot_optimization = true;
}
if (stream->apply_seamless_boot_optimization) if (stream->apply_seamless_boot_optimization)
pipe_idx = acquire_resource_from_hw_enabled_state( pipe_idx = acquire_resource_from_hw_enabled_state(
&context->res_ctx, &context->res_ctx,

View File

@ -183,6 +183,7 @@ struct dc_config {
bool disable_disp_pll_sharing; bool disable_disp_pll_sharing;
bool fbc_support; bool fbc_support;
bool optimize_edp_link_rate; bool optimize_edp_link_rate;
bool allow_seamless_boot_optimization;
}; };
enum visual_confirm { enum visual_confirm {
@ -328,8 +329,12 @@ struct dc {
struct hw_sequencer_funcs hwss; struct hw_sequencer_funcs hwss;
struct dce_hwseq *hwseq; struct dce_hwseq *hwseq;
/* Require to optimize clocks and bandwidth for added/removed planes */
bool optimized_required; bool optimized_required;
/* Require to maintain clocks and bandwidth for UEFI enabled HW */
bool optimize_seamless_boot;
/* FBC compressor */ /* FBC compressor */
struct compressor *fbc_compressor; struct compressor *fbc_compressor;
@ -625,7 +630,7 @@ struct dc_validation_set {
uint8_t plane_count; uint8_t plane_count;
}; };
bool dc_validate_seamless_boot_timing(struct dc *dc, bool dc_validate_seamless_boot_timing(const struct dc *dc,
const struct dc_sink *sink, const struct dc_sink *sink,
struct dc_crtc_timing *crtc_timing); struct dc_crtc_timing *crtc_timing);

View File

@ -978,7 +978,7 @@ static bool dce110_clock_source_power_down(
} }
static bool get_pixel_clk_frequency_100hz( static bool get_pixel_clk_frequency_100hz(
struct clock_source *clock_source, const struct clock_source *clock_source,
unsigned int inst, unsigned int inst,
unsigned int *pixel_clk_khz) unsigned int *pixel_clk_khz)
{ {

View File

@ -1026,7 +1026,8 @@ static void dcn10_init_pipes(struct dc *dc, struct dc_state *context)
* to non-preferred front end. If pipe_ctx->stream is not NULL, * to non-preferred front end. If pipe_ctx->stream is not NULL,
* we will use the pipe, so don't disable * we will use the pipe, so don't disable
*/ */
if (pipe_ctx->stream != NULL && if (can_apply_seamless_boot &&
pipe_ctx->stream != NULL &&
pipe_ctx->stream_res.tg->funcs->is_tg_enabled( pipe_ctx->stream_res.tg->funcs->is_tg_enabled(
pipe_ctx->stream_res.tg)) pipe_ctx->stream_res.tg))
continue; continue;

View File

@ -167,7 +167,7 @@ struct clock_source_funcs {
struct pixel_clk_params *, struct pixel_clk_params *,
struct pll_settings *); struct pll_settings *);
bool (*get_pixel_clk_frequency_100hz)( bool (*get_pixel_clk_frequency_100hz)(
struct clock_source *clock_source, const struct clock_source *clock_source,
unsigned int inst, unsigned int inst,
unsigned int *pixel_clk_khz); unsigned int *pixel_clk_khz);
}; };