Re: [PATCH 03/21] drm/msm/dsi: pass the right width to dsc

2024-09-03 Thread Jun Nie
Marijn Suijten  于2024年9月3日周二 18:12写道:
>
> On 2024-08-29 18:17:32, Jun Nie wrote:
> > Data width for dsc engine is aligned with pipe, not with whole screen
> > width. Because the width may be halved in DSI bonded case.
> >
> > The dsc width is not related to the timing with back front porch in
> > later stage, so update dsc timing earlier.
> >
> > Signed-off-by: Jun Nie 
>
> I already sent a patch for this:
> https://lore.kernel.org/linux-arm-msm/20240417-drm-msm-initial-dualpipe-dsc-fixes-v1-2-78ae3ee9a...@somainline.org/
>
> And then came up with a better solution, outlined in:
> https://lore.kernel.org/linux-arm-msm/7fqwkryeumkt7zxsec6va7ys22nfs3tr4rrcz323extdz3f6zv@w4uu2lk4uh7v/
>
> Would you mind dropping this patch so that I can send a better solution?

Sure. I am happy with a better solution from you.
>
> > ---
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 13 ++---
> >  1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> > b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index 7a4d9c071be5a..5abade8f26b88 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -953,7 +953,7 @@ static void dsi_timing_setup(struct msm_dsi_host 
> > *msm_host, bool is_bonded_dsi)
> >   return;
> >   }
> >
> > - dsc->pic_width = mode->hdisplay;
> > + dsc->pic_width = hdisplay;
>
> The other part of this already happened in patch 02/21?
>
> - Marijn
>
Patch 02/21 is just for parameter validation, not directly related to
this patch.

-Jun


Re: [PATCH 18/21] drm/msm/dpu: blend pipes by left and right

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:51写道:
>
> On Thu, 29 Aug 2024 at 13:21, Jun Nie  wrote:
> >
> > Blend pipes by left and right. The first 2 pipes are for
> > left half screen and the later 2 pipes are for right in quad
> > pipe case.
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 13 +++--
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 +++---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c  | 19 +--
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h  |  4 +++-
> >  4 files changed, 38 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 3b3cd17976082..8fd56f8f2851f 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -574,8 +574,17 @@ static void _dpu_crtc_blend_setup(struct drm_crtc 
> > *crtc)
> > mixer[i].mixer_op_mode,
> > ctl->idx - CTL_0);
> >
> > -   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
> > -   &stage_cfg);
> > +   /*
> > +* call dpu_hw_ctl_setup_blendstage() to blend layers per 
> > stage cfg.
> > +* There is 4 mixers at most. The first 2 are for the left 
> > half, and
> > +* the later 2 are for the right half.
> > +*/
> > +   if (cstate->num_mixers == 4 && i >= 2)
> > +   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
> > +   &stage_cfg, true);
> > +   else
> > +   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
> > +   &stage_cfg, false);
> > }
> >  }
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 76793201b984e..5d927f23e35b2 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -2049,9 +2049,13 @@ static void dpu_encoder_helper_reset_mixers(struct 
> > dpu_encoder_phys *phys_enc)
> > if (phys_enc->hw_ctl->ops.update_pending_flush_mixer)
> > 
> > phys_enc->hw_ctl->ops.update_pending_flush_mixer(ctl, hw_mixer[i]->idx);
> >
> > -   /* clear all blendstages */
> > -   if (phys_enc->hw_ctl->ops.setup_blendstage)
> > -   phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
> > hw_mixer[i]->idx, NULL);
> > +   /* clear all blendstages in both left and right */
> > +   if (phys_enc->hw_ctl->ops.setup_blendstage) {
> > +   phys_enc->hw_ctl->ops.setup_blendstage(ctl,
> > +   hw_mixer[i]->idx, NULL, false);
> > +   phys_enc->hw_ctl->ops.setup_blendstage(ctl,
> > +   hw_mixer[i]->idx, NULL, true);
> > +   }
> > }
> >  }
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> > index 602dfad127c2a..2072d18520326 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> > @@ -478,12 +478,13 @@ static const struct ctl_blend_config 
> > ctl_blend_config[][2] = {
> >  };
> >
> >  static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
> > -   enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
> > +   enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg, bool right)
> >  {
> > struct dpu_hw_blk_reg_map *c = &ctx->hw;
> > u32 mix, ext, mix_ext;
> > u32 mixercfg[5] = { 0 };
> > int i, j;
> > +   int pipe_start, pipe_end;
> > int stages;
> > int pipes_per_stage;
> >
> > @@ -502,13 +503,27 @@ static void dpu_hw_ctl_setup_blendstage(struct 
> > dpu_hw_ctl *ctx,
> > if (!stage_cfg)
> > goto exit;
> >
> > +   /*
> > +* For quad pipe case, blend pipes in right side separately. 
> > Otherwise,
> > +* all content is on the left half by defaut (no splitting case).
> > +*/
> > +   if (!right) {
>
> I th

Re: [PATCH 14/21] drm/msm/dpu: Support quad-pipe in SSPP checking

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:38写道:
>
> > @@ -1033,13 +1030,10 @@ static int dpu_plane_atomic_check(struct drm_plane 
> > *plane,
> > return -E2BIG;
> > }
> >
> > -   /*
> > -* Use multirect for wide plane. We do not support dynamic
> > -* assignment of SSPPs, so we know the configuration.
> > -*/
> > pipe->multirect_index = DPU_SSPP_RECT_0;
> > pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> >
> > +   r_pipe->sspp = pipe->sspp;
>
> NAK
>
I do not understand what's your point here. If multi-rectangle mode is
used, the 2 sw_pipe share a
SSPP structure. Otherwise the right half of mixer pair does not work
and no display on that side,
because there is no SSPP to handle in r_pipe setup.

>
> --
> With best wishes
> Dmitry


Re: [PATCH 13/21] drm/msm/dpu: Support quad pipe in header files

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:30写道:
>
> On Thu, 29 Aug 2024 at 13:20, Jun Nie  wrote:
> >
> > Support 4 pipes and their configs at most. They are for 2 SSPP
> > and their multi-rect mode. Because one SSPP can co-work with
> > 2 mixer at most, 2 pair of mixer are needed for 2 SSPP in quad-
> > pipe case. So 2 mixer configs are needed in quad-pipe case.
>
> As you wrote this is based (depends?) on the virtual planes, then you
> know that the code already uses either one or two SSPP blocks to drive
> one sw_pipe. I'm not sure what do you mean by "2 mixer configs". There
> are 4 LMs and 4 mixer configurations in the quad-pipe case. The commit
> message is thus misleading.

This patch set depends on the virtual plane patch set. The mixer config is
not a proper term per your response. It is from DPU2 branch. Maybe
clip_config is a better term for this. The config is used to split the plane
into 2 mixers pairs and 2 DSI interface with 2 halves of full screen.

>
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  2 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 11 ++-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 30 
> > +
> >  3 files changed, 33 insertions(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > index a2eff36a2224c..424725303ccad 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > @@ -32,7 +32,7 @@
> >  #define DPU_MAX_PLANES 4
> >  #endif
> >
> > -#define PIPES_PER_STAGE2
> > +#define PIPES_PER_STAGE4
> >  #ifndef DPU_MAX_DE_CURVES
> >  #define DPU_MAX_DE_CURVES  3
> >  #endif
> > 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 fc54625ae5d4f..ae6beff2c294b 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> > @@ -143,11 +143,20 @@ struct dpu_hw_pixel_ext {
> >   * such as decimation, flip etc to program this field
> >   * @dest_rect: destination ROI.
> >   * @rotation: simplified drm rotation hint
> > + * @visible: mark this cfg is valid
>
> So is it valid or visible?
Yeah, valid is better than visible.
>
> > + * @mxcfg_id: mixer config ID for left or right half screen.
> > + * We have single SSPP, dual SSPP, single SSPP+multi_rect or 
> > dual
> > + * SSPP+multi_rect case. mxcfg_id mark current pipe will use
> > + * which mixer cfg. The first mxcfg is for the left half of 
> > screen,
> > + * the 2nd mxcfg is for the right half screen. The heading cfg 
> > may
> > + * be skipped by pipe with the first mxcfg_id = 1 if the plane 
> > is
> > + * only displayed in the right side, thus SSPP goes to later 
> > mixers.
>
> too long description for an unreadable name.

Maybe the clip_id is better per above discussion?
>
> >   */
> >  struct dpu_sw_pipe_cfg {
> > struct drm_rect src_rect;
> > struct drm_rect dst_rect;
> > -   unsigned int rotation;
> > +   unsigned int rotation, mxcfg_id;
> > +   bool visible;
> >  };
> >
> >  /**
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > index e225d5baceb09..9e79cf9eba264 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > @@ -14,14 +14,30 @@
> >  #include "dpu_hw_mdss.h"
> >  #include "dpu_hw_sspp.h"
> >
> > +/**
> > + * Max number of mixer configs. Because we support 4 pipes at most,
> > + * the 4 pipes are with 2 SSPP and their multi-rect mode. While one
>
> Or 4 SSPPs. Or 3 SSPPs. Or even a single SSPP if it doesn't cover the
> whole screen.
>
> I'm really sorry to say, but I can not understand this text.

Yeah, lots of usage cases are not mentioned here. It just describe how the
config number come from. It should be the number for screen clip rectangle
in a full screen.

>
> > + * SSPP can co-work with 2 mixer at most, then 2 pair of mixer are
> > + * needed for 2 SSPP in quad-pipe case. Thus 2 mixer configs are
> > + * needed in quad-pipe case.
> > + */
> > +#define MIX_CFGS_IN_CRTC 2
> > +
> >  /**
>

Re: [PATCH 10/21] drm/msm/dpu: fix lm number counter for quad-pipe

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:17写道:
>
> On Thu, 29 Aug 2024 at 13:20, Jun Nie  wrote:
> >
> > Add the case to reserve multiple pair mixer for high resolution
>
> I think you already know what is missing here.

Add the case to reserve multiple pair mixer for high resolution. Current
code only support one pair of mixer usage case. To support quad-pipe
usage case, multiple pair mixers are needed.

>
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 +++---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 8 +++-
> >  2 files changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 33cfd94badaba..f57725ad494d2 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -54,7 +54,7 @@
> >  #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
> > (MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
> >
> > -#define MAX_CHANNELS_PER_ENC 2
> > +#define MAX_CHANNELS_PER_ENC 4
> >
> >  #define IDLE_SHORT_TIMEOUT 1
> >
> > @@ -2029,8 +2029,8 @@ static void dpu_encoder_helper_reset_mixers(struct 
> > dpu_encoder_phys *phys_enc)
> > struct dpu_hw_mixer_cfg mixer;
> > int i, num_lm;
> > struct dpu_global_state *global_state;
> > -   struct dpu_hw_blk *hw_lm[2];
> > -   struct dpu_hw_mixer *hw_mixer[2];
> > +   struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
> > +   struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
> > struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
> >
> > memset(&mixer, 0, sizeof(mixer));
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > index e219d706610c2..77d7ff789346e 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> > @@ -306,7 +306,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> > if (!rm->mixer_blks[i])
> > continue;
> >
> > -   lm_count = 0;
> > +   /*
> > +* Clear the last bit to drop the previous primary mixer if
> > +* fail to find its peer.
> > +*/
> > +   lm_count &= 0xfe;
> > lm_idx[lm_count] = i;
> >
> > if (!_dpu_rm_check_lm_and_get_connected_blks(rm, 
> > global_state,
> > @@ -353,6 +357,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
> >
> > trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
> >  pp_idx[i] + PINGPONG_0);
> > +   DPU_DEBUG("reserve lm[%d]:%d, pp_idx[%d]:%d, dspp[%d]:%d 
> > for enc_id %d\n",
> > + i, lm_idx[i], i, pp_idx[i], i, dspp_idx[i], 
> > enc_id);
> > }
> >
> > return 0;
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH 09/21] drm/msm/dpu: request more mixer for 4K+ DSC case

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:12写道:
>
> On Thu, 29 Aug 2024 at 13:20, Jun Nie  wrote:
> >
> > request more mixer for the case that hdisplay exceeding 4096
> > and DSC enabled.
>
> This doesn't seem to match the code. And it misses the _reason_ to do it.

Right. The DSC limitation should be 2560. And the reason is to support 4:4:2
quad-pipe topology. Because we prefer to use 4 layer mixer for dual DSI case.
The resolution is always higher and more DSC is power optimal. That's my
understanding.

> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 
> >  1 file changed, 20 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 05b203be2a9bc..33cfd94badaba 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -59,6 +59,7 @@
> >  #define IDLE_SHORT_TIMEOUT 1
> >
> >  #define MAX_HDISPLAY_SPLIT 1080
> > +#define MAX_HDISPLAY_DSC_SPLIT 2560
> >
> >  /* timeout in frames waiting for frame done */
> >  #define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
> > @@ -588,15 +589,19 @@ static struct msm_display_topology 
> > dpu_encoder_get_topology(
> >
> > /* Datapath topology selection
> >  *
> > -* Dual display
> > +* Dual display without DSC
> >  * 2 LM, 2 INTF ( Split display using 2 interfaces)
> >  *
> > +* Dual display with DSC
> > +* 4 LM, 2 INTF ( Split display using 2 interfaces)
>
> This doesn't match the code
>
Yeah, just use 4:4:2 case for DSC+dualDSI case is a simpler logic. I
can skip the DSC limitation
test in next version.


Re: [PATCH 07/21] drm/msm/dpu: Support dynamic DSC number

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:10写道:
>
> On Thu, 29 Aug 2024 at 13:20, Jun Nie  wrote:
> >
> > Do not assume DSC number as 2. Because there are 4 DSC in
> > quad pipe case.
>
> Please expand the commit message. You prefer brevity, but your
> comments lack clarifications.

Is below message OK?

Current DSC number is fixed to 2 for any DSC usage case. While there are
more usage case that involve different number of DSC engine, such 4 in
quad-pipe case with bonded-DSI scenario. So retrieve the real number with
this change.

>
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 6bdd9c21ff3ed..05b203be2a9bc 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -553,9 +553,9 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder 
> > *drm_enc)
> > if (dpu_enc->phys_encs[i])
> > intf_count++;
> >
> > -   /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
> > +   /* DSC and mixer are mapped 1:1, so reuse the mixer number */
>
> Why? DSCmerge is a valid topology even if it is not supported yet.

DSC merge is already supported in 2:2:1 topology without this patch
set. This change
is to get real DSC number in 4:4:2 topology, so that DSC merge can be
enabled for the
case.

>
> > if (dpu_enc->dsc)
> > -   num_dsc = 2;
> > +   num_dsc = dpu_crtc_get_lm_num(drm_enc->crtc->state);
> >
> > return (num_dsc > 0) && (num_dsc > intf_count);
> >  }
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH 06/21] drm/msm/dpu: Add utility to get mixer number

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 19:07写道:
>
> On Thu, 29 Aug 2024 at 13:19, Jun Nie  wrote:
> >
> > Add utility to get mixer number via CRTC handler
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 +++
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 5 +
> >  2 files changed, 12 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 7d0fff9472441..a27e39c525d1a 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -1306,6 +1306,13 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
> > return 0;
> >  }
> >
> > +unsigned int dpu_crtc_get_lm_num(const struct drm_crtc_state *state)
> > +{
> > +   struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
> > +
> > +   return cstate->num_mixers;
> > +}
>
> Merge with the user

OK.


>
> > +
> >  #ifdef CONFIG_DEBUG_FS
> >  static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
> >  {
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > index b26d5fe40c721..701c35803633d 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> > @@ -301,5 +301,10 @@ static inline enum dpu_crtc_client_type 
> > dpu_crtc_get_client_type(
> >  }
> >
> >  void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
> > +/**
> > + * dpu_crtc_get_lm_num - Get mixer number in this CRTC pipeline
> > + * @crtc: Pointer to drm crtc object
> > + */
>
> Move kerneldoc before the function implementation so that W=1 can check it.


>
> > +unsigned int dpu_crtc_get_lm_num(const struct drm_crtc_state *state);
> >
> >  #endif /* _DPU_CRTC_H_ */
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH 03/21] drm/msm/dsi: pass the right width to dsc

2024-09-03 Thread Jun Nie
Dmitry Baryshkov  于2024年8月29日周四 18:57写道:
>
> On Thu, 29 Aug 2024 at 13:19, Jun Nie  wrote:
> >
> > Data width for dsc engine is aligned with pipe, not with whole screen
> > width. Because the width may be halved in DSI bonded case.
>
> Can't really parse this.

Please forgive me for my bad English. Is below words better?

Data width for DSC timing is aligned with the width that goes to a DSI
interface, not with whole screen width. For bonded-DSI case, the
width for DSC timing is half width of whole screen.
>
> >
> > The dsc width is not related to the timing with back front porch in
> > later stage, so update dsc timing earlier.
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 13 ++---
> >  1 file changed, 6 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> > b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index 7a4d9c071be5a..5abade8f26b88 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -953,7 +953,7 @@ static void dsi_timing_setup(struct msm_dsi_host 
> > *msm_host, bool is_bonded_dsi)
> > return;
> > }
> >
> > -   dsc->pic_width = mode->hdisplay;
> > +   dsc->pic_width = hdisplay;
> > dsc->pic_height = mode->vdisplay;
> > DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
>
> Two separate commits

OK. Will split it.

>
> >
> > @@ -964,6 +964,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
> > *msm_host, bool is_bonded_dsi)
> > if (ret)
> > return;
> >
> > +   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
> > +   dsi_update_dsc_timing(msm_host, false, hdisplay);
> > +   else
> > +   dsi_update_dsc_timing(msm_host, true, hdisplay);
> > +
> > /*
> >  * DPU sends 3 bytes per pclk cycle to DSI. If widebus is
> >  * enabled, bus width is extended to 6 bytes.
> > @@ -990,9 +995,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> > *msm_host, bool is_bonded_dsi)
> > }
> >
> > if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
> > -   if (msm_host->dsc)
> > -   dsi_update_dsc_timing(msm_host, false, 
> > mode->hdisplay);
> > -
> > dsi_write(msm_host, REG_DSI_ACTIVE_H,
> > DSI_ACTIVE_H_START(ha_start) |
> > DSI_ACTIVE_H_END(ha_end));
> > @@ -1011,9 +1013,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
> > *msm_host, bool is_bonded_dsi)
> > DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
> > DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
> > } else {/* command mode */
> > -   if (msm_host->dsc)
> > -   dsi_update_dsc_timing(msm_host, true, 
> > mode->hdisplay);
> > -
> > /* image data and 1 byte write_memory_start cmd */
> > if (!msm_host->dsc)
> > wc = hdisplay * 
> > mipi_dsi_pixel_format_to_bpp(msm_host->format) / 8 + 1;
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


