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;
}
bool dc_validate_seamless_boot_timing(struct dc *dc,
bool dc_validate_seamless_boot_timing(const struct dc *dc,
const struct dc_sink *sink,
struct dc_crtc_timing *crtc_timing)
{
@ -1062,7 +1062,13 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c
if (!dcb->funcs->is_accelerated_mode(dcb))
dc->hwss.enable_accelerated_mode(dc, context);
dc->hwss.prepare_bandwidth(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);
/* re-program planes for existing stream, in case we need to
* free up plane resource for later use
@ -1137,8 +1143,9 @@ 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);
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
if (!dc->optimize_seamless_boot)
/* pplib is notified if disp_num changed */
dc->hwss.optimize_bandwidth(dc, context);
for (i = 0; i < context->stream_count; i++)
context->streams[i]->mode_changed = false;
@ -1181,7 +1188,7 @@ bool dc_post_update_surfaces_to_stream(struct dc *dc)
int i;
struct dc_state *context = dc->current_state;
if (dc->optimized_required == false)
if (!dc->optimized_required || dc->optimize_seamless_boot)
return true;
post_surface_trace(dc);
@ -1699,7 +1706,16 @@ static void commit_planes_for_stream(struct dc *dc,
int i, j;
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);
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 pipe_ctx *pipe_ctx = NULL;
int pipe_idx = -1;
struct dc_bios *dcb = dc->ctx->dc_bios;
/* TODO Check if this is needed */
/*if (!resource_is_stream_unchanged(old_context, stream)) {
@ -1872,6 +1873,13 @@ enum dc_status resource_map_pool_resources(
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)
pipe_idx = acquire_resource_from_hw_enabled_state(
&context->res_ctx,

View File

@ -183,6 +183,7 @@ struct dc_config {
bool disable_disp_pll_sharing;
bool fbc_support;
bool optimize_edp_link_rate;
bool allow_seamless_boot_optimization;
};
enum visual_confirm {
@ -328,8 +329,12 @@ struct dc {
struct hw_sequencer_funcs hwss;
struct dce_hwseq *hwseq;
/* Require to optimize clocks and bandwidth for added/removed planes */
bool optimized_required;
/* Require to maintain clocks and bandwidth for UEFI enabled HW */
bool optimize_seamless_boot;
/* FBC compressor */
struct compressor *fbc_compressor;
@ -625,7 +630,7 @@ struct dc_validation_set {
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,
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(
struct clock_source *clock_source,
const struct clock_source *clock_source,
unsigned int inst,
unsigned int *pixel_clk_khz)
{

View File

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

View File

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