aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
diff options
context:
space:
mode:
authorEric Cook <Eric.Cook@amd.com>2017-04-12 11:05:08 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 17:23:57 -0400
commit09e2d07f9d4d30f7d219b562d656d7c7611e2b65 (patch)
tree71ac341d66b5483d06584d59c1391832396e3241 /drivers/gpu/drm/amd/display/modules/freesync/freesync.c
parentab3c179893fd44953008d1b1442973ecb1bb5c7e (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r--drivers/gpu/drm/amd/display/modules/freesync/freesync.c67
1 files 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,
641void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, 641void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
642 const struct dc_stream **streams, int num_streams) 642 const struct dc_stream **streams, int num_streams)
643{ 643{
644 unsigned int index, v_total = 0; 644 unsigned int index, v_total, inserted_frame_v_total = 0;
645 unsigned int min_frame_duration_in_ns, vmax, vmin = 0;
645 struct freesync_state *state; 646 struct freesync_state *state;
646 struct core_freesync *core_freesync = NULL; 647 struct core_freesync *core_freesync = NULL;
647 648
@@ -665,19 +666,48 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
665 666
666 /* Only execute if in fullscreen mode */ 667 /* Only execute if in fullscreen mode */
667 if (state->fullscreen == true && 668 if (state->fullscreen == true &&
668 core_freesync->map[index].user_enable.enable_for_gaming) { 669 core_freesync->map[index].user_enable.enable_for_gaming &&
670 core_freesync->map[index].caps->btr_supported &&
671 state->btr.btr_active) {
672
673 /* TODO: pass in flag for Pre-DCE12 ASIC
674 * in order for frame variable duration to take affect,
675 * it needs to be done one VSYNC early, which is at
676 * frameCounter == 1.
677 * For DCE12 and newer updates to V_TOTAL_MIN/MAX
678 * will take affect on current frame
679 */
680 if (state->btr.frames_to_insert == state->btr.frame_counter) {
681
682 min_frame_duration_in_ns = ((unsigned int) (div64_u64(
683 (1000000000ULL * 1000000),
684 state->nominal_refresh_rate_in_micro_hz)));
685
686 calc_vmin_vmax(core_freesync, *streams, &vmin, &vmax);
669 687
670 if (state->btr.btr_active) 688 inserted_frame_v_total = vmin;
671 if (state->btr.frame_counter > 0)
672 689
673 state->btr.frame_counter--; 690 if (min_frame_duration_in_ns / 1000)
691 inserted_frame_v_total =
692 state->btr.inserted_frame_duration_in_us *
693 vmin / (min_frame_duration_in_ns / 1000);
674 694
675 if (state->btr.frame_counter == 1) { 695 /* Set length of inserted frames as v_total_max*/
696 vmax = inserted_frame_v_total;
697 vmin = inserted_frame_v_total;
676 698
677 /* Restore FreeSync */ 699 /* Program V_TOTAL */
678 set_freesync_on_streams(core_freesync, streams, 700 core_freesync->dc->stream_funcs.adjust_vmin_vmax(
679 num_streams); 701 core_freesync->dc, streams,
702 num_streams, vmin, vmax);
680 } 703 }
704
705 if (state->btr.frame_counter > 0)
706 state->btr.frame_counter--;
707
708 /* Restore FreeSync */
709 if (state->btr.frame_counter == 0)
710 set_freesync_on_streams(core_freesync, streams, num_streams);
681 } 711 }
682 712
683 /* If in fullscreen freesync mode or in video, do not program 713 /* 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,
1022 unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF; 1052 unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF;
1023 unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF; 1053 unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF;
1024 unsigned int frames_to_insert = 0; 1054 unsigned int frames_to_insert = 0;
1025 unsigned int inserted_frame_v_total = 0;
1026 unsigned int vmin = 0, vmax = 0;
1027 unsigned int min_frame_duration_in_ns = 0; 1055 unsigned int min_frame_duration_in_ns = 0;
1028 struct freesync_state *state = &core_freesync->map[map_index].state; 1056 struct freesync_state *state = &core_freesync->map[map_index].state;
1029 1057
@@ -1101,23 +1129,6 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
1101 inserted_frame_duration_in_us = 1129 inserted_frame_duration_in_us =
1102 state->time.min_render_time_in_us; 1130 state->time.min_render_time_in_us;
1103 1131
1104 /* We need the v_total_min from capability */
1105 calc_vmin_vmax(core_freesync, stream, &vmin, &vmax);
1106
1107 inserted_frame_v_total = vmin;
1108 if (min_frame_duration_in_ns / 1000)
1109 inserted_frame_v_total = inserted_frame_duration_in_us *
1110 vmin / (min_frame_duration_in_ns / 1000);
1111
1112 /* Set length of inserted frames as v_total_max*/
1113 vmax = inserted_frame_v_total;
1114
1115 /* Program V_TOTAL */
1116 core_freesync->dc->stream_funcs.adjust_vmin_vmax(
1117 core_freesync->dc, &stream,
1118 1, vmin,
1119 vmax);
1120
1121 /* Cache the calculated variables */ 1132 /* Cache the calculated variables */
1122 state->btr.inserted_frame_duration_in_us = 1133 state->btr.inserted_frame_duration_in_us =
1123 inserted_frame_duration_in_us; 1134 inserted_frame_duration_in_us;