Re: [Freedreno] [RFC PATCH 1/2] drm/msm/dpu: add dsc helper functions

2023-03-16 Thread Abhinav Kumar




On 3/16/2023 9:36 AM, Abhinav Kumar wrote:



On 3/16/2023 9:23 AM, Dmitry Baryshkov wrote:

On 16/03/2023 18:13, Abhinav Kumar wrote:



On 3/16/2023 9:03 AM, Dmitry Baryshkov wrote:

Hi,

[removed previous conversation]



Hi Dmitry and Abhinav,

Just wanted to follow up on this thread. I've gone over the 
MSM-specific

DSC params for DP and DSI and have found a few shared calculations and
variables between both DSI and DP paths:

- (as mentioned earlier in the thread) almost all the calculations in
dpu_dsc_populate_dsc_config() match dsi_populate_dsc_params() [1]. The
only difference in the math I'm seeing is initial_scale_value.


The value in dsi code is valid for initial_offset = 6144. Please use
the formula from the standard (= sde_dsc_populate_dsc_config) and add
it to drm_dsc_helper.c



Yes, I agree with this part. for rc_model_size we can use 
DSC_RC_MODEL_SIZE_CONST.


initial_offset is already handled in 
https://patchwork.freedesktop.org/patch/525424/?series=114472&rev=2


Then we can use this math:

rc_model_size / (rc_model_size -
initial_offset), keeping in mind that initial_scale_value has three 
fractional bits.


So this would be 8192 / (8192 - 6144) = 4

Then << 3 for 3 fractional bits = 32.


If I remember correctly the last remaining item in
dsi_populate_dsc_params() (except mentioned initial_offset) was
line_buf_depth, see [3]. I'm not sure about setting it to bpc+1.
According to the standard it should come from a DSC decoder spec,
which means it should be set by the DSI panel driver or via
drm_dp_dsc_sink_line_buf_depth() in the case of DP output.

- dsc_extra_pclk_cycle_cnt and dce_bytes_per_line, which were 
introduced
in Kuogee's v1 DSC series [2], are used for DSI, DP, and the DPU 
timing

engine. dsc_extra_pclk_cycle_cnt is calculated based on pclk_per_line
(which is calculated differently between DP and DSI), but
dce_bytes_per_line is calculated the same way between DP and DSI.

To avoid having to duplicate math in 2 different places, I think it
would help to have these calculations in some msm_dsc_helper.c 
file. Any

thoughts on this?


dsc_extra_pclk_cycle_cnt and dce_bytes_per_line are used only in DPU
code, so they can stay in DPU driver.



They can stay in the dpu driver is fine but where?

Like Jessica wrote, this is computed and used in 3 places today :

1) DSI video engine computation
2) DP controller computation
3) timing engine programming


Please excuse me if I'm wrong. I checked both vendor techpack and the 
Kuogee's patches. I see them being used only in the SDE / DPU driver 
code. Could you please point me to the code path that we are discussing?




DSI code :

https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/dsi/dsi_host.c#L868 



DP code:

Refer to dp_panel_dsc_pclk_param_calc in 
https://patchwork.freedesktop.org/patch/519837/?series=113240&rev=1


Timing engine:

refer to 
https://patchwork.freedesktop.org/patch/519838/?series=113240&rev=1


Probably confusion is due to the naming. bytes_per_line is nothing but 
bytes_per_pkt * pkt_per_line but the concept is common for DP and DSI.


+    if (phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC) {
+    phys->dsc_extra_pclk_cycle_cnt = dsc_info->pclk_per_line;
+    phys->dsc_extra_disp_width = dsc_info->extra_width;
+    phys->dce_bytes_per_line =
+    dsc_info->bytes_per_pkt * dsc_info->pkt_per_line;



So either we have a helper in a common location somewhere so that 
these 3 modules can call that helper and use it OR each module 
duplicates the computation code.


What should be the common location is the discussion here.

It cannot be dpu_encoder.c as the DSI/DP dont call into the encoder 
methods.




Thanks,

Jessica Zhang

[1]
https://elixir.bootlin.com/linux/v6.3-rc2/source/drivers/gpu/drm/msm/dsi/dsi_host.c#L1756 



[2] 
https://patchwork.freedesktop.org/patch/519845/?series=113240&rev=1


[3] https://patchwork.freedesktop.org/patch/525441/?series=114472&rev=2







Re: [Freedreno] [PATCH v10 01/15] dma-buf/dma-fence: Add deadline awareness

2023-03-16 Thread Rob Clark
On Thu, Mar 16, 2023 at 3:22 PM Sebastian Wick
 wrote:
>
> On Thu, Mar 16, 2023 at 5:29 PM Rob Clark  wrote:
> >
> > On Thu, Mar 16, 2023 at 2:26 AM Jonas Ådahl  wrote:
> > >
> > > On Wed, Mar 15, 2023 at 09:19:49AM -0700, Rob Clark wrote:
> > > > On Wed, Mar 15, 2023 at 6:53 AM Jonas Ådahl  wrote:
> > > > >
> > > > > On Fri, Mar 10, 2023 at 09:38:18AM -0800, Rob Clark wrote:
> > > > > > On Fri, Mar 10, 2023 at 7:45 AM Jonas Ådahl  
> > > > > > wrote:
> > > > > > >
> > > > > > > On Wed, Mar 08, 2023 at 07:52:52AM -0800, Rob Clark wrote:
> > > > > > > > From: Rob Clark 
> > > > > > > >
> > > > > > > > Add a way to hint to the fence signaler of an upcoming 
> > > > > > > > deadline, such as
> > > > > > > > vblank, which the fence waiter would prefer not to miss.  This 
> > > > > > > > is to aid
> > > > > > > > the fence signaler in making power management decisions, like 
> > > > > > > > boosting
> > > > > > > > frequency as the deadline approaches and awareness of missing 
> > > > > > > > deadlines
> > > > > > > > so that can be factored in to the frequency scaling.
> > > > > > > >
> > > > > > > > v2: Drop dma_fence::deadline and related logic to filter 
> > > > > > > > duplicate
> > > > > > > > deadlines, to avoid increasing dma_fence size.  The 
> > > > > > > > fence-context
> > > > > > > > implementation will need similar logic to track deadlines 
> > > > > > > > of all
> > > > > > > > the fences on the same timeline.  [ckoenig]
> > > > > > > > v3: Clarify locking wrt. set_deadline callback
> > > > > > > > v4: Clarify in docs comment that this is a hint
> > > > > > > > v5: Drop DMA_FENCE_FLAG_HAS_DEADLINE_BIT.
> > > > > > > > v6: More docs
> > > > > > > > v7: Fix typo, clarify past deadlines
> > > > > > > >
> > > > > > > > Signed-off-by: Rob Clark 
> > > > > > > > Reviewed-by: Christian König 
> > > > > > > > Acked-by: Pekka Paalanen 
> > > > > > > > Reviewed-by: Bagas Sanjaya 
> > > > > > > > ---
> > > > > > >
> > > > > > > Hi Rob!
> > > > > > >
> > > > > > > >  Documentation/driver-api/dma-buf.rst |  6 +++
> > > > > > > >  drivers/dma-buf/dma-fence.c  | 59 
> > > > > > > > 
> > > > > > > >  include/linux/dma-fence.h| 22 +++
> > > > > > > >  3 files changed, 87 insertions(+)
> > > > > > > >
> > > > > > > > diff --git a/Documentation/driver-api/dma-buf.rst 
> > > > > > > > b/Documentation/driver-api/dma-buf.rst
> > > > > > > > index 622b8156d212..183e480d8cea 100644
> > > > > > > > --- a/Documentation/driver-api/dma-buf.rst
> > > > > > > > +++ b/Documentation/driver-api/dma-buf.rst
> > > > > > > > @@ -164,6 +164,12 @@ DMA Fence Signalling Annotations
> > > > > > > >  .. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > > > :doc: fence signalling annotation
> > > > > > > >
> > > > > > > > +DMA Fence Deadline Hints
> > > > > > > > +
> > > > > > > > +
> > > > > > > > +.. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > > > +   :doc: deadline hints
> > > > > > > > +
> > > > > > > >  DMA Fences Functions Reference
> > > > > > > >  ~~
> > > > > > > >
> > > > > > > > diff --git a/drivers/dma-buf/dma-fence.c 
> > > > > > > > b/drivers/dma-buf/dma-fence.c
> > > > > > > > index 0de0482cd36e..f177c56269bb 100644
> > > > > > > > --- a/drivers/dma-buf/dma-fence.c
> > > > > > > > +++ b/drivers/dma-buf/dma-fence.c
> > > > > > > > @@ -912,6 +912,65 @@ dma_fence_wait_any_timeout(struct 
> > > > > > > > dma_fence **fences, uint32_t count,
> > > > > > > >  }
> > > > > > > >  EXPORT_SYMBOL(dma_fence_wait_any_timeout);
> > > > > > > >
> > > > > > > > +/**
> > > > > > > > + * DOC: deadline hints
> > > > > > > > + *
> > > > > > > > + * In an ideal world, it would be possible to pipeline a 
> > > > > > > > workload sufficiently
> > > > > > > > + * that a utilization based device frequency governor could 
> > > > > > > > arrive at a minimum
> > > > > > > > + * frequency that meets the requirements of the use-case, in 
> > > > > > > > order to minimize
> > > > > > > > + * power consumption.  But in the real world there are many 
> > > > > > > > workloads which
> > > > > > > > + * defy this ideal.  For example, but not limited to:
> > > > > > > > + *
> > > > > > > > + * * Workloads that ping-pong between device and CPU, with 
> > > > > > > > alternating periods
> > > > > > > > + *   of CPU waiting for device, and device waiting on CPU.  
> > > > > > > > This can result in
> > > > > > > > + *   devfreq and cpufreq seeing idle time in their respective 
> > > > > > > > domains and in
> > > > > > > > + *   result reduce frequency.
> > > > > > > > + *
> > > > > > > > + * * Workloads that interact with a periodic time based 
> > > > > > > > deadline, such as double
> > > > > > > > + *   buffered GPU rendering vs vblank sync'd page flipping.  
> > > > > > > > In this scenario,
> > > > > > > > + *   missing a vblank deadline results in an *increase* in 
> > > > > > > > idle time on the GPU
> > > > > > > > + * 

Re: [Freedreno] [PATCH v10 01/15] dma-buf/dma-fence: Add deadline awareness

2023-03-16 Thread Sebastian Wick
On Thu, Mar 16, 2023 at 5:29 PM Rob Clark  wrote:
>
> On Thu, Mar 16, 2023 at 2:26 AM Jonas Ådahl  wrote:
> >
> > On Wed, Mar 15, 2023 at 09:19:49AM -0700, Rob Clark wrote:
> > > On Wed, Mar 15, 2023 at 6:53 AM Jonas Ådahl  wrote:
> > > >
> > > > On Fri, Mar 10, 2023 at 09:38:18AM -0800, Rob Clark wrote:
> > > > > On Fri, Mar 10, 2023 at 7:45 AM Jonas Ådahl  wrote:
> > > > > >
> > > > > > On Wed, Mar 08, 2023 at 07:52:52AM -0800, Rob Clark wrote:
> > > > > > > From: Rob Clark 
> > > > > > >
> > > > > > > Add a way to hint to the fence signaler of an upcoming deadline, 
> > > > > > > such as
> > > > > > > vblank, which the fence waiter would prefer not to miss.  This is 
> > > > > > > to aid
> > > > > > > the fence signaler in making power management decisions, like 
> > > > > > > boosting
> > > > > > > frequency as the deadline approaches and awareness of missing 
> > > > > > > deadlines
> > > > > > > so that can be factored in to the frequency scaling.
> > > > > > >
> > > > > > > v2: Drop dma_fence::deadline and related logic to filter duplicate
> > > > > > > deadlines, to avoid increasing dma_fence size.  The 
> > > > > > > fence-context
> > > > > > > implementation will need similar logic to track deadlines of 
> > > > > > > all
> > > > > > > the fences on the same timeline.  [ckoenig]
> > > > > > > v3: Clarify locking wrt. set_deadline callback
> > > > > > > v4: Clarify in docs comment that this is a hint
> > > > > > > v5: Drop DMA_FENCE_FLAG_HAS_DEADLINE_BIT.
> > > > > > > v6: More docs
> > > > > > > v7: Fix typo, clarify past deadlines
> > > > > > >
> > > > > > > Signed-off-by: Rob Clark 
> > > > > > > Reviewed-by: Christian König 
> > > > > > > Acked-by: Pekka Paalanen 
> > > > > > > Reviewed-by: Bagas Sanjaya 
> > > > > > > ---
> > > > > >
> > > > > > Hi Rob!
> > > > > >
> > > > > > >  Documentation/driver-api/dma-buf.rst |  6 +++
> > > > > > >  drivers/dma-buf/dma-fence.c  | 59 
> > > > > > > 
> > > > > > >  include/linux/dma-fence.h| 22 +++
> > > > > > >  3 files changed, 87 insertions(+)
> > > > > > >
> > > > > > > diff --git a/Documentation/driver-api/dma-buf.rst 
> > > > > > > b/Documentation/driver-api/dma-buf.rst
> > > > > > > index 622b8156d212..183e480d8cea 100644
> > > > > > > --- a/Documentation/driver-api/dma-buf.rst
> > > > > > > +++ b/Documentation/driver-api/dma-buf.rst
> > > > > > > @@ -164,6 +164,12 @@ DMA Fence Signalling Annotations
> > > > > > >  .. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > > :doc: fence signalling annotation
> > > > > > >
> > > > > > > +DMA Fence Deadline Hints
> > > > > > > +
> > > > > > > +
> > > > > > > +.. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > > +   :doc: deadline hints
> > > > > > > +
> > > > > > >  DMA Fences Functions Reference
> > > > > > >  ~~
> > > > > > >
> > > > > > > diff --git a/drivers/dma-buf/dma-fence.c 
> > > > > > > b/drivers/dma-buf/dma-fence.c
> > > > > > > index 0de0482cd36e..f177c56269bb 100644
> > > > > > > --- a/drivers/dma-buf/dma-fence.c
> > > > > > > +++ b/drivers/dma-buf/dma-fence.c
> > > > > > > @@ -912,6 +912,65 @@ dma_fence_wait_any_timeout(struct dma_fence 
> > > > > > > **fences, uint32_t count,
> > > > > > >  }
> > > > > > >  EXPORT_SYMBOL(dma_fence_wait_any_timeout);
> > > > > > >
> > > > > > > +/**
> > > > > > > + * DOC: deadline hints
> > > > > > > + *
> > > > > > > + * In an ideal world, it would be possible to pipeline a 
> > > > > > > workload sufficiently
> > > > > > > + * that a utilization based device frequency governor could 
> > > > > > > arrive at a minimum
> > > > > > > + * frequency that meets the requirements of the use-case, in 
> > > > > > > order to minimize
> > > > > > > + * power consumption.  But in the real world there are many 
> > > > > > > workloads which
> > > > > > > + * defy this ideal.  For example, but not limited to:
> > > > > > > + *
> > > > > > > + * * Workloads that ping-pong between device and CPU, with 
> > > > > > > alternating periods
> > > > > > > + *   of CPU waiting for device, and device waiting on CPU.  This 
> > > > > > > can result in
> > > > > > > + *   devfreq and cpufreq seeing idle time in their respective 
> > > > > > > domains and in
> > > > > > > + *   result reduce frequency.
> > > > > > > + *
> > > > > > > + * * Workloads that interact with a periodic time based 
> > > > > > > deadline, such as double
> > > > > > > + *   buffered GPU rendering vs vblank sync'd page flipping.  In 
> > > > > > > this scenario,
> > > > > > > + *   missing a vblank deadline results in an *increase* in idle 
> > > > > > > time on the GPU
> > > > > > > + *   (since it has to wait an additional vblank period), sending 
> > > > > > > a signal to
> > > > > > > + *   the GPU's devfreq to reduce frequency, when in fact the 
> > > > > > > opposite is what is
> > > > > > > + *   needed.
> > > > > >
> > > > > > This is the use case I'd like to get some bet

Re: [Freedreno] [PATCH v10 00/15] dma-fence: Deadline awareness

2023-03-16 Thread Rob Clark
On Wed, Mar 8, 2023 at 7:53 AM Rob Clark  wrote:
>
> From: Rob Clark 
>
> This series adds a deadline hint to fences, so realtime deadlines
> such as vblank can be communicated to the fence signaller for power/
> frequency management decisions.
>
> This is partially inspired by a trick i915 does, but implemented
> via dma-fence for a couple of reasons:
>
> 1) To continue to be able to use the atomic helpers
> 2) To support cases where display and gpu are different drivers
>
> This iteration adds a dma-fence ioctl to set a deadline (both to
> support igt-tests, and compositors which delay decisions about which
> client buffer to display), and a sw_sync ioctl to read back the
> deadline.  IGT tests utilizing these can be found at:
>
>   
> https://gitlab.freedesktop.org/robclark/igt-gpu-tools/-/commits/fence-deadline
>

jfwiw, mesa side of this:

https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21973

BR,
-R

>
> v1: https://patchwork.freedesktop.org/series/93035/
> v2: Move filtering out of later deadlines to fence implementation
> to avoid increasing the size of dma_fence
> v3: Add support in fence-array and fence-chain; Add some uabi to
> support igt tests and userspace compositors.
> v4: Rebase, address various comments, and add syncobj deadline
> support, and sync_file EPOLLPRI based on experience with perf/
> freq issues with clvk compute workloads on i915 (anv)
> v5: Clarify that this is a hint as opposed to a more hard deadline
> guarantee, switch to using u64 ns values in UABI (still absolute
> CLOCK_MONOTONIC values), drop syncobj related cap and driver
> feature flag in favor of allowing count_handles==0 for probing
> kernel support.
> v6: Re-work vblank helper to calculate time of _start_ of vblank,
> and work correctly if the last vblank event was more than a
> frame ago.  Add (mostly unrelated) drm/msm patch which also
> uses the vblank helper.  Use dma_fence_chain_contained().  More
> verbose syncobj UABI comments.  Drop DMA_FENCE_FLAG_HAS_DEADLINE_BIT.
> v7: Fix kbuild complaints about vblank helper.  Add more docs.
> v8: Add patch to surface sync_file UAPI, and more docs updates.
> v9: Drop (E)POLLPRI support.. I still like it, but not essential and
> it can always be revived later.  Fix doc build warning.
> v10: Update 11/15 to handle multiple CRTCs
>
> Rob Clark (15):
>   dma-buf/dma-fence: Add deadline awareness
>   dma-buf/fence-array: Add fence deadline support
>   dma-buf/fence-chain: Add fence deadline support
>   dma-buf/dma-resv: Add a way to set fence deadline
>   dma-buf/sync_file: Surface sync-file uABI
>   dma-buf/sync_file: Add SET_DEADLINE ioctl
>   dma-buf/sw_sync: Add fence deadline support
>   drm/scheduler: Add fence deadline support
>   drm/syncobj: Add deadline support for syncobj waits
>   drm/vblank: Add helper to get next vblank time
>   drm/atomic-helper: Set fence deadline for vblank
>   drm/msm: Add deadline based boost support
>   drm/msm: Add wait-boost support
>   drm/msm/atomic: Switch to vblank_start helper
>   drm/i915: Add deadline based boost support
>
> Rob Clark (15):
>   dma-buf/dma-fence: Add deadline awareness
>   dma-buf/fence-array: Add fence deadline support
>   dma-buf/fence-chain: Add fence deadline support
>   dma-buf/dma-resv: Add a way to set fence deadline
>   dma-buf/sync_file: Surface sync-file uABI
>   dma-buf/sync_file: Add SET_DEADLINE ioctl
>   dma-buf/sw_sync: Add fence deadline support
>   drm/scheduler: Add fence deadline support
>   drm/syncobj: Add deadline support for syncobj waits
>   drm/vblank: Add helper to get next vblank time
>   drm/atomic-helper: Set fence deadline for vblank
>   drm/msm: Add deadline based boost support
>   drm/msm: Add wait-boost support
>   drm/msm/atomic: Switch to vblank_start helper
>   drm/i915: Add deadline based boost support
>
>  Documentation/driver-api/dma-buf.rst| 16 -
>  drivers/dma-buf/dma-fence-array.c   | 11 
>  drivers/dma-buf/dma-fence-chain.c   | 12 
>  drivers/dma-buf/dma-fence.c | 60 ++
>  drivers/dma-buf/dma-resv.c  | 22 +++
>  drivers/dma-buf/sw_sync.c   | 81 +
>  drivers/dma-buf/sync_debug.h|  2 +
>  drivers/dma-buf/sync_file.c | 19 ++
>  drivers/gpu/drm/drm_atomic_helper.c | 37 +++
>  drivers/gpu/drm/drm_syncobj.c   | 64 +++
>  drivers/gpu/drm/drm_vblank.c| 53 +---
>  drivers/gpu/drm/i915/i915_request.c | 20 ++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 15 -
>  drivers/gpu/drm/msm/msm_atomic.c|  8 ++-
>  drivers/gpu/drm/msm/msm_drv.c   | 12 ++--
>  drivers/gpu/drm/msm/msm_fence.c | 74 ++
>  drivers/gpu/drm/msm/msm_fence.h | 20 ++
>  drivers/gpu/drm/msm/msm_gem.c   |  5 ++
>  drivers/gpu/drm/msm/msm_kms.h   |  8 ---
>  drivers/gpu/drm/scheduler/sched

[Freedreno] [RFC PATCH v1 11/12] drm/msm/dpu: add support for virtual planes

2023-03-16 Thread Dmitry Baryshkov
Only several SSPP blocks support such features as YUV output or scaling,
thus different DRM planes have different features.  Properly utilizing
all planes requires the attention of the compositor, who should
prefer simpler planes to YUV-supporting ones. Otherwise it is very easy
to end up in a situation when all featureful planes are already
allocated for simple windows, leaving no spare plane for YUV playback.

To solve this problem make all planes virtual. Each plane is registered
as if it supports all possible features, but then at the runtime during
the atomic_check phase the driver selects backing SSPP block for each
plane.

Note, this does not provide support for using two different SSPP blocks
for a single plane or using two rectangles of an SSPP to drive two
planes. Each plane still gets its own SSPP and can utilize either a solo
rectangle or both multirect rectangles depending on the resolution.

Note #2: By default support for virtual planes is turned off and the
driver still uses old code path with preallocated SSPP block for each
plane. To enable virtual planes, pass 'msm.dpu_use_virtual_planes=1'
kernel parameter.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  59 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 120 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |   4 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 185 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  24 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c|  62 
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|  23 +++
 7 files changed, 407 insertions(+), 70 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 8ef191fd002d..cdece21b81c9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1273,6 +1273,29 @@ static int dpu_crtc_assign_resources(struct drm_crtc 
*crtc, struct drm_crtc_stat
return 0;
 }
 
+static int dpu_crtc_assign_plane_resources(struct drm_crtc *crtc, struct 
drm_crtc_state *crtc_state)
+{
+   struct dpu_global_state *global_state;
+   struct drm_plane *plane;
+   int rc;
+
+   global_state = dpu_kms_get_global_state(crtc_state->state);
+   if (IS_ERR(global_state))
+   return PTR_ERR(global_state);
+
+   dpu_rm_release_all_sspp(global_state, crtc);
+
+   drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+   rc = dpu_plane_virtual_assign_resources(plane, crtc,
+   global_state,
+   crtc_state->state);
+   if (rc)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_atomic_state *state)
 {
@@ -1281,7 +1304,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
 
-   const struct drm_plane_state *pstate;
struct drm_plane *plane;
 
int rc = 0;
@@ -1294,6 +1316,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return rc;
}
 
+   if (dpu_use_virtual_planes &&
+   crtc_state->planes_changed) {
+   rc = dpu_crtc_assign_plane_resources(crtc, crtc_state);
+   if (rc < 0)
+   return rc;
+   }
+
if (!crtc_state->enable || !crtc_state->active) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip 
atomic_check\n",
crtc->base.id, crtc_state->enable,
@@ -1311,20 +1340,30 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
 
-   /* FIXME: move this to dpu_plane_atomic_check? */
-   drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
-   struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-
-   if (IS_ERR_OR_NULL(pstate)) {
-   rc = PTR_ERR(pstate);
-   DPU_ERROR("%s: failed to get plane%d state, %d\n",
-   dpu_crtc->name, plane->base.id, rc);
-   return rc;
+   drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+   const struct drm_plane_state *pstate;
+   struct dpu_plane_state *dpu_pstate;
+
+   pstate = drm_atomic_get_plane_state(crtc_state->state, plane);
+   if (IS_ERR(pstate))
+   return PTR_ERR(pstate);
+
+   if (dpu_use_virtual_planes) {
+   /*
+* In case of virtual planes, the plane's atomic_check
+* is a shortcut. Perform actual check

[Freedreno] [RFC PATCH v1 12/12] drm/msm/dpu: allow using two SSPP blocks for a single plane

2023-03-16 Thread Dmitry Baryshkov
Virtual wide planes give high amount of flexibility, but it is not
always enough:

In parallel multirect case only the half of the usual width is supported
for tiled formats. Thus the whole width of two tiled multirect
rectangles can not be greater than max_linewidth, which is not enough
for some platforms/compositors.

Another example is as simple as wide YUV plane. YUV planes can not use
multirect, so currently they are limited to max_linewidth too.

Now that the planes are fully virtualized, add support for allocating
two SSPP blocks to drive a single DRM plane. This fixes both mentioned
cases and allows all planes to go up to 2*max_linewidth (at the cost of
making some of the planes unavailable to the user).

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 236 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  13 +-
 3 files changed, 227 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index cdece21b81c9..7422bee8d21f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1354,7 +1354,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 * is a shortcut. Perform actual check here, after
 * allocating SSPPs.
 */
-   rc = dpu_plane_atomic_check(plane, crtc_state->state);
+   rc = dpu_plane_virtual_atomic_check_late(plane, 
crtc_state->state);
if (rc)
return rc;
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 787e81740eb9..3bd3951d9ffa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -844,16 +844,27 @@ static int dpu_plane_virtual_atomic_check(struct 
drm_plane *plane,
drm_atomic_get_plane_state(state, plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane_state);
const struct dpu_format *format;
-   struct drm_crtc_state *crtc_state;
+   struct drm_crtc_state *crtc_state = NULL;
+   int ret;
+
+   if (plane_state->crtc)
+   crtc_state = drm_atomic_get_new_crtc_state(state, 
plane_state->crtc);
 
/*
-* Main part of checks, including drm_atomic_helper_check_plane_state()
-* is called from dpu_crtc_atomic_check(). Do minimal processing here.
+* Main part of checks is performed in
+* dpu_plane_virtual_atomic_check_late(), called from
+* dpu_crtc_atomic_check(). Do minimal processing here.
 */
+   ret = drm_atomic_helper_check_plane_noscale(plane_state, crtc_state,
+   true, true);
+   if (ret) {
+   DPU_DEBUG_PLANE(to_dpu_plane(plane),
+   "Check plane state failed (%d)\n", ret);
+   return ret;
+   }
 
-   if (!plane_state->fb) {
-   plane_state->visible = false;
 
+   if (!plane_state->visible) {
/* resources are freed by dpu_crtc_atomic_check(), but clean 
them here */
pstate->pipe.sspp = NULL;
pstate->r_pipe.sspp = NULL;
@@ -861,18 +872,46 @@ static int dpu_plane_virtual_atomic_check(struct 
drm_plane *plane,
return 0;
}
 
+   pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+   if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
+   DPU_ERROR("> %d plane stages assigned\n",
+ pdpu->catalog->caps->max_mixer_blendstages - 
DPU_STAGE_0);
+   return -EINVAL;
+   }
+
+   /* Ensure fb size is supported */
+   if (plane_state->fb->width > MAX_IMG_WIDTH ||
+   plane_state->fb->height > MAX_IMG_HEIGHT) {
+   DPU_DEBUG_PLANE(pdpu, "invalid framebuffer %dx%d\n",
+   plane_state->fb->width,
+   plane_state->fb->height);
+   return -E2BIG;
+   }
+
format = to_dpu_format(msm_framebuffer_format(plane_state->fb));
-   crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
 
-   /* force resource reallocation if the format of FB has changed */
-   if (pstate->saved_fmt ! = format) {
+   /* force resource reallocation if the format of FB or src/dst have 
changed */
+   if (pstate->saved_fmt != format ||
+   pstate->saved_src_w != plane_state->src_w ||
+   pstate->saved_src_h != plane_state->src_h ||
+   pstate->saved_src_w != plane_state->src_w ||
+   pstate->saved_crtc_h != plane_state->crtc_h) {
crtc_state->planes_changed = true;
pstate->saved_fmt = format;
+   

[Freedreno] [RFC PATCH v1 10/12] drm/msm/dpu: add a field describing inline rotation to dpu_caps

2023-03-16 Thread Dmitry Baryshkov
We need to know if the platform supports inline rotation on any of the
SSPP blocks or not. Add this information to struct dpu_caps in a form of
the boolean field has_inline_rot.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 2d6944a9679a..33527ec7c938 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -489,6 +489,7 @@ static const struct dpu_caps sc7280_dpu_caps = {
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_dim_layer = true,
.has_idle_pc = true,
+   .has_inline_rot = true,
.max_linewidth = 2400,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.format_list = plane_formats_yuv,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index 4847aae78db2..cc64fb2e815f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -400,6 +400,7 @@ struct dpu_rotation_cfg {
  * @has_dim_layer  dim layer feature status
  * @has_idle_pcindicate if idle power collapse feature is supported
  * @has_3d_merge   indicate if 3D merge is supported
+ * @has_inline_rot indicate if inline rotation is supported
  * @max_linewidth  max linewidth for sspp
  * @pixel_ram_size size of latency hiding and de-tiling buffer in bytes
  * @max_hdeci_exp  max horizontal decimation supported (max is 2^value)
@@ -416,6 +417,7 @@ struct dpu_caps {
bool has_dim_layer;
bool has_idle_pc;
bool has_3d_merge;
+   bool has_inline_rot;
/* SSPP limits */
u32 max_linewidth;
u32 pixel_ram_size;
-- 
2.30.2



[Freedreno] [RFC PATCH v1 07/12] drm/msm/dpu: fill CRTC resources in dpu_crtc.c

2023-03-16 Thread Dmitry Baryshkov
Stop poking into CRTC state from dpu_encoder.c, fill CRTC HW resources
from dpu_crtc_assign_resources().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 27 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 ++
 2 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 77226de54363..8ef191fd002d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1177,6 +1177,7 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state 
*cstate)
 }
 
 #define MAX_HDISPLAY_SPLIT 1080
+#define MAX_CHANNELS_PER_CRTC 2
 
 static struct msm_display_topology dpu_crtc_get_topology(
struct drm_crtc *crtc,
@@ -1219,9 +1220,14 @@ static struct msm_display_topology dpu_crtc_get_topology(
 
 static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct 
drm_crtc_state *crtc_state)
 {
+   struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_CRTC];
+   struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_CRTC];
+   struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_CRTC];
+   int i, num_lm, num_ctl, num_dspp;
struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
struct dpu_global_state *global_state;
struct msm_display_topology topology;
+   struct dpu_crtc_state *cstate;
int ret;
 
/*
@@ -1243,6 +1249,27 @@ static int dpu_crtc_assign_resources(struct drm_crtc 
*crtc, struct drm_crtc_stat
if (ret)
return ret;
 
+   cstate = to_dpu_crtc_state(crtc_state);
+
+   num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+   crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+   num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+   crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+   num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
+   crtc, DPU_HW_BLK_DSPP, hw_dspp,
+   ARRAY_SIZE(hw_dspp));
+
+   for (i = 0; i < num_lm; i++) {
+   int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
+
+   cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
+   cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
+   if (i < num_dspp)
+   cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
+   }
+
+   cstate->num_mixers = num_lm;
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 204360485b81..068d4e47eaa9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -934,14 +934,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
struct dpu_encoder_virt *dpu_enc;
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms;
-   struct dpu_crtc_state *cstate;
struct dpu_global_state *global_state;
struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
-   struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
-   struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
-   int num_lm, num_ctl, num_pp, num_dsc;
+   int num_pp, num_dsc;
unsigned int dsc_mask = 0;
int i;
 
@@ -968,13 +965,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
ARRAY_SIZE(hw_pp));
-   num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
-   num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
-   ARRAY_SIZE(hw_dspp));
+   drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
 
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
@@ -992,18 +984,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
 
dpu_enc->dsc_mask = dsc_mask;
 
-   cstate = to_dpu_crtc_state(crtc_state);
-
-   for (i = 0; i < num_lm; i++) {
-   int ctl_idx = (i < num_ctl) ? i : (num_ctl-1);
-
-   cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]);
-   cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]);
-   cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]);
-   }
-
-   cstate->num_mixers = num_lm;
-
  

[Freedreno] [RFC PATCH v1 09/12] drm/msm/dpu: add list of supported formats to the DPU caps

2023-03-16 Thread Dmitry Baryshkov
As we are going to add virtual planes, add the list of supported formats
to the hw catalog entry. It will be used to setup universal planes, with
later selecting a pipe depending on whether the YUV format is used for
the framebuffer.

Signed-off-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 26 +++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|  4 +++
 2 files changed, 30 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 212d546b6c5d..2d6944a9679a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -315,6 +315,8 @@ static const struct dpu_caps msm8998_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps qcm2290_dpu_caps = {
@@ -324,6 +326,8 @@ static const struct dpu_caps qcm2290_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = 2160,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sdm845_dpu_caps = {
@@ -339,6 +343,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7180_dpu_caps = {
@@ -350,6 +356,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm6115_dpu_caps = {
@@ -361,6 +369,8 @@ static const struct dpu_caps sm6115_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = 2160,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8150_dpu_caps = {
@@ -376,6 +386,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc8180x_dpu_caps = {
@@ -391,6 +403,8 @@ static const struct dpu_caps sc8180x_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc8280xp_dpu_caps = {
@@ -404,6 +418,8 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 5120,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8250_dpu_caps = {
@@ -417,6 +433,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 900,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8350_dpu_caps = {
@@ -430,6 +448,8 @@ static const struct dpu_caps sm8350_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 4096,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8450_dpu_caps = {
@@ -443,6 +463,8 @@ static const struct dpu_caps sm8450_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 5120,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8550_dpu_caps = {
@@ -456,6 +478,8 @@ static const struct dpu_caps sm8550_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 5120,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7280_dpu_caps = {
@@ -467,6 +491,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = 2400,
.pixel_ram_size = DEFAULT_PIXEL_

[Freedreno] [RFC PATCH v1 08/12] drm/msm/dpu: move pstate->pipe initialization to dpu_plane_atomic_check

2023-03-16 Thread Dmitry Baryshkov
In preparation to virtualized planes support, move pstate->pipe
initialization from dpu_plane_reset() to dpu_plane_atomic_check(). In
case of virtual planes the plane's pipe will not be known up to the
point of atomic_check() callback.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 2e63eb0a2f3f..1b11c9476fb3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -845,6 +845,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+   struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
struct dpu_sw_pipe *pipe = &pstate->pipe;
struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
const struct drm_crtc_state *crtc_state = NULL;
@@ -855,13 +856,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
uint32_t max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
-   const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
-   const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk;
+   const struct dpu_sspp_cfg *pipe_hw_caps;
+   const struct dpu_sspp_sub_blks *sblk;
 
if (new_plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
   
new_plane_state->crtc);
 
+   pipe->sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+   r_pipe->sspp = NULL;
+
+   pipe_hw_caps = pstate->pipe.sspp->cap;
+   sblk = pstate->pipe.sspp->cap->sblk;
+
min_scale = FRAC_16_16(1, sblk->maxupscale);
ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
  min_scale,
@@ -878,7 +885,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-   r_pipe->sspp = NULL;
 
pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -1367,7 +1373,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
struct dpu_plane *pdpu;
struct dpu_plane_state *pstate;
-   struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
if (!plane) {
DPU_ERROR("invalid plane\n");
@@ -1389,16 +1394,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
return;
}
 
-   /*
-* Set the SSPP here until we have proper virtualized DPU planes.
-* This is the place where the state is allocated, so fill it fully.
-*/
-   pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-
-   pstate->r_pipe.sspp = NULL;
-
__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
 
-- 
2.30.2



[Freedreno] [RFC PATCH v1 05/12] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation

2023-03-16 Thread Dmitry Baryshkov
Up to now the driver has been using encoder to allocate hardware
resources. Switch it to use CRTC id in preparation for the next step.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  16 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 119 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  15 ++-
 4 files changed, 77 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index a2cb23dea0b8..270c85ea898a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -634,11 +634,11 @@ static int dpu_encoder_virt_atomic_check(
 * Dont allocate when active is false.
 */
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
-   dpu_rm_release(global_state, drm_enc);
+   dpu_rm_release(global_state, crtc_state->crtc);
 
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
-   drm_enc, crtc_state, &topology);
+   crtc_state->crtc, &topology);
}
 
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
@@ -1034,14 +1034,14 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
 
/* Query resource that have been reserved in atomic check step. */
num_pp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->base.id, DPU_HW_BLK_PINGPONG, hw_pp,
+   drm_enc->crtc, DPU_HW_BLK_PINGPONG, hw_pp,
ARRAY_SIZE(hw_pp));
num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
+   drm_enc->crtc, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl));
num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
+   drm_enc->crtc, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm));
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
-   drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
+   drm_enc->crtc, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
 
for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
@@ -1050,7 +1050,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
 
if (dpu_enc->dsc) {
num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, 
global_state,
-   drm_enc->base.id, 
DPU_HW_BLK_DSC,
+   drm_enc->crtc, 
DPU_HW_BLK_DSC,
hw_dsc, 
ARRAY_SIZE(hw_dsc));
for (i = 0; i < num_dsc; i++) {
dpu_enc->hw_dsc[i] = to_dpu_hw_dsc(hw_dsc[i]);
@@ -1994,7 +1994,7 @@ static void dpu_encoder_helper_reset_mixers(struct 
dpu_encoder_phys *phys_enc)
global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms);
 
num_lm = dpu_rm_get_assigned_resources(&phys_enc->dpu_kms->rm, 
global_state,
-   phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, 
ARRAY_SIZE(hw_lm));
+   phys_enc->parent->crtc, DPU_HW_BLK_LM, hw_lm, 
ARRAY_SIZE(hw_lm));
 
for (i = 0; i < num_lm; i++) {
hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index ed80ed6784ee..934874eb2248 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -129,11 +129,11 @@ struct vsync_info {
 struct dpu_global_state {
struct drm_private_state base;
 
-   uint32_t pingpong_to_enc_id[PINGPONG_MAX - PINGPONG_0];
-   uint32_t mixer_to_enc_id[LM_MAX - LM_0];
-   uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
-   uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
-   uint32_t dsc_to_enc_id[DSC_MAX - DSC_0];
+   uint32_t pingpong_to_crtc_id[PINGPONG_MAX - PINGPONG_0];
+   uint32_t mixer_to_crtc_id[LM_MAX - LM_0];
+   uint32_t ctl_to_crtc_id[CTL_MAX - CTL_0];
+   uint32_t dspp_to_crtc_id[DSPP_MAX - DSPP_0];
+   uint32_t dsc_to_crtc_id[DSC_MAX - DSC_0];
 };
 
 struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 952e139c0234..f0a94008d17a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -19,9 +19,9 @@
 
 
 static inline bool reserved_by_other(uint32_t *res_map, int idx,
-uint32_t enc_id)
+uint32_t crtc_id)
 {
-   return res_map[idx]

[Freedreno] [RFC PATCH v1 04/12] drm/msm/dpu: get rid of struct dpu_rm_requirements

2023-03-16 Thread Dmitry Baryshkov
The struct dpu_rm_requirements was used to wrap display topology and
hw resources, which meant INTF indices. As of commit ef58e0ad3436
("drm/msm/dpu: get INTF blocks directly rather than through RM") the hw
resources struct was removed, leaving struct dpu_rm_requirements
containing a single field (topology). Remove the useless wrapper.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 69 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  2 +-
 3 files changed, 23 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 4ee708264f3b..a2cb23dea0b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -638,7 +638,7 @@ static int dpu_encoder_virt_atomic_check(
 
if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
-   drm_enc, crtc_state, topology);
+   drm_enc, crtc_state, &topology);
}
 
trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f4dda88a73f7..952e139c0234 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -24,15 +24,6 @@ static inline bool reserved_by_other(uint32_t *res_map, int 
idx,
return res_map[idx] && res_map[idx] != enc_id;
 }
 
-/**
- * struct dpu_rm_requirements - Reservation requirements parameter bundle
- * @topology:  selected topology for the display
- * @hw_res:   Hardware resources required as reported by the encoders
- */
-struct dpu_rm_requirements {
-   struct msm_display_topology topology;
-};
-
 int dpu_rm_destroy(struct dpu_rm *rm)
 {
int i;
@@ -329,14 +320,13 @@ static bool _dpu_rm_check_lm_peer(struct dpu_rm *rm, int 
primary_idx,
  *  mixer in rm->pingpong_blks[].
  * @dspp_idx: output parameter, index of dspp block attached to the layer
  *  mixer in rm->dspp_blks[].
- * @reqs: input parameter, rm requirements for HW blocks needed in the
- *  datapath.
+ * @topology:  selected topology for the display
  * Return: true if lm matches all requirements, false otherwise
  */
 static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm,
struct dpu_global_state *global_state,
uint32_t enc_id, int lm_idx, int *pp_idx, int *dspp_idx,
-   struct dpu_rm_requirements *reqs)
+   struct msm_display_topology *topology)
 {
const struct dpu_lm_cfg *lm_cfg;
int idx;
@@ -361,7 +351,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct 
dpu_rm *rm,
}
*pp_idx = idx;
 
-   if (!reqs->topology.num_dspp)
+   if (!topology->num_dspp)
return true;
 
idx = lm_cfg->dspp - DSPP_0;
@@ -383,7 +373,7 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct 
dpu_rm *rm,
 static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
   struct dpu_global_state *global_state,
   uint32_t enc_id,
-  struct dpu_rm_requirements *reqs)
+  struct msm_display_topology *topology)
 
 {
int lm_idx[MAX_BLOCKS];
@@ -391,14 +381,14 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
int dspp_idx[MAX_BLOCKS] = {0};
int i, j, lm_count = 0;
 
-   if (!reqs->topology.num_lm) {
-   DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm);
+   if (!topology->num_lm) {
+   DPU_ERROR("invalid number of lm: %d\n", topology->num_lm);
return -EINVAL;
}
 
/* Find a primary mixer */
for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) &&
-   lm_count < reqs->topology.num_lm; i++) {
+   lm_count < topology->num_lm; i++) {
if (!rm->mixer_blks[i])
continue;
 
@@ -407,7 +397,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
 
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
enc_id, i, &pp_idx[lm_count],
-   &dspp_idx[lm_count], reqs)) {
+   &dspp_idx[lm_count], topology)) {
continue;
}
 
@@ -415,7 +405,7 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
 
/* Valid primary mixer found, find matching peers */
for (j = i + 1; j < ARRAY_SIZE(rm->mixer_blks) &&
-   lm_count < reqs->topology.num_lm; j++) {
+   lm_count < topology->num_lm; j++) {
   

[Freedreno] [RFC PATCH v1 06/12] drm/msm/dpu: move resource allocation to CRTC

2023-03-16 Thread Dmitry Baryshkov
All resource allocation is centered around the LMs. Then other blocks
(except DSCs) are allocated basing on the LMs that was selected, and LM
powers up the CRTC rather than the encoder.

Moreover if at some point the driver supports encoder cloning,
allocating resources from the encoder will be incorrect, as all clones
will have different encoder IDs, while LMs are to be shared by these
encoders.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 76 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 88 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h |  8 ++
 3 files changed, 94 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 508e5b950e52..77226de54363 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1176,6 +1176,76 @@ static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state 
*cstate)
return false;
 }
 
+#define MAX_HDISPLAY_SPLIT 1080
+
+static struct msm_display_topology dpu_crtc_get_topology(
+   struct drm_crtc *crtc,
+   struct dpu_kms *dpu_kms,
+   struct drm_crtc_state *crtc_state)
+{
+   struct drm_display_mode *mode = &crtc_state->adjusted_mode;
+   struct msm_display_topology topology = {0};
+   struct drm_encoder *drm_enc;
+
+   drm_for_each_encoder_mask(drm_enc, crtc->dev, crtc_state->encoder_mask)
+   dpu_encoder_update_topology(drm_enc, &topology);
+
+   /*
+* Datapath topology selection
+*
+* Dual display
+* 2 LM, 2 INTF ( Split display using 2 interfaces)
+*
+* Single display
+* 1 LM, 1 INTF
+* 2 LM, 1 INTF (stream merge to support high resolution interfaces)
+*
+* Add dspps to the reservation requirements if ctm is requested
+*/
+   if (topology.num_intf == 2)
+   topology.num_lm = 2;
+   else if (topology.num_dsc == 2)
+   topology.num_lm = 2;
+   else if (dpu_kms->catalog->caps->has_3d_merge)
+   topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
+   else
+   topology.num_lm = 1;
+
+   if (crtc_state->ctm)
+   topology.num_dspp = topology.num_lm;
+
+   return topology;
+}
+
+static int dpu_crtc_assign_resources(struct drm_crtc *crtc, struct 
drm_crtc_state *crtc_state)
+{
+   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+   struct dpu_global_state *global_state;
+   struct msm_display_topology topology;
+   int ret;
+
+   /*
+* Release and Allocate resources on every modeset
+* Dont allocate when enable is false.
+*/
+   global_state = dpu_kms_get_global_state(crtc_state->state);
+   if (IS_ERR(global_state))
+   return PTR_ERR(global_state);
+
+   dpu_rm_release(global_state, crtc);
+
+   if (!crtc_state->enable)
+   return 0;
+
+   topology = dpu_crtc_get_topology(crtc, dpu_kms, crtc_state);
+   ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+crtc, &topology);
+   if (ret)
+   return ret;
+
+   return 0;
+}
+
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
struct drm_atomic_state *state)
 {
@@ -1191,6 +1261,12 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
+   if (drm_atomic_crtc_needs_modeset(crtc_state)) {
+   rc = dpu_crtc_assign_resources(crtc, crtc_state);
+   if (rc < 0)
+   return rc;
+   }
+
if (!crtc_state->enable || !crtc_state->active) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip 
atomic_check\n",
crtc->base.id, crtc_state->enable,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 270c85ea898a..204360485b81 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -53,8 +53,6 @@
 
 #define IDLE_SHORT_TIMEOUT 1
 
-#define MAX_HDISPLAY_SPLIT 1080
-
 /* timeout in frames waiting for frame done */
 #define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
 
@@ -514,71 +512,28 @@ void dpu_encoder_helper_split_config(
}
 }
 
-bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
+void dpu_encoder_update_topology(struct drm_encoder *drm_enc,
+struct msm_display_topology *topology)
 {
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
-   int i, intf_count = 0, num_dsc = 0;
+   int i;
 
for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
if (dpu_enc->phys_encs[i])
-   intf_count++;
+   t

[Freedreno] [RFC PATCH v1 03/12] drm/msm/dpu: remove unused fields from dpu_encoder_virt

2023-03-16 Thread Dmitry Baryshkov
Remove historical fields intfs_swapped and topology fields from struct
dpu_encoder_virt and also remove even more historical docs.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 --
 1 file changed, 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 28729c77364f..4ee708264f3b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -130,18 +130,12 @@ enum dpu_enc_rc_states {
  * pingpong blocks can be different than num_phys_encs.
  * @hw_dsc:Handle to the DSC blocks used for the display.
  * @dsc_mask:  Bitmask of used DSC blocks.
- * @intfs_swapped: Whether or not the phys_enc interfaces have been swapped
- * for partial update right-only cases, such as pingpong
- * split where virtual pingpong does not generate IRQs
  * @crtc:  Pointer to the currently assigned crtc. Normally you
  * would use crtc->state->encoder_mask to determine the
  * link between encoder/crtc. However in this case we need
  * to track crtc in the disable() hook which is called
  * _after_ encoder_mask is cleared.
  * @connector: If a mode is set, cached pointer to the active connector
- * @crtc_kickoff_cb:   Callback into CRTC that will flush & start
- * all CTL paths
- * @crtc_kickoff_cb_data:  Opaque user data given to crtc_kickoff_cb
  * @enc_lock:  Lock around physical encoder
  * create/destroy/enable/disable
  * @frame_busy_mask:   Bitmask tracking which phys_enc we are still
@@ -160,7 +154,6 @@ enum dpu_enc_rc_states {
  * @delayed_off_work:  delayed worker to schedule disabling of
  * clks and resources after IDLE_TIMEOUT time.
  * @vsync_event_work:  worker to handle vsync event for autorefresh
- * @topology:   topology of the display
  * @idle_timeout:  idle timeout duration in milliseconds
  * @wide_bus_en:   wide bus is enabled on this interface
  * @dsc:   drm_dsc_config pointer, for DSC-enabled encoders
@@ -180,8 +173,6 @@ struct dpu_encoder_virt {
 
unsigned int dsc_mask;
 
-   bool intfs_swapped;
-
struct drm_crtc *crtc;
struct drm_connector *connector;
 
@@ -201,7 +192,6 @@ struct dpu_encoder_virt {
enum dpu_enc_rc_states rc_state;
struct delayed_work delayed_off_work;
struct kthread_work vsync_event_work;
-   struct msm_display_topology topology;
 
u32 idle_timeout;
 
-- 
2.30.2



[Freedreno] [RFC PATCH v1 02/12] drm/msm/dpu: encoder: simplify debugfs handling

2023-03-16 Thread Dmitry Baryshkov
As the debugfs is fully cleared on drm device removal, drop the
encoder-specific cleanup function, remove debugfs_root from dpu_encoder
struct and also remove phys_encoder late_register() ops which has been
unused since the driver being added.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   | 22 +++
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  3 ---
 2 files changed, 3 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 97d8d777f178..28729c77364f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -142,7 +142,6 @@ enum dpu_enc_rc_states {
  * @crtc_kickoff_cb:   Callback into CRTC that will flush & start
  * all CTL paths
  * @crtc_kickoff_cb_data:  Opaque user data given to crtc_kickoff_cb
- * @debugfs_root:  Debug file system root file node
  * @enc_lock:  Lock around physical encoder
  * create/destroy/enable/disable
  * @frame_busy_mask:   Bitmask tracking which phys_enc we are still
@@ -186,7 +185,6 @@ struct dpu_encoder_virt {
struct drm_crtc *crtc;
struct drm_connector *connector;
 
-   struct dentry *debugfs_root;
struct mutex enc_lock;
DECLARE_BITMAP(frame_busy_mask, MAX_PHYS_ENCODERS_PER_VIRTUAL);
void (*crtc_frame_event_cb)(void *, u32 event);
@@ -2134,7 +2132,7 @@ DEFINE_SHOW_ATTRIBUTE(_dpu_encoder_status);
 static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
-   int i;
+   struct dentry *debugfs_root;
 
char name[DPU_NAME_SIZE];
 
@@ -2146,18 +2144,12 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder 
*drm_enc)
snprintf(name, DPU_NAME_SIZE, "encoder%u", drm_enc->base.id);
 
/* create overall sub-directory for the encoder */
-   dpu_enc->debugfs_root = debugfs_create_dir(name,
+   debugfs_root = debugfs_create_dir(name,
drm_enc->dev->primary->debugfs_root);
 
/* don't error check these */
debugfs_create_file("status", 0600,
-   dpu_enc->debugfs_root, dpu_enc, &_dpu_encoder_status_fops);
-
-   for (i = 0; i < dpu_enc->num_phys_encs; i++)
-   if (dpu_enc->phys_encs[i]->ops.late_register)
-   dpu_enc->phys_encs[i]->ops.late_register(
-   dpu_enc->phys_encs[i],
-   dpu_enc->debugfs_root);
+   debugfs_root, dpu_enc, &_dpu_encoder_status_fops);
 
return 0;
 }
@@ -2173,13 +2165,6 @@ static int dpu_encoder_late_register(struct drm_encoder 
*encoder)
return _dpu_encoder_init_debugfs(encoder);
 }
 
-static void dpu_encoder_early_unregister(struct drm_encoder *encoder)
-{
-   struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
-
-   debugfs_remove_recursive(dpu_enc->debugfs_root);
-}
-
 static int dpu_encoder_virt_add_phys_encs(
struct msm_display_info *disp_info,
struct dpu_encoder_virt *dpu_enc,
@@ -2406,7 +2391,6 @@ static const struct drm_encoder_helper_funcs 
dpu_encoder_helper_funcs = {
 static const struct drm_encoder_funcs dpu_encoder_funcs = {
.destroy = dpu_encoder_destroy,
.late_register = dpu_encoder_late_register,
-   .early_unregister = dpu_encoder_early_unregister,
 };
 
 int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 1d434b22180d..9e29079a6fc4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -63,7 +63,6 @@ struct dpu_encoder_phys;
 /**
  * struct dpu_encoder_phys_ops - Interface the physical encoders provide to
  * the containing virtual encoder.
- * @late_register: DRM Call. Add Userspace interfaces, debugfs.
  * @prepare_commit:MSM Atomic Call, start of atomic commit sequence
  * @is_master: Whether this phys_enc is the current master
  * encoder. Can be switched at enable time. Based
@@ -93,8 +92,6 @@ struct dpu_encoder_phys;
  */
 
 struct dpu_encoder_phys_ops {
-   int (*late_register)(struct dpu_encoder_phys *encoder,
-   struct dentry *debugfs_root);
void (*prepare_commit)(struct dpu_encoder_phys *encoder);
bool (*is_master)(struct dpu_encoder_phys *encoder);
void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
-- 
2.30.2



[Freedreno] [RFC PATCH v1 01/12] drm/atomic-helper: split not-scaling part of drm_atomic_helper_check_plane_state

2023-03-16 Thread Dmitry Baryshkov
The helper drm_atomic_helper_check_plane_state() runs several checks on
plane src and dst rectangles, including the check whether required
scaling fits into the required margins. The msm driver would benefit
from having a function that does all these checks except the scaling
one. Split them into a new helper called
drm_atomic_helper_check_plane_noscale().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/drm_atomic_helper.c | 85 ++---
 include/drm/drm_atomic_helper.h |  4 ++
 2 files changed, 68 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_helper.c 
b/drivers/gpu/drm/drm_atomic_helper.c
index d579fd8f7cb8..86c5e19c7bdb 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -825,11 +825,9 @@ drm_atomic_helper_check_wb_encoder_state(struct 
drm_encoder *encoder,
 EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state);
 
 /**
- * drm_atomic_helper_check_plane_state() - Check plane state for validity
+ * drm_atomic_helper_check_plane_noscale() - Check plane state for validity
  * @plane_state: plane state to check
  * @crtc_state: CRTC state to check
- * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
- * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
  * @can_position: is it legal to position the plane such that it
  *doesn't cover the entire CRTC?  This will generally
  *only be false for primary planes.
@@ -845,19 +843,16 @@ EXPORT_SYMBOL(drm_atomic_helper_check_wb_encoder_state);
  * RETURNS:
  * Zero if update appears valid, error code on failure
  */
-int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
-   const struct drm_crtc_state *crtc_state,
-   int min_scale,
-   int max_scale,
-   bool can_position,
-   bool can_update_disabled)
+int drm_atomic_helper_check_plane_noscale(struct drm_plane_state *plane_state,
+ const struct drm_crtc_state 
*crtc_state,
+ bool can_position,
+ bool can_update_disabled)
 {
struct drm_framebuffer *fb = plane_state->fb;
struct drm_rect *src = &plane_state->src;
struct drm_rect *dst = &plane_state->dst;
unsigned int rotation = plane_state->rotation;
struct drm_rect clip = {};
-   int hscale, vscale;
 
WARN_ON(plane_state->crtc && plane_state->crtc != crtc_state->crtc);
 
@@ -883,17 +878,6 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
 
drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
 
-   /* Check scaling */
-   hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
-   vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
-   if (hscale < 0 || vscale < 0) {
-   drm_dbg_kms(plane_state->plane->dev,
-   "Invalid scaling of plane\n");
-   drm_rect_debug_print("src: ", &plane_state->src, true);
-   drm_rect_debug_print("dst: ", &plane_state->dst, false);
-   return -ERANGE;
-   }
-
if (crtc_state->enable)
drm_mode_get_hv_timing(&crtc_state->mode, &clip.x2, &clip.y2);
 
@@ -921,6 +905,65 @@ int drm_atomic_helper_check_plane_state(struct 
drm_plane_state *plane_state,
 
return 0;
 }
+EXPORT_SYMBOL(drm_atomic_helper_check_plane_noscale);
+
+/**
+ * drm_atomic_helper_check_plane_state() - Check plane state for validity
+ * @plane_state: plane state to check
+ * @crtc_state: CRTC state to check
+ * @min_scale: minimum @src:@dest scaling factor in 16.16 fixed point
+ * @max_scale: maximum @src:@dest scaling factor in 16.16 fixed point
+ * @can_position: is it legal to position the plane such that it
+ *doesn't cover the entire CRTC?  This will generally
+ *only be false for primary planes.
+ * @can_update_disabled: can the plane be updated while the CRTC
+ *   is disabled?
+ *
+ * Checks that a desired plane update is valid, and updates various
+ * bits of derived state (clipped coordinates etc.). Drivers that provide
+ * their own plane handling rather than helper-provided implementations may
+ * still wish to call this function to avoid duplication of error checking
+ * code.
+ *
+ * RETURNS:
+ * Zero if update appears valid, error code on failure
+ */
+int drm_atomic_helper_check_plane_state(struct drm_plane_state *plane_state,
+   const struct drm_crtc_state *crtc_state,
+   int min_scale,
+   int max_scale,
+   bool can_position,
+   

[Freedreno] [RFC PATCH v1 00/12] drm/msm/dpu: support virtual wide planes

2023-03-16 Thread Dmitry Baryshkov
As promised in the basic wide planes support ([1]) here comes a series
supporting 2*max_linewidth for all the planes.

Note: Proper support for rot90 is pending. Granted that it is only
enabled on sc7280 and it only supports UBWC (tiled) framebuffers, it was
quite low on my priority list. I plan to get it done for v2.

Note#2 to simplify the dpu_plane_virtual_assign_resources(), which
already becomes big enough, I stripped support for sharing the SSPP
across two planes (doubling amount of planes available to some of
compositors/applications). I plan to get back to this topic once this
series lands.

Dependencies: msm-next + msm-fixes, [1], [2]

[1] https://patchwork.freedesktop.org/series/99909/

[2] https://patchwork.freedesktop.org/series/113423/

Dmitry Baryshkov (12):
  drm/atomic-helper: split not-scaling part of
drm_atomic_helper_check_plane_state
  drm/msm/dpu: encoder: simplify debugfs handling
  drm/msm/dpu: remove unused fields from dpu_encoder_virt
  drm/msm/dpu: get rid of struct dpu_rm_requirements
  drm/msm/dpu: switch RM to use crtc_id rather than enc_id for
allocation
  drm/msm/dpu: move resource allocation to CRTC
  drm/msm/dpu: fill CRTC resources in dpu_crtc.c
  drm/msm/dpu: move pstate->pipe initialization to
dpu_plane_atomic_check
  drm/msm/dpu: add list of supported formats to the DPU caps
  drm/msm/dpu: add a field describing inline rotation to dpu_caps
  drm/msm/dpu: add support for virtual planes
  drm/msm/dpu: allow using two SSPP blocks for a single plane

 drivers/gpu/drm/drm_atomic_helper.c   |  85 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 162 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   | 150 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h   |   8 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   3 -
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  27 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   6 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 120 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  14 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 398 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  33 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 240 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|  40 +-
 include/drm/drm_atomic_helper.h   |   4 +
 14 files changed, 933 insertions(+), 357 deletions(-)

-- 
2.30.2



Re: [Freedreno] [RFC PATCH 1/2] drm/msm/dpu: add dsc helper functions

2023-03-16 Thread Abhinav Kumar




On 3/16/2023 9:23 AM, Dmitry Baryshkov wrote:

On 16/03/2023 18:13, Abhinav Kumar wrote:



On 3/16/2023 9:03 AM, Dmitry Baryshkov wrote:

Hi,

[removed previous conversation]



Hi Dmitry and Abhinav,

Just wanted to follow up on this thread. I've gone over the 
MSM-specific

DSC params for DP and DSI and have found a few shared calculations and
variables between both DSI and DP paths:

- (as mentioned earlier in the thread) almost all the calculations in
dpu_dsc_populate_dsc_config() match dsi_populate_dsc_params() [1]. The
only difference in the math I'm seeing is initial_scale_value.


The value in dsi code is valid for initial_offset = 6144. Please use
the formula from the standard (= sde_dsc_populate_dsc_config) and add
it to drm_dsc_helper.c

If I remember correctly the last remaining item in
dsi_populate_dsc_params() (except mentioned initial_offset) was
line_buf_depth, see [3]. I'm not sure about setting it to bpc+1.
According to the standard it should come from a DSC decoder spec,
which means it should be set by the DSI panel driver or via
drm_dp_dsc_sink_line_buf_depth() in the case of DP output.

- dsc_extra_pclk_cycle_cnt and dce_bytes_per_line, which were 
introduced

in Kuogee's v1 DSC series [2], are used for DSI, DP, and the DPU timing
engine. dsc_extra_pclk_cycle_cnt is calculated based on pclk_per_line
(which is calculated differently between DP and DSI), but
dce_bytes_per_line is calculated the same way between DP and DSI.

To avoid having to duplicate math in 2 different places, I think it
would help to have these calculations in some msm_dsc_helper.c file. 
Any

thoughts on this?


dsc_extra_pclk_cycle_cnt and dce_bytes_per_line are used only in DPU
code, so they can stay in DPU driver.



They can stay in the dpu driver is fine but where?

Like Jessica wrote, this is computed and used in 3 places today :

1) DSI video engine computation
2) DP controller computation
3) timing engine programming


Please excuse me if I'm wrong. I checked both vendor techpack and the 
Kuogee's patches. I see them being used only in the SDE / DPU driver 
code. Could you please point me to the code path that we are discussing?




DSI code :

https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/dsi/dsi_host.c#L868

DP code:

Refer to dp_panel_dsc_pclk_param_calc in 
https://patchwork.freedesktop.org/patch/519837/?series=113240&rev=1


Timing engine:

refer to https://patchwork.freedesktop.org/patch/519838/?series=113240&rev=1

Probably confusion is due to the naming. bytes_per_line is nothing but 
bytes_per_pkt * pkt_per_line but the concept is common for DP and DSI.


+   if (phys->comp_type == MSM_DISPLAY_COMPRESSION_DSC) {
+   phys->dsc_extra_pclk_cycle_cnt = 
dsc_info->pclk_per_line;
+   phys->dsc_extra_disp_width = dsc_info->extra_width;
+   phys->dce_bytes_per_line =
+   dsc_info->bytes_per_pkt * 
dsc_info->pkt_per_line;



So either we have a helper in a common location somewhere so that 
these 3 modules can call that helper and use it OR each module 
duplicates the computation code.


What should be the common location is the discussion here.

It cannot be dpu_encoder.c as the DSI/DP dont call into the encoder 
methods.




Thanks,

Jessica Zhang

[1]
https://elixir.bootlin.com/linux/v6.3-rc2/source/drivers/gpu/drm/msm/dsi/dsi_host.c#L1756 



[2] https://patchwork.freedesktop.org/patch/519845/?series=113240&rev=1


[3] https://patchwork.freedesktop.org/patch/525441/?series=114472&rev=2







Re: [Freedreno] [PATCH v10 01/15] dma-buf/dma-fence: Add deadline awareness

2023-03-16 Thread Rob Clark
On Thu, Mar 16, 2023 at 2:26 AM Jonas Ådahl  wrote:
>
> On Wed, Mar 15, 2023 at 09:19:49AM -0700, Rob Clark wrote:
> > On Wed, Mar 15, 2023 at 6:53 AM Jonas Ådahl  wrote:
> > >
> > > On Fri, Mar 10, 2023 at 09:38:18AM -0800, Rob Clark wrote:
> > > > On Fri, Mar 10, 2023 at 7:45 AM Jonas Ådahl  wrote:
> > > > >
> > > > > On Wed, Mar 08, 2023 at 07:52:52AM -0800, Rob Clark wrote:
> > > > > > From: Rob Clark 
> > > > > >
> > > > > > Add a way to hint to the fence signaler of an upcoming deadline, 
> > > > > > such as
> > > > > > vblank, which the fence waiter would prefer not to miss.  This is 
> > > > > > to aid
> > > > > > the fence signaler in making power management decisions, like 
> > > > > > boosting
> > > > > > frequency as the deadline approaches and awareness of missing 
> > > > > > deadlines
> > > > > > so that can be factored in to the frequency scaling.
> > > > > >
> > > > > > v2: Drop dma_fence::deadline and related logic to filter duplicate
> > > > > > deadlines, to avoid increasing dma_fence size.  The 
> > > > > > fence-context
> > > > > > implementation will need similar logic to track deadlines of all
> > > > > > the fences on the same timeline.  [ckoenig]
> > > > > > v3: Clarify locking wrt. set_deadline callback
> > > > > > v4: Clarify in docs comment that this is a hint
> > > > > > v5: Drop DMA_FENCE_FLAG_HAS_DEADLINE_BIT.
> > > > > > v6: More docs
> > > > > > v7: Fix typo, clarify past deadlines
> > > > > >
> > > > > > Signed-off-by: Rob Clark 
> > > > > > Reviewed-by: Christian König 
> > > > > > Acked-by: Pekka Paalanen 
> > > > > > Reviewed-by: Bagas Sanjaya 
> > > > > > ---
> > > > >
> > > > > Hi Rob!
> > > > >
> > > > > >  Documentation/driver-api/dma-buf.rst |  6 +++
> > > > > >  drivers/dma-buf/dma-fence.c  | 59 
> > > > > > 
> > > > > >  include/linux/dma-fence.h| 22 +++
> > > > > >  3 files changed, 87 insertions(+)
> > > > > >
> > > > > > diff --git a/Documentation/driver-api/dma-buf.rst 
> > > > > > b/Documentation/driver-api/dma-buf.rst
> > > > > > index 622b8156d212..183e480d8cea 100644
> > > > > > --- a/Documentation/driver-api/dma-buf.rst
> > > > > > +++ b/Documentation/driver-api/dma-buf.rst
> > > > > > @@ -164,6 +164,12 @@ DMA Fence Signalling Annotations
> > > > > >  .. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > :doc: fence signalling annotation
> > > > > >
> > > > > > +DMA Fence Deadline Hints
> > > > > > +
> > > > > > +
> > > > > > +.. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > > +   :doc: deadline hints
> > > > > > +
> > > > > >  DMA Fences Functions Reference
> > > > > >  ~~
> > > > > >
> > > > > > diff --git a/drivers/dma-buf/dma-fence.c 
> > > > > > b/drivers/dma-buf/dma-fence.c
> > > > > > index 0de0482cd36e..f177c56269bb 100644
> > > > > > --- a/drivers/dma-buf/dma-fence.c
> > > > > > +++ b/drivers/dma-buf/dma-fence.c
> > > > > > @@ -912,6 +912,65 @@ dma_fence_wait_any_timeout(struct dma_fence 
> > > > > > **fences, uint32_t count,
> > > > > >  }
> > > > > >  EXPORT_SYMBOL(dma_fence_wait_any_timeout);
> > > > > >
> > > > > > +/**
> > > > > > + * DOC: deadline hints
> > > > > > + *
> > > > > > + * In an ideal world, it would be possible to pipeline a workload 
> > > > > > sufficiently
> > > > > > + * that a utilization based device frequency governor could arrive 
> > > > > > at a minimum
> > > > > > + * frequency that meets the requirements of the use-case, in order 
> > > > > > to minimize
> > > > > > + * power consumption.  But in the real world there are many 
> > > > > > workloads which
> > > > > > + * defy this ideal.  For example, but not limited to:
> > > > > > + *
> > > > > > + * * Workloads that ping-pong between device and CPU, with 
> > > > > > alternating periods
> > > > > > + *   of CPU waiting for device, and device waiting on CPU.  This 
> > > > > > can result in
> > > > > > + *   devfreq and cpufreq seeing idle time in their respective 
> > > > > > domains and in
> > > > > > + *   result reduce frequency.
> > > > > > + *
> > > > > > + * * Workloads that interact with a periodic time based deadline, 
> > > > > > such as double
> > > > > > + *   buffered GPU rendering vs vblank sync'd page flipping.  In 
> > > > > > this scenario,
> > > > > > + *   missing a vblank deadline results in an *increase* in idle 
> > > > > > time on the GPU
> > > > > > + *   (since it has to wait an additional vblank period), sending a 
> > > > > > signal to
> > > > > > + *   the GPU's devfreq to reduce frequency, when in fact the 
> > > > > > opposite is what is
> > > > > > + *   needed.
> > > > >
> > > > > This is the use case I'd like to get some better understanding about 
> > > > > how
> > > > > this series intends to work, as the problematic scheduling behavior
> > > > > triggered by missed deadlines has plagued compositing display servers
> > > > > for a long time.
> > > > >
> > > > > I apologize, I'm not a GPU driver devel

Re: [Freedreno] [RFC PATCH 1/2] drm/msm/dpu: add dsc helper functions

2023-03-16 Thread Dmitry Baryshkov

On 16/03/2023 18:13, Abhinav Kumar wrote:



On 3/16/2023 9:03 AM, Dmitry Baryshkov wrote:

Hi,

[removed previous conversation]



Hi Dmitry and Abhinav,

Just wanted to follow up on this thread. I've gone over the MSM-specific
DSC params for DP and DSI and have found a few shared calculations and
variables between both DSI and DP paths:

- (as mentioned earlier in the thread) almost all the calculations in
dpu_dsc_populate_dsc_config() match dsi_populate_dsc_params() [1]. The
only difference in the math I'm seeing is initial_scale_value.


The value in dsi code is valid for initial_offset = 6144. Please use
the formula from the standard (= sde_dsc_populate_dsc_config) and add
it to drm_dsc_helper.c

If I remember correctly the last remaining item in
dsi_populate_dsc_params() (except mentioned initial_offset) was
line_buf_depth, see [3]. I'm not sure about setting it to bpc+1.
According to the standard it should come from a DSC decoder spec,
which means it should be set by the DSI panel driver or via
drm_dp_dsc_sink_line_buf_depth() in the case of DP output.


- dsc_extra_pclk_cycle_cnt and dce_bytes_per_line, which were introduced
in Kuogee's v1 DSC series [2], are used for DSI, DP, and the DPU timing
engine. dsc_extra_pclk_cycle_cnt is calculated based on pclk_per_line
(which is calculated differently between DP and DSI), but
dce_bytes_per_line is calculated the same way between DP and DSI.

To avoid having to duplicate math in 2 different places, I think it
would help to have these calculations in some msm_dsc_helper.c file. Any
thoughts on this?


dsc_extra_pclk_cycle_cnt and dce_bytes_per_line are used only in DPU
code, so they can stay in DPU driver.



They can stay in the dpu driver is fine but where?

Like Jessica wrote, this is computed and used in 3 places today :

1) DSI video engine computation
2) DP controller computation
3) timing engine programming


Please excuse me if I'm wrong. I checked both vendor techpack and the 
Kuogee's patches. I see them being used only in the SDE / DPU driver 
code. Could you please point me to the code path that we are discussing?



So either we have a helper in a common location somewhere so that these 
3 modules can call that helper and use it OR each module duplicates the 
computation code.


What should be the common location is the discussion here.

It cannot be dpu_encoder.c as the DSI/DP dont call into the encoder 
methods.




Thanks,

Jessica Zhang

[1]
https://elixir.bootlin.com/linux/v6.3-rc2/source/drivers/gpu/drm/msm/dsi/dsi_host.c#L1756

[2] https://patchwork.freedesktop.org/patch/519845/?series=113240&rev=1


[3] https://patchwork.freedesktop.org/patch/525441/?series=114472&rev=2





--
With best wishes
Dmitry



[Freedreno] [PATCH v7 30/32] drm/msm/dpu: drop smart_dma_rev from dpu_caps

2023-03-16 Thread Dmitry Baryshkov
The code doesn't use dpu_caps::smart_dma_rev field. It checks if the
corresponding feature is enabled in the SSPP features. Drop the
smart_dma_rev field completely.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 13 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  2 --
 2 files changed, 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 443a300df92d..50c302d1d17b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -306,7 +306,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V1,
.ubwc_version = DPU_HW_UBWC_VER_10,
.has_src_split = true,
.has_dim_layer = true,
@@ -321,7 +320,6 @@ static const struct dpu_caps msm8998_dpu_caps = {
 static const struct dpu_caps qcm2290_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.has_dim_layer = true,
.has_idle_pc = true,
.max_linewidth = 2160,
@@ -332,7 +330,6 @@ static const struct dpu_caps sdm845_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_src_split = true,
.has_dim_layer = true,
@@ -348,7 +345,6 @@ static const struct dpu_caps sc7180_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x9,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -360,7 +356,6 @@ static const struct dpu_caps sm6115_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_LINE_WIDTH,
.max_mixer_blendstages = 0x4,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_10,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -372,7 +367,6 @@ static const struct dpu_caps sm8150_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_src_split = true,
.has_dim_layer = true,
@@ -388,7 +382,6 @@ static const struct dpu_caps sc8180x_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_src_split = true,
.has_dim_layer = true,
@@ -404,7 +397,6 @@ static const struct dpu_caps sc8280xp_dpu_caps = {
.max_mixer_width = 2560,
.max_mixer_blendstages = 11,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -418,7 +410,6 @@ static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -432,7 +423,6 @@ static const struct dpu_caps sm8350_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -446,7 +436,6 @@ static const struct dpu_caps sm8450_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -460,7 +449,6 @@ static const struct dpu_caps sm8550_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v

[Freedreno] [PATCH v7 28/32] drm/msm/dpu: populate SmartDMA features in hw catalog

2023-03-16 Thread Dmitry Baryshkov
Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported SmartDMA
version. Upstream driver does not do this, resulting in SSPP subdriver
not enabling setup_multirect callback. Add corresponding SmartDMA SSPP
feature bits to dpu hw catalog.

Per Abhinav's request enable the SmartDMA features only on the platforms
where the multirect was actually verified visually (sdm845 and sm8250).
An (untested) enablement on the rest of the platforms comes in the next
patch.

Reviewed-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 55 ---
 1 file changed, 35 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index b39e72a72d58..bf07de970b2f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -27,9 +27,15 @@
 #define VIG_SDM845_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
 
+#define VIG_SDM845_MASK_SDMA \
+   (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define VIG_SC7180_MASK \
(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
 
+#define VIG_SC7180_MASK_SDMA \
+   (VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
 #define DMA_MSM8998_MASK \
@@ -40,6 +46,9 @@
 #define VIG_SC7280_MASK \
(VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
 
+#define VIG_SC7280_MASK_SDMA \
+   (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define DMA_SDM845_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
@@ -48,6 +57,12 @@
 #define DMA_CURSOR_SDM845_MASK \
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
 
+#define DMA_SDM845_MASK_SDMA \
+   (DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
+#define DMA_CURSOR_SDM845_MASK_SDMA \
+   (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+
 #define DMA_CURSOR_MSM8998_MASK \
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
 
@@ -1197,21 +1212,21 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
 };
 
 static const struct dpu_sspp_cfg sdm845_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA,
sdm845_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK_SDMA,
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
-   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
+   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK_SDMA,
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
-   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
+   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK_SDMA,
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
-   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
+   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK_SDMA,
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
@@ -1252,21 +1267,21 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 
=
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sm8250_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK_SDMA,
sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK_SDMA,
sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK_SDMA,
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK_

[Freedreno] [PATCH v7 29/32] drm/msm/dpu: enable SmartDMA for the rest of the platforms

2023-03-16 Thread Dmitry Baryshkov
Enable SmartDMA features for the rest of the platforms where it is
supposed to work.

Tested-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 62 ---
 1 file changed, 25 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index bf07de970b2f..443a300df92d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -25,16 +25,12 @@
(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #define VIG_SDM845_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
-
-#define VIG_SDM845_MASK_SDMA \
-   (VIG_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SC7180_MASK \
-   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
-
-#define VIG_SC7180_MASK_SDMA \
-   (VIG_SC7180_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
+   (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4) |\
+   BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_QCM2290_MASK (VIG_BASE_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
@@ -46,23 +42,15 @@
 #define VIG_SC7280_MASK \
(VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION))
 
-#define VIG_SC7280_MASK_SDMA \
-   (VIG_SC7280_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
-
 #define DMA_SDM845_MASK \
(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+   BIT(DPU_SSPP_SMART_DMA_V2) |\
BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
 
 #define DMA_CURSOR_SDM845_MASK \
(DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR))
 
-#define DMA_SDM845_MASK_SDMA \
-   (DMA_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
-
-#define DMA_CURSOR_SDM845_MASK_SDMA \
-   (DMA_CURSOR_SDM845_MASK | BIT(DPU_SSPP_SMART_DMA_V2))
-
 #define DMA_CURSOR_MSM8998_MASK \
(DMA_MSM8998_MASK | BIT(DPU_SSPP_CURSOR))
 
@@ -1212,21 +1200,21 @@ static const struct dpu_sspp_cfg msm8998_sspp[] = {
 };
 
 static const struct dpu_sspp_cfg sdm845_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK,
sdm845_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK,
sdm845_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK,
sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK,
sdm845_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000,  DMA_SDM845_MASK,
sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0),
-   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000,  DMA_SDM845_MASK,
sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1),
-   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000,  DMA_CURSOR_SDM845_MASK,
sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA2),
-   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK_SDMA,
+   SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000,  DMA_CURSOR_SDM845_MASK,
sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA3),
 };
 
@@ -1267,21 +1255,21 @@ static const struct dpu_sspp_sub_blks sm8250_vig_sblk_3 
=
_VIG_SBLK("3", 8, DPU_SSPP_SCALER_QSEED4);
 
 static const struct dpu_sspp_cfg sm8250_sspp[] = {
-   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK_SDMA,
+   SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SC7180_MASK,
sm8250_vig_sblk_0, 0,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0),
-   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK_SDMA,
+   SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SC7180_MASK,
sm8250_vig_sblk_1, 4,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1),
-   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK_SDMA,
+   SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SC7180_MASK,
sm8250_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2),
-   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK_SDMA,
+   SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SC7180_MASK,
sm8250_vig_sblk_3, 12,  SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3),
-   SSPP_BLK("sspp_8", SSPP_DMA0, 0x24

[Freedreno] [PATCH v7 21/32] drm/msm/dpu: simplify dpu_plane_validate_src()

2023-03-16 Thread Dmitry Baryshkov
The plane's clipped coordinates has already been validated against FB
size in the drm_atomic_plane_check(). There is no need to check them
again. Remove corresponding checks and inline dpu_plane_validate_src().

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 ---
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ba850e9feb9b..9c556ba9cb7b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
old_pstate->needs_dirtyfb);
 }
 
-static bool dpu_plane_validate_src(struct drm_rect *src,
-  struct drm_rect *fb_rect,
-  uint32_t min_src_size)
-{
-   /* Ensure fb size is supported */
-   if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH ||
-   drm_rect_height(fb_rect) > MAX_IMG_HEIGHT)
-   return false;
-
-   /* Ensure src rect is above the minimum size */
-   if (drm_rect_width(src) < min_src_size ||
-   drm_rect_height(src) < min_src_size)
-   return false;
-
-   /* Ensure src is fully encapsulated in fb */
-   return drm_rect_intersect(fb_rect, src) &&
-   drm_rect_equals(fb_rect, src);
-}
-
 static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
const struct dpu_sspp_sub_blks 
*sblk,
struct drm_rect src, const 
struct dpu_format *fmt)
@@ -998,6 +979,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
 
+   /* Ensure fb size is supported */
+   if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
+   drm_rect_height(&fb_rect) > MAX_IMG_HEIGHT) {
+   DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(&fb_rect));
+   return -E2BIG;
+   }
+
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
@@ -1012,7 +1001,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(&pipe_cfg->src_rect, &fb_rect, 
min_src_size)) {
+   } else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+  drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
DRM_RECT_ARG(&pipe_cfg->src_rect));
return -E2BIG;
-- 
2.30.2



