brintos

brintos / linux-shallow public Read only

0
0
Text · 18.7 KiB · 1635e5a Raw
616 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#include "dm_services.h"27#include "basics/dc_common.h"28#include "core_types.h"29#include "resource.h"30#include "dcn201_hwseq.h"31#include "dcn201/dcn201_optc.h"32#include "dce/dce_hwseq.h"33#include "hubp.h"34#include "dchubbub.h"35#include "timing_generator.h"36#include "opp.h"37#include "ipp.h"38#include "mpc.h"39#include "dccg.h"40#include "clk_mgr.h"41#include "reg_helper.h"42 43#define CTX \44	hws->ctx45 46#define REG(reg)\47	hws->regs->reg48 49#define DC_LOGGER \50	dc->ctx->logger51 52#undef FN53#define FN(reg_name, field_name) \54	hws->shifts->field_name, hws->masks->field_name55 56static bool patch_address_for_sbs_tb_stereo(57		struct pipe_ctx *pipe_ctx, PHYSICAL_ADDRESS_LOC *addr)58{59	struct dc_plane_state *plane_state = pipe_ctx->plane_state;60	bool sec_split = pipe_ctx->top_pipe &&61		pipe_ctx->top_pipe->plane_state == pipe_ctx->plane_state;62 63	if (sec_split && plane_state->address.type == PLN_ADDR_TYPE_GRPH_STEREO &&64		(pipe_ctx->stream->timing.timing_3d_format ==65			TIMING_3D_FORMAT_SIDE_BY_SIDE ||66		pipe_ctx->stream->timing.timing_3d_format ==67			TIMING_3D_FORMAT_TOP_AND_BOTTOM)) {68		*addr = plane_state->address.grph_stereo.left_addr;69		plane_state->address.grph_stereo.left_addr =70			plane_state->address.grph_stereo.right_addr;71		return true;72	} else {73		if (pipe_ctx->stream->view_format != VIEW_3D_FORMAT_NONE &&74			plane_state->address.type != PLN_ADDR_TYPE_GRPH_STEREO) {75			plane_state->address.type = PLN_ADDR_TYPE_GRPH_STEREO;76			plane_state->address.grph_stereo.right_addr =77			plane_state->address.grph_stereo.left_addr;78			plane_state->address.grph_stereo.right_meta_addr =79			plane_state->address.grph_stereo.left_meta_addr;80		}81	}82	return false;83}84 85static bool gpu_addr_to_uma(struct dce_hwseq *hwseq,86		PHYSICAL_ADDRESS_LOC *addr)87{88	bool is_in_uma;89 90	if (hwseq->fb_base.quad_part <= addr->quad_part &&91			addr->quad_part < hwseq->fb_top.quad_part) {92		addr->quad_part -= hwseq->fb_base.quad_part;93		addr->quad_part += hwseq->fb_offset.quad_part;94		is_in_uma = true;95	} else if (hwseq->fb_offset.quad_part <= addr->quad_part &&96			addr->quad_part <= hwseq->uma_top.quad_part) {97		is_in_uma = true;98	} else if (addr->quad_part == 0) {99		is_in_uma = false;100	} else {101		is_in_uma = false;102		BREAK_TO_DEBUGGER();103	}104	return is_in_uma;105}106 107static void plane_address_in_gpu_space_to_uma(struct dce_hwseq *hwseq,108		struct dc_plane_address *addr)109{110	switch (addr->type) {111	case PLN_ADDR_TYPE_GRAPHICS:112		gpu_addr_to_uma(hwseq, &addr->grph.addr);113		gpu_addr_to_uma(hwseq, &addr->grph.meta_addr);114		break;115	case PLN_ADDR_TYPE_GRPH_STEREO:116		gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_addr);117		gpu_addr_to_uma(hwseq, &addr->grph_stereo.left_meta_addr);118		gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_addr);119		gpu_addr_to_uma(hwseq, &addr->grph_stereo.right_meta_addr);120		break;121	case PLN_ADDR_TYPE_VIDEO_PROGRESSIVE:122		gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_addr);123		gpu_addr_to_uma(hwseq, &addr->video_progressive.luma_meta_addr);124		gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_addr);125		gpu_addr_to_uma(hwseq, &addr->video_progressive.chroma_meta_addr);126		break;127	default:128		BREAK_TO_DEBUGGER();129		break;130	}131}132 133void dcn201_update_plane_addr(const struct dc *dc, struct pipe_ctx *pipe_ctx)134{135	bool addr_patched = false;136	PHYSICAL_ADDRESS_LOC addr;137	struct dc_plane_state *plane_state = pipe_ctx->plane_state;138	struct dce_hwseq *hws = dc->hwseq;139	struct dc_plane_address uma;140 141	if (plane_state == NULL)142		return;143 144	uma = plane_state->address;145	addr_patched = patch_address_for_sbs_tb_stereo(pipe_ctx, &addr);146 147	plane_address_in_gpu_space_to_uma(hws, &uma);148 149	pipe_ctx->plane_res.hubp->funcs->hubp_program_surface_flip_and_addr(150			pipe_ctx->plane_res.hubp,151			&uma,152			plane_state->flip_immediate);153 154	plane_state->status.requested_address = plane_state->address;155 156	if (plane_state->flip_immediate)157		plane_state->status.current_address = plane_state->address;158 159	if (addr_patched)160		pipe_ctx->plane_state->address.grph_stereo.left_addr = addr;161}162 163/* Blank pixel data during initialization */164void dcn201_init_blank(165		struct dc *dc,166		struct timing_generator *tg)167{168	struct dce_hwseq *hws = dc->hwseq;169	enum dc_color_space color_space;170	struct tg_color black_color = {0};171	struct output_pixel_processor *opp = NULL;172	uint32_t num_opps, opp_id_src0, opp_id_src1;173	uint32_t otg_active_width = 0, otg_active_height = 0;174 175	/* program opp dpg blank color */176	color_space = COLOR_SPACE_SRGB;177	color_space_to_black_color(dc, color_space, &black_color);178 179	/* get the OTG active size */180	tg->funcs->get_otg_active_size(tg,181			&otg_active_width,182			&otg_active_height);183 184	/* get the OPTC source */185	tg->funcs->get_optc_source(tg, &num_opps, &opp_id_src0, &opp_id_src1);186	ASSERT(opp_id_src0 < dc->res_pool->res_cap->num_opp);187	opp = dc->res_pool->opps[opp_id_src0];188 189	opp->funcs->opp_set_disp_pattern_generator(190			opp,191			CONTROLLER_DP_TEST_PATTERN_SOLID_COLOR,192			CONTROLLER_DP_COLOR_SPACE_UDEFINED,193			COLOR_DEPTH_UNDEFINED,194			&black_color,195			otg_active_width,196			otg_active_height,197			0);198 199	hws->funcs.wait_for_blank_complete(opp);200}201 202static void read_mmhub_vm_setup(struct dce_hwseq *hws)203{204	uint32_t fb_base = REG_READ(MC_VM_FB_LOCATION_BASE);205	uint32_t fb_top = REG_READ(MC_VM_FB_LOCATION_TOP);206	uint32_t fb_offset = REG_READ(MC_VM_FB_OFFSET);207 208	/* MC_VM_FB_LOCATION_TOP is in pages, actual top should add 1 */209	fb_top++;210 211	/* bit 23:0 in register map to bit 47:24 in address */212	hws->fb_base.low_part = fb_base;213	hws->fb_base.quad_part <<= 24;214 215	hws->fb_top.low_part  = fb_top;216	hws->fb_top.quad_part <<= 24;217	hws->fb_offset.low_part = fb_offset;218	hws->fb_offset.quad_part <<= 24;219 220	hws->uma_top.quad_part = hws->fb_top.quad_part221			- hws->fb_base.quad_part + hws->fb_offset.quad_part;222}223 224void dcn201_init_hw(struct dc *dc)225{226	int i, j;227	struct dce_hwseq *hws = dc->hwseq;228	struct resource_pool *res_pool = dc->res_pool;229	struct dc_state  *context = dc->current_state;230 231	if (res_pool->dccg->funcs->dccg_init)232		res_pool->dccg->funcs->dccg_init(res_pool->dccg);233 234	if (dc->clk_mgr && dc->clk_mgr->funcs->init_clocks)235		dc->clk_mgr->funcs->init_clocks(dc->clk_mgr);236 237	hws->funcs.bios_golden_init(dc);238 239	if (dc->ctx->dc_bios->fw_info_valid) {240		res_pool->ref_clocks.xtalin_clock_inKhz =241			dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency;242 243		if (res_pool->hubbub) {244			(res_pool->dccg->funcs->get_dccg_ref_freq)(res_pool->dccg,245					dc->ctx->dc_bios->fw_info.pll_info.crystal_frequency,246					&res_pool->ref_clocks.dccg_ref_clock_inKhz);247 248			(res_pool->hubbub->funcs->get_dchub_ref_freq)(res_pool->hubbub,249					res_pool->ref_clocks.dccg_ref_clock_inKhz,250					&res_pool->ref_clocks.dchub_ref_clock_inKhz);251		} else {252			res_pool->ref_clocks.dccg_ref_clock_inKhz =253					res_pool->ref_clocks.xtalin_clock_inKhz;254			res_pool->ref_clocks.dchub_ref_clock_inKhz =255					res_pool->ref_clocks.xtalin_clock_inKhz;256		}257	} else258		ASSERT_CRITICAL(false);259	for (i = 0; i < dc->link_count; i++) {260		/* Power up AND update implementation according to the261		 * required signal (which may be different from the262		 * default signal on connector).263		 */264		struct dc_link *link = dc->links[i];265 266		link->link_enc->funcs->hw_init(link->link_enc);267	}268	if (hws->fb_offset.quad_part == 0)269		read_mmhub_vm_setup(hws);270 271	/* Blank pixel data with OPP DPG */272	for (i = 0; i < res_pool->timing_generator_count; i++) {273		struct timing_generator *tg = res_pool->timing_generators[i];274 275		if (tg->funcs->is_tg_enabled(tg)) {276			dcn201_init_blank(dc, tg);277		}278	}279 280	for (i = 0; i < res_pool->timing_generator_count; i++) {281		struct timing_generator *tg = res_pool->timing_generators[i];282 283		if (tg->funcs->is_tg_enabled(tg))284			tg->funcs->lock(tg);285	}286 287	for (i = 0; i < res_pool->pipe_count; i++) {288		struct dpp *dpp = res_pool->dpps[i];289 290		dpp->funcs->dpp_reset(dpp);291	}292 293	/* Reset all MPCC muxes */294	res_pool->mpc->funcs->mpc_init(res_pool->mpc);295 296	/* initialize OPP mpc_tree parameter */297	for (i = 0; i < res_pool->res_cap->num_opp; i++) {298		res_pool->opps[i]->mpc_tree_params.opp_id = res_pool->opps[i]->inst;299		res_pool->opps[i]->mpc_tree_params.opp_list = NULL;300		for (j = 0; j < MAX_PIPES; j++)301			res_pool->opps[i]->mpcc_disconnect_pending[j] = false;302	}303 304	for (i = 0; i < res_pool->timing_generator_count; i++) {305		struct timing_generator *tg = res_pool->timing_generators[i];306		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];307		struct hubp *hubp = res_pool->hubps[i];308		struct dpp *dpp = res_pool->dpps[i];309 310		pipe_ctx->stream_res.tg = tg;311		pipe_ctx->pipe_idx = i;312 313		pipe_ctx->plane_res.hubp = hubp;314		pipe_ctx->plane_res.dpp = dpp;315		pipe_ctx->plane_res.mpcc_inst = dpp->inst;316		hubp->mpcc_id = dpp->inst;317		hubp->opp_id = OPP_ID_INVALID;318		hubp->power_gated = false;319		pipe_ctx->stream_res.opp = NULL;320 321		hubp->funcs->hubp_init(hubp);322 323		res_pool->opps[i]->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;324		pipe_ctx->stream_res.opp = res_pool->opps[i];325		/*To do: number of MPCC != number of opp*/326		hws->funcs.plane_atomic_disconnect(dc, context, pipe_ctx);327	}328 329	/* initialize DWB pointer to MCIF_WB */330	for (i = 0; i < res_pool->res_cap->num_dwb; i++)331		res_pool->dwbc[i]->mcif = res_pool->mcif_wb[i];332 333	for (i = 0; i < res_pool->timing_generator_count; i++) {334		struct timing_generator *tg = res_pool->timing_generators[i];335 336		if (tg->funcs->is_tg_enabled(tg))337			tg->funcs->unlock(tg);338	}339 340	for (i = 0; i < res_pool->pipe_count; i++) {341		struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];342 343		dc->hwss.disable_plane(dc, context, pipe_ctx);344 345		pipe_ctx->stream_res.tg = NULL;346		pipe_ctx->plane_res.hubp = NULL;347	}348 349	for (i = 0; i < res_pool->timing_generator_count; i++) {350		struct timing_generator *tg = res_pool->timing_generators[i];351 352		tg->funcs->tg_init(tg);353	}354 355	for (i = 0; i < res_pool->audio_count; i++) {356		struct audio *audio = res_pool->audios[i];357 358		audio->funcs->hw_init(audio);359	}360 361	/* power AFMT HDMI memory TODO: may move to dis/en output save power*/362	REG_WRITE(DIO_MEM_PWR_CTRL, 0);363 364	if (!dc->debug.disable_clock_gate) {365		/* enable all DCN clock gating */366		REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0);367 368		REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0);369 370		REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0);371	}372}373 374/* trigger HW to start disconnect plane from stream on the next vsync */375void dcn201_plane_atomic_disconnect(struct dc *dc,376		struct dc_state *state,377		struct pipe_ctx *pipe_ctx)378{379	struct dce_hwseq *hws = dc->hwseq;380	struct hubp *hubp = pipe_ctx->plane_res.hubp;381	int dpp_id = pipe_ctx->plane_res.dpp->inst;382	struct mpc *mpc = dc->res_pool->mpc;383	struct mpc_tree *mpc_tree_params;384	struct mpcc *mpcc_to_remove = NULL;385	struct output_pixel_processor *opp = pipe_ctx->stream_res.opp;386	bool mpcc_removed = false;387 388	mpc_tree_params = &(opp->mpc_tree_params);389 390	/* check if this plane is being used by an MPCC in the secondary blending chain */391	if (mpc->funcs->get_mpcc_for_dpp_from_secondary)392		mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);393 394	/* remove MPCC from secondary if being used */395	if (mpcc_to_remove != NULL && mpc->funcs->remove_mpcc_from_secondary) {396		mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, mpcc_to_remove);397		mpcc_removed = true;398	}399 400	/* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */401	mpcc_to_remove = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);402	if (mpcc_to_remove != NULL) {403		mpc->funcs->remove_mpcc(mpc, mpc_tree_params, mpcc_to_remove);404		mpcc_removed = true;405	}406 407	/*Already reset*/408	if (mpcc_removed == false)409		return;410 411	opp->mpcc_disconnect_pending[pipe_ctx->plane_res.mpcc_inst] = true;412 413	dc->optimized_required = true;414 415	if (hubp->funcs->hubp_disconnect)416		hubp->funcs->hubp_disconnect(hubp);417 418	if (dc->debug.sanity_checks)419		hws->funcs.verify_allow_pstate_change_high(dc);420}421 422void dcn201_update_mpcc(struct dc *dc, struct pipe_ctx *pipe_ctx)423{424	struct hubp *hubp = pipe_ctx->plane_res.hubp;425	struct mpcc_blnd_cfg blnd_cfg;426	bool per_pixel_alpha = pipe_ctx->plane_state->per_pixel_alpha && pipe_ctx->bottom_pipe;427	int mpcc_id, dpp_id;428	struct mpcc *new_mpcc;429	struct mpcc *remove_mpcc = NULL;430	struct mpc *mpc = dc->res_pool->mpc;431	struct mpc_tree *mpc_tree_params = &(pipe_ctx->stream_res.opp->mpc_tree_params);432 433	if (dc->debug.visual_confirm == VISUAL_CONFIRM_HDR) {434		get_hdr_visual_confirm_color(435				pipe_ctx, &blnd_cfg.black_color);436	} else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SURFACE) {437		get_surface_visual_confirm_color(438				pipe_ctx, &blnd_cfg.black_color);439	} else {440		color_space_to_black_color(441				dc, pipe_ctx->stream->output_color_space,442				&blnd_cfg.black_color);443	}444 445	if (per_pixel_alpha)446		blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_PER_PIXEL_ALPHA;447	else448		blnd_cfg.alpha_mode = MPCC_ALPHA_BLEND_MODE_GLOBAL_ALPHA;449 450	blnd_cfg.overlap_only = false;451 452	if (pipe_ctx->plane_state->global_alpha_value)453		blnd_cfg.global_alpha = pipe_ctx->plane_state->global_alpha_value;454	else455		blnd_cfg.global_alpha = 0xff;456 457	blnd_cfg.global_gain = 0xff;458	blnd_cfg.background_color_bpc = 4;459	blnd_cfg.bottom_gain_mode = 0;460	blnd_cfg.top_gain = 0x1f000;461	blnd_cfg.bottom_inside_gain = 0x1f000;462	blnd_cfg.bottom_outside_gain = 0x1f000;463	/*the input to MPCC is RGB*/464	blnd_cfg.black_color.color_b_cb = 0;465	blnd_cfg.black_color.color_g_y = 0;466	blnd_cfg.black_color.color_r_cr = 0;467 468	/* DCN1.0 has output CM before MPC which seems to screw with469	 * pre-multiplied alpha. This is a w/a hopefully unnecessary for DCN2.470	 */471	blnd_cfg.pre_multiplied_alpha = per_pixel_alpha;472 473	/*474	 * TODO: remove hack475	 * Note: currently there is a bug in init_hw such that476	 * on resume from hibernate, BIOS sets up MPCC0, and477	 * we do mpcc_remove but the mpcc cannot go to idle478	 * after remove. This cause us to pick mpcc1 here,479	 * which causes a pstate hang for yet unknown reason.480	 */481	dpp_id = hubp->inst;482	mpcc_id = dpp_id;483 484	/* If there is no full update, don't need to touch MPC tree*/485	if (!pipe_ctx->plane_state->update_flags.bits.full_update) {486		dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);487		mpc->funcs->update_blending(mpc, &blnd_cfg, mpcc_id);488		return;489	}490 491	/* check if this plane is being used by an MPCC in the secondary blending chain */492	if (mpc->funcs->get_mpcc_for_dpp_from_secondary)493		remove_mpcc = mpc->funcs->get_mpcc_for_dpp_from_secondary(mpc_tree_params, dpp_id);494 495	/* remove MPCC from secondary if being used */496	if (remove_mpcc != NULL && mpc->funcs->remove_mpcc_from_secondary)497		mpc->funcs->remove_mpcc_from_secondary(mpc, mpc_tree_params, remove_mpcc);498 499	/* check if this MPCC is already being used for this plane (dpp) in the primary blending chain */500	remove_mpcc = mpc->funcs->get_mpcc_for_dpp(mpc_tree_params, dpp_id);501	/* remove MPCC if being used */502 503	if (remove_mpcc != NULL)504		mpc->funcs->remove_mpcc(mpc, mpc_tree_params, remove_mpcc);505	else506		if (dc->debug.sanity_checks)507			mpc->funcs->assert_mpcc_idle_before_connect(508					dc->res_pool->mpc, mpcc_id);509 510	/* Call MPC to insert new plane */511	dc->hwss.update_visual_confirm_color(dc, pipe_ctx, mpcc_id);512	new_mpcc = mpc->funcs->insert_plane(dc->res_pool->mpc,513			mpc_tree_params,514			&blnd_cfg,515			NULL,516			NULL,517			dpp_id,518			mpcc_id);519 520	ASSERT(new_mpcc != NULL);521	hubp->opp_id = pipe_ctx->stream_res.opp->inst;522	hubp->mpcc_id = mpcc_id;523}524 525void dcn201_pipe_control_lock(526	struct dc *dc,527	struct pipe_ctx *pipe,528	bool lock)529{530	struct dce_hwseq *hws = dc->hwseq;531	/* use TG master update lock to lock everything on the TG532	 * therefore only top pipe need to lock533	 */534	if (pipe->top_pipe)535		return;536 537	if (dc->debug.sanity_checks)538		hws->funcs.verify_allow_pstate_change_high(dc);539 540	if (pipe->plane_state != NULL && pipe->plane_state->triplebuffer_flips) {541		if (lock)542			pipe->stream_res.tg->funcs->triplebuffer_lock(pipe->stream_res.tg);543		else544			pipe->stream_res.tg->funcs->triplebuffer_unlock(pipe->stream_res.tg);545	} else {546		if (lock)547			pipe->stream_res.tg->funcs->lock(pipe->stream_res.tg);548		else549			pipe->stream_res.tg->funcs->unlock(pipe->stream_res.tg);550	}551 552	if (dc->debug.sanity_checks)553		hws->funcs.verify_allow_pstate_change_high(dc);554}555 556void dcn201_set_cursor_attribute(struct pipe_ctx *pipe_ctx)557{558	struct dc_cursor_attributes *attributes = &pipe_ctx->stream->cursor_attributes;559 560	gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq, &attributes->address);561 562	pipe_ctx->plane_res.hubp->funcs->set_cursor_attributes(563			pipe_ctx->plane_res.hubp, attributes);564	pipe_ctx->plane_res.dpp->funcs->set_cursor_attributes(565		pipe_ctx->plane_res.dpp, attributes);566}567 568void dcn201_set_dmdata_attributes(struct pipe_ctx *pipe_ctx)569{570	struct dc_dmdata_attributes attr = { 0 };571	struct hubp *hubp = pipe_ctx->plane_res.hubp;572 573	gpu_addr_to_uma(pipe_ctx->stream->ctx->dc->hwseq,574			&pipe_ctx->stream->dmdata_address);575 576	attr.dmdata_mode = DMDATA_HW_MODE;577	attr.dmdata_size =578		dc_is_hdmi_signal(pipe_ctx->stream->signal) ? 32 : 36;579	attr.address.quad_part =580			pipe_ctx->stream->dmdata_address.quad_part;581	attr.dmdata_dl_delta = 0;582	attr.dmdata_qos_mode = 0;583	attr.dmdata_qos_level = 0;584	attr.dmdata_repeat = 1; /* always repeat */585	attr.dmdata_updated = 1;586	attr.dmdata_sw_data = NULL;587 588	hubp->funcs->dmdata_set_attributes(hubp, &attr);589}590 591void dcn201_unblank_stream(struct pipe_ctx *pipe_ctx,592		struct dc_link_settings *link_settings)593{594	struct encoder_unblank_param params = { { 0 } };595	struct dc_stream_state *stream = pipe_ctx->stream;596	struct dc_link *link = stream->link;597	struct dce_hwseq *hws = link->dc->hwseq;598 599	/* only 3 items below are used by unblank */600	params.timing = pipe_ctx->stream->timing;601 602	params.link_settings.link_rate = link_settings->link_rate;603 604	if (dc_is_dp_signal(pipe_ctx->stream->signal)) {605		/*check whether it is half the rate*/606		if (pipe_ctx->stream_res.tg->funcs->is_two_pixels_per_container(&stream->timing))607			params.timing.pix_clk_100hz /= 2;608 609		pipe_ctx->stream_res.stream_enc->funcs->dp_unblank(link, pipe_ctx->stream_res.stream_enc, &params);610	}611 612	if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) {613		hws->funcs.edp_backlight_control(link, true);614	}615}616