[PATCH 21/21] drm/msm/dpu: revise debug info to support quad pipe

2024-08-29 Thread Jun Nie
Unify debug info to support dual pipe and quad pipe

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 16 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 35 +--
 2 files changed, 21 insertions(+), 30 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 8fd56f8f2851f..9e8c5225c8dca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1437,15 +1437,13 @@ 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[0]:%s\n",
-  pstate->pipe.sspp->cap->name);
-   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);
+   for (i = 0; i < PIPES_PER_STAGE; i++) {
+   if (!pstate->pipe_cfg[i].visible)
+   break;
+   seq_printf(s, "\tsspp[%d]:%s\n",
+   i, pstate->pipe[i].sspp->cap->name);
+   seq_printf(s, "\tmultirect[%d]: mode: %d index: %d\n",
+   i, pstate->pipe[i].multirect_mode, 
pstate->pipe[i].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 c3ea97b4ce439..12f7b510eb5e0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1550,30 +1550,23 @@ static void dpu_plane_atomic_print_state(struct 
drm_printer *p,
const struct drm_plane_state *state)
 {
const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-   const struct dpu_sw_pipe *pipe = &pstate->pipe;
-   const struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-   const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
-   const struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+   const struct dpu_sw_pipe *pipe;
+   const struct dpu_sw_pipe_cfg *pipe_cfg;
+   int i;
 
drm_printf(p, "\tstage=%d\n", pstate->stage);
 
-   if (pipe->sspp) {
-   drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
-   drm_printf(p, "\tmultirect_mode[0]=%s\n", 
dpu_get_multirect_mode(pipe->multirect_mode));
-   drm_printf(p, "\tmultirect_index[0]=%s\n",
-  dpu_get_multirect_index(pipe->multirect_index));
-   drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", 
DRM_RECT_ARG(&pipe_cfg->src_rect));
-   drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", 
DRM_RECT_ARG(&pipe_cfg->dst_rect));
-   }
-
-   if (r_pipe->sspp) {
-   drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
-   drm_printf(p, "\tmultirect_mode[1]=%s\n",
-  dpu_get_multirect_mode(r_pipe->multirect_mode));
-   drm_printf(p, "\tmultirect_index[1]=%s\n",
-  dpu_get_multirect_index(r_pipe->multirect_index));
-   drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", 
DRM_RECT_ARG(&r_pipe_cfg->src_rect));
-   drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", 
DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+   for (i = 0; i < PIPES_PER_STAGE; i++) {
+   pipe_cfg = &pstate->pipe_cfg[i];
+   pipe = &pstate->pipe[i];
+   if (pipe->sspp) {
+   drm_printf(p, "\tsspp[%d]=%s\n", i, 
pipe->sspp->cap->name);
+   drm_printf(p, "\tmultirect_mode[%d]=%s\n", i, 
dpu_get_multirect_mode(pipe->multirect_mode));
+   drm_printf(p, "\tmultirect_index[%d]=%s\n",
+  i, 
dpu_get_multirect_index(pipe->multirect_index));
+   drm_printf(p, "\tsrc[%d]=" DRM_RECT_FMT "\n", i, 
DRM_RECT_ARG(&pipe_cfg->src_rect));
+   drm_printf(p, "\tdst[%d]=" DRM_RECT_FMT "\n", i, 
DRM_RECT_ARG(&pipe_cfg->dst_rect));
+   }
}
 }
 

-- 
2.34.1



[PATCH 20/21] drm/msm/dpu: support quad pipe in general operations

2024-08-29 Thread Jun Nie
Support quad pipe in general operations with unified method.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 87 +--
 1 file changed, 47 insertions(+), 40 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c38c1bedd40fb..c3ea97b4ce439 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -619,6 +619,7 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
struct msm_drm_private *priv = plane->dev->dev_private;
struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
u32 fill_color = (color & 0xFF) | ((alpha & 0xFF) << 24);
+   int i;
 
DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -632,12 +633,11 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
return;
 
/* 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);
+   for (i = 0; i < PIPES_PER_STAGE; i++)
+   if (pstate->pipe[i].sspp)
+   _dpu_plane_color_fill_pipe(pstate, &pstate->pipe[i],
+  
&pstate->pipe_cfg[i].dst_rect,
+  fill_color, fmt);
 }
 
 static int dpu_plane_prepare_fb(struct drm_plane *plane,
@@ -1279,8 +1279,11 @@ void dpu_plane_flush(struct drm_plane *plane)
/* force 100% alpha */
_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
else {
-   dpu_plane_flush_csc(pdpu, &pstate->pipe);
-   dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+   int i;
+
+   for (i = 0; i < PIPES_PER_STAGE; i++)
+   if (pstate->pipe_cfg[i].visible)
+   dpu_plane_flush_csc(pdpu, &pstate->pipe[i]);
}
 
/* flag h/w flush complete */
@@ -1380,20 +1383,17 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
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 dpu_sw_pipe *r_pipe = &pstate->r_pipe;
struct drm_crtc *crtc = state->crtc;
struct drm_framebuffer *fb = state->fb;
bool is_rt_pipe;
const struct msm_format *fmt =
msm_framebuffer_format(fb);
-   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-   struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+   struct dpu_sw_pipe_cfg *pipe_cfg;
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;
bool layout_valid = false;
-   int ret;
+   int ret, i;
 
ret = dpu_format_populate_layout(aspace, fb, &layout);
if (ret)
@@ -1412,28 +1412,28 @@ static void dpu_plane_sspp_atomic_update(struct 
drm_plane *plane)
crtc->base.id, DRM_RECT_ARG(&state->dst),
&fmt->pixel_format, MSM_FORMAT_IS_UBWC(fmt));
 
-   dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
-  drm_mode_vrefresh(&crtc->mode),
-  layout_valid ? &layout : NULL);
-
-   if (r_pipe->sspp) {
-   dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
-  drm_mode_vrefresh(&crtc->mode),
-  layout_valid ? &layout : NULL);
+   for (i = 0; i < PIPES_PER_STAGE; i++) {
+   if (pstate->pipe_cfg[i].visible && pstate->pipe[i].sspp)
+   dpu_plane_sspp_update_pipe(plane, &pstate->pipe[i],
+  &pstate->pipe_cfg[i], fmt,
+  
drm_mode_vrefresh(&crtc->mode),
+  layout_valid ? &layout : 
NULL);
}
 
if (pstate->needs_qos_remap)
pstate->needs_qos_remap = false;
 
-   pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt,
-   &crtc->mode, pipe_cfg);
-
-   pstate->plane_clk = _dpu_plane_calc_clk(

[PATCH 19/21] drm/msm/dpu: bind correct pingpong for quad pipe

2024-08-29 Thread Jun Nie
There are 2 interface and 4 PP in quad pipe. Map the 2nd
interface to 3rd PP instead of the 2nd PP.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 5d927f23e35b2..e17b7b39c4db9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1116,7 +1116,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_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_lm, num_ctl, num_pp, num_dsc, num_pp_per_intf;
unsigned int dsc_mask = 0;
int i;
 
@@ -1186,9 +1186,14 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
}
 
cstate->num_mixers = num_lm;
-
dpu_enc->connector = conn_state->connector;
 
+   /*
+* There may be 4 PP and 2 INTF for quad pipe case, so INTF is not
+* bind to PP 1:1. Let's calculate the stride with pipe/INTF
+*/
+   num_pp_per_intf = num_lm / dpu_enc->num_phys_encs;
+
for (i = 0; i < dpu_enc->num_phys_encs; i++) {
struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i];
struct dpu_hw_ctl *ctl0 = to_dpu_hw_ctl(hw_ctl[0]);
@@ -1210,7 +1215,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
return;
}
 
-   phys->hw_pp = dpu_enc->hw_pp[i];
+   phys->hw_pp = dpu_enc->hw_pp[num_pp_per_intf * i];
 
phys->cached_mode = crtc_state->adjusted_mode;
if (phys->ops.atomic_mode_set)

-- 
2.34.1



[PATCH 18/21] drm/msm/dpu: blend pipes by left and right

2024-08-29 Thread Jun Nie
Blend pipes by left and right. The first 2 pipes are for
left half screen and the later 2 pipes are for right in quad
pipe case.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 13 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 10 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c  | 19 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h  |  4 +++-
 4 files changed, 38 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 3b3cd17976082..8fd56f8f2851f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -574,8 +574,17 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
mixer[i].mixer_op_mode,
ctl->idx - CTL_0);
 
-   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-   &stage_cfg);
+   /*
+* call dpu_hw_ctl_setup_blendstage() to blend layers per stage 
cfg.
+* There is 4 mixers at most. The first 2 are for the left 
half, and
+* the later 2 are for the right half.
+*/
+   if (cstate->num_mixers == 4 && i >= 2)
+   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
+   &stage_cfg, true);
+   else
+   ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
+   &stage_cfg, false);
}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 76793201b984e..5d927f23e35b2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2049,9 +2049,13 @@ static void dpu_encoder_helper_reset_mixers(struct 
dpu_encoder_phys *phys_enc)
if (phys_enc->hw_ctl->ops.update_pending_flush_mixer)
phys_enc->hw_ctl->ops.update_pending_flush_mixer(ctl, 
hw_mixer[i]->idx);
 
-   /* clear all blendstages */
-   if (phys_enc->hw_ctl->ops.setup_blendstage)
-   phys_enc->hw_ctl->ops.setup_blendstage(ctl, 
hw_mixer[i]->idx, NULL);
+   /* clear all blendstages in both left and right */
+   if (phys_enc->hw_ctl->ops.setup_blendstage) {
+   phys_enc->hw_ctl->ops.setup_blendstage(ctl,
+   hw_mixer[i]->idx, NULL, false);
+   phys_enc->hw_ctl->ops.setup_blendstage(ctl,
+   hw_mixer[i]->idx, NULL, true);
+   }
}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 602dfad127c2a..2072d18520326 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -478,12 +478,13 @@ static const struct ctl_blend_config 
ctl_blend_config[][2] = {
 };
 
 static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx,
-   enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg)
+   enum dpu_lm lm, struct dpu_hw_stage_cfg *stage_cfg, bool right)
 {
struct dpu_hw_blk_reg_map *c = &ctx->hw;
u32 mix, ext, mix_ext;
u32 mixercfg[5] = { 0 };
int i, j;
+   int pipe_start, pipe_end;
int stages;
int pipes_per_stage;
 
@@ -502,13 +503,27 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl 
*ctx,
if (!stage_cfg)
goto exit;
 
+   /*
+* For quad pipe case, blend pipes in right side separately. Otherwise,
+* all content is on the left half by defaut (no splitting case).
+*/
+   if (!right) {
+   pipe_start = 0;
+   pipe_end = pipes_per_stage == PIPES_PER_STAGE ? 2 : 1;
+   } else {
+   pipe_start = 2;
+   pipe_end = PIPES_PER_STAGE;
+   }
+
+   DRM_DEBUG_ATOMIC("blend lm %d on the %s side\n", lm - LM_0,
+right ? "right" : "left");
for (i = 0; i <= stages; i++) {
/* overflow to ext register if 'i + 1 > 7' */
mix = (i + 1) & 0x7;
ext = i >= 7;
mix_ext = (i + 1) & 0xf;
 
-   for (j = 0 ; j < pipes_per_stage; j++) {
+   for (j = pipe_start; j < pipe_end; j++) {
enum dpu_sspp_multirect_index rect_index =
stage_cfg->multirect_index[i][j];
enum dpu_sspp pipe = stage_cfg->stage[i][j];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 557ec9a924f81..2dac7885fc5e7 100644
--- a/d

[PATCH 17/21] drm/msm/dpu: setup pipes with 2 set of stage config

2024-08-29 Thread Jun Nie
The first 2 fields in multirect_index and stage array are for the first
SSPP and its multi-rect. And the later 2 fields are for the 2nd SSPP
and its multi-rect.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 76 +++-
 1 file changed, 55 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 2c21a1e13d32f..3b3cd17976082 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -397,9 +397,8 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
   const struct msm_format *format,
   uint64_t modifier,
   struct dpu_sw_pipe *pipe,
-  unsigned int stage_idx,
-  struct dpu_hw_stage_cfg *stage_cfg
- )
+  unsigned int pipe_idx,
+  struct dpu_hw_stage_cfg *stage_cfg)
 {
uint32_t lm_idx;
enum dpu_sspp sspp_idx;
@@ -410,7 +409,7 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
state = plane->state;
 
trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-  state, to_dpu_plane_state(state), stage_idx,
+  state, to_dpu_plane_state(state), pipe_idx,
   format->pixel_format,
   modifier);
 
@@ -422,8 +421,14 @@ static void _dpu_crtc_blend_setup_pipe(struct drm_crtc 
*crtc,
 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;
+   /* Mark sspp[sspp_idx] to be blended in stage[stage], pipe_idx decide
+* the SSPP is blended into which mixer. For example, SSPP 1 goes to
+* left half of screen, then pipe_idx 0 and 1 shall be set for sspp_idx
+* 1 in quad-pipe case.
+* The operation is done in dpu_hw_ctl_setup_blendstage()
+*/
+   stage_cfg->stage[stage][pipe_idx] = sspp_idx;
+   stage_cfg->multirect_index[stage][pipe_idx] = pipe->multirect_index;
 
/* blend config update */
for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
@@ -441,8 +446,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
struct dpu_plane_state *pstate = NULL;
const struct msm_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
+   struct dpu_sw_pipe *pipe;
 
-   uint32_t lm_idx;
+   uint32_t lm_idx, i, c;
bool bg_alpha_enable = false;
DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
@@ -463,20 +469,48 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc 
*crtc,
if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
bg_alpha_enable = true;
 
-   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,
-  &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);
+   /*
+* Check whether the SSPP fall into left/right half of screen
+* via mxcfg_id. The left half is the default area with the
+* first config. And the right half is with the second config
+* in quad pipe case. The SSPP for the left half always come
+* first in pipe array.
+*
+* For example: there are one SSPP for left and another SSPP for
+* right with a super wide plane in quad-pipe case, with multi-
+* rect mode on both SSPP. The pipe index for the 1st SSPP are
+* 0/1 which goes to left half with the first 2 mixers. The pipe
+* index for the 2nd SSPP are 2/3 to indicate the SSPP will go
+* to the right half with 3rd/4th mixer in 4

[PATCH 16/21] drm/msm/dpu: support SSPP assignment for quad-pipe case

2024-08-29 Thread Jun Nie
Support SSPP assignment for quad-pipe case with unified method

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 58 +--
 1 file changed, 25 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 95cb2575c63b4..c38c1bedd40fb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1143,25 +1143,18 @@ static int dpu_plane_virtual_assign_resources(struct 
drm_crtc *crtc,
struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
struct dpu_rm_sspp_requirements reqs;
struct dpu_plane_state *pstate;
-   struct dpu_sw_pipe *pipe;
-   struct dpu_sw_pipe *r_pipe;
-   struct dpu_sw_pipe_cfg *pipe_cfg;
-   struct dpu_sw_pipe_cfg *r_pipe_cfg;
+   struct dpu_plane *pdpu = to_dpu_plane(plane);
const struct msm_format *fmt;
uint32_t max_linewidth;
+   u32 i;
 
if (plane_state->crtc)
crtc_state = drm_atomic_get_new_crtc_state(state,
   plane_state->crtc);
 
pstate = to_dpu_plane_state(plane_state);
-   pipe = &pstate->pipe;
-   r_pipe = &pstate->r_pipe;
-   pipe_cfg = &pstate->pipe_cfg;
-   r_pipe_cfg = &pstate->r_pipe_cfg;
-
-   pipe->sspp = NULL;
-   r_pipe->sspp = NULL;
+   for (i = 0; i < PIPES_PER_STAGE; i++)
+   pstate->pipe[i].sspp = NULL;
 
if (!plane_state->fb)
return -EINVAL;
@@ -1175,41 +1168,40 @@ static int dpu_plane_virtual_assign_resources(struct 
drm_crtc *crtc,
 
max_linewidth = dpu_kms->catalog->caps->max_linewidth;
 
-   pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, crtc, 
&reqs);
-   if (!pipe->sspp)
-   return -ENODEV;
+   for (i = 0; i < PIPES_PER_STAGE; i++) {
+   struct dpu_sw_pipe *r_pipe = &pstate->pipe[i + 1];
+   struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->pipe_cfg[i + 1];
+   struct dpu_sw_pipe *pipe = &pstate->pipe[i];
+   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg[i];
 
-   if (drm_rect_width(&r_pipe_cfg->src_rect) == 0) {
-   pipe->multirect_index = DPU_SSPP_RECT_SOLO;
-   pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   if (!pipe_cfg->visible)
+   break;
 
-   r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
-   r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+   pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, global_state, 
crtc, &reqs);
+   if (!pipe->sspp)
+   return -ENODEV;
 
-   r_pipe->sspp = NULL;
-   } else {
-   if (dpu_plane_is_multirect_parallel_capable(pipe, pipe_cfg, 
fmt, max_linewidth) &&
-   dpu_plane_is_multirect_parallel_capable(r_pipe, r_pipe_cfg, 
fmt, max_linewidth) &&
+   if (r_pipe_cfg->visible &&
+   drm_rect_width(&r_pipe_cfg->src_rect) != 0 &&
+   dpu_plane_is_multirect_parallel_capable(pipe_cfg, fmt, 
max_linewidth) &&
+   dpu_plane_is_multirect_parallel_capable(r_pipe_cfg, fmt, 
max_linewidth) &&
+   pipe_cfg->mxcfg_id == r_pipe_cfg->mxcfg_id &&
(test_bit(DPU_SSPP_SMART_DMA_V1, 
&pipe->sspp->cap->features) ||
 test_bit(DPU_SSPP_SMART_DMA_V2, 
&pipe->sspp->cap->features))) {
-   r_pipe->sspp = pipe->sspp;
-
pipe->multirect_index = DPU_SSPP_RECT_0;
pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
 
+   DPU_DEBUG_PLANE(pdpu, "allocating sspp_%d for pipe %d 
and set pipe %d as multi-rect\n",
+   pipe->sspp->idx, i, i+1);
+   r_pipe->sspp = pipe->sspp;
r_pipe->multirect_index = DPU_SSPP_RECT_1;
r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+   i++;
} else {
-   /* multirect is not possible, use two SSPP blocks */
-   r_pipe->sspp = dpu_rm_reserve_sspp(&dpu_kms->rm, 
global_state, crtc, &reqs);
-   if (!r_pipe->sspp)
-   return -ENODEV;
-
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;
+   DPU_DEBUG_PLANE(pdpu, "allocating sspp_%d for pipe 
%d.\n",
+   pipe->sspp->idx, i);
}
}
 

-- 
2.34.1



[PATCH 15/21] drm/msm/dpu: support plane splitting in quad-pipe case

2024-08-29 Thread Jun Nie
Clip plane into SSPPs per left and right half screen per ROI if topology
is quad pipe. Then split the split rectangle by half if the clip
width still exceed limit.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 97 ++-
 1 file changed, 71 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 78bf8f0292f62..95cb2575c63b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -836,10 +836,12 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
u64 max_mdp_clk_rate = kms->perf.max_core_clk_rate;
struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
-   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-   struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
+   struct dpu_sw_pipe_cfg pipe_cfg;
struct drm_rect fb_rect = { 0 };
+   const struct drm_display_mode *mode = &crtc_state->adjusted_mode;
uint32_t max_linewidth;
+   u32 lm_num;
+   int cfg_idx = 0, cfg_id, mixercfg_num;
 
min_scale = FRAC_16_16(1, MAX_UPSCALE_RATIO);
max_scale = MAX_DOWNSCALE_RATIO << 16;
@@ -862,10 +864,10 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
return -EINVAL;
}
 
-   /* state->src is 16.16, src_rect is not */
-   drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src);
+   lm_num = dpu_crtc_get_lm_num(crtc_state);
 
-   pipe_cfg->dst_rect = new_plane_state->dst;
+   /* state->src is 16.16, src_rect is not */
+   drm_rect_fp_to_int(&pipe_cfg.src_rect, &new_plane_state->src);
 
fb_rect.x2 = new_plane_state->fb->width;
fb_rect.y2 = new_plane_state->fb->height;
@@ -880,34 +882,77 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
 
max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-   drm_rect_rotate(&pipe_cfg->src_rect,
+   drm_rect_rotate(&pipe_cfg.src_rect,
new_plane_state->fb->width, new_plane_state->fb->height,
new_plane_state->rotation);
 
-   if ((drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) ||
-_dpu_plane_calc_clk(&crtc_state->adjusted_mode, pipe_cfg) > 
max_mdp_clk_rate) {
-   if (drm_rect_width(&pipe_cfg->src_rect) > 2 * max_linewidth) {
-   DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " 
line:%u\n",
-   DRM_RECT_ARG(&pipe_cfg->src_rect), 
max_linewidth);
-   return -E2BIG;
-   }
+   /*
+* We have 1 mixer cfg for 1:1:1 and 2:2:1 topology, 2 mixer configs
+* for left and right half screen in case of 4:4:2 topology.
+* But we may have 2 SSPP to split plane with 1 mixer config for 2:2:1.
+* So need to handle super wide plane splitting, and plane on right half
+* for dual-DSI case. Check dest rectangle left/right splitting
+* first, then check super wide rectangle splitting next.
+*/
+   mixercfg_num = lm_num / 2;
+   mixercfg_num = mixercfg_num == 0 ? 1 : mixercfg_num;
+   /* iterate mixer configs for this plane, to separate left/right with 
the id */
+   for (cfg_id = 0; cfg_id < mixercfg_num; cfg_id++) {
+   struct drm_rect mixer_rect = {cfg_id * mode->hdisplay / 
mixercfg_num, 0,
+   (cfg_id + 1) * mode->hdisplay / 
mixercfg_num, mode->vdisplay};
+   struct dpu_sw_pipe_cfg *cur_cfg = &pstate->pipe_cfg[cfg_idx];
+
+   drm_rect_fp_to_int(&cur_cfg->src_rect, &new_plane_state->src);
+   cur_cfg->dst_rect = new_plane_state->dst;
+
+   DPU_DEBUG_PLANE(pdpu, "checking src " DRM_RECT_FMT " vs clip " 
DRM_RECT_FMT "\n",
+   DRM_RECT_ARG(&cur_cfg->src_rect), 
DRM_RECT_ARG(&mixer_rect));
+
+   /* If this plane does not fall into mixer rect, check next 
mixer rect */
+   if (!drm_rect_clip_scaled(&cur_cfg->src_rect, 
&cur_cfg->dst_rect, &mixer_rect))
+   continue;
 
-   *r_pipe_cfg = *pipe_cfg;
-   pipe_cfg->src_rect.x2 = (pipe_cfg->src_rect.x1 + 
pipe_cfg->src_rect.x2) >> 1;
-   pipe_cfg->dst_rect.x2 = (pipe_cfg->dst_rect.x1 + 
pipe_cfg->dst_rect.x2) >> 1;
-   r_pipe_cfg->src_rect.x1 = pipe_cfg->src_rect.x2;
-   r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x

[PATCH 14/21] drm/msm/dpu: Support quad-pipe in SSPP checking

2024-08-29 Thread Jun Nie
Support quad-pipe in SSPP checking with unified method

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 108 ++
 1 file changed, 51 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4df7cfed4d230..78bf8f0292f62 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -738,12 +738,40 @@ static int dpu_plane_check_inline_rotation(struct 
dpu_plane *pdpu,
 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 msm_format *fmt,
-   const struct drm_display_mode *mode)
+   const struct drm_display_mode *mode,
+   struct drm_plane_state *new_plane_state)
 {
uint32_t min_src_size;
struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
int ret;
+   const struct msm_format *fmt;
+   uint32_t supported_rotations;
+   const struct dpu_sspp_cfg *pipe_hw_caps;
+   const struct dpu_sspp_sub_blks *sblk;
+
+   pipe_hw_caps = pipe->sspp->cap;
+   sblk = pipe->sspp->cap->sblk;
+
+   /*
+* We already have verified scaling against platform limitations.
+* Now check if the SSPP supports scaling at all.
+*/
+   if (!sblk->scaler_blk.len &&
+   ((drm_rect_width(&new_plane_state->src) >> 16 !=
+ drm_rect_width(&new_plane_state->dst)) ||
+(drm_rect_height(&new_plane_state->src) >> 16 !=
+ drm_rect_height(&new_plane_state->dst
+   return -ERANGE;
+
+   fmt = msm_framebuffer_format(new_plane_state->fb);
+
+   supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
+
+   if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
+   supported_rotations |= DRM_MODE_ROTATE_90;
+
+   pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
+  supported_rotations);
 
min_src_size = MSM_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
@@ -886,8 +914,7 @@ static int dpu_plane_atomic_check_nopipe(struct drm_plane 
*plane,
return 0;
 }
 
-static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe *pipe,
-  struct dpu_sw_pipe_cfg 
*pipe_cfg,
+static int dpu_plane_is_multirect_parallel_capable(struct dpu_sw_pipe_cfg 
*pipe_cfg,
   const struct msm_format *fmt,
   uint32_t max_linewidth)
 {
@@ -916,49 +943,19 @@ static int dpu_plane_atomic_check_pipes(struct drm_plane 
*plane,
drm_atomic_get_new_plane_state(state, plane);
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 msm_format *fmt;
-   struct dpu_sw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-   struct dpu_sw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
-   uint32_t supported_rotations;
-   const struct dpu_sspp_cfg *pipe_hw_caps;
-   const struct dpu_sspp_sub_blks *sblk;
-   int ret = 0;
-
-   pipe_hw_caps = pipe->sspp->cap;
-   sblk = pipe->sspp->cap->sblk;
-
-   /*
-* We already have verified scaling against platform limitations.
-* Now check if the SSPP supports scaling at all.
-*/
-   if (!sblk->scaler_blk.len &&
-   ((drm_rect_width(&new_plane_state->src) >> 16 !=
- drm_rect_width(&new_plane_state->dst)) ||
-(drm_rect_height(&new_plane_state->src) >> 16 !=
- drm_rect_height(&new_plane_state->dst
-   return -ERANGE;
-
-   fmt = msm_framebuffer_format(new_plane_state->fb);
-
-   supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
-
-   if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
-   supported_rotations |= DRM_MODE_ROTATE_90;
-
-   pipe_cfg->rotation = drm_rotation_simplify(new_plane_state->rotation,
-  supported_rotations);
-   r_pipe_cfg->rotation = pipe_cfg->rotation;
-
-   ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt,
- &crtc_state->adjusted_mode);
-   if (ret)
-   return ret;
+   struct dpu_sw_pipe *pipe;
+   struct dpu_sw_pipe_cfg *pipe_cfg;
+   int ret = 0, i;
 
-   if (drm_rect_width(&r_pipe_cfg->s

[PATCH 13/21] drm/msm/dpu: Support quad pipe in header files

2024-08-29 Thread Jun Nie
Support 4 pipes and their configs at most. They are for 2 SSPP
and their multi-rect mode. Because one SSPP can co-work with
2 mixer at most, 2 pair of mixer are needed for 2 SSPP in quad-
pipe case. So 2 mixer configs are needed in quad-pipe case.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 11 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 30 +
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index a2eff36a2224c..424725303ccad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -32,7 +32,7 @@
 #define DPU_MAX_PLANES 4
 #endif
 
-#define PIPES_PER_STAGE2
+#define PIPES_PER_STAGE4
 #ifndef DPU_MAX_DE_CURVES
 #define DPU_MAX_DE_CURVES  3
 #endif
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 fc54625ae5d4f..ae6beff2c294b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -143,11 +143,20 @@ struct dpu_hw_pixel_ext {
  * such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
  * @rotation: simplified drm rotation hint
+ * @visible: mark this cfg is valid
+ * @mxcfg_id: mixer config ID for left or right half screen.
+ * We have single SSPP, dual SSPP, single SSPP+multi_rect or dual
+ * SSPP+multi_rect case. mxcfg_id mark current pipe will use
+ * which mixer cfg. The first mxcfg is for the left half of screen,
+ * the 2nd mxcfg is for the right half screen. The heading cfg may
+ * be skipped by pipe with the first mxcfg_id = 1 if the plane is
+ * only displayed in the right side, thus SSPP goes to later 
mixers.
  */
 struct dpu_sw_pipe_cfg {
struct drm_rect src_rect;
struct drm_rect dst_rect;
-   unsigned int rotation;
+   unsigned int rotation, mxcfg_id;
+   bool visible;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index e225d5baceb09..9e79cf9eba264 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -14,14 +14,30 @@
 #include "dpu_hw_mdss.h"
 #include "dpu_hw_sspp.h"
 
+/**
+ * Max number of mixer configs. Because we support 4 pipes at most,
+ * the 4 pipes are with 2 SSPP and their multi-rect mode. While one
+ * SSPP can co-work with 2 mixer at most, then 2 pair of mixer are
+ * needed for 2 SSPP in quad-pipe case. Thus 2 mixer configs are
+ * needed in quad-pipe case.
+ */
+#define MIX_CFGS_IN_CRTC 2
+
 /**
  * struct dpu_plane_state: Define dpu extension of drm plane state object
  * @base:  base drm plane state object
  * @aspace:pointer to address space for input/output buffers
- * @pipe:  software pipe description
- * @r_pipe:software pipe description of the second pipe
- * @pipe_cfg:  software pipe configuration
- * @r_pipe_cfg:software pipe configuration for the second pipe
+ * @pipe:  software pipe description. Some or all of fields in array can
+ * be in use per topology. The heading fields are used first,
+ * and the later fields is invalid if visible field of pipe_cfg
+ * is not set. For example, the visible fields of pipe_cfg are set
+ * in the first 2 pipe_cfg fields, and the mxcfg_id for them are
+ * 0 and 1. That means the first pipe is for left half screen and
+ * the 2nd pipe is for right half. The visible field of the 3rd
+ * pipe_cfg is not set, which means the 3rd and 4th pipe are not
+ * in use.
+ * @pipe_cfg:  software pipe configuration. The 4 fields are for SSPP and their
+   parallel rect as above pipes.
  * @stage: assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -34,10 +50,8 @@
 struct dpu_plane_state {
struct drm_plane_state base;
struct msm_gem_address_space *aspace;
-   struct dpu_sw_pipe pipe;
-   struct dpu_sw_pipe r_pipe;
-   struct dpu_sw_pipe_cfg pipe_cfg;
-   struct dpu_sw_pipe_cfg r_pipe_cfg;
+   struct dpu_sw_pipe pipe[PIPES_PER_STAGE];
+   struct dpu_sw_pipe_cfg pipe_cfg[PIPES_PER_STAGE];
enum dpu_stage stage;
bool needs_qos_remap;
bool pending;

-- 
2.34.1



[PATCH 12/21] drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation

2024-08-29 Thread Jun Nie
Up to now the driver has been using encoder to allocate hardware resources.
Switch it to use CRTC id so that mixer number can be known in
dpu_plane_virtual_assign_resources() via CRTC id for sspp alloation.

Because the mixer allocation is done in drm_atomic_helper_check_modeset()
as part of CRTC operation. While the sspp assignment is in
drm_atomic_helper_check_planes() call tree. So CRTC is more central
than encoder. Siwtching the id achieves above goal.

Co-developed-by: Dmitry Baryshkov 
Signed-off-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  18 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 190 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  19 ++-
 4 files changed, 115 insertions(+), 124 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index f57725ad494d2..76793201b984e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -703,11 +703,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);
@@ -1141,14 +1141,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++)
@@ -1156,7 +1156,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
: NULL;
 
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]);
@@ -1170,7 +1170,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_cdm = NULL;
 
dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state,
- drm_enc->base.id, DPU_HW_BLK_CDM,
+ drm_enc->crtc, DPU_HW_BLK_CDM,
  &hw_cdm, 1);
dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : 
NULL;
}
@@ -2042,7 +2042,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 1952576600575..4f0fa1596b414 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -134,12 +134,12 @@ struct dpu_global_state {
 
str

[PATCH 11/21] drm/msm/dpu: Support 4 mixers at most

2024-08-29 Thread Jun Nie
Support 4 mixers case with increasing array size and checking
the usage case.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 6 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h   | 1 +
 4 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d9f26e189eebf..2c21a1e13d32f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -200,7 +200,7 @@ static int dpu_crtc_get_lm_crc(struct drm_crtc *crtc,
struct dpu_crtc_state *crtc_state)
 {
struct dpu_crtc_mixer *m;
-   u32 crcs[CRTC_DUAL_MIXERS];
+   u32 crcs[CRTC_QUAD_MIXERS];
 
int rc = 0;
int i;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 701c35803633d..08fc88d03bf6c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -210,7 +210,7 @@ struct dpu_crtc_state {
 
bool bw_control;
bool bw_split_vote;
-   struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
+   struct drm_rect lm_bounds[CRTC_QUAD_MIXERS];
 
uint64_t input_fence_timeout_ns;
 
@@ -218,10 +218,10 @@ struct dpu_crtc_state {
 
/* HW Resources reserved for the crtc */
u32 num_mixers;
-   struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS];
+   struct dpu_crtc_mixer mixers[CRTC_QUAD_MIXERS];
 
u32 num_ctls;
-   struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS];
+   struct dpu_hw_ctl *hw_ctls[CRTC_QUAD_MIXERS];
 
enum dpu_crtc_crc_source crc_source;
int crc_frame_skip_count;
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 e77ebe3a68da9..c877ee45535ac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -324,7 +324,8 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
 
/* Use merge_3d unless DSC MERGE topology is used */
if (phys_enc->split_role == ENC_ROLE_SOLO &&
-   dpu_cstate->num_mixers == CRTC_DUAL_MIXERS &&
+   (dpu_cstate->num_mixers == CRTC_DUAL_MIXERS ||
+   dpu_cstate->num_mixers == CRTC_QUAD_MIXERS) &&
!dpu_encoder_use_dsc_merge(phys_enc->parent))
return BLEND_3D_H_ROW_INT;
 
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 bf86d643887dd..f79ecd409a830 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -25,6 +25,7 @@
 #define MAX_IMG_HEIGHT 0x3fff
 
 #define CRTC_DUAL_MIXERS   2
+#define CRTC_QUAD_MIXERS   4
 
 #define MAX_XIN_COUNT 16
 

-- 
2.34.1



[PATCH 10/21] drm/msm/dpu: fix lm number counter for quad-pipe

2024-08-29 Thread Jun Nie
Add the case to reserve multiple pair mixer for high resolution

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 6 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 8 +++-
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 33cfd94badaba..f57725ad494d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -54,7 +54,7 @@
 #define MAX_PHYS_ENCODERS_PER_VIRTUAL \
(MAX_H_TILES_PER_DISPLAY * NUM_PHYS_ENCODER_TYPES)
 
-#define MAX_CHANNELS_PER_ENC 2
+#define MAX_CHANNELS_PER_ENC 4
 
 #define IDLE_SHORT_TIMEOUT 1
 
@@ -2029,8 +2029,8 @@ static void dpu_encoder_helper_reset_mixers(struct 
dpu_encoder_phys *phys_enc)
struct dpu_hw_mixer_cfg mixer;
int i, num_lm;
struct dpu_global_state *global_state;
-   struct dpu_hw_blk *hw_lm[2];
-   struct dpu_hw_mixer *hw_mixer[2];
+   struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
+   struct dpu_hw_mixer *hw_mixer[MAX_CHANNELS_PER_ENC];
struct dpu_hw_ctl *ctl = phys_enc->hw_ctl;
 
memset(&mixer, 0, sizeof(mixer));
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index e219d706610c2..77d7ff789346e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -306,7 +306,11 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
if (!rm->mixer_blks[i])
continue;
 
-   lm_count = 0;
+   /*
+* Clear the last bit to drop the previous primary mixer if
+* fail to find its peer.
+*/
+   lm_count &= 0xfe;
lm_idx[lm_count] = i;
 
if (!_dpu_rm_check_lm_and_get_connected_blks(rm, global_state,
@@ -353,6 +357,8 @@ static int _dpu_rm_reserve_lms(struct dpu_rm *rm,
 
trace_dpu_rm_reserve_lms(lm_idx[i] + LM_0, enc_id,
 pp_idx[i] + PINGPONG_0);
+   DPU_DEBUG("reserve lm[%d]:%d, pp_idx[%d]:%d, dspp[%d]:%d for 
enc_id %d\n",
+ i, lm_idx[i], i, pp_idx[i], i, dspp_idx[i], enc_id);
}
 
return 0;

-- 
2.34.1



[PATCH 09/21] drm/msm/dpu: request more mixer for 4K+ DSC case

2024-08-29 Thread Jun Nie
request more mixer for the case that hdisplay exceeding 4096
and DSC enabled.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 24 
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 05b203be2a9bc..33cfd94badaba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -59,6 +59,7 @@
 #define IDLE_SHORT_TIMEOUT 1
 
 #define MAX_HDISPLAY_SPLIT 1080
+#define MAX_HDISPLAY_DSC_SPLIT 2560
 
 /* timeout in frames waiting for frame done */
 #define DPU_ENCODER_FRAME_DONE_TIMEOUT_FRAMES 5
@@ -588,15 +589,19 @@ static struct msm_display_topology 
dpu_encoder_get_topology(
 
/* Datapath topology selection
 *
-* Dual display
+* Dual display without DSC
 * 2 LM, 2 INTF ( Split display using 2 interfaces)
 *
+* Dual display with DSC
+* 4 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 (intf_count == 2)
topology.num_lm = 2;
else if (!dpu_kms->catalog->caps->has_3d_merge)
@@ -615,10 +620,21 @@ static struct msm_display_topology 
dpu_encoder_get_topology(
 * 2 DSC encoders, 2 layer mixers and 1 interface
 * this is power optimal and can drive up to (including) 4k
 * screens
+* But for dual display with hdisplay exceeding 4096, we need
+* 4 layer mixer. Because DSC has a max width of 2048 and
+* a single plane can only be used by one mixer pair
 */
-   topology.num_dsc = 2;
-   topology.num_lm = 2;
-   topology.num_intf = 1;
+
+   if (intf_count == 2 &&
+   mode->hdisplay > MAX_HDISPLAY_DSC_SPLIT) {
+   topology.num_dsc = 4;
+   topology.num_lm = 4;
+   topology.num_intf = 2;
+   } else {
+   topology.num_dsc = 2;
+   topology.num_lm = 2;
+   topology.num_intf = 1;
+   }
}
 
return topology;

-- 
2.34.1



[PATCH 08/21] drm/msm/dpu: decide right side per last bit

2024-08-29 Thread Jun Nie
in case of multiple mixer pairs

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index a27e39c525d1a..d9f26e189eebf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -369,11 +369,10 @@ static void _dpu_crtc_setup_blend_cfg(struct 
dpu_crtc_mixer *mixer,
 static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 {
struct dpu_crtc_state *crtc_state;
-   int lm_idx, lm_horiz_position;
+   int lm_idx;
 
crtc_state = to_dpu_crtc_state(crtc->state);
 
-   lm_horiz_position = 0;
for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) {
const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm;
@@ -384,7 +383,7 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc 
*crtc)
 
cfg.out_width = drm_rect_width(lm_roi);
cfg.out_height = drm_rect_height(lm_roi);
-   cfg.right_mixer = lm_horiz_position++;
+   cfg.right_mixer = lm_idx & 0x1;
cfg.flags = 0;
hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
}

-- 
2.34.1



[PATCH 07/21] drm/msm/dpu: Support dynamic DSC number

2024-08-29 Thread Jun Nie
Do not assume DSC number as 2. Because there are 4 DSC in
quad pipe case.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 6bdd9c21ff3ed..05b203be2a9bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -553,9 +553,9 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
if (dpu_enc->phys_encs[i])
intf_count++;
 
-   /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
+   /* DSC and mixer are mapped 1:1, so reuse the mixer number */
if (dpu_enc->dsc)
-   num_dsc = 2;
+   num_dsc = dpu_crtc_get_lm_num(drm_enc->crtc->state);
 
return (num_dsc > 0) && (num_dsc > intf_count);
 }

-- 
2.34.1



[PATCH 06/21] drm/msm/dpu: Add utility to get mixer number

2024-08-29 Thread Jun Nie
Add utility to get mixer number via CRTC handler

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 7 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 5 +
 2 files changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 7d0fff9472441..a27e39c525d1a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1306,6 +1306,13 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
return 0;
 }
 
+unsigned int dpu_crtc_get_lm_num(const struct drm_crtc_state *state)
+{
+   struct dpu_crtc_state *cstate = to_dpu_crtc_state(state);
+
+   return cstate->num_mixers;
+}
+
 #ifdef CONFIG_DEBUG_FS
 static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
 {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index b26d5fe40c721..701c35803633d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -301,5 +301,10 @@ static inline enum dpu_crtc_client_type 
dpu_crtc_get_client_type(
 }
 
 void dpu_crtc_frame_event_cb(struct drm_crtc *crtc, u32 event);
+/**
+ * dpu_crtc_get_lm_num - Get mixer number in this CRTC pipeline
+ * @crtc: Pointer to drm crtc object
+ */
+unsigned int dpu_crtc_get_lm_num(const struct drm_crtc_state *state);
 
 #endif /* _DPU_CRTC_H_ */

-- 
2.34.1



[PATCH 05/21] drm/msm/dpu: polish log for resource allocation

2024-08-29 Thread Jun Nie
Add resource allocation type info.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 23 +++
 1 file changed, 19 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 15b42a6683639..e219d706610c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -778,6 +778,21 @@ void dpu_rm_release_all_sspp(struct dpu_global_state 
*global_state,
ARRAY_SIZE(global_state->sspp_to_crtc_id), crtc_id);
 }
 
+static char *dpu_hw_blk_type_name[] = {
+   [DPU_HW_BLK_TOP] = "blk_top",
+   [DPU_HW_BLK_SSPP] = "blk_sspp",
+   [DPU_HW_BLK_LM] = "blk_lm",
+   [DPU_HW_BLK_CTL] = "blk_ctl",
+   [DPU_HW_BLK_PINGPONG] = "blk_pingpong",
+   [DPU_HW_BLK_INTF] = "blk_intf",
+   [DPU_HW_BLK_WB] = "blk_wb",
+   [DPU_HW_BLK_DSPP] = "blk_dspp",
+   [DPU_HW_BLK_MERGE_3D] = "blk_merge_3d",
+   [DPU_HW_BLK_DSC] = "blk_dsc",
+   [DPU_HW_BLK_CDM] = "blk_cdm",
+   [DPU_HW_BLK_MAX] = "blk_none",
+};
+
 int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
struct dpu_global_state *global_state, uint32_t enc_id,
enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size)
@@ -828,13 +843,13 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
continue;
 
if (num_blks == blks_size) {
-   DPU_ERROR("More than %d resources assigned to enc %d\n",
- blks_size, enc_id);
+   DPU_ERROR("More than %d %s assigned to enc %d\n",
+ blks_size, dpu_hw_blk_type_name[type], 
enc_id);
break;
}
if (!hw_blks[i]) {
-   DPU_ERROR("Allocated resource %d unavailable to assign 
to enc %d\n",
- type, enc_id);
+   DPU_ERROR("%s unavailable to assign to enc %d\n",
+ dpu_hw_blk_type_name[type], enc_id);
break;
}
blks[num_blks++] = hw_blks[i];

-- 
2.34.1



[PATCH 04/21] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2024-08-29 Thread Jun Nie
From: Jonathan Marek 

MSM display controller support multiple slice to be sent in a single DSC
packet. Add a dsc_slice_per_pkt field to mipi_dsi_device struct and
support this field in msm mdss driver.

Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
comment is incorrect.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 25 ++---
 include/drm/drm_mipi_dsi.h |  2 ++
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 5abade8f26b88..36f0470cdf588 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -157,6 +157,7 @@ struct msm_dsi_host {
 
struct drm_display_mode *mode;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 
/* connected device info */
unsigned int channel;
@@ -861,17 +862,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
-   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
+   bytes_per_pkt = dsc->slice_chunk_size * msm_host->dsc_slice_per_pkt;
 
eol_byte_num = total_bytes_per_intf % 3;
-
-   /*
-* Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
-*
-* Since the current driver only supports slice_per_pkt = 1,
-* pkt_per_line will be equal to slice per intf for now.
-*/
-   pkt_per_line = slice_per_intf;
+   pkt_per_line = slice_per_intf / msm_host->dsc_slice_per_pkt;
 
if (is_cmd_mode) /* packet data type */
reg = 
DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
@@ -1019,12 +1013,8 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
else
/*
 * When DSC is enabled, WC = slice_chunk_size * 
slice_per_pkt + 1.
-* Currently, the driver only supports default value of 
slice_per_pkt = 1
-*
-* TODO: Expand mipi_dsi_device struct to hold 
slice_per_pkt info
-*   and adjust DSC math to account for 
slice_per_pkt.
 */
-   wc = msm_host->dsc->slice_chunk_size + 1;
+   wc = msm_host->dsc->slice_chunk_size * 
msm_host->dsc_slice_per_pkt + 1;
 
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1629,8 +1619,13 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
msm_host->lanes = dsi->lanes;
msm_host->format = dsi->format;
msm_host->mode_flags = dsi->mode_flags;
-   if (dsi->dsc)
+   if (dsi->dsc) {
msm_host->dsc = dsi->dsc;
+   msm_host->dsc_slice_per_pkt = dsi->dsc_slice_per_pkt;
+   /* for backwards compatibility, assume 1 if not set */
+   if (!msm_host->dsc_slice_per_pkt)
+   msm_host->dsc_slice_per_pkt = 1;
+   }
 
ret = dsi_dev_attach(msm_host->pdev);
if (ret)
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 0f520eeeaa8e3..1c1b56077d44a 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -182,6 +182,7 @@ struct mipi_dsi_device_info {
  * be set to the real limits of the hardware, zero is only accepted for
  * legacy drivers
  * @dsc: panel/bridge DSC pps payload to be sent
+ * @dsc_slice_per_pkt: number of DSC slices to be sent as in a single packet
  */
 struct mipi_dsi_device {
struct mipi_dsi_host *host;
@@ -196,6 +197,7 @@ struct mipi_dsi_device {
unsigned long hs_rate;
unsigned long lp_rate;
struct drm_dsc_config *dsc;
+   unsigned int dsc_slice_per_pkt;
 };
 
 /**

-- 
2.34.1



[PATCH 03/21] drm/msm/dsi: pass the right width to dsc

2024-08-29 Thread Jun Nie
Data width for dsc engine is aligned with pipe, not with whole screen
width. Because the width may be halved in DSI bonded case.

The dsc width is not related to the timing with back front porch in
later stage, so update dsc timing earlier.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7a4d9c071be5a..5abade8f26b88 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -953,7 +953,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
return;
}
 
-   dsc->pic_width = mode->hdisplay;
+   dsc->pic_width = hdisplay;
dsc->pic_height = mode->vdisplay;
DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height);
 
@@ -964,6 +964,11 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
if (ret)
return;
 
+   if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)
+   dsi_update_dsc_timing(msm_host, false, hdisplay);
+   else
+   dsi_update_dsc_timing(msm_host, true, hdisplay);
+
/*
 * DPU sends 3 bytes per pclk cycle to DSI. If widebus is
 * enabled, bus width is extended to 6 bytes.
@@ -990,9 +995,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
}
 
if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
-
dsi_write(msm_host, REG_DSI_ACTIVE_H,
DSI_ACTIVE_H_START(ha_start) |
DSI_ACTIVE_H_END(ha_end));
@@ -1011,9 +1013,6 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
} else {/* command mode */
-   if (msm_host->dsc)
-   dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
-
/* image data and 1 byte write_memory_start cmd */
if (!msm_host->dsc)
wc = hdisplay * 
mipi_dsi_pixel_format_to_bpp(msm_host->format) / 8 + 1;

-- 
2.34.1



[PATCH 02/21] drm/msm/dsi: fix DSC width for the bonded DSI case

2024-08-29 Thread Jun Nie
From: Jonathan Marek 

For the bonded DSI case, DSC pic_width and timing calculations should use
the width of a single panel instead of the total combined width.

Bonded DSI can be used to drive a single panel having two input
channels, or to drive two panels with a input channel on every panel that
behave like single panel for display controller.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi.h | 3 ++-
 drivers/gpu/drm/msm/dsi/dsi_host.c| 6 +-
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h
index 87496db203d6c..35b90c462f637 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -79,7 +79,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host);
 int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
  const struct drm_display_mode *mode);
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode 
*mode);
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi);
 unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
 int msm_dsi_host_register(struct mipi_dsi_host *host);
 void msm_dsi_host_unregister(struct mipi_dsi_host *host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 6388bb12696ff..7a4d9c071be5a 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2489,7 +2489,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host 
*host,
 }
 
 enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host,
-   const struct drm_display_mode *mode)
+   const struct drm_display_mode *mode,
+   bool is_bonded_dsi)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
struct drm_dsc_config *dsc = msm_host->dsc;
@@ -2499,6 +2500,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct 
mipi_dsi_host *host,
if (!msm_host->dsc)
return MODE_OK;
 
+   if (is_bonded_dsi)
+   pic_width = mode->hdisplay / 2;
+
if (pic_width % dsc->slice_width) {
pr_err("DSI: pic_width %d has to be multiple of slice %d\n",
   pic_width, dsc->slice_width);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c 
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index a210b7c9e5ca2..6e915b57e14bb 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -420,7 +420,7 @@ static enum drm_mode_status 
dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge,
return MODE_ERROR;
}
 
-   return msm_dsi_host_check_dsc(host, mode);
+   return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI());
 }
 
 static int dsi_mgr_bridge_attach(struct drm_bridge *bridge,

-- 
2.34.1



[PATCH 01/21] drm/msm/dsi: add support to DSI CTRL v2.8.0

2024-08-29 Thread Jun Nie
From: Jonathan Marek 

Add support to DSI CTRL v2.8.0 with priority support

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 185d7de0bf376..6388bb12696ff 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2238,13 +2238,23 @@ int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
return ret;
 }
 
+#define DSI_VBIF_CTRL  (0x01CC - 4)
+#define DSI_VBIF_CTRL_PRIORITY 0x07
+
 void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host, u32 dma_base,
  u32 len)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+   const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
+   u32 reg;
 
dsi_write(msm_host, REG_DSI_DMA_BASE, dma_base);
dsi_write(msm_host, REG_DSI_DMA_LEN, len);
+   if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V2_8_0) {
+   reg = dsi_read(msm_host, DSI_VBIF_CTRL);
+   reg |= (DSI_VBIF_CTRL_PRIORITY & 0x7);
+   dsi_write(msm_host, DSI_VBIF_CTRL, reg);
+   }
dsi_write(msm_host, REG_DSI_TRIG_DMA, 1);
 
/* Make sure trigger happens */

-- 
2.34.1



[PATCH 00/21] drm/msm: Support quad pipe with dual-DSI

2024-08-29 Thread Jun Nie
2 SSPP and dual-DSI interface are need for super wide DSI panel.
This patch set make changes to DSI driver and extend pipes
and related mixer blending logic to support quad pipe.

This patch set is based on virtual plane patch set:
https://patchwork.freedesktop.org/series/131109/

Signed-off-by: Jun Nie 
---
Jonathan Marek (3):
  drm/msm/dsi: add support to DSI CTRL v2.8.0
  drm/msm/dsi: fix DSC width for the bonded DSI case
  drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

Jun Nie (18):
  drm/msm/dsi: pass the right width to dsc
  drm/msm/dpu: polish log for resource allocation
  drm/msm/dpu: Add utility to get mixer number
  drm/msm/dpu: Support dynamic DSC number
  drm/msm/dpu: decide right side per last bit
  drm/msm/dpu: request more mixer for 4K+ DSC case
  drm/msm/dpu: fix lm number counter for quad-pipe
  drm/msm/dpu: Support 4 mixers at most
  drm/msm/dpu: switch RM to use crtc_id rather than enc_id for allocation
  drm/msm/dpu: Support quad pipe in header files
  drm/msm/dpu: Support quad-pipe in SSPP checking
  drm/msm/dpu: support plane splitting in quad-pipe case
  drm/msm/dpu: support SSPP assignment for quad-pipe case
  drm/msm/dpu: setup pipes with 2 set of stage config
  drm/msm/dpu: blend pipes by left and right
  drm/msm/dpu: bind correct pingpong for quad pipe
  drm/msm/dpu: support quad pipe in general operations
  drm/msm/dpu: revise debug info to support quad pipe

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 119 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h |  11 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  73 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |   3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h   |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c   |  19 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h   |   4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h  |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h  |  11 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h  |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c| 385 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h|  30 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c   | 209 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h   |  19 +-
 drivers/gpu/drm/msm/dsi/dsi.h|   3 +-
 drivers/gpu/drm/msm/dsi/dsi_host.c   |  54 ++--
 drivers/gpu/drm/msm/dsi/dsi_manager.c|   2 +-
 include/drm/drm_mipi_dsi.h   |   2 +
 18 files changed, 566 insertions(+), 393 deletions(-)
---
base-commit: 9651fbfb684e7a1288dbae3bf1f15cd484c0217a
change-id: 20240829-sm8650-v6-11-hmd-pocf-mdss-quad-upstream-8-d2d6b3eb1d57

Best regards,
-- 
Jun Nie 



[PATCH v6 6/6] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2024-05-29 Thread Jun Nie
From: Jonathan Marek 

Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
Reviewed-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7252d36687e6..4768cff08381 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -885,7 +885,11 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
+   if (pkt_per_line > 4)
+   drm_warn_once(msm_host->dev, "pkt_per_line too big");
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN;

-- 
2.34.1



[PATCH v6 5/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC

2024-05-29 Thread Jun Nie
From: Jonathan Marek 

Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
Reviewed-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 47f5858334f6..7252d36687e6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -857,6 +857,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -864,6 +865,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -901,6 +903,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }

-- 
2.34.1



[PATCH v6 4/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2024-05-29 Thread Jun Nie
From: Jonathan Marek 

The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
driver is doing in video mode. Fix that by actually enabling widebus for
video mode.

Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Reviewed-by: Jessica Zhang 
Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index a50f4dda5941..47f5858334f6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -754,6 +754,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+   if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+   data |= DSI_VID_CFG0_DATABUS_WIDEN;
dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
/* Do not swap RGB colors */
@@ -778,7 +780,6 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
 
-   /* TODO: Allow for video-mode support once tested/fixed 
*/
if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
 

-- 
2.34.1



[PATCH v6 3/6] drm/msm/dpu: enable compression bit in cfg2 for DSC

2024-05-29 Thread Jun Nie
Enable compression bit in cfg2 register for DSC in the DSI case
per hardware version.

Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 3 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  | 8 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h  | 3 ++-
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index 925ec6ada0e1..f2aab3e7c783 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -307,7 +307,8 @@ static void dpu_encoder_phys_vid_setup_timing_engine(
 
spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags);
phys_enc->hw_intf->ops.setup_timing_gen(phys_enc->hw_intf,
-   &timing_params, fmt);
+   &timing_params, fmt,
+   phys_enc->dpu_kms->catalog->mdss_ver);
phys_enc->hw_ctl->ops.setup_intf_cfg(phys_enc->hw_ctl, &intf_cfg);
 
/* setup which pp blk will connect to this intf */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index f97221423249..fa6debda0774 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -98,7 +98,8 @@
 
 static void dpu_hw_intf_setup_timing_engine(struct dpu_hw_intf *intf,
const struct dpu_hw_intf_timing_params *p,
-   const struct msm_format *fmt)
+   const struct msm_format *fmt,
+   const struct dpu_mdss_version *mdss_ver)
 {
struct dpu_hw_blk_reg_map *c = &intf->hw;
u32 hsync_period, vsync_period;
@@ -177,6 +178,11 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
if (p->wide_bus_en && !dp_intf)
data_width = p->width >> 1;
 
+   /* TODO: handle DSC+DP case, we only handle DSC+DSI case so far */
+   if (p->compression_en && !dp_intf &&
+   mdss_ver->core_major_ver >= 7)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
index f9015c67a574..ef947bf77693 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -81,7 +81,8 @@ struct dpu_hw_intf_cmd_mode_cfg {
 struct dpu_hw_intf_ops {
void (*setup_timing_gen)(struct dpu_hw_intf *intf,
const struct dpu_hw_intf_timing_params *p,
-   const struct msm_format *fmt);
+   const struct msm_format *fmt,
+   const struct dpu_mdss_version *mdss_ver);
 
void (*setup_prg_fetch)(struct dpu_hw_intf *intf,
const struct dpu_hw_intf_prog_fetch *fetch);

-- 
2.34.1



[PATCH v6 2/6] drm/msm/dpu: adjust data width for widen bus case

2024-05-29 Thread Jun Nie
data is valid for only half the active window if widebus
is enabled

Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 225c1c7768ff..f97221423249 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -168,6 +168,15 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
 
data_width = p->width;
 
+   /*
+* If widebus is enabled, data is valid for only half the active window
+* since the data rate is doubled in this mode. But for the compression
+* mode in DP case, the p->width is already adjusted in
+* drm_mode_to_intf_timing_params()
+*/
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
+
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
 

-- 
2.34.1



[PATCH v6 1/6] drm/msm/dpu: fix video mode DSC for DSI

2024-05-29 Thread Jun Nie
From: Jonathan Marek 

Add width change in DPU timing for DSC compression case to work with
DSI video mode.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
Tested-by: Neil Armstrong  # on SM8550-QRD
Tested-by: Neil Armstrong  # on SM8650-QRD
Tested-by: Neil Armstrong  # on SM8650-HDK
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Jessica Zhang 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 18 ++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 119f3ea50a7c..48cef6e79c70 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -564,7 +564,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
return (num_dsc > 0) && (num_dsc > intf_count);
 }
 
-static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder 
*drm_enc)
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
 {
struct msm_drm_private *priv = drm_enc->dev->dev_private;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_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 002e89cc1705..2167c46c1a45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -334,6 +334,14 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
  */
 unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
 
+/**
+ * dpu_encoder_get_dsc_config - get DSC config for the DPU encoder
+ *   This helper function is used by physical encoder to get DSC config
+ *   used for this encoder.
+ * @drm_enc: Pointer to encoder structure
+ */
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc);
+
 /**
  * dpu_encoder_get_drm_fmt - return DRM fourcc format
  * @phys_enc: Pointer to physical encoder structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index ef69c2f408c3..925ec6ada0e1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -11,6 +11,7 @@
 #include "dpu_trace.h"
 #include "disp/msm_disp_snapshot.h"
 
+#include 
 #include 
 
 #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
@@ -115,6 +116,23 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio. bits of 3 components(R/G/B)
+* is compressed into bits of 1 pixel.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->compression_en) {
+   struct drm_dsc_config *dsc =
+  dpu_encoder_get_dsc_config(phys_enc->parent);
+   /*
+* TODO: replace drm_dsc_get_bpp_int with logic to handle
+* fractional part if there is fraction
+*/
+   timing->width = timing->width * drm_dsc_get_bpp_int(dsc) /
+   (dsc->bits_per_component * 3);
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)

-- 
2.34.1



[PATCH v6 0/6] Add DSC support to DSI video panel

2024-05-29 Thread Jun Nie
This is follow up update to Jonathan's patch set.

Changes vs V5:
- Add hardware version check for compression bit change in cfg2 register

Changes vs V4:
- Polish width calculation with helper function
- Split cfg2 compression bit into another patch

Changes vs V3:
- Rebase to latest msm-next-lumag branch.
- Drop the slice_per_pkt change as it does impact basic DSC feature.
- Remove change in generated dsi header
- update DSC compressed width calculation with bpp and bpc
- split wide bus impact on width into another patch
- rename patch tile of VIDEO_COMPRESSION_MODE_CTRL_WC change
- Polish warning usage
- Add tags from reviewers

Changes vs V2:
- Drop the INTF_CFG2_DATA_HCTL_EN change as it is handled in
latest mainline code.
- Drop the bonded DSI patch as I do not have device to test it.
- Address comments from version 2.

Signed-off-by: Jun Nie 
---
Changes in v6:
- Link to v5: 
https://lore.kernel.org/r/20240527-msm-drm-dsc-dsi-video-upstream-4-v5-0-f797ffba4...@linaro.org

Changes in v5:
- Link to v4: 
https://lore.kernel.org/r/20240524-msm-drm-dsc-dsi-video-upstream-4-v4-0-e61c05b40...@linaro.org

---
Jonathan Marek (4):
  drm/msm/dpu: fix video mode DSC for DSI
  drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
  drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
  drm/msm/dsi: add a comment to explain pkt_per_line encoding

Jun Nie (2):
  drm/msm/dpu: adjust data width for widen bus case
  drm/msm/dpu: enable compression bit in cfg2 for DSC

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h|  8 
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c| 21 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 17 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h |  3 ++-
 drivers/gpu/drm/msm/dsi/dsi_host.c  | 10 +-
 6 files changed, 56 insertions(+), 5 deletions(-)
---
base-commit: e6428bcb611f6c164856a41fc5a1ae8471a9b5a9
change-id: 20240524-msm-drm-dsc-dsi-video-upstream-4-22e2266fbe89

Best regards,
-- 
Jun Nie 



Re: [PATCH v5 2/6] drm/msm/dpu: adjust data width for widen bus case

2024-05-28 Thread Jun Nie
Dmitry Baryshkov  于2024年5月28日周二 08:48写道:
>
> On Mon, May 27, 2024 at 10:21:48PM +0800, Jun Nie wrote:
> > data is valid for only half the active window if widebus
> > is enabled
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 9 +
> >  1 file changed, 9 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > index 225c1c7768ff..f97221423249 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > @@ -168,6 +168,15 @@ static void dpu_hw_intf_setup_timing_engine(struct 
> > dpu_hw_intf *intf,
> >
> >   data_width = p->width;
> >
> > + /*
> > +  * If widebus is enabled, data is valid for only half the active 
> > window
> > +  * since the data rate is doubled in this mode. But for the 
> > compression
> > +  * mode in DP case, the p->width is already adjusted in
> > +  * drm_mode_to_intf_timing_params()
>
> Is there any reason for divergence here?

Lots of parameters in dpu_hw_intf_setup_timing_engine() is calculated
from timing->width,
such as hsync_period and display_v_start. So the width cannot be
adjusted beforehand in
drm_mode_to_intf_timing_params(). Otherwise, we get below error.

I guess the interface timing configuration differ in silicon, thus the
software shall handle the
difference. If we adjust the width beforehand for DSI, we get below error.

[6.625446] [drm:dpu_encoder_frame_done_timeout:2469] [dpu
error]enc31 frame done timeout
[6.642369] [drm:dpu_encoder_phys_vid_wait_for_commit_done:525]
[dpu error]vblank timeout: 4200c1
[6.642395] [drm:dpu_kms_wait_for_commit_done:493] [dpu error]wait
for commit done returned -110


>
> > +  */
> > + if (p->wide_bus_en && !dp_intf)
> > + data_width = p->width >> 1;
> > +
> >   hsync_data_start_x = hsync_start_x;
> >   hsync_data_end_x =  hsync_start_x + data_width - 1;
> >
> >
> > --
> > 2.34.1
> >
>
> --
> With best wishes
> Dmitry


[PATCH v5 6/6] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2024-05-27 Thread Jun Nie
From: Jonathan Marek 

Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7252d36687e6..4768cff08381 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -885,7 +885,11 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
+   if (pkt_per_line > 4)
+   drm_warn_once(msm_host->dev, "pkt_per_line too big");
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN;

-- 
2.34.1



[PATCH v5 5/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC

2024-05-27 Thread Jun Nie
From: Jonathan Marek 

Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 47f5858334f6..7252d36687e6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -857,6 +857,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -864,6 +865,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -901,6 +903,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }

-- 
2.34.1



[PATCH v5 4/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2024-05-27 Thread Jun Nie
From: Jonathan Marek 

The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
driver is doing in video mode. Fix that by actually enabling widebus for
video mode.

Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Reviewed-by: Jessica Zhang 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index a50f4dda5941..47f5858334f6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -754,6 +754,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+   if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+   data |= DSI_VID_CFG0_DATABUS_WIDEN;
dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
/* Do not swap RGB colors */
@@ -778,7 +780,6 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
 
-   /* TODO: Allow for video-mode support once tested/fixed 
*/
if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
 

-- 
2.34.1



[PATCH v5 3/6] drm/msm/dpu: enable compression bit in cfg2 for DSC

2024-05-27 Thread Jun Nie
Enable compression bit in cfg2 register for DSC in the DSI case

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index f97221423249..34bfcfba3df2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -177,6 +177,10 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
if (p->wide_bus_en && !dp_intf)
data_width = p->width >> 1;
 
+   /* TODO: handle DSC+DP case, we only handle DSC+DSI case so far */
+   if (p->compression_en && !dp_intf)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
 

-- 
2.34.1



[PATCH v5 2/6] drm/msm/dpu: adjust data width for widen bus case

2024-05-27 Thread Jun Nie
data is valid for only half the active window if widebus
is enabled

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 225c1c7768ff..f97221423249 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -168,6 +168,15 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
 
data_width = p->width;
 
+   /*
+* If widebus is enabled, data is valid for only half the active window
+* since the data rate is doubled in this mode. But for the compression
+* mode in DP case, the p->width is already adjusted in
+* drm_mode_to_intf_timing_params()
+*/
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
+
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
 

-- 
2.34.1



[PATCH v5 1/6] drm/msm/dpu: fix video mode DSC for DSI

2024-05-27 Thread Jun Nie
From: Jonathan Marek 

Add width change in DPU timing for DSC compression case to work with
DSI video mode.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 18 ++
 3 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 119f3ea50a7c..48cef6e79c70 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -564,7 +564,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
return (num_dsc > 0) && (num_dsc > intf_count);
 }
 
-static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder 
*drm_enc)
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
 {
struct msm_drm_private *priv = drm_enc->dev->dev_private;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_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 002e89cc1705..2167c46c1a45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -334,6 +334,14 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
  */
 unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
 
+/**
+ * dpu_encoder_get_dsc_config - get DSC config for the DPU encoder
+ *   This helper function is used by physical encoder to get DSC config
+ *   used for this encoder.
+ * @drm_enc: Pointer to encoder structure
+ */
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc);
+
 /**
  * dpu_encoder_get_drm_fmt - return DRM fourcc format
  * @phys_enc: Pointer to physical encoder structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index ef69c2f408c3..925ec6ada0e1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -11,6 +11,7 @@
 #include "dpu_trace.h"
 #include "disp/msm_disp_snapshot.h"
 
+#include 
 #include 
 
 #define DPU_DEBUG_VIDENC(e, fmt, ...) DPU_DEBUG("enc%d intf%d " fmt, \
@@ -115,6 +116,23 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio. bits of 3 components(R/G/B)
+* is compressed into bits of 1 pixel.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->compression_en) {
+   struct drm_dsc_config *dsc =
+  dpu_encoder_get_dsc_config(phys_enc->parent);
+   /*
+* TODO: replace drm_dsc_get_bpp_int with logic to handle
+* fractional part if there is fraction
+*/
+   timing->width = timing->width * drm_dsc_get_bpp_int(dsc) /
+   (dsc->bits_per_component * 3);
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)

-- 
2.34.1



[PATCH v5 0/6] Add DSC support to DSI video panel

2024-05-27 Thread Jun Nie
This is follow up update to Jonathan's patch set.

Changes vs V4:
- Polish width calculation with helper function
- Split cfg2 compression bit into another patch

Changes vs V3:
- Rebase to latest msm-next-lumag branch.
- Drop the slice_per_pkt change as it does impact basic DSC feature.
- Remove change in generated dsi header
- update DSC compressed width calculation with bpp and bpc
- split wide bus impact on width into another patch
- rename patch tile of VIDEO_COMPRESSION_MODE_CTRL_WC change
- Polish warning usage
- Add tags from reviewers

Changes vs V2:
- Drop the INTF_CFG2_DATA_HCTL_EN change as it is handled in
latest mainline code.
- Drop the bonded DSI patch as I do not have device to test it.
- Address comments from version 2.

Signed-off-by: Jun Nie 
---
Changes in v5:
- Link to v4: 
https://lore.kernel.org/r/20240524-msm-drm-dsc-dsi-video-upstream-4-v4-0-e61c05b40...@linaro.org

---
Jonathan Marek (4):
  drm/msm/dpu: fix video mode DSC for DSI
  drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
  drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
  drm/msm/dsi: add a comment to explain pkt_per_line encoding

Jun Nie (2):
  drm/msm/dpu: adjust data width for widen bus case
  drm/msm/dpu: enable compression bit in cfg2 for DSC

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 18 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  | 13 +
 drivers/gpu/drm/msm/dsi/dsi_host.c   | 10 +-
 5 files changed, 49 insertions(+), 2 deletions(-)
---
base-commit: e6428bcb611f6c164856a41fc5a1ae8471a9b5a9
change-id: 20240524-msm-drm-dsc-dsi-video-upstream-4-22e2266fbe89

Best regards,
-- 
Jun Nie 



[PATCH v4 5/5] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2024-05-24 Thread Jun Nie
From: Jonathan Marek 

Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 7252d36687e6..4768cff08381 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -885,7 +885,11 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
+   if (pkt_per_line > 4)
+   drm_warn_once(msm_host->dev, "pkt_per_line too big");
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN;

-- 
2.34.1



[PATCH v4 3/5] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2024-05-24 Thread Jun Nie
From: Jonathan Marek 

The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
driver is doing in video mode. Fix that by actually enabling widebus for
video mode.

Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Marijn Suijten 
Reviewed-by: Jessica Zhang 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index a50f4dda5941..47f5858334f6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -754,6 +754,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+   if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+   data |= DSI_VID_CFG0_DATABUS_WIDEN;
dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
/* Do not swap RGB colors */
@@ -778,7 +780,6 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
if (cfg_hnd->minor >= MSM_DSI_6G_VER_MINOR_V1_3)
data |= DSI_CMD_MODE_MDP_CTRL2_BURST_MODE;
 
-   /* TODO: Allow for video-mode support once tested/fixed 
*/
if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
data |= DSI_CMD_MODE_MDP_CTRL2_DATABUS_WIDEN;
 

-- 
2.34.1



[PATCH v4 4/5] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC

2024-05-24 Thread Jun Nie
From: Jonathan Marek 

Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 47f5858334f6..7252d36687e6 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -857,6 +857,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -864,6 +865,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -901,6 +903,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }

