From a3a885878e74d3d81e4742f8dd84faa27c8863ad Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 20 May 2022 11:55:10 -0400 Subject: [PATCH] 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 Acked-by: Rodrigo Siqueira Signed-off-by: George Shen Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c | 18 ++++++++++-------- 1 file 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 bab85f3..8ece88d 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, -- 2.7.4