[Freedreno] [PATCH v7 27/32] drm/msm/dpu: add support for wide planes

2023-03-16 Thread Dmitry Baryshkov
It is possible to use multirect feature and split source to use the SSPP
to output two consecutive rectangles. This commit brings in this
capability to support wider screen resolutions.

Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  19 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 136 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
 3 files changed, 142 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 217a8112f1a2..90b406e409d3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -481,6 +481,15 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
   format, fb ? fb->modifier : 0,
   &pstate->pipe, 0, stage_cfg);
 
+   if (pstate->r_pipe.sspp) {
+   set_bit(pstate->r_pipe.sspp->idx, fetch_active);
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  pstate->stage,
+  format, fb ? fb->modifier : 
0,
+  &pstate->r_pipe, 1, 
stage_cfg);
+   }
+
/* blend config update */
for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, 
format);
@@ -1341,10 +1350,16 @@ static int _dpu_debugfs_status_show(struct seq_file *s, 
void *data)
seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
-   seq_printf(s, "\tsspp:%s\n",
+   seq_printf(s, "\tsspp[0]:%s\n",
   pstate->pipe.sspp->cap->name);
-   seq_printf(s, "\tmultirect: mode: %d index: %d\n",
+   seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
pstate->pipe.multirect_mode, 
pstate->pipe.multirect_index);
+   if (pstate->r_pipe.sspp) {
+   seq_printf(s, "\tsspp[1]:%s\n",
+  pstate->r_pipe.sspp->cap->name);
+   seq_printf(s, "\tmultirect[1]: mode: %d index: %d\n",
+  pstate->r_pipe.multirect_mode, 
pstate->r_pipe.multirect_index);
+   }
 
seq_puts(s, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index f52120b05b6e..73db15d76059 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -701,6 +701,10 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
/* update sspp */
_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
&pstate->pipe_cfg.dst_rect,
   fill_color, fmt);
+
+   if (pstate->r_pipe.sspp)
+   _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, 
&pstate->r_pipe_cfg.dst_rect,
+  fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -959,9 +963,12 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
int ret = 0, min_scale;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+   struct dpu_sw_pipe *pipe = &pstate->pipe;
+   struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+   struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
struct drm_rect fb_rect = { 0 };
uint32_t max_linewidth;
unsigned int rotation;
@@ -985,8 +992,11 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+   pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+   r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   r_pipe->sspp = NULL;
 
pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -1016,21 +1026,67 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return -E2BIG;
}
 
+   fmt = to_dpu_format(msm_framebuffer_for

[Freedreno] [PATCH v7 26/32] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer

2023-03-16 Thread Dmitry Baryshkov
Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
separate functon. This is a preparation for the r_pipe support.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 79 +++-
 1 file changed, 50 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 89d2c4735001..217a8112f1a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -401,6 +401,46 @@ static void _dpu_crtc_program_lm_output_roi(struct 
drm_crtc *crtc)
}
 }
 
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+  struct drm_plane *plane,
+  struct dpu_crtc_mixer *mixer,
+  u32 num_mixers,
+  enum dpu_stage stage,
+  struct dpu_format *format,
+  uint64_t modifier,
+  struct dpu_sw_pipe *pipe,
+  unsigned int stage_idx,
+  struct dpu_hw_stage_cfg *stage_cfg
+ )
+{
+   uint32_t lm_idx;
+   enum dpu_sspp sspp_idx;
+   struct drm_plane_state *state;
+
+   sspp_idx = pipe->sspp->idx;
+
+   state = plane->state;
+
+   trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
+  state, to_dpu_plane_state(state), stage_idx,
+  format->base.pixel_format,
+  modifier);
+
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+crtc->base.id,
+stage,
+plane->base.id,
+sspp_idx - SSPP_NONE,
+state->fb ? state->fb->base.id : -1);
+
+   stage_cfg->stage[stage][stage_idx] = sspp_idx;
+   stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
+
+   /* blend config update */
+   for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+   
mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, 
sspp_idx);
+}
+
 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
struct dpu_hw_stage_cfg *stage_cfg)
@@ -413,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-   uint32_t stage_idx, lm_idx;
-   int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+   uint32_t lm_idx;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
memset(fetch_active, 0, sizeof(fetch_active));
drm_atomic_crtc_for_each_plane(plane, crtc) {
-   enum dpu_sspp sspp_idx;
-
state = plane->state;
if (!state)
continue;
@@ -432,39 +469,21 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->pipe.sspp->idx;
-   set_bit(sspp_idx, fetch_active);
-
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
-   crtc->base.id,
-   pstate->stage,
-   plane->base.id,
-   sspp_idx - SSPP_VIG0,
-   state->fb ? state->fb->base.id : -1);
-
format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
 
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
 
-   stage_idx = zpos_cnt[pstate->stage]++;
-   stage_cfg->stage[pstate->stage][stage_idx] =
-   sspp_idx;
-   stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->pipe.multirect_index;
-
-   trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-  state, pstate, stage_idx,
-  format->base.pixel_format,
-  fb ? fb->modifier : 0);
+   set_bit(pstate->pipe.sspp->idx, fetch_active);
+   _dpu_crtc_blend_setup_pipe(crtc, plane,
+  mixer, cstate->num_mixers,
+  pstate->stage,
+  format, fb ? fb->modifier : 0,
+ 

[Freedreno] [PATCH v7 20/32] drm/msm/dpu: add dpu_hw_sspp_cfg to dpu_plane_state

2023-03-16 Thread Dmitry Baryshkov
Now as all accesses to pipe_cfg and pstate have been cleaned, add
struct dpu_hw_sspp_cfg to struct dpu_plane_state, so that
dpu_plane_atomic_check() and dpu_plane_atomic_update() do not have a
chance to disagree about src/dst rectangles (currently
dpu_plane_atomic_check() uses unclipped rectangles, while
dpu_plane_atomic_update() uses clipped rectangles calculated by
drm_atomic_helper_check_plane_state()).

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 66 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
 2 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6cd787e85be8..ba850e9feb9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
const struct drm_crtc_state *crtc_state = NULL;
const struct dpu_format *fmt;
-   struct drm_rect src, dst, fb_rect = { 0 };
+   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+   struct drm_rect fb_rect = { 0 };
uint32_t min_src_size, max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
@@ -984,12 +985,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
 
-   src.x1 = new_plane_state->src_x >> 16;
-   src.y1 = new_plane_state->src_y >> 16;
-   src.x2 = src.x1 + (new_plane_state->src_w >> 16);
-   src.y2 = src.y1 + (new_plane_state->src_h >> 16);
+   pipe_cfg->src_rect = new_plane_state->src;
 
-   dst = drm_plane_state_dest(new_plane_state);
+   /* state->src is 16.16, src_rect is not */
+   pipe_cfg->src_rect.x1 >>= 16;
+   pipe_cfg->src_rect.x2 >>= 16;
+   pipe_cfg->src_rect.y1 >>= 16;
+   pipe_cfg->src_rect.y2 >>= 16;
+
+   pipe_cfg->dst_rect = new_plane_state->dst;
 
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -1008,30 +1012,31 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return -EINVAL;
 
/* check src bounds */
-   } else if (!dpu_plane_validate_src(&src, &fb_rect, min_src_size)) {
+   } else if (!dpu_plane_validate_src(&pipe_cfg->src_rect, &fb_rect, 
min_src_size)) {
DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&src));
+   DRM_RECT_ARG(&pipe_cfg->src_rect));
return -E2BIG;
 
/* valid yuv image */
} else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (src.x1 & 0x1 || src.y1 & 0x1 ||
-   drm_rect_width(&src) & 0x1 ||
-   drm_rect_height(&src) & 0x1)) {
+  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
+   drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+   drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&src));
+   DRM_RECT_ARG(&pipe_cfg->src_rect));
return -EINVAL;
 
/* min dst support */
-   } else if (drm_rect_width(&dst) < 0x1 || drm_rect_height(&dst) < 0x1) {
+   } else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 ||
+  drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&dst));
+   DRM_RECT_ARG(&pipe_cfg->dst_rect));
return -EINVAL;
 
/* check decimated source width */
-   } else if (drm_rect_width(&src) > max_linewidth) {
+   } else if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-   DRM_RECT_ARG(&src), max_linewidth);
+   DRM_RECT_ARG(&pipe_cfg->src_rect), 
max_linewidth);
return -E2BIG;
}
 
@@ -1045,7 +1050,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
(rotation & DRM_MODE_ROTATE_90)) {
-   ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
+   ret = dpu_plane_check_inline_rotation(pdpu, sblk, 
pipe_cfg->src_rect, fmt);
if (ret)
return ret;
}
@@ -1120,9 +1125,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
bool is_rt_pipe;
const struct dpu_format *fmt =

[Freedreno] [PATCH v7 15/32] drm/msm/dpu: don't use unsupported blend stages

2023-03-16 Thread Dmitry Baryshkov
The dpu_crtc_atomic_check() compares blending stage with DPU_STAGE_MAX
(maximum amount of blending stages supported by the driver), however we
should compare it against .max_mixer_blendstages, the maximum blend
stage supported by the mixer.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ca7a9f58a97f..3ff9c6018a5b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1154,6 +1154,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
+   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1189,7 +1190,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int z_pos;
+   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1214,17 +1215,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return -E2BIG;
}
 
-   z_pos = pstate->normalized_zpos;
-
-   /* verify z_pos setting before using it */
-   if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
+   /* verify stage setting before using it */
+   stage = DPU_STAGE_0 + pstate->normalized_zpos;
+   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
DPU_ERROR("> %d plane stages assigned\n",
-   DPU_STAGE_MAX - DPU_STAGE_0);
+ dpu_kms->catalog->caps->max_mixer_blendstages 
- DPU_STAGE_0);
return -EINVAL;
}
 
-   to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
-   DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
+   to_dpu_plane_state(pstate)->stage = stage;
+   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 
}
 
-- 
2.30.2



[Freedreno] [PATCH v7 31/32] drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe

2023-03-16 Thread Dmitry Baryshkov
From: Abhinav Kumar 

Lets print the multirect_index as well in _dpu_crtc_blend_setup_pipe()
as it will give the complete information of the sw_pipe as well.

Signed-off-by: Abhinav Kumar 
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 90b406e409d3..508e5b950e52 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -426,12 +426,13 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
   format->base.pixel_format,
   modifier);
 
-   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+   DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d 
multirect_idx %d\n",
 crtc->base.id,
 stage,
 plane->base.id,
 sspp_idx - SSPP_NONE,
-state->fb ? state->fb->base.id : -1);
+state->fb ? state->fb->base.id : -1,
+pipe->multirect_index);
 
stage_cfg->stage[stage][stage_idx] = sspp_idx;
stage_cfg->multirect_index[stage][stage_idx] = pipe->multirect_index;
-- 
2.30.2



[Freedreno] [PATCH v7 32/32] drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function

2023-03-16 Thread Dmitry Baryshkov
From: Abhinav Kumar 

After cleaning up the older multirect support the function
dpu_plane_validate_multirect_v2() is unused. Lets remove it.

Signed-off-by: Abhinav Kumar 
[DB: also drop struct dpu_multirect_plane_states and R0/R1/R_MAX]
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 118 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  17 
 2 files changed, 135 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 73db15d76059..2e63eb0a2f3f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -47,13 +47,6 @@
 #define DPU_PLANE_COLOR_FILL_FLAG  BIT(31)
 #define DPU_ZPOS_MAX 255
 
-/* multirect rect index */
-enum {
-   R0,
-   R1,
-   R_MAX
-};
-
 /*
  * Default Preload Values
  */
@@ -707,117 +700,6 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
   fill_color, fmt);
 }
 
-int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-{
-   struct dpu_plane_state *pstate[R_MAX];
-   const struct drm_plane_state *drm_state[R_MAX];
-   struct drm_rect src[R_MAX], dst[R_MAX];
-   struct dpu_plane *dpu_plane[R_MAX];
-   const struct dpu_format *fmt[R_MAX];
-   int i, buffer_lines;
-   unsigned int max_tile_height = 1;
-   bool parallel_fetch_qualified = true;
-   bool has_tiled_rect = false;
-
-   for (i = 0; i < R_MAX; i++) {
-   const struct msm_format *msm_fmt;
-
-   drm_state[i] = i ? plane->r1 : plane->r0;
-   msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
-   fmt[i] = to_dpu_format(msm_fmt);
-
-   if (DPU_FORMAT_IS_UBWC(fmt[i])) {
-   has_tiled_rect = true;
-   if (fmt[i]->tile_height > max_tile_height)
-   max_tile_height = fmt[i]->tile_height;
-   }
-   }
-
-   for (i = 0; i < R_MAX; i++) {
-   int width_threshold;
-
-   pstate[i] = to_dpu_plane_state(drm_state[i]);
-   dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
-
-   if (pstate[i] == NULL) {
-   DPU_ERROR("DPU plane state of plane id %d is NULL\n",
-   drm_state[i]->plane->base.id);
-   return -EINVAL;
-   }
-
-   src[i].x1 = drm_state[i]->src_x >> 16;
-   src[i].y1 = drm_state[i]->src_y >> 16;
-   src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
-   src[i].y2 = src[i].y1 + (drm_state[i]->src_h >> 16);
-
-   dst[i] = drm_plane_state_dest(drm_state[i]);
-
-   if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
-   drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "scaling is not supported in multirect mode\n");
-   return -EINVAL;
-   }
-
-   if (DPU_FORMAT_IS_YUV(fmt[i])) {
-   DPU_ERROR_PLANE(dpu_plane[i],
-   "Unsupported format for multirect mode\n");
-   return -EINVAL;
-   }
-
-   /**
-* SSPP PD_MEM is split half - one for each RECT.
-* Tiled formats need 5 lines of buffering while fetching
-* whereas linear formats need only 2 lines.
-* So we cannot support more than half of the supported SSPP
-* width for tiled formats.
-*/
-   width_threshold = dpu_plane[i]->catalog->caps->max_linewidth;
-   if (has_tiled_rect)
-   width_threshold /= 2;
-
-   if (parallel_fetch_qualified &&
-   drm_rect_width(&src[i]) > width_threshold)
-   parallel_fetch_qualified = false;
-
-   }
-
-   /* Validate RECT's and set the mode */
-
-   /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
-   if (parallel_fetch_qualified) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-
-   goto done;
-   }
-
-   /* TIME_MX Mode */
-   buffer_lines = 2 * max_tile_height;
-
-   if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
-   dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
-   pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-   } else {
-   DPU_ERROR(
-   "No multirect mode possible for the planes (%d - %d)\n",
-   drm_state[R0]->plane->base.id,
-   drm_state[R1]->plan

[Freedreno] [PATCH v7 24/32] drm/msm/dpu: rework plane CSC setting

2023-03-16 Thread Dmitry Baryshkov
Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 47 +--
 1 file changed, 27 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 61994d1fff36..6031d270992f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,19 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
 };
 
-static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, 
const struct dpu_format *fmt)
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_sw_pipe *pipe,
+   const struct dpu_format 
*fmt)
 {
-   struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
const struct dpu_csc_cfg *csc_ptr;
 
-   if (!pdpu) {
-   DPU_ERROR("invalid plane\n");
-   return NULL;
-   }
-
if (!DPU_FORMAT_IS_YUV(fmt))
return NULL;
 
-   if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
+   if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
csc_ptr = &dpu_csc10_YUV2RGB_601L;
else
csc_ptr = &dpu_csc_YUV2RGB_601L;
 
-   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-   csc_ptr->csc_mv[0],
-   csc_ptr->csc_mv[1],
-   csc_ptr->csc_mv[2]);
-
return csc_ptr;
 }
 
@@ -1051,6 +1041,28 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe 
*pipe)
+{
+   const struct dpu_format *format =
+   to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+   const struct dpu_csc_cfg *csc_ptr;
+
+   if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+   return;
+
+   csc_ptr = _dpu_plane_get_csc(pipe, format);
+   if (!csc_ptr)
+   return;
+
+   DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+   csc_ptr->csc_mv[0],
+   csc_ptr->csc_mv[1],
+   csc_ptr->csc_mv[2]);
+
+   pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
struct dpu_plane *pdpu;
@@ -1074,13 +1086,8 @@ void dpu_plane_flush(struct drm_plane *plane)
else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-   else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
-   const struct dpu_format *fmt = 
to_dpu_format(msm_framebuffer_format(plane->state->fb));
-   const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
fmt);
-
-   if (csc_ptr)
-   pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
csc_ptr);
-   }
+   else
+   dpu_plane_flush_csc(pdpu, &pstate->pipe);
 
