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:
parent
f503100060
commit
46570f0904
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue