aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch229
1 files changed, 229 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch b/common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch
new file mode 100644
index 00000000..88e4cf8e
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.14.71/0500-drm-amd-display-Fix-DRR-Enable-on-Desktop.patch
@@ -0,0 +1,229 @@
+From c5669fa0e29a6bddf90c294ca513bcef8bd2b26b Mon Sep 17 00:00:00 2001
+From: Amy Zhang <Amy.Zhang@amd.com>
+Date: Fri, 2 Jun 2017 16:33:47 -0400
+Subject: [PATCH 0500/4131] 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>
+---
+ .../drm/amd/display/modules/freesync/freesync.c | 89 ++++++++++++++--------
+ .../gpu/drm/amd/display/modules/inc/mod_freesync.h | 3 +-
+ 2 files changed, 61 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index 9a073bc..f79c479 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,
+ 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
+ */
+diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+index 3947cc4..f7f5a2c 100644
+--- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+@@ -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,
+--
+2.7.4
+