-- 
2.34.1



[PATCH v4 2/5] drm: adjust data width for widen bus case

2024-05-24 Thread Jun Nie
data is valid for only half the active window if widebus
is enabled

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 2cf1f8c116b5..3d1bc8fa4ca2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -167,6 +167,14 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
 
data_width = p->width;
+   /*
+* If widebus is enabled, data is valid for only half the active window
+* since the data rate is doubled in this mode. But for the compression
+* mode in DP case, the p->width is already adjusted in
+* drm_mode_to_intf_timing_params()
+*/
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
 
/* TODO: handle DSC+DP case, we only handle DSC+DSI case so far */
if (p->compression_en && !dp_intf)

-- 
2.34.1



[PATCH v4 1/5] drm/msm/dpu: fix video mode DSC for DSI

2024-05-24 Thread Jun Nie
From: Jonathan Marek 

Add necessary DPU timing and control changes for DSC to work with DSI
video mode.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  |  4 
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 119f3ea50a7c..48cef6e79c70 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -564,7 +564,7 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
return (num_dsc > 0) && (num_dsc > intf_count);
 }
 
-static struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder 
*drm_enc)
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc)
 {
struct msm_drm_private *priv = drm_enc->dev->dev_private;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_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 002e89cc1705..2167c46c1a45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -334,6 +334,14 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
  */
 unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
 
+/**
+ * dpu_encoder_get_dsc_config - get DSC config for the DPU encoder
+ *   This helper function is used by physical encoder to get DSC config
+ *   used for this encoder.
+ * @drm_enc: Pointer to encoder structure
+ */
+struct drm_dsc_config *dpu_encoder_get_dsc_config(struct drm_encoder *drm_enc);
+
 /**
  * dpu_encoder_get_drm_fmt - return DRM fourcc format
  * @phys_enc: Pointer to physical encoder structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index ef69c2f408c3..7047b607ca91 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -115,6 +115,19 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio. bits of 3 components(R/G/B)
+* is compressed into bits of 1 pixel.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->compression_en) {
+   struct drm_dsc_config *dsc =
+  dpu_encoder_get_dsc_config(phys_enc->parent);
+   timing->width = timing->width * (dsc->bits_per_pixel >> 4) /
+   (dsc->bits_per_component * 3);
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 225c1c7768ff..2cf1f8c116b5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -168,6 +168,10 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *intf,
 
data_width = p->width;
 
+   /* TODO: handle DSC+DP case, we only handle DSC+DSI case so far */
+   if (p->compression_en && !dp_intf)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
 

-- 
2.34.1



[PATCH v4 0/5] Add DSC support to DSI video panel

2024-05-24 Thread Jun Nie
This is follow up update to Jonathan's patch set.

Changes vs V3:
- Rebase to latest msm-next-lumag branch.
- Drop the slice_per_pkt change as it does impact basic DSC feature.
- Remove change in generated dsi header
- update DSC compressed width calculation with bpp and bpc
- split wide bus impact on width into another patch
- rename patch tile of VIDEO_COMPRESSION_MODE_CTRL_WC change
- Polish warning usage
- Add tags from reviewers

Changes vs V2:
- Drop the INTF_CFG2_DATA_HCTL_EN change as it is handled in
latest mainline code.
- Drop the bonded DSI patch as I do not have device to test it.
- Address comments from version 2.

Signed-off-by: Jun Nie 
---
Jonathan Marek (4):
  drm/msm/dpu: fix video mode DSC for DSI
  drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
  drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC
  drm/msm/dsi: add a comment to explain pkt_per_line encoding

Jun Nie (1):
  drm: adjust data width for widen bus case

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c  |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h |  8 
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 13 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  | 12 
 drivers/gpu/drm/msm/dsi/dsi_host.c   | 10 +-
 5 files changed, 43 insertions(+), 2 deletions(-)
---
base-commit: e6428bcb611f6c164856a41fc5a1ae8471a9b5a9
change-id: 20240524-msm-drm-dsc-dsi-video-upstream-4-22e2266fbe89

Best regards,
-- 
Jun Nie 



Re: [PATCH v3 3/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)

2024-04-08 Thread Jun Nie
Marijn Suijten  于2024年4月9日周二 00:45写道:
>
> Can we drop (fix video mode DSC) from this patch title?  It looks like more
> patches are required to get this done, such a mention is more something for 
> the
> cover letter.
>
> We could also clarify further to "set Word Count for video-mode DSC".
>
Accepted. video-mode DSC is achieved with the patch set, not this
specific patch.


Re: [PATCH v3 6/6] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2024-04-08 Thread Jun Nie
Dmitry Baryshkov  于2024年4月3日周三 18:51写道:
>
> On Wed, 3 Apr 2024 at 12:11, Jun Nie  wrote:
> >
> > From: Jonathan Marek 
> >
> > Support slice_per_pkt in msm driver.
> >
> > Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
> > comment is incorrect.
> >
> > Also trim the code to simplify the dsc reference.
> >
> > Signed-off-by: Jonathan Marek 
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 35 ++-
> >  1 file changed, 14 insertions(+), 21 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> > b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index b0507a42ee6a..0c6f40dbd25c 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -866,17 +866,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
> > *msm_host, bool is_cmd_mod
> > slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
> >
> > total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
> > -   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
> > -
> > +   bytes_per_pkt = dsc->slice_chunk_size * dsc->slice_per_pkt;
>
> Please don't mix cleanup and functional changes.

OK. Will fix this.


Re: [PATCH v3 5/6] drm/display: Add slice_per_pkt for dsc

2024-04-08 Thread Jun Nie
Dmitry Baryshkov  于2024年4月3日周三 17:41写道:
>
> On Wed, 3 Apr 2024 at 12:11, Jun Nie  wrote:
> >
> > Add variable for slice number of a DSC compression bit stream packet.
> > Its value shall be specified in panel driver, or default value can be set
> > in display controller driver if panel driver does not set it.
>
> This is not a part of the standard. Please justify it.

Right, I read the standard but did not find any details of packet description.
Looks like msm silicon support tuning of number of slice packing per downstream
code.
The slice_per_pkt can be set in the downstream msm device tree. And I test the
values 1 and 2 on vtdr6130 panel and both work. So I guess this is related to
performance or something like that. I will have more test with different panel
to check the impact.
drivers/gpu/drm/panel/panel-raydium-rm692e5.c also mentions to pass new value
to slice_per_pkt.

Hi Konrad,
Do you remember why value 2 is TODO for slice_per_pkt for panel rm692e5?

>
> >
> > Signed-off-by: Jun Nie 
> > ---
> >  include/drm/display/drm_dsc.h | 4 
> >  1 file changed, 4 insertions(+)
> >
> > diff --git a/include/drm/display/drm_dsc.h b/include/drm/display/drm_dsc.h
> > index bc90273d06a6..4fac0a2746ae 100644
> > --- a/include/drm/display/drm_dsc.h
> > +++ b/include/drm/display/drm_dsc.h
> > @@ -82,6 +82,10 @@ struct drm_dsc_config {
> >  * @bits_per_component: Bits per component to code (8/10/12)
> >  */
> > u8 bits_per_component;
> > +   /**
> > +* @slice_per_pkt: slice number per DSC bit stream packet
> > +*/
> > +   u8 slice_per_pkt;
> > /**
> >  * @convert_rgb:
> >  * Flag to indicate if RGB - YCoCg conversion is needed
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH v3 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2024-04-08 Thread Jun Nie
Dmitry Baryshkov  于2024年4月3日周三 18:10写道:
>
> On Wed, 3 Apr 2024 at 12:11, Jun Nie  wrote:
> >
> > From: Jonathan Marek 
> >
> > The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
> > driver is doing in video mode. Fix that by actually enabling widebus for
> > video mode.
> >
> > Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
> > Signed-off-by: Jonathan Marek 
> > Signed-off-by: Jun Nie 
>
> You have ignored all the review comments that were provided for v1.
> None of the tags were picked up either.
Just find that It was an accident that I cherry-picked wrong patch.
>
> Have you posted this for internal review like I have explicitly asked you?
Sorry, I guess I skipped your word in depression when I read the email.
>
> > ---
> >  drivers/gpu/drm/msm/dsi/dsi.xml.h  | 1 +
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
> >  2 files changed, 3 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
> > b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> > index 2a7d980e12c3..f0b3cdc020a1 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
> > +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
> > @@ -231,6 +231,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum 
> > dsi_traffic_mode val)
> >  #define DSI_VID_CFG0_HSA_POWER_STOP0x0001
> >  #define DSI_VID_CFG0_HBP_POWER_STOP0x0010
> >  #define DSI_VID_CFG0_HFP_POWER_STOP0x0100
> > +#define DSI_VID_CFG0_DATABUS_WIDEN 0x0200
> >  #define DSI_VID_CFG0_PULSE_MODE_HSA_HE 0x1000
>
> From the top of the file:
>
> /* Autogenerated file, DO NOT EDIT manually!
This is my fault, I did not notice the top of this file totally. Will
fix it in next version.

>
> >
> >  #define REG_DSI_VID_CFG1   0x001c
> > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
> > b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > index 9d86a6aca6f2..2a0422cad6de 100644
> > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> > @@ -754,6 +754,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host 
> > *msm_host,
> > data |= 
> > DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
> > data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
> > data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
> > +   if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
> > +   data |= DSI_VID_CFG0_DATABUS_WIDEN;
> > dsi_write(msm_host, REG_DSI_VID_CFG0, data);
> >
> > /* Do not swap RGB colors */
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH v3 1/6] drm/msm/dpu: fix video mode DSC for DSI

2024-04-03 Thread Jun Nie
Dmitry Baryshkov  于2024年4月3日周三 17:57写道:
>
> On Wed, 3 Apr 2024 at 12:11, Jun Nie  wrote:
> >
> > From: Jonathan Marek 
> >
> > Add necessary DPU timing and control changes for DSC to work with DSI
> > video mode.
> >
> > Signed-off-by: Jonathan Marek 
> > Signed-off-by: Jun Nie 
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 9 +
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  | 8 
> >  2 files changed, 17 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > index d9e7dbf0499c..c7b009a60b63 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
> > @@ -115,6 +115,15 @@ static void drm_mode_to_intf_timing_params(
> > timing->h_front_porch = timing->h_front_porch >> 1;
> > timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
> > }
> > +
> > +   /*
> > +* for DSI, if compression is enabled, then divide the horizonal 
> > active
> > +* timing parameters by compression ratio.
> > +*/
> > +   if (phys_enc->hw_intf->cap->type != INTF_DP && 
> > timing->compression_en) {
> > +   timing->width = timing->width / 3; /* XXX: don't assume 3:1 
> > compression ratio */
> > +   timing->xres = timing->width;
> > +   }
> >  }
> >
> >  static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params 
> > *timing)
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > index 965692ef7892..079efb48db05 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> > @@ -167,6 +167,14 @@ static void dpu_hw_intf_setup_timing_engine(struct 
> > dpu_hw_intf *ctx,
> > intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
> >
> > data_width = p->width;
> > +   if (p->wide_bus_en && !dp_intf)
> > +   data_width = p->width >> 1;
>
> How is wide_bus relevant to the DSC case?
> Is there a need for the Fixes tag?

48bit bus width should be used when DSC is enabled. Without the
widebus configuration,
a lot dsi error happens as below in DSC case.
[  206.275992] dsi_err_worker: status=4

For the Fixes tag, the previous patch mentioned to enable the widebus
mode for any DSC case. So it is fair to add the tag.
>
> > +
> > +   if (p->compression_en)
> > +   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
> > +
> > +   if (p->compression_en && dp_intf)
> > +   DPU_ERROR("missing adjustments for DSC+DP\n");
> >
> > hsync_data_start_x = hsync_start_x;
> > hsync_data_end_x =  hsync_start_x + data_width - 1;
> >
> > --
> > 2.34.1
> >
>
>
> --
> With best wishes
> Dmitry


Re: [PATCH v3 0/6] Add DSC support to DSI video panel

2024-04-03 Thread Jun Nie
Dmitry Baryshkov  于2024年4月3日周三 17:49写道:
>
> On Wed, 3 Apr 2024 at 12:11, Jun Nie  wrote:
> >
> > This is follow up update to Jonathan's patch set.
> >
> > Changes vs V2:
> > - Rebase to latest mainline.
> > - Drop the INTF_CFG2_DATA_HCTL_EN change as it is handled in
> > latest mainline code.
> > - Drop the bonded DSI patch as I do not have device to test it.
> > - Address comments from version 2.
>
> Which comments? "Adress comments" is the worst case of changelog.
Adopted. Will add more details in next version.
>
> Also, what do you consider as version 2? Jonathan Marek has only sent v1.

It's wired. I see v2 in patch title of below link. Just notice that
there is v1 in the link address.
https://patchwork.freedesktop.org/patch/567518/?series=126430&rev=1

>
> >
> > Signed-off-by: Jun Nie 
> > ---
> > Jonathan Marek (5):
> >   drm/msm/dpu: fix video mode DSC for DSI
> >   drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
> >   drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)
> >       drm/msm/dsi: add a comment to explain pkt_per_line encoding
> >   drm/msm/dsi: support DSC configurations with slice_per_pkt > 1
> >
> > Jun Nie (1):
> >   drm/display: Add slice_per_pkt for dsc
> >
> >  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  9 +
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  8 +
> >  drivers/gpu/drm/msm/dsi/dsi.xml.h  |  1 +
> >  drivers/gpu/drm/msm/dsi/dsi_host.c | 42 
> > +++---
> >  include/drm/display/drm_dsc.h  |  4 +++
> >  5 files changed, 44 insertions(+), 20 deletions(-)
> > ---
> > base-commit: b1e6ec0a0fd0252af046e542f91234cd6c30b2cb
> > change-id: 20240403-msm-drm-dsc-dsi-video-upstream-1156d110a53d
> >
> > Best regards,
> > --
> > Jun Nie 
> >
>
>
> --
> With best wishes
> Dmitry


