]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/amd/display: Fix divide by zero in calc_psr_num_static_frames
authorSrinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Thu, 23 Apr 2026 13:16:13 +0000 (18:46 +0530)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 24 Apr 2026 14:52:04 +0000 (10:52 -0400)
calc_psr_num_static_frames() divides by vsync_rate_hz before checking
whether it is zero:

frame_time_microsec = 1000000 / vsync_rate_hz;

This can trigger a divide-by-zero bug if an invalid refresh rate is
passed in.

Rewrite the calculation to directly compute the number of frames needed
for at least 30 ms using DIV_ROUND_UP(). This avoids the invalid divisor
and removes the temporary frame_time_microsec calculation.

Keep the existing fallback behavior of 2 static frames when
vsync_rate_hz is zero.

Fixes: 4cef2ac4c795 ("drm/amd/display: Introduce power module on Linux")
Reported-by: Dan Carpenter <error27@gmail.com>
Cc: Leo Li <sunpeng.li@amd.com>
Cc: Ray Wu <ray.wu@amd.com>
Cc: Chenyu Chen <chen-yu.chen@amd.com>
Signed-off-by: Srinivasan Shanmugam <srinivasan.shanmugam@amd.com>
Reviewed-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/modules/power/power.c

index 6c73fecf57d5e54cc0b8d8960354678928304cdb..81d15a51e0454f73e069593fbaf7aed8f8df4f06 100644 (file)
@@ -157,20 +157,14 @@ static const unsigned int default_dc_backlight_percent   = 70;
 
 static unsigned int calc_psr_num_static_frames(unsigned int vsync_rate_hz)
 {
-       /* Calculate number of static frames before generating interrupt to
-        * enter PSR.
-        */
-       unsigned int frame_time_microsec = 1000000 / vsync_rate_hz;
-
-       // Init fail safe of 2 frames static
+       /* Initialize fail-safe to 2 static frames. */
        unsigned int num_frames_static = 2;
 
-       /* Round up
-        * Calculate number of frames such that at least 30 ms of time has
-        * passed.
+       /* Calculate number of frames such that at least 30 ms has passed.
+        * Round up to ensure the static period is not shorter than 30 ms.
         */
        if (vsync_rate_hz != 0)
-               num_frames_static = (30000 / frame_time_microsec) + 1;
+               num_frames_static = DIV_ROUND_UP(30000 * vsync_rate_hz, 1000000);
 
        return num_frames_static;
 }