636 lines · c
1/*2 * Copyright 2016 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26 27#include "dm_services.h"28#include "dm_helpers.h"29#include "core_types.h"30#include "resource.h"31#include "dccg.h"32#include "dce/dce_hwseq.h"33#include "clk_mgr.h"34#include "reg_helper.h"35#include "abm.h"36#include "hubp.h"37#include "dchubbub.h"38#include "timing_generator.h"39#include "opp.h"40#include "ipp.h"41#include "mpc.h"42#include "mcif_wb.h"43#include "dc_dmub_srv.h"44#include "dcn31_hwseq.h"45#include "link_hwss.h"46#include "dpcd_defs.h"47#include "dce/dmub_outbox.h"48#include "link.h"49#include "dcn10/dcn10_hwseq.h"50#include "inc/link_enc_cfg.h"51#include "dcn30/dcn30_vpg.h"52#include "dce/dce_i2c_hw.h"53 54#define DC_LOGGER_INIT(logger)55 56#define CTX \57 hws->ctx58#define REG(reg)\59 hws->regs->reg60#define DC_LOGGER \61 dc->ctx->logger62 63 64#undef FN65#define FN(reg_name, field_name) \66 hws->shifts->field_name, hws->masks->field_name67 68static void enable_memory_low_power(struct dc *dc)69{70 struct dce_hwseq *hws = dc->hwseq;71 int i;72 73 if (dc->debug.enable_mem_low_power.bits.dmcu) {74 // Force ERAM to shutdown if DMCU is not enabled75 if (dc->debug.disable_dmcu || dc->config.disable_dmcu) {76 REG_UPDATE(DMU_MEM_PWR_CNTL, DMCU_ERAM_MEM_PWR_FORCE, 3);77 }78 }79 80 // Set default OPTC memory power states81 if (dc->debug.enable_mem_low_power.bits.optc) {82 // Shutdown when unassigned and light sleep in VBLANK83 REG_SET_2(ODM_MEM_PWR_CTRL3, 0, ODM_MEM_UNASSIGNED_PWR_MODE, 3, ODM_MEM_VBLANK_PWR_MODE, 1);84 }85 86 if (dc->debug.enable_mem_low_power.bits.vga) {87 // Power down VGA memory88 REG_UPDATE(MMHUBBUB_MEM_PWR_CNTL, VGA_MEM_PWR_FORCE, 1);89 }90 91 if (dc->debug.enable_mem_low_power.bits.mpc &&92 dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode)93 dc->res_pool->mpc->funcs->set_mpc_mem_lp_mode(dc->res_pool->mpc);94 95 96 if (dc->debug.enable_mem_low_power.bits.vpg && dc->res_pool->stream_enc[0]->vpg->funcs->vpg_powerdown) {97 // Power down VPGs98 for (i = 0; i < dc->res_pool->stream_enc_count; i++)99 if (dc->res_pool->stream_enc[i]->vpg)100 dc->res_pool->stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->stream_enc[i]->vpg);101 for (i = 0; i < dc->res_pool->hpo_dp_stream_enc_count; i++)102 dc->res_pool->hpo_dp_stream_enc[i]->vpg->funcs->vpg_powerdown(dc->res_pool->hpo_dp_stream_enc[i]->vpg);103 }104 105}106 107void dcn31_init_hw(struct dc *dc)108{109 struct abm **abms = dc->res_pool->multiple_abms;110 struct dce_hwseq *hws = dc->hwseq;111 struct dc_bios *dcb = dc->ctx->dc_bios;112 struct resource_pool *res_pool = dc->res_pool;113 uint32_t backlight = MAX_BACKLIGHT_LEVEL;114 uint32_t user_level = MAX_BACKLIGHT_LEVEL;115 int i;116 117 if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)118 dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);119 120 if (!dcb->funcs->is_accelerated_mode(dcb)) {121 hws->funcs.bios_golden_init(dc);122 if (hws->funcs.disable_vga)123 hws->funcs.disable_vga(dc->hwseq);124 }125 // Initialize the dccg126 if (res_pool->dccg->funcs->dccg_init)127 res_pool->dccg->funcs->dccg_init(res_pool->dccg);128 129 enable_memory_low_power(dc);130 131 if (dc->ctx->dc_bios->fw_info_valid) {132 res_pool->ref_clocks.xtalin_clock_inKhz =133 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;134 135 if (res_pool->hubbub) {136 137 (res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,138 dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,139 &res_pool->ref_clocks.dccg_ref_clock_inKhz);140 141 (res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,142 res_pool->ref_clocks.dccg_ref_clock_inKhz,143 &res_pool->ref_clocks.dchub_ref_clock_inKhz);144 } else {145 // Not all ASICs have DCCG sw component146 res_pool->ref_clocks.dccg_ref_clock_inKhz =147 res_pool->ref_clocks.xtalin_clock_inKhz;148 res_pool->ref_clocks.dchub_ref_clock_inKhz =149 res_pool->ref_clocks.xtalin_clock_inKhz;150 }151 } else152 ASSERT_CRITICAL(false);153 154 for (i = 0; i < dc->link_count; i++) {155 /* Power up AND update implementation according to the156 * required signal (which may be different from the157 * default signal on connector).158 */159 struct dc_link *link = dc->links[i];160 161 if (link->ep_type != DISPLAY_ENDPOINT_PHY)162 continue;163 164 link->link_enc->funcs->hw_init(link->link_enc);165 166 /* Check for enabled DIG to identify enabled display */167 if (link->link_enc->funcs->is_dig_enabled &&168 link->link_enc->funcs->is_dig_enabled(link->link_enc)) {169 link->link_status.link_active = true;170 if (link->link_enc->funcs->fec_is_active &&171 link->link_enc->funcs->fec_is_active(link->link_enc))172 link->fec_state = dc_link_fec_enabled;173 }174 }175 176 /* we want to turn off all dp displays before doing detection */177 dc->link_srv->blank_all_dp_displays(dc);178 179 if (hws->funcs.enable_power_gating_plane)180 hws->funcs.enable_power_gating_plane(dc->hwseq, true);181 182 /* If taking control over from VBIOS, we may want to optimize our first183 * mode set, so we need to skip powering down pipes until we know which184 * pipes we want to use.185 * Otherwise, if taking control is not possible, we need to power186 * everything down.187 */188 if (dcb->funcs->is_accelerated_mode(dcb) || !dc->config.seamless_boot_edp_requested) {189 190 // we want to turn off edp displays if odm is enabled and no seamless boot191 if (!dc->caps.seamless_odm) {192 for (i = 0; i < dc->res_pool->timing_generator_count; i++) {193 struct timing_generator *tg = dc->res_pool->timing_generators[i];194 uint32_t num_opps, opp_id_src0, opp_id_src1;195 196 num_opps = 1;197 if (tg) {198 if (tg->funcs->is_tg_enabled(tg) && tg->funcs->get_optc_source) {199 tg->funcs->get_optc_source(tg, &num_opps,200 &opp_id_src0, &opp_id_src1);201 }202 }203 204 if (num_opps > 1) {205 dc->link_srv->blank_all_edp_displays(dc);206 break;207 }208 }209 }210 211 hws->funcs.init_pipes(dc, dc->current_state);212 if (dc->res_pool->hubbub->funcs->allow_self_refresh_control)213 dc->res_pool->hubbub->funcs->allow_self_refresh_control(dc->res_pool->hubbub,214 !dc->res_pool->hubbub->ctx->dc->debug.disable_stutter);215 }216 217 for (i = 0; i < res_pool->audio_count; i++) {218 struct audio *audio = res_pool->audios[i];219 220 audio->funcs->hw_init(audio);221 }222 223 for (i = 0; i < dc->link_count; i++) {224 struct dc_link *link = dc->links[i];225 226 if (link->panel_cntl) {227 backlight = link->panel_cntl->funcs->hw_init(link->panel_cntl);228 user_level = link->panel_cntl->stored_backlight_registers.USER_LEVEL;229 }230 }231 232 for (i = 0; i < dc->res_pool->pipe_count; i++) {233 if (abms[i] != NULL)234 abms[i]->funcs->abm_init(abms[i], backlight, user_level);235 }236 237 /* power AFMT HDMI memory TODO: may move to dis/en output save power*/238 REG_WRITE(DIO_MEM_PWR_CTRL, 0);239 240 // Set i2c to light sleep until engine is setup241 if (dc->debug.enable_mem_low_power.bits.i2c)242 REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1);243 244 if (hws->funcs.setup_hpo_hw_control)245 hws->funcs.setup_hpo_hw_control(hws, false);246 247 if (!dc->debug.disable_clock_gate) {248 /* enable all DCN clock gating */249 REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);250 251 REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);252 253 REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);254 }255 256 if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks)257 dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub);258 259 if (dc->clk_mgr && dc->clk_mgr->funcs->notify_wm_ranges)260 dc->clk_mgr->funcs->notify_wm_ranges(dc->clk_mgr);261 262 if (dc->clk_mgr && dc->clk_mgr->funcs->set_hard_max_memclk && !dc->clk_mgr->dc_mode_softmax_enabled)263 dc->clk_mgr->funcs->set_hard_max_memclk(dc->clk_mgr);264 265 if (dc->res_pool->hubbub->funcs->force_pstate_change_control)266 dc->res_pool->hubbub->funcs->force_pstate_change_control(267 dc->res_pool->hubbub, false, false);268#if defined(CONFIG_DRM_AMD_DC_FP)269 if (dc->res_pool->hubbub->funcs->init_crb)270 dc->res_pool->hubbub->funcs->init_crb(dc->res_pool->hubbub);271#endif272 273 // Get DMCUB capabilities274 dc_dmub_srv_query_caps_cmd(dc->ctx->dmub_srv);275 dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr;276 dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver;277}278 279void dcn31_dsc_pg_control(280 struct dce_hwseq *hws,281 unsigned int dsc_inst,282 bool power_on)283{284 uint32_t power_gate = power_on ? 0 : 1;285 uint32_t pwr_status = power_on ? 0 : 2;286 uint32_t org_ip_request_cntl = 0;287 288 if (hws->ctx->dc->debug.disable_dsc_power_gate)289 return;290 291 if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc &&292 hws->ctx->dc->res_pool->dccg->funcs->enable_dsc &&293 power_on)294 hws->ctx->dc->res_pool->dccg->funcs->enable_dsc(295 hws->ctx->dc->res_pool->dccg, dsc_inst);296 297 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);298 if (org_ip_request_cntl == 0)299 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);300 301 switch (dsc_inst) {302 case 0: /* DSC0 */303 REG_UPDATE(DOMAIN16_PG_CONFIG,304 DOMAIN_POWER_GATE, power_gate);305 306 REG_WAIT(DOMAIN16_PG_STATUS,307 DOMAIN_PGFSM_PWR_STATUS, pwr_status,308 1, 1000);309 break;310 case 1: /* DSC1 */311 REG_UPDATE(DOMAIN17_PG_CONFIG,312 DOMAIN_POWER_GATE, power_gate);313 314 REG_WAIT(DOMAIN17_PG_STATUS,315 DOMAIN_PGFSM_PWR_STATUS, pwr_status,316 1, 1000);317 break;318 case 2: /* DSC2 */319 REG_UPDATE(DOMAIN18_PG_CONFIG,320 DOMAIN_POWER_GATE, power_gate);321 322 REG_WAIT(DOMAIN18_PG_STATUS,323 DOMAIN_PGFSM_PWR_STATUS, pwr_status,324 1, 1000);325 break;326 default:327 BREAK_TO_DEBUGGER();328 break;329 }330 331 if (org_ip_request_cntl == 0)332 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);333 334 if (hws->ctx->dc->debug.root_clock_optimization.bits.dsc) {335 if (hws->ctx->dc->res_pool->dccg->funcs->disable_dsc && !power_on)336 hws->ctx->dc->res_pool->dccg->funcs->disable_dsc(337 hws->ctx->dc->res_pool->dccg, dsc_inst);338 }339 340}341 342 343void dcn31_enable_power_gating_plane(344 struct dce_hwseq *hws,345 bool enable)346{347 bool force_on = true; /* disable power gating */348 uint32_t org_ip_request_cntl = 0;349 350 if (enable && !hws->ctx->dc->debug.disable_hubp_power_gate)351 force_on = false;352 353 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);354 if (org_ip_request_cntl == 0)355 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);356 /* DCHUBP0/1/2/3/4/5 */357 REG_UPDATE(DOMAIN0_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);358 REG_UPDATE(DOMAIN2_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);359 /* DPP0/1/2/3/4/5 */360 REG_UPDATE(DOMAIN1_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);361 REG_UPDATE(DOMAIN3_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);362 363 force_on = true; /* disable power gating */364 if (enable && !hws->ctx->dc->debug.disable_dsc_power_gate)365 force_on = false;366 367 /* DCS0/1/2/3/4/5 */368 REG_UPDATE(DOMAIN16_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);369 REG_UPDATE(DOMAIN17_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);370 REG_UPDATE(DOMAIN18_PG_CONFIG, DOMAIN_POWER_FORCEON, force_on);371 372 if (org_ip_request_cntl == 0)373 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);374}375 376void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)377{378 bool is_hdmi_tmds;379 bool is_dp;380 381 ASSERT(pipe_ctx->stream);382 383 if (pipe_ctx->stream_res.stream_enc == NULL)384 return; /* this is not root pipe */385 386 is_hdmi_tmds = dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal);387 is_dp = dc_is_dp_signal(pipe_ctx->stream->signal);388 389 if (!is_hdmi_tmds && !is_dp)390 return;391 392 if (is_hdmi_tmds)393 pipe_ctx->stream_res.stream_enc->funcs->update_hdmi_info_packets(394 pipe_ctx->stream_res.stream_enc,395 &pipe_ctx->stream_res.encoder_info_frame);396 else if (pipe_ctx->stream->ctx->dc->link_srv->dp_is_128b_132b_signal(pipe_ctx)) {397 pipe_ctx->stream_res.hpo_dp_stream_enc->funcs->update_dp_info_packets(398 pipe_ctx->stream_res.hpo_dp_stream_enc,399 &pipe_ctx->stream_res.encoder_info_frame);400 return;401 } else {402 if (pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num)403 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets_sdp_line_num(404 pipe_ctx->stream_res.stream_enc,405 &pipe_ctx->stream_res.encoder_info_frame);406 407 pipe_ctx->stream_res.stream_enc->funcs->update_dp_info_packets(408 pipe_ctx->stream_res.stream_enc,409 &pipe_ctx->stream_res.encoder_info_frame);410 }411}412void dcn31_z10_save_init(struct dc *dc)413{414 union dmub_rb_cmd cmd;415 416 memset(&cmd, 0, sizeof(cmd));417 cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;418 cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;419 420 dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);421}422 423void dcn31_z10_restore(const struct dc *dc)424{425 union dmub_rb_cmd cmd;426 427 /*428 * DMUB notifies whether restore is required.429 * Optimization to avoid sending commands when not required.430 */431 if (!dc_dmub_srv_is_restore_required(dc->ctx->dmub_srv))432 return;433 434 memset(&cmd, 0, sizeof(cmd));435 cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;436 cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_RESTORE;437 438 dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT);439}440 441void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on)442{443 uint32_t power_gate = power_on ? 0 : 1;444 uint32_t pwr_status = power_on ? 0 : 2;445 uint32_t org_ip_request_cntl;446 if (hws->ctx->dc->debug.disable_hubp_power_gate)447 return;448 449 if (REG(DOMAIN0_PG_CONFIG) == 0)450 return;451 REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl);452 if (org_ip_request_cntl == 0)453 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1);454 455 switch (hubp_inst) {456 case 0:457 REG_SET(DOMAIN0_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);458 REG_WAIT(DOMAIN0_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);459 break;460 case 1:461 REG_SET(DOMAIN1_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);462 REG_WAIT(DOMAIN1_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);463 break;464 case 2:465 REG_SET(DOMAIN2_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);466 REG_WAIT(DOMAIN2_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);467 break;468 case 3:469 REG_SET(DOMAIN3_PG_CONFIG, 0, DOMAIN_POWER_GATE, power_gate);470 REG_WAIT(DOMAIN3_PG_STATUS, DOMAIN_PGFSM_PWR_STATUS, pwr_status, 1, 1000);471 break;472 default:473 BREAK_TO_DEBUGGER();474 break;475 }476 if (org_ip_request_cntl == 0)477 REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 0);478}479 480int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config)481{482 struct dcn_hubbub_phys_addr_config config = {0};483 484 config.system_aperture.fb_top = pa_config->system_aperture.fb_top;485 config.system_aperture.fb_offset = pa_config->system_aperture.fb_offset;486 config.system_aperture.fb_base = pa_config->system_aperture.fb_base;487 config.system_aperture.agp_top = pa_config->system_aperture.agp_top;488 config.system_aperture.agp_bot = pa_config->system_aperture.agp_bot;489 config.system_aperture.agp_base = pa_config->system_aperture.agp_base;490 config.gart_config.page_table_start_addr = pa_config->gart_config.page_table_start_addr;491 config.gart_config.page_table_end_addr = pa_config->gart_config.page_table_end_addr;492 493 if (pa_config->gart_config.base_addr_is_mc_addr) {494 /* Convert from MC address to offset into FB */495 config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr -496 pa_config->system_aperture.fb_base +497 pa_config->system_aperture.fb_offset;498 } else499 config.gart_config.page_table_base_addr = pa_config->gart_config.page_table_base_addr;500 501 return dc->res_pool->hubbub->funcs->init_dchub_sys_ctx(dc->res_pool->hubbub, &config);502}503 504static void dcn31_reset_back_end_for_pipe(505 struct dc *dc,506 struct pipe_ctx *pipe_ctx,507 struct dc_state *context)508{509 struct dc_link *link;510 511 DC_LOGGER_INIT(dc->ctx->logger);512 if (pipe_ctx->stream_res.stream_enc == NULL) {513 pipe_ctx->stream = NULL;514 return;515 }516 ASSERT(!pipe_ctx->top_pipe);517 518 dc->hwss.set_abm_immediate_disable(pipe_ctx);519 520 pipe_ctx->stream_res.tg->funcs->set_dsc_config(521 pipe_ctx->stream_res.tg,522 OPTC_DSC_DISABLED, 0, 0);523 pipe_ctx->stream_res.tg->funcs->disable_crtc(pipe_ctx->stream_res.tg);524 pipe_ctx->stream_res.tg->funcs->enable_optc_clock(pipe_ctx->stream_res.tg, false);525 if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass)526 pipe_ctx->stream_res.tg->funcs->set_odm_bypass(527 pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing);528 if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal))529 pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0;530 531 if (pipe_ctx->stream_res.tg->funcs->set_drr)532 pipe_ctx->stream_res.tg->funcs->set_drr(533 pipe_ctx->stream_res.tg, NULL);534 535 link = pipe_ctx->stream->link;536 /* DPMS may already disable or */537 /* dpms_off status is incorrect due to fastboot538 * feature. When system resume from S4 with second539 * screen only, the dpms_off would be true but540 * VBIOS lit up eDP, so check link status too.541 */542 if (!pipe_ctx->stream->dpms_off || link->link_status.link_active)543 dc->link_srv->set_dpms_off(pipe_ctx);544 else if (pipe_ctx->stream_res.audio)545 dc->hwss.disable_audio_stream(pipe_ctx);546 547 /* free acquired resources */548 if (pipe_ctx->stream_res.audio) {549 /*disable az_endpoint*/550 pipe_ctx->stream_res.audio->funcs->az_disable(pipe_ctx->stream_res.audio);551 552 /*free audio*/553 if (dc->caps.dynamic_audio == true) {554 /*we have to dynamic arbitrate the audio endpoints*/555 /*we free the resource, need reset is_audio_acquired*/556 update_audio_usage(&dc->current_state->res_ctx, dc->res_pool,557 pipe_ctx->stream_res.audio, false);558 pipe_ctx->stream_res.audio = NULL;559 }560 }561 562 pipe_ctx->stream = NULL;563 DC_LOG_DEBUG("Reset back end for pipe %d, tg:%d\n",564 pipe_ctx->pipe_idx, pipe_ctx->stream_res.tg->inst);565}566 567void dcn31_reset_hw_ctx_wrap(568 struct dc *dc,569 struct dc_state *context)570{571 int i;572 struct dce_hwseq *hws = dc->hwseq;573 574 /* Reset Back End*/575 for (i = dc->res_pool->pipe_count - 1; i >= 0 ; i--) {576 struct pipe_ctx *pipe_ctx_old =577 &dc->current_state->res_ctx.pipe_ctx[i];578 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];579 580 if (!pipe_ctx_old->stream)581 continue;582 583 if (pipe_ctx_old->top_pipe || pipe_ctx_old->prev_odm_pipe)584 continue;585 586 if (!pipe_ctx->stream ||587 pipe_need_reprogram(pipe_ctx_old, pipe_ctx)) {588 struct clock_source *old_clk = pipe_ctx_old->clock_source;589 590 /* Reset pipe which is seamless boot stream. */591 if (!pipe_ctx_old->plane_state &&592 dc->res_pool->hubbub->funcs->program_det_size &&593 dc->res_pool->hubbub->funcs->wait_for_det_apply) {594 dc->res_pool->hubbub->funcs->program_det_size(595 dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst, 0);596 /* Wait det size changed. */597 dc->res_pool->hubbub->funcs->wait_for_det_apply(598 dc->res_pool->hubbub, pipe_ctx_old->plane_res.hubp->inst);599 }600 601 dcn31_reset_back_end_for_pipe(dc, pipe_ctx_old, dc->current_state);602 if (hws->funcs.enable_stream_gating)603 hws->funcs.enable_stream_gating(dc, pipe_ctx_old);604 if (old_clk)605 old_clk->funcs->cs_power_down(old_clk);606 }607 }608 609 /* New dc_state in the process of being applied to hardware. */610 link_enc_cfg_set_transient_mode(dc, dc->current_state, context);611}612 613void dcn31_setup_hpo_hw_control(const struct dce_hwseq *hws, bool enable)614{615 if (hws->ctx->dc->debug.hpo_optimization)616 REG_UPDATE(HPO_TOP_HW_CONTROL, HPO_IO_EN, !!enable);617}618 619void dcn31_set_static_screen_control(struct pipe_ctx **pipe_ctx,620 int num_pipes, const struct dc_static_screen_params *params)621{622 unsigned int i;623 unsigned int triggers = 0;624 625 if (params->triggers.surface_update)626 triggers |= 0x100;627 if (params->triggers.cursor_update)628 triggers |= 0x8;629 if (params->triggers.force_trigger)630 triggers |= 0x1;631 632 for (i = 0; i < num_pipes; i++)633 pipe_ctx[i]->stream_res.tg->funcs->set_static_screen_control(pipe_ctx[i]->stream_res.tg,634 triggers, params->num_frames);635}636