From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 924592E63E for ; Mon, 9 Oct 2023 13:29:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="FdFCs1k3" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0A821C433C9; Mon, 9 Oct 2023 13:29:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1696858179; bh=bnU9je6qHZo3oa0v+9ztG8cJ7teill9WWhhh/wLN9XA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FdFCs1k3A4Opo+HUFwNyV3WLeaNEYQYry/3YSoYWBb6eWyo54lVqeIAsENgSQXsa0 JX5KSlIr8fntH5ZqOmUAnebdzqVLZKLiwfLEqBrvS2tDMP4YIhJG6XsHaWUjcfzWem nM9YW7abaNl8MszXQFM2AMxvovsi3VBrLEN5wdXU= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Anthony Koo , Aric Cyr , Qingqing Zhuo , Alex Deucher , Sasha Levin Subject: [PATCH 5.4 040/131] drm/amd/display: Fix LFC multiplier changing erratically Date: Mon, 9 Oct 2023 15:01:20 +0200 Message-ID: <20231009130117.536360898@linuxfoundation.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20231009130116.329529591@linuxfoundation.org> References: <20231009130116.329529591@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Anthony Koo [ Upstream commit 575da8db31572d1d8de572d0b6ffb113624c2f8f ] [Why] 1. There is a calculation that is using frame_time_in_us instead of last_render_time_in_us to calculate whether choosing an LFC multiplier would cause the inserted frame duration to be outside of range. 2. We do not handle unsigned integer subtraction correctly and it underflows to a really large value, which causes some logic errors. [How] 1. Fix logic to calculate 'within range' using last_render_time_in_us 2. Split out delta_from_mid_point_delta_in_us calculation to ensure we don't underflow and wrap around Signed-off-by: Anthony Koo Reviewed-by: Aric Cyr Acked-by: Qingqing Zhuo Signed-off-by: Alex Deucher Stable-dep-of: 07e388aab042 ("drm/amd/display: prevent potential division by zero errors") Signed-off-by: Sasha Levin --- .../amd/display/modules/freesync/freesync.c | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index dbbd7d2765ea5..5835b968cac5d 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -320,22 +320,44 @@ static void apply_below_the_range(struct core_freesync *core_freesync, /* Choose number of frames to insert based on how close it * can get to the mid point of the variable range. + * - Delta for CEIL: delta_from_mid_point_in_us_1 + * - Delta for FLOOR: delta_from_mid_point_in_us_2 */ - if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us && - (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 || - mid_point_frames_floor < 2)) { + if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) { + /* Check for out of range. + * If using CEIL produces a value that is out of range, + * then we are forced to use FLOOR. + */ + frames_to_insert = mid_point_frames_floor; + } else if (mid_point_frames_floor < 2) { + /* Check if FLOOR would result in non-LFC. In this case + * choose to use CEIL + */ + frames_to_insert = mid_point_frames_ceil; + } else if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { + /* If choosing CEIL results in a frame duration that is + * closer to the mid point of the range. + * Choose CEIL + */ frames_to_insert = mid_point_frames_ceil; - delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 - - delta_from_mid_point_in_us_1; } else { + /* If choosing FLOOR results in a frame duration that is + * closer to the mid point of the range. + * Choose FLOOR + */ frames_to_insert = mid_point_frames_floor; - delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 - - delta_from_mid_point_in_us_2; } /* Prefer current frame multiplier when BTR is enabled unless it drifts * too far from the midpoint */ + if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { + delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 - + delta_from_mid_point_in_us_1; + } else { + delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 - + delta_from_mid_point_in_us_2; + } if (in_out_vrr->btr.frames_to_insert != 0 && delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) { if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) < -- 2.40.1