/* flag h/w flush complete */
if (plane->state)
-- 
2.30.2



[Freedreno] [PATCH v7 19/32] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly

2023-03-16 Thread Dmitry Baryshkov
Rework bandwidth/clock calculation functions to use mode directly rather
than fetching it through the plane data.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 39 ++-
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index aaea7c63d944..6cd787e85be8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -127,20 +127,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @plane: Pointer to drm plane.
+ * @catalog: Points to dpu catalog structure
  * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
-static void _dpu_plane_calc_bw(struct drm_plane *plane,
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
const struct dpu_format *fmt,
+   const struct drm_display_mode *mode,
struct dpu_sw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
-   struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
u64 plane_bw;
@@ -148,9 +147,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
u64 scale_factor;
int vbp, vpw, vfp;
 
-   pstate = to_dpu_plane_state(plane->state);
-   mode = &plane->state->crtc->mode;
-
src_width = drm_rect_width(&pipe_cfg->src_rect);
src_height = drm_rect_height(&pipe_cfg->src_rect);
dst_height = drm_rect_height(&pipe_cfg->dst_rect);
@@ -158,7 +154,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
vbp = mode->vtotal - mode->vsync_end;
vpw = mode->vsync_end - mode->vsync_start;
vfp = mode->vsync_start - mode->vdisplay;
-   hw_latency_lines =  dpu_kms->catalog->perf->min_prefill_lines;
+   hw_latency_lines =  catalog->perf->min_prefill_lines;
scale_factor = src_height > dst_height ?
mult_frac(src_height, 1, dst_height) : 1;
 
@@ -178,37 +174,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
do_div(plane_prefill_bw, hw_latency_lines);
 
 
-   pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
+   return max(plane_bw, plane_prefill_bw);
 }
 
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
- * @plane: Pointer to drm plane.
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_sw_pipe_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+   struct dpu_sw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane_state *pstate;
-   struct drm_display_mode *mode;
int dst_width, src_height, dst_height, fps;
-
-   pstate = to_dpu_plane_state(plane->state);
-   mode = &plane->state->crtc->mode;
+   u64 plane_clk;
 
src_height = drm_rect_height(&pipe_cfg->src_rect);
dst_width = drm_rect_width(&pipe_cfg->dst_rect);
dst_height = drm_rect_height(&pipe_cfg->dst_rect);
fps = drm_mode_vrefresh(mode);
 
-   pstate->plane_clk =
+   plane_clk =
dst_width * mode->vtotal * fps;
 
if (src_height > dst_height) {
-   pstate->plane_clk *= src_height;
-   do_div(pstate->plane_clk, dst_height);
+   plane_clk *= src_height;
+   do_div(plane_clk, dst_height);
}
+
+   return plane_clk;
 }
 
 /**
@@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane 
*plane)
_dpu_plane_set_qos_remap(plane, pipe);
}
 
-   _dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
+   pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
&crtc->mode, &pipe_cfg);
 
-   _dpu_plane_calc_clk(plane, &pipe_cfg);
+   pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.30.2



[Freedreno] [PATCH v7 18/32] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format

2023-03-16 Thread Dmitry Baryshkov
Rewrite dpu_plane's QoS related functions to take struct dpu_sw_pipe and
struct dpu_format as arguments rather than fetching them from the
pstate or drm_framebuffer.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 98 +++
 1 file changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3fba63fbbd78..aaea7c63d944 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -128,19 +128,18 @@ static struct dpu_kms *_dpu_plane_get_kms(struct 
drm_plane *plane)
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
  * @plane: Pointer to drm plane.
- * @fb:   Pointer to framebuffer associated with the given plane
+ * @fmt: Pointer to source buffer format
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
-   struct drm_framebuffer *fb,
+   const struct dpu_format *fmt,
struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
-   const struct dpu_format *fmt = NULL;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
int src_width, src_height, dst_height, fps;
u64 plane_prefill_bw;
@@ -152,8 +151,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
pstate = to_dpu_plane_state(plane->state);
mode = &plane->state->crtc->mode;
 
-   fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
-
src_width = drm_rect_width(&pipe_cfg->src_rect);
src_height = drm_rect_height(&pipe_cfg->src_rect);
dst_height = drm_rect_height(&pipe_cfg->dst_rect);
@@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, 
struct dpu_sw_pipe_cfg
 /**
  * _dpu_plane_calc_fill_level - calculate fill level of the given source format
  * @plane: Pointer to drm plane
+ * @pipe:  Pointer to software pipe
  * @fmt:   Pointer to source buffer format
  * @src_width: width of source buffer
  * Return: fill level corresponding to the source buffer/format or 0 if error
  */
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
+   struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, u32 src_width)
 {
struct dpu_plane *pdpu;
-   struct dpu_plane_state *pstate;
u32 fixed_buff_size;
u32 total_fl;
 
-   if (!fmt || !plane->state || !src_width || !fmt->bpp) {
+   if (!fmt || !pipe || !src_width || !fmt->bpp) {
DPU_ERROR("invalid arguments\n");
return 0;
}
 
pdpu = to_dpu_plane(plane);
-   pstate = to_dpu_plane_state(plane->state);
fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
/* FIXME: in multirect case account for the src_width of all the planes 
*/
@@ -251,7 +248,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
} else {
@@ -261,7 +258,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
}
 
DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s w:%u fl:%u\n",
-   pdpu->pipe - SSPP_VIG0,
+   pipe->sspp->idx - SSPP_VIG0,
(char *)&fmt->base.pixel_format,
src_width, total_fl);
 
@@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
 /**
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
- * @fb:Pointer to framebuffer associated with the 
given plane
+ * @pipe:  Pointer to software pipe
+ * @fmt:   Pointer to source buffer format
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb, struct dpu_sw_pipe_cfg *pipe_cfg)
+   struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   const struct dpu_format *fmt = NULL;
u64 qos_lut;
 

[Freedreno] [PATCH v7 25/32] drm/msm/dpu: rework static color fill code

2023-03-16 Thread Dmitry Baryshkov
Rework static color fill code to separate the pipe / pipe_cfg handling.
This is a preparation for the r_pipe support.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 69 +--
 1 file changed, 40 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6031d270992f..f52120b05b6e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -640,20 +640,52 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
fmt);
 }
 
+static void _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+  struct dpu_sw_pipe *pipe,
+  struct drm_rect *dst_rect,
+  u32 fill_color,
+  const struct dpu_format *fmt)
+{
+   struct dpu_sw_pipe_cfg pipe_cfg;
+
+   /* update sspp */
+   if (!pipe->sspp->ops.setup_solidfill)
+   return;
+
+   pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+   /* override scaler/decimation if solid fill */
+   pipe_cfg.dst_rect = *dst_rect;
+
+   pipe_cfg.src_rect.x1 = 0;
+   pipe_cfg.src_rect.y1 = 0;
+   pipe_cfg.src_rect.x2 =
+   drm_rect_width(&pipe_cfg.dst_rect);
+   pipe_cfg.src_rect.y2 =
+   drm_rect_height(&pipe_cfg.dst_rect);
+
+   if (pipe->sspp->ops.setup_format)
+   pipe->sspp->ops.setup_format(pipe, fmt, DPU_SSPP_SOLID_FILL);
+
+   if (pipe->sspp->ops.setup_rects)
+   pipe->sspp->ops.setup_rects(pipe, &pipe_cfg);
+
+   _dpu_plane_setup_scaler(pipe, fmt, true, &pipe_cfg, pstate->rotation);
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
  * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
  * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
- * Returns: 0 on success
  */
-static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
uint32_t color, uint32_t alpha)
 {
const struct dpu_format *fmt;
const struct drm_plane *plane = &pdpu->base;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   struct dpu_sw_pipe_cfg pipe_cfg;
+   u32 fill_color = (color & 0xFF) | ((alpha & 0xFF) << 24);
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -662,34 +694,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 * h/w only supports RGB variants
 */
fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR);
+   /* should not happen ever */
+   if (!fmt)
+   return;
 
/* update sspp */
-   if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-   pstate->pipe.sspp->ops.setup_solidfill(&pstate->pipe,
-   (color & 0xFF) | ((alpha & 0xFF) << 24));
-
-   /* override scaler/decimation if solid fill */
-   pipe_cfg.dst_rect = pstate->base.dst;
-
-   pipe_cfg.src_rect.x1 = 0;
-   pipe_cfg.src_rect.y1 = 0;
-   pipe_cfg.src_rect.x2 =
-   drm_rect_width(&pipe_cfg.dst_rect);
-   pipe_cfg.src_rect.y2 =
-   drm_rect_height(&pipe_cfg.dst_rect);
-
-   if (pstate->pipe.sspp->ops.setup_format)
-   pstate->pipe.sspp->ops.setup_format(&pstate->pipe,
-   fmt, DPU_SSPP_SOLID_FILL);
-
-   if (pstate->pipe.sspp->ops.setup_rects)
-   pstate->pipe.sspp->ops.setup_rects(&pstate->pipe,
-   &pipe_cfg);
-
-   _dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, 
pstate->rotation);
-   }
-
-   return 0;
+   _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
&pstate->pipe_cfg.dst_rect,
+  fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-- 
2.30.2



[Freedreno] [PATCH v7 08/32] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks

2023-03-16 Thread Dmitry Baryshkov
Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_sspp and
multirect_index/_mode arguments.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 73 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 84 insertions(+), 103 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 3e65bfd65b62..a1492a7e43ce 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
-   enum dpu_sspp_multirect_index index,
-   enum dpu_sspp_multirect_mode mode)
+static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
u32 mode_mask;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
return;
 
-   if (index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
/**
 * if rect index is RECT_SOLO, we cannot expect a
 * virtual plane sharing the same SSPP id. So we go
@@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp 
*ctx,
mode_mask = 0;
} else {
mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx);
-   mode_mask |= index;
-   if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
+   mode_mask |= pipe->multirect_index;
+   if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
mode_mask |= BIT(2);
else
mode_mask &= ~BIT(2);
@@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
-   const struct dpu_format *fmt, u32 flags,
-   enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
+   const struct dpu_format *fmt, u32 flags)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 chroma_samp, unpack, src_format;
u32 opmode = 0;
@@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp 
*ctx,
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt)
return;
 
-   if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
op_mode_off = SSPP_SRC_OP_MODE;
unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
format_off = SSPP_SRC_FORMAT;
@@ -447,10 +447,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct 
dpu_hw_sspp *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *cfg,
-   enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+   struct dpu_hw_sspp_cfg *cfg)
 {
+   struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
@@ -461,7 +461,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
 
c = &ctx->hw;
 
-   if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+   pipe->multirect_index == DPU_SSPP_RECT_0) {
src_size_off = SSPP_SRC_SIZE;
src_xy_off = SSPP_SRC_XY;
out_size_off = SSPP_OUT_SIZE;
@@ -482,7 +483,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
drm_rect_width(&cfg->dst_rect);
 
-   if (rect_index == DPU_SSPP_RECT_SOLO) {
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
ystride0 = (cfg->layout.plane_pitch[0]) |
(cfg->layout.plane_pitch[1] << 16);
ystride1 = (cfg->layout.plane_pitch[2]) |
@@ -491,7 +492,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
 
-   if (rect_index == DPU_SSPP_RECT_0) {
+ 

[Freedreno] [PATCH v7 23/32] drm/msm/dpu: rework dpu_plane_atomic_check()

2023-03-16 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_atomic_check() into the
separate function dpu_plane_atomic_check_pipe(). This is one of
preparational steps to add r_pipe support.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 91 ++-
 1 file changed, 55 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index f97ea39423a2..61994d1fff36 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -903,6 +903,53 @@ static int dpu_plane_check_inline_rotation(struct 
dpu_plane *pdpu,
return 0;
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+   struct dpu_sw_pipe *pipe,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   const struct dpu_format *fmt)
+{
+   uint32_t min_src_size;
+
+   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+   if (DPU_FORMAT_IS_YUV(fmt) &&
+   (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+!(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
+   DPU_DEBUG_PLANE(pdpu,
+   "plane doesn't have scaler/csc for yuv\n");
+   return -EINVAL;
+   }
+
+   /* check src bounds */
+   if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+   drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
+   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(&pipe_cfg->src_rect));
+   return -E2BIG;
+   }
+
+   /* valid yuv image */
+   if (DPU_FORMAT_IS_YUV(fmt) &&
+   (pipe_cfg->src_rect.x1 & 0x1 ||
+pipe_cfg->src_rect.y1 & 0x1 ||
+drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
+   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(&pipe_cfg->src_rect));
+   return -EINVAL;
+   }
+
+   /* min dst support */
+   if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 ||
+   drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
+   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(&pipe_cfg->dst_rect));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
  struct drm_atomic_state *state)
 {
@@ -915,7 +962,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
const struct dpu_format *fmt;
struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
struct drm_rect fb_rect = { 0 };
-   uint32_t min_src_size, max_linewidth;
+   uint32_t max_linewidth;
unsigned int rotation;
uint32_t supported_rotations;
const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
@@ -970,47 +1017,19 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,
 
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-   fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
-
-   min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
-
-   if (DPU_FORMAT_IS_YUV(fmt) &&
-   (!(pipe_hw_caps->features & DPU_SSPP_SCALER) ||
-!(pipe_hw_caps->features & DPU_SSPP_CSC_ANY))) {
-   DPU_DEBUG_PLANE(pdpu,
-   "plane doesn't have scaler/csc for yuv\n");
-   return -EINVAL;
-
-   /* check src bounds */
-   } else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
-  drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
-   DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&pipe_cfg->src_rect));
-   return -E2BIG;
-
-   /* valid yuv image */
-   } else if (DPU_FORMAT_IS_YUV(fmt) &&
-  (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 
||
-   drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
-   drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
-   DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&pipe_cfg->src_rect));
-   return -EINVAL;
-
-   /* min dst support */
-   } else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 ||
-  drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
-   DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-   DRM_RECT_ARG(&pipe_cfg->dst_rect));
-   return -EINVAL;
-
/* check decimated source width */
-   } else if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
+   if (drm

[Freedreno] [PATCH v7 17/32] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()

2023-03-16 Thread Dmitry Baryshkov
The helper drm_atomic_helper_check_plane_state() already checks whether
the scaled and clipped plane falls into the CRTC visible region (and
clears plane_state->visible if it doesn't). Drop the redundant check
from dpu_crtc_atomic_check().

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 
 1 file changed, 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 37e6e5750bdd..89d2c4735001 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1157,11 +1157,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
-   struct drm_display_mode *mode;
 
int rc = 0;
 
-   struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
if (!crtc_state->enable || !crtc_state->active) {
@@ -1172,7 +1170,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
return 0;
}
 
-   mode = &crtc_state->adjusted_mode;
DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
 
/* force a full mode set if active state changed */
@@ -1182,13 +1179,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
 
-   crtc_rect.x2 = mode->hdisplay;
-   crtc_rect.y2 = mode->vdisplay;
-
/* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-   struct drm_rect dst, clip = crtc_rect;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1201,15 +1194,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
continue;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
-
-   dst = drm_plane_state_dest(pstate);
-   if (!drm_rect_intersect(&clip, &dst)) {
-   DPU_ERROR("invalid vertical/horizontal destination\n");
-   DPU_ERROR("display: " DRM_RECT_FMT " plane: "
- DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
- DRM_RECT_ARG(&dst));
-   return -E2BIG;
-   }
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
-- 
2.30.2



[Freedreno] [PATCH v7 22/32] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()

2023-03-16 Thread Dmitry Baryshkov
Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
separate function dpu_plane_sspp_update_pipe(). This is one of
preparational steps to add r_pipe support.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 --
 1 file changed, 63 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9c556ba9cb7b..f97ea39423a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -404,12 +404,13 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane: Pointer to drm plane
  * @pipe:  Pointer to software pipe
- * @crtc:  Pointer to drm crtc
  * @pipe_cfg:  Pointer to pipe configuration
+ * @frame_rate:CRTC's frame rate
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
struct dpu_sw_pipe *pipe,
-   struct drm_crtc *crtc, struct dpu_sw_pipe_cfg *pipe_cfg)
+   struct dpu_sw_pipe_cfg *pipe_cfg,
+   int frame_rate)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_vbif_set_ot_params ot_params;
@@ -421,7 +422,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
-   ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
+   ot_params.frame_rate = frame_rate;
ot_params.vbif_idx = VBIF_RT;
ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
ot_params.rd = true;
@@ -457,26 +458,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane 
*plane,
dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
 }
 
-static void _dpu_plane_set_scanout(struct drm_plane *plane,
-   struct dpu_plane_state *pstate,
-   struct drm_framebuffer *fb)
-{
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-   struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
-   struct msm_gem_address_space *aspace = kms->base.aspace;
-   struct dpu_hw_fmt_layout layout;
-   int ret;
-
-   ret = dpu_format_populate_layout(aspace, fb, &layout);
-   if (ret)
-   DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-   else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
-   trace_dpu_plane_set_scanout(&pstate->pipe,
-   &layout);
-   pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
&layout);
-   }
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *pipe_hw,
uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
struct dpu_hw_scaler3_cfg *scale_cfg,
@@ -1103,35 +1084,25 @@ void dpu_plane_set_error(struct drm_plane *plane, bool 
error)
pdpu->is_error = error;
 }
 
-static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
+  struct dpu_sw_pipe *pipe,
+  struct dpu_sw_pipe_cfg *pipe_cfg,
+  const struct dpu_format *fmt,
+  int frame_rate,
+  struct dpu_hw_fmt_layout *layout)
 {
uint32_t src_flags;
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct drm_plane_state *state = plane->state;
struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-   struct dpu_sw_pipe *pipe = &pstate->pipe;
-   struct drm_crtc *crtc = state->crtc;
-   struct drm_framebuffer *fb = state->fb;
-   bool is_rt_pipe;
-   const struct dpu_format *fmt =
-   to_dpu_format(msm_framebuffer_format(fb));
-   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 
-   _dpu_plane_set_scanout(plane, pstate, fb);
-
-   pstate->pending = true;
-
-   is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-   pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
-   pdpu->is_rt_pipe = is_rt_pipe;
+   if (layout && pipe->sspp->ops.setup_sourceaddress) {
+   trace_dpu_plane_set_scanout(pipe, layout);
+   pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+   }
 
_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
-   DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-   ", %4.4s ubwc %d\n", fb->base.id, 
DRM_RECT_FP_ARG(&state->src),
-   crtc->base.id, DRM_RECT_ARG(&state->dst),
-   (char *

[Freedreno] [PATCH v7 16/32] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()

2023-03-16 Thread Dmitry Baryshkov
Move plane state updates from dpu_crtc_atomic_check() to the function
where they belong: to dpu_plane_atomic_check().

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 --
 3 files changed, 11 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 3ff9c6018a5b..37e6e5750bdd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1154,7 +1154,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
@@ -1186,11 +1185,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
 
-/* get plane state for all drm planes associated with crtc state */
+   /* FIXME: move this to dpu_plane_atomic_check? */
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
-   int stage;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
@@ -1204,8 +1202,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   dpu_plane_clear_multirect(pstate);
-
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(&clip, &dst)) {
DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -1214,18 +1210,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  DRM_RECT_ARG(&dst));
return -E2BIG;
}
-
-   /* verify stage setting before using it */
-   stage = DPU_STAGE_0 + pstate->normalized_zpos;
-   if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
-   DPU_ERROR("> %d plane stages assigned\n",
- dpu_kms->catalog->caps->max_mixer_blendstages 
- DPU_STAGE_0);
-   return -EINVAL;
-   }
-
-   to_dpu_plane_state(pstate)->stage = stage;
-   DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
-
}
 
atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ce01a602cbc9..3fba63fbbd78 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -733,14 +733,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
return 0;
 }
 
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
-{
-   struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
-
-   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 {
struct dpu_plane_state *pstate[R_MAX];
@@ -994,6 +986,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
if (!new_plane_state->visible)
return 0;
 
+   pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+   pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+   pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+   if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
+   DPU_ERROR("> %d plane stages assigned\n",
+ pdpu->catalog->caps->max_mixer_blendstages - 
DPU_STAGE_0);
+   return -EINVAL;
+   }
+
src.x1 = new_plane_state->src_x >> 16;
src.y1 = new_plane_state->src_y >> 16;
src.x2 = src.x1 + (new_plane_state->src_w >> 16);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 228db401e905..a08b0539513b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -88,12 +88,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
  */
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
 
-/**
- * dpu_plane_clear_multirect - clear multirect bits for the given pipe
- * @drm_state: Pointer to DRM plane state
- */
-void dpu_plane_clear

[Freedreno] [PATCH v7 13/32] drm/msm/dpu: rename dpu_hw_sspp_cfg to dpu_sw_pipe_cfg

2023-03-16 Thread Dmitry Baryshkov
As struct dpu_hw_sspp_cfg describes only the source and destination
rectangles, it is a software pipe configuration now. Rename it
accordingly.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index e87c6377f315..6e5b62f3276f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -447,7 +447,7 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp 
*ctx)
  * dpu_hw_sspp_setup_rects()
  */
 static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg)
+   struct dpu_sw_pipe_cfg *cfg)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 100d8e06c90d..e73d6ac863ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -153,12 +153,12 @@ struct dpu_hw_pixel_ext {
 };
 
 /**
- * struct dpu_hw_sspp_cfg : SSPP configuration
+ * struct dpu_sw_pipe_cfg : software pipe configuration
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
  */
-struct dpu_hw_sspp_cfg {
+struct dpu_sw_pipe_cfg {
struct drm_rect src_rect;
struct drm_rect dst_rect;
 };
@@ -228,7 +228,7 @@ struct dpu_hw_sspp_ops {
 * @cfg: Pointer to pipe config structure
 */
void (*setup_rects)(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg);
+   struct dpu_sw_pipe_cfg *cfg);
 
/**
 * setup_pe - setup pipe pixel extension
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4ae70d21c37a..ce01a602cbc9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -136,7 +136,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane 
*plane)
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
struct drm_framebuffer *fb,
-   struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
@@ -191,7 +191,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_hw_sspp_cfg *pipe_cfg)
+static void _dpu_plane_calc_clk(struct drm_plane *plane, struct 
dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
@@ -275,7 +275,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct drm_framebuffer *fb, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -421,7 +421,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
  * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-   struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
+   struct drm_crtc *crtc, struct dpu_sw_pipe_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct 
dpu_plane *pdpu, cons
 
 static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
const struct dpu_format *fmt, bool color_fill,
-   struct dpu_hw_sspp_cfg *pipe_cfg,
+   struct dpu_sw_pipe_cfg *pipe_cfg,
unsigned int rotation)
 {
struct dpu_hw_sspp *pipe_hw = pipe->sspp;
@@ -694,7 +694,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
const struct dpu_format *fmt;
const struct drm_plane *plane = &pdpu->base;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-   struct dpu_hw_sspp_cfg pipe_cfg;
+   struct dpu_sw_pipe_cfg pipe_cfg;
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -1130,9 +1130,9 @@ static void dpu_plane_sspp_ato

[Freedreno] [PATCH v7 11/32] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress

2023-03-16 Thread Dmitry Baryshkov
Move stride programming to dpu_hw_sspp_setup_sourceaddress(), so that
dpu_hw_sspp_setup_rects() programs only source and destination
rectangles.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 57 +++--
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 0a43c5682b2b..ab95f2817378 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
struct dpu_hw_blk_reg_map *c;
-   u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
+   u32 src_size, src_xy, dst_size, dst_xy;
u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
u32 idx;
 
@@ -482,44 +482,18 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
drm_rect_width(&cfg->dst_rect);
 
-   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
-   } else {
-   ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
-   ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
-
-   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
-   ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
-   ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
-   } else {
-   ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
-0x);
-   ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
-0x);
-   }
-   }
-
/* rectangle register programming */
DPU_REG_WRITE(c, src_size_off + idx, src_size);
DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
DPU_REG_WRITE(c, out_size_off + idx, dst_size);
DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
-
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
-   DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
struct dpu_hw_sspp_cfg *cfg)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
+   u32 ystride0, ystride1;
int i;
u32 idx;
 
