diff options
author | Anthony Koo <Anthony.Koo@amd.com> | 2017-06-27 13:27:00 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:08:23 -0400 |
commit | d09fec0f94376b1c0048215e14838295730ed6d3 (patch) | |
tree | 117fc6b4425aaada0b35a5bc68b9bafc8d71bac4 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |
parent | dc0ea008168bfbc61a7915eb6ffb1cc48ce5e9cc (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.c | 56 |
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 | ||
74 | struct fixed_refresh { | 77 | struct 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 | ||
79 | struct freesync_range { | 83 | struct 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) */ |