Re: [PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-06-13 Thread Abhinav Kumar




On 6/13/2024 3:05 AM, Dmitry Baryshkov wrote:

On Wed, Jun 12, 2024 at 06:17:37PM -0700, Abhinav Kumar wrote:



On 6/12/2024 2:08 AM, Dmitry Baryshkov wrote:

On Wed, 12 Jun 2024 at 02:12, Abhinav Kumar  wrote:




On 3/13/2024 5:02 PM, Dmitry Baryshkov wrote:

Since SmartDMA planes provide two rectangles, it is possible to use them
to drive two different DRM planes, first plane getting the rect_0,
another one using rect_1 of the same SSPP. The sharing algorithm is
pretty simple, it requires that each of the planes can be driven by the
single rectangle and only consequetive planes are considered.



consequetive - > consecutive

Can you please explain why only consecutive planes are considered for this?

So lets say we have 4 virtual planes : 0, 1, 2, 3

It will try 0-1, 1-2, 2-3

Because all planes are virtual, there are only 3 unique pairs to be
considered? Otherwise technically 6 pairs are possible.


An implementation that tries all 6 pairs taking the zpos and the
overlapping into account is appreciated. I cared for the simplest case
here. Yes, further optimizations can be implemented.



Ok got it. So you would like to build a better one on top of this.
But I see one case where this has an issue or is not optimal. Pls see below.


Yes, it is not optimal. This is the 'best possible effort' or 'best
simple effort' from my POV.






General request:

Patches 1-9 : Add support for using 2 SSPPs in one plane
Patches 10-12 : Add support for using two rectangles of the same SSPP as
two virtual planes
Patch 13 : Can be pushed along with the first set.

Can we break up this series in this way to make it easier to test and
land the bulk of it in this cycle?


Sure.



Thanks.



I have some doubts on patches 10-12 and would like to spend more time
reviewing and testing this. So I am trying to reduce the debt of patches
we have been carrying as this is a tricky feature to simulate and test
the cases.


Signed-off-by: Dmitry Baryshkov 
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 +++---
1 file changed, 112 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cde20c1fa90d..2e1c544efc4a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
return 0;
}

-static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
-struct dpu_sw_pipe_cfg 
*pipe_cfg,
-const struct dpu_format *fmt,
-uint32_t max_linewidth)
+static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   const struct dpu_format *fmt)
{
if (drm_rect_width(&pipe_cfg->src_rect) != 
drm_rect_width(&pipe_cfg->dst_rect) ||
drm_rect_height(&pipe_cfg->src_rect) != 
drm_rect_height(&pipe_cfg->dst_rect))
@@ -901,6 +900,13 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
if (DPU_FORMAT_IS_YUV(fmt))
return false;

+ return true;
+}
+
+static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
if (DPU_FORMAT_IS_UBWC(fmt) &&
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
return false;
@@ -908,6 +914,82 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
return true;
}

