aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
diff options
context:
space:
mode:
authorAmy Zhang <Amy.Zhang@amd.com>2017-06-02 16:33:47 -0400
committerAlex Deucher <alexander.deucher@amd.com>2017-09-26 18:07:51 -0400
commitfc82c5cb306d6f201cdee2c4c092ff49c6929634 (patch)
tree27d286c19343f4afd9d2cb8ae85f5ba50874b83d /drivers/gpu/drm/amd/display/modules/freesync/freesync.c
parent9f72f51d701cd2dd87a157d972650924fe91ec80 (diff)
drm/amd/display: Fix DRR Enable on Desktop
- Block PSR in Full screen apps to prevent incorrect static screen curser events - Reprogram static screen events when update freesync state - Program static ramp variable active after other values are programmed - Correct wrong assigning of the nominal and current vcount Signed-off-by: Amy Zhang <Amy.Zhang@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@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.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 9a073bc55144..f79c47951f90 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -257,8 +257,10 @@ bool mod_freesync_add_stream(struct mod_freesync *mod_freesync,
257 nom_refresh_rate_micro_hz = (unsigned int) temp; 257 nom_refresh_rate_micro_hz = (unsigned int) temp;
258 258
259 if (core_freesync->opts.min_refresh_from_edid != 0 && 259 if (core_freesync->opts.min_refresh_from_edid != 0 &&
260 dc_is_embedded_signal( 260 dc_is_embedded_signal(stream->sink->sink_signal)
261 stream->sink->sink_signal)) { 261 && (nom_refresh_rate_micro_hz -
262 core_freesync->opts.min_refresh_from_edid *
263 1000000) >= 10000000) {
262 caps->supported = true; 264 caps->supported = true;
263 caps->min_refresh_in_micro_hz = 265 caps->min_refresh_in_micro_hz =
264 core_freesync->opts.min_refresh_from_edid * 266 core_freesync->opts.min_refresh_from_edid *
@@ -683,44 +685,47 @@ static void set_static_ramp_variables(struct core_freesync *core_freesync,
683 unsigned int index, bool enable_static_screen) 685 unsigned int index, bool enable_static_screen)
684{ 686{
685 unsigned int frame_duration = 0; 687 unsigned int frame_duration = 0;
686 688 unsigned int nominal_refresh_rate = core_freesync->map[index].state.
689 nominal_refresh_rate_in_micro_hz;
690 unsigned int min_refresh_rate= core_freesync->map[index].caps->
691 min_refresh_in_micro_hz;
687 struct gradual_static_ramp *static_ramp_variables = 692 struct gradual_static_ramp *static_ramp_variables =
688 &core_freesync->map[index].state.static_ramp; 693 &core_freesync->map[index].state.static_ramp;
689 694
695 /* If we are ENABLING static screen, refresh rate should go DOWN.
696 * If we are DISABLING static screen, refresh rate should go UP.
697 */
698 if (enable_static_screen)
699 static_ramp_variables->ramp_direction_is_up = false;
700 else
701 static_ramp_variables->ramp_direction_is_up = true;
702
690 /* If ramp is not active, set initial frame duration depending on 703 /* If ramp is not active, set initial frame duration depending on
691 * whether we are enabling/disabling static screen mode. If the ramp is 704 * whether we are enabling/disabling static screen mode. If the ramp is
692 * already active, ramp should continue in the opposite direction 705 * already active, ramp should continue in the opposite direction
693 * starting with the current frame duration 706 * starting with the current frame duration
694 */ 707 */
695 if (!static_ramp_variables->ramp_is_active) { 708 if (!static_ramp_variables->ramp_is_active) {
696
697 static_ramp_variables->ramp_is_active = true;
698
699 if (enable_static_screen == true) { 709 if (enable_static_screen == true) {
700 /* Going to lower refresh rate, so start from max 710 /* Going to lower refresh rate, so start from max
701 * refresh rate (min frame duration) 711 * refresh rate (min frame duration)
702 */ 712 */
703 frame_duration = ((unsigned int) (div64_u64( 713 frame_duration = ((unsigned int) (div64_u64(
704 (1000000000ULL * 1000000), 714 (1000000000ULL * 1000000),
705 core_freesync->map[index].state. 715 nominal_refresh_rate)));
706 nominal_refresh_rate_in_micro_hz)));
707 } else { 716 } else {
708 /* Going to higher refresh rate, so start from min 717 /* Going to higher refresh rate, so start from min
709 * refresh rate (max frame duration) 718 * refresh rate (max frame duration)
710 */ 719 */
711 frame_duration = ((unsigned int) (div64_u64( 720 frame_duration = ((unsigned int) (div64_u64(
712 (1000000000ULL * 1000000), 721 (1000000000ULL * 1000000),
713 core_freesync->map[index].caps->min_refresh_in_micro_hz))); 722 min_refresh_rate)));
714 } 723 }
715
716 static_ramp_variables-> 724 static_ramp_variables->
717 ramp_current_frame_duration_in_ns = frame_duration; 725 ramp_current_frame_duration_in_ns = frame_duration;
718 }
719 726
720 /* If we are ENABLING static screen, refresh rate should go DOWN. 727 static_ramp_variables->ramp_is_active = true;
721 * If we are DISABLING static screen, refresh rate should go UP. 728 }
722 */
723 static_ramp_variables->ramp_direction_is_up = !enable_static_screen;
724} 729}
725 730
726void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, 731void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
@@ -841,6 +846,7 @@ void mod_freesync_update_state(struct mod_freesync *mod_freesync,
841 unsigned int stream_index; 846 unsigned int stream_index;
842 struct freesync_state *state; 847 struct freesync_state *state;
843 struct core_freesync *core_freesync = NULL; 848 struct core_freesync *core_freesync = NULL;
849 struct dc_static_screen_events triggers = {0};
844 850
845 if (mod_freesync == NULL) 851 if (mod_freesync == NULL)
846 return; 852 return;
@@ -902,6 +908,14 @@ void mod_freesync_update_state(struct mod_freesync *mod_freesync,
902 } 908 }
903 } 909 }
904 910
911 /* Update mask */
912 triggers.overlay_update = true;
913 triggers.surface_update = true;
914
915 core_freesync->dc->stream_funcs.set_static_screen_events(
916 core_freesync->dc, streams, num_streams,
917 &triggers);
918
905 if (freesync_program_required) 919 if (freesync_program_required)
906 /* Program freesync according to current state*/ 920 /* Program freesync according to current state*/
907 set_freesync_on_streams(core_freesync, streams, num_streams); 921 set_freesync_on_streams(core_freesync, streams, num_streams);
@@ -1017,7 +1031,8 @@ bool mod_freesync_get_user_enable(struct mod_freesync *mod_freesync,
1017bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, 1031bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
1018 const struct dc_stream *streams, 1032 const struct dc_stream *streams,
1019 unsigned int min_refresh, 1033 unsigned int min_refresh,
1020 unsigned int max_refresh) 1034 unsigned int max_refresh,
1035 struct mod_freesync_caps *caps)
1021{ 1036{
1022 unsigned int index = 0; 1037 unsigned int index = 0;
1023 struct core_freesync *core_freesync; 1038 struct core_freesync *core_freesync;
@@ -1030,7 +1045,10 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
1030 index = map_index_from_stream(core_freesync, streams); 1045 index = map_index_from_stream(core_freesync, streams);
1031 state = &core_freesync->map[index].state; 1046 state = &core_freesync->map[index].state;
1032 1047
1033 if (min_refresh == 0 || max_refresh == 0) { 1048 if (max_refresh == 0)
1049 max_refresh = state->nominal_refresh_rate_in_micro_hz;
1050
1051 if (min_refresh == 0) {
1034 /* Restore defaults */ 1052 /* Restore defaults */
1035 calc_freesync_range(core_freesync, streams, state, 1053 calc_freesync_range(core_freesync, streams, state,
1036 core_freesync->map[index].caps-> 1054 core_freesync->map[index].caps->
@@ -1049,6 +1067,17 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
1049 state->freesync_range.vmax); 1067 state->freesync_range.vmax);
1050 } 1068 }
1051 1069
1070 if (min_refresh != 0 &&
1071 dc_is_embedded_signal(streams->sink->sink_signal) &&
1072 (max_refresh - min_refresh >= 10000000)) {
1073 caps->supported = true;
1074 caps->min_refresh_in_micro_hz = min_refresh;
1075 caps->max_refresh_in_micro_hz = max_refresh;
1076 }
1077
1078 /* Update the stream */
1079 update_stream(core_freesync, streams);
1080
1052 return true; 1081 return true;
1053} 1082}
1054 1083
@@ -1115,8 +1144,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
1115 core_freesync->dc, &stream, 1, 1144 core_freesync->dc, &stream, 1,
1116 &position.vertical_count, &position.nominal_vcount)) { 1145 &position.vertical_count, &position.nominal_vcount)) {
1117 1146
1118 *nom_v_pos = position.vertical_count; 1147 *nom_v_pos = position.nominal_vcount;
1119 *v_pos = position.nominal_vcount; 1148 *v_pos = position.vertical_count;
1120 1149
1121 return true; 1150 return true;
1122 } 1151 }
@@ -1131,6 +1160,7 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
1131 struct freesync_state *state; 1160 struct freesync_state *state;
1132 struct core_freesync *core_freesync = NULL; 1161 struct core_freesync *core_freesync = NULL;
1133 struct dc_static_screen_events triggers = {0}; 1162 struct dc_static_screen_events triggers = {0};
1163 unsigned long long temp = 0;
1134 1164
1135 if (mod_freesync == NULL) 1165 if (mod_freesync == NULL)
1136 return; 1166 return;
@@ -1143,22 +1173,21 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
1143 1173
1144 state = &core_freesync->map[map_index].state; 1174 state = &core_freesync->map[map_index].state;
1145 1175
1176 /* Update the field rate for new timing */
1177 temp = streams[stream_index]->timing.pix_clk_khz;
1178 temp *= 1000ULL * 1000ULL * 1000ULL;
1179 temp = div_u64(temp,
1180 streams[stream_index]->timing.h_total);
1181 temp = div_u64(temp,
1182 streams[stream_index]->timing.v_total);
1183 state->nominal_refresh_rate_in_micro_hz =
1184 (unsigned int) temp;
1185
1146 if (core_freesync->map[map_index].caps->supported) { 1186 if (core_freesync->map[map_index].caps->supported) {
1147 /* Update the field rate for new timing */
1148 unsigned long long temp;
1149 temp = streams[stream_index]->timing.pix_clk_khz;
1150 temp *= 1000ULL * 1000ULL * 1000ULL;
1151 temp = div_u64(temp,
1152 streams[stream_index]->timing.h_total);
1153 temp = div_u64(temp,
1154 streams[stream_index]->timing.v_total);
1155 state->nominal_refresh_rate_in_micro_hz =
1156 (unsigned int) temp;
1157 1187
1158 /* Update the stream */ 1188 /* Update the stream */
1159 update_stream(core_freesync, streams[stream_index]); 1189 update_stream(core_freesync, streams[stream_index]);
1160 1190
1161
1162 /* Calculate vmin/vmax and refresh rate for 1191 /* Calculate vmin/vmax and refresh rate for
1163 * current mode 1192 * current mode
1164 */ 1193 */