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: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
cbec6477ce
commit
8f43965f79
@ -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);
|
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
|
* unblank_crtc
|
||||||
* Call ASIC Control Object to 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)
|
void optc1_tg_init(struct timing_generator *optc)
|
||||||
{
|
{
|
||||||
optc1_set_blank_data_double_buffer(optc, true);
|
optc1_set_blank_data_double_buffer(optc, true);
|
||||||
|
optc1_set_timing_double_buffer(optc, true);
|
||||||
optc1_clear_optc_underflow(optc);
|
optc1_clear_optc_underflow(optc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ struct dcn_optc_registers {
|
|||||||
SF(OTG0_OTG_GLOBAL_CONTROL0, OTG_MASTER_UPDATE_LOCK_SEL, mask_sh),\
|
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_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_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_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_START, mask_sh),\
|
||||||
SF(OTG0_OTG_H_BLANK_START_END, OTG_H_BLANK_END, 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_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,
|
bool optc1_get_otg_active_size(struct timing_generator *optc,
|
||||||
uint32_t *otg_active_width,
|
uint32_t *otg_active_width,
|
||||||
uint32_t *otg_active_height);
|
uint32_t *otg_active_height);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user