+static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
+struct dpu_sw_pipe_cfg 
*pipe_cfg,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
+ return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
+ dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
+}
+
+
+static int dpu_plane_try_multirect(struct dpu_plane_state *pstate,
+struct dpu_plane_state *prev_pstate,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
+ struct dpu_sw_pipe *pipe = &pstate->pipe;
+ struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+ struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+ struct dpu_sw_pipe *prev_pipe = &prev_pstate->pipe;
+ struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_pstate->pipe_cfg;
+ const struct dpu_format *prev_fmt =
+ to_dpu_format(msm_framebuffer_format(prev_pstate->base.fb));
+ u16 max_tile_height = 1;
+

Re: [PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-06-13 Thread Dmitry Baryshkov
On Wed, Jun 12, 2024 at 06:17:37PM -0700, Abhinav Kumar wrote:
> 
> 
> On 6/12/2024 2:08 AM, Dmitry Baryshkov wrote:
> > On Wed, 12 Jun 2024 at 02:12, Abhinav Kumar  
> > wrote:
> > > 
> > > 
> > > 
> > > On 3/13/2024 5:02 PM, Dmitry Baryshkov wrote:
> > > > Since SmartDMA planes provide two rectangles, it is possible to use them
> > > > to drive two different DRM planes, first plane getting the rect_0,
> > > > another one using rect_1 of the same SSPP. The sharing algorithm is
> > > > pretty simple, it requires that each of the planes can be driven by the
> > > > single rectangle and only consequetive planes are considered.
> > > > 
> > > 
> > > consequetive - > consecutive
> > > 
> > > Can you please explain why only consecutive planes are considered for 
> > > this?
> > > 
> > > So lets say we have 4 virtual planes : 0, 1, 2, 3
> > > 
> > > It will try 0-1, 1-2, 2-3
> > > 
> > > Because all planes are virtual, there are only 3 unique pairs to be
> > > considered? Otherwise technically 6 pairs are possible.
> > 
> > An implementation that tries all 6 pairs taking the zpos and the
> > overlapping into account is appreciated. I cared for the simplest case
> > here. Yes, further optimizations can be implemented.
> > 
> 
> Ok got it. So you would like to build a better one on top of this.
> But I see one case where this has an issue or is not optimal. Pls see below.

Yes, it is not optimal. This is the 'best possible effort' or 'best
simple effort' from my POV.

> 
> > > 
> > > 
> > > General request:
> > > 
> > > Patches 1-9 : Add support for using 2 SSPPs in one plane
> > > Patches 10-12 : Add support for using two rectangles of the same SSPP as
> > > two virtual planes
> > > Patch 13 : Can be pushed along with the first set.
> > > 
> > > Can we break up this series in this way to make it easier to test and
> > > land the bulk of it in this cycle?
> > 
> > Sure.
> > 
> 
> Thanks.
> 
> > > 
> > > I have some doubts on patches 10-12 and would like to spend more time
> > > reviewing and testing this. So I am trying to reduce the debt of patches
> > > we have been carrying as this is a tricky feature to simulate and test
> > > the cases.
> > > 
> > > > Signed-off-by: Dmitry Baryshkov 
> > > > ---
> > > >drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 
> > > > +++---
> > > >1 file changed, 112 insertions(+), 16 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
> > > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > index cde20c1fa90d..2e1c544efc4a 100644
> > > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > > > @@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct 
> > > > drm_plane *plane,
> > > >return 0;
> > > >}
> > > > 
> > > > -static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe 
> > > > *pipe,
> > > > -struct dpu_sw_pipe_cfg 
> > > > *pipe_cfg,
> > > > -const struct 
> > > > dpu_format *fmt,
> > > > -uint32_t max_linewidth)
> > > > +static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
> > > > +   struct dpu_sw_pipe_cfg 
> > > > *pipe_cfg,
> > > > +   const struct dpu_format *fmt)
> > > >{
> > > >if (drm_rect_width(&pipe_cfg->src_rect) != 
> > > > drm_rect_width(&pipe_cfg->dst_rect) ||
> > > >drm_rect_height(&pipe_cfg->src_rect) != 
> > > > drm_rect_height(&pipe_cfg->dst_rect))
> > > > @@ -901,6 +900,13 @@ static int 
> > > > dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
> > > >if (DPU_FORMAT_IS_YUV(fmt))
> > > >return false;
> > > > 
> > > > + return true;
> > > > +}
> > > > +
> > > > +static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg 
> > > > *pipe_cfg,
> > > > +  const struct dpu_format *fmt,
> > > > +  uint32_t max_linewidth)
> > > > +{
> > > >if (DPU_FORMAT_IS_UBWC(fmt) &&
> > > >drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
> > > >return false;
> > > > @@ -908,6 +914,82 @@ static int 
> > > > dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
> > > >return true;
> > > >}
> > > > 
> > > > +static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe 
> > > > *pipe,
> > > > +struct dpu_sw_pipe_cfg 
> > > > *pipe_cfg,
> > > > +const struct 
> > > > dpu_format *fmt,
> > > > +uint32_t max_linewidth)
> > > > +{
> > > > + return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
> > > > + dpu_plane_is_parallel_capa

Re: [PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-06-12 Thread Abhinav Kumar




On 6/12/2024 2:08 AM, Dmitry Baryshkov wrote:

On Wed, 12 Jun 2024 at 02:12, Abhinav Kumar  wrote:




On 3/13/2024 5:02 PM, Dmitry Baryshkov wrote:

Since SmartDMA planes provide two rectangles, it is possible to use them
to drive two different DRM planes, first plane getting the rect_0,
another one using rect_1 of the same SSPP. The sharing algorithm is
pretty simple, it requires that each of the planes can be driven by the
single rectangle and only consequetive planes are considered.



consequetive - > consecutive

Can you please explain why only consecutive planes are considered for this?

So lets say we have 4 virtual planes : 0, 1, 2, 3

It will try 0-1, 1-2, 2-3

Because all planes are virtual, there are only 3 unique pairs to be
considered? Otherwise technically 6 pairs are possible.


An implementation that tries all 6 pairs taking the zpos and the
overlapping into account is appreciated. I cared for the simplest case
here. Yes, further optimizations can be implemented.



Ok got it. So you would like to build a better one on top of this.
But I see one case where this has an issue or is not optimal. Pls see below.




General request:

Patches 1-9 : Add support for using 2 SSPPs in one plane
Patches 10-12 : Add support for using two rectangles of the same SSPP as
two virtual planes
Patch 13 : Can be pushed along with the first set.

Can we break up this series in this way to make it easier to test and
land the bulk of it in this cycle?


Sure.



Thanks.



I have some doubts on patches 10-12 and would like to spend more time
reviewing and testing this. So I am trying to reduce the debt of patches
we have been carrying as this is a tricky feature to simulate and test
the cases.


Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 +++---
   1 file changed, 112 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cde20c1fa90d..2e1c544efc4a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
   return 0;
   }

-static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
-struct dpu_sw_pipe_cfg 
*pipe_cfg,
-const struct dpu_format *fmt,
-uint32_t max_linewidth)
+static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   const struct dpu_format *fmt)
   {
   if (drm_rect_width(&pipe_cfg->src_rect) != 
drm_rect_width(&pipe_cfg->dst_rect) ||
   drm_rect_height(&pipe_cfg->src_rect) != 
drm_rect_height(&pipe_cfg->dst_rect))
@@ -901,6 +900,13 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
   if (DPU_FORMAT_IS_YUV(fmt))
   return false;

+ return true;
+}
+
+static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
   if (DPU_FORMAT_IS_UBWC(fmt) &&
   drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
   return false;
@@ -908,6 +914,82 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
   return true;
   }

