Commit fc82c5cb authored by Amy Zhang's avatar Amy Zhang Committed by Alex Deucher

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: default avatarAmy Zhang <Amy.Zhang@amd.com>
Reviewed-by: default avatarTony Cheng <Tony.Cheng@amd.com>
Acked-by: default avatarHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9f72f51d
...@@ -257,8 +257,10 @@ bool mod_freesync_add_stream(struct mod_freesync *mod_freesync, ...@@ -257,8 +257,10 @@ bool mod_freesync_add_stream(struct mod_freesync *mod_freesync,
nom_refresh_rate_micro_hz = (unsigned int) temp; nom_refresh_rate_micro_hz = (unsigned int) temp;
if (core_freesync->opts.min_refresh_from_edid != 0 && if (core_freesync->opts.min_refresh_from_edid != 0 &&
dc_is_embedded_signal( dc_is_embedded_signal(stream->sink->sink_signal)
stream->sink->sink_signal)) { && (nom_refresh_rate_micro_hz -
core_freesync->opts.min_refresh_from_edid *
1000000) >= 10000000) {
caps->supported = true; caps->supported = true;
caps->min_refresh_in_micro_hz = caps->min_refresh_in_micro_hz =
core_freesync->opts.min_refresh_from_edid * core_freesync->opts.min_refresh_from_edid *
...@@ -683,44 +685,47 @@ static void set_static_ramp_variables(struct core_freesync *core_freesync, ...@@ -683,44 +685,47 @@ static void set_static_ramp_variables(struct core_freesync *core_freesync,
unsigned int index, bool enable_static_screen) unsigned int index, bool enable_static_screen)
{ {
unsigned int frame_duration = 0; unsigned int frame_duration = 0;
unsigned int nominal_refresh_rate = core_freesync->map[index].state.
nominal_refresh_rate_in_micro_hz;
unsigned int min_refresh_rate= core_freesync->map[index].caps->
min_refresh_in_micro_hz;
struct gradual_static_ramp *static_ramp_variables = struct gradual_static_ramp *static_ramp_variables =
&core_freesync->map[index].state.static_ramp; &core_freesync->map[index].state.static_ramp;
/* If we are ENABLING static screen, refresh rate should go DOWN.
* If we are DISABLING static screen, refresh rate should go UP.
*/
if (enable_static_screen)
static_ramp_variables->ramp_direction_is_up = false;
else
static_ramp_variables->ramp_direction_is_up = true;
/* If ramp is not active, set initial frame duration depending on /* If ramp is not active, set initial frame duration depending on
* whether we are enabling/disabling static screen mode. If the ramp is * whether we are enabling/disabling static screen mode. If the ramp is
* already active, ramp should continue in the opposite direction * already active, ramp should continue in the opposite direction
* starting with the current frame duration * starting with the current frame duration
*/ */
if (!static_ramp_variables->ramp_is_active) { if (!static_ramp_variables->ramp_is_active) {
static_ramp_variables->ramp_is_active = true;
if (enable_static_screen == true) { if (enable_static_screen == true) {
/* Going to lower refresh rate, so start from max /* Going to lower refresh rate, so start from max
* refresh rate (min frame duration) * refresh rate (min frame duration)
*/ */
frame_duration = ((unsigned int) (div64_u64( frame_duration = ((unsigned int) (div64_u64(
(1000000000ULL * 1000000), (1000000000ULL * 1000000),
core_freesync->map[index].state. nominal_refresh_rate)));
nominal_refresh_rate_in_micro_hz)));
} else { } else {
/* Going to higher refresh rate, so start from min /* Going to higher refresh rate, so start from min
* refresh rate (max frame duration) * refresh rate (max frame duration)
*/ */
frame_duration = ((unsigned int) (div64_u64( frame_duration = ((unsigned int) (div64_u64(
(1000000000ULL * 1000000), (1000000000ULL * 1000000),
core_freesync->map[index].caps->min_refresh_in_micro_hz))); min_refresh_rate)));
} }
static_ramp_variables-> static_ramp_variables->
ramp_current_frame_duration_in_ns = frame_duration; ramp_current_frame_duration_in_ns = frame_duration;
}
/* If we are ENABLING static screen, refresh rate should go DOWN. static_ramp_variables->ramp_is_active = true;
* If we are DISABLING static screen, refresh rate should go UP. }
*/
static_ramp_variables->ramp_direction_is_up = !enable_static_screen;
} }
void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync, 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,6 +846,7 @@ void mod_freesync_update_state(struct mod_freesync *mod_freesync,
unsigned int stream_index; unsigned int stream_index;
struct freesync_state *state; struct freesync_state *state;
struct core_freesync *core_freesync = NULL; struct core_freesync *core_freesync = NULL;
struct dc_static_screen_events triggers = {0};
if (mod_freesync == NULL) if (mod_freesync == NULL)
return; return;
...@@ -902,6 +908,14 @@ void mod_freesync_update_state(struct mod_freesync *mod_freesync, ...@@ -902,6 +908,14 @@ void mod_freesync_update_state(struct mod_freesync *mod_freesync,
} }
} }
/* Update mask */
triggers.overlay_update = true;
triggers.surface_update = true;
core_freesync->dc->stream_funcs.set_static_screen_events(
core_freesync->dc, streams, num_streams,
&triggers);
if (freesync_program_required) if (freesync_program_required)
/* Program freesync according to current state*/ /* Program freesync according to current state*/
set_freesync_on_streams(core_freesync, streams, num_streams); 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,7 +1031,8 @@ bool mod_freesync_get_user_enable(struct mod_freesync *mod_freesync,
bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
const struct dc_stream *streams, const struct dc_stream *streams,
unsigned int min_refresh, unsigned int min_refresh,
unsigned int max_refresh) unsigned int max_refresh,
struct mod_freesync_caps *caps)
{ {
unsigned int index = 0; unsigned int index = 0;
struct core_freesync *core_freesync; struct core_freesync *core_freesync;
...@@ -1030,7 +1045,10 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, ...@@ -1030,7 +1045,10 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
index = map_index_from_stream(core_freesync, streams); index = map_index_from_stream(core_freesync, streams);
state = &core_freesync->map[index].state; state = &core_freesync->map[index].state;
if (min_refresh == 0 || max_refresh == 0) { if (max_refresh == 0)
max_refresh = state->nominal_refresh_rate_in_micro_hz;
if (min_refresh == 0) {
/* Restore defaults */ /* Restore defaults */
calc_freesync_range(core_freesync, streams, state, calc_freesync_range(core_freesync, streams, state,
core_freesync->map[index].caps-> core_freesync->map[index].caps->
...@@ -1049,6 +1067,17 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, ...@@ -1049,6 +1067,17 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
state->freesync_range.vmax); state->freesync_range.vmax);
} }
if (min_refresh != 0 &&
dc_is_embedded_signal(streams->sink->sink_signal) &&
(max_refresh - min_refresh >= 10000000)) {
caps->supported = true;
caps->min_refresh_in_micro_hz = min_refresh;
caps->max_refresh_in_micro_hz = max_refresh;
}
/* Update the stream */
update_stream(core_freesync, streams);
return true; return true;
} }
...@@ -1115,8 +1144,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync, ...@@ -1115,8 +1144,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
core_freesync->dc, &stream, 1, core_freesync->dc, &stream, 1,
&position.vertical_count, &position.nominal_vcount)) { &position.vertical_count, &position.nominal_vcount)) {
*nom_v_pos = position.vertical_count; *nom_v_pos = position.nominal_vcount;
*v_pos = position.nominal_vcount; *v_pos = position.vertical_count;
return true; return true;
} }
...@@ -1131,6 +1160,7 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync, ...@@ -1131,6 +1160,7 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
struct freesync_state *state; struct freesync_state *state;
struct core_freesync *core_freesync = NULL; struct core_freesync *core_freesync = NULL;
struct dc_static_screen_events triggers = {0}; struct dc_static_screen_events triggers = {0};
unsigned long long temp = 0;
if (mod_freesync == NULL) if (mod_freesync == NULL)
return; return;
...@@ -1143,22 +1173,21 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync, ...@@ -1143,22 +1173,21 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
state = &core_freesync->map[map_index].state; state = &core_freesync->map[map_index].state;
/* Update the field rate for new timing */
temp = streams[stream_index]->timing.pix_clk_khz;
temp *= 1000ULL * 1000ULL * 1000ULL;
temp = div_u64(temp,
streams[stream_index]->timing.h_total);
temp = div_u64(temp,
streams[stream_index]->timing.v_total);
state->nominal_refresh_rate_in_micro_hz =
(unsigned int) temp;
if (core_freesync->map[map_index].caps->supported) { if (core_freesync->map[map_index].caps->supported) {
/* Update the field rate for new timing */
unsigned long long temp;
temp = streams[stream_index]->timing.pix_clk_khz;
temp *= 1000ULL * 1000ULL * 1000ULL;
temp = div_u64(temp,
streams[stream_index]->timing.h_total);
temp = div_u64(temp,
streams[stream_index]->timing.v_total);
state->nominal_refresh_rate_in_micro_hz =
(unsigned int) temp;
/* Update the stream */ /* Update the stream */
update_stream(core_freesync, streams[stream_index]); update_stream(core_freesync, streams[stream_index]);
/* Calculate vmin/vmax and refresh rate for /* Calculate vmin/vmax and refresh rate for
* current mode * current mode
*/ */
......
...@@ -132,7 +132,8 @@ bool mod_freesync_get_user_enable(struct mod_freesync *mod_freesync, ...@@ -132,7 +132,8 @@ bool mod_freesync_get_user_enable(struct mod_freesync *mod_freesync,
bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync, bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
const struct dc_stream *streams, const struct dc_stream *streams,
unsigned int min_refresh, unsigned int min_refresh,
unsigned int max_refresh); unsigned int max_refresh,
struct mod_freesync_caps *caps);
bool mod_freesync_get_min_max(struct mod_freesync *mod_freesync, bool mod_freesync_get_min_max(struct mod_freesync *mod_freesync,
const struct dc_stream *stream, const struct dc_stream *stream,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment