Commit f382e2d0 authored by Yihan Zhu's avatar Yihan Zhu Committed by Alex Deucher
Browse files

drm/amd/display: wait for otg update pending latch before clock optimization



[WHY & HOW]
OTG pending update unlatched will cause system fail, wait OTG fully disabled to
avoid this error.

Reviewed-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: default avatarYihan Zhu <Yihan.Zhu@amd.com>
Signed-off-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: default avatarDan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 048ce48c
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1177,6 +1177,8 @@ void hwss_wait_for_odm_update_pending_complete(struct dc *dc, struct dc_state *c
		tg = otg_master->stream_res.tg;
		if (tg->funcs->wait_odm_doublebuffer_pending_clear)
			tg->funcs->wait_odm_doublebuffer_pending_clear(tg);
		if (tg->funcs->wait_otg_disable)
			tg->funcs->wait_otg_disable(tg);
	}

	/* ODM update may require to reprogram blank pattern for each OPP */
+1 −0
Original line number Diff line number Diff line
@@ -374,6 +374,7 @@ struct timing_generator_funcs {
	void (*wait_drr_doublebuffer_pending_clear)(struct timing_generator *tg);
	void (*set_long_vtotal)(struct timing_generator *optc, const struct long_vtotal_params *params);
	void (*wait_odm_doublebuffer_pending_clear)(struct timing_generator *tg);
	void (*wait_otg_disable)(struct timing_generator *optc);
	bool (*get_optc_double_buffer_pending)(struct timing_generator *tg);
	bool (*get_otg_double_buffer_pending)(struct timing_generator *tg);
	bool (*get_pipe_update_pending)(struct timing_generator *tg);
+1 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
	SF(OTG0_OTG_CONTROL, OTG_DISABLE_POINT_CNTL, mask_sh),\
	SF(OTG0_OTG_CONTROL, OTG_FIELD_NUMBER_CNTL, mask_sh),\
	SF(OTG0_OTG_CONTROL, OTG_OUT_MUX, mask_sh),\
	SF(OTG0_OTG_CONTROL, OTG_CURRENT_MASTER_EN_STATE, mask_sh),\
	SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_EN, mask_sh),\
	SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_LINE_NUM, mask_sh),\
	SF(OTG0_OTG_STEREO_CONTROL, OTG_STEREO_SYNC_OUTPUT_POLARITY, mask_sh),\
+18 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ static bool optc35_disable_crtc(struct timing_generator *optc)
	REG_WAIT(OTG_CLOCK_CONTROL,
			OTG_BUSY, 0,
			1, 100000);
	REG_WAIT(OTG_CONTROL, OTG_CURRENT_MASTER_EN_STATE, 0, 1, 100000);

	optc1_clear_optc_underflow(optc);

	return true;
@@ -428,6 +430,21 @@ static void optc35_set_long_vtotal(
	}
}

static void optc35_wait_otg_disable(struct timing_generator *optc)
{
	struct optc *optc1;
	uint32_t is_master_en;

	if (!optc || !optc->ctx)
		return;

	optc1 = DCN10TG_FROM_TG(optc);

	REG_GET(OTG_CONTROL, OTG_MASTER_EN, &is_master_en);
	if (!is_master_en)
		REG_WAIT(OTG_CLOCK_CONTROL, OTG_CURRENT_MASTER_EN_STATE, 0, 1, 100000);
}

static const struct timing_generator_funcs dcn35_tg_funcs = {
		.validate_timing = optc1_validate_timing,
		.program_timing = optc1_program_timing,
@@ -479,6 +496,7 @@ static const struct timing_generator_funcs dcn35_tg_funcs = {
		.set_odm_bypass = optc32_set_odm_bypass,
		.set_odm_combine = optc35_set_odm_combine,
		.get_optc_source = optc2_get_optc_source,
		.wait_otg_disable = optc35_wait_otg_disable,
		.set_h_timing_div_manual_mode = optc32_set_h_timing_div_manual_mode,
		.set_out_mux = optc3_set_out_mux,
		.set_drr_trigger_window = optc3_set_drr_trigger_window,