diff mbox series

[1/5] drm/amd/display: Update VRR state earlier in atomic_commit_tail.

Message ID 20190329120057.1472-2-mario.kleiner.de@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/5] drm/amd/display: Update VRR state earlier in atomic_commit_tail. | expand

Commit Message

Mario Kleiner March 29, 2019, noon UTC
We need the VRR active/inactive state info earlier in
the commit sequence, so VRR related setup functions like
amdgpu_dm_handle_vrr_transition() know the final VRR state
when they need to do their hw setup work.

Split update_freesync_state_on_stream() into an early part,
that can run at the beginning of commit tail before the
vrr transition handling, and a late part that must run after
vrr transition handling inside the commit planes code for
enabled crtc's.

Suggested by Nicholas Kazlauskas.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
---
 .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 61 ++++++++++++++-----
 1 file changed, 46 insertions(+), 15 deletions(-)

Comments

Kazlauskas, Nicholas March 29, 2019, 1:43 p.m. UTC | #1
On 3/29/19 8:00 AM, Mario Kleiner wrote:
> We need the VRR active/inactive state info earlier in
> the commit sequence, so VRR related setup functions like
> amdgpu_dm_handle_vrr_transition() know the final VRR state
> when they need to do their hw setup work.
> 
> Split update_freesync_state_on_stream() into an early part,
> that can run at the beginning of commit tail before the
> vrr transition handling, and a late part that must run after
> vrr transition handling inside the commit planes code for
> enabled crtc's.
> 
> Suggested by Nicholas Kazlauskas.
> Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>

This works fine as far as I can tell even though my preference was still 
on doing it on atomic check. I can still refactor or take a look at that 
later if I find some time at least.

Nicholas Kazlauskas

