Commit 880af2ea authored by Yongqiang Sun's avatar Yongqiang Sun Committed by Alex Deucher

drm/amd/display: cap dpp dto phase not more than modulo.

[Why]
4K monitor shows corruption if dpp dto phase is larger than modulo.

[How]
cap phase value never larger than modulo.
Signed-off-by: default avatarYongqiang Sun <yongqiang.sun@amd.com>
Acked-by: default avatarBindu Ramamurthy <bindu.r@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 4b0b1d05
......@@ -50,43 +50,47 @@ void dccg21_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk)
if (dccg->ref_dppclk) {
int ref_dppclk = dccg->ref_dppclk;
int modulo = ref_dppclk / 10000;
int phase;
if (req_dppclk) {
int phase;
/*
* program DPP DTO phase and modulo as below
* phase = dpp_pipe_clk_mhz / 10
* module = dpp_global_clk_mhz / 10
* dmub FW will read phase value to
* determine minimum dpp clk and notify smu
* to set clks for more power saving in PSR state
* phase = ceiling(dpp_pipe_clk_mhz / 10)
* module = trunc(dpp_global_clk_mhz / 10)
*
* storing frequencies in registers allow dmcub fw
* to run time lower clocks when possible for power saving
*
* ceiling phase and truncate modulo guarentees the divided
* down per pipe dpp clock has high enough frequency
*/
phase = (req_dppclk + 9999) / 10000;
if (phase > 0xff) {
ASSERT(false);
phase = 0xff;
if (phase > modulo) {
/* phase > modulo result in screen corruption
* ie phase = 30, mod = 29 for 4k@60 HDMI
* in these case we don't want pipe clock to be divided
*/
phase = modulo;
}
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, phase,
DPPCLK0_DTO_MODULO, modulo);
REG_UPDATE(DPPCLK_DTO_CTRL,
DPPCLK_DTO_ENABLE[dpp_inst], 1);
} else {
/*
* set phase to 10 if dpp isn't used to
* prevent hard hang if access dpp register
* on unused pipe
*
* DTO should be on to divide down un-used
* pipe clock for power saving
*/
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, 10,
phase = 10;
}
REG_SET_2(DPPCLK_DTO_PARAM[dpp_inst], 0,
DPPCLK0_DTO_PHASE, phase,
DPPCLK0_DTO_MODULO, modulo);
REG_UPDATE(DPPCLK_DTO_CTRL,
DPPCLK_DTO_ENABLE[dpp_inst], 0);
}
REG_UPDATE(DPPCLK_DTO_CTRL,
DPPCLK_DTO_ENABLE[dpp_inst], 1);
}
dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk;
......
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