brintos

brintos / linux-shallow public Read only

0
0
Text · 20.0 KiB · 3d4b31b Raw
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