diff mbox series

[17/23] drm/i915: Get the uapi state from the correct plane when bigjoiner is used

Message ID 20201113220358.24794-18-ville.syrjala@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series drm/i915: Big bigjoiner series | expand

Commit Message

Ville Syrjälä Nov. 13, 2020, 10:03 p.m. UTC
From: Ville Syrjälä <ville.syrjala@linux.intel.com>

When using bigjoiner userspace is only controlling the "master"
plane, so use its uapi state for the "slave" plane as well.

hw.crtc needs a bit of magic since we don't want to copy that from
the uapi state (as it points to the wrong pipe for the "slave
" plane). Instead we pass the right crtc in explicitly but only
assign it when the uapi state indicates the plane to be logically
enabled (ie. uapi.crtc != NULL).

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 59 +++++++++++++------
 .../gpu/drm/i915/display/intel_atomic_plane.h |  3 +-
 drivers/gpu/drm/i915/display/intel_display.c  |  5 +-
 3 files changed, 46 insertions(+), 21 deletions(-)

Comments

Navare, Manasi Nov. 17, 2020, 12:24 a.m. UTC | #1
On Sat, Nov 14, 2020 at 12:03:52AM +0200, Ville Syrjala wrote:
> From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> 
> When using bigjoiner userspace is only controlling the "master"
> plane, so use its uapi state for the "slave" plane as well.
> 
> hw.crtc needs a bit of magic since we don't want to copy that from
> the uapi state (as it points to the wrong pipe for the "slave
> " plane). Instead we pass the right crtc in explicitly but only
> assign it when the uapi state indicates the plane to be logically
> enabled (ie. uapi.crtc != NULL).
> 
> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> ---
>  .../gpu/drm/i915/display/intel_atomic_plane.c | 59 +++++++++++++------
>  .../gpu/drm/i915/display/intel_atomic_plane.h |  3 +-
>  drivers/gpu/drm/i915/display/intel_display.c  |  5 +-
>  3 files changed, 46 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> index f47558efb3c2..7abb0e3d6c0b 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> @@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
>  }
>  
>  void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
> -				       const struct intel_plane_state *from_plane_state)
> +				       const struct intel_plane_state *from_plane_state,
> +				       struct intel_crtc *crtc)
>  {
>  	intel_plane_clear_hw_state(plane_state);
>  
> -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> +	/*
> +	 * For the bigjoiner slave uapi.crtc will point at
> +	 * the master crtc. So we explicitly assign the right
> +	 * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
> +	 * the plane is logically enabled on the uapi level.
> +	 */
> +	plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;

But here in case of bigjoiner_slave we actualy compute new_master_plane_state from master_plane which is
obtained from the slaves linked crtc.

So here, even for the slave plane's hw.crtc we are using master's uapi.crtc? Is that what is happening here?

Manasi

> +
>  	plane_state->hw.fb = from_plane_state->uapi.fb;
>  	if (plane_state->hw.fb)
>  		drm_framebuffer_get(plane_state->hw.fb);
> @@ -331,15 +339,16 @@ int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
>  					       old_plane_state, new_plane_state);
>  }
>  
> -static struct intel_crtc *
> -get_crtc_from_states(const struct intel_plane_state *old_plane_state,
> -		     const struct intel_plane_state *new_plane_state)
> +static struct intel_plane *
> +intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
>  {
> -	if (new_plane_state->uapi.crtc)
> -		return to_intel_crtc(new_plane_state->uapi.crtc);
> +	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
> +	struct intel_plane *plane;
>  
> -	if (old_plane_state->uapi.crtc)
> -		return to_intel_crtc(old_plane_state->uapi.crtc);
> +	for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
> +		if (plane->id == plane_id)
> +			return plane;
> +	}
>  
>  	return NULL;
>  }
> @@ -347,23 +356,37 @@ get_crtc_from_states(const struct intel_plane_state *old_plane_state,
>  int intel_plane_atomic_check(struct intel_atomic_state *state,
>  			     struct intel_plane *plane)
>  {
> +	struct drm_i915_private *i915 = to_i915(state->base.dev);
>  	struct intel_plane_state *new_plane_state =
>  		intel_atomic_get_new_plane_state(state, plane);
>  	const struct intel_plane_state *old_plane_state =
>  		intel_atomic_get_old_plane_state(state, plane);
> -	struct intel_crtc *crtc =
> -		get_crtc_from_states(old_plane_state, new_plane_state);
> -	const struct intel_crtc_state *old_crtc_state;
> -	struct intel_crtc_state *new_crtc_state;
> +	const struct intel_plane_state *new_master_plane_state;
> +	struct intel_crtc *crtc = intel_get_crtc_for_pipe(i915, plane->pipe);
> +	const struct intel_crtc_state *old_crtc_state =
> +		intel_atomic_get_old_crtc_state(state, crtc);
> +	struct intel_crtc_state *new_crtc_state =
> +		intel_atomic_get_new_crtc_state(state, crtc);
> +
> +	if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
> +		struct intel_plane *master_plane =
> +			intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
> +					     plane->id);
> +
> +		new_master_plane_state =
> +			intel_atomic_get_new_plane_state(state, master_plane);
> +	} else {
> +		new_master_plane_state = new_plane_state;
> +	}
> +
> +	intel_plane_copy_uapi_to_hw_state(new_plane_state,
> +					  new_master_plane_state,
> +					  crtc);
>  
> -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
>  	new_plane_state->uapi.visible = false;
> -	if (!crtc)
> +	if (!new_crtc_state)
>  		return 0;
>  
> -	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
> -	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
> -
>  	return intel_plane_atomic_check_with_state(old_crtc_state,
>  						   new_crtc_state,
>  						   old_plane_state,
> diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> index 24a3a148aa62..5cae9db41062 100644
> --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
> @@ -24,7 +24,8 @@ unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
>  unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
>  				   const struct intel_plane_state *plane_state);
>  void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
> -				       const struct intel_plane_state *from_plane_state);
> +				       const struct intel_plane_state *from_plane_state,
> +				       struct intel_crtc *crtc);
>  void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
>  			       const struct intel_plane_state *from_plane_state);
>  void intel_update_plane(struct intel_plane *plane,
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 1118ff73c0d4..55e0a2f21d98 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -3718,7 +3718,8 @@ intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
>  	drm_framebuffer_get(fb);
>  
>  	plane_state->crtc = &intel_crtc->base;
> -	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state);
> +	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state,
> +					  intel_crtc);
>  
>  	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
>  
> @@ -16942,7 +16943,7 @@ intel_legacy_cursor_update(struct drm_plane *_plane,
>  	new_plane_state->uapi.crtc_w = crtc_w;
>  	new_plane_state->uapi.crtc_h = crtc_h;
>  
> -	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
> +	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
>  
>  	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
>  						  old_plane_state, new_plane_state);
> -- 
> 2.26.2
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
Ville Syrjälä Nov. 17, 2020, 3:17 p.m. UTC | #2
On Mon, Nov 16, 2020 at 04:24:15PM -0800, Navare, Manasi wrote:
> On Sat, Nov 14, 2020 at 12:03:52AM +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > 
> > When using bigjoiner userspace is only controlling the "master"
> > plane, so use its uapi state for the "slave" plane as well.
> > 
> > hw.crtc needs a bit of magic since we don't want to copy that from
> > the uapi state (as it points to the wrong pipe for the "slave
> > " plane). Instead we pass the right crtc in explicitly but only
> > assign it when the uapi state indicates the plane to be logically
> > enabled (ie. uapi.crtc != NULL).
> > 
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> >  .../gpu/drm/i915/display/intel_atomic_plane.c | 59 +++++++++++++------
> >  .../gpu/drm/i915/display/intel_atomic_plane.h |  3 +-
> >  drivers/gpu/drm/i915/display/intel_display.c  |  5 +-
> >  3 files changed, 46 insertions(+), 21 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > index f47558efb3c2..7abb0e3d6c0b 100644
> > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > @@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
> >  }
> >  
> >  void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
> > -				       const struct intel_plane_state *from_plane_state)
> > +				       const struct intel_plane_state *from_plane_state,
> > +				       struct intel_crtc *crtc)
> >  {
> >  	intel_plane_clear_hw_state(plane_state);
> >  
> > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > +	/*
> > +	 * For the bigjoiner slave uapi.crtc will point at
> > +	 * the master crtc. So we explicitly assign the right
> > +	 * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
> > +	 * the plane is logically enabled on the uapi level.
> > +	 */
> > +	plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
> 
> But here in case of bigjoiner_slave we actualy compute new_master_plane_state from master_plane which is
> obtained from the slaves linked crtc.
> 
> So here, even for the slave plane's hw.crtc we are using master's uapi.crtc? Is that what is happening here?

Yes.
Navare, Manasi Nov. 17, 2020, 3:48 p.m. UTC | #3
On Tue, Nov 17, 2020 at 05:17:15PM +0200, Ville Syrjälä wrote:
> On Mon, Nov 16, 2020 at 04:24:15PM -0800, Navare, Manasi wrote:
> > On Sat, Nov 14, 2020 at 12:03:52AM +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > 
> > > When using bigjoiner userspace is only controlling the "master"
> > > plane, so use its uapi state for the "slave" plane as well.
> > > 
> > > hw.crtc needs a bit of magic since we don't want to copy that from
> > > the uapi state (as it points to the wrong pipe for the "slave
> > > " plane). Instead we pass the right crtc in explicitly but only
> > > assign it when the uapi state indicates the plane to be logically
> > > enabled (ie. uapi.crtc != NULL).
> > > 
> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > > ---
> > >  .../gpu/drm/i915/display/intel_atomic_plane.c | 59 +++++++++++++------
> > >  .../gpu/drm/i915/display/intel_atomic_plane.h |  3 +-
> > >  drivers/gpu/drm/i915/display/intel_display.c  |  5 +-
> > >  3 files changed, 46 insertions(+), 21 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > index f47558efb3c2..7abb0e3d6c0b 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
> > > @@ -247,11 +247,19 @@ static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
> > >  }
> > >  
> > >  void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
> > > -				       const struct intel_plane_state *from_plane_state)
> > > +				       const struct intel_plane_state *from_plane_state,
> > > +				       struct intel_crtc *crtc)
> > >  {
> > >  	intel_plane_clear_hw_state(plane_state);
> > >  
> > > -	plane_state->hw.crtc = from_plane_state->uapi.crtc;
> > > +	/*
> > > +	 * For the bigjoiner slave uapi.crtc will point at
> > > +	 * the master crtc. So we explicitly assign the right
> > > +	 * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
> > > +	 * the plane is logically enabled on the uapi level.
> > > +	 */
> > > +	plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
> > 
> > But here in case of bigjoiner_slave we actualy compute new_master_plane_state from master_plane which is
> > obtained from the slaves linked crtc.
> > 
> > So here, even for the slave plane's hw.crtc we are using master's uapi.crtc? Is that what is happening here?
> 
> Yes.

Ok gotcha

Reviewed-by: Manasi Navare <manasi.d.navare@intel.com>

Manasi

> 
> -- 
> Ville Syrjälä
> Intel
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index f47558efb3c2..7abb0e3d6c0b 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -247,11 +247,19 @@  static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
 }
 
 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
-				       const struct intel_plane_state *from_plane_state)
+				       const struct intel_plane_state *from_plane_state,
+				       struct intel_crtc *crtc)
 {
 	intel_plane_clear_hw_state(plane_state);
 
-	plane_state->hw.crtc = from_plane_state->uapi.crtc;
+	/*
+	 * For the bigjoiner slave uapi.crtc will point at
+	 * the master crtc. So we explicitly assign the right
+	 * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
+	 * the plane is logically enabled on the uapi level.
+	 */
+	plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
+
 	plane_state->hw.fb = from_plane_state->uapi.fb;
 	if (plane_state->hw.fb)
 		drm_framebuffer_get(plane_state->hw.fb);
@@ -331,15 +339,16 @@  int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_
 					       old_plane_state, new_plane_state);
 }
 
-static struct intel_crtc *
-get_crtc_from_states(const struct intel_plane_state *old_plane_state,
-		     const struct intel_plane_state *new_plane_state)
+static struct intel_plane *
+intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
 {
-	if (new_plane_state->uapi.crtc)
-		return to_intel_crtc(new_plane_state->uapi.crtc);
+	struct drm_i915_private *i915 = to_i915(crtc->base.dev);
+	struct intel_plane *plane;
 
-	if (old_plane_state->uapi.crtc)
-		return to_intel_crtc(old_plane_state->uapi.crtc);
+	for_each_intel_plane_on_crtc(&i915->drm, crtc, plane) {
+		if (plane->id == plane_id)
+			return plane;
+	}
 
 	return NULL;
 }
@@ -347,23 +356,37 @@  get_crtc_from_states(const struct intel_plane_state *old_plane_state,
 int intel_plane_atomic_check(struct intel_atomic_state *state,
 			     struct intel_plane *plane)
 {
+	struct drm_i915_private *i915 = to_i915(state->base.dev);
 	struct intel_plane_state *new_plane_state =
 		intel_atomic_get_new_plane_state(state, plane);
 	const struct intel_plane_state *old_plane_state =
 		intel_atomic_get_old_plane_state(state, plane);
-	struct intel_crtc *crtc =
-		get_crtc_from_states(old_plane_state, new_plane_state);
-	const struct intel_crtc_state *old_crtc_state;
-	struct intel_crtc_state *new_crtc_state;
+	const struct intel_plane_state *new_master_plane_state;
+	struct intel_crtc *crtc = intel_get_crtc_for_pipe(i915, plane->pipe);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+
+	if (new_crtc_state && new_crtc_state->bigjoiner_slave) {
+		struct intel_plane *master_plane =
+			intel_crtc_get_plane(new_crtc_state->bigjoiner_linked_crtc,
+					     plane->id);
+
+		new_master_plane_state =
+			intel_atomic_get_new_plane_state(state, master_plane);
+	} else {
+		new_master_plane_state = new_plane_state;
+	}
+
+	intel_plane_copy_uapi_to_hw_state(new_plane_state,
+					  new_master_plane_state,
+					  crtc);
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
 	new_plane_state->uapi.visible = false;
-	if (!crtc)
+	if (!new_crtc_state)
 		return 0;
 
-	old_crtc_state = intel_atomic_get_old_crtc_state(state, crtc);
-	new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
-
 	return intel_plane_atomic_check_with_state(old_crtc_state,
 						   new_crtc_state,
 						   old_plane_state,
diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.h b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
index 24a3a148aa62..5cae9db41062 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.h
@@ -24,7 +24,8 @@  unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
 unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
 				   const struct intel_plane_state *plane_state);
 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
-				       const struct intel_plane_state *from_plane_state);
+				       const struct intel_plane_state *from_plane_state,
+				       struct intel_crtc *crtc);
 void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
 			       const struct intel_plane_state *from_plane_state);
 void intel_update_plane(struct intel_plane *plane,
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 1118ff73c0d4..55e0a2f21d98 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -3718,7 +3718,8 @@  intel_find_initial_plane_obj(struct intel_crtc *intel_crtc,
 	drm_framebuffer_get(fb);
 
 	plane_state->crtc = &intel_crtc->base;
-	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state);
+	intel_plane_copy_uapi_to_hw_state(intel_state, intel_state,
+					  intel_crtc);
 
 	intel_frontbuffer_flush(to_intel_frontbuffer(fb), ORIGIN_DIRTYFB);
 
@@ -16942,7 +16943,7 @@  intel_legacy_cursor_update(struct drm_plane *_plane,
 	new_plane_state->uapi.crtc_w = crtc_w;
 	new_plane_state->uapi.crtc_h = crtc_h;
 
-	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state);
+	intel_plane_copy_uapi_to_hw_state(new_plane_state, new_plane_state, crtc);
 
 	ret = intel_plane_atomic_check_with_state(crtc_state, new_crtc_state,
 						  old_plane_state, new_plane_state);