diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 106 |
1 files changed, 47 insertions, 59 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c index 3afa1159a5f7..d24ad7754d71 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -48,6 +48,9 @@ #include "dc_link_dp.h" #include "inc/link_dpcd.h" #include "dcn10/dcn10_hw_sequencer.h" +#include "inc/link_enc_cfg.h" +#include "dcn30/dcn30_vpg.h" +#include "dce/dce_i2c_hw.h" #define DC_LOGGER_INIT(logger) @@ -71,7 +74,6 @@ void dcn31_init_hw(struct dc *dc) struct resource_pool *res_pool = dc->res_pool; uint32_t backlight = MAX_BACKLIGHT_LEVEL; int i, j; - int edp_num; if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks) dc->clk_mgr->funcs->init_clocks(dc->clk_mgr); @@ -124,6 +126,18 @@ void dcn31_init_hw(struct dc *dc) REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1); } +#if defined(CONFIG_DRM_AMD_DC_DCN) + if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) { + // Power down VPGs + for (i = 0; i < dc->res_pool->stream_enc_count; i++) + dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg); +#if defined(CONFIG_DRM_AMD_DC_DP2_0) + for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++) + dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg); +#endif + } +#endif + if (dc->ctx->dc_bios->fw_info_valid) { res_pool->ref_clocks.xtalin_clock_inKhz = dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency; @@ -156,6 +170,9 @@ void dcn31_init_hw(struct dc *dc) */ struct dc_link *link = dc->links[i]; + if (link->ep_type != DISPLAY_ENDPOINT_PHY) + continue; + link->link_enc->funcs->hw_init(link->link_enc); /* Check for enabled DIG to identify enabled display */ @@ -169,6 +186,10 @@ void dcn31_init_hw(struct dc *dc) if (hws->funcs.dsc_pg_control != NULL) hws->funcs.dsc_pg_control(hws, res_pool->dscs[i]->inst, false); + /* Enables outbox notifications for usb4 dpia */ + if (dc->res_pool->usb4_dpia_count) + dmub_enable_outbox_notification(dc); + /* we want to turn off all dp displays before doing detection */ if (dc->config.power_down_display_on_boot) { uint8_t dpcd_power_state = '\0'; @@ -183,7 +204,8 @@ void dcn31_init_hw(struct dc *dc) &dpcd_power_state, sizeof(dpcd_power_state)); if (status == DC_OK && dpcd_power_state == DP_POWER_STATE_D0) { /* blank dp stream before power off receiver*/ - if (dc->links[i]->link_enc->funcs->get_dig_frontend) { + if (dc->links[i]->ep_type == DISPLAY_ENDPOINT_PHY && + dc->links[i]->link_enc->funcs->get_dig_frontend) { unsigned int fe; fe = dc->links[i]->link_enc->funcs->get_dig_frontend( @@ -193,7 +215,7 @@ void dcn31_init_hw(struct dc *dc) for (j = 0; j < dc->res_pool->stream_enc_count; j++) { if (fe == dc->res_pool->stream_enc[j]->id) { - dc->res_pool->stream_enc[j]->funcs->dp_blank( + dc->res_pool->stream_enc[j]->funcs->dp_blank(dc->links[i], dc->res_pool->stream_enc[j]); break; } @@ -217,47 +239,6 @@ void dcn31_init_hw(struct dc *dc) !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter); } - /* 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_links[MAX_NUM_EDP]; - struct dc_link *edp_link; - bool power_down = false; - - get_edp_links(dc, edp_links, &edp_num); - if (edp_num) { - for (i = 0; i < edp_num; i++) { - edp_link = edp_links[i]; - if (edp_link->link_enc->funcs->is_dig_enabled && - edp_link->link_enc->funcs->is_dig_enabled(edp_link->link_enc) && - dc->hwss.edp_backlight_control && - dc->hwss.power_down && - dc->hwss.edp_power_control) { - dc->hwss.edp_backlight_control(edp_link, false); - dc->hwss.power_down(dc); - dc->hwss.edp_power_control(edp_link, false); - power_down = true; - } - } - } - if (!power_down) { - 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; - } - - } - } - } - for (i = 0; i < res_pool->audio_count; i++) { struct audio *audio = res_pool->audios[i]; @@ -279,6 +260,10 @@ void dcn31_init_hw(struct dc *dc) /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ REG_WRITE(DIO_MEM_PWR_CTRL, 0); + // Set i2c to light sleep until engine is setup + if (dc->debug.enable_mem_low_power.bits.i2c) + REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1); + if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); @@ -302,8 +287,10 @@ void dcn31_init_hw(struct dc *dc) if (dc->res_pool->hubbub->funcs->force_pstate_change_control) dc->res_pool->hubbub->funcs->force_pstate_change_control( dc->res_pool->hubbub, false, false); +#if defined(CONFIG_DRM_AMD_DC_DCN) if (dc->res_pool->hubbub->funcs->init_crb) dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub); +#endif } void dcn31_dsc_pg_control( @@ -318,6 +305,12 @@ void dcn31_dsc_pg_control( if (hws->ctx->dc->debug.disable_dsc_power_gate) return; + if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc && + hws->ctx->dc->res_pool->dccg->funcs->enable_dsc && + power_on) + hws->ctx->dc->res_pool->dccg->funcs->enable_dsc( + hws->ctx->dc->res_pool->dccg, dsc_inst); + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); if (org_ip_request_cntl == 0) REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); @@ -354,6 +347,13 @@ void dcn31_dsc_pg_control( if (org_ip_request_cntl == 0) REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0); + + if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) { + if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on) + hws->ctx->dc->res_pool->dccg->funcs->disable_dsc( + hws->ctx->dc->res_pool->dccg, dsc_inst); + } + } @@ -419,7 +419,7 @@ void dcn31_z10_save_init(struct dc *dc) dc_dmub_srv_wait_idle(dc->ctx->dmub_srv); } -void dcn31_z10_restore(struct dc *dc) +void dcn31_z10_restore(const struct dc *dc) { union dmub_rb_cmd cmd; @@ -593,19 +593,7 @@ void dcn31_reset_hw_ctx_wrap( old_clk->funcs->cs_power_down(old_clk); } } -} -bool dcn31_is_abm_supported(struct dc *dc, - struct dc_state *context, struct dc_stream_state *stream) -{ - int i; - - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i]; - - if (pipe_ctx->stream == stream && - (pipe_ctx->prev_odm_pipe == NULL && pipe_ctx->next_odm_pipe == NULL)) - return true; - } - return false; + /* New dc_state in the process of being applied to hardware. */ + dc->current_state->res_ctx.link_enc_cfg_ctx.mode = LINK_ENC_CFG_TRANSIENT; } |