[PATCH 14/24] drm/amd/display: FreeSync LFC MIN/MAX update on current frame

Harry Wentland harry.wentland at amd.com
Tue Apr 25 18:39:03 UTC 2017


From: Eric Cook <Eric.Cook at amd.com>

- Update BTR/LFC logic so that V_TOTAL_MIN/MAX will take affect on current frame
- Add in FreeSync update to MPO code path

Change-Id: I12fb498254086fbae8f19b4b3c718104dab62486
Signed-off-by: Eric Cook <Eric.Cook at amd.com>
Acked-by: Harry Wentland <Harry.Wentland at amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo at amd.com>
---
 .../drm/amd/display/modules/freesync/freesync.c    | 67 +++++++++++++---------
 1 file changed, 39 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 7a0731e2dbb0..94566c0a0e62 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -641,7 +641,8 @@ static void set_static_ramp_variables(struct core_freesync *core_freesync,
 void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
 		const struct dc_stream **streams, int num_streams)
 {
-	unsigned int index, v_total = 0;
+	unsigned int index, v_total, inserted_frame_v_total = 0;
+	unsigned int min_frame_duration_in_ns, vmax, vmin = 0;
 	struct freesync_state *state;
 	struct core_freesync *core_freesync = NULL;
 
@@ -665,19 +666,48 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
 
 	/* Only execute if in fullscreen mode */
 	if (state->fullscreen == true &&
-		core_freesync->map[index].user_enable.enable_for_gaming) {
+		core_freesync->map[index].user_enable.enable_for_gaming &&
+		core_freesync->map[index].caps->btr_supported &&
+		state->btr.btr_active) {
+
+		/* TODO: pass in flag for Pre-DCE12 ASIC
+		 * in order for frame variable duration to take affect,
+		 * it needs to be done one VSYNC early, which is at
+		 * frameCounter == 1.
+		 * For DCE12 and newer updates to V_TOTAL_MIN/MAX
+		 * will take affect on current frame
+		 */
+		if (state->btr.frames_to_insert == state->btr.frame_counter) {
+
+			min_frame_duration_in_ns = ((unsigned int) (div64_u64(
+					(1000000000ULL * 1000000),
+					state->nominal_refresh_rate_in_micro_hz)));
+
+			calc_vmin_vmax(core_freesync, *streams, &vmin, &vmax);
 
-		if (state->btr.btr_active)
-			if (state->btr.frame_counter > 0)
+			inserted_frame_v_total = vmin;
 
-				state->btr.frame_counter--;
+			if (min_frame_duration_in_ns / 1000)
+				inserted_frame_v_total =
+					state->btr.inserted_frame_duration_in_us *
+					vmin / (min_frame_duration_in_ns / 1000);
 
-		if (state->btr.frame_counter == 1) {
+			/* Set length of inserted frames as v_total_max*/
+			vmax = inserted_frame_v_total;
+			vmin = inserted_frame_v_total;
 
-			/* Restore FreeSync */
-			set_freesync_on_streams(core_freesync, streams,
-					num_streams);
+			/* Program V_TOTAL */
+			core_freesync->dc->stream_funcs.adjust_vmin_vmax(
+				core_freesync->dc, streams,
+				num_streams, vmin, vmax);
 		}
+
+		if (state->btr.frame_counter > 0)
+			state->btr.frame_counter--;
+
+		/* Restore FreeSync */
+		if (state->btr.frame_counter == 0)
+			set_freesync_on_streams(core_freesync, streams, num_streams);
 	}
 
 	/* If in fullscreen freesync mode or in video, do not program
@@ -1022,8 +1052,6 @@ 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 inserted_frame_v_total = 0;
-	unsigned int vmin = 0, vmax = 0;
 	unsigned int min_frame_duration_in_ns = 0;
 	struct freesync_state *state = &core_freesync->map[map_index].state;
 
@@ -1101,23 +1129,6 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
 			inserted_frame_duration_in_us =
 				state->time.min_render_time_in_us;
 
-		/* We need the v_total_min from capability */
-		calc_vmin_vmax(core_freesync, stream, &vmin, &vmax);
-
-		inserted_frame_v_total = vmin;
-		if (min_frame_duration_in_ns / 1000)
-			inserted_frame_v_total = inserted_frame_duration_in_us *
-				vmin / (min_frame_duration_in_ns / 1000);
-
-		/* Set length of inserted frames as v_total_max*/
-		vmax = inserted_frame_v_total;
-
-		/* Program V_TOTAL */
-		core_freesync->dc->stream_funcs.adjust_vmin_vmax(
-			core_freesync->dc, &stream,
-			1, vmin,
-			vmax);
-
 		/* Cache the calculated variables */
 		state->btr.inserted_frame_duration_in_us =
 			inserted_frame_duration_in_us;
-- 
2.11.0



More information about the amd-gfx mailing list