> ---
>   .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 61 ++++++++++++++-----
>   1 file changed, 46 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> index 7d1c782072ee..6528258f8975 100644
> --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
> @@ -4645,7 +4645,6 @@ static void update_freesync_state_on_stream(
>   {
>   	struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
>   	struct dc_info_packet vrr_infopacket = {0};
> -	struct mod_freesync_config config = new_crtc_state->freesync_config;
>   
>   	if (!new_stream)
>   		return;
> @@ -4658,20 +4657,6 @@ static void update_freesync_state_on_stream(
>   	if (!new_stream->timing.h_total || !new_stream->timing.v_total)
>   		return;
>   
> -	if (new_crtc_state->vrr_supported &&
> -	    config.min_refresh_in_uhz &&
> -	    config.max_refresh_in_uhz) {
> -		config.state = new_crtc_state->base.vrr_enabled ?
> -			VRR_STATE_ACTIVE_VARIABLE :
> -			VRR_STATE_INACTIVE;
> -	} else {
> -		config.state = VRR_STATE_UNSUPPORTED;
> -	}
> -
> -	mod_freesync_build_vrr_params(dm->freesync_module,
> -				      new_stream,
> -				      &config, &vrr_params);
> -
>   	if (surface) {
>   		mod_freesync_handle_preflip(
>   			dm->freesync_module,
> @@ -4712,6 +4697,46 @@ static void update_freesync_state_on_stream(
>   			      (int)vrr_params.state);
>   }
>   
> +static void pre_update_freesync_state_on_stream(
> +	struct amdgpu_display_manager *dm,
> +	struct dm_crtc_state *new_crtc_state)
> +{
> +	struct dc_stream_state *new_stream = new_crtc_state->stream;
> +	struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
> +	struct mod_freesync_config config = new_crtc_state->freesync_config;
> +
> +	if (!new_stream)
> +		return;
> +
> +	/*
> +	 * TODO: Determine why min/max totals and vrefresh can be 0 here.
> +	 * For now it's sufficient to just guard against these conditions.
> +	 */
> +	if (!new_stream->timing.h_total || !new_stream->timing.v_total)
> +		return;
> +
> +	if (new_crtc_state->vrr_supported &&
> +	    config.min_refresh_in_uhz &&
> +	    config.max_refresh_in_uhz) {
> +		config.state = new_crtc_state->base.vrr_enabled ?
> +			VRR_STATE_ACTIVE_VARIABLE :
> +			VRR_STATE_INACTIVE;
> +	} else {
> +		config.state = VRR_STATE_UNSUPPORTED;
> +	}
> +
> +	mod_freesync_build_vrr_params(dm->freesync_module,
> +				      new_stream,
> +				      &config, &vrr_params);
> +
> +	new_crtc_state->freesync_timing_changed |=
> +		(memcmp(&new_crtc_state->vrr_params.adjust,
> +			&vrr_params.adjust,
> +			sizeof(vrr_params.adjust)) != 0);
> +
> +	new_crtc_state->vrr_params = vrr_params;
> +}
> +
>   static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>   				    struct dc_state *dc_state,
>   				    struct drm_device *dev,
> @@ -5233,6 +5258,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
>   		mutex_unlock(&dm->dc_lock);
>   	}
>   
> +	/* Update freesync state before amdgpu_dm_handle_vrr_transition(). */
> +	for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
> +		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
> +		pre_update_freesync_state_on_stream(dm, dm_new_crtc_state);
> +	}
> +
>   	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
>   			new_crtc_state, i) {
>   		/*
>
diff mbox series

Patch

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 7d1c782072ee..6528258f8975 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -4645,7 +4645,6 @@  static void update_freesync_state_on_stream(
 {
 	struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
 	struct dc_info_packet vrr_infopacket = {0};
-	struct mod_freesync_config config = new_crtc_state->freesync_config;
 
 	if (!new_stream)
 		return;
@@ -4658,20 +4657,6 @@  static void update_freesync_state_on_stream(
 	if (!new_stream->timing.h_total || !new_stream->timing.v_total)
 		return;
 
-	if (new_crtc_state->vrr_supported &&
-	    config.min_refresh_in_uhz &&
-	    config.max_refresh_in_uhz) {
-		config.state = new_crtc_state->base.vrr_enabled ?
-			VRR_STATE_ACTIVE_VARIABLE :
-			VRR_STATE_INACTIVE;
-	} else {
-		config.state = VRR_STATE_UNSUPPORTED;
-	}
-
-	mod_freesync_build_vrr_params(dm->freesync_module,
-				      new_stream,
-				      &config, &vrr_params);
-
 	if (surface) {
 		mod_freesync_handle_preflip(
 			dm->freesync_module,
@@ -4712,6 +4697,46 @@  static void update_freesync_state_on_stream(
 			      (int)vrr_params.state);
 }
 
+static void pre_update_freesync_state_on_stream(
+	struct amdgpu_display_manager *dm,
+	struct dm_crtc_state *new_crtc_state)
+{
+	struct dc_stream_state *new_stream = new_crtc_state->stream;
+	struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
+	struct mod_freesync_config config = new_crtc_state->freesync_config;
+
+	if (!new_stream)
+		return;
+
+	/*
+	 * TODO: Determine why min/max totals and vrefresh can be 0 here.
+	 * For now it's sufficient to just guard against these conditions.
+	 */
+	if (!new_stream->timing.h_total || !new_stream->timing.v_total)
+		return;
+
+	if (new_crtc_state->vrr_supported &&
+	    config.min_refresh_in_uhz &&
+	    config.max_refresh_in_uhz) {
+		config.state = new_crtc_state->base.vrr_enabled ?
+			VRR_STATE_ACTIVE_VARIABLE :
+			VRR_STATE_INACTIVE;
+	} else {
+		config.state = VRR_STATE_UNSUPPORTED;
+	}
+
+	mod_freesync_build_vrr_params(dm->freesync_module,
+				      new_stream,
+				      &config, &vrr_params);
+
+	new_crtc_state->freesync_timing_changed |=
+		(memcmp(&new_crtc_state->vrr_params.adjust,
+			&vrr_params.adjust,
+			sizeof(vrr_params.adjust)) != 0);
+
+	new_crtc_state->vrr_params = vrr_params;
+}
+
 static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
 				    struct dc_state *dc_state,
 				    struct drm_device *dev,
@@ -5233,6 +5258,12 @@  static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state)
 		mutex_unlock(&dm->dc_lock);
 	}
 
+	/* Update freesync state before amdgpu_dm_handle_vrr_transition(). */
+	for_each_new_crtc_in_state(state, crtc, new_crtc_state, i) {
+		dm_new_crtc_state = to_dm_crtc_state(new_crtc_state);
+		pre_update_freesync_state_on_stream(dm, dm_new_crtc_state);
+	}
+
 	for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state,
 			new_crtc_state, i) {
 		/*