drm/amd/display: Fix DRR Enable on Desktop
authorAmy Zhang <Amy.Zhang@amd.com>
Fri, 2 Jun 2017 20:33:47 +0000 (16:33 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 26 Sep 2017 22:07:51 +0000 (18:07 -0400)
- 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>
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h

index 9a073bc55144671e42266c4187ea516a5dd65d56..f79c47951f90ce9830c524681b0907e18d61e08b 100644 (file)
@@ -257,8 +257,10 @@ bool mod_freesync_add_stream(struct mod_freesync *mod_freesync,
                nom_refresh_rate_micro_hz = (unsigned int) temp;
 
                if (core_freesync->opts.min_refresh_from_edid != 0 &&
-                               dc_is_embedded_signal(
-                                       stream->sink->sink_signal)) {
+                               dc_is_embedded_signal(stream->sink->sink_signal)
+                               && (nom_refresh_rate_micro_hz -
+                               core_freesync->opts.min_refresh_from_edid *
+                               1000000) >= 10000000) {
                        caps->supported = true;
                        caps->min_refresh_in_micro_hz =
                                core_freesync->opts.min_refresh_from_edid *
@@ -683,44 +685,47 @@ static void set_static_ramp_variables(struct core_freesync *core_freesync,
                unsigned int index, bool enable_static_screen)
 {
        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 =
                        &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
         * whether we are enabling/disabling static screen mode. If the ramp is
         * already active, ramp should continue in the opposite direction
         * starting with the current frame duration
         */
        if (!static_ramp_variables->ramp_is_active) {
-
-               static_ramp_variables->ramp_is_active = true;
-
                if (enable_static_screen == true) {
                        /* Going to lower refresh rate, so start from max
                         * refresh rate (min frame duration)
                         */
                        frame_duration = ((unsigned int) (div64_u64(
                                (1000000000ULL * 1000000),
-                               core_freesync->map[index].state.
-                               nominal_refresh_rate_in_micro_hz)));
+                               nominal_refresh_rate)));
                } else {
                        /* Going to higher refresh rate, so start from min
                         * refresh rate (max frame duration)
                         */
                        frame_duration = ((unsigned int) (div64_u64(
                                (1000000000ULL * 1000000),
-                               core_freesync->map[index].caps->min_refresh_in_micro_hz)));
+                               min_refresh_rate)));
                }
-
                static_ramp_variables->
                        ramp_current_frame_duration_in_ns = frame_duration;
-       }
 
-       /* If we are ENABLING static screen, refresh rate should go DOWN.
-        * If we are DISABLING static screen, refresh rate should go UP.
-        */
-       static_ramp_variables->ramp_direction_is_up = !enable_static_screen;
+               static_ramp_variables->ramp_is_active = true;
+       }
 }
 
 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,
        unsigned int stream_index;
        struct freesync_state *state;
        struct core_freesync *core_freesync = NULL;
+       struct dc_static_screen_events triggers = {0};
 
        if (mod_freesync == NULL)
                return;
@@ -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)
                /* Program freesync according to current state*/
                set_freesync_on_streams(core_freesync, streams, num_streams);
@@ -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,
                const struct dc_stream *streams,
                unsigned int min_refresh,
-               unsigned int max_refresh)
+               unsigned int max_refresh,
+               struct mod_freesync_caps *caps)
 {
        unsigned int index = 0;
        struct core_freesync *core_freesync;
@@ -1030,7 +1045,10 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
        index = map_index_from_stream(core_freesync, streams);
        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 */
                calc_freesync_range(core_freesync, streams, state,
                        core_freesync->map[index].caps->
@@ -1049,6 +1067,17 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
                        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;
 }
 
@@ -1115,8 +1144,8 @@ bool mod_freesync_get_v_position(struct mod_freesync *mod_freesync,
                        core_freesync->dc, &stream, 1,
                        &position.vertical_count, &position.nominal_vcount)) {
 
-               *nom_v_pos = position.vertical_count;
-               *v_pos = position.nominal_vcount;
+               *nom_v_pos = position.nominal_vcount;
+               *v_pos = position.vertical_count;
 
                return true;
        }
@@ -1131,6 +1160,7 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
        struct freesync_state *state;
        struct core_freesync *core_freesync = NULL;
        struct dc_static_screen_events triggers = {0};
+       unsigned long long temp = 0;
 
        if (mod_freesync == NULL)
                return;
@@ -1143,22 +1173,21 @@ void mod_freesync_notify_mode_change(struct mod_freesync *mod_freesync,
 
                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) {
-                       /* 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_stream(core_freesync, streams[stream_index]);
 
-
                        /* Calculate vmin/vmax and refresh rate for
                         * current mode
                         */
index 3947cc412ad71740231fefcb3df1f60a03f58be0..f7f5a2cd79140b67d702037f7dbb4ce45b2b1662 100644 (file)
@@ -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,
                const struct dc_stream *streams,
                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,
                const struct dc_stream *stream,