[PATCH v3 6/6] drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

2024-04-03 Thread Jun Nie
From: Jonathan Marek 

Support slice_per_pkt in msm driver.

Note that the removed "pkt_per_line = slice_per_intf * slice_per_pkt"
comment is incorrect.

Also trim the code to simplify the dsc reference.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 35 ++-
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index b0507a42ee6a..0c6f40dbd25c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -866,17 +866,10 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
-   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
-
+   bytes_per_pkt = dsc->slice_chunk_size * dsc->slice_per_pkt;
eol_byte_num = total_bytes_per_intf % 3;
 
-   /*
-* Typically, pkt_per_line = slice_per_intf * slice_per_pkt.
-*
-* Since the current driver only supports slice_per_pkt = 1,
-* pkt_per_line will be equal to slice per intf for now.
-*/
-   pkt_per_line = slice_per_intf;
+   pkt_per_line = slice_per_intf / dsc->slice_per_pkt;
 
if (is_cmd_mode) /* packet data type */
reg = 
DSI_COMMAND_COMPRESSION_MODE_CTRL_STREAM0_DATATYPE(MIPI_DSI_DCS_LONG_WRITE);
@@ -916,6 +909,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
 static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi)
 {
struct drm_display_mode *mode = msm_host->mode;
+   struct drm_dsc_config *dsc = msm_host->dsc;
u32 hs_start = 0, vs_start = 0; /* take sync start as 0 */
u32 h_total = mode->htotal;
u32 v_total = mode->vtotal;
@@ -947,8 +941,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, 
bool is_bonded_dsi)
hdisplay /= 2;
}
 
