From: Sung Lee <sung.lee@xxxxxxx> [WHY] In headless systems, if set mode is not called, hardware will not be powered down on boot, causing HW/SW discrepancies. Powering down hardware on boot will ensure SW state is accurate. [HOW] Set a timer callback on boot for 10 seconds. If set mode is not called within that time, power down hardware. Otherwise, do not power down. Signed-off-by: Sung Lee <sung.lee@xxxxxxx> Reviewed-by: Anthony Koo <Anthony.Koo@xxxxxxx> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@xxxxxxx> --- drivers/gpu/drm/amd/display/dc/core/dc.c | 6 ++ drivers/gpu/drm/amd/display/dc/dc.h | 3 + .../amd/display/dc/dcn10/dcn10_hw_sequencer.c | 69 ++++++++++--------- .../amd/display/dc/dcn10/dcn10_hw_sequencer.h | 1 + .../gpu/drm/amd/display/dc/dcn10/dcn10_init.c | 1 + .../gpu/drm/amd/display/dc/dcn20/dcn20_init.c | 1 + .../gpu/drm/amd/display/dc/dcn21/dcn21_init.c | 1 + .../gpu/drm/amd/display/dc/inc/hw_sequencer.h | 1 + 8 files changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index 942ceb0f6383..8d935020068f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -2683,6 +2683,12 @@ void dc_interrupt_ack(struct dc *dc, enum dc_irq_source src) dal_irq_service_ack(dc->res_pool->irqs, src); } +void dc_power_down_on_boot(struct dc *dc) +{ + if (dc->ctx->dce_environment != DCE_ENV_VIRTUAL_HW && + dc->hwss.power_down_on_boot) + dc->hwss.power_down_on_boot(dc); +} void dc_set_power_state( struct dc *dc, diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index 389edcf3f6ce..c2336ca3a9e0 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -1029,6 +1029,7 @@ bool dc_resource_is_dsc_encoding_supported(const struct dc *dc); */ bool dc_commit_state(struct dc *dc, struct dc_state *context); +void dc_power_down_on_boot(struct dc *dc); struct dc_state *dc_create_state(struct dc *dc); struct dc_state *dc_copy_state(struct dc_state *src_ctx); @@ -1229,6 +1230,8 @@ void dc_set_power_state( enum dc_acpi_cm_power_state power_state); void dc_resume(struct dc *dc); +void dc_power_down_on_boot(struct dc *dc); + #if defined(CONFIG_DRM_AMD_DC_HDCP) /* * HDCP Interfaces diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c index 6711ff908bcf..20466cad6ade 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1393,38 +1393,6 @@ void dcn10_init_hw(struct dc *dc) } } - /* In headless boot cases, DIG may be turned - * on which causes HW/SW discrepancies. - * To avoid this, power down hardware on boot - * if DIG is turned on and seamless boot not enabled - */ - if (dc->config.power_down_display_on_boot) { - struct dc_link *edp_link = get_edp_link(dc); - - if (edp_link && - edp_link->link_enc->funcs->is_dig_enabled && - edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && - dc->hwseq->funcs.edp_backlight_control && - dc->hwss.power_down && - dc->hwss.edp_power_control) { - dc->hwseq->funcs.edp_backlight_control(edp_link, false); - dc->hwss.power_down(dc); - dc->hwss.edp_power_control(edp_link, false); - } else { - for (i = 0; i < dc->link_count; i++) { - struct dc_link *link = dc->links[i]; - - if (link->link_enc->funcs->is_dig_enabled && - link->link_enc->funcs->is_dig_enabled(link->link_enc) && - dc->hwss.power_down) { - dc->hwss.power_down(dc); - break; - } - - } - } - } - if (!is_optimized_init_done) { for (i = 0; i < res_pool->audio_count; i++) { @@ -1475,6 +1443,43 @@ void dcn10_init_hw(struct dc *dc) } +/* In headless boot cases, DIG may be turned + * on which causes HW/SW discrepancies. + * To avoid this, power down hardware on boot + * if DIG is turned on and seamless boot not enabled + */ +void dcn10_power_down_on_boot(struct dc *dc) +{ + int i = 0; + + if (dc->config.power_down_display_on_boot) { + struct dc_link *edp_link = get_edp_link(dc); + + if (edp_link && + edp_link->link_enc->funcs->is_dig_enabled && + edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && + dc->hwseq->funcs.edp_backlight_control && + dc->hwss.power_down && + dc->hwss.edp_power_control) { + dc->hwseq->funcs.edp_backlight_control(edp_link, false); + dc->hwss.power_down(dc); + dc->hwss.edp_power_control(edp_link, false); + } else { + for (i = 0; i < dc->link_count; i++) { + struct dc_link *link = dc->links[i]; + + if (link->link_enc->funcs->is_dig_enabled && + link->link_enc->funcs->is_dig_enabled(link->link_enc) && + dc->hwss.power_down) { + dc->hwss.power_down(dc); + break; + } + + } + } + } +} + void dcn10_reset_hw_ctx_wrap( struct dc *dc, struct dc_state *context) diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h index 42b6e016d71e..6d891166da8a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.h @@ -109,6 +109,7 @@ void dcn10_program_pipe( void dcn10_program_gamut_remap(struct pipe_ctx *pipe_ctx); void dcn10_init_hw(struct dc *dc); void dcn10_init_pipes(struct dc *dc, struct dc_state *context); +void dcn10_power_down_on_boot(struct dc *dc); enum dc_status dce110_apply_ctx_to_hw( struct dc *dc, struct dc_state *context); diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c index f6a790c49321..5c98b71c1d47 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_init.c @@ -30,6 +30,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, + .power_down_on_boot = dcn10_power_down_on_boot, .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = dcn10_apply_ctx_for_surface, .post_unlock_program_front_end = dcn10_post_unlock_program_front_end, diff --git a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c index bb9e9bec2f28..2380392b916e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_init.c @@ -30,6 +30,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, + .power_down_on_boot = dcn10_power_down_on_boot, .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c index 8575de1a8ad2..177d0dc8927a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn21/dcn21_init.c @@ -31,6 +31,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = { .program_gamut_remap = dcn10_program_gamut_remap, .init_hw = dcn10_init_hw, + .power_down_on_boot = dcn10_power_down_on_boot, .apply_ctx_to_hw = dce110_apply_ctx_to_hw, .apply_ctx_for_surface = NULL, .program_front_end_for_ctx = dcn20_program_front_end_for_ctx, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h index 066a2a723c12..720ce5e458d8 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h @@ -56,6 +56,7 @@ struct hw_sequencer_funcs { /* Pipe Programming Related */ void (*init_hw)(struct dc *dc); + void (*power_down_on_boot)(struct dc *dc); void (*enable_accelerated_mode)(struct dc *dc, struct dc_state *context); enum dc_status (*apply_ctx_to_hw)(struct dc *dc, -- 2.27.0 _______________________________________________ amd-gfx mailing list amd-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/amd-gfx