diff options
author | Amy Zhang <Amy.Zhang@amd.com> | 2017-06-02 16:33:47 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-09-26 18:07:51 -0400 |
commit | fc82c5cb306d6f201cdee2c4c092ff49c6929634 (patch) | |
tree | 27d286c19343f4afd9d2cb8ae85f5ba50874b83d /drivers/gpu/drm/amd/display/modules/freesync/freesync.c | |
parent | 9f72f51d701cd2dd87a157d972650924fe91ec80 (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.c | 89 |
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 | ||
726 | void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, | 731 | void 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, | |||
1017 | bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, | 1031 | bool 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 | */ |