-   if (msm_host->dsc) {
-   struct drm_dsc_config *dsc = msm_host->dsc;
+   if (dsc) {
u32 bytes_per_pclk;
 
/* update dsc params with timing params */
@@ -988,14 +981,14 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
else
bytes_per_pclk = 3;
 
-   hdisplay = 
DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk);
+   hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(dsc), 
bytes_per_pclk);
 
h_total += hdisplay;
ha_end = ha_start + hdisplay;
}
 
if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
-   if (msm_host->dsc)
+   if (dsc)
dsi_update_dsc_timing(msm_host, false, mode->hdisplay);
 
dsi_write(msm_host, REG_DSI_ACTIVE_H,
@@ -1016,21 +1009,17 @@ static void dsi_timing_setup(struct msm_dsi_host 
*msm_host, bool is_bonded_dsi)
DSI_ACTIVE_VSYNC_VPOS_START(vs_start) |
DSI_ACTIVE_VSYNC_VPOS_END(vs_end));
} else {/* command mode */
-   if (msm_host->dsc)
+   if (dsc)
dsi_update_dsc_timing(msm_host, true, mode->hdisplay);
 
/* image data and 1 byte write_memory_start cmd */
-   if (!msm_host->dsc)
+   if (!dsc)
wc = hdisplay * 
mipi_dsi_pixel_format_to_bpp(msm_host->format) / 8 + 1;
else
/*
 * When DSC is enabled, WC = slice_chunk_size * 
slice_per_pkt + 1.
-* Currently, the driver only supports default value of 
slice_per_pkt = 1
-*
-* TODO: Expand mipi_dsi_device struct to hold 
slice_per_pkt info
-*   and adjust DSC math to account for 
slice_per_pkt.
 */
-   wc = msm_host->dsc->slice_chunk_size + 1;
+   wc = dsc->slice_chunk_size * dsc->slice_per_pkt + 1;
 
dsi_write(msm_host, REG_DSI_CMD_MDP_STREAM0_CTRL,
DSI_CMD_MDP_STREAM0_CTRL_WORD_COUNT(wc) |
@@ -1657,8 +1646,12 @@ static int dsi_host_attach(struct mipi_dsi_host *host,
msm_host->lanes = dsi->lanes;
msm_host->format = dsi->format;
msm_host->mode_flags = dsi->mode_flags;
-   if (dsi->dsc)
+   if (dsi->dsc) {
msm_host->dsc = dsi->dsc;
+   /* for backwards compatibility, assume 1 if not set */
+   if (!dsi->dsc->slice_per_pkt)
+   dsi->

[PATCH v3 5/6] drm/display: Add slice_per_pkt for dsc

2024-04-03 Thread Jun Nie
Add variable for slice number of a DSC compression bit stream packet.
Its value shall be specified in panel driver, or default value can be set
in display controller driver if panel driver does not set it.

Signed-off-by: Jun Nie 
---
 include/drm/display/drm_dsc.h | 4 
 1 file changed, 4 insertions(+)

diff --git a/include/drm/display/drm_dsc.h b/include/drm/display/drm_dsc.h
index bc90273d06a6..4fac0a2746ae 100644
--- a/include/drm/display/drm_dsc.h
+++ b/include/drm/display/drm_dsc.h
@@ -82,6 +82,10 @@ struct drm_dsc_config {
 * @bits_per_component: Bits per component to code (8/10/12)
 */
u8 bits_per_component;
+   /**
+* @slice_per_pkt: slice number per DSC bit stream packet
+*/
+   u8 slice_per_pkt;
/**
 * @convert_rgb:
 * Flag to indicate if RGB - YCoCg conversion is needed

-- 
2.34.1



[PATCH v3 4/6] drm/msm/dsi: add a comment to explain pkt_per_line encoding

2024-04-03 Thread Jun Nie
From: Jonathan Marek 

Make it clear why the pkt_per_line value is being "divided by 2".

Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 80ea4f1d8274..b0507a42ee6a 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -886,7 +886,11 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
/* DSI_VIDEO_COMPRESSION_MODE & DSI_COMMAND_COMPRESSION_MODE
 * registers have similar offsets, so for below common code use
 * DSI_VIDEO_COMPRESSION_MODE_ for setting bits
+*
+* pkt_per_line is log2 encoded, >>1 works for supported values (1,2,4)
 */
+   if (pkt_per_line > 4)
+   drm_warn(msm_host->dev, "pkt_per_line too big");
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_PKT_PER_LINE(pkt_per_line >> 1);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EOL_BYTE_NUM(eol_byte_num);
reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_EN;

-- 
2.34.1



[PATCH v3 3/6] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)

2024-04-03 Thread Jun Nie
From: Jonathan Marek 

Video mode DSC won't work if this field is not set correctly. Set it to fix
video mode DSC (for slice_per_pkt==1 cases at least).

Fixes: 08802f515c3c ("drm/msm/dsi: Add support for DSC configuration")
Signed-off-by: Jonathan Marek 
Reviewed-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 2a0422cad6de..80ea4f1d8274 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -858,6 +858,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
u32 slice_per_intf, total_bytes_per_intf;
u32 pkt_per_line;
u32 eol_byte_num;
+   u32 bytes_per_pkt;
 
/* first calculate dsc parameters and then program
 * compress mode registers
@@ -865,6 +866,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
slice_per_intf = msm_dsc_get_slices_per_intf(dsc, hdisplay);
 
total_bytes_per_intf = dsc->slice_chunk_size * slice_per_intf;
+   bytes_per_pkt = dsc->slice_chunk_size; /* * slice_per_pkt; */
 
eol_byte_num = total_bytes_per_intf % 3;
 
@@ -902,6 +904,7 @@ static void dsi_update_dsc_timing(struct msm_dsi_host 
*msm_host, bool is_cmd_mod
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL, 
reg_ctrl);
dsi_write(msm_host, REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2, 
reg_ctrl2);
} else {
+   reg |= DSI_VIDEO_COMPRESSION_MODE_CTRL_WC(bytes_per_pkt);
dsi_write(msm_host, REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg);
}
 }

-- 
2.34.1



[PATCH v3 2/6] drm/msm/dsi: set video mode widebus enable bit when widebus is enabled

2024-04-03 Thread Jun Nie
From: Jonathan Marek 

The value returned by msm_dsi_wide_bus_enabled() doesn't match what the
driver is doing in video mode. Fix that by actually enabling widebus for
video mode.

Fixes: efcbd6f9cdeb ("drm/msm/dsi: Enable widebus for DSI")
Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/dsi/dsi.xml.h  | 1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h 
b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 2a7d980e12c3..f0b3cdc020a1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -231,6 +231,7 @@ static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum 
dsi_traffic_mode val)
 #define DSI_VID_CFG0_HSA_POWER_STOP0x0001
 #define DSI_VID_CFG0_HBP_POWER_STOP0x0010
 #define DSI_VID_CFG0_HFP_POWER_STOP0x0100
+#define DSI_VID_CFG0_DATABUS_WIDEN 0x0200
 #define DSI_VID_CFG0_PULSE_MODE_HSA_HE 0x1000
 
 #define REG_DSI_VID_CFG1   0x001c
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 9d86a6aca6f2..2a0422cad6de 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -754,6 +754,8 @@ static void dsi_ctrl_enable(struct msm_dsi_host *msm_host,
data |= DSI_VID_CFG0_TRAFFIC_MODE(dsi_get_traffic_mode(flags));
data |= DSI_VID_CFG0_DST_FORMAT(dsi_get_vid_fmt(mipi_fmt));
data |= DSI_VID_CFG0_VIRT_CHANNEL(msm_host->channel);
+   if (msm_dsi_host_is_wide_bus_enabled(&msm_host->base))
+   data |= DSI_VID_CFG0_DATABUS_WIDEN;
dsi_write(msm_host, REG_DSI_VID_CFG0, data);
 
/* Do not swap RGB colors */

-- 
2.34.1



[PATCH v3 1/6] drm/msm/dpu: fix video mode DSC for DSI

2024-04-03 Thread Jun Nie
From: Jonathan Marek 

Add necessary DPU timing and control changes for DSC to work with DSI
video mode.

Signed-off-by: Jonathan Marek 
Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c | 9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c  | 8 
 2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index d9e7dbf0499c..c7b009a60b63 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -115,6 +115,15 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->compression_en) {
+   timing->width = timing->width / 3; /* XXX: don't assume 3:1 
compression ratio */
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 965692ef7892..079efb48db05 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -167,6 +167,14 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *ctx,
intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
 
data_width = p->width;
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
+
+   if (p->compression_en)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
+
+   if (p->compression_en && dp_intf)
+   DPU_ERROR("missing adjustments for DSC+DP\n");
 
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;

-- 
2.34.1



[PATCH v3 0/6] Add DSC support to DSI video panel

2024-04-03 Thread Jun Nie
This is follow up update to Jonathan's patch set.

Changes vs V2:
- Rebase to latest mainline.
- Drop the INTF_CFG2_DATA_HCTL_EN change as it is handled in
latest mainline code.
- Drop the bonded DSI patch as I do not have device to test it.
- Address comments from version 2.

Signed-off-by: Jun Nie 
---
Jonathan Marek (5):
  drm/msm/dpu: fix video mode DSC for DSI
  drm/msm/dsi: set video mode widebus enable bit when widebus is enabled
  drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)
  drm/msm/dsi: add a comment to explain pkt_per_line encoding
  drm/msm/dsi: support DSC configurations with slice_per_pkt > 1

Jun Nie (1):
  drm/display: Add slice_per_pkt for dsc

 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   |  9 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  8 +
 drivers/gpu/drm/msm/dsi/dsi.xml.h  |  1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c | 42 +++---
 include/drm/display/drm_dsc.h  |  4 +++
 5 files changed, 44 insertions(+), 20 deletions(-)
---
base-commit: b1e6ec0a0fd0252af046e542f91234cd6c30b2cb
change-id: 20240403-msm-drm-dsc-dsi-video-upstream-1156d110a53d

Best regards,
-- 
Jun Nie 



Re: [PATCH 1/3] drm/msm/dpu: fix DSC for DSI video mode

2024-03-28 Thread Jun Nie
Dmitry Baryshkov  于2024年3月28日周四 23:05写道:
>
> On Thu, 28 Mar 2024 at 13:12, Jun Nie  wrote:
> >
> > Fix DSC timing and control configurations in DPU for DSI video mode.
> > Only compression ratio 3:1 is handled and tested.
> >
> > This patch is modified from patchs of Jonathan Marek.
> >
> > Signed-off-by: Jun Nie 
>
> This almost looks like a joke, except it isn't the 1st of April yet.
> The patch lacks proper Author / Sign-off tags from Jonathan.
> This is pretty close to copyright infringement. I'm sorry, but I'd
> have to ask you to abstain from sending patches w/o prior internal
> review.

Thanks for pointing me the previous version. I am not aware of it actually.
The only version I knew is from internal repo. It is my fault. I see the slides
says that Jonathan does not want to disturbed, so only his name is
mentioned in the commit message.

What's the patch set status? I do not see it in mainline yet. If it is
in pipeline,
I can just forget the DPU side change.

Thanks!
Jun

>
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
> >  .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  2 +-
> >  .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 12 +
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 10 +++-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  1 +
> >  drivers/gpu/drm/msm/dsi/dsi.xml.h |  1 +
> >  drivers/gpu/drm/msm/dsi/dsi_host.c| 48 +++
> >  include/drm/display/drm_dsc.h |  4 ++
>
> Ok. The feedback for the original patchset [1]  was that it should be
> split logically. Instead you pile everything together into a single
> patch. This is a complete no-go.
>
> Also, this patchset lacks changelog in comparison to the previous
> patchseris. I don't think I'll continue the review of this patch.
> Please rework it properly and add corresponding changelog.
>
> [1] https://patchwork.freedesktop.org/patch/567518/?series=126430&rev=1
>
> >  8 files changed, 56 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 6a4b489d44e5..c1b9da06dde2 100644
>
> --
> With best wishes
> Dmitry


[PATCH 3/3] drm/panel: Enable DSC for Visionox VTDR6130 panel

2024-03-28 Thread Jun Nie
Enable display compression (DSC v1.2) for 1080x2400 Visionox
VTDR6130 AMOLED DSI panel. DTS property is needed to enable DSC.
Default configuration is video mode + non-DSC for any back
compatibility.

Below modes works on SM8650. While cmd mode does not work yet.
- video mode + DSC
- video mode
- cmd mode + DSC

Signed-off-by: Jun Nie 
---
 .../gpu/drm/panel/panel-visionox-vtdr6130.c   | 58 ++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c 
b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c
index 540099253e1b..d6c44816cdd0 100644
--- a/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c
+++ b/drivers/gpu/drm/panel/panel-visionox-vtdr6130.c
@@ -9,6 +9,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -17,9 +18,12 @@
 
 struct visionox_vtdr6130 {
struct drm_panel panel;
+   struct drm_dsc_config dsc;
struct mipi_dsi_device *dsi;
struct gpio_desc *reset_gpio;
struct regulator_bulk_data supplies[3];
+   bool cmd_mode;
+   bool dsc_enable;
 };
 
 static inline struct visionox_vtdr6130 *to_visionox_vtdr6130(struct drm_panel 
*panel)
@@ -49,12 +53,20 @@ static int visionox_vtdr6130_on(struct visionox_vtdr6130 
*ctx)
if (ret)
return ret;
 
+   if (ctx->dsc_enable)
+   mipi_dsi_dcs_write_seq(dsi, 0x03, 0x01);
+
mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x20);
mipi_dsi_dcs_write_seq(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS, 0x00, 
0x00);
mipi_dsi_dcs_write_seq(dsi, 0x59, 0x09);
mipi_dsi_dcs_write_seq(dsi, 0x6c, 0x01);
mipi_dsi_dcs_write_seq(dsi, 0x6d, 0x00);
-   mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x01);
+
+   if (ctx->cmd_mode)
+   mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x02);
+   else
+   mipi_dsi_dcs_write_seq(dsi, 0x6f, 0x01);
+
mipi_dsi_dcs_write_seq(dsi, 0x70,
   0x12, 0x00, 0x00, 0xab, 0x30, 0x80, 0x09, 0x60, 
0x04,
   0x38, 0x00, 0x28, 0x02, 0x1c, 0x02, 0x1c, 0x02, 
0x00,
@@ -205,6 +217,26 @@ static const struct drm_display_mode 
visionox_vtdr6130_mode = {
.height_mm = 157,
 };
 
+static int visionox_vtdr6130_enable(struct drm_panel *panel)
+{
+   struct visionox_vtdr6130 *ctx = to_visionox_vtdr6130(panel);
+   struct mipi_dsi_device *dsi = ctx->dsi;
+   struct drm_dsc_picture_parameter_set pps;
+   int ret;
+
+   if (!dsi->dsc)
+   return 0;
+
+   drm_dsc_pps_payload_pack(&pps, dsi->dsc);
+   ret = mipi_dsi_picture_parameter_set(dsi, &pps);
+   if (ret) {
+   dev_err(&dsi->dev, "Failed to set PPS\n");
+   return ret;
+   }
+
+   return 0;
+}
+
 static int visionox_vtdr6130_get_modes(struct drm_panel *panel,
   struct drm_connector *connector)
 {
@@ -228,6 +260,7 @@ static const struct drm_panel_funcs 
visionox_vtdr6130_panel_funcs = {
.prepare = visionox_vtdr6130_prepare,
.unprepare = visionox_vtdr6130_unprepare,
.get_modes = visionox_vtdr6130_get_modes,
+   .enable = visionox_vtdr6130_enable,
 };
 
 static int visionox_vtdr6130_bl_update_status(struct backlight_device *bl)
@@ -260,12 +293,32 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device 
*dsi)
 {
struct device *dev = &dsi->dev;
struct visionox_vtdr6130 *ctx;
+   struct drm_dsc_config *dsc;
int ret;
 
ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
 
+   ctx->cmd_mode = of_property_read_bool(dev->of_node, "enforce-cmd-mode");
+   ctx->dsc_enable = of_property_read_bool(dev->of_node, "enable-dsc");
+
+   /* Set DSC params */
+   if (ctx->dsc_enable) {
+   dsc = &ctx->dsc;
+   dsc->dsc_version_major = 0x1;
+   dsc->dsc_version_minor = 0x2;
+   dsc->slice_height = 40;
+   dsc->slice_width = 540;
+   dsc->slice_count = 2;
+   dsc->slice_per_pkt = 1;
+   dsc->bits_per_component = 8;
+   dsc->bits_per_pixel = 8 << 4;
+   dsc->block_pred_enable = true;
+
+   dsi->dsc = dsc;
+   }
+
ctx->supplies[0].supply = "vddio";
ctx->supplies[1].supply = "vci";
ctx->supplies[2].supply = "vdd";
@@ -306,6 +359,9 @@ static int visionox_vtdr6130_probe(struct mipi_dsi_device 
*dsi)
return ret;
}
 
+   dev_err(&dsi->dev, "discovered with %s mode %s\n",
+   ctx->cmd_mode ? "cmd" : "video",
+   ctx->dsc_enable ? "and DSC enabled" : "");
return 0;
 }
 
