Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 11e3f781 authored by Amanda Liu's avatar Amanda Liu Committed by Greg Kroah-Hartman
Browse files

drm/amd/display: Reinstate LFC optimization



[ Upstream commit ded6119e825aaf0bfc7f2a578b549d610da852a7 ]

[why]
We want to streamline the calculations made when entering LFC.
Previously, the optimizations led to screen tearing and were backed out
to unblock development.

[how]
Integrate other calculations parameters, as well as screen tearing,
fixes with the original LFC calculation optimizations.

Signed-off-by: default avatarAmanda Liu <amanda.liu@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Stable-dep-of: 07e388aab042 ("drm/amd/display: prevent potential division by zero errors")
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent a4628a5b
Loading
Loading
Loading
Loading
+19 −13
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@
#define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
/* Number of elements in the render times cache array */
#define RENDER_TIMES_MAX_COUNT 10
/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
#define BTR_EXIT_MARGIN 2000
/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */
#define BTR_MAX_MARGIN 2500
/* Threshold to change BTR multiplier (to avoid frequent changes) */
#define BTR_DRIFT_MARGIN 2000
/*Threshold to exit fixed refresh rate*/
@@ -250,25 +250,23 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
	unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF;
	unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF;
	unsigned int frames_to_insert = 0;
	unsigned int min_frame_duration_in_ns = 0;
	unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
	unsigned int delta_from_mid_point_delta_in_us;

	min_frame_duration_in_ns = ((unsigned int) (div64_u64(
		(1000000000ULL * 1000000),
		in_out_vrr->max_refresh_in_uhz)));
	unsigned int max_render_time_in_us =
			in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us;

	/* Program BTR */
	if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) {
	if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) {
		/* Exit Below the Range */
		if (in_out_vrr->btr.btr_active) {
			in_out_vrr->btr.frame_counter = 0;
			in_out_vrr->btr.btr_active = false;
		}
	} else if (last_render_time_in_us > max_render_time_in_us) {
	} else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) {
		/* Enter Below the Range */
		if (!in_out_vrr->btr.btr_active) {
			in_out_vrr->btr.btr_active = true;
		}
	}

	/* BTR set to "not active" so disengage */
	if (!in_out_vrr->btr.btr_active) {
@@ -323,7 +321,9 @@ 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.
		 */
		if (delta_from_mid_point_in_us_1 < 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)) {
			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;
@@ -339,7 +339,7 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
		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) <
					in_out_vrr->max_duration_in_us) &&
					max_render_time_in_us) &&
				((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) >
					in_out_vrr->min_duration_in_us))
				frames_to_insert = in_out_vrr->btr.frames_to_insert;
@@ -792,6 +792,11 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
		refresh_range = in_out_vrr->max_refresh_in_uhz -
				in_out_vrr->min_refresh_in_uhz;

		in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us -
				2 * in_out_vrr->min_duration_in_us;
		if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN)
			in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN;

		in_out_vrr->supported = true;
	}

@@ -808,6 +813,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
	in_out_vrr->btr.inserted_duration_in_us = 0;
	in_out_vrr->btr.frames_to_insert = 0;
	in_out_vrr->btr.frame_counter = 0;

	in_out_vrr->btr.mid_point_in_us =
				(in_out_vrr->min_duration_in_us +
				 in_out_vrr->max_duration_in_us) / 2;
+1 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ struct mod_vrr_params_btr {
	uint32_t inserted_duration_in_us;
	uint32_t frames_to_insert;
	uint32_t frame_counter;
	uint32_t margin_in_us;
};

struct mod_vrr_params_fixed_refresh {