diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dcn30')
15 files changed, 333 insertions, 126 deletions
| diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c index fa981cd04dd0..95528e5ef89e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.c @@ -44,11 +44,14 @@  	afmt3->base.ctx -static void afmt3_setup_hdmi_audio( +void afmt3_setup_hdmi_audio(  	struct afmt *afmt)  {  	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); +	if (afmt->funcs->afmt_poweron) +		afmt->funcs->afmt_poweron(afmt); +  	/* AFMT_AUDIO_PACKET_CONTROL */  	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); @@ -113,7 +116,7 @@ static union audio_cea_channels speakers_to_channels(  	return cea_channels;  } -static void afmt3_se_audio_setup( +void afmt3_se_audio_setup(  	struct afmt *afmt,  	unsigned int az_inst,  	struct audio_info *audio_info) @@ -138,20 +141,24 @@ static void afmt3_se_audio_setup(  	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);  	/* Disable forced mem power off */ -	REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0); +	if (afmt->funcs->afmt_poweron == NULL) +		REG_UPDATE(AFMT_MEM_PWR, AFMT_MEM_PWR_FORCE, 0);  } -static void afmt3_audio_mute_control( +void afmt3_audio_mute_control(  	struct afmt *afmt,  	bool mute)  {  	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); - +	if (mute && afmt->funcs->afmt_powerdown) +		afmt->funcs->afmt_powerdown(afmt); +	if (!mute && afmt->funcs->afmt_poweron) +		afmt->funcs->afmt_poweron(afmt);  	/* enable/disable transmission of audio packets */  	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);  } -static void afmt3_audio_info_immediate_update( +void afmt3_audio_info_immediate_update(  	struct afmt *afmt)  {  	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); @@ -160,11 +167,14 @@ static void afmt3_audio_info_immediate_update(  	REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);  } -static void afmt3_setup_dp_audio( +void afmt3_setup_dp_audio(  		struct afmt *afmt)  {  	struct dcn30_afmt *afmt3 = DCN30_AFMT_FROM_AFMT(afmt); +	if (afmt->funcs->afmt_poweron) +		afmt->funcs->afmt_poweron(afmt); +  	/* AFMT_AUDIO_PACKET_CONTROL */  	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h index 85d4619207e2..97e0cf62f98e 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_afmt.h @@ -121,6 +121,12 @@ struct afmt_funcs {  	void (*setup_dp_audio)(  		struct afmt *afmt); + +	void (*afmt_poweron)( +		struct afmt *afmt); + +	void (*afmt_powerdown)( +		struct afmt *afmt);  };  struct afmt { @@ -136,6 +142,24 @@ struct dcn30_afmt {  	const struct dcn30_afmt_mask *afmt_mask;  }; +void afmt3_setup_hdmi_audio( +	struct afmt *afmt); + +void afmt3_se_audio_setup( +	struct afmt *afmt, +	unsigned int az_inst, +	struct audio_info *audio_info); + +void afmt3_audio_mute_control( +	struct afmt *afmt, +	bool mute); + +void afmt3_audio_info_immediate_update( +	struct afmt *afmt); + +void afmt3_setup_dp_audio( +		struct afmt *afmt); +  void afmt3_construct(struct dcn30_afmt *afmt3,  	struct dc_context *ctx,  	uint32_t inst, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c index 46ea39f5ef8d..6f3c2fb60790 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_link_encoder.c @@ -192,6 +192,10 @@ void dcn30_link_encoder_construct(  		enc10->base.features.flags.bits.IS_HBR3_CAPABLE =  				bp_cap_info.DP_HBR3_EN;  		enc10->base.features.flags.bits.HDMI_6GB_EN = bp_cap_info.HDMI_6GB_EN; +		enc10->base.features.flags.bits.IS_DP2_CAPABLE = bp_cap_info.IS_DP2_CAPABLE; +		enc10->base.features.flags.bits.IS_UHBR10_CAPABLE = bp_cap_info.DP_UHBR10_EN; +		enc10->base.features.flags.bits.IS_UHBR13_5_CAPABLE = bp_cap_info.DP_UHBR13_5_EN; +		enc10->base.features.flags.bits.IS_UHBR20_CAPABLE = bp_cap_info.DP_UHBR20_EN;  		enc10->base.features.flags.bits.DP_IS_USB_C =  				bp_cap_info.DP_IS_USB_C;  	} else { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c index 8487516819ef..ebd9c35c914f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dio_stream_encoder.c @@ -77,7 +77,8 @@ static void enc3_update_hdmi_info_packet(  		enc1->base.vpg->funcs->update_generic_info_packet(  				enc1->base.vpg,  				packet_index, -				info_packet); +				info_packet, +				true);  		/* enable transmission of packet(s) -  		 * packet transmission begins on the next frame */ @@ -335,7 +336,8 @@ static void enc3_dp_set_dsc_config(struct stream_encoder *enc,  static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,  					bool enable, -					uint8_t *dsc_packed_pps) +					uint8_t *dsc_packed_pps, +					bool immediate_update)  {  	struct dcn10_stream_encoder *enc1 = DCN10STRENC_FROM_STRENC(enc); @@ -365,7 +367,8 @@ static void enc3_dp_set_dsc_pps_info_packet(struct stream_encoder *enc,  			enc1->base.vpg->funcs->update_generic_info_packet(  							enc1->base.vpg,  							11 + i, -							&pps_sdp); +							&pps_sdp, +							immediate_update);  		}  		/* SW should make sure VBID[6] update line number is bigger @@ -429,19 +432,22 @@ static void enc3_stream_encoder_update_dp_info_packets(  		enc->vpg->funcs->update_generic_info_packet(  				enc->vpg,  				0,  /* packetIndex */ -				&info_frame->vsc); +				&info_frame->vsc, +				true);  	}  	if (info_frame->spd.valid) {  		enc->vpg->funcs->update_generic_info_packet(  				enc->vpg,  				2,  /* packetIndex */ -				&info_frame->spd); +				&info_frame->spd, +				true);  	}  	if (info_frame->hdrsmd.valid) {  		enc->vpg->funcs->update_generic_info_packet(  				enc->vpg,  				3,  /* packetIndex */ -				&info_frame->hdrsmd); +				&info_frame->hdrsmd, +				true);  	}  	/* packetIndex 4 is used for send immediate sdp message, and please  	 * use other packetIndex (such as 5,6) for other info packet diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c index 23a52d47e61c..c1d967ed6551 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp.c @@ -488,6 +488,54 @@ void dpp3_cnv_set_bias_scale(  	REG_UPDATE(FCNV_FP_SCALE_B, FCNV_FP_SCALE_B, bias_and_scale->scale_blue);  } +void dpp3_deferred_update( +	struct dpp *dpp_base) +{ +	int bypass_state; +	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base); + +	if (dpp_base->deferred_reg_writes.bits.disable_dscl) { +		REG_UPDATE(DSCL_MEM_PWR_CTRL, LUT_MEM_PWR_FORCE, 3); +		dpp_base->deferred_reg_writes.bits.disable_dscl = false; +	} + +	if (dpp_base->deferred_reg_writes.bits.disable_gamcor) { +		REG_GET(CM_GAMCOR_CONTROL, CM_GAMCOR_MODE_CURRENT, &bypass_state); +		if (bypass_state == 0) {	// only program if bypass was latched +			REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 3); +		} else +			ASSERT(0); // LUT select was updated again before vupdate +		dpp_base->deferred_reg_writes.bits.disable_gamcor = false; +	} + +	if (dpp_base->deferred_reg_writes.bits.disable_blnd_lut) { +		REG_GET(CM_BLNDGAM_CONTROL, CM_BLNDGAM_MODE_CURRENT, &bypass_state); +		if (bypass_state == 0) {	// only program if bypass was latched +			REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 3); +		} else +			ASSERT(0); // LUT select was updated again before vupdate +		dpp_base->deferred_reg_writes.bits.disable_blnd_lut = false; +	} + +	if (dpp_base->deferred_reg_writes.bits.disable_3dlut) { +		REG_GET(CM_3DLUT_MODE, CM_3DLUT_MODE_CURRENT, &bypass_state); +		if (bypass_state == 0) {	// only program if bypass was latched +			REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 3); +		} else +			ASSERT(0); // LUT select was updated again before vupdate +		dpp_base->deferred_reg_writes.bits.disable_3dlut = false; +	} + +	if (dpp_base->deferred_reg_writes.bits.disable_shaper) { +		REG_GET(CM_SHAPER_CONTROL, CM_SHAPER_MODE_CURRENT, &bypass_state); +		if (bypass_state == 0) {	// only program if bypass was latched +			REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 3); +		} else +			ASSERT(0); // LUT select was updated again before vupdate +		dpp_base->deferred_reg_writes.bits.disable_shaper = false; +	} +} +  static void dpp3_power_on_blnd_lut(  	struct dpp *dpp_base,  	bool power_on) @@ -495,9 +543,13 @@ static void dpp3_power_on_blnd_lut(  	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);  	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { -		REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, power_on ? 0 : 3); -		if (power_on) +		if (power_on) { +			REG_UPDATE(CM_MEM_PWR_CTRL, BLNDGAM_MEM_PWR_FORCE, 0);  			REG_WAIT(CM_MEM_PWR_STATUS, BLNDGAM_MEM_PWR_STATE, 0, 1, 5); +		} else { +			dpp_base->ctx->dc->optimized_required = true; +			dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true; +		}  	} else {  		REG_SET(CM_MEM_PWR_CTRL, 0,  				BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0 : 1); @@ -511,9 +563,13 @@ static void dpp3_power_on_hdr3dlut(  	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);  	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { -		REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, power_on ? 0 : 3); -		if (power_on) +		if (power_on) { +			REG_UPDATE(CM_MEM_PWR_CTRL2, HDR3DLUT_MEM_PWR_FORCE, 0);  			REG_WAIT(CM_MEM_PWR_STATUS2, HDR3DLUT_MEM_PWR_STATE, 0, 1, 5); +		} else { +			dpp_base->ctx->dc->optimized_required = true; +			dpp_base->deferred_reg_writes.bits.disable_3dlut = true; +		}  	}  } @@ -524,9 +580,13 @@ static void dpp3_power_on_shaper(  	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);  	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { -		REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, power_on ? 0 : 3); -		if (power_on) +		if (power_on) { +			REG_UPDATE(CM_MEM_PWR_CTRL2, SHAPER_MEM_PWR_FORCE, 0);  			REG_WAIT(CM_MEM_PWR_STATUS2, SHAPER_MEM_PWR_STATE, 0, 1, 5); +		} else { +			dpp_base->ctx->dc->optimized_required = true; +			dpp_base->deferred_reg_writes.bits.disable_shaper = true; +		}  	}  } @@ -1400,6 +1460,7 @@ static struct dpp_funcs dcn30_dpp_funcs = {  	.dpp_program_blnd_lut = dpp3_program_blnd_lut,  	.dpp_program_shaper_lut = dpp3_program_shaper,  	.dpp_program_3dlut = dpp3_program_3dlut, +	.dpp_deferred_update = dpp3_deferred_update,  	.dpp_program_bias_and_scale	= NULL,  	.dpp_cnv_set_alpha_keyer	= dpp2_cnv_set_alpha_keyer,  	.set_cursor_attributes		= dpp3_set_cursor_attributes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c index 72c5687adc68..387eec616162 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_dpp_cm.c @@ -136,9 +136,13 @@ static void dpp3_power_on_gamcor_lut(  	struct dcn3_dpp *dpp = TO_DCN30_DPP(dpp_base);  	if (dpp_base->ctx->dc->debug.enable_mem_low_power.bits.cm) { -		REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, power_on ? 0 : 3); -		if (power_on) +		if (power_on) { +			REG_UPDATE(CM_MEM_PWR_CTRL, GAMCOR_MEM_PWR_FORCE, 0);  			REG_WAIT(CM_MEM_PWR_STATUS, GAMCOR_MEM_PWR_STATE, 0, 1, 5); +		} else { +			dpp_base->ctx->dc->optimized_required = true; +			dpp_base->deferred_reg_writes.bits.disable_gamcor = true; +		}  	} else  		REG_SET(CM_MEM_PWR_CTRL, 0,  				GAMCOR_MEM_PWR_DIS, power_on == true ? 0:1); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c index f24612523248..eac08926b574 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hubp.c @@ -356,12 +356,6 @@ void hubp3_dcc_control_sienna_cichlid(struct hubp *hubp,  {  	struct dcn20_hubp *hubp2 = TO_DCN20_HUBP(hubp); -	/*Workaround until UMD fix the new dcc_ind_blk interface */ -	if (dcc->independent_64b_blks && dcc->dcc_ind_blk == 0) -		dcc->dcc_ind_blk = 1; -	if (dcc->independent_64b_blks_c && dcc->dcc_ind_blk_c == 0) -		dcc->dcc_ind_blk_c = 1; -  	REG_UPDATE_6(DCSURF_SURFACE_CONTROL,  		PRIMARY_SURFACE_DCC_EN, dcc->enable,  		PRIMARY_SURFACE_DCC_IND_BLK, dcc->dcc_ind_blk, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c index fafed1e4a998..df2717116604 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_hwseq.c @@ -559,7 +559,7 @@ void dcn30_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;  						} @@ -1002,7 +1002,8 @@ void dcn30_set_disp_pattern_generator(const struct dc *dc,  		/* turning off DPG */  		pipe_ctx->plane_res.hubp->funcs->set_blank(pipe_ctx->plane_res.hubp, false);  		for (mpcc_pipe = pipe_ctx->bottom_pipe; mpcc_pipe; mpcc_pipe = mpcc_pipe->bottom_pipe) -			mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false); +			if (mpcc_pipe->plane_res.hubp) +				mpcc_pipe->plane_res.hubp->funcs->set_blank(mpcc_pipe->plane_res.hubp, false);  		stream_res->opp->funcs->opp_set_disp_pattern_generator(stream_res->opp, test_pattern, color_space,  				color_depth, solid_color, width, height, offset); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c index 3a5b53dd2f6d..93f32a312fee 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_init.c @@ -100,6 +100,7 @@ static const struct hw_sequencer_funcs dcn30_funcs = {  	.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,  	.get_dcc_en_bits = dcn10_get_dcc_en_bits,  	.update_visual_confirm_color = dcn20_update_visual_confirm_color, +	.is_abm_supported = dcn21_is_abm_supported  };  static const struct hwseq_private_funcs dcn30_private_funcs = { diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c index a82319f4d081..95149734378b 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_mpc.c @@ -1381,13 +1381,11 @@ int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id)  } -static void mpc3_mpc_init(struct mpc *mpc) +static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)  {  	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);  	int mpcc_id; -	mpc1_mpc_init(mpc); -  	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {  		if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) {  			REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3); @@ -1405,7 +1403,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {  	.read_mpcc_state = mpc1_read_mpcc_state,  	.insert_plane = mpc1_insert_plane,  	.remove_mpcc = mpc1_remove_mpcc, -	.mpc_init = mpc3_mpc_init, +	.mpc_init = mpc1_mpc_init,  	.mpc_init_single_inst = mpc1_mpc_init_single_inst,  	.update_blending = mpc2_update_blending,  	.cursor_lock = mpc1_cursor_lock, @@ -1432,6 +1430,7 @@ const struct mpc_funcs dcn30_mpc_funcs = {  	.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,  	.get_mpc_out_mux = mpc1_get_mpc_out_mux,  	.set_bg_color = mpc1_set_bg_color, +	.set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode,  };  void dcn30_mpc_construct(struct dcn30_mpc *mpc30, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c index 089be7347591..5d9e6413d67a 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_optc.c @@ -73,16 +73,23 @@ void optc3_lock_doublebuffer_enable(struct timing_generator *optc)  		OTG_H_BLANK_END, &h_blank_end);  	REG_UPDATE_2(OTG_GLOBAL_CONTROL1, -		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start, -		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_end); +		MASTER_UPDATE_LOCK_DB_START_Y, v_blank_start - 1, +		MASTER_UPDATE_LOCK_DB_END_Y, v_blank_start);  	REG_UPDATE_2(OTG_GLOBAL_CONTROL4, -		DIG_UPDATE_POSITION_X, 20, -		DIG_UPDATE_POSITION_Y, v_blank_start); +		DIG_UPDATE_POSITION_X, h_blank_start - 180 - 1, +		DIG_UPDATE_POSITION_Y, v_blank_start - 1); +	// there is a DIG_UPDATE_VCOUNT_MODE and it is 0. +  	REG_UPDATE_3(OTG_GLOBAL_CONTROL0,  		MASTER_UPDATE_LOCK_DB_START_X, h_blank_start - 200 - 1, -		MASTER_UPDATE_LOCK_DB_END_X, h_blank_end, +		MASTER_UPDATE_LOCK_DB_END_X, h_blank_start - 180,  		MASTER_UPDATE_LOCK_DB_EN, 1);  	REG_UPDATE(OTG_GLOBAL_CONTROL2, GLOBAL_UPDATE_LOCK_EN, 1); + +	REG_SET_3(OTG_VUPDATE_KEEPOUT, 0, +		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_START_OFFSET, 0, +		MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_END_OFFSET, 100, +		OTG_MASTER_UPDATE_LOCK_VUPDATE_KEEPOUT_EN, 1);  }  void optc3_lock_doublebuffer_disable(struct timing_generator *optc) diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c index a0de309475a9..79a66e0c4303 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.c @@ -1164,8 +1164,12 @@ struct stream_encoder *dcn30_stream_encoder_create(  	vpg = dcn30_vpg_create(ctx, vpg_inst);  	afmt = dcn30_afmt_create(ctx, afmt_inst); -	if (!enc1 || !vpg || !afmt) +	if (!enc1 || !vpg || !afmt) { +		kfree(enc1); +		kfree(vpg); +		kfree(afmt);  		return NULL; +	}  	dcn30_dio_stream_encoder_construct(enc1, ctx, ctx->dc_bios,  					eng_id, vpg, afmt, @@ -1703,9 +1707,6 @@ bool dcn30_release_post_bldn_3dlut(  	return ret;  } -#define fixed16_to_double(x) (((double) x) / ((double) (1 << 16))) -#define fixed16_to_double_to_cpu(x) fixed16_to_double(le32_to_cpu(x)) -  static bool is_soc_bounding_box_valid(struct dc *dc)  {  	uint32_t hw_internal_rev = dc->ctx->asic_id.hw_internal_rev; @@ -1856,7 +1857,7 @@ static struct pipe_ctx *dcn30_find_split_pipe(  	return pipe;  } -static noinline bool dcn30_internal_validate_bw( +noinline bool dcn30_internal_validate_bw(  		struct dc *dc,  		struct dc_state *context,  		display_e2e_pipe_params_st *pipes, @@ -1925,23 +1926,25 @@ static noinline bool dcn30_internal_validate_bw(  	if (vlevel == context->bw_ctx.dml.soc.num_states)  		goto validate_fail; -	for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { -		struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; -		struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; +	if (!dc->config.enable_windowed_mpo_odm) { +		for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) { +			struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; +			struct pipe_ctx *mpo_pipe = pipe->bottom_pipe; -		if (!pipe->stream) -			continue; +			if (!pipe->stream) +				continue; -		/* We only support full screen mpo with ODM */ -		if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled -				&& pipe->plane_state && mpo_pipe -				&& memcmp(&mpo_pipe->plane_res.scl_data.recout, -						&pipe->plane_res.scl_data.recout, -						sizeof(struct rect)) != 0) { -			ASSERT(mpo_pipe->plane_state != pipe->plane_state); -			goto validate_fail; +			/* We only support full screen mpo with ODM */ +			if (vba->ODMCombineEnabled[vba->pipe_plane[pipe_idx]] != dm_odm_combine_mode_disabled +					&& pipe->plane_state && mpo_pipe +					&& memcmp(&mpo_pipe->plane_res.scl_data.recout, +							&pipe->plane_res.scl_data.recout, +							sizeof(struct rect)) != 0) { +				ASSERT(mpo_pipe->plane_state != pipe->plane_state); +				goto validate_fail; +			} +			pipe_idx++;  		} -		pipe_idx++;  	}  	/* merge pipes if necessary */ @@ -2125,10 +2128,10 @@ static noinline void dcn30_calculate_wm_and_dlg_fp(  		int pipe_cnt,  		int vlevel)  { +	int maxMpcComb = context->bw_ctx.dml.vba.maxMpcComb;  	int i, pipe_idx; -	double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][context->bw_ctx.dml.vba.maxMpcComb]; -	bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][context->bw_ctx.dml.vba.maxMpcComb] != -			dm_dram_clock_change_unsupported; +	double dcfclk = context->bw_ctx.dml.vba.DCFCLKState[vlevel][maxMpcComb]; +	bool pstate_en = context->bw_ctx.dml.vba.DRAMClockChangeSupport[vlevel][maxMpcComb] != dm_dram_clock_change_unsupported;  	if (context->bw_ctx.dml.soc.min_dcfclk > dcfclk)  		dcfclk = context->bw_ctx.dml.soc.min_dcfclk; @@ -2204,6 +2207,7 @@ static noinline void dcn30_calculate_wm_and_dlg_fp(  		context->bw_ctx.dml.soc.sr_enter_plus_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_enter_plus_exit_time_us;  		context->bw_ctx.dml.soc.sr_exit_time_us = dc->clk_mgr->bw_params->wm_table.nv_entries[WM_C].dml_input.sr_exit_time_us;  	} +  	context->bw_ctx.bw.dcn.watermarks.c.urgent_ns = get_wm_urgent(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;  	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000;  	context->bw_ctx.bw.dcn.watermarks.c.cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(&context->bw_ctx.dml, pipes, pipe_cnt) * 1000; @@ -2319,7 +2323,9 @@ bool dcn30_validate_bandwidth(struct dc *dc,  		goto validate_out;  	} +	DC_FP_START();  	dc->res_pool->funcs->calculate_wm_and_dlg(dc, context, pipes, pipe_cnt, vlevel); +	DC_FP_END();  	BW_VAL_TRACE_END_WATERMARKS(); diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h index b754b89beadf..b92e4cc0232f 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_resource.h @@ -55,6 +55,13 @@ unsigned int dcn30_calc_max_scaled_time(  bool dcn30_validate_bandwidth(struct dc *dc, struct dc_state *context,  		bool fast_validate); +bool dcn30_internal_validate_bw( +		struct dc *dc, +		struct dc_state *context, +		display_e2e_pipe_params_st *pipes, +		int *pipe_cnt_out, +		int *vlevel_out, +		bool fast_validate);  void dcn30_calculate_wm_and_dlg(  		struct dc *dc, struct dc_state *context,  		display_e2e_pipe_params_st *pipes, diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c index 8cfd181b4d5f..14bc44b1f886 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.c @@ -43,10 +43,11 @@  	vpg3->base.ctx -static void vpg3_update_generic_info_packet( +void vpg3_update_generic_info_packet(  	struct vpg *vpg,  	uint32_t packet_index, -	const struct dc_info_packet *info_packet) +	const struct dc_info_packet *info_packet, +	bool immediate_update)  {  	struct dcn30_vpg *vpg3 = DCN30_VPG_FROM_VPG(vpg);  	uint32_t i; @@ -106,69 +107,138 @@ static void vpg3_update_generic_info_packet(  	/* atomically update double-buffered GENERIC0 registers in immediate mode  	 * (update at next block_update when block_update_lock == 0).  	 */ -	switch (packet_index) { -	case 0: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC0_IMMEDIATE_UPDATE, 1); -		break; -	case 1: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC1_IMMEDIATE_UPDATE, 1); -		break; -	case 2: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC2_IMMEDIATE_UPDATE, 1); -		break; -	case 3: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC3_IMMEDIATE_UPDATE, 1); -		break; -	case 4: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC4_IMMEDIATE_UPDATE, 1); -		break; -	case 5: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC5_IMMEDIATE_UPDATE, 1); -		break; -	case 6: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC6_IMMEDIATE_UPDATE, 1); -		break; -	case 7: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC7_IMMEDIATE_UPDATE, 1); -		break; -	case 8: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC8_IMMEDIATE_UPDATE, 1); -		break; -	case 9: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC9_IMMEDIATE_UPDATE, 1); -		break; -	case 10: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC10_IMMEDIATE_UPDATE, 1); -		break; -	case 11: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC11_IMMEDIATE_UPDATE, 1); -		break; -	case 12: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC12_IMMEDIATE_UPDATE, 1); -		break; -	case 13: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC13_IMMEDIATE_UPDATE, 1); -		break; -	case 14: -		REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, -				VPG_GENERIC14_IMMEDIATE_UPDATE, 1); -		break; -	default: -		break; +	if (immediate_update) { +		switch (packet_index) { +		case 0: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC0_IMMEDIATE_UPDATE, 1); +			break; +		case 1: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC1_IMMEDIATE_UPDATE, 1); +			break; +		case 2: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC2_IMMEDIATE_UPDATE, 1); +			break; +		case 3: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC3_IMMEDIATE_UPDATE, 1); +			break; +		case 4: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC4_IMMEDIATE_UPDATE, 1); +			break; +		case 5: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC5_IMMEDIATE_UPDATE, 1); +			break; +		case 6: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC6_IMMEDIATE_UPDATE, 1); +			break; +		case 7: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC7_IMMEDIATE_UPDATE, 1); +			break; +		case 8: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC8_IMMEDIATE_UPDATE, 1); +			break; +		case 9: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC9_IMMEDIATE_UPDATE, 1); +			break; +		case 10: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC10_IMMEDIATE_UPDATE, 1); +			break; +		case 11: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC11_IMMEDIATE_UPDATE, 1); +			break; +		case 12: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC12_IMMEDIATE_UPDATE, 1); +			break; +		case 13: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC13_IMMEDIATE_UPDATE, 1); +			break; +		case 14: +			REG_UPDATE(VPG_GSP_IMMEDIATE_UPDATE_CTRL, +					VPG_GENERIC14_IMMEDIATE_UPDATE, 1); +			break; +		default: +			break; +		} +	} else { +		switch (packet_index) { +		case 0: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC0_FRAME_UPDATE, 1); +			break; +		case 1: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC1_FRAME_UPDATE, 1); +			break; +		case 2: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC2_FRAME_UPDATE, 1); +			break; +		case 3: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC3_FRAME_UPDATE, 1); +			break; +		case 4: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC4_FRAME_UPDATE, 1); +			break; +		case 5: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC5_FRAME_UPDATE, 1); +			break; +		case 6: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC6_FRAME_UPDATE, 1); +			break; +		case 7: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC7_FRAME_UPDATE, 1); +			break; +		case 8: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC8_FRAME_UPDATE, 1); +			break; +		case 9: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC9_FRAME_UPDATE, 1); +			break; +		case 10: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC10_FRAME_UPDATE, 1); +			break; +		case 11: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC11_FRAME_UPDATE, 1); +			break; +		case 12: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC12_FRAME_UPDATE, 1); +			break; +		case 13: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC13_FRAME_UPDATE, 1); +			break; +		case 14: +			REG_UPDATE(VPG_GSP_FRAME_UPDATE_CTRL, +					VPG_GENERIC14_FRAME_UPDATE, 1); +			break; + +		default: +			break; +		} +  	}  } diff --git a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h index 6161e9e66355..ed9a5549c389 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h +++ b/drivers/gpu/drm/amd/display/dc/dcn30/dcn30_vpg.h @@ -138,7 +138,14 @@ struct vpg_funcs {  	void (*update_generic_info_packet)(  		struct vpg *vpg,  		uint32_t packet_index, -		const struct dc_info_packet *info_packet); +		const struct dc_info_packet *info_packet, +		bool immediate_update); + +	void (*vpg_poweron)( +		struct vpg *vpg); + +	void (*vpg_powerdown)( +		struct vpg *vpg);  };  struct vpg { @@ -154,6 +161,12 @@ struct dcn30_vpg {  	const struct dcn30_vpg_mask *vpg_mask;  }; +void vpg3_update_generic_info_packet( +	struct vpg *vpg, +	uint32_t packet_index, +	const struct dc_info_packet *info_packet, +	bool immediate_update); +  void vpg3_construct(struct dcn30_vpg *vpg3,  	struct dc_context *ctx,  	uint32_t inst, | 