-- 
2.34.1



[PATCH 2/3] dt-bindings: display: panel: visionox, vtdr6130: Add mode property

2024-03-28 Thread Jun Nie
Add DSI mode property and compression mode property

Signed-off-by: Jun Nie 
---
 .../bindings/display/panel/visionox,vtdr6130.yaml | 8 
 1 file changed, 8 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml 
b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml
index d5a8295106c1..36ae94fa96ec 100644
--- a/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml
+++ b/Documentation/devicetree/bindings/display/panel/visionox,vtdr6130.yaml
@@ -26,6 +26,14 @@ properties:
   port: true
   reset-gpios: true
 
+  enforce-cmd-mode:
+type: boolean
+description: Set DSI as command mode. Video mode by default.
+
+  enable-dsc:
+type: boolean
+description: Enable display stream compression
+
 additionalProperties: false
 
 required:
-- 
2.34.1



[PATCH 1/3] drm/msm/dpu: fix DSC for DSI video mode

2024-03-28 Thread Jun Nie
Fix DSC timing and control configurations in DPU for DSI video mode.
Only compression ratio 3:1 is handled and tested.

This patch is modified from patchs of Jonathan Marek.

Signed-off-by: Jun Nie 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  2 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 10 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  1 +
 drivers/gpu/drm/msm/dsi/dsi.xml.h |  1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c| 48 +++
 include/drm/display/drm_dsc.h |  4 ++
 8 files changed, 56 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 6a4b489d44e5..c1b9da06dde2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2440,7 +2440,7 @@ enum dpu_intf_mode dpu_encoder_get_intf_mode(struct 
drm_encoder *encoder)
return INTF_MODE_NONE;
 }
 
-unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc)
+unsigned int dpu_encoder_helper_get_dsc(const struct dpu_encoder_phys 
*phys_enc)
 {
struct drm_encoder *encoder = phys_enc->parent;
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(encoder);
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 993f26343331..5000fa22ad40 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -339,7 +339,7 @@ static inline enum dpu_3d_blend_mode 
dpu_encoder_helper_get_3d_blend_mode(
  *   used for this encoder.
  * @phys_enc: Pointer to physical encoder structure
  */
-unsigned int dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc);
+unsigned int dpu_encoder_helper_get_dsc(const struct dpu_encoder_phys 
*phys_enc);
 
 /**
  * dpu_encoder_helper_split_config - split display configuration helper 
function
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
index d0f56c5c4cce..c0ff39450e66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c
@@ -102,6 +102,8 @@ static void drm_mode_to_intf_timing_params(
}
 
timing->wide_bus_en = dpu_encoder_is_widebus_enabled(phys_enc->parent);
+   if (dpu_encoder_helper_get_dsc(phys_enc))
+   timing->dsc_en = true;
 
/*
 * for DP, divide the horizonal parameters by 2 when
@@ -114,6 +116,16 @@ static void drm_mode_to_intf_timing_params(
timing->h_front_porch = timing->h_front_porch >> 1;
timing->hsync_pulse_width = timing->hsync_pulse_width >> 1;
}
+
+   /*
+* for DSI, if compression is enabled, then divide the horizonal active
+* timing parameters by compression ratio.
+*/
+   if (phys_enc->hw_intf->cap->type != INTF_DP && timing->dsc_en) {
+   /* TODO: handle non 3:1 compression ratio, such as 30bpp case */
+   timing->width = timing->width / 3;
+   timing->xres = timing->width;
+   }
 }
 
 static u32 get_horizontal_total(const struct dpu_hw_intf_timing_params *timing)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 6bba531d6dc4..e2f6fa542883 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -168,10 +168,18 @@ static void dpu_hw_intf_setup_timing_engine(struct 
dpu_hw_intf *ctx,
 * video timing. It is recommended to enable it for all cases, except
 * if compression is enabled in 1 pixel per clock mode
 */
+   if (!p->dsc_en || p->wide_bus_en)
+   intf_cfg2 |= INTF_CFG2_DATA_HCTL_EN;
+
if (p->wide_bus_en)
-   intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN | INTF_CFG2_DATA_HCTL_EN;
+   intf_cfg2 |= INTF_CFG2_DATABUS_WIDEN;
+
+   if (p->dsc_en)
+   intf_cfg2 |= INTF_CFG2_DCE_DATA_COMPRESS;
 
data_width = p->width;
+   if (p->wide_bus_en && !dp_intf)
+   data_width = p->width >> 1;
 
hsync_data_start_x = hsync_start_x;
hsync_data_end_x =  hsync_start_x + data_width - 1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
index 0bd57a32144a..b452e3557d10 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -33,6 +33,7 @@ struct dpu_hw_intf_timing_params {
u32 hsync_skew;
 
bool wide_bus_en;
+   bool dsc_en;
 };
 
 struct dpu_hw_intf_prog_fetch {
diff --git a/drivers/gpu/d

Re: [PATCH] drm: bridge: adv7511: Add set_jack handler

2021-02-02 Thread Jun Nie
Jun Nie  于2021年1月19日周二 下午12:42写道:
>
> With commit 55c5cc63ab, the hdmi_codec_set_jack() will report unsupport
> failure if set_jack handler is missing. Add set_jack handler to resolve
> this failure.
>
> Signed-off-by: Jun Nie 
> ---
>  .../gpu/drm/bridge/adv7511/adv7511_audio.c| 27 ++-
>  1 file changed, 20 insertions(+), 7 deletions(-)
>

Does anyone have comments on this patch?

Thanks!
Jun
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH] drm: bridge: adv7511: Add set_jack handler

2021-01-19 Thread Jun Nie
With commit 55c5cc63ab, the hdmi_codec_set_jack() will report unsupport
failure if set_jack handler is missing. Add set_jack handler to resolve
this failure.

Signed-off-by: Jun Nie 
---
 .../gpu/drm/bridge/adv7511/adv7511_audio.c| 27 ++-
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c 
b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
index f101dd2819b5..16de1a8ca7a0 100644
--- a/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
+++ b/drivers/gpu/drm/bridge/adv7511/adv7511_audio.c
@@ -217,22 +217,35 @@ static int adv7511_hdmi_i2s_get_dai_id(struct 
snd_soc_component *component,
return -EINVAL;
 }
 
+static int adv7511_hdmi_i2s_hook_plugged_cb(struct device *dev, void *data,
+   hdmi_codec_plugged_cb fn,
+   struct device *codec_dev)
+{
+   struct adv7511 *adv7511 = data;
+   bool plugged = adv7511->connector.status == connector_status_connected;
+
+   fn(codec_dev, plugged);
+   return 0;
+}
+
 static const struct hdmi_codec_ops adv7511_codec_ops = {
.hw_params  = adv7511_hdmi_hw_params,
.audio_shutdown = audio_shutdown,
.audio_startup  = audio_startup,
.get_dai_id = adv7511_hdmi_i2s_get_dai_id,
-};
-
-static const struct hdmi_codec_pdata codec_data = {
-   .ops = &adv7511_codec_ops,
-   .max_i2s_channels = 2,
-   .i2s = 1,
-   .spdif = 1,
+   .hook_plugged_cb = adv7511_hdmi_i2s_hook_plugged_cb,
 };
 
 int adv7511_audio_init(struct device *dev, struct adv7511 *adv7511)
 {
+   struct hdmi_codec_pdata codec_data = {
+   .ops = &adv7511_codec_ops,
+   .max_i2s_channels = 2,
+   .i2s = 1,
+   .spdif = 1,
+   .data = adv7511,
+   };
+
adv7511->audio_pdev = platform_device_register_data(dev,
HDMI_CODEC_DRV_NAME,
PLATFORM_DEVID_AUTO,
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[RFC 0/5] Generic panel framework

2012-08-23 Thread Jun Nie
Hi Laurent,
Do you plan to add an API to get and parse EDID to mode list?
video mode is tightly coupled with panel that is capable of hot-plug.
Or you are busy on modifying EDID parsing code for sharing it amoung
DRM/FB/etc? I see you mentioned this in Mar. It is great if you are
considering add more info into video mode, such as pixel repeating, 3D
timing related parameter. I have some code for CEA modes filtering and
3D parsing, but still tight coupled with FB and with a little hack
style.

My HDMI driver is implemented as lcd device as you mentioned here.
But more complex than other lcd devices for a kthread is handling
hot-plug/EDID/HDCP/ASoC etc.

I also feel a little weird to add code parsing HDMI audio related
info in fbmod.c in my current implementation, thought it is the only
place to handle EDID in kernel. Your panel framework provide a better
place to add panel related audio/HDCP code. panel notifier can also
trigger hot-plug related feature, such as HDCP start.

Looking forward to your hot-plug panel patch. Or I can help add it
if you would like me to.

Thanks!
Jun


Re: [RFC 0/5] Generic panel framework

2012-08-23 Thread Jun Nie
Hi Laurent,
Do you plan to add an API to get and parse EDID to mode list?
video mode is tightly coupled with panel that is capable of hot-plug.
Or you are busy on modifying EDID parsing code for sharing it amoung
DRM/FB/etc? I see you mentioned this in Mar. It is great if you are
considering add more info into video mode, such as pixel repeating, 3D
timing related parameter. I have some code for CEA modes filtering and
3D parsing, but still tight coupled with FB and with a little hack
style.

My HDMI driver is implemented as lcd device as you mentioned here.
But more complex than other lcd devices for a kthread is handling
hot-plug/EDID/HDCP/ASoC etc.

I also feel a little weird to add code parsing HDMI audio related
info in fbmod.c in my current implementation, thought it is the only
place to handle EDID in kernel. Your panel framework provide a better
place to add panel related audio/HDCP code. panel notifier can also
trigger hot-plug related feature, such as HDCP start.

Looking forward to your hot-plug panel patch. Or I can help add it
if you would like me to.

Thanks!
Jun
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


Kernel Display and Video API Consolidation mini-summit at ELC 2012 - Notes

2012-05-17 Thread Jun Nie
Is there any discussion on HDCP on the summit? It is tightly
coupled with HDMI and DVI and should be managed together with the
transmitter. But there is not code to handle HDCP in DRM/FB/V4L in
latest kernel. Any thoughts on HDCP? Or you guys think there is risk
to support it in kernel? Thanks for your comments!

Jun


Re: Kernel Display and Video API Consolidation mini-summit at ELC 2012 - Notes

2012-05-17 Thread Jun Nie
Is there any discussion on HDCP on the summit? It is tightly
coupled with HDMI and DVI and should be managed together with the
transmitter. But there is not code to handle HDCP in DRM/FB/V4L in
latest kernel. Any thoughts on HDCP? Or you guys think there is risk
to support it in kernel? Thanks for your comments!

Jun
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel