aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0347-drm-amd-display-FreeSync-LFC-MIN-MAX-update-on-curre.patch
blob: 764ef48ac4c040f13df500ffb73b624b3bd277dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From 7b72607acfacbe862c111c87f2a34155c370bced Mon Sep 17 00:00:00 2001
From: Eric Cook <Eric.Cook@amd.com>
Date: Wed, 12 Apr 2017 11:05:08 -0400
Subject: [PATCH 0347/4131] drm/amd/display: FreeSync LFC MIN/MAX update on
 current frame

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

Signed-off-by: Eric Cook <Eric.Cook@amd.com>
Acked-by: Harry Wentland <Harry.Wentland@amd.com>
Reviewed-by: Anthony Koo <Anthony.Koo@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@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 7a0731e..94566c0 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.7.4