+static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
+struct dpu_sw_pipe_cfg 
*pipe_cfg,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
+ return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
+ dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
+}
+
+
+static int dpu_plane_try_multirect(struct dpu_plane_state *pstate,
+struct dpu_plane_state *prev_pstate,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
+ struct dpu_sw_pipe *pipe = &pstate->pipe;
+ struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+ struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+ struct dpu_sw_pipe *prev_pipe = &prev_pstate->pipe;
+ struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_pstate->pipe_cfg;
+ const struct dpu_format *prev_fmt =
+ to_dpu_format(msm_framebuffer_format(prev_pstate->base.fb));
+ u16 max_tile_height = 1;
+
+ if (prev_pstate->r_pipe.sspp != NULL ||
+ prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE)
+ return false;
+
+ if (!dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) ||
+ !dpu_plane

Re: [PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-06-12 Thread Dmitry Baryshkov
On Wed, 12 Jun 2024 at 02:12, Abhinav Kumar  wrote:
>
>
>
> On 3/13/2024 5:02 PM, Dmitry Baryshkov wrote:
> > Since SmartDMA planes provide two rectangles, it is possible to use them
> > to drive two different DRM planes, first plane getting the rect_0,
> > another one using rect_1 of the same SSPP. The sharing algorithm is
> > pretty simple, it requires that each of the planes can be driven by the
> > single rectangle and only consequetive planes are considered.
> >
>
> consequetive - > consecutive
>
> Can you please explain why only consecutive planes are considered for this?
>
> So lets say we have 4 virtual planes : 0, 1, 2, 3
>
> It will try 0-1, 1-2, 2-3
>
> Because all planes are virtual, there are only 3 unique pairs to be
> considered? Otherwise technically 6 pairs are possible.

An implementation that tries all 6 pairs taking the zpos and the
overlapping into account is appreciated. I cared for the simplest case
here. Yes, further optimizations can be implemented.

>
>
> General request:
>
> Patches 1-9 : Add support for using 2 SSPPs in one plane
> Patches 10-12 : Add support for using two rectangles of the same SSPP as
> two virtual planes
> Patch 13 : Can be pushed along with the first set.
>
> Can we break up this series in this way to make it easier to test and
> land the bulk of it in this cycle?

Sure.

>
> I have some doubts on patches 10-12 and would like to spend more time
> reviewing and testing this. So I am trying to reduce the debt of patches
> we have been carrying as this is a tricky feature to simulate and test
> the cases.
>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 +++---
> >   1 file changed, 112 insertions(+), 16 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index cde20c1fa90d..2e1c544efc4a 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct 
> > drm_plane *plane,
> >   return 0;
> >   }
> >
> > -static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe 
> > *pipe,
> > -struct dpu_sw_pipe_cfg 
> > *pipe_cfg,
> > -const struct dpu_format 
> > *fmt,
> > -uint32_t max_linewidth)
> > +static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
> > +   struct dpu_sw_pipe_cfg *pipe_cfg,
> > +   const struct dpu_format *fmt)
> >   {
> >   if (drm_rect_width(&pipe_cfg->src_rect) != 
> > drm_rect_width(&pipe_cfg->dst_rect) ||
> >   drm_rect_height(&pipe_cfg->src_rect) != 
> > drm_rect_height(&pipe_cfg->dst_rect))
> > @@ -901,6 +900,13 @@ static int 
> > dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
> >   if (DPU_FORMAT_IS_YUV(fmt))
> >   return false;
> >
> > + return true;
> > +}
> > +
> > +static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
> > +  const struct dpu_format *fmt,
> > +  uint32_t max_linewidth)
> > +{
> >   if (DPU_FORMAT_IS_UBWC(fmt) &&
> >   drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
> >   return false;
> > @@ -908,6 +914,82 @@ static int 
> > dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
> >   return true;
> >   }
> >
> > +static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe 
> > *pipe,
> > +struct dpu_sw_pipe_cfg 
> > *pipe_cfg,
> > +const struct dpu_format 
> > *fmt,
> > +uint32_t max_linewidth)
> > +{
> > + return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
> > + dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
> > +}
> > +
> > +
> > +static int dpu_plane_try_multirect(struct dpu_plane_state *pstate,
> > +struct dpu_plane_state *prev_pstate,
> > +const struct dpu_format *fmt,
> > +uint32_t max_linewidth)
> > +{
> > + struct dpu_sw_pipe *pipe = &pstate->pipe;
> > + struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> > + struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
> > + struct dpu_sw_pipe *prev_pipe = &prev_pstate->pipe;
> > + struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_pstate->pipe_cfg;
> > + const struct dpu_format *prev_fmt =
> > + to_dpu_format(msm_framebuffer_format(prev_pstate->base.fb));
> > + u16 max_tile_height = 1;
> > +
> > + if (prev_pstate->r_pipe.sspp != NULL ||
> > + prev_pipe->m

Re: [PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-06-11 Thread Abhinav Kumar




On 3/13/2024 5:02 PM, Dmitry Baryshkov wrote:

Since SmartDMA planes provide two rectangles, it is possible to use them
to drive two different DRM planes, first plane getting the rect_0,
another one using rect_1 of the same SSPP. The sharing algorithm is
pretty simple, it requires that each of the planes can be driven by the
single rectangle and only consequetive planes are considered.



consequetive - > consecutive

Can you please explain why only consecutive planes are considered for this?

So lets say we have 4 virtual planes : 0, 1, 2, 3

It will try 0-1, 1-2, 2-3

Because all planes are virtual, there are only 3 unique pairs to be 
considered? Otherwise technically 6 pairs are possible.



General request:

Patches 1-9 : Add support for using 2 SSPPs in one plane
Patches 10-12 : Add support for using two rectangles of the same SSPP as 
two virtual planes

Patch 13 : Can be pushed along with the first set.

Can we break up this series in this way to make it easier to test and 
land the bulk of it in this cycle?


I have some doubts on patches 10-12 and would like to spend more time 
reviewing and testing this. So I am trying to reduce the debt of patches 
we have been carrying as this is a tricky feature to simulate and test 
the cases.



Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 +++---
  1 file changed, 112 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cde20c1fa90d..2e1c544efc4a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
return 0;
  }
  
-static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,

-  struct dpu_sw_pipe_cfg 
*pipe_cfg,
-  const struct dpu_format *fmt,
-  uint32_t max_linewidth)
+static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
+ struct dpu_sw_pipe_cfg *pipe_cfg,
+ const struct dpu_format *fmt)
  {
if (drm_rect_width(&pipe_cfg->src_rect) != 
drm_rect_width(&pipe_cfg->dst_rect) ||
drm_rect_height(&pipe_cfg->src_rect) != 
drm_rect_height(&pipe_cfg->dst_rect))
@@ -901,6 +900,13 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
if (DPU_FORMAT_IS_YUV(fmt))
return false;
  
+	return true;

+}
+
+static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
if (DPU_FORMAT_IS_UBWC(fmt) &&
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
return false;
@@ -908,6 +914,82 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
return true;
  }
  
