Commit 01c0c124 authored by Dillon Varone's avatar Dillon Varone Committed by Alex Deucher

drm/amd/display: Enforce minimum prefetch time for low memclk on DCN32

[WHY?]
Data return times when using lowest memclk can be <= 60us, which can cause
underflow on high bandwidth displays with a workload.

[HOW?]
Enforce a minimum prefetch time during validation for low memclk modes.
Reviewed-by: default avatarJun Lei <Jun.Lei@amd.com>
Acked-by: default avatarAlan Liu <HaoPing.Liu@amd.com>
Signed-off-by: default avatarDillon Varone <Dillon.Varone@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ea192af5
...@@ -864,6 +864,7 @@ struct dc_debug_options { ...@@ -864,6 +864,7 @@ struct dc_debug_options {
bool enable_dp_dig_pixel_rate_div_policy; bool enable_dp_dig_pixel_rate_div_policy;
enum lttpr_mode lttpr_mode_override; enum lttpr_mode lttpr_mode_override;
unsigned int dsc_delay_factor_wa_x1000; unsigned int dsc_delay_factor_wa_x1000;
unsigned int min_prefetch_in_strobe_ns;
}; };
struct gpu_info_soc_bounding_box_v1_0; struct gpu_info_soc_bounding_box_v1_0;
......
...@@ -724,6 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = { ...@@ -724,6 +724,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.enable_dp_dig_pixel_rate_div_policy = 1, .enable_dp_dig_pixel_rate_div_policy = 1,
.allow_sw_cursor_fallback = false, .allow_sw_cursor_fallback = false,
.alloc_extra_way_for_cursor = true, .alloc_extra_way_for_cursor = true,
.min_prefetch_in_strobe_ns = 60000, // 60us
}; };
static const struct dc_debug_options debug_defaults_diags = { static const struct dc_debug_options debug_defaults_diags = {
......
...@@ -722,6 +722,7 @@ static const struct dc_debug_options debug_defaults_drv = { ...@@ -722,6 +722,7 @@ static const struct dc_debug_options debug_defaults_drv = {
.enable_dp_dig_pixel_rate_div_policy = 1, .enable_dp_dig_pixel_rate_div_policy = 1,
.allow_sw_cursor_fallback = false, .allow_sw_cursor_fallback = false,
.alloc_extra_way_for_cursor = true, .alloc_extra_way_for_cursor = true,
.min_prefetch_in_strobe_ns = 60000, // 60us
}; };
static const struct dc_debug_options debug_defaults_diags = { static const struct dc_debug_options debug_defaults_diags = {
......
...@@ -2351,6 +2351,8 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa ...@@ -2351,6 +2351,8 @@ void dcn32_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_pa
/* DML DSC delay factor workaround */ /* DML DSC delay factor workaround */
dcn3_2_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0; dcn3_2_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0;
dcn3_2_ip.min_prefetch_in_strobe_us = dc->debug.min_prefetch_in_strobe_ns / 1000.0;
/* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */ /* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */
dcn3_2_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dcn3_2_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
......
...@@ -786,6 +786,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman ...@@ -786,6 +786,8 @@ static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerforman
v->SwathHeightY[k], v->SwathHeightY[k],
v->SwathHeightC[k], v->SwathHeightC[k],
TWait, TWait,
v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ ?
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
/* Output */ /* Output */
&v->DSTXAfterScaler[k], &v->DSTXAfterScaler[k],
&v->DSTYAfterScaler[k], &v->DSTYAfterScaler[k],
...@@ -3245,6 +3247,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l ...@@ -3245,6 +3247,8 @@ void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
v->swath_width_chroma_ub_this_state[k], v->swath_width_chroma_ub_this_state[k],
v->SwathHeightYThisState[k], v->SwathHeightYThisState[k],
v->SwathHeightCThisState[k], v->TWait, v->SwathHeightCThisState[k], v->TWait,
v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ ?
mode_lib->vba.ip.min_prefetch_in_strobe_us : 0,
/* Output */ /* Output */
&v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k],
......
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
#define BPP_INVALID 0 #define BPP_INVALID 0
#define BPP_BLENDED_PIPE 0xffffffff #define BPP_BLENDED_PIPE 0xffffffff
#define MEM_STROBE_FREQ_MHZ 1600
#define MEM_STROBE_MAX_DELIVERY_TIME_US 60.0
struct display_mode_lib; struct display_mode_lib;
void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib); void dml32_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_lib);
......
...@@ -3417,6 +3417,7 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -3417,6 +3417,7 @@ bool dml32_CalculatePrefetchSchedule(
unsigned int SwathHeightY, unsigned int SwathHeightY,
unsigned int SwathHeightC, unsigned int SwathHeightC,
double TWait, double TWait,
double TPreReq,
/* Output */ /* Output */
double *DSTXAfterScaler, double *DSTXAfterScaler,
double *DSTYAfterScaler, double *DSTYAfterScaler,
...@@ -3474,6 +3475,7 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -3474,6 +3475,7 @@ bool dml32_CalculatePrefetchSchedule(
double min_Lsw; double min_Lsw;
double Tsw_est1 = 0; double Tsw_est1 = 0;
double Tsw_est3 = 0; double Tsw_est3 = 0;
double TPreMargin = 0;
if (v->GPUVMEnable == true && v->HostVMEnable == true) if (v->GPUVMEnable == true && v->HostVMEnable == true)
HostVMDynamicLevelsTrips = v->HostVMMaxNonCachedPageTableLevels; HostVMDynamicLevelsTrips = v->HostVMMaxNonCachedPageTableLevels;
...@@ -3699,6 +3701,8 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -3699,6 +3701,8 @@ bool dml32_CalculatePrefetchSchedule(
dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0; dst_y_prefetch_equ = dml_floor(4.0 * (dst_y_prefetch_equ + 0.125), 1) / 4.0;
Tpre_rounded = dst_y_prefetch_equ * LineTime; Tpre_rounded = dst_y_prefetch_equ * LineTime;
TPreMargin = Tpre_rounded - TPreReq;
#ifdef __DML_VBA_DEBUG__ #ifdef __DML_VBA_DEBUG__
dml_print("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, dst_y_prefetch_equ); dml_print("DML::%s: dst_y_prefetch_equ: %f (after round)\n", __func__, dst_y_prefetch_equ);
dml_print("DML::%s: LineTime: %f\n", __func__, LineTime); dml_print("DML::%s: LineTime: %f\n", __func__, LineTime);
...@@ -3726,7 +3730,7 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -3726,7 +3730,7 @@ bool dml32_CalculatePrefetchSchedule(
*VRatioPrefetchY = 0; *VRatioPrefetchY = 0;
*VRatioPrefetchC = 0; *VRatioPrefetchC = 0;
*RequiredPrefetchPixDataBWLuma = 0; *RequiredPrefetchPixDataBWLuma = 0;
if (dst_y_prefetch_equ > 1) { if (dst_y_prefetch_equ > 1 && TPreMargin > 0.0) {
double PrefetchBandwidth1; double PrefetchBandwidth1;
double PrefetchBandwidth2; double PrefetchBandwidth2;
double PrefetchBandwidth3; double PrefetchBandwidth3;
...@@ -3872,7 +3876,11 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -3872,7 +3876,11 @@ bool dml32_CalculatePrefetchSchedule(
} }
if (dst_y_prefetch_oto < dst_y_prefetch_equ) { if (dst_y_prefetch_oto < dst_y_prefetch_equ) {
*DestinationLinesForPrefetch = dst_y_prefetch_oto; if (dst_y_prefetch_oto * LineTime < TPreReq) {
*DestinationLinesForPrefetch = dst_y_prefetch_equ;
} else {
*DestinationLinesForPrefetch = dst_y_prefetch_oto;
}
TimeForFetchingMetaPTE = Tvm_oto; TimeForFetchingMetaPTE = Tvm_oto;
TimeForFetchingRowInVBlank = Tr0_oto; TimeForFetchingRowInVBlank = Tr0_oto;
*PrefetchBandwidth = prefetch_bw_oto; *PrefetchBandwidth = prefetch_bw_oto;
......
...@@ -743,6 +743,7 @@ bool dml32_CalculatePrefetchSchedule( ...@@ -743,6 +743,7 @@ bool dml32_CalculatePrefetchSchedule(
unsigned int SwathHeightY, unsigned int SwathHeightY,
unsigned int SwathHeightC, unsigned int SwathHeightC,
double TWait, double TWait,
double TPreReq,
/* Output */ /* Output */
double *DSTXAfterScaler, double *DSTXAfterScaler,
double *DSTYAfterScaler, double *DSTYAfterScaler,
......
...@@ -544,6 +544,8 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p ...@@ -544,6 +544,8 @@ void dcn321_update_bw_bounding_box_fpu(struct dc *dc, struct clk_bw_params *bw_p
/* DML DSC delay factor workaround */ /* DML DSC delay factor workaround */
dcn3_21_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0; dcn3_21_ip.dsc_delay_factor_wa = dc->debug.dsc_delay_factor_wa_x1000 / 1000.0;
dcn3_21_ip.min_prefetch_in_strobe_us = dc->debug.min_prefetch_in_strobe_ns / 1000.0;
/* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */ /* Override dispclk_dppclk_vco_speed_mhz from Clk Mgr */
dcn3_21_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dcn3_21_soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0; dc->dml.soc.dispclk_dppclk_vco_speed_mhz = dc->clk_mgr->dentist_vco_freq_khz / 1000.0;
......
...@@ -367,6 +367,7 @@ struct _vcs_dpi_ip_params_st { ...@@ -367,6 +367,7 @@ struct _vcs_dpi_ip_params_st {
/* DM workarounds */ /* DM workarounds */
double dsc_delay_factor_wa; // TODO: Remove after implementing root cause fix double dsc_delay_factor_wa; // TODO: Remove after implementing root cause fix
double min_prefetch_in_strobe_us;
}; };
struct _vcs_dpi_display_xfc_params_st { struct _vcs_dpi_display_xfc_params_st {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment