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>
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;
}