+static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,

+  struct dpu_sw_pipe_cfg 
*pipe_cfg,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
+   return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
+   dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
+}
+
+
+static int dpu_plane_try_multirect(struct dpu_plane_state *pstate,
+  struct dpu_plane_state *prev_pstate,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
+   struct dpu_sw_pipe *pipe = &pstate->pipe;
+   struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+   struct dpu_sw_pipe *prev_pipe = &prev_pstate->pipe;
+   struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_pstate->pipe_cfg;
+   const struct dpu_format *prev_fmt =
+   to_dpu_format(msm_framebuffer_format(prev_pstate->base.fb));
+   u16 max_tile_height = 1;
+
+   if (prev_pstate->r_pipe.sspp != NULL ||
+   prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE)
+   return false;
+
+   if (!dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) ||
+   !dpu_plane_is_multirect_capable(prev_pipe, prev_pipe_cfg, prev_fmt) 
||
+   !(test_bit(DPU_SSPP_SMART_DMA_V1, &prev_pipe->sspp->cap->features) 
||
+ test_bit(DPU_SSPP_SMART_DMA_V2, &prev_pipe->sspp->cap->features)))


This test_bit check should be absorbed into 
dpu_plane_is_multirect_capable()?



+   return false;
+
+   if (DPU_FORMAT_IS_UBWC(fmt))
+ 

