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;
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue