Commit 8f43965f authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher
Browse files

drm/amd/display: Use double buffered DRR timing update by default



[Why]
For some monitors extreme flickering can occur while using LFC for if
we're not doing the DRR timing update for V_TOTAL_MIN / V_TOTAL_MAX at
the DP start of frame.

Hardware can default to any time in the frame which isn't the behavior
we want.

[How]
Add a new function for setting the double buffering mode for DRR timing.

Default to DP start of frame double buffering on timing generator init.

Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent cbec6477
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -342,6 +342,23 @@ void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enab
			OTG_BLANK_DATA_DOUBLE_BUFFER_EN, blank_data_double_buffer_enable);
}

/**
 * optc1_set_timing_double_buffer() - DRR double buffering control
 *
 * Sets double buffer point for V_TOTAL, H_TOTAL, VTOTAL_MIN,
 * VTOTAL_MAX, VTOTAL_MIN_SEL and VTOTAL_MAX_SEL registers.
 *
 * Options: any time,  start of frame, dp start of frame (range timing)
 */
void optc1_set_timing_double_buffer(struct timing_generator *optc, bool enable)
{
	struct optc *optc1 = DCN10TG_FROM_TG(optc);
	uint32_t mode = enable ? 2 : 0;

	REG_UPDATE(OTG_DOUBLE_BUFFER_CONTROL,
		   OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mode);
}

/**
 * unblank_crtc
 * Call ASIC Control Object to UnBlank CRTC.
@@ -1353,6 +1370,7 @@ void optc1_clear_optc_underflow(struct timing_generator *optc)
void optc1_tg_init(struct timing_generator *optc)
{
	optc1_set_blank_data_double_buffer(optc, true);
	optc1_set_timing_double_buffer(optc, true);
	optc1_clear_optc_underflow(optc);
}

+3 −0
Original line number Diff line number Diff line
@@ -185,6 +185,7 @@ struct dcn_optc_registers {
	SF(OTG0_OTG_GLOBAL_CONTROL0, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\
	SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_UPDATE_PENDING, mask_sh),\
	SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_BLANK_DATA_DOUBLE_BUFFER_EN, mask_sh),\
	SF(OTG0_OTG_DOUBLE_BUFFER_CONTROL, OTG_RANGE_TIMING_DBUF_UPDATE_MODE, mask_sh),\
	SF(OTG0_OTG_H_TOTAL, OTG_H_TOTAL, mask_sh),\
	SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_START, mask_sh),\
	SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, mask_sh),\
@@ -643,6 +644,8 @@ bool optc1_is_optc_underflow_occurred(struct timing_generator *optc);

void optc1_set_blank_data_double_buffer(struct timing_generator *optc, bool enable);

void optc1_set_timing_double_buffer(struct timing_generator *optc, bool enable);

bool optc1_get_otg_active_size(struct timing_generator *optc,
		uint32_t *otg_active_width,
		uint32_t *otg_active_height);