aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Shen <[email protected]>2022-05-20 11:55:10 -0400
committerAlex Deucher <[email protected]>2022-06-21 18:17:24 -0400
commita3a885878e74d3d81e4742f8dd84faa27c8863ad (patch)
tree8d81d97eff03aea7dca2792929bd4d0c0449aead
parent04e6931a76e592e66e1014ffe4d13303ccac5d8b (diff)
drm/amd/display: Fix divide-by-zero in DPPCLK and DISPCLK calculation
[Why] Certain use cases will pass in zero in the new_clocks parameter for all clocks. This results in a divide-by-zero error when attempting to round up the new clock. When new_clocks are zero, no rounding is required, so we can skip it. [How] Guard the division calculation with a check to make sure clocks are not zero. Tested-by: Daniel Wheeler <[email protected]> Acked-by: Rodrigo Siqueira <[email protected]> Signed-off-by: George Shen <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
-rw-r--r--drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
index bab85f3c9c67..8ece88ddfb5b 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
@@ -335,14 +335,16 @@ static void dcn32_update_dppclk_dispclk_freq(struct clk_mgr_internal *clk_mgr, s
int dpp_divider = 0;
int disp_divider = 0;
- dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz / new_clocks->dppclk_khz;
- disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
- * clk_mgr->base.dentist_vco_freq_khz / new_clocks->dispclk_khz;
-
- // Divide back the previous result to round up to the actual clock value that will be set from divider
- new_clocks->dppclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / dpp_divider;
- new_clocks->dispclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / disp_divider;
+ if (new_clocks->dppclk_khz) {
+ dpp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz / new_clocks->dppclk_khz;
+ new_clocks->dppclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / dpp_divider;
+ }
+ if (new_clocks->dispclk_khz > 0) {
+ disp_divider = DENTIST_DIVIDER_RANGE_SCALE_FACTOR
+ * clk_mgr->base.dentist_vco_freq_khz / new_clocks->dispclk_khz;
+ new_clocks->dispclk_khz = (DENTIST_DIVIDER_RANGE_SCALE_FACTOR * clk_mgr->base.dentist_vco_freq_khz) / disp_divider;
+ }
}
static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,