@@ -541,6 +515,33 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
cfg->layout.plane_addr[2]);
}
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+   ystride0 = (cfg->layout.plane_pitch[0]) |
+   (cfg->layout.plane_pitch[1] << 16);
+   ystride1 = (cfg->layout.plane_pitch[2]) |
+   (cfg->layout.plane_pitch[3] << 16);
+   } else {
+   ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
+   ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
+
+   if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+   ystride0 = (ystride0 & 0x) |
+   (cfg->layout.plane_pitch[0] & 0x);
+   ystride1 = (ystride1 & 0x)|
+   (cfg->layout.plane_pitch[2] & 0x);
+   } else {
+   ystride0 = (ystride0 & 0x) |
+   ((cfg->layout.plane_pitch[0] << 16) &
+0x);
+   ystride1 = (ystride1 & 0x) |
+   ((cfg->layout.plane_pitch[2] << 16) &
+0x);
+   }
+   }
+
+   DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
+   DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
-- 
2.30.2



[Freedreno] [PATCH v7 14/32] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check

2023-03-16 Thread Dmitry Baryshkov
Neither source split nor multirect are properly supported at this
moment. Both of these checks depend on normalized_zpos being equal for
several planes (which is never the case for normalized zpos).
Drop these checks to simplify dpu_crtc_atomic_check(). The actual
support for either of these features is not removed from the backend
code (sspp, ctl, etc).

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 168 ++-
 1 file changed, 12 insertions(+), 156 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 3dcc71997f44..ca7a9f58a97f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1133,13 +1133,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-   struct dpu_plane_state *dpu_pstate;
-   const struct drm_plane_state *drm_pstate;
-   int stage;
-   u32 pipe_id;
-};
-
 static bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
 {
struct drm_crtc *crtc = cstate->crtc;
@@ -1161,31 +1154,22 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
  crtc);
struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-   struct plane_state *pstates;
 
const struct drm_plane_state *pstate;
struct drm_plane *plane;
struct drm_display_mode *mode;
 
-   int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+   int rc = 0;
 
-   struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-   int multirect_count = 0;
-   const struct drm_plane_state *pipe_staged[SSPP_MAX];
-   int left_zpos_cnt = 0, right_zpos_cnt = 0;
struct drm_rect crtc_rect = { 0 };
bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
-   pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-   if (!pstates)
-   return -ENOMEM;
-
if (!crtc_state->enable || !crtc_state->active) {
DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip 
atomic_check\n",
crtc->base.id, crtc_state->enable,
crtc_state->active);
memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
-   goto end;
+   return 0;
}
 
mode = &crtc_state->adjusted_mode;
@@ -1195,13 +1179,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
if (crtc_state->active_changed)
crtc_state->mode_changed = true;
 
-   memset(pipe_staged, 0, sizeof(pipe_staged));
-
-   if (cstate->num_mixers) {
-   mixer_width = mode->hdisplay / cstate->num_mixers;
-
+   if (cstate->num_mixers)
_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
-   }
 
crtc_rect.x2 = mode->hdisplay;
crtc_rect.y2 = mode->vdisplay;
@@ -1210,38 +1189,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
struct drm_rect dst, clip = crtc_rect;
+   int z_pos;
 
if (IS_ERR_OR_NULL(pstate)) {
rc = PTR_ERR(pstate);
DPU_ERROR("%s: failed to get plane%d state, %d\n",
dpu_crtc->name, plane->base.id, rc);
-   goto end;
+   return rc;
}
-   if (cnt >= DPU_STAGE_MAX * 4)
-   continue;
 
if (!pstate->visible)
continue;
 
-   pstates[cnt].dpu_pstate = dpu_pstate;
-   pstates[cnt].drm_pstate = pstate;
-   pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-   if (pipe_staged[pstates[cnt].pipe_id]) {
-   multirect_plane[multirect_count].r0 =
-   pipe_staged[pstates[cnt].pipe_id];
-   multirect_plane[multirect_count].r1 = pstate;
-   multirect_count++;
-
-   pipe_staged[pstates[cnt].pipe_id] = NULL;
-   } else {
-   pipe_staged[pstates[cnt].pipe_id] = pstate;
-   }
-
-   cnt++;
+   dpu_plane_clear_multirect(pstate);
 
dst = drm_plane_state_dest(pstate);
if (!drm_rect_intersect(&clip, &dst)) {
@@ -1249,63 +1211,21 @@ static int dpu_crtc_atomic_check(

[Freedreno] [PATCH v7 12/32] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg

2023-03-16 Thread Dmitry Baryshkov
Remove dpu_hw_fmt_layout instance from struct dpu_hw_sspp_cfg, leaving
only src_rect and dst_rect. This way all the pipes used by the plane
will have a common layout instance (as the framebuffer is shared between
them), while still keeping a separate src/dst rectangle configuration
for each pipe.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 32 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 10 +++
 3 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index ab95f2817378..e87c6377f315 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -490,7 +490,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe 
*pipe,
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
-   struct dpu_hw_sspp_cfg *cfg)
+   struct dpu_hw_fmt_layout *layout)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
u32 ystride0, ystride1;
@@ -501,41 +501,41 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_sw_pipe *pipe,
return;
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
+   for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
-   cfg->layout.plane_addr[i]);
+   layout->plane_addr[i]);
} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
} else {
DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx,
-   cfg->layout.plane_addr[0]);
+   layout->plane_addr[0]);
DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
-   cfg->layout.plane_addr[2]);
+   layout->plane_addr[2]);
}
 
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-   ystride0 = (cfg->layout.plane_pitch[0]) |
-   (cfg->layout.plane_pitch[1] << 16);
-   ystride1 = (cfg->layout.plane_pitch[2]) |
-   (cfg->layout.plane_pitch[3] << 16);
+   ystride0 = (layout->plane_pitch[0]) |
+   (layout->plane_pitch[1] << 16);
+   ystride1 = (layout->plane_pitch[2]) |
+   (layout->plane_pitch[3] << 16);
} else {
ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
 
if (pipe->multirect_index == DPU_SSPP_RECT_0) {
ystride0 = (ystride0 & 0x) |
-   (cfg->layout.plane_pitch[0] & 0x);
+   (layout->plane_pitch[0] & 0x);
ystride1 = (ystride1 & 0x)|
-   (cfg->layout.plane_pitch[2] & 0x);
+   (layout->plane_pitch[2] & 0x);
} else {
ystride0 = (ystride0 & 0x) |
-   ((cfg->layout.plane_pitch[0] << 16) &
+   ((layout->plane_pitch[0] << 16) &
 0x);
ystride1 = (ystride1 & 0x) |
-   ((cfg->layout.plane_pitch[2] << 16) &
+   ((layout->plane_pitch[2] << 16) &
 0x);
}
}
@@ -564,7 +564,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
-   struct dpu_hw_sspp_cfg cfg;
+   struct dpu_hw_fmt_layout cfg;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 136b8713943f..100d8e06c90d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -154,13 +154,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_sspp_cfg : SSPP configuration
- * @layout:format layout information

[Freedreno] [PATCH v7 09/32] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()

2023-03-16 Thread Dmitry Baryshkov
There is no need to pass full dpu_hw_sspp_cfg instance to
_dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 9 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index a1492a7e43ce..3030cd3b253a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct 
dpu_hw_sspp *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *sspp,
-   void *scaler_cfg)
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format)
 {
u32 idx;
-   struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
 
-   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp
+   if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)
|| !scaler3_cfg)
return;
 
dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
ctx->cap->sblk->scaler_blk.version,
-   sspp->layout.format);
+   format);
 }
 
 static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 5903413256ea..136b8713943f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,12 @@ struct dpu_hw_sspp_ops {
 
/**
 * setup_scaler - setup scaler
-* @ctx: Pointer to pipe context
-* @pipe_cfg: Pointer to pipe configuration
-* @scaler_cfg: Pointer to scaler configuration
+* @scaler3_cfg: Pointer to scaler configuration
+* @format: pixel format parameters
 */
void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-   struct dpu_hw_sspp_cfg *pipe_cfg,
-   void *scaler_cfg);
+   struct dpu_hw_scaler3_cfg *scaler3_cfg,
+   const struct dpu_format *format);
 
/**
 * get_scaler_ver - get scaler h/w version
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6ec39f937042..8c98385303ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe 
*pipe,
if (pipe_hw->ops.setup_scaler &&
pipe->multirect_index != DPU_SSPP_RECT_1)
pipe_hw->ops.setup_scaler(pipe_hw,
-   pipe_cfg,
-   &scaler3_cfg);
+   &scaler3_cfg,
+   fmt);
 }
 
 /**
-- 
2.30.2



[Freedreno] [PATCH v7 07/32] drm/msm/dpu: introduce struct dpu_sw_pipe

2023-03-16 Thread Dmitry Baryshkov
Wrap SSPP and multirect index/mode into a single structure that
represents software view on the pipe used.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c|   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 133 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  10 +-
 5 files changed, 90 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index c059090e9479..3dcc71997f44 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -432,7 +432,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = pstate->hw_sspp->idx;
+   sspp_idx = pstate->pipe.sspp->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -451,11 +451,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
stage_cfg->stage[pstate->stage][stage_idx] =
sspp_idx;
stage_cfg->multirect_index[pstate->stage][stage_idx] =
-   pstate->multirect_index;
+   pstate->pipe.multirect_index;
 
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
   state, pstate, stage_idx,
-  sspp_idx - SSPP_VIG0,
   format->base.pixel_format,
   fb ? fb->modifier : 0);
 
@@ -1227,7 +1226,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
+   pstates[cnt].pipe_id = 
to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
@@ -1500,7 +1499,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, 
void *data)
state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h);
seq_printf(s, "\tmultirect: mode: %d index: %d\n",
-   pstate->multirect_mode, pstate->multirect_index);
+   pstate->pipe.multirect_mode, 
pstate->pipe.multirect_index);
 
seq_puts(s, "\n");
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index c30f168b6c0a..13d9e04a5153 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -158,15 +158,11 @@ struct dpu_hw_pixel_ext {
  * @src_rect:  src ROI, caller takes into account the different operations
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
- * @index: index of the rectangle of SSPP
- * @mode:  parallel or time multiplex multirect mode
  */
 struct dpu_hw_sspp_cfg {
struct dpu_hw_fmt_layout layout;
struct drm_rect src_rect;
struct drm_rect dst_rect;
-   enum dpu_sspp_multirect_index index;
-   enum dpu_sspp_multirect_mode mode;
 };
 
 /**
@@ -201,6 +197,18 @@ struct dpu_hw_pipe_ts_cfg {
u64 time;
 };
 
+/**
+ * struct dpu_sw_pipe - software pipe description
+ * @sspp:  backing SSPP pipe
+ * @index: index of the rectangle of SSPP
+ * @mode:  parallel or time multiplex multirect mode
+ */
+struct dpu_sw_pipe {
+   struct dpu_hw_sspp *sspp;
+   enum dpu_sspp_multirect_index multirect_index;
+   enum dpu_sspp_multirect_mode multirect_mode;
+};
+
 /**
  * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
  * Caller must call the init function to get the pipe context for each pipe
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 10678f6502a2..ce726bec0c31 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -251,7 +251,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane 
*plane,
((src_width + 32) * fmt->bpp);
}
} else {
-   if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+   if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) 
{
total_fl = (fixed_buff_size / 2) * 2 /
((src_width + 32) * fmt->bpp);
   

[Freedreno] [PATCH v7 10/32] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill

2023-03-16 Thread Dmitry Baryshkov
Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
not be sure that the previous address is still valid.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 3030cd3b253a..0a43c5682b2b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
struct dpu_hw_sspp *ctx = pipe->sspp;
+   struct dpu_hw_sspp_cfg cfg;
u32 idx;
 
if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
return;
 
+   /* cleanup source addresses */
+   memset(&cfg, 0, sizeof(cfg));
+   ctx->ops.setup_sourceaddress(pipe, &cfg);
+
if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
pipe->multirect_index == DPU_SSPP_RECT_0)
DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
-- 
2.30.2



[Freedreno] [PATCH v7 05/32] drm/msm/dpu: move pipe_hw to dpu_plane_state

2023-03-16 Thread Dmitry Baryshkov
In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (variable, changes during runtime) rather
than part of a plane (ideally should be statically allocated during boot).

The sspp pointer is set at the dpu_plane_reset(), since this is the
function which allocates the state. Once we have fully virtual
plane<->SSPP relationship, the SSPP will be allocated dynamically in the
dpu_plane_atomic_check() function.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 107 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 2 files changed, 62 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d6518ef1beb2..546629232e3d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
 
enum dpu_sspp pipe;
 
-   struct dpu_hw_sspp *pipe_hw;
uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
struct drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u64 qos_lut;
u32 total_fl = 0, lut_usage;
@@ -310,7 +310,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
fmt ? (char *)&fmt->base.pixel_format : NULL,
pdpu->is_rt_pipe, total_fl, qos_lut);
 
-   pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+   pstate->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
 }
 
 /**
@@ -322,6 +322,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
struct drm_framebuffer *fb)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
const struct dpu_format *fmt = NULL;
u32 danger_lut, safe_lut;
 
@@ -361,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane 
*plane,
danger_lut,
safe_lut);
 
-   pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+   pstate->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
danger_lut, safe_lut);
 }
 
@@ -375,14 +376,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane 
*plane,
bool enable, u32 flags)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-   pipe_qos_cfg.creq_vblank = 
pdpu->pipe_hw->cap->sblk->creq_vblank;
+   pipe_qos_cfg.creq_vblank = 
pstate->hw_sspp->cap->sblk->creq_vblank;
pipe_qos_cfg.danger_vblank =
-   pdpu->pipe_hw->cap->sblk->danger_vblank;
+   pstate->hw_sspp->cap->sblk->danger_vblank;
pipe_qos_cfg.vblank_en = enable;
}
 
@@ -408,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
pipe_qos_cfg.danger_vblank,
pdpu->is_rt_pipe);
 
-   pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+   pstate->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
&pipe_qos_cfg);
 }
 
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane 
*plane,
struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
struct dpu_vbif_set_ot_params ot_params;
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
memset(&ot_params, 0, sizeof(ot_params));
-   ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-   ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+   ot_params.xin_id = pstate->hw_sspp->cap->xin_id;
+   ot_params.num = pstate->hw_sspp->idx - SSPP_NONE;
ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
ot_params.is_wfd = !pdpu->is_rt_pipe;
ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
ot_params.vbif_idx = VBIF_RT;
-   ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+   ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
ot_params.rd = true;
 
dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -446,14 +449,15 @@ static void _dpu_plane_set

[Freedreno] [PATCH v7 06/32] drm/msm/dpu: drop dpu_plane_pipe function

2023-03-16 Thread Dmitry Baryshkov
There no more need for the dpu_plane_pipe() function, crtc code can
access pstate->pipe_hw.idx directly.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 7 ---
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b1ec0c35947b..c059090e9479 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -432,7 +432,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
pstate = to_dpu_plane_state(state);
fb = state->fb;
 
-   sspp_idx = dpu_plane_pipe(plane);
+   sspp_idx = pstate->hw_sspp->idx;
set_bit(sspp_idx, fetch_active);
 
DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1227,7 +1227,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
pstates[cnt].dpu_pstate = dpu_pstate;
pstates[cnt].drm_pstate = pstate;
pstates[cnt].stage = pstate->normalized_zpos;
-   pstates[cnt].pipe_id = dpu_plane_pipe(plane);
+   pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
 
dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 546629232e3d..10678f6502a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1442,11 +1442,6 @@ static const struct drm_plane_helper_funcs 
dpu_plane_helper_funcs = {
.atomic_update = dpu_plane_atomic_update,
 };
 
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
-{
-   return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
uint32_t pipe, enum drm_plane_type type,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 08a4b6a99f51..25e261cabadc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,13 +59,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
-- 
2.30.2



[Freedreno] [PATCH v7 03/32] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c

2023-03-16 Thread Dmitry Baryshkov
As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
SSPP debugfs creation from dpu_plane to dpu_kms. We are going to break
the 1:1 correspondence between planes and SSPPs, so it makes no sense
anymore to create SSPP debugfs entries in dpu_plane.c

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 
 3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index bbff908e6dbe..c30f168b6c0a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,7 +388,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms,
  struct dentry *entry);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 681dd2e0c7e8..35194262e628 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t 
mode,
debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
 }
 
+static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
+{
+   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
+   int i;
+
+   if (IS_ERR(entry))
+   return;
+
+   for (i = SSPP_NONE; i < SSPP_MAX; i++) {
+   struct dpu_hw_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
+
+   if (!hw)
+   continue;
+
+   _dpu_hw_sspp_init_debugfs(hw, dpu_kms, entry);
+   }
+}
+
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
 {
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b054055f120b..2b0ebdd4c207 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1399,22 +1399,6 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane 
*plane, bool enable)
_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
-
-/* SSPP live inside dpu_plane private data only. Enumerate them here. */
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
*debugfs_root)
-{
-   struct drm_plane *plane;
-   struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
-
-   if (IS_ERR(entry))
-   return;
-
-   drm_for_each_plane(plane, dpu_kms->dev) {
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-   _dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
-   }
-}
 #endif
 
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
-- 
2.30.2



[Freedreno] [PATCH v7 00/32] drm/msm/dpu: wide planes support

2023-03-16 Thread Dmitry Baryshkov
This patchset brings in multirect usage to support using two SSPP
rectangles for a single plane. Full virtual planes support is omitted
from this pull request, it will come later (I'm at the final stages of
polishing and testing, will be posted today).

Changes since v6:
- Really fixed line width check for UBWC formats (Abhinav)
- Also dropped R0/R1/R_MAX previously used by
  dpu_plane_validate_multirect_v2()
- Explicitly enabled SmartDMA for SC7280 following Abhinav's testing
- Reapplied Abhinav's Tested-by tags with the # sc7280 comment

Changes since v5:
- Rephrased wide planes commit message
- Fixed line width check for UBWC formats (Abhinav)
- Also drop struct dpu_multirect_plane_states, unused now

Changes since v4:
- Incorporate two fixes and two cleanup patches from Abhinav

Changes since v3:

- moved if (!pipe->sspp) checks back to the calling site, the caller
  should know if there is a backing SSPP or not.
- Restored state_idx argument of trace_dpu_crtc_setup_mixer trace point
- Removed .smart_dma_rev from dpu_caps
- Added cleaning of multirect to _dpu_plane_atomic_disable()
- Per Abhinavs request split the SmartDMA enablement patch into the
  "verified by me" and "the rest of the platforms" patches, which is not
  supposed to be merged in. Users of other platforms are supposed to
  verify multirect support on their platforms and then send patches
  enabling SmartDMA for their SoC.
- Expanded several commit messages

Changes since v2:

- Renamed dpu_hw_pipe_cfg to dpu_hw_sspp_cfg
- Added a patch to clean up src add / layout for the solid fill planes
- Fixed several comments and commit messages which caused confusion
- Added documentation for new dpu_plane_state members
- Slightly reworked dpu_plane_atomic_check() to make it more logical and 
obvious.

Changes since v1 (which was ages ago):
- Rebased on top of 6.2-rc1
- Dropped the controversial _dpu_crtc_blend_setup() split patch
- Renamed dpu_hw_pipe to dpu_hw_sspp
- Other misc changes

Abhinav Kumar (2):
  drm/msm/dpu: log the multirect_index in _dpu_crtc_blend_setup_pipe
  drm/msm/dpu: remove unused dpu_plane_validate_multirect_v2 function

Dmitry Baryshkov (30):
  drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  drm/msm/dpu: move SSPP allocation to the RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid
fill
  drm/msm/dpu: move stride programming to
dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
  drm/msm/dpu: rename dpu_hw_sspp_cfg to dpu_sw_pipe_cfg
  drm/msm/dpu: drop src_split and multirect check from
dpu_crtc_atomic_check
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: drop redundant plane dst check from
dpu_crtc_atomic_check()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
and dpu_format
  drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  drm/msm/dpu: add dpu_hw_sspp_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rework dpu_plane_atomic_check()
  drm/msm/dpu: rework plane CSC setting
  drm/msm/dpu: rework static color fill code
  drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  drm/msm/dpu: add support for wide planes
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: enable SmartDMA for the rest of the platforms
  drm/msm/dpu: drop smart_dma_rev from dpu_caps

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 290 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |  10 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  20 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h|   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 169 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   | 111 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |  18 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 866 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  40 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c|  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h|  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  19 +-
 12 files changed, 718 insertions(+), 861 deletions(-)

-- 
2.30.2



[Freedreno] [PATCH v7 04/32] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout

2023-03-16 Thread Dmitry Baryshkov
The pipe's layout is not cached, corresponding data structure is zeroed
out each time in the dpu_plane_sspp_atomic_update(), right before the
call to _dpu_plane_set_scanout() -> dpu_format_populate_layout().

Drop plane_addr comparison against previous layout and corresponding
EAGAIN handling.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 +---
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index d95540309d4d..ec1001e10f4f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -918,8 +918,7 @@ int dpu_format_populate_layout(
struct drm_framebuffer *fb,
struct dpu_hw_fmt_layout *layout)
 {
-   uint32_t plane_addr[DPU_MAX_PLANES];
-   int i, ret;
+   int ret;
 
if (!fb || !layout) {
DRM_ERROR("invalid arguments\n");
@@ -940,9 +939,6 @@ int dpu_format_populate_layout(
if (ret)
return ret;
 
-   for (i = 0; i < DPU_MAX_PLANES; ++i)
-   plane_addr[i] = layout->plane_addr[i];
-
/* Populate the addresses given the fb */
if (DPU_FORMAT_IS_UBWC(layout->format) ||
DPU_FORMAT_IS_TILE(layout->format))
@@ -950,10 +946,6 @@ int dpu_format_populate_layout(
else
ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
 
-   /* check if anything changed */
-   if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
-   ret = -EAGAIN;
-
return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 2b0ebdd4c207..d6518ef1beb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,9 +476,7 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
int ret;
 
ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
-   if (ret == -EAGAIN)
-   DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
-   else if (ret)
+   if (ret)
DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
-- 
2.30.2



[Freedreno] [PATCH v7 02/32] drm/msm/dpu: move SSPP allocation to the RM

2023-03-16 Thread Dmitry Baryshkov
Follow the example of all other hw blocks and initialize SSPP blocks in
Resource Manager.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 22 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 12 
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5a4578ab62a6..b054055f120b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1275,8 +1275,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
/* this will destroy the states as well */
drm_plane_cleanup(plane);
 
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
kfree(pdpu);
}
 }
@@ -1482,14 +1480,10 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pdpu->pipe = pipe;
 
/* initialize underlying h/w driver */
-   pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
-   if (IS_ERR(pdpu->pipe_hw)) {
-   DPU_ERROR("[%u]SSPP init failed\n", pipe);
-   ret = PTR_ERR(pdpu->pipe_hw);
+   pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+   if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) 
{
+   DPU_ERROR("[%u]SSPP is invalid\n", pipe);
goto clean_plane;
-   } else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
-   DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-   goto clean_sspp;
}
 
format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1499,7 +1493,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
format_list, num_formats,
supported_format_modifiers, type, NULL);
if (ret)
-   goto clean_sspp;
+   goto clean_plane;
 
pdpu->catalog = kms->catalog;
 
@@ -1532,9 +1526,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pipe, plane->base.id);
return plane;
 
-clean_sspp:
-   if (pdpu && pdpu->pipe_hw)
-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
 clean_plane:
kfree(pdpu);
return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 66c1b70d244f..f4dda88a73f7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -8,6 +8,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_pingpong.h"
+#include "dpu_hw_sspp.h"
 #include "dpu_hw_intf.h"
 #include "dpu_hw_wb.h"
 #include "dpu_hw_dspp.h"
@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
dpu_hw_wb_destroy(rm->hw_wb[i]);
 
+   for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
+   dpu_hw_sspp_destroy(rm->hw_sspp[i]);
+
return 0;
 }
 
@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
}
 
+   for (i = 0; i < cat->sspp_count; i++) {
+   struct dpu_hw_sspp *hw;
+   const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
+
+   if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
+   DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
+   continue;
+   }
+
+   hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+   if (IS_ERR(hw)) {
+   rc = PTR_ERR(hw);
+   DPU_ERROR("failed sspp object creation: err %d\n", rc);
+   goto fail;
+   }
+   rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+   }
+
return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 59de72b381f9..d62c2edb2460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -21,6 +21,7 @@ struct dpu_global_state;
  * @hw_intf: array of intf hardware resources
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
  */
 struct dpu_rm {
struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -31,6 +32,7 @@ struct dpu_rm {
struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+   struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
 };
 
 /**
@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct 
dpu_rm *rm, enum dpu_wb wb_
return rm->hw_wb[wb_idx - W

[Freedreno] [PATCH v7 01/32] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)

2023-03-16 Thread Dmitry Baryshkov
For all hardware blocks except SSPP the corresponding struct is named
after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
change.

Reviewed-by: Abhinav Kumar 
Tested-by: Abhinav Kumar  # sc7280
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 49 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 53 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 
 3 files changed, 62 insertions(+), 60 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 4246ab0b3bee..3e65bfd65b62 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -136,7 +136,7 @@
 #define TS_CLK 1920
 
 
-static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
+static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
int s_id,
u32 *idx)
 {
@@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
enum dpu_sspp_multirect_index index,
enum dpu_sspp_multirect_mode mode)
 {
@@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
 }
 
-static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
 }
 
-static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
u32 mask, u8 en)
 {
u32 idx;
@@ -239,7 +239,7 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe 
*ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
const struct dpu_format *fmt, u32 flags,
enum dpu_sspp_multirect_index rect_mode)
 {
@@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe 
*ctx,
DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
 }
 
-static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
struct dpu_hw_pixel_ext *pe_ext)
 {
struct dpu_hw_blk_reg_map *c;
@@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe 
*ctx,
tot_req_pixels[3]);
 }
 
-static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *sspp,
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *sspp,
void *scaler_cfg)
 {
u32 idx;
@@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe 
*ctx,
sspp->layout.format);
 }
 
-static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
+static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 {
u32 idx;
 
@@ -447,8 +447,8 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe 
*ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *cfg,
+static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *cfg,
enum dpu_sspp_multirect_index rect_index)
 {
struct dpu_hw_blk_reg_map *c;
@@ -516,8 +516,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cfg *cfg,
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
+   struct dpu_hw_sspp_cfg *cfg,
enum dpu_sspp_multirect_index rect_mode)
 {
int i;
@@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct 
dpu_hw_pipe *ctx,
}
 }
 
-static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
const struct dpu_csc_cfg *data)
 {
u32 idx;
@@ -560,7 +560,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, 
enum
+static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, 
enum
dpu_

Re: [Freedreno] [RFC PATCH 1/2] drm/msm/dpu: add dsc helper functions

2023-03-16 Thread Abhinav Kumar




On 3/16/2023 9:03 AM, Dmitry Baryshkov wrote:

Hi,

[removed previous conversation]



Hi Dmitry and Abhinav,

Just wanted to follow up on this thread. I've gone over the MSM-specific
DSC params for DP and DSI and have found a few shared calculations and
variables between both DSI and DP paths:

- (as mentioned earlier in the thread) almost all the calculations in
dpu_dsc_populate_dsc_config() match dsi_populate_dsc_params() [1]. The
only difference in the math I'm seeing is initial_scale_value.


The value in dsi code is valid for initial_offset = 6144. Please use
the formula from the standard (= sde_dsc_populate_dsc_config) and add
it to drm_dsc_helper.c

If I remember correctly the last remaining item in
dsi_populate_dsc_params() (except mentioned initial_offset) was
line_buf_depth, see [3]. I'm not sure about setting it to bpc+1.
According to the standard it should come from a DSC decoder spec,
which means it should be set by the DSI panel driver or via
drm_dp_dsc_sink_line_buf_depth() in the case of DP output.


- dsc_extra_pclk_cycle_cnt and dce_bytes_per_line, which were introduced
in Kuogee's v1 DSC series [2], are used for DSI, DP, and the DPU timing
engine. dsc_extra_pclk_cycle_cnt is calculated based on pclk_per_line
(which is calculated differently between DP and DSI), but
dce_bytes_per_line is calculated the same way between DP and DSI.

To avoid having to duplicate math in 2 different places, I think it
would help to have these calculations in some msm_dsc_helper.c file. Any
thoughts on this?


dsc_extra_pclk_cycle_cnt and dce_bytes_per_line are used only in DPU
code, so they can stay in DPU driver.



They can stay in the dpu driver is fine but where?

Like Jessica wrote, this is computed and used in 3 places today :

1) DSI video engine computation
2) DP controller computation
3) timing engine programming

So either we have a helper in a common location somewhere so that these 
3 modules can call that helper and use it OR each module duplicates the 
computation code.


What should be the common location is the discussion here.

It cannot be dpu_encoder.c as the DSI/DP dont call into the encoder methods.



Thanks,

Jessica Zhang

[1]
https://elixir.bootlin.com/linux/v6.3-rc2/source/drivers/gpu/drm/msm/dsi/dsi_host.c#L1756

[2] https://patchwork.freedesktop.org/patch/519845/?series=113240&rev=1


[3] https://patchwork.freedesktop.org/patch/525441/?series=114472&rev=2





Re: [Freedreno] [RFC PATCH 1/2] drm/msm/dpu: add dsc helper functions

2023-03-16 Thread Dmitry Baryshkov
Hi,

[removed previous conversation]

>
> Hi Dmitry and Abhinav,
>
> Just wanted to follow up on this thread. I've gone over the MSM-specific
> DSC params for DP and DSI and have found a few shared calculations and
> variables between both DSI and DP paths:
>
> - (as mentioned earlier in the thread) almost all the calculations in
> dpu_dsc_populate_dsc_config() match dsi_populate_dsc_params() [1]. The
> only difference in the math I'm seeing is initial_scale_value.

The value in dsi code is valid for initial_offset = 6144. Please use
the formula from the standard (= sde_dsc_populate_dsc_config) and add
it to drm_dsc_helper.c

If I remember correctly the last remaining item in
dsi_populate_dsc_params() (except mentioned initial_offset) was
line_buf_depth, see [3]. I'm not sure about setting it to bpc+1.
According to the standard it should come from a DSC decoder spec,
which means it should be set by the DSI panel driver or via
drm_dp_dsc_sink_line_buf_depth() in the case of DP output.

> - dsc_extra_pclk_cycle_cnt and dce_bytes_per_line, which were introduced
> in Kuogee's v1 DSC series [2], are used for DSI, DP, and the DPU timing
> engine. dsc_extra_pclk_cycle_cnt is calculated based on pclk_per_line
> (which is calculated differently between DP and DSI), but
> dce_bytes_per_line is calculated the same way between DP and DSI.
>
> To avoid having to duplicate math in 2 different places, I think it
> would help to have these calculations in some msm_dsc_helper.c file. Any
> thoughts on this?

dsc_extra_pclk_cycle_cnt and dce_bytes_per_line are used only in DPU
code, so they can stay in DPU driver.

>
> Thanks,
>
> Jessica Zhang
>
> [1]
> https://elixir.bootlin.com/linux/v6.3-rc2/source/drivers/gpu/drm/msm/dsi/dsi_host.c#L1756
>
> [2] https://patchwork.freedesktop.org/patch/519845/?series=113240&rev=1

[3] https://patchwork.freedesktop.org/patch/525441/?series=114472&rev=2



-- 
With best wishes
Dmitry


Re: [Freedreno] [PATCH v5 01/10] dt-bindings: display/msm: dsi-controller-main: Fix deprecated QCM2290 compatible

2023-03-16 Thread Rob Herring


On Thu, 16 Mar 2023 09:51:07 +0100, Konrad Dybcio wrote:
> The qcom, prefix was missed previously. Fix it.
> 
> Fixes: 0c0f65c6dd44 ("dt-bindings: msm: dsi-controller-main: Add compatible 
> strings for every current SoC")
> Acked-by: Rob Herring 
> Reviewed-by: Marijn Suijten 
> Signed-off-by: Konrad Dybcio 
> ---
>  Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.example.dtb:
 dsi@5e94000: compatible: 'oneOf' conditional failed, one must be fixed:
['qcom,dsi-ctrl-6g-qcm2290'] is too short
'qcom,dsi-ctrl-6g-qcm2290' is not one of ['qcom,apq8064-dsi-ctrl', 
'qcom,msm8916-dsi-ctrl', 'qcom,msm8953-dsi-ctrl', 'qcom,msm8974-dsi-ctrl', 
'qcom,msm8996-dsi-ctrl', 'qcom,msm8998-dsi-ctrl', 'qcom,qcm2290-dsi-ctrl', 
'qcom,sc7180-dsi-ctrl', 'qcom,sc7280-dsi-ctrl', 'qcom,sdm660-dsi-ctrl', 
'qcom,sdm845-dsi-ctrl', 'qcom,sm8150-dsi-ctrl', 'qcom,sm8250-dsi-ctrl', 
'qcom,sm8350-dsi-ctrl', 'qcom,sm8450-dsi-ctrl', 'qcom,sm8550-dsi-ctrl']
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.example.dtb:
 dsi@5e94000: Unevaluated properties are not allowed ('compatible' was 
unexpected)
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.example.dtb:
 dsi@5e94000: compatible: 'oneOf' conditional failed, one must be fixed:
['qcom,dsi-ctrl-6g-qcm2290'] is too short
'qcom,dsi-ctrl-6g-qcm2290' is not one of ['qcom,apq8064-dsi-ctrl', 
'qcom,msm8916-dsi-ctrl', 'qcom,msm8953-dsi-ctrl', 'qcom,msm8974-dsi-ctrl', 
'qcom,msm8996-dsi-ctrl', 'qcom,msm8998-dsi-ctrl', 'qcom,qcm2290-dsi-ctrl', 
'qcom,sc7180-dsi-ctrl', 'qcom,sc7280-dsi-ctrl', 'qcom,sdm660-dsi-ctrl', 
'qcom,sdm845-dsi-ctrl', 'qcom,sm8150-dsi-ctrl', 'qcom,sm8250-dsi-ctrl', 
'qcom,sm8350-dsi-ctrl', 'qcom,sm8450-dsi-ctrl', 'qcom,sm8550-dsi-ctrl']
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/qcom,qcm2290-mdss.example.dtb:
 dsi@5e94000: Unevaluated properties are not allowed ('compatible' was 
unexpected)
From schema: 
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml

doc reference errors (make refcheckdocs):

See 
https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20230307-topic-dsi_qcm-v5-1-9d4235b77...@linaro.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.



Re: [Freedreno] [PATCH] drm: msm: adreno: Disable preemption on Adreno 510

2023-03-16 Thread Dmitry Baryshkov

On 15/03/2023 00:17, Adam Skladowski wrote:

Downstream driver appears to not support preemption on A510 target,
trying to use one make device slow and fill log with rings related errors.
Set num_rings to 1 to disable preemption.

Suggested-by: Dmitry Baryshkov 
Fixes: e20c9284c8f2 ("drm/msm/adreno: Add support for Adreno 510 GPU")
Signed-off-by: Adam Skladowski 


Reviewed-by: Dmitry Baryshkov 

--
With best wishes
Dmitry



Re: [Freedreno] [PATCH v10 01/15] dma-buf/dma-fence: Add deadline awareness

2023-03-16 Thread Jonas Ådahl
On Wed, Mar 15, 2023 at 09:19:49AM -0700, Rob Clark wrote:
> On Wed, Mar 15, 2023 at 6:53 AM Jonas Ådahl  wrote:
> >
> > On Fri, Mar 10, 2023 at 09:38:18AM -0800, Rob Clark wrote:
> > > On Fri, Mar 10, 2023 at 7:45 AM Jonas Ådahl  wrote:
> > > >
> > > > On Wed, Mar 08, 2023 at 07:52:52AM -0800, Rob Clark wrote:
> > > > > From: Rob Clark 
> > > > >
> > > > > Add a way to hint to the fence signaler of an upcoming deadline, such 
> > > > > as
> > > > > vblank, which the fence waiter would prefer not to miss.  This is to 
> > > > > aid
> > > > > the fence signaler in making power management decisions, like boosting
> > > > > frequency as the deadline approaches and awareness of missing 
> > > > > deadlines
> > > > > so that can be factored in to the frequency scaling.
> > > > >
> > > > > v2: Drop dma_fence::deadline and related logic to filter duplicate
> > > > > deadlines, to avoid increasing dma_fence size.  The fence-context
> > > > > implementation will need similar logic to track deadlines of all
> > > > > the fences on the same timeline.  [ckoenig]
> > > > > v3: Clarify locking wrt. set_deadline callback
> > > > > v4: Clarify in docs comment that this is a hint
> > > > > v5: Drop DMA_FENCE_FLAG_HAS_DEADLINE_BIT.
> > > > > v6: More docs
> > > > > v7: Fix typo, clarify past deadlines
> > > > >
> > > > > Signed-off-by: Rob Clark 
> > > > > Reviewed-by: Christian König 
> > > > > Acked-by: Pekka Paalanen 
> > > > > Reviewed-by: Bagas Sanjaya 
> > > > > ---
> > > >
> > > > Hi Rob!
> > > >
> > > > >  Documentation/driver-api/dma-buf.rst |  6 +++
> > > > >  drivers/dma-buf/dma-fence.c  | 59 
> > > > > 
> > > > >  include/linux/dma-fence.h| 22 +++
> > > > >  3 files changed, 87 insertions(+)
> > > > >
> > > > > diff --git a/Documentation/driver-api/dma-buf.rst 
> > > > > b/Documentation/driver-api/dma-buf.rst
> > > > > index 622b8156d212..183e480d8cea 100644
> > > > > --- a/Documentation/driver-api/dma-buf.rst
> > > > > +++ b/Documentation/driver-api/dma-buf.rst
> > > > > @@ -164,6 +164,12 @@ DMA Fence Signalling Annotations
> > > > >  .. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > :doc: fence signalling annotation
> > > > >
> > > > > +DMA Fence Deadline Hints
> > > > > +
> > > > > +
> > > > > +.. kernel-doc:: drivers/dma-buf/dma-fence.c
> > > > > +   :doc: deadline hints
> > > > > +
> > > > >  DMA Fences Functions Reference
> > > > >  ~~
> > > > >
> > > > > diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
> > > > > index 0de0482cd36e..f177c56269bb 100644
> > > > > --- a/drivers/dma-buf/dma-fence.c
> > > > > +++ b/drivers/dma-buf/dma-fence.c
> > > > > @@ -912,6 +912,65 @@ dma_fence_wait_any_timeout(struct dma_fence 
> > > > > **fences, uint32_t count,
> > > > >  }
> > > > >  EXPORT_SYMBOL(dma_fence_wait_any_timeout);
> > > > >
> > > > > +/**
> > > > > + * DOC: deadline hints
> > > > > + *
> > > > > + * In an ideal world, it would be possible to pipeline a workload 
> > > > > sufficiently
> > > > > + * that a utilization based device frequency governor could arrive 
> > > > > at a minimum
> > > > > + * frequency that meets the requirements of the use-case, in order 
> > > > > to minimize
> > > > > + * power consumption.  But in the real world there are many 
> > > > > workloads which
> > > > > + * defy this ideal.  For example, but not limited to:
> > > > > + *
> > > > > + * * Workloads that ping-pong between device and CPU, with 
> > > > > alternating periods
> > > > > + *   of CPU waiting for device, and device waiting on CPU.  This can 
> > > > > result in
> > > > > + *   devfreq and cpufreq seeing idle time in their respective 
> > > > > domains and in
> > > > > + *   result reduce frequency.
> > > > > + *
> > > > > + * * Workloads that interact with a periodic time based deadline, 
> > > > > such as double
> > > > > + *   buffered GPU rendering vs vblank sync'd page flipping.  In this 
> > > > > scenario,
> > > > > + *   missing a vblank deadline results in an *increase* in idle time 
> > > > > on the GPU
> > > > > + *   (since it has to wait an additional vblank period), sending a 
> > > > > signal to
> > > > > + *   the GPU's devfreq to reduce frequency, when in fact the 
> > > > > opposite is what is
> > > > > + *   needed.
> > > >
> > > > This is the use case I'd like to get some better understanding about how
> > > > this series intends to work, as the problematic scheduling behavior
> > > > triggered by missed deadlines has plagued compositing display servers
> > > > for a long time.
> > > >
> > > > I apologize, I'm not a GPU driver developer, nor an OpenGL driver
> > > > developer, so I will need some hand holding when it comes to
> > > > understanding exactly what piece of software is responsible for
> > > > communicating what piece of information.
> > > >
> > > > > + *
> > > > > + * To this end, deadline hint(s) can be set on a &dma_fence via 
> > >

[Freedreno] [PATCH v5 09/10] dt-bindings: display/msm: dsi-controller-main: Add SM6115

2023-03-16 Thread Konrad Dybcio
Add a compatible for the DSI on SM6115.

Acked-by: Rob Herring 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 .../devicetree/bindings/display/msm/dsi-controller-main.yaml   |  2 ++
 .../devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml  | 10 --
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index ecc89011bec4..c8884a84e73d 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -25,6 +25,7 @@ properties:
   - qcom,sc7280-dsi-ctrl
   - qcom,sdm660-dsi-ctrl
   - qcom,sdm845-dsi-ctrl
+  - qcom,sm6115-dsi-ctrl
   - qcom,sm8150-dsi-ctrl
   - qcom,sm8250-dsi-ctrl
   - qcom,sm8350-dsi-ctrl
@@ -350,6 +351,7 @@ allOf:
   contains:
 enum:
   - qcom,sdm845-dsi-ctrl
+  - qcom,sm6115-dsi-ctrl
 then:
   properties:
 clocks:
diff --git 
a/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml 
b/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml
index 2491cb100b33..b9f83088f370 100644
--- a/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml
+++ b/Documentation/devicetree/bindings/display/msm/qcom,sm6115-mdss.yaml
@@ -40,7 +40,13 @@ patternProperties:
 type: object
 properties:
   compatible:
-const: qcom,dsi-ctrl-6g-qcm2290
+oneOf:
+  - items:
+  - const: qcom,sm6115-dsi-ctrl
+  - const: qcom,mdss-dsi-ctrl
+  - description: Old binding, please don't use
+deprecated: true
+const: qcom,dsi-ctrl-6g-qcm2290
 
   "^phy@[0-9a-f]+$":
 type: object
@@ -114,7 +120,7 @@ examples:
 };
 
 dsi@5e94000 {
-compatible = "qcom,dsi-ctrl-6g-qcm2290";
+compatible = "qcom,sm6115-dsi-ctrl", "qcom,mdss-dsi-ctrl";
 reg = <0x05e94000 0x400>;
 reg-names = "dsi_ctrl";
 

-- 
2.39.2



[Freedreno] [PATCH v5 04/10] drm/msm/dsi: dsi_cfg: Deduplicate identical structs

2023-03-16 Thread Konrad Dybcio
Some structs were defined multiple times for no apparent reason.
Deduplicate them.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c | 93 +--
 1 file changed, 30 insertions(+), 63 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 6c192963c100..039f503233d7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -47,41 +47,32 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg 
= {
},
 };
 
-static const char * const dsi_8916_bus_clk_names[] = {
+static const char * const dsi_v1_3_1_clk_names[] = {
"mdp_core", "iface", "bus",
 };
 
-static const struct regulator_bulk_data msm8916_dsi_regulators[] = {
+static const struct regulator_bulk_data dsi_v1_3_1_regulators[] = {
{ .supply = "vdda", .init_load_uA = 10 },   /* 1.2 V */
{ .supply = "vddio", .init_load_uA = 10 },  /* 1.8 V */
 };
 
 static const struct msm_dsi_config msm8916_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
-   .regulator_data = msm8916_dsi_regulators,
-   .num_regulators = ARRAY_SIZE(msm8916_dsi_regulators),
-   .bus_clk_names = dsi_8916_bus_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names),
+   .regulator_data = dsi_v1_3_1_regulators,
+   .num_regulators = ARRAY_SIZE(dsi_v1_3_1_regulators),
+   .bus_clk_names = dsi_v1_3_1_clk_names,
+   .num_bus_clks = ARRAY_SIZE(dsi_v1_3_1_clk_names),
.io_start = {
{ 0x1a98000 },
},
 };
 
-static const char * const dsi_8976_bus_clk_names[] = {
-   "mdp_core", "iface", "bus",
-};
-
-static const struct regulator_bulk_data msm8976_dsi_regulators[] = {
-   { .supply = "vdda", .init_load_uA = 10 },   /* 1.2 V */
-   { .supply = "vddio", .init_load_uA = 10 },  /* 1.8 V */
-};
-
 static const struct msm_dsi_config msm8976_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
-   .regulator_data = msm8976_dsi_regulators,
-   .num_regulators = ARRAY_SIZE(msm8976_dsi_regulators),
-   .bus_clk_names = dsi_8976_bus_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names),
+   .regulator_data = dsi_v1_3_1_regulators,
+   .num_regulators = ARRAY_SIZE(dsi_v1_3_1_regulators),
+   .bus_clk_names = dsi_v1_3_1_clk_names,
+   .num_bus_clks = ARRAY_SIZE(dsi_v1_3_1_clk_names),
.io_start = {
{ 0x1a94000, 0x1a96000 },
},
@@ -107,10 +98,6 @@ static const struct msm_dsi_config msm8994_dsi_cfg = {
},
 };
 
-static const char * const dsi_8996_bus_clk_names[] = {
-   "mdp_core", "iface", "bus", "core_mmss",
-};
-
 static const struct regulator_bulk_data msm8996_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 18160 },/* 1.25 V */
{ .supply = "vcca", .init_load_uA = 17000 },/* 0.925 V */
@@ -121,8 +108,8 @@ static const struct msm_dsi_config msm8996_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
.regulator_data = msm8996_dsi_regulators,
.num_regulators = ARRAY_SIZE(msm8996_dsi_regulators),
-   .bus_clk_names = dsi_8996_bus_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_8996_bus_clk_names),
+   .bus_clk_names = dsi_6g_bus_clk_names,
+   .num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
.io_start = {
{ 0x994000, 0x996000 },
},
@@ -167,24 +154,20 @@ static const struct msm_dsi_config sdm660_dsi_cfg = {
},
 };
 
-static const char * const dsi_sdm845_bus_clk_names[] = {
+static const char * const dsi_v2_4_clk_names[] = {
"iface", "bus",
 };
 
-static const char * const dsi_sc7180_bus_clk_names[] = {
-   "iface", "bus",
-};
-
-static const struct regulator_bulk_data sdm845_dsi_regulators[] = {
+static const struct regulator_bulk_data dsi_v2_4_regulators[] = {
{ .supply = "vdda", .init_load_uA = 21800 },/* 1.2 V */
 };
 
 static const struct msm_dsi_config sdm845_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
-   .regulator_data = sdm845_dsi_regulators,
-   .num_regulators = ARRAY_SIZE(sdm845_dsi_regulators),
-   .bus_clk_names = dsi_sdm845_bus_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
+   .regulator_data = dsi_v2_4_regulators,
+   .num_regulators = ARRAY_SIZE(dsi_v2_4_regulators),
+   .bus_clk_names = dsi_v2_4_clk_names,
+   .num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
.io_start = {
{ 0xae94000, 0xae96000 },
},
@@ -198,32 +181,24 @@ static const struct msm_dsi_config sm8550_dsi_cfg = {
.io_offset = DSI_6G_REG_SHIFT,
.regulator_data = sm8550_dsi_regulators,
.num_regulators = ARRAY_SIZE(sm8550_dsi_regulators),
-   .bus_clk_names = dsi_sdm845_bus_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
+   .bus_clk_names = dsi_v2_4_clk_nam

[Freedreno] [PATCH v5 10/10] arm64: dts: qcom: sm6115: Use the correct DSI compatible

2023-03-16 Thread Konrad Dybcio
Use the non-deprecated, SoC-specific DSI compatible.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 arch/arm64/boot/dts/qcom/sm6115.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi 
b/arch/arm64/boot/dts/qcom/sm6115.dtsi
index fbd67d2c8d78..18c7eedff300 100644
--- a/arch/arm64/boot/dts/qcom/sm6115.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -1219,7 +1219,7 @@ opp-38400 {
};
 
mdss_dsi0: dsi@5e94000 {
-   compatible = "qcom,dsi-ctrl-6g-qcm2290";
+   compatible = "qcom,sm6115-dsi-ctrl", 
"qcom,mdss-dsi-ctrl";
reg = <0x0 0x05e94000 0x0 0x400>;
reg-names = "dsi_ctrl";
 

-- 
2.39.2



[Freedreno] [PATCH v5 07/10] drm/msm/dsi: Remove custom DSI config handling

2023-03-16 Thread Konrad Dybcio
Now that the only user is handled by common code, remove the option to
specify custom handlers through match data.

This is effectively a revert of commit:
5ae15e76271 ("drm/msm/dsi: Allow to specify dsi config as pdata")

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi.c  | 4 ++--
 drivers/gpu/drm/msm/dsi/dsi_host.c | 4 
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index f761973e4cba..baab79ab6e74 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -172,10 +172,10 @@ static int dsi_dev_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id dt_match[] = {
-   { .compatible = "qcom,mdss-dsi-ctrl", .data = NULL /* autodetect cfg */ 
},
+   { .compatible = "qcom,mdss-dsi-ctrl" },
 
/* Deprecated, don't use */
-   { .compatible = "qcom,dsi-ctrl-6g-qcm2290", .data = NULL },
+   { .compatible = "qcom,dsi-ctrl-6g-qcm2290" },
{}
 };
 
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 9cfb9e91bfea..961689a255c4 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -214,10 +214,6 @@ static const struct msm_dsi_cfg_handler *dsi_get_config(
int ret;
u32 major = 0, minor = 0;
 
-   cfg_hnd = device_get_match_data(dev);
-   if (cfg_hnd)
-   return cfg_hnd;
-
ahb_clk = msm_clk_get(msm_host->pdev, "iface");
if (IS_ERR(ahb_clk)) {
pr_err("%s: cannot get interface clock\n", __func__);

-- 
2.39.2



[Freedreno] [PATCH v5 08/10] dt-bindings: display/msm: dsi-controller-main: Fix deprecated compatible

2023-03-16 Thread Konrad Dybcio
The point of the previous cleanup was to disallow "qcom,mdss-dsi-ctrl"
alone. This however didn't quite work out and the property became
undocumented instead of deprecated. Fix that.

Fixes: 0c0f65c6dd44 ("dt-bindings: msm: dsi-controller-main: Add compatible 
strings for every current SoC")
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 .../devicetree/bindings/display/msm/dsi-controller-main.yaml   | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 2494817c1bd6..ecc89011bec4 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -31,10 +31,9 @@ properties:
   - qcom,sm8450-dsi-ctrl
   - qcom,sm8550-dsi-ctrl
   - const: qcom,mdss-dsi-ctrl
-  - items:
-  - enum:
-  - qcom,dsi-ctrl-6g-qcm2290
-  - const: qcom,mdss-dsi-ctrl
+  - enum:
+  - qcom,dsi-ctrl-6g-qcm2290
+  - qcom,mdss-dsi-ctrl # This should always come with an SoC-specific 
compatible
 deprecated: true
 
   reg:

-- 
2.39.2



[Freedreno] [PATCH v5 05/10] drm/msm/dsi: dsi_cfg: Merge SC7180 config into SDM845

2023-03-16 Thread Konrad Dybcio
The configs are identical, other than the number of *maximum* DSI
hosts allowed. This isn't an issue, unless somebody deliberately
tries to access the inexistent host by adding a dt node for it.

Remove the SC7180 struct and point the hw revision match to the
SDM845's one. On a note, this could have been done back when
7180 support was introduced.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 039f503233d7..03d98cbcc978 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -169,7 +169,7 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.bus_clk_names = dsi_v2_4_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
.io_start = {
-   { 0xae94000, 0xae96000 },
+   { 0xae94000, 0xae96000 }, /* SDM845 / SDM670 / SC7180 */
},
 };
 
@@ -188,17 +188,6 @@ static const struct msm_dsi_config sm8550_dsi_cfg = {
},
 };
 
-static const struct msm_dsi_config sc7180_dsi_cfg = {
-   .io_offset = DSI_6G_REG_SHIFT,
-   .regulator_data = dsi_v2_4_regulators,
-   .num_regulators = ARRAY_SIZE(dsi_v2_4_regulators),
-   .bus_clk_names = dsi_v2_4_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
-   .io_start = {
-   { 0xae94000 },
-   },
-};
-
 static const struct regulator_bulk_data sc7280_dsi_regulators[] = {
{ .supply = "vdda", .init_load_uA = 8350 }, /* 1.2 V */
 };
@@ -291,7 +280,7 @@ static const struct msm_dsi_cfg_handler dsi_cfg_handlers[] 
= {
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_0,
&sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_4_1,
-   &sc7180_dsi_cfg, &msm_dsi_6g_v2_host_ops},
+   &sdm845_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_5_0,
&sc7280_dsi_cfg, &msm_dsi_6g_v2_host_ops},
{MSM_DSI_VER_MAJOR_6G, MSM_DSI_6G_VER_MINOR_V2_6_0,

-- 
2.39.2



[Freedreno] [PATCH v5 06/10] drm/msm/dsi: Switch the QCM2290-specific compatible to index autodetection

2023-03-16 Thread Konrad Dybcio
Now that the logic can handle multiple sets of registers, move
the QCM2290 to the common logic and mark it deprecated. This allows us
to remove a couple of structs, saving some memory.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi.c |  5 +++--
 drivers/gpu/drm/msm/dsi/dsi_cfg.c | 20 ++--
 drivers/gpu/drm/msm/dsi/dsi_cfg.h |  3 ---
 3 files changed, 5 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c
index 31fdee2052be..f761973e4cba 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.c
+++ b/drivers/gpu/drm/msm/dsi/dsi.c
@@ -4,7 +4,6 @@
  */
 
 #include "dsi.h"
-#include "dsi_cfg.h"
 
 bool msm_dsi_is_cmd_mode(struct msm_dsi *msm_dsi)
 {
@@ -174,7 +173,9 @@ static int dsi_dev_remove(struct platform_device *pdev)
 
 static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,mdss-dsi-ctrl", .data = NULL /* autodetect cfg */ 
},
-   { .compatible = "qcom,dsi-ctrl-6g-qcm2290", .data = 
&qcm2290_dsi_cfg_handler },
+
+   /* Deprecated, don't use */
+   { .compatible = "qcom,dsi-ctrl-6g-qcm2290", .data = NULL },
{}
 };
 
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 03d98cbcc978..29ccd755cc2e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -169,7 +169,8 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.bus_clk_names = dsi_v2_4_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
.io_start = {
-   { 0xae94000, 0xae96000 }, /* SDM845 / SDM670 / SC7180 */
+   { 0xae94000, 0xae96000 }, /* SDM845 / SDM670 */
+   { 0x5e94000 }, /* QCM2290 / SM6115 / SM6125 / SM6375 */
},
 };
 
@@ -203,17 +204,6 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
},
 };
 
-static const struct msm_dsi_config qcm2290_dsi_cfg = {
-   .io_offset = DSI_6G_REG_SHIFT,
-   .regulator_data = dsi_v2_4_regulators,
-   .num_regulators = ARRAY_SIZE(dsi_v2_4_regulators),
-   .bus_clk_names = dsi_v2_4_clk_names,
-   .num_bus_clks = ARRAY_SIZE(dsi_v2_4_clk_names),
-   .io_start = {
-   { 0x5e94000 },
-   },
-};
-
 static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
.link_clk_set_rate = dsi_link_clk_set_rate_v2,
.link_clk_enable = dsi_link_clk_enable_v2,
@@ -304,9 +294,3 @@ const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 
major, u32 minor)
 
return cfg_hnd;
 }
-
-/*  Non autodetect configs */
-const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler = {
-   .cfg = &qcm2290_dsi_cfg,
-   .ops = &msm_dsi_6g_v2_host_ops,
-};
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
index 8772a3631ac1..91bdaf50bb1a 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.h
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.h
@@ -65,8 +65,5 @@ struct msm_dsi_cfg_handler {
 
 const struct msm_dsi_cfg_handler *msm_dsi_cfg_get(u32 major, u32 minor);
 
-/* Non autodetect configs */
-extern const struct msm_dsi_cfg_handler qcm2290_dsi_cfg_handler;
-
 #endif /* __MSM_DSI_CFG_H__ */
 

-- 
2.39.2



[Freedreno] [PATCH v5 02/10] drm/msm/dsi: Get rid of msm_dsi_config::num_dsi

2023-03-16 Thread Konrad Dybcio
In preparation for supporting multiple sets of possible base registers,
remove the num_dsi variable. We're comparing the io_start array contents
with the reg value from the DTS, so it will either match one of the
expected values or don't match against a zero (which we get from partial
array initialization).

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  | 13 -
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |  1 -
 drivers/gpu/drm/msm/dsi/dsi_host.c |  2 +-
 3 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 6d21f0b33411..4515f52b407a 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -22,7 +22,6 @@ static const struct msm_dsi_config apq8064_dsi_cfg = {
.bus_clk_names = dsi_v2_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_v2_bus_clk_names),
.io_start = { 0x470, 0x580 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_6g_bus_clk_names[] = {
@@ -42,7 +41,6 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = {
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
.io_start = { 0xfd922800, 0xfd922b00 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_8916_bus_clk_names[] = {
@@ -61,7 +59,6 @@ static const struct msm_dsi_config msm8916_dsi_cfg = {
.bus_clk_names = dsi_8916_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names),
.io_start = { 0x1a98000 },
-   .num_dsi = 1,
 };
 
 static const char * const dsi_8976_bus_clk_names[] = {
@@ -80,7 +77,6 @@ static const struct msm_dsi_config msm8976_dsi_cfg = {
.bus_clk_names = dsi_8976_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names),
.io_start = { 0x1a94000, 0x1a96000 },
-   .num_dsi = 2,
 };
 
 static const struct regulator_bulk_data msm8994_dsi_regulators[] = {
@@ -99,7 +95,6 @@ static const struct msm_dsi_config msm8994_dsi_cfg = {
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
.io_start = { 0xfd998000, 0xfd9a },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_8996_bus_clk_names[] = {
@@ -119,7 +114,6 @@ static const struct msm_dsi_config msm8996_dsi_cfg = {
.bus_clk_names = dsi_8996_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8996_bus_clk_names),
.io_start = { 0x994000, 0x996000 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_msm8998_bus_clk_names[] = {
@@ -138,7 +132,6 @@ static const struct msm_dsi_config msm8998_dsi_cfg = {
.bus_clk_names = dsi_msm8998_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_msm8998_bus_clk_names),
.io_start = { 0xc994000, 0xc996000 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_sdm660_bus_clk_names[] = {
@@ -156,7 +149,6 @@ static const struct msm_dsi_config sdm660_dsi_cfg = {
.bus_clk_names = dsi_sdm660_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sdm660_bus_clk_names),
.io_start = { 0xc994000, 0xc996000 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_sdm845_bus_clk_names[] = {
@@ -178,7 +170,6 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.bus_clk_names = dsi_sdm845_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
.io_start = { 0xae94000, 0xae96000 },
-   .num_dsi = 2,
 };
 
 static const struct regulator_bulk_data sm8550_dsi_regulators[] = {
@@ -192,7 +183,6 @@ static const struct msm_dsi_config sm8550_dsi_cfg = {
.bus_clk_names = dsi_sdm845_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sdm845_bus_clk_names),
.io_start = { 0xae94000, 0xae96000 },
-   .num_dsi = 2,
 };
 
 static const struct regulator_bulk_data sc7180_dsi_regulators[] = {
@@ -206,7 +196,6 @@ static const struct msm_dsi_config sc7180_dsi_cfg = {
.bus_clk_names = dsi_sc7180_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sc7180_bus_clk_names),
.io_start = { 0xae94000 },
-   .num_dsi = 1,
 };
 
 static const char * const dsi_sc7280_bus_clk_names[] = {
@@ -224,7 +213,6 @@ static const struct msm_dsi_config sc7280_dsi_cfg = {
.bus_clk_names = dsi_sc7280_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sc7280_bus_clk_names),
.io_start = { 0xae94000, 0xae96000 },
-   .num_dsi = 2,
 };
 
 static const char * const dsi_qcm2290_bus_clk_names[] = {
@@ -242,7 +230,6 @@ static const struct msm_dsi_config qcm2290_dsi_cfg = {
.bus_clk_names = dsi_qcm2290_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_qcm2290_bus_clk_names),
.io_start = { 0x5e94000 },
-   .num_dsi = 1,
 };
 
 static const struct msm_dsi_host_cfg_ops msm_dsi_v2_host_ops = {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.h 
b/drivers/gpu/drm/msm/dsi/

[Freedreno] [PATCH v5 03/10] drm/msm/dsi: Fix DSI index detection when version clash occurs

2023-03-16 Thread Konrad Dybcio
Currently, we allow for MAX_DSI entries in io_start to facilitate for
MAX_DSI number of DSI hosts at different addresses. The configuration
is matched against the DSI CTRL hardware revision read back from the
component. We need a way to resolve situations where multiple SoCs
with different register maps may use the same version of DSI CTRL. In
preparation to do so, make msm_dsi_config a 2d array where each entry
represents a set of configurations adequate for a given SoC.

This is totally fine to do, as the only differentiating factors
between same-version-different-SoCs configurations are the number of
DSI hosts (1 or 2, at least as of today) and the set of base registers.
The regulator setup is the same, because the DSI hardware is the same,
regardless of the SoC it was implemented in.

In addition to that, update the matching logic such that it will loop
over VARIANTS_MAX variants, making sure they are all taken into account.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  | 52 --
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |  5 +++-
 drivers/gpu/drm/msm/dsi/dsi_host.c | 10 
 3 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_cfg.c 
b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
index 4515f52b407a..6c192963c100 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_cfg.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_cfg.c
@@ -21,7 +21,9 @@ static const struct msm_dsi_config apq8064_dsi_cfg = {
.num_regulators = ARRAY_SIZE(apq8064_dsi_regulators),
.bus_clk_names = dsi_v2_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_v2_bus_clk_names),
-   .io_start = { 0x470, 0x580 },
+   .io_start = {
+   { 0x470, 0x580 },
+   },
 };
 
 static const char * const dsi_6g_bus_clk_names[] = {
@@ -40,7 +42,9 @@ static const struct msm_dsi_config msm8974_apq8084_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8974_apq8084_regulators),
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
-   .io_start = { 0xfd922800, 0xfd922b00 },
+   .io_start = {
+   { 0xfd922800, 0xfd922b00 },
+   },
 };
 
 static const char * const dsi_8916_bus_clk_names[] = {
@@ -58,7 +62,9 @@ static const struct msm_dsi_config msm8916_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8916_dsi_regulators),
.bus_clk_names = dsi_8916_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8916_bus_clk_names),
-   .io_start = { 0x1a98000 },
+   .io_start = {
+   { 0x1a98000 },
+   },
 };
 
 static const char * const dsi_8976_bus_clk_names[] = {
@@ -76,7 +82,9 @@ static const struct msm_dsi_config msm8976_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8976_dsi_regulators),
.bus_clk_names = dsi_8976_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8976_bus_clk_names),
-   .io_start = { 0x1a94000, 0x1a96000 },
+   .io_start = {
+   { 0x1a94000, 0x1a96000 },
+   },
 };
 
 static const struct regulator_bulk_data msm8994_dsi_regulators[] = {
@@ -94,7 +102,9 @@ static const struct msm_dsi_config msm8994_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8994_dsi_regulators),
.bus_clk_names = dsi_6g_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_6g_bus_clk_names),
-   .io_start = { 0xfd998000, 0xfd9a },
+   .io_start = {
+   { 0xfd998000, 0xfd9a },
+   },
 };
 
 static const char * const dsi_8996_bus_clk_names[] = {
@@ -113,7 +123,9 @@ static const struct msm_dsi_config msm8996_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8996_dsi_regulators),
.bus_clk_names = dsi_8996_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_8996_bus_clk_names),
-   .io_start = { 0x994000, 0x996000 },
+   .io_start = {
+   { 0x994000, 0x996000 },
+   },
 };
 
 static const char * const dsi_msm8998_bus_clk_names[] = {
@@ -131,7 +143,9 @@ static const struct msm_dsi_config msm8998_dsi_cfg = {
.num_regulators = ARRAY_SIZE(msm8998_dsi_regulators),
.bus_clk_names = dsi_msm8998_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_msm8998_bus_clk_names),
-   .io_start = { 0xc994000, 0xc996000 },
+   .io_start = {
+   { 0xc994000, 0xc996000 },
+   },
 };
 
 static const char * const dsi_sdm660_bus_clk_names[] = {
@@ -148,7 +162,9 @@ static const struct msm_dsi_config sdm660_dsi_cfg = {
.num_regulators = ARRAY_SIZE(sdm660_dsi_regulators),
.bus_clk_names = dsi_sdm660_bus_clk_names,
.num_bus_clks = ARRAY_SIZE(dsi_sdm660_bus_clk_names),
-   .io_start = { 0xc994000, 0xc996000 },
+   .io_start = {
+   { 0xc994000, 0xc996000 },
+   },
 };
 
 static const char * const dsi_sdm845_bus_clk_names[] = {
@@ -169,7 +185,9 @@ static const struct msm_dsi_config sdm845_dsi_cfg = {
.num_regulator

[Freedreno] [PATCH v5 01/10] dt-bindings: display/msm: dsi-controller-main: Fix deprecated QCM2290 compatible

2023-03-16 Thread Konrad Dybcio
The qcom, prefix was missed previously. Fix it.

Fixes: 0c0f65c6dd44 ("dt-bindings: msm: dsi-controller-main: Add compatible 
strings for every current SoC")
Acked-by: Rob Herring 
Reviewed-by: Marijn Suijten 
Signed-off-by: Konrad Dybcio 
---
 Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index e75a3efe4dac..2494817c1bd6 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -33,7 +33,7 @@ properties:
   - const: qcom,mdss-dsi-ctrl
   - items:
   - enum:
-  - dsi-ctrl-6g-qcm2290
+  - qcom,dsi-ctrl-6g-qcm2290
   - const: qcom,mdss-dsi-ctrl
 deprecated: true
 

-- 
2.39.2



[Freedreno] [PATCH v5 00/10] Fix DSI host idx detection on HW revision clash

2023-03-16 Thread Konrad Dybcio
v4 -> v5:
- Drop superfluous items: level in [8/10]
- Remove the header define for the qcm2290 config in [6/10] instead of
  [7/10]
- Pick up tags

v4: 
https://lore.kernel.org/r/20230307-topic-dsi_qcm-v4-0-54b489818...@linaro.org

v3 -> v4:
- Use the shiny new compatible in the 6115 bindings example [9/10]
- Remove the leftover include and header definition [6, 7/10]
- Deduplicate the qcm2290 clks/regs in the common deduplication commit
  instead of doing it separately
- Pick up tags
- Rebase on next-20230314 (nothing seems to have changed fwiw)

v3: 
https://lore.kernel.org/r/20230307-topic-dsi_qcm-v3-0-8bd7e1add...@linaro.org

v2 -> v3:
- Merge with [1], I should have done that earlier..
  - Squash 6115 compatible patches into one
- Pick up tags (except Rob's ack in 6115 compatible addition, as it was changed)
- Use b4 (sorry if you got an incomplete set of messages before..)

[1] 
https://lore.kernel.org/linux-arm-msm/145066db-5723-6baa-237d-7c2b8fd47...@linaro.org/
v2: 
https://lore.kernel.org/linux-arm-msm/20230213121012.1768296-1-konrad.dyb...@linaro.org/

v1 -> v2:
- squash the 2d-array-ification and fixing up the logic into one patch
- drop num_variants, loop over VARIANTS_MAX*DSI_MAX unconditionally
- drop inadequate Fixes: tags
- pick up rbs

v1: 
https://lore.kernel.org/linux-arm-msm/2023025110.1462920-1-konrad.dyb...@linaro.org/

Some DSI host versions are implemented on multiple SoCs which use
vastly different register maps. This messes with our current
assumptions of being able to map {dsi0, dsi1} to {reg0, reg1}.
Solve that by adding a way of specifying multiple sets of base
registers and try comparing them against the register specified in DT
until we find a match.

This removes the need for the QCM2290-specific compatible which was
used in the SM6115 DT (which uses DSIv2.4.1, just like SC7180).
The series also takes care of that.

Tested on SM6115P Lenovo Tab P11 and SM8350 PDX215

Signed-off-by: Konrad Dybcio 
---
Konrad Dybcio (10):
  dt-bindings: display/msm: dsi-controller-main: Fix deprecated QCM2290 
compatible
  drm/msm/dsi: Get rid of msm_dsi_config::num_dsi
  drm/msm/dsi: Fix DSI index detection when version clash occurs
  drm/msm/dsi: dsi_cfg: Deduplicate identical structs
  drm/msm/dsi: dsi_cfg: Merge SC7180 config into SDM845
  drm/msm/dsi: Switch the QCM2290-specific compatible to index autodetection
  drm/msm/dsi: Remove custom DSI config handling
  dt-bindings: display/msm: dsi-controller-main: Fix deprecated compatible
  dt-bindings: display/msm: dsi-controller-main: Add SM6115
  arm64: dts: qcom: sm6115: Use the correct DSI compatible

 .../bindings/display/msm/dsi-controller-main.yaml  |   9 +-
 .../bindings/display/msm/qcom,sm6115-mdss.yaml |  10 +-
 arch/arm64/boot/dts/qcom/sm6115.dtsi   |   2 +-
 drivers/gpu/drm/msm/dsi/dsi.c  |   7 +-
 drivers/gpu/drm/msm/dsi/dsi_cfg.c  | 161 -
 drivers/gpu/drm/msm/dsi/dsi_cfg.h  |   9 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c |  14 +-
 7 files changed, 84 insertions(+), 128 deletions(-)
---
base-commit: ec0fa9a0a6fac454745c930bdb8619d0a354bac9
change-id: 20230307-topic-dsi_qcm-5cd03c230f8f

Best regards,
-- 
Konrad Dybcio 



Re: [Freedreno] [PATCH v4 02/14] dt-bindings: display/msm/gmu: Add GMU wrapper

2023-03-16 Thread Krzysztof Kozlowski
On 14/03/2023 16:28, Konrad Dybcio wrote:
> The "GMU Wrapper" is Qualcomm's name for "let's treat the GPU blocks
> we'd normally assign to the GMU as if they were a part of the GMU, even
> though they are not". It's a (good) software representation of the GMU_CX
> and GMU_GX register spaces within the GPUSS that helps us programatically
> treat these de-facto GMU-less parts in a way that's very similar to their
> GMU-equipped cousins, massively saving up on code duplication.
> 
> The "wrapper" register space was specifically designed to mimic the layout
> of a real GMU, though it rather obviously does not have the M3 core et al.
> 
> To sum it all up, the GMU wrapper is essentially a register space within
> the GPU, which Linux sees as a dumbed-down regular GMU: there's no clocks,
> interrupts, multiple reg spaces, iommus and OPP. Document it.
> 
> Signed-off-by: Konrad Dybcio 
> ---
>  .../devicetree/bindings/display/msm/gmu.yaml   | 49 
> --
>  1 file changed, 37 insertions(+), 12 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/display/msm/gmu.yaml 
> b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> index ab14e81cb050..021373e686e1 100644
> --- a/Documentation/devicetree/bindings/display/msm/gmu.yaml
> +++ b/Documentation/devicetree/bindings/display/msm/gmu.yaml
> @@ -19,16 +19,18 @@ description: |
>  
>  properties:
>compatible:
> -items:
> -  - pattern: '^qcom,adreno-gmu-6[0-9][0-9]\.[0-9]$'
> -  - const: qcom,adreno-gmu
> +oneOf:
> +  - items:
> +  - pattern: '^qcom,adreno-gmu-6[0-9][0-9]\.[0-9]$'
> +  - const: qcom,adreno-gmu
> +  - const: qcom,adreno-gmu-wrapper
>  
>reg:
> -minItems: 3
> +minItems: 1
>  maxItems: 4
>  
>reg-names:
> -minItems: 3
> +minItems: 1
>  maxItems: 4
>  
>clocks:
> @@ -44,7 +46,6 @@ properties:
>- description: GMU HFI interrupt
>- description: GMU interrupt
>  
> -
>interrupt-names:
>  items:
>- const: hfi
> @@ -72,14 +73,8 @@ required:
>- compatible
>- reg
>- reg-names
> -  - clocks
> -  - clock-names
> -  - interrupts
> -  - interrupt-names
>- power-domains
>- power-domain-names
> -  - iommus
> -  - operating-points-v2
>  
>  additionalProperties: false
>  
> @@ -216,6 +211,27 @@ allOf:
>  - const: cxo
>  - const: axi
>  - const: memnoc

Blank line (you added such between ifs in previous patch)

Reviewed-by: Krzysztof Kozlowski 

Best regards,
Krzysztof