aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
diff options
context:
space:
mode:
authorAnthony Koo <Anthony.Koo@amd.com>2017-06-27 13:27:00 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 18:08:23 -0400
commitd09fec0f94376b1c0048215e14838295730ed6d3 (patch)
tree117fc6b4425aaada0b35a5bc68b9bafc8d71bac4 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c
parentdc0ea008168bfbc61a7915eb6ffb1cc48ce5e9cc (diff)
drm/amd/display: add hyst frames for fixed refresh
Signed-off-by: Anthony Koo <anthony.koo@amd.com> Reviewed-by: Anthony Koo <Anthony.Koo@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r--drivers/gpu/drm/amd/display/modules/freesync/freesync.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 7109742bd67c..c7da90f2d8e7 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -37,6 +37,9 @@
37#define RENDER_TIMES_MAX_COUNT 20 37#define RENDER_TIMES_MAX_COUNT 20
38/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ 38/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
39#define BTR_EXIT_MARGIN 2000 39#define BTR_EXIT_MARGIN 2000
40/* Number of consecutive frames to check before entering/exiting fixed refresh*/
41#define FIXED_REFRESH_ENTER_FRAME_COUNT 5
42#define FIXED_REFRESH_EXIT_FRAME_COUNT 5
40 43
41#define FREESYNC_REGISTRY_NAME "freesync_v1" 44#define FREESYNC_REGISTRY_NAME "freesync_v1"
42 45
@@ -72,8 +75,9 @@ struct below_the_range {
72}; 75};
73 76
74struct fixed_refresh { 77struct fixed_refresh {
75 bool fixed_refresh_active; 78 bool fixed_active;
76 bool program_fixed_refresh; 79 bool program_fixed;
80 unsigned int frame_counter;
77}; 81};
78 82
79struct freesync_range { 83struct freesync_range {
@@ -168,8 +172,8 @@ struct mod_freesync *mod_freesync_create(struct dc *dc)
168 /* Create initial module folder in registry for freesync enable data */ 172 /* Create initial module folder in registry for freesync enable data */
169 flag.save_per_edid = true; 173 flag.save_per_edid = true;
170 flag.save_per_link = false; 174 flag.save_per_link = false;
171 dm_write_persistent_data(core_dc->ctx, NULL, FREESYNC_REGISTRY_NAME, NULL, NULL, 175 dm_write_persistent_data(core_dc->ctx, NULL, FREESYNC_REGISTRY_NAME,
172 0, &flag); 176 NULL, NULL, 0, &flag);
173 flag.save_per_edid = false; 177 flag.save_per_edid = false;
174 flag.save_per_link = false; 178 flag.save_per_link = false;
175 if (dm_read_persistent_data(core_dc->ctx, NULL, NULL, 179 if (dm_read_persistent_data(core_dc->ctx, NULL, NULL,
@@ -422,7 +426,7 @@ static void calc_freesync_range(struct core_freesync *core_freesync,
422 min_frame_duration_in_ns) * stream->timing.pix_clk_khz), 426 min_frame_duration_in_ns) * stream->timing.pix_clk_khz),
423 stream->timing.h_total), 1000000); 427 stream->timing.h_total), 1000000);
424 428
425 /* In case of 4k free sync monitor, vmin or vmax cannot be less than vtotal */ 429 /* vmin/vmax cannot be less than vtotal */
426 if (state->freesync_range.vmin < vtotal) { 430 if (state->freesync_range.vmin < vtotal) {
427 /* Error of 1 is permissible */ 431 /* Error of 1 is permissible */
428 ASSERT((state->freesync_range.vmin + 1) >= vtotal); 432 ASSERT((state->freesync_range.vmin + 1) >= vtotal);
@@ -553,8 +557,8 @@ static void reset_freesync_state_variables(struct freesync_state* state)
553 state->btr.inserted_frame_duration_in_us = 0; 557 state->btr.inserted_frame_duration_in_us = 0;
554 state->btr.program_btr = false; 558 state->btr.program_btr = false;
555 559
556 state->fixed_refresh.fixed_refresh_active = false; 560 state->fixed_refresh.fixed_active = false;
557 state->fixed_refresh.program_fixed_refresh = false; 561 state->fixed_refresh.program_fixed = false;
558} 562}
559/* 563/*
560 * Sets freesync mode on a stream depending on current freesync state. 564 * Sets freesync mode on a stream depending on current freesync state.
@@ -594,7 +598,7 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync,
594 if (core_freesync->map[map_index].user_enable. 598 if (core_freesync->map[map_index].user_enable.
595 enable_for_gaming == true && 599 enable_for_gaming == true &&
596 state->fullscreen == true && 600 state->fullscreen == true &&
597 state->fixed_refresh.fixed_refresh_active == false) { 601 state->fixed_refresh.fixed_active == false) {
598 /* Enable freesync */ 602 /* Enable freesync */
599 603
600 v_total_min = state->freesync_range.vmin; 604 v_total_min = state->freesync_range.vmin;
@@ -1240,29 +1244,39 @@ static void update_timestamps(struct core_freesync *core_freesync,
1240 state->btr.frame_counter = 0; 1244 state->btr.frame_counter = 0;
1241 1245
1242 /* Exit Fixed Refresh mode */ 1246 /* Exit Fixed Refresh mode */
1243 } else if (state->fixed_refresh.fixed_refresh_active) { 1247 } else if (state->fixed_refresh.fixed_active) {
1244 1248
1245 state->fixed_refresh.program_fixed_refresh = true; 1249 state->fixed_refresh.frame_counter++;
1246 state->fixed_refresh.fixed_refresh_active = false;
1247 1250
1251 if (state->fixed_refresh.frame_counter >
1252 FIXED_REFRESH_EXIT_FRAME_COUNT) {
1253 state->fixed_refresh.frame_counter = 0;
1254 state->fixed_refresh.program_fixed = true;
1255 state->fixed_refresh.fixed_active = false;
1256 }
1248 } 1257 }
1249 1258
1250 } else if (last_render_time_in_us > state->time.max_render_time_in_us) { 1259 } else if (last_render_time_in_us > state->time.max_render_time_in_us) {
1251 1260
1252 /* Enter Below the Range */ 1261 /* Enter Below the Range */
1253 if (!state->btr.btr_active && 1262 if (!state->btr.btr_active &&
1254 core_freesync->map[map_index].caps->btr_supported) { 1263 core_freesync->map[map_index].caps->btr_supported) {
1255 1264
1256 state->btr.program_btr = true; 1265 state->btr.program_btr = true;
1257 state->btr.btr_active = true; 1266 state->btr.btr_active = true;
1258 1267
1259 /* Enter Fixed Refresh mode */ 1268 /* Enter Fixed Refresh mode */
1260 } else if (!state->fixed_refresh.fixed_refresh_active && 1269 } else if (!state->fixed_refresh.fixed_active &&
1261 !core_freesync->map[map_index].caps->btr_supported) { 1270 !core_freesync->map[map_index].caps->btr_supported) {
1262 1271
1263 state->fixed_refresh.program_fixed_refresh = true; 1272 state->fixed_refresh.frame_counter++;
1264 state->fixed_refresh.fixed_refresh_active = true;
1265 1273
1274 if (state->fixed_refresh.frame_counter >
1275 FIXED_REFRESH_ENTER_FRAME_COUNT) {
1276 state->fixed_refresh.frame_counter = 0;
1277 state->fixed_refresh.program_fixed = true;
1278 state->fixed_refresh.fixed_active = true;
1279 }
1266 } 1280 }
1267 } 1281 }
1268 1282
@@ -1316,7 +1330,8 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
1316 1330
1317 frame_time_in_us = last_render_time_in_us / 1331 frame_time_in_us = last_render_time_in_us /
1318 mid_point_frames_ceil; 1332 mid_point_frames_ceil;
1319 delta_from_mid_point_in_us_1 = (state->btr.mid_point_in_us > 1333 delta_from_mid_point_in_us_1 =
1334 (state->btr.mid_point_in_us >
1320 frame_time_in_us) ? 1335 frame_time_in_us) ?
1321 (state->btr.mid_point_in_us - frame_time_in_us): 1336 (state->btr.mid_point_in_us - frame_time_in_us):
1322 (frame_time_in_us - state->btr.mid_point_in_us); 1337 (frame_time_in_us - state->btr.mid_point_in_us);
@@ -1332,7 +1347,8 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
1332 1347
1333 frame_time_in_us = last_render_time_in_us / 1348 frame_time_in_us = last_render_time_in_us /
1334 mid_point_frames_floor; 1349 mid_point_frames_floor;
1335 delta_from_mid_point_in_us_2 = (state->btr.mid_point_in_us > 1350 delta_from_mid_point_in_us_2 =
1351 (state->btr.mid_point_in_us >
1336 frame_time_in_us) ? 1352 frame_time_in_us) ?
1337 (state->btr.mid_point_in_us - frame_time_in_us): 1353 (state->btr.mid_point_in_us - frame_time_in_us):
1338 (frame_time_in_us - state->btr.mid_point_in_us); 1354 (frame_time_in_us - state->btr.mid_point_in_us);
@@ -1374,15 +1390,15 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync,
1374 unsigned int vmin = 0, vmax = 0; 1390 unsigned int vmin = 0, vmax = 0;
1375 struct freesync_state *state = &core_freesync->map[map_index].state; 1391 struct freesync_state *state = &core_freesync->map[map_index].state;
1376 1392
1377 if (!state->fixed_refresh.program_fixed_refresh) 1393 if (!state->fixed_refresh.program_fixed)
1378 return; 1394 return;
1379 1395
1380 state->fixed_refresh.program_fixed_refresh = false; 1396 state->fixed_refresh.program_fixed = false;
1381 1397
1382 /* Program Fixed Refresh */ 1398 /* Program Fixed Refresh */
1383 1399
1384 /* Fixed Refresh set to "not active" so disengage */ 1400 /* Fixed Refresh set to "not active" so disengage */
1385 if (!state->fixed_refresh.fixed_refresh_active) { 1401 if (!state->fixed_refresh.fixed_active) {
1386 set_freesync_on_streams(core_freesync, &stream, 1); 1402 set_freesync_on_streams(core_freesync, &stream, 1);
1387 1403
1388 /* Fixed Refresh set to "active" so engage (fix to max) */ 1404 /* Fixed Refresh set to "active" so engage (fix to max) */