[PATCH v4 10/13] drm/msm/dpu: allow sharing SSPP between planes

2024-03-13 Thread Dmitry Baryshkov
Since SmartDMA planes provide two rectangles, it is possible to use them
to drive two different DRM planes, first plane getting the rect_0,
another one using rect_1 of the same SSPP. The sharing algorithm is
pretty simple, it requires that each of the planes can be driven by the
single rectangle and only consequetive planes are considered.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 128 +++---
 1 file changed, 112 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cde20c1fa90d..2e1c544efc4a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -886,10 +886,9 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
return 0;
 }
 
-static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
-  struct dpu_sw_pipe_cfg 
*pipe_cfg,
-  const struct dpu_format *fmt,
-  uint32_t max_linewidth)
+static int dpu_plane_is_multirect_capable(struct dpu_sw_pipe *pipe,
+ struct dpu_sw_pipe_cfg *pipe_cfg,
+ const struct dpu_format *fmt)
 {
if (drm_rect_width(&pipe_cfg->src_rect) != 
drm_rect_width(&pipe_cfg->dst_rect) ||
drm_rect_height(&pipe_cfg->src_rect) != 
drm_rect_height(&pipe_cfg->dst_rect))
@@ -901,6 +900,13 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
if (DPU_FORMAT_IS_YUV(fmt))
return false;
 
+   return true;
+}
+
+static int dpu_plane_is_parallel_capable(struct dpu_sw_pipe_cfg *pipe_cfg,
+const struct dpu_format *fmt,
+uint32_t max_linewidth)
+{
if (DPU_FORMAT_IS_UBWC(fmt) &&
drm_rect_width(&pipe_cfg->src_rect) > max_linewidth / 2)
return false;
@@ -908,6 +914,82 @@ static int dpu_plane_is_multirect_parallel_capable(struct 
dpu_sw_pipe *pipe,
return true;
 }
 
+static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
+  struct dpu_sw_pipe_cfg 
*pipe_cfg,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
+   return dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) &&
+   dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth);
+}
+
+
+static int dpu_plane_try_multirect(struct dpu_plane_state *pstate,
+  struct dpu_plane_state *prev_pstate,
+  const struct dpu_format *fmt,
+  uint32_t max_linewidth)
+{
+   struct dpu_sw_pipe *pipe = &pstate->pipe;
+   struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+   struct dpu_sw_pipe *prev_pipe = &prev_pstate->pipe;
+   struct dpu_sw_pipe_cfg *prev_pipe_cfg = &prev_pstate->pipe_cfg;
+   const struct dpu_format *prev_fmt =
+   to_dpu_format(msm_framebuffer_format(prev_pstate->base.fb));
+   u16 max_tile_height = 1;
+
+   if (prev_pstate->r_pipe.sspp != NULL ||
+   prev_pipe->multirect_mode != DPU_SSPP_MULTIRECT_NONE)
+   return false;
+
+   if (!dpu_plane_is_multirect_capable(pipe, pipe_cfg, fmt) ||
+   !dpu_plane_is_multirect_capable(prev_pipe, prev_pipe_cfg, prev_fmt) 
||
+   !(test_bit(DPU_SSPP_SMART_DMA_V1, &prev_pipe->sspp->cap->features) 
||
+ test_bit(DPU_SSPP_SMART_DMA_V2, &prev_pipe->sspp->cap->features)))
+   return false;
+
+   if (DPU_FORMAT_IS_UBWC(fmt))
+   max_tile_height = max(max_tile_height, fmt->tile_height);
+
+   if (DPU_FORMAT_IS_UBWC(prev_fmt))
+   max_tile_height = max(max_tile_height, prev_fmt->tile_height);
+
+   r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+   r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+   r_pipe->sspp = NULL;
+
+   if (dpu_plane_is_parallel_capable(pipe_cfg, fmt, max_linewidth) &&
+   dpu_plane_is_parallel_capable(prev_pipe_cfg, prev_fmt, 
max_linewidth) &&
+   (pipe_cfg->dst_rect.x1 >= prev_pipe_cfg->dst_rect.x2 ||
+prev_pipe_cfg->dst_rect.x1 >= pipe_cfg->dst_rect.x2)) {
+   pipe->sspp = prev_pipe->sspp;
+
+   pipe->multirect_index = DPU_SSPP_RECT_1;
+   pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+   prev_pipe->multirect_index = DPU_SSPP_RECT_0;
+   prev_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+   return true;
+   }
+
+   if (pipe_cfg->dst_rect