Re: [Freedreno] [PATCH v2 4/7] drm/msm/dpu: allow just single IRQ callback

2022-01-18 Thread abhinavk
one>


On 2021-08-17 20:30, abhin...@codeaurora.org wrote:

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

DPU interrupts code allows multiple callbacks per interrut. In reality

/interrupt
none of the interrupts is shared between blocks (and will probably 
never

be). Drop support for registering multiple callbacks per interrupt to
simplify interrupt handling code.

Signed-off-by: Dmitry Baryshkov 


I need to check on why we had this design originally and we still do.
the idx with which we are registering today can generate only one hw 
interrupt.

But i am not sure if something for planned for future use. Will update
in a day or two.

meanwhile some comments and questions below.


I did check internally on the original design of this and yes the plan 
was for other
sub-modules to register for callbacks and that callback goes into the 
callback list.


For example, lets say for some reason some other modules like the DSI 
want to register
for the VSYNC interrupt, it can register for a callback and that will 
get added to the

callback list.

But, this never got used that way and even now there is only one 
callback per interrupt.
We dont have a concrete use-case where we will need this in the future 
but like many other things,

we cannot tell for certain.

Since there is no concrete use-case where we might need this, if you 
would like to go ahead

with this, please do.

Once you address the other comments on this, I can ack this.




---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h  |  18 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   6 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   2 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  10 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  |   6 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 144 
+++---

 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  12 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  10 +-
 9 files changed, 86 insertions(+), 134 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
index 90ae6c9ccc95..44ab97fb2964 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
@@ -46,10 +46,8 @@ u32 dpu_core_irq_read(
  * interrupt
  * @dpu_kms:   DPU handle
  * @irq_idx:   irq index
- * @irq_cb:IRQ callback structure, containing callback function
- * and argument. Passing NULL for irq_cb will unregister
- * the callback for the given irq_idx
- * This must exist until un-registration.
+ * @irq_cb:IRQ callback funcion.
+ * @irq_arg:   IRQ callback argument.
  * @return:0 for success registering callback, otherwise failure
  *
  * This function supports registration of multiple callbacks for each
interrupt.
@@ -57,17 +55,16 @@ u32 dpu_core_irq_read(
 int dpu_core_irq_register_callback(
struct dpu_kms *dpu_kms,
int irq_idx,
-   struct dpu_irq_callback *irq_cb);
+   void (*irq_cb)(void *arg, int irq_idx),
+   void *irq_arg);

 /**
  * dpu_core_irq_unregister_callback - For unregistering callback
function on IRQ
  * interrupt
  * @dpu_kms:   DPU handle
  * @irq_idx:   irq index
- * @irq_cb:IRQ callback structure, containing callback function
- * and argument. Passing NULL for irq_cb will unregister
- * the callback for the given irq_idx
- * This must match with registration.
+ * @irq_cb:IRQ callback funcion.

/function
this typo is there in multiple places

+ * @irq_arg:   IRQ callback argument.
  * @return:0 for success registering callback, otherwise failure
  *
  * This function supports registration of multiple callbacks for each
interrupt.
@@ -75,7 +72,8 @@ int dpu_core_irq_register_callback(
 int dpu_core_irq_unregister_callback(
struct dpu_kms *dpu_kms,
int irq_idx,
-   struct dpu_irq_callback *irq_cb);
+   void (*irq_cb)(void *arg, int irq_idx),
+   void *irq_arg);

 /**
  * dpu_debugfs_core_irq_init - register core irq debugfs
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1c04b7cce43e..d3557b0f4db9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -310,7 +310,7 @@ int dpu_encoder_helper_wait_for_irq(struct
dpu_encoder_phys *phys_enc,
  phys_enc->hw_pp->idx - PINGPONG_0,
  atomic_read(wait_info->atomic_cnt));
local_irq_save(flags);
-   irq->cb.func(phys_enc, irq->irq_idx);

Re: [Freedreno] [PATCH] drm/msm/dp: Move debugfs files into subdirectory

2021-12-09 Thread abhinavk

On 2021-10-18 11:36, Bjorn Andersson wrote:

On Mon 18 Oct 11:07 PDT 2021, abhin...@codeaurora.org wrote:


Hi Bjorn

On 2021-10-17 09:42, Bjorn Andersson wrote:
> On Fri 15 Oct 16:53 PDT 2021, abhin...@codeaurora.org wrote:
>
> > On 2021-10-15 16:17, Bjorn Andersson wrote:
> > > In the cleanup path of the MSM DP driver the DP driver's debugfs files
> > > are destroyed by invoking debugfs_remove_recursive() on debug->root,
> > > which during initialization has been set to minor->debugfs_root.
> > >
> > > To allow cleaning up the DP driver's debugfs files either each dentry
> > > needs to be kept track of or the files needs to be put in a subdirectory
> > > which can be removed in one go.
> > >
> > > By choosing to put the debugfs files in a subdirectory, based on the
> > > name of the associated connector this also solves the problem that these
> > > names would collide as support for multiple DP instances are introduced.
> > >
> > > One alternative solution to the problem with colliding file names would
> > > have been to put keep track of the individual files and put them under
> > > the connector's debugfs directory. But while the drm_connector has been
> > > allocated, its associated debugfs directory has not been created at the
> > > time of initialization of the dp_debug.
> > >
> > > Signed-off-by: Bjorn Andersson 
> >
> > I have been thinking about this problem ever since multi-DP has been
> > posted
> > :)
> > Creating sub-directories seems right but at the moment it looks like
> > IGT
> > which
> > uses these debugfs nodes doesnt check sub-directories:
> >
> > 
https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tools/msm_dp_compliance.c#L215
> >
> > It looks for the DP debugfs nodes under /sys/kernel/debug/dri/*/
> >
> > We have to fix IGT too to be able to handle multi-DP cases. I will
> > try to
> > come up
> > with a proposal to address this.
> >
> > Till then, can we go with the other solution to keep track of the
> > dentries?
> >
>
> I'm afraid I don't see what you're proposing.
>
> Afaict we need one set of dp_test{type,active,data} per DP controller,
> so even doing this by keeping track of the dentries requires that we
> rename the files based on some identifier (id or connector name) - which
> will cause igt to break.

Yes, I also thought the same that there needs to be some identifier.

"To allow cleaning up the DP driver's debugfs files either each dentry
needs to be kept track of or the files needs to be put in a 
subdirectory

which can be removed in one go"

I guess I misunderstood your statement in the commit text thinking 
that you

had some other way to keep track of the dentries as it mentioned that
use a subdirectory OR keep track of each dentry.



No, I did write that code as well and then ditched it.

Unfortunately I don't think it would help you, because we still need to
add some identifier to the file names and preferably we should add that
to the single case as well to make things consistent.


>
> As such, I think the practical path forward is that we merge the
> multi-DP series as currently proposed. This will not cause any issues on
> single-DP systems, but on multi-DP systems we will have warnings about
> duplicate debugfs entries in the kernel logs.
>
> Then you can figure out how to rework igt to deal with the multiple DP
> instances and update the dp_debug interface accordingly.
>

Fine with me, I will take care of this.



Cool, thanks.

Regards,
Bjorn


Following up on this, Rob has posted the igt change today which i acked.
https://patchwork.freedesktop.org/patch/465930/
With this in place, we can actually go ahead with this change.

Hence,

Reviewed-by: Abhinav Kumar 

>
> Which also implies that we should hold this patch back. But if we go
> that path, I think we should fix dp_debug_deinit() so that it doesn't
> remove /sys/kernel/debug/dri/128 when the DP driver is unloaded.
Yes, lets hold this patch back till I fix multi-DP for IGT.
>
> Regards,
> Bjorn
>
> > > ---
> > >
> > > This depends on
> > > 
https://lore.kernel.org/linux-arm-msm/20211010030435.4000642-1-bjorn.anders...@linaro.org/
> > > reducing the connector from a double pointer.
> > >
> > >  drivers/gpu/drm/msm/dp/dp_debug.c | 15 +--
> > >  1 file changed, 9 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
> > > b/drivers/gpu/drm/msm/dp/dp_debug.c
> > > index da4323556ef3..67da4c69eca1 100644
> > > --- a/drivers/gpu/drm/msm/dp/dp_debug.c
> > > +++ b/drivers/gpu/drm/msm/dp/dp_debug.c
> > > @@ -210,26 +210,29 @@ static const struct file_operations
> > > test_active_fops = {
> > >  static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor
> > > *minor)
> > >  {
> > >  int rc = 0;
> > > +char path[64];
> > >  struct dp_debug_private *debug = container_of(dp_debug,
> > >  struct dp_debug_private, dp_debug);
> > >
> > > -debugfs_create_file("dp_debug", 0444, 

Re: [Freedreno] [PATCH v2 22/22] drm/msm/dpu: add multirect support

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

If SmartDMA is supported by the hardware, SSPPs allow using two RGB
layers per the hardware pipe (with some additional restrictions, like 
no
support for scaling, etc). Register additional planes (two per the 
SSPP)

and check if we can use multirect during atomic_check.



I can see you are still making use of the dpu_rm_get_sspp() function to 
allocate SSPPs

for the drm planes even in the case of smart dma.

That function doesnt account for the foll considerations:

1) How does it guarantee plane priority while allocation? smart dma 
planes need to be allocated
in a priority order and that priority order decides which sspp does on 
the left rectangle and which one
on the right. I am not seeing how that is enforced in this 
implementation.


2) Another condition to be taken into account is that if one rectangle 
of one SSPP is utilized for one display,
the other rectangle of the SSPP cannot be used for another display. How 
is this guaranteed?

Does the RM global state account for this?


Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  18 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 109 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  29 +-
 4 files changed, 86 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 49bdd5953b9f..49bd9df387b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -892,7 +892,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
*crtc,
 	struct dpu_global_state *global_state = 
dpu_kms_get_global_state(state);


struct dpu_plane_state **pstates;
-   struct dpu_plane_state *pstate;
+   struct dpu_plane_state *pstate, *prev_plane_state;

struct drm_plane_state *plane_state;
struct drm_plane *plane;
@@ -962,6 +962,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
*crtc,

}

stage = DPU_STAGE_0;
+   prev_plane_state = NULL;
for (i = 0; i <= max_zpos; i++) {
pstate = pstates[i];
if (!pstate)
@@ -977,8 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
*crtc,


plane_state = >base;

-   dpu_plane_clear_multirect(plane_state);
-
dst = drm_plane_state_dest(plane_state);
if (!drm_rect_intersect(, _rect)) {
DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -990,7 +989,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
*crtc,

}

plane = pstate->base.plane;
-   rc = dpu_plane_set_pipe(plane, pstate);
+   rc = dpu_plane_set_pipe(plane, pstate, prev_plane_state);
if (rc) {
 			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, 
plane->name);

goto end;
@@ -1002,6 +1001,17 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
*crtc,

goto end;
}

+   /*
+* If this plane was not selected for multirect, so we can try
+* using it together with the next pipe.  If it selected for
+* the REC1, next pipe will have to start from REC_SOLO (and
+* maybe be promoted to REC0 later.
+*/
+   if (pstate->multirect_index == DPU_SSPP_RECT_SOLO)
+   prev_plane_state = pstate;
+   else
+   prev_plane_state = NULL;
+
pstates[i]->stage = stage++;
DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 08a7e56cc98f..c3c3972627ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -646,7 +646,7 @@ static int _dpu_kms_create_planes_virtual(struct
dpu_kms *dpu_kms, int max_crtc_
catalog = dpu_kms->catalog;

/* Create the planes, keeping track of one primary/cursor per crtc */
-   for (i = 0; i < catalog->sspp_count; i++) {
+   for (i = 0; i < 2 * catalog->sspp_count; i++) {
enum drm_plane_type type;

if (primary_planes_idx < max_crtc_count)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 420cdd90e89b..77cb4f172379 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -292,10 +292,10 @@ static u64 _dpu_plane_get_qos_lut(const struct
dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
  * @fb:Pointer to framebuffer associated with the 
given plane
- * @pipe_cfg:  Pointer 

Re: [Freedreno] [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

Client driven prefetch (CDP) is properly setup only for SSPP REC0
currently. Enable client driven prefetch also for SSPP REC1.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 12 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
 3 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index f93cdeb08ac7..96f2f3f12f34 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -75,6 +75,7 @@
 #define SSPP_TRAFFIC_SHAPER0x130
 #define SSPP_CDP_CNTL  0x134
 #define SSPP_UBWC_ERROR_STATUS 0x138
+#define SSPP_CDP_CNTL_REC1 0x13c
 #define SSPP_TRAFFIC_SHAPER_PREFILL0x150
 #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
 #define SSPP_TRAFFIC_SHAPER_REC1   0x158
@@ -624,10 +625,12 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct
dpu_hw_pipe *ctx,
 }

 static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cdp_cfg *cfg)
+   struct dpu_hw_pipe_cdp_cfg *cfg,
+   enum dpu_sspp_multirect_index index)
 {
u32 idx;
u32 cdp_cntl = 0;
+   u32 cdp_cntl_offset = 0;

if (!ctx || !cfg)
return;
@@ -635,6 +638,11 @@ static void dpu_hw_sspp_setup_cdp(struct 
dpu_hw_pipe *ctx,

if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
return;

+   if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
+   cdp_cntl_offset = SSPP_CDP_CNTL;
+   else
+   cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
+
if (cfg->enable)
cdp_cntl |= BIT(0);
if (cfg->ubwc_meta_enable)
@@ -644,7 +652,7 @@ static void dpu_hw_sspp_setup_cdp(struct 
dpu_hw_pipe *ctx,

if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64)
cdp_cntl |= BIT(3);

-   DPU_REG_WRITE(>hw, SSPP_CDP_CNTL, cdp_cntl);
+   DPU_REG_WRITE(>hw, cdp_cntl_offset, cdp_cntl);
 }

 static void _setup_layer_ops(struct dpu_hw_pipe *c,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index c5ac8defa073..19c5358b962c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -358,9 +358,11 @@ struct dpu_hw_sspp_ops {
 * setup_cdp - setup client driven prefetch
 * @ctx: Pointer to pipe context
 * @cfg: Pointer to cdp configuration
+* @index: rectangle index in multirect
 */
void (*setup_cdp)(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_cdp_cfg *cfg);
+   struct dpu_hw_pipe_cdp_cfg *cfg,
+   enum dpu_sspp_multirect_index index);
 };

 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d692136884ad..420cdd90e89b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1241,7 +1241,7 @@ static void dpu_plane_sspp_atomic_update(struct
drm_plane *plane)
DPU_FORMAT_IS_TILE(fmt);
cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;

-   pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
_cfg);
+   pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
_cfg,
pstate->multirect_index);
}
}


Re: [Freedreno] [PATCH v2 20/22] drm/msm/dpu: fix smart dma support

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported 
SmartDMA

version. Upstream driver does not do this, resulting in SSPP subdriver
not enbaling setup_multirect callback. Make SSPP subdriver check global
smart_dma_rev to decide if setup_multirect should be enabled.

Signed-off-by: Dmitry Baryshkov 


Instead of this approach, we can OR the DPU_SSPP_SMART_DMA_* to the 
features list?



---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 16 
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c|  9 +
 3 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index b8e0fece1f0b..d2321648b8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -185,7 +185,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+   .smart_dma_rev = DPU_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_src_split = true,
.has_dim_layer = true,
@@ -203,7 +203,7 @@ static const struct dpu_caps sc7180_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x9,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+   .smart_dma_rev = DPU_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_dim_layer = true,
.has_idle_pc = true,
@@ -217,7 +217,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+   .smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_src_split = true,
.has_dim_layer = true,
@@ -235,7 +235,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+   .smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
.ubwc_version = DPU_HW_UBWC_VER_40,
.has_src_split = true,
.has_dim_layer = true,
@@ -251,7 +251,7 @@ static const struct dpu_caps sc7280_dpu_caps = {
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0x7,
.qseed_type = DPU_SSPP_SCALER_QSEED4,
-   .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+   .smart_dma_rev = DPU_SMART_DMA_V2,
.ubwc_version = DPU_HW_UBWC_VER_30,
.has_dim_layer = true,
.has_idle_pc = true,
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 f3c5aa3f4b3f..66d7b43c0019 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -70,6 +70,18 @@ enum {
DPU_HW_UBWC_VER_40 = 0x400,
 };

+/**
+ * SmartDMA support
+ * @DPU_SMART_DMA_UNSUPPORTED,   SmartDMA not support
+ * @DPU_SMART_DMA_V1,   SmartDMA 1.0 support
+ * @DPU_SMART_DMA_V2,   SmartDMA 2.0 support
+ */
+enum {
+   DPU_SMART_DMA_UNSUPPORTED,
+   DPU_SMART_DMA_V1,
+   DPU_SMART_DMA_V2,
+};
+
 /**
  * MDP TOP BLOCK features
  * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per 
pipe

@@ -104,8 +116,6 @@ enum {
  * @DPU_SSPP_QOS,SSPP support QoS control, 
danger/safe/creq

  * @DPU_SSPP_QOS_8LVL,   SSPP support 8-level QoS control
  * @DPU_SSPP_EXCL_RECT,  SSPP supports exclusion rect
- * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
- * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
  * @DPU_SSPP_TS_PREFILL  Supports prefill with traffic shaper
  * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper 
multirec

  * @DPU_SSPP_CDP Supports client driven prefetch
@@ -124,8 +134,6 @@ enum {
DPU_SSPP_QOS,
DPU_SSPP_QOS_8LVL,
DPU_SSPP_EXCL_RECT,
-   DPU_SSPP_SMART_DMA_V1,
-   DPU_SSPP_SMART_DMA_V2,
DPU_SSPP_TS_PREFILL,
DPU_SSPP_TS_PREFILL_REC1,
DPU_SSPP_CDP,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 2be43d5a235a..f93cdeb08ac7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -648,7 +648,8 @@ static void dpu_hw_sspp_setup_cdp(struct 
dpu_hw_pipe *ctx,

 }

 static void _setup_layer_ops(struct dpu_hw_pipe 

Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property

2021-11-09 Thread abhinavk

On 2021-11-09 12:21, Dmitry Baryshkov wrote:

On Tue, 9 Nov 2021 at 23:15,  wrote:


On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Stop limiting zpos property values, we use normalized_zpos anyway. And
> nothing stops userspace from assigning several planes to a single zpos
> (it is a userspace bug, but the kernel is forgiving about it).

Userspace assigning several planes to a single zpos was intended to
identify
cases where src split can be used. Downstream does not use normalized
zpos,
hence it did not come across as a bug but mostly as a way to identify
when
usermode needs src split to be enabled based on the composition
strategy.

We can talk about that more in the rest of the patches of this series.

For this one, I only have a couple of questions:

1) Across different vendors, some have gone with limiting the zpos and
some have gone with
the max, so is there an issue with sticking with the max_blend_stages
limit?

2) If there is no hard reason to make this change, I think its better 
to

keep it the way it is.


Short answer to both questions: we want to have more planes than the
max_blend_stages. So we should remove the limit.

Consider this to be a unification with MDP5, which uses 255 here.


Alright, one minor comment below.

Also, what you have mentioned now "wanting to have more planes than 
blend stages"
should goto the commit text and the userspace bug part can be omitted as 
its technically

isnt a bug but just the way we intended it to be.






>
> Signed-off-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +--
>  1 file changed, 1 insertion(+), 10 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 8ed7b8f0db69..3850f2714bf3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -44,7 +44,6 @@
>  #define DPU_NAME_SIZE  12
>
>  #define DPU_PLANE_COLOR_FILL_FLAGBIT(31)
> -#define DPU_ZPOS_MAX 255
instead of getting rid of this, you can use this macro below where 255 
is hardcoded.

>
>  /* multirect rect index */
>  enum {
> @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
> drm_device *dev,
>   struct dpu_plane *pdpu;
>   struct msm_drm_private *priv = dev->dev_private;
>   struct dpu_kms *kms = to_dpu_kms(priv->kms);
> - int zpos_max = DPU_ZPOS_MAX;
>   uint32_t num_formats;
>   int ret = -EINVAL;
>
> @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
> drm_device *dev,
>
>   pdpu->catalog = kms->catalog;
>
> - if (kms->catalog->mixer_count &&
> - kms->catalog->mixer[0].sblk->maxblendstages) {
> - zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> - if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> - zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> - }
> -
> - ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> + ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
>   if (ret)
>   DPU_ERROR("failed to install zpos property, rc = %d\n", ret);


Re: [Freedreno] [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

Add support for handling and allocting SSPP blocks through the resource
manager. Handling code is not converted to use it though.

Signed-off-by: Dmitry Baryshkov 


Conceptually this is identical to the previous attempt from QC on this:

https://patchwork.kernel.org/project/dri-devel/patch/1529499020-8499-5-git-send-email-skoll...@codeaurora.org/

So I wanted to get your comments on the foll questions:

1) Originally the idea was that to add 4K support to DPU, we will expand 
on top of your series.
From our prior discussion on why the previous QC attempt was not taken 
over to add multirect support, the reason
was that it removed mutirect support which is was actually the end goal 
of this series. The end goal of the previous
attempt was to add 4K support hence looks like multirect was given lower 
priority and removed that time and not added

back.

But overall idea is the same which is to allocate hw sspps for drm 
planes to suit the requirement needed in the dpu_rm.


So to add 4K support on top of this series, we would just have to tweak 
dpu_rm_get_sspp to allocate 2x hw sspps right?



2) If the sspps are going to be iterated over a loop potentially every 
frame in the atomic check, wouldnt there be

a performance hit due to this?


+retry_loop:
+	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks) && pipe == SSPP_NONE; i++) 
{


This is where some help from usermode will help to optimize number of 
atomic_checks coming in.
If usermode tries atomic_checks too many times there can be potential 
glitches with this. Is that something

factored into this design?




---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 10 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 18 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c  | 81 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h  |  6 ++
 5 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 00098e33391e..c5ac8defa073 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -387,6 +387,16 @@ struct dpu_hw_pipe {
struct dpu_hw_sspp_ops ops;
 };

+/**
+ * to_dpu_hw_pipe - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_pipe *to_dpu_hw_pipe(struct dpu_hw_blk 
*hw)

+{
+   return container_of(hw, struct dpu_hw_pipe, base);
+}
+
 /**
  * dpu_hw_sspp_init - initializes the sspp hw driver object.
  * Should be called once before accessing every pipe.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index ab65c817eb42..04a2ab548f54 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -159,6 +159,7 @@ struct dpu_global_state {
uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
+   uint32_t pipe_to_plane_id[SSPP_MAX - SSPP_NONE];
 };

 struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3850f2714bf3..61008e8afb0a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1234,8 +1234,6 @@ static void dpu_plane_destroy(struct drm_plane 
*plane)

/* this will destroy the states as well */
drm_plane_cleanup(plane);

-   dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
kfree(pdpu);
}
 }
@@ -1389,14 +1387,13 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

pdpu->pipe = pipe;

/* initialize underlying h/w driver */
-   pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
-   if (IS_ERR(pdpu->pipe_hw)) {
-   DPU_ERROR("[%u]SSPP init failed\n", pipe);
-   ret = PTR_ERR(pdpu->pipe_hw);
+   if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
goto clean_plane;
-   } else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+   pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+
+   if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-   goto clean_sspp;
+   goto clean_plane;
}

format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1406,7 +1403,7 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

format_list, num_formats,
supported_format_modifiers, type, NULL);
if (ret)
-   goto clean_sspp;
+   goto clean_plane;

pdpu->catalog = kms->catalog;

@@ -1432,9 +1429,6 @@ 

Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

Stop limiting zpos property values, we use normalized_zpos anyway. And
nothing stops userspace from assigning several planes to a single zpos
(it is a userspace bug, but the kernel is forgiving about it).


Userspace assigning several planes to a single zpos was intended to 
identify
cases where src split can be used. Downstream does not use normalized 
zpos,
hence it did not come across as a bug but mostly as a way to identify 
when
usermode needs src split to be enabled based on the composition 
strategy.


We can talk about that more in the rest of the patches of this series.

For this one, I only have a couple of questions:

1) Across different vendors, some have gone with limiting the zpos and 
some have gone with
the max, so is there an issue with sticking with the max_blend_stages 
limit?


2) If there is no hard reason to make this change, I think its better to 
keep it the way it is.




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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8ed7b8f0db69..3850f2714bf3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -44,7 +44,6 @@
 #define DPU_NAME_SIZE  12

 #define DPU_PLANE_COLOR_FILL_FLAG  BIT(31)
-#define DPU_ZPOS_MAX 255

 /* multirect rect index */
 enum {
@@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

struct dpu_plane *pdpu;
struct msm_drm_private *priv = dev->dev_private;
struct dpu_kms *kms = to_dpu_kms(priv->kms);
-   int zpos_max = DPU_ZPOS_MAX;
uint32_t num_formats;
int ret = -EINVAL;

@@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,


pdpu->catalog = kms->catalog;

-   if (kms->catalog->mixer_count &&
-   kms->catalog->mixer[0].sblk->maxblendstages) {
-   zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
-   if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
-   zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
-   }
-
-   ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
+   ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
if (ret)
DPU_ERROR("failed to install zpos property, rc = %d\n", ret);


Re: [Freedreno] [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:

Add DPU_SSPP_CSC_ANY denoting any CSC block. As we are at it, rewrite
DPU_SSPP_SCALER (any scaler) to use BIT(x) instead of hand-coded
bitshifts.

This can go independent of the multi-rect series, so can you please take 
this with the

first half of the series which was going to be taken separately?

With that,
Reviewed-by: Abhinav Kumar 

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 264a9d0d5fca..00098e33391e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -25,11 +25,17 @@ struct dpu_hw_pipe;
 /**
  * Define all scaler feature bits in catalog
  */
-#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
-   (1UL << DPU_SSPP_SCALER_QSEED2) | \
-(1UL << DPU_SSPP_SCALER_QSEED3) | \
-(1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
- (1UL << DPU_SSPP_SCALER_QSEED4))
+#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
+BIT(DPU_SSPP_SCALER_QSEED2) | \
+BIT(DPU_SSPP_SCALER_QSEED3) | \
+BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
+BIT(DPU_SSPP_SCALER_QSEED4))
+
+/*
+ * Define all CSC feature bits in catalog
+ */
+#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
+ BIT(DPU_SSPP_CSC_10BIT))

 /**
  * Component indices
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 34ecd971cbbb..8ed7b8f0db69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -983,8 +983,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
*plane,


if (DPU_FORMAT_IS_YUV(fmt) &&
(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-!(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
-| BIT(DPU_SSPP_CSC_10BIT) {
+!(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
DPU_DEBUG_PLANE(pdpu,
"plane doesn't have scaler/csc for yuv\n");
return -EINVAL;


Re: [Freedreno] [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps

2021-11-09 Thread abhinavk

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
As we are going to add virtual planes, add the list of supported 
formats
to the hw catalog entry. It will be used to setup universal planes, 
with

later selecting a pipe depending on whether the YUV format is used for
the framebuffer.

Signed-off-by: Dmitry Baryshkov 


I dont see an issue with exposing the format_list in the catalog, hence
Reviewed-by: Abhinav Kumar 


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 
 2 files changed, 14 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index d01c4c919504..b8e0fece1f0b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -195,6 +195,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };

 static const struct dpu_caps sc7180_dpu_caps = {
@@ -207,6 +209,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };

 static const struct dpu_caps sm8150_dpu_caps = {
@@ -223,6 +227,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_hdeci_exp = MAX_HORZ_DECIMATION,
.max_vdeci_exp = MAX_VERT_DECIMATION,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };

 static const struct dpu_caps sm8250_dpu_caps = {
@@ -237,6 +243,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
.has_3d_merge = true,
.max_linewidth = 4096,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };

 static const struct dpu_caps sc7280_dpu_caps = {
@@ -249,6 +257,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
.has_idle_pc = true,
.max_linewidth = 2400,
.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+   .format_list = plane_formats_yuv,
+   .num_formats = ARRAY_SIZE(plane_formats_yuv),
 };

 static const struct dpu_mdp_cfg sdm845_mdp[] = {
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 d2a945a27cfa..f3c5aa3f4b3f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -324,6 +324,8 @@ struct dpu_qos_lut_tbl {
  * @pixel_ram_size size of latency hiding and de-tiling buffer in 
bytes
  * @max_hdeci_exp  max horizontal decimation supported (max is 
2^value)
  * @max_vdeci_exp  max vertical decimation supported (max is 
2^value)

+ * @format_list: Pointer to list of supported formats
+ * @num_formats: Number of supported formats
  */
 struct dpu_caps {
u32 max_mixer_width;
@@ -340,6 +342,8 @@ struct dpu_caps {
u32 pixel_ram_size;
u32 max_hdeci_exp;
u32 max_vdeci_exp;
+   const u32 *format_list;
+   u32 num_formats;
 };

 /**


Re: [Freedreno] [PATCH v3 04/14] drm/hdcp: Expand HDCP helper library for enable/disable/check

2021-10-22 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the "shim" vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Cc: Abhinav Kumar 
Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 


For vendors/chipsets supporting HW polling, this needs rework to skip 
the SW

polling, as agreed this will be done in a follow up change. Hence,

Reviewed-by: Abhinav Kumar 


Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-5-s...@poorly.run
#v2

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
Changes in v3:
-Fixed uninitialized variable warning identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 1103 
 include/drm/drm_hdcp.h |  191 +++
 2 files changed, 1294 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 8c851d40cd45..2bfa07fc3fbc 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -6,15 +6,20 @@
  * Ramalingam C 
  */

+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -513,3 +518,1101 @@ bool drm_hdcp_atomic_check(struct drm_connector
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_ddc_lut = {

+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_dpcd_lut = {

+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+	 * definition by different names. In the HDMI spec, it's called 
BSTATUS,

+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+static int drm_hdcp_remote_ddc_read(struct i2c_adapter *i2c,
+   unsigned int offset, 

Re: [Freedreno] [PATCH v3 09/14] drm/msm/dpu: Remove useless checks in dpu_encoder

2021-10-22 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

A couple more useless checks to remove in dpu_encoder.

Reviewed-by: Stephen Boyd 
Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-10-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-10-s...@poorly.run
#v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 12 
 1 file changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e9d3fa1544b..984f8a59cb73 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1153,10 +1153,6 @@ static void dpu_encoder_virt_enable(struct
drm_encoder *drm_enc)
struct msm_drm_private *priv;
struct drm_display_mode *cur_mode = NULL;

-   if (!drm_enc) {
-   DPU_ERROR("invalid encoder\n");
-   return;
-   }
dpu_enc = to_dpu_encoder_virt(drm_enc);

mutex_lock(_enc->enc_lock);
@@ -1203,14 +1199,6 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
struct msm_drm_private *priv;
int i = 0;

-   if (!drm_enc) {
-   DPU_ERROR("invalid encoder\n");
-   return;
-   } else if (!drm_enc->dev) {
-   DPU_ERROR("invalid dev\n");
-   return;
-   }
-
dpu_enc = to_dpu_encoder_virt(drm_enc);
DPU_DEBUG_ENC(dpu_enc, "\n");


Re: [Freedreno] [PATCH v3 03/14] drm/hdcp: Update property value on content type and user changes

2021-10-22 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

This patch updates the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-4-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-4-s...@poorly.run
#v2

Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index dd8fa91c51d6..8c851d40cd45 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -487,21 +487,29 @@ bool drm_hdcp_atomic_check(struct drm_connector
*connector,
return true;

/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
+* Content type changes require an HDCP disable/enable cycle.
+*/
+	if (new_conn_state->hdcp_content_type != 
old_conn_state->hdcp_content_type) {

+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
 *  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+*  - Attempting to set to desired while already enabled
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}

-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);


Re: [Freedreno] [PATCH v3 01/14] drm/hdcp: Add drm_hdcp_atomic_check()

2021-10-22 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

This patch moves the hdcp atomic check from i915 to drm_hdcp so other
drivers can use it. No functional changes, just cleaned up some of the
code when moving it over.

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 

For the drm/hdcp pieces:
Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-2-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-2-s...@poorly.run
#v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/drm_hdcp.c  | 71 -
 drivers/gpu/drm/i915/display/intel_atomic.c |  4 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c   | 47 --
 drivers/gpu/drm/i915/display/intel_hdcp.h   |  3 -
 include/drm/drm_hdcp.h  |  3 +
 5 files changed, 75 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index ca9b8f697202..522326b03e66 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -13,13 +13,14 @@
 #include 
 #include 

+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
-#include 

 #include "drm_internal.h"

@@ -421,3 +422,71 @@ void drm_hdcp_update_content_protection(struct
drm_connector *connector,
 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_hdcp_atomic_check - Helper for drivers to call during
connector->atomic_check
+ *
+ * @state: pointer to the atomic state being checked
+ * @connector: drm_connector on which content protection state needs 
an update

+ *
+ * This function can be used by display drivers to perform an atomic
check on the
+ * hdcp state elements. If hdcp state has changed, this function will 
set
+ * mode_changed on the crtc driving the connector so it can update its 
hardware

+ * to match the hdcp state.
+ */
+void drm_hdcp_atomic_check(struct drm_connector *connector,
+  struct drm_atomic_state *state)
+{
+   struct drm_connector_state *new_conn_state, *old_conn_state;
+   struct drm_crtc_state *new_crtc_state;
+   u64 old_hdcp, new_hdcp;
+
+	old_conn_state = drm_atomic_get_old_connector_state(state, 
connector);

+   old_hdcp = old_conn_state->content_protection;
+
+	new_conn_state = drm_atomic_get_new_connector_state(state, 
connector);

+   new_hdcp = new_conn_state->content_protection;
+
+   if (!new_conn_state->crtc) {
+   /*
+* If the connector is being disabled with CP enabled, mark it
+* desired so it's re-enabled when the connector is brought back
+*/
+   if (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED)
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return;
+   }
+
+   new_crtc_state = drm_atomic_get_new_crtc_state(state,
+  new_conn_state->crtc);
+   /*
+   * Fix the HDCP uapi content protection state in case of modeset.
+	* FIXME: As per HDCP content protection property uapi doc, an 
uevent()

+   * need to be sent if there is transition from ENABLED->DESIRED.
+   */
+   if (drm_atomic_crtc_needs_modeset(new_crtc_state) &&
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp != DRM_MODE_CONTENT_PROTECTION_UNDESIRED))
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+
+   /*
+* Nothing to do if content type is unchanged and one of:
+*  - state didn't change
+*  - HDCP was activated since the last commit
+*  - attempting to set to desired while already enabled
+*/
+   if (old_hdcp == new_hdcp ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
+   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
+   if (old_conn_state->hdcp_content_type ==
+   new_conn_state->hdcp_content_type)
+   return;
+   }
+
+   new_crtc_state->mode_changed = true;
+}
+EXPORT_SYMBOL(drm_hdcp_atomic_check);
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c
b/drivers/gpu/drm/i915/display/intel_atomic.c
index b4e7ac51aa31..1e306e8427ec 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -32,13 +32,13 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 #include "intel_atomic.h"
 #include "intel_cdclk.h"
 #include "intel_display_types.h"
 #include "intel_global_state.h"
-#include "intel_hdcp.h"
 #include "intel_psr.h"
 #include 

Re: [PATCH v3 10/14] drm/msm/dpu: Remove encoder->enable() hack

2021-10-22 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

encoder->commit() was being misused because there were some global
resources which needed to be tweaked in encoder->enable() which were 
not

accessible in dpu_encoder.c. That is no longer true and the redirect
serves no purpose any longer. So remove the indirection.

Reviewed-by: Stephen Boyd 
Tested-by: Stephen Boyd 
Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-11-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-11-s...@poorly.run
#v2

Changes in v2:
-None
Changes in v3:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  5 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 22 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h |  2 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  4 
 4 files changed, 1 insertion(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 984f8a59cb73..ddc542a0d41f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2122,11 +2122,8 @@ static void
dpu_encoder_frame_done_timeout(struct timer_list *t)
 static const struct drm_encoder_helper_funcs dpu_encoder_helper_funcs 
= {

.mode_set = dpu_encoder_virt_mode_set,
.disable = dpu_encoder_virt_disable,
-   .enable = dpu_kms_encoder_enable,
+   .enable = dpu_encoder_virt_enable,
.atomic_check = dpu_encoder_virt_atomic_check,
-
-   /* This is called by dpu_kms_encoder_enable */
-   .commit = dpu_encoder_virt_enable,
 };

 static const struct drm_encoder_funcs dpu_encoder_funcs = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index fb0d9f781c66..4a0b55d145ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -381,28 +381,6 @@ static void dpu_kms_flush_commit(struct msm_kms
*kms, unsigned crtc_mask)
}
 }

-/*
- * Override the encoder enable since we need to setup the inline 
rotator and do

- * some crtc magic before enabling any bridge that might be present.
- */
-void dpu_kms_encoder_enable(struct drm_encoder *encoder)
-{
-	const struct drm_encoder_helper_funcs *funcs = 
encoder->helper_private;

-   struct drm_device *dev = encoder->dev;
-   struct drm_crtc *crtc;
-
-   /* Forward this enable call to the commit hook */
-   if (funcs && funcs->commit)
-   funcs->commit(encoder);
-
-   drm_for_each_crtc(crtc, dev) {
-   if (!(crtc->state->encoder_mask & drm_encoder_mask(encoder)))
-   continue;
-
-   trace_dpu_kms_enc_enable(DRMID(crtc));
-   }
-}
-
 static void dpu_kms_complete_commit(struct msm_kms *kms, unsigned 
crtc_mask)

 {
struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 323a6bce9e64..f1ebb60dacab 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -248,8 +248,6 @@ void *dpu_debugfs_get_root(struct dpu_kms 
*dpu_kms);

 int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
 void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);

-void dpu_kms_encoder_enable(struct drm_encoder *encoder);
-
 /**
  * dpu_kms_get_clk_rate() - get the clock rate
  * @dpu_kms:  pointer to dpu_kms structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 37bba57675a8..54d74341e690 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -266,10 +266,6 @@ DEFINE_EVENT(dpu_drm_obj_template,
dpu_crtc_complete_commit,
TP_PROTO(uint32_t drm_id),
TP_ARGS(drm_id)
 );
-DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_enc_enable,
-   TP_PROTO(uint32_t drm_id),
-   TP_ARGS(drm_id)
-);
 DEFINE_EVENT(dpu_drm_obj_template, dpu_kms_commit,
TP_PROTO(uint32_t drm_id),
TP_ARGS(drm_id)


Re: [Freedreno] [PATCH 11/11] drm/msm/dpu: rip out debugfs support from dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 07:00, Dmitry Baryshkov wrote:

In preparations of virtualizing the dpu_plane rip out debugfs support
from dpu_plane (as it is mostly used to expose plane's pipe registers).
Also move disable_danger file to danger/ debugfs subdir where it 
belongs.


Signed-off-by: Dmitry Baryshkov 


I am yet to review the second part of the virtual plane series to 
understand why this removal

is necessary so I might be missing something.

The plane's debugfs holds useful information to check a few things 
rightaway.


So if there is some misconfiguration or corruption in addition to the 
plane state,

this is good to check.

localhost /sys/kernel/debug/dri/1/plane35 # cat src_blk
[4000] 03000556   03000556
[4010]  00414000  0040e000
[4020]  1600 0080 
[4030] 800236ff 03010002 8001 
[4040]  0030 000c0087 0707
[4050]    
[4060]    0001
[4070]  44556677 00112233 
[4080]    
[4090]    
[40a0]  00414000  0040e000
[40b0]    
[40c0]    
[40d0] 0003f820   
[40e0] 0003e2c4   
[40f0] 000f000f 00010330 02e402e4 
[4100]   03000556 
[4110]   03000556 
[4120]   03000556 
[4130]  000f  000f
[4140]    

So I would like to keep this functionality unless there is some 
compelling reason

to remove this.

BTW, are you going to submit the second half as a new series now that 
most

of the first one has been reviewed?


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 123 
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  69 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 171 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   6 +
 4 files changed, 69 insertions(+), 300 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae48f41821cf..fe33273cdf57 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -101,84 +101,85 @@ static int dpu_debugfs_safe_stats_show(struct
seq_file *s, void *v)
 }
 DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_safe_stats);

-static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
-   struct dentry *parent)
+static ssize_t _dpu_plane_danger_read(struct file *file,
+   char __user *buff, size_t count, loff_t *ppos)
 {
-   struct dentry *entry = debugfs_create_dir("danger", parent);
+   struct dpu_kms *kms = file->private_data;
+   int len;
+   char buf[40];

-   debugfs_create_file("danger_status", 0600, entry,
-   dpu_kms, _debugfs_danger_stats_fops);
-   debugfs_create_file("safe_status", 0600, entry,
-   dpu_kms, _debugfs_safe_stats_fops);
+   len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
+
+   return simple_read_from_buffer(buff, count, ppos, buf, len);
 }

-static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
+static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool 
enable)

 {
-   struct dpu_debugfs_regset32 *regset = s->private;
-   struct dpu_kms *dpu_kms = regset->dpu_kms;
-   void __iomem *base;
-   uint32_t i, addr;
-
-   if (!dpu_kms->mmio)
-   return 0;
-
-   base = dpu_kms->mmio + regset->offset;
-
-   /* insert padding spaces, if needed */
-   if (regset->offset & 0xF) {
-   seq_printf(s, "[%x]", regset->offset & ~0xF);
-   for (i = 0; i < (regset->offset & 0xF); i += 4)
-   seq_puts(s, " ");
-   }
-
-   pm_runtime_get_sync(_kms->pdev->dev);
-
-   /* main register output */
-   for (i = 0; i < regset->blk_len; i += 4) {
-   addr = regset->offset + i;
-   if ((addr & 0xF) == 0x0)
-   seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
-   seq_printf(s, " %08x", readl_relaxed(base + i));
+   struct drm_plane *plane;
+
+   drm_for_each_plane(plane, kms->dev) {
+   if (plane->fb && plane->state) {
+   dpu_plane_danger_signal_ctrl(plane, enable);
+   DPU_DEBUG("plane:%d img:%dx%d ",
+   plane->base.id, plane->fb->width,
+   plane->fb->height);
+   DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
+   plane->state->src_x >> 16,
+   plane->state->src_y >> 16,
+   plane->state->src_w >> 16,
+   plane->state->src_h >> 16,
+  

Re: [Freedreno] [PATCH 10/11] drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 07:00, Dmitry Baryshkov wrote:

Do not cache hw_pipe's sblk in dpu_plane. Use
pdpu->pipe_hw->cap->sblk directly.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 25 ---
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index af403c0d3d7d..d8018e664925 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -109,8 +109,6 @@ struct dpu_plane {
struct list_head mplane_list;
struct dpu_mdss_cfg *catalog;

-   const struct dpu_sspp_sub_blks *pipe_sblk;
-
/* debugfs related stuff */
struct dentry *debugfs_root;
struct dpu_debugfs_regset32 debugfs_src;
@@ -425,9 +423,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
drm_plane *plane,

memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));

if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-   pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
+   pipe_qos_cfg.creq_vblank = 
pdpu->pipe_hw->cap->sblk->creq_vblank;
pipe_qos_cfg.danger_vblank =
-   pdpu->pipe_sblk->danger_vblank;
+   pdpu->pipe_hw->cap->sblk->danger_vblank;
pipe_qos_cfg.vblank_en = enable;
}

@@ -982,10 +980,10 @@ static int dpu_plane_atomic_check(struct 
drm_plane *plane,

crtc_state = drm_atomic_get_new_crtc_state(state,
   
new_plane_state->crtc);

-   min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
+   min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, 
crtc_state,

  min_scale,
- pdpu->pipe_sblk->maxdwnscale 
<< 16,
+ 
pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
  true, true);
if (ret) {
DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -1611,20 +1609,13 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

goto clean_sspp;
}

-   /* cache features mask for later */
-   pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
-   if (!pdpu->pipe_sblk) {
-   DPU_ERROR("[%u]invalid sblk\n", pipe);
-   goto clean_sspp;
-   }
-
if (pdpu->is_virtual) {
-   format_list = pdpu->pipe_sblk->virt_format_list;
-   num_formats = pdpu->pipe_sblk->virt_num_formats;
+   format_list = pdpu->pipe_hw->cap->sblk->virt_format_list;
+   num_formats = pdpu->pipe_hw->cap->sblk->virt_num_formats;
}
else {
-   format_list = pdpu->pipe_sblk->format_list;
-   num_formats = pdpu->pipe_sblk->num_formats;
+   format_list = pdpu->pipe_hw->cap->sblk->format_list;
+   num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
}

ret = drm_universal_plane_init(dev, plane, 0xff, _plane_funcs,


Re: [Freedreno] [PATCH 09/11] drm/msm/dpu: don't cache pipe->cap->features in dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 07:00, Dmitry Baryshkov wrote:

Do not cache hw_pipe's features in dpu_plane. Use
pdpu->pipe_hw->cap->features directly.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 +---
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d3ae0cb2047c..af403c0d3d7d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -100,7 +100,6 @@ struct dpu_plane {
struct mutex lock;

enum dpu_sspp pipe;
-   uint32_t features;  /* capabilities from catalog */

struct dpu_hw_pipe *pipe_hw;
uint32_t color_fill;
@@ -644,7 +643,7 @@ static const struct dpu_csc_cfg
*_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
if (!DPU_FORMAT_IS_YUV(fmt))
return NULL;

-   if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->features)
+   if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
csc_ptr = _csc10_YUV2RGB_601L;
else
csc_ptr = _csc_YUV2RGB_601L;
@@ -1012,8 +1011,8 @@ static int dpu_plane_atomic_check(struct 
drm_plane *plane,

min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;

if (DPU_FORMAT_IS_YUV(fmt) &&
-   (!(pdpu->features & DPU_SSPP_SCALER) ||
-!(pdpu->features & (BIT(DPU_SSPP_CSC)
+   (!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+!(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
 | BIT(DPU_SSPP_CSC_10BIT) {
DPU_DEBUG_PLANE(pdpu,
"plane doesn't have scaler/csc for yuv\n");
@@ -1439,8 +1438,8 @@ static int _dpu_plane_init_debugfs(struct
drm_plane *plane)
plane->dev->primary->debugfs_root);

/* don't error check these */
-   debugfs_create_x32("features", 0600,
-   pdpu->debugfs_root, >features);
+   debugfs_create_xul("features", 0600,
+			pdpu->debugfs_root, (unsigned long 
*)>pipe_hw->cap->features);


/* add register dump support */
dpu_debugfs_setup_regset32(>debugfs_src,
@@ -1613,7 +1612,6 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

}

/* cache features mask for later */
-   pdpu->features = pdpu->pipe_hw->cap->features;
pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
if (!pdpu->pipe_sblk) {
DPU_ERROR("[%u]invalid sblk\n", pipe);


Re: [Freedreno] [PATCH 08/11] drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:

Remove struct dpu_hw_pipe_cdp_cfg instance from dpu_plane, it is an
interim configuration structure. Allocate it on stack instead.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 14 +++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 --
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b8836c089863..d3ae0cb2047c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1182,20 +1182,20 @@ static void
dpu_plane_sspp_atomic_update(struct drm_plane *plane)
pstate->multirect_index);

if (pdpu->pipe_hw->ops.setup_cdp) {
-   struct dpu_hw_pipe_cdp_cfg *cdp_cfg = >cdp_cfg;
+   struct dpu_hw_pipe_cdp_cfg cdp_cfg;

-   memset(cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
+   memset(_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));

-   cdp_cfg->enable = pdpu->catalog->perf.cdp_cfg
+   cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
[DPU_PERF_CDP_USAGE_RT].rd_enable;
-   cdp_cfg->ubwc_meta_enable =
+   cdp_cfg.ubwc_meta_enable =
DPU_FORMAT_IS_UBWC(fmt);
-   cdp_cfg->tile_amortize_enable =
+   cdp_cfg.tile_amortize_enable =
DPU_FORMAT_IS_UBWC(fmt) ||
DPU_FORMAT_IS_TILE(fmt);
-   cdp_cfg->preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
+   cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;

-   pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg);
+   pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, _cfg);
}
}

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 087194be3c22..1ee5ca5fcdf7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,7 +23,6 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:   whether the current update is still pending
- * @cdp_cfg:   CDP configuration
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
  */
@@ -36,7 +35,6 @@ struct dpu_plane_state {
uint32_t multirect_mode;
bool pending;

-   struct dpu_hw_pipe_cdp_cfg cdp_cfg;
u64 plane_fetch_bw;
u64 plane_clk;
 };


Re: [Freedreno] [PATCH 07/11] drm/msm/dpu: drop dpu_csc_cfg from dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:
Simplify code surrounding CSC table setup by removing struct 
dpu_csc_cfg

pointer from dpu_plane and getting it directly at the CSC setup time.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 96 +++--
 5 files changed, 54 insertions(+), 50 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index cbafb61404d0..103d4bd7585b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -537,7 +537,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct
dpu_hw_pipe *ctx,
 }

 static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
-   struct dpu_csc_cfg *data)
+   const struct dpu_csc_cfg *data)
 {
u32 idx;
bool csc10 = false;
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 27263bc1a1ef..e8939d7387cb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -262,7 +262,7 @@ struct dpu_hw_sspp_ops {
 * @ctx: Pointer to pipe context
 * @data: Pointer to config structure
 */
-   void (*setup_csc)(struct dpu_hw_pipe *ctx, struct dpu_csc_cfg *data);
+	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg 
*data);


/**
 * setup_solidfill - enable/disable colorfill
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
index f94584c982cd..aad85116b0a0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
@@ -374,7 +374,7 @@ u32 dpu_hw_get_scaler3_ver(struct 
dpu_hw_blk_reg_map *c,


 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
u32 csc_reg_off,
-   struct dpu_csc_cfg *data, bool csc10)
+   const struct dpu_csc_cfg *data, bool csc10)
 {
static const u32 matrix_shift = 7;
u32 clamp_shift = csc10 ? 16 : 8;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index ff3cffde84cd..bc2fdb2b8f5f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -321,6 +321,6 @@ u32 dpu_hw_get_scaler3_ver(struct 
dpu_hw_blk_reg_map *c,


 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
u32 csc_reg_off,
-   struct dpu_csc_cfg *data, bool csc10);
+   const struct dpu_csc_cfg *data, bool csc10);

 #endif /* _DPU_HW_UTIL_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 4259c4ecde9b..b8836c089863 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -90,7 +90,6 @@ enum dpu_plane_qos {
 /*
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
- * @csc_ptr: Points to dpu_csc_cfg structure to use for current
  * @mplane_list: List of multirect planes of the same pipe
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
@@ -111,8 +110,6 @@ struct dpu_plane {
struct list_head mplane_list;
struct dpu_mdss_cfg *catalog;

-   struct dpu_csc_cfg *csc_ptr;
-
const struct dpu_sspp_sub_blks *pipe_sblk;

/* debugfs related stuff */
@@ -605,51 +602,59 @@ static void _dpu_plane_setup_scaler3(struct
dpu_plane *pdpu,
scale_cfg->enable = 1;
 }

-static void _dpu_plane_setup_csc(struct dpu_plane *pdpu)
-{
-   static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
-   {
-   /* S15.16 format */
-   0x00012A00, 0x, 0x00019880,
-   0x00012A00, 0x9B80, 0x3000,
-   0x00012A00, 0x00020480, 0x,
+static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
+   {
+   /* S15.16 format */
+   0x00012A00, 0x, 0x00019880,
+   0x00012A00, 0x9B80, 0x3000,
+   0x00012A00, 0x00020480, 0x,
+   },
+   /* signed bias */
+   { 0xfff0, 0xff80, 0xff80,},
+   { 0x0, 0x0, 0x0,},
+   /* unsigned clamp */
+   { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
+   { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
+};
+
+static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
+   {
+   /* S15.16 format */
+   0x00012A00, 0x, 0x00019880,
+   0x00012A00, 0x9B80, 0x3000,
+   0x00012A00, 0x00020480, 0x,
   

Re: [Freedreno] [PATCH 06/11] drm/msm/dpu: drop scaler config from plane state

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:
Scaler and pixel_ext configuration does not contain a long living 
state,

it is used only during plane update, so remove these two fiels from

fiels ---> fields

dpu_plane_state and allocate them on stack.

Signed-off-by: Dmitry Baryshkov 


While addressing the bugs reported by the smatch tool, I saw that pe is 
not

being used at the moment.

412 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
413 struct dpu_hw_pipe_cfg *sspp,
414 struct dpu_hw_pixel_ext *pe,
415 void *scaler_cfg)
416 {
417 u32 idx;
418 struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
419
420 (void)pe;
421 if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, ) || !sspp
422 || !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk)
423 return;
424
425 dpu_hw_setup_scaler3(>hw, scaler3_cfg, idx,
426 ctx->cap->sblk->scaler_blk.version,
427 sspp->layout.format);
428 }

As part of this change, can you please drop this?


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 59 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ---
 2 files changed, 26 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5288b5b824f8..4259c4ecde9b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -542,14 +542,12 @@ static void _dpu_plane_setup_scaler3(struct
dpu_plane *pdpu,
struct dpu_plane_state *pstate,
uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
struct dpu_hw_scaler3_cfg *scale_cfg,
+   struct dpu_hw_pixel_ext *pixel_ext,
const struct dpu_format *fmt,
uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
 {
uint32_t i;

-   memset(scale_cfg, 0, sizeof(*scale_cfg));
-   memset(>pixel_ext, 0, sizeof(struct dpu_hw_pixel_ext));
-
scale_cfg->phase_step_x[DPU_SSPP_COMP_0] =
mult_frac((1 << PHASE_STEP_SHIFT), src_w, dst_w);
scale_cfg->phase_step_y[DPU_SSPP_COMP_0] =
@@ -588,9 +586,9 @@ static void _dpu_plane_setup_scaler3(struct 
dpu_plane *pdpu,

scale_cfg->preload_y[i] = DPU_QSEED3_DEFAULT_PRELOAD_V;
}

-   pstate->pixel_ext.num_ext_pxls_top[i] =
+   pixel_ext->num_ext_pxls_top[i] =
scale_cfg->src_height[i];
-   pstate->pixel_ext.num_ext_pxls_left[i] =
+   pixel_ext->num_ext_pxls_left[i] =
scale_cfg->src_width[i];
}
if (!(DPU_FORMAT_IS_YUV(fmt)) && (src_h == dst_h)
@@ -660,6 +658,11 @@ static void _dpu_plane_setup_scaler(struct 
dpu_plane *pdpu,

struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	const struct drm_format_info *info = 
drm_format_info(fmt->base.pixel_format);

+   struct dpu_hw_scaler3_cfg scaler3_cfg;
+   struct dpu_hw_pixel_ext pixel_ext;
+
+   memset(_cfg, 0, sizeof(scaler3_cfg));
+   memset(_ext, 0, sizeof(pixel_ext));

/* don't chroma subsample if decimating */
/* update scaler. calculate default config for QSEED3 */
@@ -668,8 +671,23 @@ static void _dpu_plane_setup_scaler(struct 
dpu_plane *pdpu,

drm_rect_height(_cfg->src_rect),
drm_rect_width(_cfg->dst_rect),
drm_rect_height(_cfg->dst_rect),
-   >scaler3_cfg, fmt,
+   _cfg, _ext, fmt,
info->hsub, info->vsub);
+
+   if (pdpu->pipe_hw->ops.setup_pe)
+   pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+   _ext);
+
+   /**
+* when programmed in multirect mode, scalar block will be
+* bypassed. Still we need to update alpha and bitwidth
+* ONLY for RECT0
+*/
+   if (pdpu->pipe_hw->ops.setup_scaler &&
+   pstate->multirect_index != DPU_SSPP_RECT_1)
+   pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+   pipe_cfg, _ext,
+   _cfg);
 }

 /**
@@ -710,7 +728,6 @@ static int _dpu_plane_color_fill(struct dpu_plane 
*pdpu,

drm_rect_width(_cfg.dst_rect);
pipe_cfg.src_rect.y2 =
drm_rect_height(_cfg.dst_rect);
-   _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, _cfg);

if (pdpu->pipe_hw->ops.setup_format)
pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
@@ -722,15 +739,7 @@ static int _dpu_plane_color_fill(struct dpu_plane 
*pdpu,

_cfg,
pstate->multirect_index);

-   if (pdpu->pipe_hw->ops.setup_pe)
-   

Re: [Freedreno] [PATCH 05/11] drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:

struct dpu_hw_pipe_cfg represents an interim state during atomic
update/color fill, so move it out of struct dpu_plane.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 --
 1 file changed, 57 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ef3737642b0c..5288b5b824f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
uint32_t features;  /* capabilities from catalog */

struct dpu_hw_pipe *pipe_hw;
-   struct dpu_hw_pipe_cfg pipe_cfg;
uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -143,14 +142,15 @@ static struct dpu_kms *_dpu_plane_get_kms(struct
drm_plane *plane)
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
  * @plane: Pointer to drm plane.
  * @fb:   Pointer to framebuffer associated with the given plane
+ * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
-   struct drm_framebuffer *fb)
+   struct drm_framebuffer *fb,
+   struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
const struct dpu_format *fmt = NULL;
@@ -167,9 +167,9 @@ static void _dpu_plane_calc_bw(struct drm_plane 
*plane,


fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);

-   src_width = drm_rect_width(>pipe_cfg.src_rect);
-   src_height = drm_rect_height(>pipe_cfg.src_rect);
-   dst_height = drm_rect_height(>pipe_cfg.dst_rect);
+   src_width = drm_rect_width(_cfg->src_rect);
+   src_height = drm_rect_height(_cfg->src_rect);
+   dst_height = drm_rect_height(_cfg->dst_rect);
fps = drm_mode_vrefresh(mode);
vbp = mode->vtotal - mode->vsync_end;
vpw = mode->vsync_end - mode->vsync_start;
@@ -200,12 +200,12 @@ static void _dpu_plane_calc_bw(struct drm_plane 
*plane,

 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
  * @plane: Pointer to drm plane.
+ * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane)
+static void _dpu_plane_calc_clk(struct drm_plane *plane, struct
dpu_hw_pipe_cfg *pipe_cfg)
 {
-   struct dpu_plane *pdpu = to_dpu_plane(plane);
struct dpu_plane_state *pstate;
struct drm_display_mode *mode;
int dst_width, src_height, dst_height, fps;
@@ -213,9 +213,9 @@ static void _dpu_plane_calc_clk(struct drm_plane 
*plane)

pstate = to_dpu_plane_state(plane->state);
mode = >state->crtc->mode;

-   src_height = drm_rect_height(>pipe_cfg.src_rect);
-   dst_width = drm_rect_width(>pipe_cfg.dst_rect);
-   dst_height = drm_rect_height(>pipe_cfg.dst_rect);
+   src_height = drm_rect_height(_cfg->src_rect);
+   dst_width = drm_rect_width(_cfg->dst_rect);
+   dst_height = drm_rect_height(_cfg->dst_rect);
fps = drm_mode_vrefresh(mode);

pstate->plane_clk =
@@ -252,14 +252,17 @@ static int _dpu_plane_calc_fill_level(struct
drm_plane *plane,
fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;

list_for_each_entry(tmp, >mplane_list, mplane_list) {
+   u32 tmp_width;
+
if (!tmp->base.state->visible)
continue;
+   tmp_width = drm_rect_width(>base.state->src) >> 16;
DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
pdpu->base.base.id, tmp->base.base.id,
src_width,
-   drm_rect_width(>pipe_cfg.src_rect));
+   tmp_width);
src_width = max_t(u32, src_width,
- drm_rect_width(>pipe_cfg.src_rect));
+ tmp_width);
}

if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
@@ -319,9 +322,10 @@ static u64 _dpu_plane_get_qos_lut(const struct
dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane: Pointer to drm plane
  * @fb:Pointer to framebuffer associated with the 
given plane
+ * @pipe_cfg:  Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-   struct drm_framebuffer *fb)
+   struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg 

Re: [Freedreno] [PATCH 04/11] drm/msm/dpu: remove stage_cfg from struct dpu_crtc

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:

The stage_cfg is not used outside of _dpu_crtc_blend_setup(), so remove
the temporary config from global struct.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 11 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h |  2 --
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 768012243b44..19f0715a4089 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -207,7 +207,8 @@ static void _dpu_crtc_program_lm_output_roi(struct
drm_crtc *crtc)
 }

 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
-   struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer)
+   struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
+   struct dpu_hw_stage_cfg *stage_cfg)
 {
struct drm_plane *plane;
struct drm_framebuffer *fb;
@@ -216,7 +217,6 @@ static void _dpu_crtc_blend_setup_mixer(struct
drm_crtc *crtc,
struct dpu_plane_state *pstate = NULL;
struct dpu_format *format;
struct dpu_hw_ctl *ctl = mixer->lm_ctl;
-   struct dpu_hw_stage_cfg *stage_cfg = _crtc->stage_cfg;

u32 flush_mask;
uint32_t stage_idx, lm_idx;
@@ -292,6 +292,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc 
*crtc)

struct dpu_crtc_mixer *mixer = cstate->mixers;
struct dpu_hw_ctl *ctl;
struct dpu_hw_mixer *lm;
+   struct dpu_hw_stage_cfg stage_cfg;
int i;

DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
@@ -305,9 +306,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc 
*crtc)

}

/* initialize stage cfg */
-   memset(_crtc->stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
+   memset(_cfg, 0, sizeof(struct dpu_hw_stage_cfg));

-   _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer);
+   _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, _cfg);

for (i = 0; i < cstate->num_mixers; i++) {
ctl = mixer[i].lm_ctl;
@@ -328,7 +329,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc 
*crtc)

mixer[i].flush_mask);

ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-   _crtc->stage_cfg);
+   _cfg);
}
 }

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index cec3474340e8..30535acec670 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -116,7 +116,6 @@ struct dpu_crtc_frame_event {
  * @drm_requested_vblank : Whether vblanks have been enabled in the 
encoder

  * @property_info : Opaque structure for generic property support
  * @property_defaults : Array of default values for generic property 
support

- * @stage_cfg : H/w mixer stage configuration
  * @debugfs_root  : Parent of debugfs node
  * @vblank_cb_count : count of vblank callback since last reset
  * @play_count: frame count between crtc enable and disable
@@ -147,7 +146,6 @@ struct dpu_crtc {
struct drm_pending_vblank_event *event;
u32 vsync_count;

-   struct dpu_hw_stage_cfg stage_cfg;
struct dentry *debugfs_root;

u32 vblank_cb_count;


Re: [Freedreno] [PATCH 03/11] drm/msm/dpu: drop pipe_name from struct dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:

Use plane->name instead of artificial pipe_name.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 88d726133b8b..ef3737642b0c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -115,7 +115,6 @@ struct dpu_plane {
struct dpu_csc_cfg *csc_ptr;

const struct dpu_sspp_sub_blks *pipe_sblk;
-   char pipe_name[DPU_NAME_SIZE];

/* debugfs related stuff */
struct dentry *debugfs_root;
@@ -1429,7 +1428,7 @@ static int _dpu_plane_init_debugfs(struct
drm_plane *plane)

/* create overall sub-directory for the pipe */
pdpu->debugfs_root =
-   debugfs_create_dir(pdpu->pipe_name,
+   debugfs_create_dir(plane->name,
plane->dev->primary->debugfs_root);

/* don't error check these */
@@ -1660,12 +1659,9 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

/* success! finalize initialization */
drm_plane_helper_add(plane, _plane_helper_funcs);

-   /* save user friendly pipe name for later */
-   snprintf(pdpu->pipe_name, DPU_NAME_SIZE, "plane%u", plane->base.id);
-
mutex_init(>lock);

-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", 
pdpu->pipe_name,

+   DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
pipe, plane->base.id, master_plane_id);
return plane;


Re: [Freedreno] [PATCH 02/11] drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:
The pipe_qos_cfg is used only in _dpu_plane_set_qos_ctrl(), so remove 
it

from the dpu_plane struct and allocate it on stack when necessary.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 ---
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5e0d06f26e53..88d726133b8b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -105,7 +105,6 @@ struct dpu_plane {

struct dpu_hw_pipe *pipe_hw;
struct dpu_hw_pipe_cfg pipe_cfg;
-   struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
uint32_t color_fill;
bool is_error;
bool is_rt_pipe;
@@ -422,38 +421,41 @@ static void _dpu_plane_set_qos_ctrl(struct
drm_plane *plane,
bool enable, u32 flags)
 {
struct dpu_plane *pdpu = to_dpu_plane(plane);
+   struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
+
+   memset(_qos_cfg, 0, sizeof(pipe_qos_cfg));

if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-   pdpu->pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
-   pdpu->pipe_qos_cfg.danger_vblank =
+   pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
+   pipe_qos_cfg.danger_vblank =
pdpu->pipe_sblk->danger_vblank;
-   pdpu->pipe_qos_cfg.vblank_en = enable;
+   pipe_qos_cfg.vblank_en = enable;
}

if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) {
/* this feature overrules previous VBLANK_CTRL */
-   pdpu->pipe_qos_cfg.vblank_en = false;
-   pdpu->pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
+   pipe_qos_cfg.vblank_en = false;
+   pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
}

if (flags & DPU_PLANE_QOS_PANIC_CTRL)
-   pdpu->pipe_qos_cfg.danger_safe_en = enable;
+   pipe_qos_cfg.danger_safe_en = enable;

if (!pdpu->is_rt_pipe) {
-   pdpu->pipe_qos_cfg.vblank_en = false;
-   pdpu->pipe_qos_cfg.danger_safe_en = false;
+   pipe_qos_cfg.vblank_en = false;
+   pipe_qos_cfg.danger_safe_en = false;
}

 	DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d vb:%d pri[0x%x, 0x%x] 
is_rt:%d\n",

pdpu->pipe - SSPP_VIG0,
-   pdpu->pipe_qos_cfg.danger_safe_en,
-   pdpu->pipe_qos_cfg.vblank_en,
-   pdpu->pipe_qos_cfg.creq_vblank,
-   pdpu->pipe_qos_cfg.danger_vblank,
+   pipe_qos_cfg.danger_safe_en,
+   pipe_qos_cfg.vblank_en,
+   pipe_qos_cfg.creq_vblank,
+   pipe_qos_cfg.danger_vblank,
pdpu->is_rt_pipe);

pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
-   >pipe_qos_cfg);
+   _qos_cfg);
 }

 /**


Re: [Freedreno] [PATCH 01/11] drm/msm/dpu: move LUT levels out of QOS config

2021-10-21 Thread abhinavk

On 2021-09-30 06:59, Dmitry Baryshkov wrote:

LUT levels are setup outside of setup_qos_ctrl, so remove them from the
struct dpu_hw_pipe_qos_cfg.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 15 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 17 ++---
 3 files changed, 20 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 69eed7932486..cbafb61404d0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -569,19 +569,20 @@ static void dpu_hw_sspp_setup_solidfill(struct
dpu_hw_pipe *ctx, u32 color, enum
 }

 static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_qos_cfg *cfg)
+   u32 danger_lut,
+   u32 safe_lut)
 {
u32 idx;

if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, ))
return;

-   DPU_REG_WRITE(>hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
-   DPU_REG_WRITE(>hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
+   DPU_REG_WRITE(>hw, SSPP_DANGER_LUT + idx, danger_lut);
+   DPU_REG_WRITE(>hw, SSPP_SAFE_LUT + idx, safe_lut);
 }

 static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_qos_cfg *cfg)
+   u64 creq_lut)
 {
u32 idx;

@@ -589,11 +590,11 @@ static void dpu_hw_sspp_setup_creq_lut(struct
dpu_hw_pipe *ctx,
return;

if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, >cap->features)) {
-   DPU_REG_WRITE(>hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut);
+   DPU_REG_WRITE(>hw, SSPP_CREQ_LUT_0 + idx, creq_lut);
DPU_REG_WRITE(>hw, SSPP_CREQ_LUT_1 + idx,
-   cfg->creq_lut >> 32);
+   creq_lut >> 32);
} else {
-   DPU_REG_WRITE(>hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
+   DPU_REG_WRITE(>hw, SSPP_CREQ_LUT + idx, creq_lut);
}
 }

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 fdfd4b46e2c6..27263bc1a1ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -166,18 +166,12 @@ struct dpu_hw_pipe_cfg {

 /**
  * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration
- * @danger_lut: LUT for generate danger level based on fill level
- * @safe_lut: LUT for generate safe level based on fill level
- * @creq_lut: LUT for generate creq level based on fill level
  * @creq_vblank: creq value generated to vbif during vertical blanking
  * @danger_vblank: danger value generated during vertical blanking
  * @vblank_en: enable creq_vblank and danger_vblank during vblank
  * @danger_safe_en: enable danger safe generation
  */
 struct dpu_hw_pipe_qos_cfg {
-   u32 danger_lut;
-   u32 safe_lut;
-   u64 creq_lut;
u32 creq_vblank;
u32 danger_vblank;
bool vblank_en;
@@ -302,20 +296,22 @@ struct dpu_hw_sspp_ops {
/**
 * setup_danger_safe_lut - setup danger safe LUTs
 * @ctx: Pointer to pipe context
-* @cfg: Pointer to pipe QoS configuration
+* @danger_lut: LUT for generate danger level based on fill level
+* @safe_lut: LUT for generate safe level based on fill level
 *
 */
void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_qos_cfg *cfg);
+   u32 danger_lut,
+   u32 safe_lut);

/**
 * setup_creq_lut - setup CREQ LUT
 * @ctx: Pointer to pipe context
-* @cfg: Pointer to pipe QoS configuration
+* @creq_lut: LUT for generate creq level based on fill level
 *
 */
void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
-   struct dpu_hw_pipe_qos_cfg *cfg);
+   u64 creq_lut);

/**
 * setup_qos_ctrl - setup QoS control
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c989621209aa..5e0d06f26e53 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -348,8 +348,6 @@ static void _dpu_plane_set_qos_lut(struct drm_plane 
*plane,

qos_lut = _dpu_plane_get_qos_lut(
>catalog->perf.qos_lut_tbl[lut_usage], total_fl);

-   pdpu->pipe_qos_cfg.creq_lut = qos_lut;
-
trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0,
(fmt) ? fmt->base.pixel_format : 0,
pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage);
@@ -359,7 +357,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane 
*plane,

  

Re: [Freedreno] [PATCH] drm/msm/dsi: use bulk clk API

2021-10-21 Thread abhinavk

On 2021-10-01 18:27, Dmitry Baryshkov wrote:
Use clk_bulk_* API instead of hand-coding them. Note, this drops 
support

for legacy clk naming (e.g. "iface_clk" instead of just "iface"),
however all in-kernel device trees were converted long long ago. The
warning is present there since 2017.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 59 ++
 1 file changed, 12 insertions(+), 47 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..3b81f40bba2e 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -106,7 +106,8 @@ struct msm_dsi_host {
phys_addr_t ctrl_size;
struct regulator_bulk_data supplies[DSI_DEV_REGULATOR_MAX];

-   struct clk *bus_clks[DSI_BUS_CLK_MAX];
+   int num_bus_clks;
+   struct clk_bulk_data bus_clks[DSI_BUS_CLK_MAX];

struct clk *byte_clk;
struct clk *esc_clk;
@@ -374,15 +375,14 @@ static int dsi_clk_init(struct msm_dsi_host 
*msm_host)

int i, ret = 0;

/* get bus clocks */
-   for (i = 0; i < cfg->num_bus_clks; i++) {
-   msm_host->bus_clks[i] = msm_clk_get(pdev,
-   cfg->bus_clk_names[i]);
-   if (IS_ERR(msm_host->bus_clks[i])) {
-   ret = PTR_ERR(msm_host->bus_clks[i]);
-   pr_err("%s: Unable to get %s clock, ret = %d\n",
-   __func__, cfg->bus_clk_names[i], ret);
-   goto exit;
-   }
+   for (i = 0; i < cfg->num_bus_clks; i++)
+   msm_host->bus_clks[i].id = cfg->bus_clk_names[i];
+   msm_host->num_bus_clks = cfg->num_bus_clks;
+
+   ret = devm_clk_bulk_get(>dev, msm_host->num_bus_clks,
msm_host->bus_clks);
+   if (ret < 0) {
+   dev_err(>dev, "Unable to get clocks, ret = %d\n", ret);
+   goto exit;
}

/* get link and source clocks */
@@ -433,41 +433,6 @@ static int dsi_clk_init(struct msm_dsi_host 
*msm_host)

return ret;
 }

-static int dsi_bus_clk_enable(struct msm_dsi_host *msm_host)
-{
-   const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-   int i, ret;
-
-   DBG("id=%d", msm_host->id);
-
-   for (i = 0; i < cfg->num_bus_clks; i++) {
-   ret = clk_prepare_enable(msm_host->bus_clks[i]);
-   if (ret) {
-   pr_err("%s: failed to enable bus clock %d ret %d\n",
-   __func__, i, ret);
-   goto err;
-   }
-   }
-
-   return 0;
-err:
-   for (; i > 0; i--)
-   clk_disable_unprepare(msm_host->bus_clks[i]);
-
-   return ret;
-}
-
-static void dsi_bus_clk_disable(struct msm_dsi_host *msm_host)
-{
-   const struct msm_dsi_config *cfg = msm_host->cfg_hnd->cfg;
-   int i;
-
-   DBG("");
-
-   for (i = cfg->num_bus_clks - 1; i >= 0; i--)
-   clk_disable_unprepare(msm_host->bus_clks[i]);
-}
-
 int msm_dsi_runtime_suspend(struct device *dev)
 {
struct platform_device *pdev = to_platform_device(dev);
@@ -478,7 +443,7 @@ int msm_dsi_runtime_suspend(struct device *dev)
if (!msm_host->cfg_hnd)
return 0;

-   dsi_bus_clk_disable(msm_host);
+	clk_bulk_disable_unprepare(msm_host->num_bus_clks, 
msm_host->bus_clks);


return 0;
 }
@@ -493,7 +458,7 @@ int msm_dsi_runtime_resume(struct device *dev)
if (!msm_host->cfg_hnd)
return 0;

-   return dsi_bus_clk_enable(msm_host);
+	return clk_bulk_prepare_enable(msm_host->num_bus_clks, 
msm_host->bus_clks);

 }

 int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host)


Re: [Freedreno] [PATCH 2/2] drm/msm/dsi: stop setting clock parents manually

2021-10-19 Thread abhinavk

On 2021-10-06 13:48, Dmitry Baryshkov wrote:

There is no reason to set clock parents manually, use device tree to
assign DSI/display clock parents to DSI PHY clocks. Dropping this 
manual

setup allows us to drop repeating code and to move registration of hw
clock providers to generic place.

Signed-off-by: Dmitry Baryshkov 


I believe this was reviewed previously on

https://patchwork.freedesktop.org/patch/443470/

Hence,

Reviewed-by: Abhinav Kumar 


---
 drivers/gpu/drm/msm/dsi/dsi.h |  2 -
 drivers/gpu/drm/msm/dsi/dsi_host.c| 53 ---
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 11 +-
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 11 --
 4 files changed, 2 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
b/drivers/gpu/drm/msm/dsi/dsi.h

index 7dfb6d198ca9..c03a8d09c764 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -173,8 +173,6 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy,
 void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
 void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
 enum msm_dsi_phy_usecase uc);
-int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy *phy,
-   struct clk **byte_clk_provider, struct clk **pixel_clk_provider);
 void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy);
 int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy);
 void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct
msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 1ffcd0577e99..9600b4fa27eb 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2232,59 +2232,6 @@ void msm_dsi_host_set_phy_mode(struct
mipi_dsi_host *host,
msm_host->cphy_mode = src_phy->cphy_mode;
 }

-int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
-   struct msm_dsi_phy *src_phy)
-{
-   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
-   struct clk *byte_clk_provider, *pixel_clk_provider;
-   int ret;
-
-   msm_host->cphy_mode = src_phy->cphy_mode;
-
-   ret = msm_dsi_phy_get_clk_provider(src_phy,
-   _clk_provider, _clk_provider);
-   if (ret) {
-   pr_info("%s: can't get provider from pll, don't set parent\n",
-   __func__);
-   return 0;
-   }
-
-   ret = clk_set_parent(msm_host->byte_clk_src, byte_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to byte_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-
-   ret = clk_set_parent(msm_host->pixel_clk_src, pixel_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to pixel_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-
-   if (msm_host->dsi_clk_src) {
-   ret = clk_set_parent(msm_host->dsi_clk_src, pixel_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to dsi_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-   }
-
-   if (msm_host->esc_clk_src) {
-   ret = clk_set_parent(msm_host->esc_clk_src, byte_clk_provider);
-   if (ret) {
-   pr_err("%s: can't set parent to esc_clk_src. ret=%d\n",
-   __func__, ret);
-   goto exit;
-   }
-   }
-
-exit:
-   return ret;
-}
-
 void msm_dsi_host_reset_phy(struct mipi_dsi_host *host)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index 49a0a0841487..9342a822ad20 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -78,10 +78,7 @@ static int dsi_mgr_setup_components(int id)

msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
-   ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
-   } else if (!other_dsi) {
-   ret = 0;
-   } else {
+   } else if (other_dsi) {
struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
msm_dsi : other_dsi;
struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
@@ -107,13 +104,9 @@ static int dsi_mgr_setup_components(int id)
MSM_DSI_PHY_SLAVE);
msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
-   ret = msm_dsi_host_set_src_pll(msm_dsi->host, 
clk_master_dsi->phy);
-   if (ret)
-   

Re: [Freedreno] [PATCH 1/2] drm/msm/dsi: untangle cphy setting from the src pll setting

2021-10-19 Thread abhinavk

On 2021-10-06 13:48, Dmitry Baryshkov wrote:

Move DPHY/CPHY setting from msm_dsi_host_set_src_pll() to new function
msm_dsi_host_set_phy_mode().

Signed-off-by: Dmitry Baryshkov 


Just a minor comment, can you also include the part which removes
msm_host->cphy_mode = src_phy->cphy_mode; from msm_dsi_host_set_src_pll
in this change itself so that its clear that you are removing from there
and moving it into a new API?

You can still keep my
Reviewed-by: Abhinav Kumar 

once you address this.


---
 drivers/gpu/drm/msm/dsi/dsi.h | 2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 8 
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 3 +++
 3 files changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
b/drivers/gpu/drm/msm/dsi/dsi.h

index b50db91cb8a7..7dfb6d198ca9 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -118,6 +118,8 @@ unsigned long msm_dsi_host_get_mode_flags(struct
mipi_dsi_host *host);
 struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host 
*host);
 int msm_dsi_host_register(struct mipi_dsi_host *host, bool 
check_defer);

 void msm_dsi_host_unregister(struct mipi_dsi_host *host);
+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+   struct msm_dsi_phy *src_phy);
 int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
struct msm_dsi_phy *src_phy);
 void msm_dsi_host_reset_phy(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 e269df285136..1ffcd0577e99 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2224,6 +2224,14 @@ void msm_dsi_host_cmd_xfer_commit(struct
mipi_dsi_host *host, u32 dma_base,
wmb();
 }

+void msm_dsi_host_set_phy_mode(struct mipi_dsi_host *host,
+   struct msm_dsi_phy *src_phy)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   msm_host->cphy_mode = src_phy->cphy_mode;
+}
+
 int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
struct msm_dsi_phy *src_phy)
 {
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..49a0a0841487 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -77,6 +77,7 @@ static int dsi_mgr_setup_components(int id)
return ret;

msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
+   msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
} else if (!other_dsi) {
ret = 0;
@@ -104,6 +105,8 @@ static int dsi_mgr_setup_components(int id)
MSM_DSI_PHY_MASTER);
msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
MSM_DSI_PHY_SLAVE);
+   msm_dsi_host_set_phy_mode(msm_dsi->host, msm_dsi->phy);
+   msm_dsi_host_set_phy_mode(other_dsi->host, other_dsi->phy);
ret = msm_dsi_host_set_src_pll(msm_dsi->host, 
clk_master_dsi->phy);
if (ret)
return ret;


Re: [Freedreno] [PATCH 2/2] drm/msm/hdmi: switch to drm_bridge_connector

2021-10-18 Thread abhinavk

On 2021-10-16 07:21, Dmitry Baryshkov wrote:

On Sat, 16 Oct 2021 at 01:25,  wrote:


Hi Dmitry

On 2021-10-14 17:11, Dmitry Baryshkov wrote:
> Merge old hdmi_bridge and hdmi_connector implementations. Use
> drm_bridge_connector instead.
>
Can you please comment on the validation done on this change?
Has basic bootup been verified on db820c as thats the only platform
which shall use this.


Yes, this has been developed and validated on db820c

Thanks for confirming.




> Signed-off-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/msm/Makefile  |   2 +-
>  drivers/gpu/drm/msm/hdmi/hdmi.c   |  12 +-
>  drivers/gpu/drm/msm/hdmi/hdmi.h   |  19 ++-
>  drivers/gpu/drm/msm/hdmi/hdmi_bridge.c|  81 -
>  .../msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} | 154 ++
>  5 files changed, 109 insertions(+), 159 deletions(-)
>  rename drivers/gpu/drm/msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} (62%)
>
> diff --git a/drivers/gpu/drm/msm/Makefile
> b/drivers/gpu/drm/msm/Makefile
> index 904535eda0c4..91b09cda8a9c 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -19,7 +19,7 @@ msm-y := \
>   hdmi/hdmi.o \
>   hdmi/hdmi_audio.o \
>   hdmi/hdmi_bridge.o \
> - hdmi/hdmi_connector.o \
> + hdmi/hdmi_hpd.o \
>   hdmi/hdmi_i2c.o \
>   hdmi/hdmi_phy.o \
>   hdmi/hdmi_phy_8960.o \
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c
> b/drivers/gpu/drm/msm/hdmi/hdmi.c
> index db17a000d968..d1cf4df7188c 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
> @@ -8,6 +8,8 @@
>  #include 
>  #include 
>
> +#include 
> +
>  #include 
>  #include "hdmi.h"
>
> @@ -41,7 +43,7 @@ static irqreturn_t msm_hdmi_irq(int irq, void
> *dev_id)
>   struct hdmi *hdmi = dev_id;
>
>   /* Process HPD: */
> - msm_hdmi_connector_irq(hdmi->connector);
> + msm_hdmi_hpd_irq(hdmi->bridge);
>
>   /* Process DDC: */
>   msm_hdmi_i2c_irq(hdmi->i2c);
> @@ -283,7 +285,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
>   goto fail;
>   }
>
> - hdmi->connector = msm_hdmi_connector_init(hdmi);
> + hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder);
>   if (IS_ERR(hdmi->connector)) {
>   ret = PTR_ERR(hdmi->connector);
>   DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n",
> ret);
> @@ -291,6 +293,8 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
>   goto fail;
>   }
>
> + drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
> +
>   hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
>   if (hdmi->irq < 0) {
>   ret = hdmi->irq;
> @@ -307,7 +311,9 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
>   goto fail;
>   }
>
> - ret = msm_hdmi_hpd_enable(hdmi->connector);
> + drm_bridge_connector_enable_hpd(hdmi->connector);
> +
> + ret = msm_hdmi_hpd_enable(hdmi->bridge);
>   if (ret < 0) {
>   DRM_DEV_ERROR(>pdev->dev, "failed to enable HPD: %d\n", 
ret);
>   goto fail;
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h
> b/drivers/gpu/drm/msm/hdmi/hdmi.h
> index 82261078c6b1..736f348befb3 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi.h
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
> @@ -114,6 +114,13 @@ struct hdmi_platform_config {
>   struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO];
>  };
>
> +struct hdmi_bridge {
> + struct drm_bridge base;
> + struct hdmi *hdmi;
> + struct work_struct hpd_work;
> +};
> +#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
> +
>  void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
>
>  static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
> @@ -230,13 +237,11 @@ void msm_hdmi_audio_set_sample_rate(struct hdmi
> *hdmi, int rate);
>  struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi);
>  void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
>
> -/*
> - * hdmi connector:
> - */
> -
> -void msm_hdmi_connector_irq(struct drm_connector *connector);
> -struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
> -int msm_hdmi_hpd_enable(struct drm_connector *connector);
> +void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
> +enum drm_connector_status msm_hdmi_bridge_detect(
> + struct drm_bridge *bridge);
> +int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
> +void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge);
>
>  /*
>   * i2c adapter for ddc:
> diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> index f04eb4a70f0d..211b73dddf65 100644
> --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
> @@ -5,17 +5,16 @@
>   */
>
>  #include 
> +#include 
>
> +#include "msm_kms.h"
>  #include "hdmi.h"
>
> -struct hdmi_bridge {
> - struct drm_bridge base;
> - struct hdmi *hdmi;
> -};
> -#define to_hdmi_bridge(x) 

Re: [Freedreno] [PATCH v5 7/7] drm/msm/dp: Add sc8180x DP controllers

2021-10-18 Thread abhinavk

On 2021-10-16 15:18, Bjorn Andersson wrote:
The sc8180x has 2 DP and 1 eDP controllers, add support for these to 
the

DP driver.

Link:
https://lore.kernel.org/linux-arm-msm/20210725042436.3967173-7-bjorn.anders...@linaro.org/
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v4:
- Use the MSM_DP_CONTROLLER_n enums
- const the msm_dp_desc array

 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  6 +++---
 drivers/gpu/drm/msm/dp/dp_display.c| 11 +++
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 47d5d71eb5d3..0ac6a79e8af9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -918,13 +918,13 @@ static const struct dpu_intf_cfg sc7280_intf[] = 
{

 };

 static const struct dpu_intf_cfg sc8180x_intf[] = {
-   INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+   INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0,
24, INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index
until this is supported */
INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
-   INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
-   INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24,
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
+   INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1,
24, INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
+   INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2,
24, INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
 };

 /*
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index d3c9d7273354..70dcd4e6d466 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -135,8 +135,19 @@ static const struct msm_dp_config sc7180_dp_cfg = 
{

.num_descs = 1,
 };

+static const struct msm_dp_config sc8180x_dp_cfg = {
+   .descs = (const struct msm_dp_desc[]) {
+   [MSM_DP_CONTROLLER_0] = { .io_start = 0x0ae9, 
.connector_type =
DRM_MODE_CONNECTOR_DisplayPort },
+   [MSM_DP_CONTROLLER_1] = { .io_start = 0x0ae98000, 
.connector_type =
DRM_MODE_CONNECTOR_DisplayPort },
+   [MSM_DP_CONTROLLER_2] = { .io_start = 0x0ae9a000, 
.connector_type =
DRM_MODE_CONNECTOR_eDP },
+   },
+   .num_descs = 3,
+};
+
 static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = _dp_cfg },
+   { .compatible = "qcom,sc8180x-dp", .data = _dp_cfg },
+   { .compatible = "qcom,sc8180x-edp", .data = _dp_cfg },
{}
 };


Re: [Freedreno] [PATCH v5 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-18 Thread abhinavk

On 2021-10-16 15:18, Bjorn Andersson wrote:

Based on the removal of the g_dp_display and the movement of the
priv->dp lookup into the DP code it's now possible to have multiple
DP instances.

In line with the other controllers in the MSM driver, introduce a
per-compatible list of base addresses which is used to resolve the
"instance id" for the given DP controller. This instance id is used as
index in the priv->dp[] array.

Then extend the initialization code to initialize struct drm_encoder 
for

each of the registered priv->dp[] and update the logic for associating
each struct msm_dp with the struct dpu_encoder_virt.

A new enum is introduced to document the connection between the
instances referenced in the dpu_intf_cfg array and the controllers in
the DP driver and sc7180 is updated.

Lastly, bump the number of struct msm_dp instances carries by priv->dp
to 3, the currently known maximum number of controllers found in a
Qualcomm SoC.

Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v4:
- MSM_DP_CONTROLLER_n introduced to clarify the relationship between 
the intf

  specification and the indices of the msm_dp_desc
- Unnecessary parenthesis around dp->dp_display was dropped

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c|  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 66 +++
 .../gpu/drm/msm/disp/msm_disp_snapshot_util.c |  8 ++-
 drivers/gpu/drm/msm/dp/dp_display.c   | 20 --
 drivers/gpu/drm/msm/msm_drv.h |  9 ++-
 6 files changed, 68 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b7f33da2799c..9cd9539a1504 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2173,7 +2173,7 @@ int dpu_encoder_setup(struct drm_device *dev,
struct drm_encoder *enc,
dpu_encoder_vsync_event_handler,
0);
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
-   dpu_enc->dp = priv->dp;
+   dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];

INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 60eed3128b54..47d5d71eb5d3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -900,7 +900,7 @@ static const struct dpu_intf_cfg sdm845_intf[] = {
 };

 static const struct dpu_intf_cfg sc7180_intf[] = {
-   INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
+   INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0,
24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24,
INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
 };

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index f655adbc2421..875b07e7183d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -188,6 +188,7 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
struct dentry *entry;
struct drm_device *dev;
struct msm_drm_private *priv;
+   int i;

if (!p)
return -EINVAL;
@@ -203,8 +204,10 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
dpu_debugfs_vbif_init(dpu_kms, entry);
dpu_debugfs_core_irq_init(dpu_kms, entry);

-   if (priv->dp)
-   msm_dp_debugfs_init(priv->dp, minor);
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (priv->dp[i])
+   msm_dp_debugfs_init(priv->dp[i], minor);
+   }

return dpu_core_perf_debugfs_init(dpu_kms, entry);
 }
@@ -544,35 +547,42 @@ static int
_dpu_kms_initialize_displayport(struct drm_device *dev,
 {
struct drm_encoder *encoder = NULL;
struct msm_display_info info;
-   int rc = 0;
+   int rc;
+   int i;

-   if (!priv->dp)
-   return rc;
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (!priv->dp[i])
+   continue;

-   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
-   if (IS_ERR(encoder)) {
-   DPU_ERROR("encoder init failed for dsi display\n");
-   return PTR_ERR(encoder);
-   }
+   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR(encoder)) {
+   DPU_ERROR("encoder init failed for dsi display\n");
+   return PTR_ERR(encoder);
+   }

-   memset(, 0, sizeof(info));
-   rc = 

Re: [Freedreno] [PATCH v5 4/7] drm/msm/dp: Allow attaching a drm_panel

2021-10-18 Thread abhinavk

On 2021-10-16 15:18, Bjorn Andersson wrote:

eDP panels might need some power sequencing and backlight management,
so make it possible to associate a drm_panel with an eDP instance and
prepare and enable the panel accordingly.

Now that we know which hardware instance is DP and which is eDP,
parser->parse() is passed the connector_type and the parser is limited
to only search for a panel in the eDP case.

Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v4:
- None

 drivers/gpu/drm/msm/dp/dp_display.c |  9 ++---
 drivers/gpu/drm/msm/dp/dp_display.h |  1 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 11 +++
 drivers/gpu/drm/msm/dp/dp_parser.c  | 30 -
 drivers/gpu/drm/msm/dp/dp_parser.h  |  3 ++-
 5 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index 6913970c8cf9..c663cd619925 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -230,12 +231,14 @@ static int dp_display_bind(struct device *dev,
struct device *master,
priv = drm->dev_private;
priv->dp = &(dp->dp_display);

-   rc = dp->parser->parse(dp->parser);
+   rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
if (rc) {
DRM_ERROR("device tree parsing failed\n");
goto end;
}

+   dp->dp_display.panel_bridge = dp->parser->panel_bridge;
+
dp->aux->drm_dev = drm;
rc = dp_aux_register(dp->aux);
if (rc) {
@@ -822,7 +825,7 @@ static int dp_display_set_mode(struct msm_dp 
*dp_display,

return 0;
 }

-static int dp_display_prepare(struct msm_dp *dp)
+static int dp_display_prepare(struct msm_dp *dp_display)
 {
return 0;
 }
@@ -896,7 +899,7 @@ static int dp_display_disable(struct
dp_display_private *dp, u32 data)
return 0;
 }

-static int dp_display_unprepare(struct msm_dp *dp)
+static int dp_display_unprepare(struct msm_dp *dp_display)
 {
return 0;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
b/drivers/gpu/drm/msm/dp/dp_display.h
index 75fcabcfbbdd..8e80e3bac394 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -15,6 +15,7 @@ struct msm_dp {
struct device *codec_dev;
struct drm_connector *connector;
struct drm_encoder *encoder;
+   struct drm_bridge *panel_bridge;
bool is_connected;
bool audio_enabled;
bool power_on;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
b/drivers/gpu/drm/msm/dp/dp_drm.c

index f33e31523f56..76856c4ee1d6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -5,6 +5,7 @@

 #include 
 #include 
+#include 
 #include 

 #include "msm_drv.h"
@@ -160,5 +161,15 @@ struct drm_connector
*dp_drm_connector_init(struct msm_dp *dp_display)

drm_connector_attach_encoder(connector, dp_display->encoder);

+   if (dp_display->panel_bridge) {
+   ret = drm_bridge_attach(dp_display->encoder,
+   dp_display->panel_bridge, NULL,
+   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (ret < 0) {
+   DRM_ERROR("failed to attach panel bridge: %d\n", ret);
+   return ERR_PTR(ret);
+   }
+   }
+
return connector;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 4d6e047f803d..eb6bbfbea484 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -6,6 +6,7 @@
 #include 
 #include 

+#include 
 #include 

 #include "dp_parser.h"
@@ -263,7 +264,28 @@ static int dp_parser_clock(struct dp_parser 
*parser)

return 0;
 }

-static int dp_parser_parse(struct dp_parser *parser)
+static int dp_parser_find_panel(struct dp_parser *parser)
+{
+   struct device *dev = >pdev->dev;
+   struct drm_panel *panel;
+   int rc;
+
+   rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
+   if (rc) {
+   DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
+   return rc;
+   }
+
+   parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+   if (IS_ERR(parser->panel_bridge)) {
+   DRM_ERROR("failed to create panel bridge\n");
+   return PTR_ERR(parser->panel_bridge);
+   }
+
+   return 0;
+}
+
+static int dp_parser_parse(struct dp_parser *parser, int 
connector_type)

 {
int rc = 0;

@@ -284,6 +306,12 @@ static int dp_parser_parse(struct dp_parser 
*parser)

if (rc)
return rc;

+   if (connector_type == DRM_MODE_CONNECTOR_eDP) {
+   rc = dp_parser_find_panel(parser);
+   if (rc)
+   return 

Re: [Freedreno] [PATCH v5 3/7] drm/msm/dp: Allow specifying connector_type per controller

2021-10-18 Thread abhinavk

On 2021-10-16 15:18, Bjorn Andersson wrote:

As the following patches introduced support for multiple DP blocks in a
platform and some of those block might be eDP it becomes useful to be
able to specify the connector type per block.

Although there's only a single block at this point, the array of descs
and the search in dp_display_get_desc() are introduced here to simplify
the next patch, that does introduce support for multiple DP blocks.

Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v4:
- const the various struct msm_dp_desc instances
- unsigned the connector_type


The references to DRM_MODE_CONNECTOR_DisplayPort in dp_debug.c, that 
was

highligted in the review of v4 has been removed in a separate patch.

 drivers/gpu/drm/msm/dp/dp_display.c | 43 -
 drivers/gpu/drm/msm/dp/dp_display.h |  1 +
 drivers/gpu/drm/msm/dp/dp_drm.c |  2 +-
 3 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index 5d3ee5ef07c2..6913970c8cf9 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -115,8 +115,25 @@ struct dp_display_private {
struct dp_audio *audio;
 };

+struct msm_dp_desc {
+   phys_addr_t io_start;
+   unsigned int connector_type;
+};
+
+struct msm_dp_config {
+   const struct msm_dp_desc *descs;
+   size_t num_descs;
+};
+
+static const struct msm_dp_config sc7180_dp_cfg = {
+   .descs = (const struct msm_dp_desc[]) {
+		{ .io_start = 0x0ae9, .connector_type = 
DRM_MODE_CONNECTOR_DisplayPort },

+   },
+   .num_descs = 1,
+};
+
 static const struct of_device_id dp_dt_match[] = {
-   {.compatible = "qcom,sc7180-dp"},
+   { .compatible = "qcom,sc7180-dp", .data = _dp_cfg },
{}
 };

@@ -1180,10 +1197,29 @@ int dp_display_request_irq(struct msm_dp 
*dp_display)

return 0;
 }

+static const struct msm_dp_desc *dp_display_get_desc(struct
platform_device *pdev)
+{
+	const struct msm_dp_config *cfg = 
of_device_get_match_data(>dev);

+   struct resource *res;
+   int i;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   if (!res)
+   return NULL;
+
+   for (i = 0; i < cfg->num_descs; i++)
+   if (cfg->descs[i].io_start == res->start)
+   return >descs[i];
+
+   dev_err(>dev, "unknown displayport instance\n");
+   return NULL;
+}
+
 static int dp_display_probe(struct platform_device *pdev)
 {
int rc = 0;
struct dp_display_private *dp;
+   const struct msm_dp_desc *desc;

if (!pdev || !pdev->dev.of_node) {
DRM_ERROR("pdev not found\n");
@@ -1194,8 +1230,13 @@ static int dp_display_probe(struct 
platform_device *pdev)

if (!dp)
return -ENOMEM;

+   desc = dp_display_get_desc(pdev);
+   if (!desc)
+   return -EINVAL;
+
dp->pdev = pdev;
dp->name = "drm_dp";
+   dp->dp_display.connector_type = desc->connector_type;

rc = dp_init_sub_modules(dp);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
b/drivers/gpu/drm/msm/dp/dp_display.h
index 8b47cdabb67e..75fcabcfbbdd 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -18,6 +18,7 @@ struct msm_dp {
bool is_connected;
bool audio_enabled;
bool power_on;
+   unsigned int connector_type;

hdmi_codec_plugged_cb plugged_cb;

diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
b/drivers/gpu/drm/msm/dp/dp_drm.c

index 764f4b81017e..f33e31523f56 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -147,7 +147,7 @@ struct drm_connector *dp_drm_connector_init(struct
msm_dp *dp_display)

ret = drm_connector_init(dp_display->drm_dev, connector,
_connector_funcs,
-   DRM_MODE_CONNECTOR_DisplayPort);
+   dp_display->connector_type);
if (ret)
return ERR_PTR(ret);


Re: [Freedreno] [PATCH] drm/msm/dp: Move debugfs files into subdirectory

2021-10-18 Thread abhinavk

Hi Bjorn

On 2021-10-17 09:42, Bjorn Andersson wrote:

On Fri 15 Oct 16:53 PDT 2021, abhin...@codeaurora.org wrote:


On 2021-10-15 16:17, Bjorn Andersson wrote:
> In the cleanup path of the MSM DP driver the DP driver's debugfs files
> are destroyed by invoking debugfs_remove_recursive() on debug->root,
> which during initialization has been set to minor->debugfs_root.
>
> To allow cleaning up the DP driver's debugfs files either each dentry
> needs to be kept track of or the files needs to be put in a subdirectory
> which can be removed in one go.
>
> By choosing to put the debugfs files in a subdirectory, based on the
> name of the associated connector this also solves the problem that these
> names would collide as support for multiple DP instances are introduced.
>
> One alternative solution to the problem with colliding file names would
> have been to put keep track of the individual files and put them under
> the connector's debugfs directory. But while the drm_connector has been
> allocated, its associated debugfs directory has not been created at the
> time of initialization of the dp_debug.
>
> Signed-off-by: Bjorn Andersson 

I have been thinking about this problem ever since multi-DP has been 
posted

:)
Creating sub-directories seems right but at the moment it looks like 
IGT

which
uses these debugfs nodes doesnt check sub-directories:

https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tools/msm_dp_compliance.c#L215

It looks for the DP debugfs nodes under /sys/kernel/debug/dri/*/

We have to fix IGT too to be able to handle multi-DP cases. I will try 
to

come up
with a proposal to address this.

Till then, can we go with the other solution to keep track of the 
dentries?




I'm afraid I don't see what you're proposing.

Afaict we need one set of dp_test{type,active,data} per DP controller,
so even doing this by keeping track of the dentries requires that we
rename the files based on some identifier (id or connector name) - 
which

will cause igt to break.


Yes, I also thought the same that there needs to be some identifier.

"To allow cleaning up the DP driver's debugfs files either each dentry
needs to be kept track of or the files needs to be put in a subdirectory
which can be removed in one go"

I guess I misunderstood your statement in the commit text thinking that 
you

had some other way to keep track of the dentries as it mentioned that
use a subdirectory OR keep track of each dentry.



As such, I think the practical path forward is that we merge the
multi-DP series as currently proposed. This will not cause any issues 
on

single-DP systems, but on multi-DP systems we will have warnings about
duplicate debugfs entries in the kernel logs.

Then you can figure out how to rework igt to deal with the multiple DP
instances and update the dp_debug interface accordingly.



Fine with me, I will take care of this.



Which also implies that we should hold this patch back. But if we go
that path, I think we should fix dp_debug_deinit() so that it doesn't
remove /sys/kernel/debug/dri/128 when the DP driver is unloaded.

Yes, lets hold this patch back till I fix multi-DP for IGT.


Regards,
Bjorn


> ---
>
> This depends on
> 
https://lore.kernel.org/linux-arm-msm/20211010030435.4000642-1-bjorn.anders...@linaro.org/
> reducing the connector from a double pointer.
>
>  drivers/gpu/drm/msm/dp/dp_debug.c | 15 +--
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
> b/drivers/gpu/drm/msm/dp/dp_debug.c
> index da4323556ef3..67da4c69eca1 100644
> --- a/drivers/gpu/drm/msm/dp/dp_debug.c
> +++ b/drivers/gpu/drm/msm/dp/dp_debug.c
> @@ -210,26 +210,29 @@ static const struct file_operations
> test_active_fops = {
>  static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor
> *minor)
>  {
>int rc = 0;
> +  char path[64];
>struct dp_debug_private *debug = container_of(dp_debug,
>struct dp_debug_private, dp_debug);
>
> -  debugfs_create_file("dp_debug", 0444, minor->debugfs_root,
> +  snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name);
> +
> +  debug->root = debugfs_create_dir(path, minor->debugfs_root);
> +
> +  debugfs_create_file("dp_debug", 0444, debug->root,
>debug, _debug_fops);
>
>debugfs_create_file("msm_dp_test_active", 0444,
> -  minor->debugfs_root,
> +  debug->root,
>debug, _active_fops);
>
>debugfs_create_file("msm_dp_test_data", 0444,
> -  minor->debugfs_root,
> +  debug->root,
>debug, _test_data_fops);
>
>debugfs_create_file("msm_dp_test_type", 0444,
> -  minor->debugfs_root,
> +  debug->root,
>debug, _test_type_fops);
>
> -  debug->root = minor->debugfs_root;
> -
>return rc;
>  }


Re: [Freedreno] [PATCH] drm/msm/dp: Move debugfs files into subdirectory

2021-10-15 Thread abhinavk

On 2021-10-15 16:17, Bjorn Andersson wrote:

In the cleanup path of the MSM DP driver the DP driver's debugfs files
are destroyed by invoking debugfs_remove_recursive() on debug->root,
which during initialization has been set to minor->debugfs_root.

To allow cleaning up the DP driver's debugfs files either each dentry
needs to be kept track of or the files needs to be put in a 
subdirectory

which can be removed in one go.

By choosing to put the debugfs files in a subdirectory, based on the
name of the associated connector this also solves the problem that 
these
names would collide as support for multiple DP instances are 
introduced.


One alternative solution to the problem with colliding file names would
have been to put keep track of the individual files and put them under
the connector's debugfs directory. But while the drm_connector has been
allocated, its associated debugfs directory has not been created at the
time of initialization of the dp_debug.

Signed-off-by: Bjorn Andersson 


I have been thinking about this problem ever since multi-DP has been 
posted :)
Creating sub-directories seems right but at the moment it looks like IGT 
which

uses these debugfs nodes doesnt check sub-directories:

https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/blob/master/tools/msm_dp_compliance.c#L215

It looks for the DP debugfs nodes under /sys/kernel/debug/dri/*/

We have to fix IGT too to be able to handle multi-DP cases. I will try 
to come up

with a proposal to address this.

Till then, can we go with the other solution to keep track of the 
dentries?



---

This depends on
https://lore.kernel.org/linux-arm-msm/20211010030435.4000642-1-bjorn.anders...@linaro.org/
reducing the connector from a double pointer.

 drivers/gpu/drm/msm/dp/dp_debug.c | 15 +--
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
b/drivers/gpu/drm/msm/dp/dp_debug.c
index da4323556ef3..67da4c69eca1 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -210,26 +210,29 @@ static const struct file_operations 
test_active_fops = {
 static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor 
*minor)

 {
int rc = 0;
+   char path[64];
struct dp_debug_private *debug = container_of(dp_debug,
struct dp_debug_private, dp_debug);

-   debugfs_create_file("dp_debug", 0444, minor->debugfs_root,
+   snprintf(path, sizeof(path), "msm_dp-%s", debug->connector->name);
+
+   debug->root = debugfs_create_dir(path, minor->debugfs_root);
+
+   debugfs_create_file("dp_debug", 0444, debug->root,
debug, _debug_fops);

debugfs_create_file("msm_dp_test_active", 0444,
-   minor->debugfs_root,
+   debug->root,
debug, _active_fops);

debugfs_create_file("msm_dp_test_data", 0444,
-   minor->debugfs_root,
+   debug->root,
debug, _test_data_fops);

debugfs_create_file("msm_dp_test_type", 0444,
-   minor->debugfs_root,
+   debug->root,
debug, _test_type_fops);

-   debug->root = minor->debugfs_root;
-
return rc;
 }


Re: [Freedreno] [PATCH] drm/msm/dp: Only create debugfs for PRIMARY minor

2021-10-15 Thread abhinavk

On 2021-10-15 16:13, Bjorn Andersson wrote:

dpu_kms_debugfs_init() and hence dp_debug_get() gets invoked for each
minor being registered. But dp_debug_get() will allocate a new struct
dp_debug for each call and this will be associated as dp->debug.

As such dp_debug will create debugfs files in both the PRIMARY and the
RENDER minor's debugfs directory, but only the last reference will be
remembered.

The only use of this reference today is in the cleanup path in
dp_display_deinit_sub_modules() and the dp_debug_private object does
outlive the debugfs entries in either case, so there doesn't seem to be
any adverse effects of this, but per the code the current behavior is
unexpected, so change it to only create dp_debug for the PRIMARY minor.



If i understand correctly, today because of this, we get redundant 
debugfs nodes right?


/sys/kernel/debug/dri//dp_debug
/sys/kernel/debug/dri//dp_debug

Both of these will hold the same information as they are for the same DP 
controller right?

In that case, this is true even for the other DPU kms information too.

Why not move this check one level up to dpu_kms_debugfs_init?


Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_display.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index 3aa67c53dbc0..06773b58bb60 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 #include "msm_drv.h"
@@ -1463,6 +1464,10 @@ void msm_dp_debugfs_init(struct msm_dp
*dp_display, struct drm_minor *minor)
dp = container_of(dp_display, struct dp_display_private, dp_display);
dev = >pdev->dev;

+   /* Only create one set of debugfs per DP instance */
+   if (minor->type != DRM_MINOR_PRIMARY)
+   return;
+
dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd,
dp->link, dp->dp_display.connector,
minor);


Re: [Freedreno] [PATCH 2/2] drm/msm/hdmi: switch to drm_bridge_connector

2021-10-15 Thread abhinavk

Hi Dmitry

On 2021-10-14 17:11, Dmitry Baryshkov wrote:

Merge old hdmi_bridge and hdmi_connector implementations. Use
drm_bridge_connector instead.


Can you please comment on the validation done on this change?
Has basic bootup been verified on db820c as thats the only platform 
which shall use this.



Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/Makefile  |   2 +-
 drivers/gpu/drm/msm/hdmi/hdmi.c   |  12 +-
 drivers/gpu/drm/msm/hdmi/hdmi.h   |  19 ++-
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c|  81 -
 .../msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} | 154 ++
 5 files changed, 109 insertions(+), 159 deletions(-)
 rename drivers/gpu/drm/msm/hdmi/{hdmi_connector.c => hdmi_hpd.c} (62%)

diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index 904535eda0c4..91b09cda8a9c 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -19,7 +19,7 @@ msm-y := \
hdmi/hdmi.o \
hdmi/hdmi_audio.o \
hdmi/hdmi_bridge.o \
-   hdmi/hdmi_connector.o \
+   hdmi/hdmi_hpd.o \
hdmi/hdmi_i2c.o \
hdmi/hdmi_phy.o \
hdmi/hdmi_phy_8960.o \
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c 
b/drivers/gpu/drm/msm/hdmi/hdmi.c

index db17a000d968..d1cf4df7188c 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -8,6 +8,8 @@
 #include 
 #include 

+#include 
+
 #include 
 #include "hdmi.h"

@@ -41,7 +43,7 @@ static irqreturn_t msm_hdmi_irq(int irq, void 
*dev_id)

struct hdmi *hdmi = dev_id;

/* Process HPD: */
-   msm_hdmi_connector_irq(hdmi->connector);
+   msm_hdmi_hpd_irq(hdmi->bridge);

/* Process DDC: */
msm_hdmi_i2c_irq(hdmi->i2c);
@@ -283,7 +285,7 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
goto fail;
}

-   hdmi->connector = msm_hdmi_connector_init(hdmi);
+   hdmi->connector = drm_bridge_connector_init(hdmi->dev, encoder);
if (IS_ERR(hdmi->connector)) {
ret = PTR_ERR(hdmi->connector);
 		DRM_DEV_ERROR(dev->dev, "failed to create HDMI connector: %d\n", 
ret);

@@ -291,6 +293,8 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
goto fail;
}

+   drm_connector_attach_encoder(hdmi->connector, hdmi->encoder);
+
hdmi->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
if (hdmi->irq < 0) {
ret = hdmi->irq;
@@ -307,7 +311,9 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
goto fail;
}

-   ret = msm_hdmi_hpd_enable(hdmi->connector);
+   drm_bridge_connector_enable_hpd(hdmi->connector);
+
+   ret = msm_hdmi_hpd_enable(hdmi->bridge);
if (ret < 0) {
DRM_DEV_ERROR(>pdev->dev, "failed to enable HPD: %d\n", 
ret);
goto fail;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h 
b/drivers/gpu/drm/msm/hdmi/hdmi.h

index 82261078c6b1..736f348befb3 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -114,6 +114,13 @@ struct hdmi_platform_config {
struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO];
 };

+struct hdmi_bridge {
+   struct drm_bridge base;
+   struct hdmi *hdmi;
+   struct work_struct hpd_work;
+};
+#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
+
 void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);

 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
@@ -230,13 +237,11 @@ void msm_hdmi_audio_set_sample_rate(struct hdmi
*hdmi, int rate);
 struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi);
 void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);

-/*
- * hdmi connector:
- */
-
-void msm_hdmi_connector_irq(struct drm_connector *connector);
-struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
-int msm_hdmi_hpd_enable(struct drm_connector *connector);
+void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
+enum drm_connector_status msm_hdmi_bridge_detect(
+   struct drm_bridge *bridge);
+int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
+void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge);

 /*
  * i2c adapter for ddc:
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index f04eb4a70f0d..211b73dddf65 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -5,17 +5,16 @@
  */

 #include 
+#include 

+#include "msm_kms.h"
 #include "hdmi.h"

-struct hdmi_bridge {
-   struct drm_bridge base;
-   struct hdmi *hdmi;
-};
-#define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
-
 void msm_hdmi_bridge_destroy(struct drm_bridge *bridge)
 {
+   struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+
+   msm_hdmi_hpd_disable(hdmi_bridge);
 }

 static void msm_hdmi_power_on(struct drm_bridge *bridge)
@@ -251,14 +250,76 @@ static void msm_hdmi_bridge_mode_set(struct

Re: [Freedreno] [PATCH 1/2] drm/msm/hdmi: use bulk regulator API

2021-10-15 Thread abhinavk

On 2021-10-14 17:10, Dmitry Baryshkov wrote:

Switch to using bulk regulator API instead of hand coding loops.


Nice cleanup!


Signed-off-by: Dmitry Baryshkov 


Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/hdmi/hdmi.c   | 34 +++
 drivers/gpu/drm/msm/hdmi/hdmi.h   |  6 ++--
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c| 20 -
 drivers/gpu/drm/msm/hdmi/hdmi_connector.c | 24 ++--
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c   | 33 --
 5 files changed, 40 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c 
b/drivers/gpu/drm/msm/hdmi/hdmi.c

index 737453b6e596..db17a000d968 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -154,19 +154,13 @@ static struct hdmi *msm_hdmi_init(struct
platform_device *pdev)
ret = -ENOMEM;
goto fail;
}
-   for (i = 0; i < config->hpd_reg_cnt; i++) {
-   struct regulator *reg;
-
-   reg = devm_regulator_get(>dev,
-   config->hpd_reg_names[i]);
-   if (IS_ERR(reg)) {
-   ret = PTR_ERR(reg);
-   DRM_DEV_ERROR(>dev, "failed to get hpd regulator: %s 
(%d)\n",
-   config->hpd_reg_names[i], ret);
-   goto fail;
-   }
+   for (i = 0; i < config->hpd_reg_cnt; i++)
+   hdmi->hpd_regs[i].supply = config->hpd_reg_names[i];

-   hdmi->hpd_regs[i] = reg;
+   ret = devm_regulator_bulk_get(>dev, config->hpd_reg_cnt,
hdmi->hpd_regs);
+   if (ret) {
+   DRM_DEV_ERROR(>dev, "failed to get hpd regulator: %d\n", 
ret);
+   goto fail;
}

hdmi->pwr_regs = devm_kcalloc(>dev,
@@ -177,19 +171,11 @@ static struct hdmi *msm_hdmi_init(struct
platform_device *pdev)
ret = -ENOMEM;
goto fail;
}
-   for (i = 0; i < config->pwr_reg_cnt; i++) {
-   struct regulator *reg;

-   reg = devm_regulator_get(>dev,
-   config->pwr_reg_names[i]);
-   if (IS_ERR(reg)) {
-   ret = PTR_ERR(reg);
-   DRM_DEV_ERROR(>dev, "failed to get pwr regulator: %s 
(%d)\n",
-   config->pwr_reg_names[i], ret);
-   goto fail;
-   }
-
-   hdmi->pwr_regs[i] = reg;
+   ret = devm_regulator_bulk_get(>dev, config->pwr_reg_cnt,
hdmi->pwr_regs);
+   if (ret) {
+   DRM_DEV_ERROR(>dev, "failed to get pwr regulator: %d\n", 
ret);
+   goto fail;
}

hdmi->hpd_clks = devm_kcalloc(>dev,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h 
b/drivers/gpu/drm/msm/hdmi/hdmi.h

index d0b84f0abee1..82261078c6b1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -56,8 +56,8 @@ struct hdmi {
void __iomem *qfprom_mmio;
phys_addr_t mmio_phy_addr;

-   struct regulator **hpd_regs;
-   struct regulator **pwr_regs;
+   struct regulator_bulk_data *hpd_regs;
+   struct regulator_bulk_data *pwr_regs;
struct clk **hpd_clks;
struct clk **pwr_clks;

@@ -163,7 +163,7 @@ struct hdmi_phy {
void __iomem *mmio;
struct hdmi_phy_cfg *cfg;
const struct hdmi_phy_funcs *funcs;
-   struct regulator **regs;
+   struct regulator_bulk_data *regs;
struct clk **clks;
 };

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 6e380db9287b..f04eb4a70f0d 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -28,13 +28,9 @@ static void msm_hdmi_power_on(struct drm_bridge 
*bridge)


pm_runtime_get_sync(>pdev->dev);

-   for (i = 0; i < config->pwr_reg_cnt; i++) {
-   ret = regulator_enable(hdmi->pwr_regs[i]);
-   if (ret) {
-			DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %s 
(%d)\n",

-   config->pwr_reg_names[i], ret);
-   }
-   }
+   ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
+   if (ret)
+		DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", 
ret);


if (config->pwr_clk_cnt > 0) {
DBG("pixclock: %lu", hdmi->pixclock);
@@ -70,13 +66,9 @@ static void power_off(struct drm_bridge *bridge)
for (i = 0; i < config->pwr_clk_cnt; i++)
clk_disable_unprepare(hdmi->pwr_clks[i]);

-   for (i = 0; i < config->pwr_reg_cnt; i++) {
-   ret = regulator_disable(hdmi->pwr_regs[i]);
-   if (ret) {
-			DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %s 
(%d)\n",

-   config->pwr_reg_names[i], ret);
-   }
-   }
+   ret = 

Re: [Freedreno] [PATCH 0/3] drm/msm: drop old eDP support

2021-10-15 Thread abhinavk

Hi Dmitry

No concerns from our side to drop this.

Reviewed-by: Abhinav Kumar  for the series.

Thanks

Abhinav

On 2021-10-01 09:50, Dmitry Baryshkov wrote:

MSM DRM driver has support for eDP block present on MSM 8x74/8x84 SoC
families. However since addition back in 2015 this driver received only
generic fixes. No actual devices with these SoCs supported upstream (or
by the community) seem to support eDP panels. Judging from downstream
kernels the eDP was present only on MSM8974 LIQUID or on APQ8084 CDP.
Remove this driver.


Dmitry Baryshkov (3):
  drm/msm/mdp5: drop eDP support
  drm/msm/edp: drop old eDP support
  dt-bindings: display/msm: remove edp.txt

 .../devicetree/bindings/display/msm/edp.txt|   56 -
 drivers/gpu/drm/msm/Makefile   |6 -
 drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c   |   17 +-
 drivers/gpu/drm/msm/edp/edp.c  |  198 ---
 drivers/gpu/drm/msm/edp/edp.h  |   77 --
 drivers/gpu/drm/msm/edp/edp.xml.h  |  388 --
 drivers/gpu/drm/msm/edp/edp_aux.c  |  265 
 drivers/gpu/drm/msm/edp/edp_bridge.c   |  111 --
 drivers/gpu/drm/msm/edp/edp_connector.c|  132 --
 drivers/gpu/drm/msm/edp/edp_ctrl.c | 1375 


 drivers/gpu/drm/msm/edp/edp_phy.c  |   98 --
 drivers/gpu/drm/msm/msm_drv.c  |2 -
 drivers/gpu/drm/msm/msm_drv.h  |   12 -
 13 files changed, 1 insertion(+), 2736 deletions(-)
 delete mode 100644 
Documentation/devicetree/bindings/display/msm/edp.txt

 delete mode 100644 drivers/gpu/drm/msm/edp/edp.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp.xml.h
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_aux.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_bridge.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_connector.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_ctrl.c
 delete mode 100644 drivers/gpu/drm/msm/edp/edp_phy.c


Re: [Freedreno] [PATCH] drm/msm/dp: Use the connector passed to dp_debug_get()

2021-10-12 Thread abhinavk

On 2021-10-12 16:38, Bjorn Andersson wrote:

On Tue 12 Oct 16:03 PDT 2021, abhin...@codeaurora.org wrote:


On 2021-10-09 20:04, Bjorn Andersson wrote:
> The debugfs code is provided an array of a single drm_connector. Then to
> access the connector, the list of all connectors of the DRM device is
> traversed and all non-DisplayPort connectors are skipped, to find the
> one and only DisplayPort connector.
>
> But as we move to support multiple DisplayPort controllers this will now
> find multiple connectors and has no way to distinguish them.
>
> Pass the single connector to dp_debug_get() and use this in the debugfs
> functions instead, both to simplify the code and the support the
> multiple instances.
>
Change itself is fine, hence
Reviewed-by: Abhinav Kumar 



Thanks.

What has to be checked now is now to create multiple DP nodes for 
multi-DP

cases.
Today, the debug node will be created only once :

https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c#L206

This also needs to be expanded for multi-DP to make the solution 
complete.




In my multi-DP support patch I end up invoking msm_dp_debugfs_init() 
for

each of the DP/eDP instances and in its current form the first one gets
registered and any others will fail because of the resulting name
collision.

This patch came as a byproduct of the effort of addressing that 
problem.


Regards,
Bjorn


Ah, okay. Yes i see the part you are referring to in 
https://patchwork.freedesktop.org/patch/457667/:


@@ -203,8 +204,10 @@  static int dpu_kms_debugfs_init(struct msm_kms 
*kms, struct drm_minor *minor)

dpu_debugfs_vbif_init(dpu_kms, entry);
dpu_debugfs_core_irq_init(dpu_kms, entry);

-   if (priv->dp)
-   msm_dp_debugfs_init(priv->dp, minor);
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (priv->dp[i])
+   msm_dp_debugfs_init(priv->dp[i], minor);
+   }

That clarifies it. Thanks.




> Signed-off-by: Bjorn Andersson 
> ---
>  drivers/gpu/drm/msm/dp/dp_debug.c   | 131 ++--
>  drivers/gpu/drm/msm/dp/dp_debug.h   |   2 +-
>  drivers/gpu/drm/msm/dp/dp_display.c |   2 +-
>  3 files changed, 46 insertions(+), 89 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
> b/drivers/gpu/drm/msm/dp/dp_debug.c
> index af709d93bb9f..da4323556ef3 100644
> --- a/drivers/gpu/drm/msm/dp/dp_debug.c
> +++ b/drivers/gpu/drm/msm/dp/dp_debug.c
> @@ -24,7 +24,7 @@ struct dp_debug_private {
>struct dp_usbpd *usbpd;
>struct dp_link *link;
>struct dp_panel *panel;
> -  struct drm_connector **connector;
> +  struct drm_connector *connector;
>struct device *dev;
>struct drm_device *drm_dev;
>
> @@ -97,59 +97,35 @@ DEFINE_SHOW_ATTRIBUTE(dp_debug);
>
>  static int dp_test_data_show(struct seq_file *m, void *data)
>  {
> -  struct drm_device *dev;
> -  struct dp_debug_private *debug;
> -  struct drm_connector *connector;
> -  struct drm_connector_list_iter conn_iter;
> +  const struct dp_debug_private *debug = m->private;
> +  const struct drm_connector *connector = debug->connector;
>u32 bpc;
>
> -  debug = m->private;
> -  dev = debug->drm_dev;
> -  drm_connector_list_iter_begin(dev, _iter);
> -  drm_for_each_connector_iter(connector, _iter) {
> -
> -  if (connector->connector_type !=
> -  DRM_MODE_CONNECTOR_DisplayPort)
> -  continue;
> -
> -  if (connector->status == connector_status_connected) {
> -  bpc = debug->link->test_video.test_bit_depth;
> -  seq_printf(m, "hdisplay: %d\n",
> -  debug->link->test_video.test_h_width);
> -  seq_printf(m, "vdisplay: %d\n",
> -  debug->link->test_video.test_v_height);
> -  seq_printf(m, "bpc: %u\n",
> -  dp_link_bit_depth_to_bpc(bpc));
> -  } else
> -  seq_puts(m, "0");
> +  if (connector->status == connector_status_connected) {
> +  bpc = debug->link->test_video.test_bit_depth;
> +  seq_printf(m, "hdisplay: %d\n",
> +  debug->link->test_video.test_h_width);
> +  seq_printf(m, "vdisplay: %d\n",
> +  debug->link->test_video.test_v_height);
> +  seq_printf(m, "bpc: %u\n",
> +  dp_link_bit_depth_to_bpc(bpc));
> +  } else {
> +  seq_puts(m, "0");
>}
>
> -  drm_connector_list_iter_end(_iter);
> -
>return 0;
>  }
>  DEFINE_SHOW_ATTRIBUTE(dp_test_data);
>
>  static int dp_test_type_show(struct seq_file *m, void *data)
>  {
> -  struct dp_debug_private *debug = m->private;
> -  struct drm_device *dev = debug->drm_dev;
> -  struct drm_connector *connector;
> -  struct drm_connector_list_iter conn_iter;
> -
> -  drm_connector_list_iter_begin(dev, _iter);
> -  drm_for_each_connector_iter(connector, _iter) {
> -
> -  if 

Re: [PATCH] drm/msm/dp: Use the connector passed to dp_debug_get()

2021-10-12 Thread abhinavk

On 2021-10-09 20:04, Bjorn Andersson wrote:
The debugfs code is provided an array of a single drm_connector. Then 
to

access the connector, the list of all connectors of the DRM device is
traversed and all non-DisplayPort connectors are skipped, to find the
one and only DisplayPort connector.

But as we move to support multiple DisplayPort controllers this will 
now

find multiple connectors and has no way to distinguish them.

Pass the single connector to dp_debug_get() and use this in the debugfs
functions instead, both to simplify the code and the support the
multiple instances.


Change itself is fine, hence
Reviewed-by: Abhinav Kumar 

What has to be checked now is now to create multiple DP nodes for 
multi-DP cases.

Today, the debug node will be created only once :

https://gitlab.freedesktop.org/drm/msm/-/blob/msm-next/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c#L206

This also needs to be expanded for multi-DP to make the solution 
complete.



Signed-off-by: Bjorn Andersson 
---
 drivers/gpu/drm/msm/dp/dp_debug.c   | 131 ++--
 drivers/gpu/drm/msm/dp/dp_debug.h   |   2 +-
 drivers/gpu/drm/msm/dp/dp_display.c |   2 +-
 3 files changed, 46 insertions(+), 89 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
b/drivers/gpu/drm/msm/dp/dp_debug.c
index af709d93bb9f..da4323556ef3 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -24,7 +24,7 @@ struct dp_debug_private {
struct dp_usbpd *usbpd;
struct dp_link *link;
struct dp_panel *panel;
-   struct drm_connector **connector;
+   struct drm_connector *connector;
struct device *dev;
struct drm_device *drm_dev;

@@ -97,59 +97,35 @@ DEFINE_SHOW_ATTRIBUTE(dp_debug);

 static int dp_test_data_show(struct seq_file *m, void *data)
 {
-   struct drm_device *dev;
-   struct dp_debug_private *debug;
-   struct drm_connector *connector;
-   struct drm_connector_list_iter conn_iter;
+   const struct dp_debug_private *debug = m->private;
+   const struct drm_connector *connector = debug->connector;
u32 bpc;

-   debug = m->private;
-   dev = debug->drm_dev;
-   drm_connector_list_iter_begin(dev, _iter);
-   drm_for_each_connector_iter(connector, _iter) {
-
-   if (connector->connector_type !=
-   DRM_MODE_CONNECTOR_DisplayPort)
-   continue;
-
-   if (connector->status == connector_status_connected) {
-   bpc = debug->link->test_video.test_bit_depth;
-   seq_printf(m, "hdisplay: %d\n",
-   debug->link->test_video.test_h_width);
-   seq_printf(m, "vdisplay: %d\n",
-   debug->link->test_video.test_v_height);
-   seq_printf(m, "bpc: %u\n",
-   dp_link_bit_depth_to_bpc(bpc));
-   } else
-   seq_puts(m, "0");
+   if (connector->status == connector_status_connected) {
+   bpc = debug->link->test_video.test_bit_depth;
+   seq_printf(m, "hdisplay: %d\n",
+   debug->link->test_video.test_h_width);
+   seq_printf(m, "vdisplay: %d\n",
+   debug->link->test_video.test_v_height);
+   seq_printf(m, "bpc: %u\n",
+   dp_link_bit_depth_to_bpc(bpc));
+   } else {
+   seq_puts(m, "0");
}

-   drm_connector_list_iter_end(_iter);
-
return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(dp_test_data);

 static int dp_test_type_show(struct seq_file *m, void *data)
 {
-   struct dp_debug_private *debug = m->private;
-   struct drm_device *dev = debug->drm_dev;
-   struct drm_connector *connector;
-   struct drm_connector_list_iter conn_iter;
-
-   drm_connector_list_iter_begin(dev, _iter);
-   drm_for_each_connector_iter(connector, _iter) {
-
-   if (connector->connector_type !=
-   DRM_MODE_CONNECTOR_DisplayPort)
-   continue;
+   const struct dp_debug_private *debug = m->private;
+   const struct drm_connector *connector = debug->connector;

-   if (connector->status == connector_status_connected)
-   seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
-   else
-   seq_puts(m, "0");
-   }
-   drm_connector_list_iter_end(_iter);
+   if (connector->status == connector_status_connected)
+   seq_printf(m, "%02x", DP_TEST_LINK_VIDEO_PATTERN);
+   else
+   seq_puts(m, "0");

return 0;
 }
@@ -161,14 +137,12 @@ static ssize_t dp_test_active_write(struct file 
*file,

 {
char *input_buffer;
int status = 0;
-   struct dp_debug_private *debug;
-   struct drm_device *dev;
-   struct 

Re: [Freedreno] [PATCH v2] drm/msm/dsi: Use division result from div_u64_rem in 7nm and 14nm PLL

2021-10-11 Thread abhinavk

On 2021-10-11 13:16, Marijn Suijten wrote:

div_u64_rem provides the result of the division and additionally the
remainder; don't use this function to solely calculate the remainder
while calculating the division again with div_u64.

A similar improvement was applied earlier to the 10nm pll in
5c191fef4ce2 ("drm/msm/dsi_pll_10nm: Fix dividing the same numbers
twice").

Signed-off-by: Marijn Suijten 

Reviewed-by: Abhinav Kumar 

---

Changes in v2:
- Corrected two typos in the first commit-message sentence.

 drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 4 +---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c  | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
index 9a959a5dcc1e..de3c6556a587 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
@@ -215,9 +215,7 @@ static void pll_14nm_dec_frac_calc(struct
dsi_pll_14nm *pll, struct dsi_pll_conf
DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref);

dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref);
-   div_u64_rem(dec_start_multiple, multiplier, _frac_start);
-
-   dec_start = div_u64(dec_start_multiple, multiplier);
+	dec_start = div_u64_rem(dec_start_multiple, multiplier, 
_frac_start);


pconf->dec_start = (u32)dec_start;
pconf->div_frac_start = div_frac_start;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
index 9f7c408325ba..36eb6109cb88 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -114,9 +114,7 @@ static void dsi_pll_calc_dec_frac(struct
dsi_pll_7nm *pll, struct dsi_pll_config

multiplier = 1 << FRAC_BITS;
dec_multiple = div_u64(pll_freq * multiplier, divider);
-   div_u64_rem(dec_multiple, multiplier, );
-
-   dec = div_u64(dec_multiple, multiplier);
+   dec = div_u64_rem(dec_multiple, multiplier, );

if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
config->pll_clock_inverters = 0x28;
--
2.33.0


Re: [PATCH v4 5/7] drm/msm/dp: Support up to 3 DP controllers

2021-10-07 Thread abhinavk

Hi Bjorn and Stephen

On 2021-10-06 13:39, Bjorn Andersson wrote:

On Wed 06 Oct 11:59 PDT 2021, Stephen Boyd wrote:


Quoting Bjorn Andersson (2021-10-06 11:05:09)
> On Wed 06 Oct 10:19 PDT 2021, Stephen Boyd wrote:
>
> > Quoting Bjorn Andersson (2021-10-06 10:07:17)
> > > On Tue 05 Oct 21:26 PDT 2021, Stephen Boyd wrote:
> > >
> > > > Quoting Bjorn Andersson (2021-10-05 19:37:52)
> > > > > On Tue 05 Oct 19:06 PDT 2021, Stephen Boyd wrote:
> > > > >
> > > > > > Quoting Bjorn Andersson (2021-10-05 18:43:16)
> > > > > > > On Tue 05 Oct 17:43 PDT 2021, Stephen Boyd wrote:
> > > > > > >
> > > > > > > > Quoting Bjorn Andersson (2021-10-05 16:13:21)
> > > > > > > > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c 
b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > index bdaf227f05dc..674cddfee5b0 100644
> > > > > > > > > --- a/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> > > > > > > > > @@ -1233,7 +1239,7 @@ static int dp_display_probe(struct 
platform_device *pdev)
> > > > > > > > > if (!dp)
> > > > > > > > > return -ENOMEM;
> > > > > > > > >
> > > > > > > > > -   desc = dp_display_get_desc(pdev);
> > > > > > > > > +   desc = dp_display_get_desc(pdev, >id);
> > > > > > > >
> > > > > > > > I'm sad that dp->id has to match the number in the SoC specific
> > > > > > > > dpu_intf_cfg array in 
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > > > > > > > still. Is there any way we can avoid that? Also, notice how 
those arrays
> > > > > > > > already have INTF_DP macros, which makes me think that it may 
be better
> > > > > > > > to connect this to those arrays instead of making an msm_dp_desc
> > > > > > > > structure and then make sure the 'type' member matches a 
connector
> > > > > > > > type number. Otherwise this code is super fragile.
> > > > > > > >
> > > > > > >
> > > > > > > I'm afraid I don't understand what you're proposing. Or which 
part you
> > > > > > > consider fragile, the indices of the INTF_DP instances aren't 
going to
> > > > > > > move around...
> > > > > > >
> > > > > > > I have N instances of the DP driver that I need to match to N 
entries
> > > > > > > from the platform specific intf array, I need some stable 
reference
> > > > > > > between them. When I started this journey I figured I could rely 
on the
> > > > > > > of_graph between the DPU and the interface controllers, but the 
values
> > > > > > > used there today are just bogus, so that was a no go.
> > > > > > >
> > > > > > > We can use whatever, as long as _dpu_kms_initialize_displayport() 
can
> > > > > > > come up with an identifier to put in h_tile_instance[0] so that
> > > > > > > dpu_encoder_setup_display() can find the relevant INTF.
> > > > > > >
> > > > > >
> > > > > > To make it more concrete we can look at sc7180
> > > > > >
> > > > > > static const struct dpu_intf_cfg sc7180_intf[] = {
> > > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24,
> > > > > > INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > >  ^
> > > > > >  |
> > > > > >
> > > > > > intf0 is irrelevant. Also the address is irrelevant. But here we 
have a
> > > > > > zero, the number after INTF_DP, and that is very relevant. That 
number
> > > > > > needs to match the dp->id. Somewhere we have a match between
> > > > > > controller_id and dp->id in the code.
> > > > >
> > > > > That number (the 0, not INTF_0) is what the code matches against 
dp->id
> > > > > in _dpu_kms_initialize_displayport(), in order to figure out that this
> > > > > is INTF_0 in dpu_encoder_setup_display().
> > > > >
> > > > > I.e. look at the sc8180x patch:
> > > > >
> > > > > INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> > > > > INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> > > > > INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> > > > > /* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until 
this is supported */
> > > > > INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> > > > > INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, 1, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
> > > > > INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, 2, 24, 
INTF_SC8180X_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> > > > >
> > > > > Where the DP driver defines the 3 controllers with dp->id of 0, 1 and 
2,
> > > > > which the DPU code will match against to INTF_0, INTF_4 and INTF_5.
> > > > >
> > > >
> > > > Yep. I'm saying that having to make that number in this intf array match
> > > > the order of the register mapping descriptor array is fragile. Why can't
> > > > we indicate the interface is DP or eDP with INTF_DP or INTF_EDP and then
> > > > map from 

Re: [Freedreno] [PATCH v4 4/7] drm/msm/dp: Allow attaching a drm_panel

2021-10-05 Thread abhinavk

On 2021-10-05 19:09, Bjorn Andersson wrote:

On Tue 05 Oct 17:35 PDT 2021, abhin...@codeaurora.org wrote:


Hi Bjorn

On 2021-10-05 16:13, Bjorn Andersson wrote:
> eDP panels might need some power sequencing and backlight management,
> so make it possible to associate a drm_panel with an eDP instance and
> prepare and enable the panel accordingly.
>
> Now that we know which hardware instance is DP and which is eDP,
> parser->parse() is passed the connector_type and the parser is limited
> to only search for a panel in the eDP case.
>
> Signed-off-by: Bjorn Andersson 
> ---
>
> Changes since v3:
> - Previously posted separately, now added to series
> - Make the search for a panel conditional on it being an eDP connector
> - Move the search to of_graph port 1 (was 2 to distinguish from DP
> link to USB-C connector)
>
>  drivers/gpu/drm/msm/dp/dp_display.c |  9 ++---
>  drivers/gpu/drm/msm/dp/dp_display.h |  1 +
>  drivers/gpu/drm/msm/dp/dp_drm.c | 11 +++
>  drivers/gpu/drm/msm/dp/dp_parser.c  | 30 -
>  drivers/gpu/drm/msm/dp/dp_parser.h  |  3 ++-
>  5 files changed, 49 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
> b/drivers/gpu/drm/msm/dp/dp_display.c
> index eaf08f9e7d87..bdaf227f05dc 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.c
> +++ b/drivers/gpu/drm/msm/dp/dp_display.c
> @@ -10,6 +10,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include "msm_drv.h"
>  #include "msm_kms.h"
> @@ -230,12 +231,14 @@ static int dp_display_bind(struct device *dev,
> struct device *master,
>priv = drm->dev_private;
>priv->dp = &(dp->dp_display);
>
> -  rc = dp->parser->parse(dp->parser);
> +  rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
>if (rc) {
>DRM_ERROR("device tree parsing failed\n");
>goto end;
>}
>
> +  dp->dp_display.panel_bridge = dp->parser->panel_bridge;
> +
>dp->aux->drm_dev = drm;
>rc = dp_aux_register(dp->aux);
>if (rc) {
> @@ -822,7 +825,7 @@ static int dp_display_set_mode(struct msm_dp
> *dp_display,
>return 0;
>  }
>
> -static int dp_display_prepare(struct msm_dp *dp)
> +static int dp_display_prepare(struct msm_dp *dp_display)
>  {
>return 0;
>  }
> @@ -896,7 +899,7 @@ static int dp_display_disable(struct
> dp_display_private *dp, u32 data)
>return 0;
>  }
>
> -static int dp_display_unprepare(struct msm_dp *dp)
> +static int dp_display_unprepare(struct msm_dp *dp_display)
>  {
>return 0;
>  }
> diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
> b/drivers/gpu/drm/msm/dp/dp_display.h
> index 02999408c052..24aefca66029 100644
> --- a/drivers/gpu/drm/msm/dp/dp_display.h
> +++ b/drivers/gpu/drm/msm/dp/dp_display.h
> @@ -15,6 +15,7 @@ struct msm_dp {
>struct device *codec_dev;
>struct drm_connector *connector;
>struct drm_encoder *encoder;
> +  struct drm_bridge *panel_bridge;
>bool is_connected;
>bool audio_enabled;
>bool power_on;
> diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c
> b/drivers/gpu/drm/msm/dp/dp_drm.c
> index f33e31523f56..76856c4ee1d6 100644
> --- a/drivers/gpu/drm/msm/dp/dp_drm.c
> +++ b/drivers/gpu/drm/msm/dp/dp_drm.c
> @@ -5,6 +5,7 @@
>
>  #include 
>  #include 
> +#include 
>  #include 
>
>  #include "msm_drv.h"
> @@ -160,5 +161,15 @@ struct drm_connector
> *dp_drm_connector_init(struct msm_dp *dp_display)
>
>drm_connector_attach_encoder(connector, dp_display->encoder);
>
> +  if (dp_display->panel_bridge) {
> +  ret = drm_bridge_attach(dp_display->encoder,
> +  dp_display->panel_bridge, NULL,
> +  DRM_BRIDGE_ATTACH_NO_CONNECTOR);
> +  if (ret < 0) {
> +  DRM_ERROR("failed to attach panel bridge: %d\n", ret);
> +  return ERR_PTR(ret);
> +  }
> +  }
> +
>return connector;
>  }
> diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c
> b/drivers/gpu/drm/msm/dp/dp_parser.c
> index 4d6e047f803d..eb6bbfbea484 100644
> --- a/drivers/gpu/drm/msm/dp/dp_parser.c
> +++ b/drivers/gpu/drm/msm/dp/dp_parser.c
> @@ -6,6 +6,7 @@
>  #include 
>  #include 
>
> +#include 
>  #include 
>
>  #include "dp_parser.h"
> @@ -263,7 +264,28 @@ static int dp_parser_clock(struct dp_parser
> *parser)
>return 0;
>  }
>
> -static int dp_parser_parse(struct dp_parser *parser)
> +static int dp_parser_find_panel(struct dp_parser *parser)
> +{
> +  struct device *dev = >pdev->dev;
> +  struct drm_panel *panel;
> +  int rc;
> +
> +  rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
> +  if (rc) {
> +  DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
> +  return rc;
> +  }
> +
> +  parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> +  if (IS_ERR(parser->panel_bridge)) {
> +  DRM_ERROR("failed to create panel bridge\n");
> +  return PTR_ERR(parser->panel_bridge);
> +  }

When we add a bridge using devm_drm_panel_bridge_add(), it will 

Re: [Freedreno] [PATCH v4 4/7] drm/msm/dp: Allow attaching a drm_panel

2021-10-05 Thread abhinavk

Hi Bjorn

On 2021-10-05 16:13, Bjorn Andersson wrote:

eDP panels might need some power sequencing and backlight management,
so make it possible to associate a drm_panel with an eDP instance and
prepare and enable the panel accordingly.

Now that we know which hardware instance is DP and which is eDP,
parser->parse() is passed the connector_type and the parser is limited
to only search for a panel in the eDP case.

Signed-off-by: Bjorn Andersson 
---

Changes since v3:
- Previously posted separately, now added to series
- Make the search for a panel conditional on it being an eDP connector
- Move the search to of_graph port 1 (was 2 to distinguish from DP
link to USB-C connector)

 drivers/gpu/drm/msm/dp/dp_display.c |  9 ++---
 drivers/gpu/drm/msm/dp/dp_display.h |  1 +
 drivers/gpu/drm/msm/dp/dp_drm.c | 11 +++
 drivers/gpu/drm/msm/dp/dp_parser.c  | 30 -
 drivers/gpu/drm/msm/dp/dp_parser.h  |  3 ++-
 5 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index eaf08f9e7d87..bdaf227f05dc 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "msm_drv.h"
 #include "msm_kms.h"
@@ -230,12 +231,14 @@ static int dp_display_bind(struct device *dev,
struct device *master,
priv = drm->dev_private;
priv->dp = &(dp->dp_display);

-   rc = dp->parser->parse(dp->parser);
+   rc = dp->parser->parse(dp->parser, dp->dp_display.connector_type);
if (rc) {
DRM_ERROR("device tree parsing failed\n");
goto end;
}

+   dp->dp_display.panel_bridge = dp->parser->panel_bridge;
+
dp->aux->drm_dev = drm;
rc = dp_aux_register(dp->aux);
if (rc) {
@@ -822,7 +825,7 @@ static int dp_display_set_mode(struct msm_dp 
*dp_display,

return 0;
 }

-static int dp_display_prepare(struct msm_dp *dp)
+static int dp_display_prepare(struct msm_dp *dp_display)
 {
return 0;
 }
@@ -896,7 +899,7 @@ static int dp_display_disable(struct
dp_display_private *dp, u32 data)
return 0;
 }

-static int dp_display_unprepare(struct msm_dp *dp)
+static int dp_display_unprepare(struct msm_dp *dp_display)
 {
return 0;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_display.h
b/drivers/gpu/drm/msm/dp/dp_display.h
index 02999408c052..24aefca66029 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.h
+++ b/drivers/gpu/drm/msm/dp/dp_display.h
@@ -15,6 +15,7 @@ struct msm_dp {
struct device *codec_dev;
struct drm_connector *connector;
struct drm_encoder *encoder;
+   struct drm_bridge *panel_bridge;
bool is_connected;
bool audio_enabled;
bool power_on;
diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c 
b/drivers/gpu/drm/msm/dp/dp_drm.c

index f33e31523f56..76856c4ee1d6 100644
--- a/drivers/gpu/drm/msm/dp/dp_drm.c
+++ b/drivers/gpu/drm/msm/dp/dp_drm.c
@@ -5,6 +5,7 @@

 #include 
 #include 
+#include 
 #include 

 #include "msm_drv.h"
@@ -160,5 +161,15 @@ struct drm_connector
*dp_drm_connector_init(struct msm_dp *dp_display)

drm_connector_attach_encoder(connector, dp_display->encoder);

+   if (dp_display->panel_bridge) {
+   ret = drm_bridge_attach(dp_display->encoder,
+   dp_display->panel_bridge, NULL,
+   DRM_BRIDGE_ATTACH_NO_CONNECTOR);
+   if (ret < 0) {
+   DRM_ERROR("failed to attach panel bridge: %d\n", ret);
+   return ERR_PTR(ret);
+   }
+   }
+
return connector;
 }
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c
b/drivers/gpu/drm/msm/dp/dp_parser.c
index 4d6e047f803d..eb6bbfbea484 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -6,6 +6,7 @@
 #include 
 #include 

+#include 
 #include 

 #include "dp_parser.h"
@@ -263,7 +264,28 @@ static int dp_parser_clock(struct dp_parser 
*parser)

return 0;
 }

-static int dp_parser_parse(struct dp_parser *parser)
+static int dp_parser_find_panel(struct dp_parser *parser)
+{
+   struct device *dev = >pdev->dev;
+   struct drm_panel *panel;
+   int rc;
+
+   rc = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, , NULL);
+   if (rc) {
+   DRM_ERROR("failed to acquire DRM panel: %d\n", rc);
+   return rc;
+   }
+
+   parser->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
+   if (IS_ERR(parser->panel_bridge)) {
+   DRM_ERROR("failed to create panel bridge\n");
+   return PTR_ERR(parser->panel_bridge);
+   }


When we add a bridge using devm_drm_panel_bridge_add(), it will register 
with default bridge functions which is fine

because we need the panel power to be controlled here.


140 static const struct drm_bridge_funcs 

Re: [Freedreno] [PATCH v3 4/5] drm/msm/dp: Store each subblock in the io region

2021-10-05 Thread abhinavk

On 2021-10-01 10:43, Bjorn Andersson wrote:

Not all platforms has DP_P0 at offset 0x1000 from the beginning of the
DP block. So split the dss_io_data memory region into a set of
sub-regions, to make it possible in the next patch to specify each of
the sub-regions individually.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- Skipped the unnecessary reorder in struct dss_io_region

 drivers/gpu/drm/msm/dp/dp_catalog.c | 64 +
 drivers/gpu/drm/msm/dp/dp_parser.c  | 28 +++--
 drivers/gpu/drm/msm/dp/dp_parser.h  |  9 +++-
 3 files changed, 53 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c
b/drivers/gpu/drm/msm/dp/dp_catalog.c
index cc2bb8295329..6ae9b29044b6 100644
--- a/drivers/gpu/drm/msm/dp/dp_catalog.c
+++ b/drivers/gpu/drm/msm/dp/dp_catalog.c
@@ -24,15 +24,6 @@
 #define DP_INTERRUPT_STATUS_ACK_SHIFT  1
 #define DP_INTERRUPT_STATUS_MASK_SHIFT 2

-#define MSM_DP_CONTROLLER_AHB_OFFSET   0x
-#define MSM_DP_CONTROLLER_AHB_SIZE 0x0200
-#define MSM_DP_CONTROLLER_AUX_OFFSET   0x0200
-#define MSM_DP_CONTROLLER_AUX_SIZE 0x0200
-#define MSM_DP_CONTROLLER_LINK_OFFSET  0x0400
-#define MSM_DP_CONTROLLER_LINK_SIZE0x0C00
-#define MSM_DP_CONTROLLER_P0_OFFSET0x1000
-#define MSM_DP_CONTROLLER_P0_SIZE  0x0400
-
 #define DP_INTERRUPT_STATUS1 \
(DP_INTR_AUX_I2C_DONE| \
DP_INTR_WRONG_ADDR | DP_INTR_TIMEOUT | \
@@ -66,82 +57,77 @@ void dp_catalog_snapshot(struct dp_catalog
*dp_catalog, struct msm_disp_state *d
 {
struct dp_catalog_private *catalog = container_of(dp_catalog,
struct dp_catalog_private, dp_catalog);
+   struct dss_io_data *dss = >io->dp_controller;

-	msm_disp_snapshot_add_block(disp_state, 
catalog->io->dp_controller.len,

-   catalog->io->dp_controller.base, "dp_ctrl");
+   msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base,
"dp_ahb");
+   msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base,
"dp_aux");
+   msm_disp_snapshot_add_block(disp_state, dss->link.len,
dss->link.base, "dp_link");
+	msm_disp_snapshot_add_block(disp_state, dss->p0.len, dss->p0.base, 
"dp_p0");

 }
I like this part, devcoredump will look pretty clean and well separated 
with this.




 static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 
offset)

 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.aux.base + offset);
 }

 static inline void dp_write_aux(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AUX_OFFSET;
/*
 * To make sure aux reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.aux.base + offset);
 }

 static inline u32 dp_read_ahb(struct dp_catalog_private *catalog, u32 
offset)

 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
 }

 static inline void dp_write_ahb(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_AHB_OFFSET;
/*
 * To make sure phy reg writes happens before any other operation,
 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.ahb.base + offset);
 }

 static inline void dp_write_p0(struct dp_catalog_private *catalog,
   u32 offset, u32 data)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 	 * To make sure interface reg writes happens before any other 
operation,

 * this function uses writel() instread of writel_relaxed()
 */
-   writel(data, catalog->io->dp_controller.base + offset);
+   writel(data, catalog->io->dp_controller.p0.base + offset);
 }

 static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
   u32 offset)
 {
-   offset += MSM_DP_CONTROLLER_P0_OFFSET;
/*
 	 * To make sure interface reg writes happens before any other 
operation,

 * this function uses writel() instread of writel_relaxed()
 */
-   return readl_relaxed(catalog->io->dp_controller.base + offset);
+   return readl_relaxed(catalog->io->dp_controller.p0.base + offset);
 }

 static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 
offset)

 {
-   offset += MSM_DP_CONTROLLER_LINK_OFFSET;
-   return 

Re: [Freedreno] [PATCH v3 3/5] drm/msm/dp: Refactor ioremap wrapper

2021-10-05 Thread abhinavk

On 2021-10-01 10:43, Bjorn Andersson wrote:

In order to deal with multiple memory ranges in the following commit
change the ioremap wrapper to not poke directly into the dss_io_data
struct.

While at it, devm_ioremap_resource() already prints useful error
messages on failure, so omit the unnecessary prints from the caller.

Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- Switched to devm_platform_get_and_ioremap_resource()

 drivers/gpu/drm/msm/dp/dp_parser.c | 35 ++
 drivers/gpu/drm/msm/dp/dp_parser.h |  2 +-
 2 files changed, 12 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c
b/drivers/gpu/drm/msm/dp/dp_parser.c
index c064ced78278..c05ba1990218 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -19,40 +19,27 @@ static const struct dp_regulator_cfg 
sdm845_dp_reg_cfg = {

},
 };

-static int msm_dss_ioremap(struct platform_device *pdev,
-   struct dss_io_data *io_data)
+static void __iomem *dp_ioremap(struct platform_device *pdev, int
idx, size_t *len)
 {
-   struct resource *res = NULL;
+   struct resource *res;
+   void __iomem *base;

-   res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (!res) {
-   DRM_ERROR("%pS->%s: msm_dss_get_res failed\n",
-   __builtin_return_address(0), __func__);
-   return -ENODEV;
-   }
-
-   io_data->len = (u32)resource_size(res);
-   io_data->base = devm_ioremap(>dev, res->start, io_data->len);
-   if (!io_data->base) {
-   DRM_ERROR("%pS->%s: ioremap failed\n",
-   __builtin_return_address(0), __func__);
-   return -EIO;
-   }
+   base = devm_platform_get_and_ioremap_resource(pdev, idx, );
+   if (!IS_ERR(base))
+   *len = resource_size(res);

-   return 0;
+   return base;
 }

 static int dp_parser_ctrl_res(struct dp_parser *parser)
 {
-   int rc = 0;
struct platform_device *pdev = parser->pdev;
struct dp_io *io = >io;
+   struct dss_io_data *dss = >dp_controller;

-   rc = msm_dss_ioremap(pdev, >dp_controller);
-   if (rc) {
-   DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc);
-   return rc;
-   }
+   dss->base = dp_ioremap(pdev, 0, >len);
+   if (IS_ERR(dss->base))
+   return PTR_ERR(dss->base);

io->phy = devm_phy_get(>dev, "dp");
if (IS_ERR(io->phy))
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h
b/drivers/gpu/drm/msm/dp/dp_parser.h
index 34b49628bbaf..dc62e70b1640 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -26,7 +26,7 @@ enum dp_pm_type {
 };

 struct dss_io_data {
-   u32 len;
+   size_t len;
void __iomem *base;
 };


Re: [Freedreno] [PATCH v3 1/5] dt-bindings: msm/dp: Change reg definition

2021-10-05 Thread abhinavk

On 2021-10-01 10:43, Bjorn Andersson wrote:

reg was defined as one region covering the entire DP block, but the
memory map is actually split in 4 regions and obviously the size of
these regions differs between platforms.

Switch the reg to require that all four regions are specified instead.
It is expected that the implementation will handle existing DTBs, even
though the schema defines the new layout.

Reviewed-by: Stephen Boyd 
Reviewed-by: Rob Herring 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- None

 .../bindings/display/msm/dp-controller.yaml | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git
a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index d89b3c510c27..6bb424c21340 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -19,7 +19,12 @@ properties:
   - qcom,sc7180-dp

   reg:
-maxItems: 1
+items:
+  - description: ahb register block
+  - description: aux register block
+  - description: link register block
+  - description: p0 register block
+  - description: p1 register block

   interrupts:
 maxItems: 1
@@ -99,7 +104,11 @@ examples:

 displayport-controller@ae9 {
 compatible = "qcom,sc7180-dp";
-reg = <0xae9 0x1400>;
+reg = <0xae9 0x200>,
+  <0xae90200 0x200>,
+  <0xae90400 0xc00>,
+  <0xae91000 0x400>,
+  <0xae91400 0x400>;
 interrupt-parent = <>;
 interrupts = <12>;
 clocks = < DISP_CC_MDSS_AHB_CLK>,


Re: [Freedreno] [PATCH v3 5/5] drm/msm/dp: Add sc8180x DP controllers

2021-10-05 Thread abhinavk

On 2021-10-01 11:00, Bjorn Andersson wrote:
The sc8180x has 2 DP and 1 eDP controllers, add support for these to 
the

DP driver.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_display.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index ff3477474c5d..56a79aeffed4 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -127,8 +127,15 @@ static const struct msm_dp_config sc7180_dp_cfg = 
{

.num_descs = 1,
 };

+static const struct msm_dp_config sc8180x_dp_cfg = {
+   .io_start = { 0xae9, 0xae98000, 0xae9a000 },
+   .num_descs = 3,
+};
+
 static const struct of_device_id dp_dt_match[] = {
{ .compatible = "qcom,sc7180-dp", .data = _dp_cfg },
+   { .compatible = "qcom,sc8180x-dp", .data = _dp_cfg },
+   { .compatible = "qcom,sc8180x-edp", .data = _dp_cfg },
{}
 };


Re: [PATCH v3 4/5] dt-bindings: msm/dp: Add SC8180x compatibles

2021-10-05 Thread abhinavk

On 2021-10-01 11:00, Bjorn Andersson wrote:

The Qualcomm SC8180x has 2 DP controllers and 1 eDP controller, add
compatibles for these to the msm/dp binding.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- None

 .../devicetree/bindings/display/msm/dp-controller.yaml  | 2 ++
 1 file changed, 2 insertions(+)

diff --git
a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
index 6bb424c21340..63e585f48789 100644
--- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml
@@ -17,6 +17,8 @@ properties:
   compatible:
 enum:
   - qcom,sc7180-dp
+  - qcom,sc8180x-dp
+  - qcom,sc8180x-edp

   reg:
 items:


Re: [Freedreno] [PATCH v3 3/5] drm/msm/dp: Support up to 3 DP controllers

2021-10-05 Thread abhinavk

On 2021-10-05 13:16, abhin...@codeaurora.org wrote:

On 2021-10-01 11:00, Bjorn Andersson wrote:

Based on the removal of the g_dp_display and the movement of the
priv->dp lookup into the DP code it's now possible to have multiple
DP instances.

In line with the other controllers in the MSM driver, introduce a
per-compatible list of base addresses which is used to resolve the
"instance id" for the given DP controller. This instance id is used as
index in the priv->dp[] array.

Then extend the initialization code to initialize struct drm_encoder 
for

each of the registered priv->dp[] and update the logic for associating
each struct msm_dp with the struct dpu_encoder_virt.

Lastly, bump the number of struct msm_dp instances carries by priv->dp
to 3, the currently known maximum number of controllers found in a
Qualcomm SoC.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Added MSM_DRM_DP_COUNT to link the two 3s
- Moved NULL check for msm_dp_debugfs_init() to the call site
- Made struct dp_display_private->id unsigned

I also implemented added connector_type to each of the DP instances 
and
propagated this to dp_drm_connector_init() but later dropped this 
again per
Doug's suggestion that we'll base this on the presence/absence of a 
associated

drm bridge or panel.


Hi Bjorn / Doug

I suggest we add the dp_drm_connector_init() part back to this change.
Having the same connector type for DP and eDP is an error and instead of
blocking/pending it on a potential RFC which attaches a panel to DP,
I would rather do it right here. So till thats done, I would retract my
R-B.

Thanks

Abhinav




 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 66 
+++

 .../gpu/drm/msm/disp/msm_disp_snapshot_util.c |  8 ++-
 drivers/gpu/drm/msm/dp/dp_display.c   | 44 -
 drivers/gpu/drm/msm/msm_drv.h |  4 +-
 5 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b7f33da2799c..9cd9539a1504 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2173,7 +2173,7 @@ int dpu_encoder_setup(struct drm_device *dev,
struct drm_encoder *enc,
dpu_encoder_vsync_event_handler,
0);
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
-   dpu_enc->dp = priv->dp;
+   dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];


At this point this is a nit but not sure if this is right to use the
tile_instance as the index.
In the future if we chose to assign another index to the
h_tile_instance, this would break.
But I cant think of the use-case for that yet.






INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index f655adbc2421..875b07e7183d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -188,6 +188,7 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
struct dentry *entry;
struct drm_device *dev;
struct msm_drm_private *priv;
+   int i;

if (!p)
return -EINVAL;
@@ -203,8 +204,10 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
dpu_debugfs_vbif_init(dpu_kms, entry);
dpu_debugfs_core_irq_init(dpu_kms, entry);

-   if (priv->dp)
-   msm_dp_debugfs_init(priv->dp, minor);
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (priv->dp[i])
+   msm_dp_debugfs_init(priv->dp[i], minor);
+   }

return dpu_core_perf_debugfs_init(dpu_kms, entry);
 }
@@ -544,35 +547,42 @@ static int
_dpu_kms_initialize_displayport(struct drm_device *dev,
 {
struct drm_encoder *encoder = NULL;
struct msm_display_info info;
-   int rc = 0;
+   int rc;
+   int i;

-   if (!priv->dp)
-   return rc;
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (!priv->dp[i])
+   continue;

-   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
-   if (IS_ERR(encoder)) {
-   DPU_ERROR("encoder init failed for dsi display\n");
-   return PTR_ERR(encoder);
-   }
+   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR(encoder)) {
+   DPU_ERROR("encoder init failed for dsi display\n");
+   return PTR_ERR(encoder);
+   }

-   memset(, 0, sizeof(info));
-   rc = msm_dp_modeset_init(priv->dp, dev, encoder);
-   if (rc) {
-   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
-   

Re: [Freedreno] [PATCH v3 3/5] drm/msm/dp: Support up to 3 DP controllers

2021-10-05 Thread abhinavk

On 2021-10-01 11:00, Bjorn Andersson wrote:

Based on the removal of the g_dp_display and the movement of the
priv->dp lookup into the DP code it's now possible to have multiple
DP instances.

In line with the other controllers in the MSM driver, introduce a
per-compatible list of base addresses which is used to resolve the
"instance id" for the given DP controller. This instance id is used as
index in the priv->dp[] array.

Then extend the initialization code to initialize struct drm_encoder 
for

each of the registered priv->dp[] and update the logic for associating
each struct msm_dp with the struct dpu_encoder_virt.

Lastly, bump the number of struct msm_dp instances carries by priv->dp
to 3, the currently known maximum number of controllers found in a
Qualcomm SoC.

Signed-off-by: Bjorn Andersson 
---

Changes since v2:
- Added MSM_DRM_DP_COUNT to link the two 3s
- Moved NULL check for msm_dp_debugfs_init() to the call site
- Made struct dp_display_private->id unsigned

I also implemented added connector_type to each of the DP instances and
propagated this to dp_drm_connector_init() but later dropped this again 
per
Doug's suggestion that we'll base this on the presence/absence of a 
associated

drm bridge or panel.

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 66 +++
 .../gpu/drm/msm/disp/msm_disp_snapshot_util.c |  8 ++-
 drivers/gpu/drm/msm/dp/dp_display.c   | 44 -
 drivers/gpu/drm/msm/msm_drv.h |  4 +-
 5 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index b7f33da2799c..9cd9539a1504 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -2173,7 +2173,7 @@ int dpu_encoder_setup(struct drm_device *dev,
struct drm_encoder *enc,
dpu_encoder_vsync_event_handler,
0);
else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
-   dpu_enc->dp = priv->dp;
+   dpu_enc->dp = priv->dp[disp_info->h_tile_instance[0]];


At this point this is a nit but not sure if this is right to use the 
tile_instance as the index.
In the future if we chose to assign another index to the 
h_tile_instance, this would break.

But I cant think of the use-case for that yet, Hence
Reviewed-by: Abhinav Kumar 



INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index f655adbc2421..875b07e7183d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -188,6 +188,7 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
struct dentry *entry;
struct drm_device *dev;
struct msm_drm_private *priv;
+   int i;

if (!p)
return -EINVAL;
@@ -203,8 +204,10 @@ static int dpu_kms_debugfs_init(struct msm_kms
*kms, struct drm_minor *minor)
dpu_debugfs_vbif_init(dpu_kms, entry);
dpu_debugfs_core_irq_init(dpu_kms, entry);

-   if (priv->dp)
-   msm_dp_debugfs_init(priv->dp, minor);
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (priv->dp[i])
+   msm_dp_debugfs_init(priv->dp[i], minor);
+   }

return dpu_core_perf_debugfs_init(dpu_kms, entry);
 }
@@ -544,35 +547,42 @@ static int
_dpu_kms_initialize_displayport(struct drm_device *dev,
 {
struct drm_encoder *encoder = NULL;
struct msm_display_info info;
-   int rc = 0;
+   int rc;
+   int i;

-   if (!priv->dp)
-   return rc;
+   for (i = 0; i < ARRAY_SIZE(priv->dp); i++) {
+   if (!priv->dp[i])
+   continue;

-   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
-   if (IS_ERR(encoder)) {
-   DPU_ERROR("encoder init failed for dsi display\n");
-   return PTR_ERR(encoder);
-   }
+   encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_TMDS);
+   if (IS_ERR(encoder)) {
+   DPU_ERROR("encoder init failed for dsi display\n");
+   return PTR_ERR(encoder);
+   }

-   memset(, 0, sizeof(info));
-   rc = msm_dp_modeset_init(priv->dp, dev, encoder);
-   if (rc) {
-   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
-   drm_encoder_cleanup(encoder);
-   return rc;
-   }
+   memset(, 0, sizeof(info));
+   rc = msm_dp_modeset_init(priv->dp[i], dev, encoder);
+   if (rc) {
+   DPU_ERROR("modeset_init failed for DP, rc = %d\n", rc);
+   drm_encoder_cleanup(encoder);
+   

Re: [Freedreno] [PATCH v3 2/5] drm/msm/dp: Modify prototype of encoder based API

2021-10-05 Thread abhinavk

On 2021-10-01 11:00, Bjorn Andersson wrote:

Functions in the DisplayPort code that relates to individual instances
(encoders) are passed both the struct msm_dp and the struct 
drm_encoder. But

in a situation where multiple DP instances would exist this means that
the caller need to resolve which struct msm_dp relates to the struct
drm_encoder at hand.

Store a reference to the struct msm_dp associated with each
dpu_encoder_virt to allow the particular instance to be associate with
the encoder in the following patch.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- None

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 23 -
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0e9d3fa1544b..b7f33da2799c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -168,6 +168,7 @@ enum dpu_enc_rc_states {
  * @vsync_event_work:  worker to handle vsync event for autorefresh
  * @topology:   topology of the display
  * @idle_timeout:  idle timeout duration in milliseconds
+ * @dp:msm_dp pointer, for DP encoders
  */
 struct dpu_encoder_virt {
struct drm_encoder base;
@@ -206,6 +207,8 @@ struct dpu_encoder_virt {
struct msm_display_topology topology;

u32 idle_timeout;
+
+   struct msm_dp *dp;
 };

 #define to_dpu_encoder_virt(x) container_of(x, struct 
dpu_encoder_virt, base)

@@ -1000,8 +1003,8 @@ static void dpu_encoder_virt_mode_set(struct
drm_encoder *drm_enc,

trace_dpu_enc_mode_set(DRMID(drm_enc));

-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp)
-   msm_dp_display_mode_set(priv->dp, drm_enc, mode, adj_mode);
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS)
+   msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode);

list_for_each_entry(conn_iter, connector_list, head)
if (conn_iter->encoder == drm_enc)
@@ -1182,9 +1185,8 @@ static void dpu_encoder_virt_enable(struct
drm_encoder *drm_enc)

_dpu_encoder_virt_enable_helper(drm_enc);

-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   ret = msm_dp_display_enable(priv->dp,
-   drm_enc);
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   ret = msm_dp_display_enable(dpu_enc->dp, drm_enc);
if (ret) {
DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n",
ret);
@@ -1224,8 +1226,8 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)
/* wait for idle */
dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);

-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   if (msm_dp_display_pre_disable(priv->dp, drm_enc))
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc))
DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n");
}

@@ -1253,8 +1255,8 @@ static void dpu_encoder_virt_disable(struct
drm_encoder *drm_enc)

DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");

-   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS && priv->dp) {
-   if (msm_dp_display_disable(priv->dp, drm_enc))
+   if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) {
+   if (msm_dp_display_disable(dpu_enc->dp, drm_enc))
DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n");
}

@@ -2170,7 +2172,8 @@ int dpu_encoder_setup(struct drm_device *dev,
struct drm_encoder *enc,
timer_setup(_enc->vsync_event_timer,
dpu_encoder_vsync_event_handler,
0);
-
+   else if (disp_info->intf_type == DRM_MODE_ENCODER_TMDS)
+   dpu_enc->dp = priv->dp;

INIT_DELAYED_WORK(_enc->delayed_off_work,
dpu_encoder_off_work);


Re: [Freedreno] [PATCH v3 1/5] drm/msm/dp: Remove global g_dp_display variable

2021-10-05 Thread abhinavk

On 2021-10-01 11:00, Bjorn Andersson wrote:

As the Qualcomm DisplayPort driver only supports a single instance of
the driver the commonly used struct dp_display is kept in a global
variable. As we introduce additional instances this obviously doesn't
work.

Replace this with a combination of existing references to adjacent
objects and drvdata.

Reviewed-by: Stephen Boyd 
Signed-off-by: Bjorn Andersson 

Reviewed-by: Abhinav Kumar 

---

Changes since v2:
- None

 drivers/gpu/drm/msm/dp/dp_display.c | 80 -
 1 file changed, 21 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/msm/dp/dp_display.c
b/drivers/gpu/drm/msm/dp/dp_display.c
index fbe4c2cd52a3..5d3ee5ef07c2 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -27,7 +27,6 @@
 #include "dp_audio.h"
 #include "dp_debug.h"

-static struct msm_dp *g_dp_display;
 #define HPD_STRING_SIZE 30

 enum {
@@ -121,6 +120,13 @@ static const struct of_device_id dp_dt_match[] = {
{}
 };

+static struct dp_display_private *dev_get_dp_display_private(struct
device *dev)
+{
+   struct msm_dp *dp = dev_get_drvdata(dev);
+
+   return container_of(dp, struct dp_display_private, dp_display);
+}
+
 static int dp_add_event(struct dp_display_private *dp_priv, u32 event,
u32 data, u32 delay)
 {
@@ -197,15 +203,12 @@ static int dp_display_bind(struct device *dev,
struct device *master,
   void *data)
 {
int rc = 0;
-   struct dp_display_private *dp;
-   struct drm_device *drm;
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct msm_drm_private *priv;
+   struct drm_device *drm;

drm = dev_get_drvdata(master);

-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
-
dp->dp_display.drm_dev = drm;
priv = drm->dev_private;
priv->dp = &(dp->dp_display);
@@ -240,13 +243,10 @@ static int dp_display_bind(struct device *dev,
struct device *master,
 static void dp_display_unbind(struct device *dev, struct device 
*master,

  void *data)
 {
-   struct dp_display_private *dp;
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);
struct drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private;

-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
-
dp_power_client_deinit(dp->power);
dp_aux_unregister(dp->aux);
priv->dp = NULL;
@@ -379,38 +379,17 @@ static void dp_display_host_deinit(struct
dp_display_private *dp)

 static int dp_display_usbpd_configure_cb(struct device *dev)
 {
-   int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   rc = -EINVAL;
-   goto end;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);

dp_display_host_init(dp, false);

-   rc = dp_display_process_hpd_high(dp);
-end:
-   return rc;
+   return dp_display_process_hpd_high(dp);
 }

 static int dp_display_usbpd_disconnect_cb(struct device *dev)
 {
int rc = 0;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   rc = -EINVAL;
-   return rc;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);

dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);

@@ -472,15 +451,7 @@ static int dp_display_usbpd_attention_cb(struct
device *dev)
 {
int rc = 0;
u32 sink_request;
-   struct dp_display_private *dp;
-
-   if (!dev) {
-   DRM_ERROR("invalid dev\n");
-   return -EINVAL;
-   }
-
-   dp = container_of(g_dp_display,
-   struct dp_display_private, dp_display);
+   struct dp_display_private *dp = dev_get_dp_display_private(dev);

/* check for any test request issued by sink */
rc = dp_link_process_request(dp->link);
@@ -647,7 +618,7 @@ static int dp_hpd_unplug_handle(struct
dp_display_private *dp, u32 data)

DRM_DEBUG_DP("hpd_state=%d\n", state);
/* signal the disconnect event early to ensure proper teardown */
-   dp_display_handle_plugged_change(g_dp_display, false);
+   dp_display_handle_plugged_change(>dp_display, false);

/* enable HDP plug interrupt to prepare for next plugin */
 	dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, 
true);

@@ -842,9 +813,7 @@ static int dp_display_prepare(struct msm_dp *dp)
 static int 

Re: [Freedreno] [PATCH v3 03/14] drm/hdcp: Update property value on content type and user changes

2021-10-04 Thread abhinavk

On 2021-10-01 08:11, Sean Paul wrote:

From: Sean Paul 

This patch updates the connector's property value in 2 cases which were
previously missed:

1- Content type changes. The value should revert back to DESIRED from
   ENABLED in case the driver must re-authenticate the link due to the
   new content type.

2- Userspace sets value to DESIRED while ENABLED. In this case, the
   value should be reset immediately to ENABLED since the link is
   actively being encrypted.

To accommodate these changes, I've split up the conditionals to make
things a bit more clear (as much as one can with this mess of state).

Acked-by: Jani Nikula 
Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-4-s...@poorly.run
#v1
Link:
https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-4-s...@poorly.run
#v2

Changes in v2:
-None
Changes in v3:
-Fixed indentation issue identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 26 +-
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index dd8fa91c51d6..8c851d40cd45 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -487,21 +487,29 @@ bool drm_hdcp_atomic_check(struct drm_connector
*connector,
return true;

/*
-* Nothing to do if content type is unchanged and one of:
-*  - state didn't change
+* Content type changes require an HDCP disable/enable cycle.
+*/
+	if (new_conn_state->hdcp_content_type != 
old_conn_state->hdcp_content_type) {

+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_DESIRED;
+   return true;
+   }
+
+   /*
+* Ignore meaningless state changes:
 *  - HDCP was activated since the last commit
-*  - attempting to set to desired while already enabled
+*  - Attempting to set to desired while already enabled
 */
-   if (old_hdcp == new_hdcp ||
-   (old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
+   if ((old_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED) ||
(old_hdcp == DRM_MODE_CONTENT_PROTECTION_ENABLED &&
 new_hdcp == DRM_MODE_CONTENT_PROTECTION_DESIRED)) {
-   if (old_conn_state->hdcp_content_type ==
-   new_conn_state->hdcp_content_type)
-   return false;
+   new_conn_state->content_protection =
+   DRM_MODE_CONTENT_PROTECTION_ENABLED;
+   return false;
}

-   return true;
+   /* Finally, if state changes, we need action */
+   return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);


Re: [PATCH] drm/msm: potential error pointer dereference in init()

2021-10-04 Thread abhinavk

On 2021-10-04 03:38, Dan Carpenter wrote:

The msm_iommu_new() returns error pointers on failure so check for that
to avoid an Oops.

Fixes: ccac7ce373c1 ("drm/msm: Refactor address space initialization")
Signed-off-by: Dan Carpenter 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae48f41821cf..ad247c06e198 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -908,6 +908,10 @@ static int _dpu_kms_mmu_init(struct dpu_kms 
*dpu_kms)

return 0;

mmu = msm_iommu_new(dpu_kms->dev->dev, domain);
+   if (IS_ERR(mmu)) {
+   iommu_domain_free(domain);
+   return PTR_ERR(mmu);
+   }
aspace = msm_gem_address_space_create(mmu, "dpu1",
0x1000, 0x1 - 0x1000);


Re: [PATCH] drm/msm/disp: fix endian bug in debugfs code

2021-10-04 Thread abhinavk

On 2021-10-04 06:47, Dan Carpenter wrote:

The "vbif->features" is type unsigned long but the debugfs file
is treating it as a u32 type.  This will work in little endian
systems, but the correct thing is to change the debugfs to use
an unsigned long.

Fixes: 25fdd5933e4c ("drm/msm: Add SDM845 DPU support")
Signed-off-by: Dan Carpenter 

Reviewed-by: Abhinav Kumar 

---
You might wonder why this code has so many casts.  It's required 
because

this data is const.  Which is fine because the file is read only.

 drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
index 21d20373eb8b..e645a886e3c6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_vbif.c
@@ -305,8 +305,8 @@ void dpu_debugfs_vbif_init(struct dpu_kms
*dpu_kms, struct dentry *debugfs_root)

debugfs_vbif = debugfs_create_dir(vbif_name, entry);

-   debugfs_create_u32("features", 0600, debugfs_vbif,
-   (u32 *)>features);
+   debugfs_create_ulong("features", 0600, debugfs_vbif,
+(unsigned long *)>features);

debugfs_create_u32("xin_halt_timeout", 0400, debugfs_vbif,
(u32 *)>xin_halt_timeout);


Re: [Freedreno] [PATCH v3] drm/msm/dsi: do not enable irq handler before powering up the host

2021-10-01 Thread abhinavk

On 2021-10-01 18:08, Dmitry Baryshkov wrote:

The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.

Move the request_irq into msm_dsi_host_init and pass IRQF_NO_AUTOEN to
it. Call enable/disable_irq after msm_dsi_host_power_on/_off()
functions, so that we can be sure that the interrupt is delivered when
the host is in the known state.

It is not possible to defer the interrupt enablement to a later point,
because drm_panel_prepare might need to communicate with the panel over
the DSI link and that requires working interrupt.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/dsi/dsi.h |  2 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c| 48 +--
 drivers/gpu/drm/msm/dsi/dsi_manager.c | 16 +
 3 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
b/drivers/gpu/drm/msm/dsi/dsi.h

index b50db91cb8a7..569c8ff062ba 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -107,6 +107,8 @@ void msm_dsi_host_cmd_xfer_commit(struct
mipi_dsi_host *host,
u32 dma_base, u32 len);
 int msm_dsi_host_enable(struct mipi_dsi_host *host);
 int msm_dsi_host_disable(struct mipi_dsi_host *host);
+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host);
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host);
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
struct msm_dsi_phy_shared_timings *phy_shared_timings,
bool is_bonded_dsi, struct msm_dsi_phy *phy);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..ce26eb78cb6c 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1898,6 +1898,23 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi)
return ret;
}

+   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+   if (msm_host->irq < 0) {
+   ret = msm_host->irq;
+   dev_err(>dev, "failed to get irq: %d\n", ret);
+   return ret;
+   }
+
+   /* do not autoenable, will be enabled later */
+   ret = devm_request_irq(>dev, msm_host->irq, dsi_host_irq,
+   IRQF_TRIGGER_HIGH | IRQF_ONESHOT | IRQF_NO_AUTOEN,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   dev_err(>dev, "failed to request IRQ%u: %d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
init_completion(_host->dma_comp);
init_completion(_host->video_comp);
mutex_init(_host->dev_mutex);
@@ -1941,25 +1958,8 @@ int msm_dsi_host_modeset_init(struct 
mipi_dsi_host *host,

 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
-   struct platform_device *pdev = msm_host->pdev;
int ret;

-   msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
-   if (msm_host->irq < 0) {
-   ret = msm_host->irq;
-   DRM_DEV_ERROR(dev->dev, "failed to get irq: %d\n", ret);
-   return ret;
-   }
-
-   ret = devm_request_irq(>dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
-   msm_host->irq, ret);
-   return ret;
-   }
-
msm_host->dev = dev;
ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
@@ -2315,6 +2315,20 @@ void msm_dsi_host_get_phy_clk_req(struct
mipi_dsi_host *host,
clk_req->escclk_rate = msm_host->esc_clk_rate;
 }

+void msm_dsi_host_enable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   enable_irq(msm_host->irq);
+}
+
+void msm_dsi_host_disable_irq(struct mipi_dsi_host *host)
+{
+   struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
+
+   disable_irq(msm_host->irq);
+}
+
 int msm_dsi_host_enable(struct mipi_dsi_host *host)
 {
struct msm_dsi_host *msm_host = to_msm_dsi_host(host);
diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c
b/drivers/gpu/drm/msm/dsi/dsi_manager.c
index c41d39f5b7cf..fb4ccffdcfe1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c
@@ -377,6 +377,14 @@ static void dsi_mgr_bridge_pre_enable(struct
drm_bridge *bridge)
}
}

+   /*
+* Enable before preparing the panel, disable after unpreparing, so
+* that the panel can communicate over the DSI 

Re: [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual

2021-09-29 Thread abhinavk

Hi Dmitry

On 2021-07-04 18:20, Dmitry Baryshkov wrote:

As discussed on IRC, change dpu_plane implementation to be virtual:
register unified planes and select backing SSPP block at runtime.

Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
rather than statically allocated SSPPs at the plane registration.

Patches 1-9 move state variables from struct dpu_plane onto the stack
allocation. State should not be a part of struct dpu_plane anyway.

Patches 10-18 make additional changes to plane code, reworking check,
debugfs, dropping old multirec support, which results in patch 19 
adding

support for virtual planes per se.

Patches 20-22 demonstrate my main goal behind reworking dpu_plane
support. They change dpu_plane to automatically use one of SSPP block
features - multirec, an ability to display two unscaled RGB rectangles
using single SSPP block. This allows us to double the amount of created
planes. If the user tries to enable more planes than actually supported
by the underlying SSPP blocks, atomic_check code would return an error.

As you can see, this patchset is not atomic, so different patches can 
go

separately.


I am half way through this series and have finished checking patches 
1-12
I am okay with patches 1-4, 6-12. Its a reasonable cleanup to make the 
dpu_plane struct lighter.
I need a little more time with the rest as I am comparing the downstream 
solution against yours.


As you mentioned, this patchset is not atomic, hence can you break it up 
like

-> cleanup of dpu_plane struct in one series
-> removal of current multirect and current src split which will include 
patch 5 as well


So that the first series can go through and it gives us a little more 
time to check the second

series.

Thanks

Abhinav



Changes since v1:
 - Add multirec implementation
 - Added msm.dpu_use_virtual_planes kernel parameter instead of using
   compile time switch
 - Changed code to always reallocate SSPPs in the CRTC atomic check to
   let the kernel pick up the best multirec config. This can be
   optimized later.
 - Rework RM SSPP API to always receive plane id
 - Removed scaler_cfg, pixel_ext and cdp_cfg from struct 
dpu_plane_state

 - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
 - Removed dpu_csc_cfg from dpu_plane

The following changes since commit 
e88bbc91849b2bf57683119c339e52916d34433f:


  Revert "drm/msm/mdp5: provide dynamic bandwidth management"
(2021-06-23 14:06:20 -0700)

are available in the Git repository at:

  https://git.linaro.org/people/dmitry.baryshkov/kernel.git 
dpu-multirec-2


for you to fetch changes up to 
19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:


  drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)


Dmitry Baryshkov (22):
  drm/msm/dpu: move LUT levels out of QOS config
  drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
  drm/msm/dpu: drop pipe_name from struct dpu_plane
  drm/msm/dpu: remove stage_cfg from struct dpu_crtc
  drm/msm/dpu: rip out master planes support
  drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
  drm/msm/dpu: drop scaler config from plane state
  drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
  drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
  drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
  drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
  drm/msm/dpu: rip out debugfs support from dpu_plane
  drm/msm/dpu: drop src_split and multirect check from 
dpu_crtc_atomic_check

  drm/msm/dpu: add list of supported formats to the DPU caps
  drm/msm/dpu: simplify DPU_SSPP features checks
  drm/msm/dpu: do not limit the zpos property
  drm/msm/dpu: add support for SSPP allocation to RM
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: add support for virtualized planes
  drm/msm/dpu: fix smart dma support
  drm/msm/dpu: fix CDP setup to account for multirect index
  drm/msm/dpu: add multirect support

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 261 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h   |   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c|  41 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h|  52 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c|   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h|   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 234 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h|  70 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c  | 851 
+++--

 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h  |  75 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c |  81 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h |   6 +
 14 files changed, 793 insertions(+), 924 deletions(-)


Re: [Freedreno] [PATCH v2 13/13] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2021-09-28 Thread abhinavk

On 2021-09-28 11:02, Sean Paul wrote:
On Tue, Sep 21, 2021 at 07:25:41PM -0700, abhin...@codeaurora.org 
wrote:

On 2021-09-15 13:38, Sean Paul wrote:
> From: Sean Paul 
>
> This patch adds HDCP 1.x support to msm DP connectors using the new HDCP
> helpers.
>
> Cc: Stephen Boyd 
> Signed-off-by: Sean Paul 
> Link:
> 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
> #v1
>
> Changes in v2:
> -Squash [1] into this patch with the following changes (Stephen)
>   -Update the sc7180 dtsi file
>   -Remove resource names and just use index (Stephen)
>


> [1]
> 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run
> ---


/snip


> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index 904535eda0c4..98731fd262d6 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -109,6 +109,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
>dp/dp_ctrl.o \
>dp/dp_display.o \
>dp/dp_drm.o \
> +  dp/dp_hdcp.o \
>dp/dp_hpd.o \
>dp/dp_link.o \
>dp/dp_panel.o \
> diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
> b/drivers/gpu/drm/msm/dp/dp_debug.c
> index 2f6247e80e9d..de16fca8782a 100644
> --- a/drivers/gpu/drm/msm/dp/dp_debug.c
> +++ b/drivers/gpu/drm/msm/dp/dp_debug.c


/snip


> +static ssize_t dp_hdcp_key_write(struct file *file, const char __user
> *ubuf,
> +   size_t len, loff_t *offp)
> +{
> +  char *input_buffer;
> +  int ret = 0;
> +  struct dp_debug_private *debug = file->private_data;
> +  struct drm_device *dev;
> +
> +  dev = debug->drm_dev;
> +
> +  if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
> +  return -EINVAL;
> +
> +  if (!debug->hdcp)
> +  return -ENOENT;
> +
> +  input_buffer = memdup_user_nul(ubuf, len);
> +  if (IS_ERR(input_buffer))
> +  return PTR_ERR(input_buffer);
> +
> +  ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
> +
> +  kfree(input_buffer);
> +  if (ret < 0) {
> +  DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
> +  return ret;
> +  }
> +
> +  *offp += len;
> +  return len;
> +}

It seems like the HDCP keys written using debugfs, just for my
understanding,
are you storing this in some secure partition and the usermode reads 
from it

and writes them here?



We have not sorted out the userspace side of HDCP enablement yet, so it 
remains
to be seen whether the keys will be injected via debugfs/firmware 
file/property.


/snip


> +static int dp_connector_atomic_check(struct drm_connector *connector,
> +   struct drm_atomic_state *state)
> +{
> +  struct drm_connector_state *conn_state;
> +  struct dp_connector_state *dp_state;
> +
> +  conn_state = drm_atomic_get_new_connector_state(state, connector);
> +  dp_state = to_dp_connector_state(conn_state);
> +
> +  dp_state->hdcp_transition = drm_hdcp_atomic_check(connector, state);

I have a general question related to the transition flag and overall 
tying

the HDCP
enable and authentication to the commit.
So lets say there is a case where the driver needs to disable HDCP. It 
could

be due
to link integrity failure OR some other error condition which usermode 
is

not aware of.
In that case, we will set this hdcp_transition to true but in the next
commit we will
actually do the authentication. What if usermode doesnt issue a new 
frame?
This question arises because currently the link intergrity check is 
done

using SW polling
in the previous patchset. But as I had commented there, this occurs in 
HW

for us.
I dont see that isr itself in this patchset. So wanted to understand 
if

thats part of this
approach to still tie it with commit.

So if we go with the HW polling based approach which is the preferred
method, we need to
untie this from the commit.



In the case of error, the worker will detect it and try to 
re-authenticate. If
the re-authentication is successful, userspace will continue to be 
unaware and
everything will keep working. If re-authentication is unsuccessful, the 
worker

will update the property value and issue a uevent to userspace. So HDCP
enablement is only tied to commits when the property value is changing 
as a

result of userspace.

Regarding SW vs HW link checks, I don't think there's any difference in 
efficacy
between them. If HW can be relied on to issue an interrupt in failure 
cases, a

follow-up set allowing for this seems like a great idea.



Thanks for the explanation. Yes, from our experience it has been pretty 
reliable to
issue signal integrity failures. We already had the isr based approach 
downstream
and would prefer to keep it that way based on our experience of it 
firing reliably.
We can still keep the SW polling code but it should come into effect 
only if HW polling

is not supported / preferred.


> +
> +  return 0;
> +}


/snip


> +static int dp_hdcp_load_keys(struct drm_connector *connector)
> +{
> +  struct dp_hdcp 

Re: [Freedreno] [PATCH v2 04/13] drm/hdcp: Expand HDCP helper library for enable/disable/check

2021-09-28 Thread abhinavk

Hi Sean

On 2021-09-28 10:33, Sean Paul wrote:
On Tue, Sep 21, 2021 at 04:34:59PM -0700, abhin...@codeaurora.org 
wrote:

On 2021-09-15 13:38, Sean Paul wrote:
> From: Sean Paul 
>
> This patch expands upon the HDCP helper library to manage HDCP
> enable, disable, and check.
>
> Previous to this patch, the majority of the state management and sink
> interaction is tucked inside the Intel driver with the understanding
> that once a new platform supported HDCP we could make good decisions
> about what should be centralized. With the addition of HDCP support
> for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
> authentication, key exchange, and link checks to the HDCP helper.
>
> In terms of functionality, this migration is 1:1 with the Intel driver,
> however things are laid out a bit differently than with intel_hdcp.c,
> which is why this is a separate patch from the i915 transition to the
> helper. On i915, the "shim" vtable is used to account for HDMI vs. DP
> vs. DP-MST differences whereas the helper library uses a LUT to
> account for the register offsets and a remote read function to route
> the messages. On i915, storing the sink information in the source is
> done inline whereas now we use the new drm_hdcp_helper_funcs vtable
> to store and fetch information to/from source hw. Finally, instead of
> calling enable/disable directly from the driver, we'll leave that
> decision to the helper and by calling drm_hdcp_helper_atomic_commit()
> from the driver. All told, this will centralize the protocol and state
> handling in the helper, ensuring we collect all of our bugs^Wlogic
> in one place.
>
> Signed-off-by: Sean Paul 
> Link:
> 
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
> #v1
>
> Changes in v2:
> -Fixed set-but-unused variable identified by 0-day
> ---
>  drivers/gpu/drm/drm_hdcp.c | 1103 
>  include/drm/drm_hdcp.h |  191 +++
>  2 files changed, 1294 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index 742313ce8f6f..47c6e6923a76 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c


/snip


> +static void drm_hdcp_helper_check_work(struct work_struct *work)
> +{
> +  struct drm_hdcp_helper_data *data =
> container_of(to_delayed_work(work),
> +   struct 
drm_hdcp_helper_data,
> +   check_work);
> +  unsigned long check_link_interval;
> +

Does this SW polling for Ri' mismatch need to be done even if the HW 
is

capable of doing it
on its own?
MSM HDCP 1x HW can periodically check Ri' mismatches and issue an 
interrupt

if there is a mismatch.
In that case this SW polling is not needed. So maybe check if the HW
supports polling and if so
skip this SW polling?



One could certainly change this to be HW driven. There is also an 
interrupt on
Intel for DP links which [re]schedules link check in the interrupt 
handler,
something similar could be done for msm. Note that even on these Intel 
links
which support the CP interrupt, the worker still runs on the normal 
cadence. I
haven't considered relying solely on the interrupt since I want to be 
sure we

didn't miss anything.

Sean


I think we should have the support for HW polling added. From our 
experience,
it has been pretty reliable for us and has a pretty consistent cadence 
in alignment
with the spec. I dont quite understand why we should have both in 
chipsets capable
of HW polling and am bit surprised if SW polling will catch something 
which HW

polling and the subsequent interrupt has missed.




> +  mutex_lock(>mutex);
> +  if (data->value != DRM_MODE_CONTENT_PROTECTION_ENABLED)
> +  goto out_data_mutex;
> +
> +  drm_hdcp_helper_driver_lock(data);
> +
> +  if (data->enabled_type == DRM_MODE_HDCP_CONTENT_TYPE1) {
> +  if (drm_hdcp_hdcp2_check_link(data))
> +  goto out;
> +  check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS;
> +  } else {
> +  if (drm_hdcp_hdcp1_check_link(data))
> +  goto out;
> +  check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
> +  }
> +  schedule_delayed_work(>check_work, check_link_interval);
> +
> +out:
> +  drm_hdcp_helper_driver_unlock(data);
> +out_data_mutex:
> +  mutex_unlock(>mutex);
> +}


/snip


Re: [Freedreno] [PATCH v2 00/13] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2021-09-28 Thread abhinavk

On 2021-09-28 11:06, Sean Paul wrote:
On Tue, Sep 21, 2021 at 07:30:29PM -0700, abhin...@codeaurora.org 
wrote:

Hi Sean

On 2021-09-15 13:38, Sean Paul wrote:
> From: Sean Paul 
>
> Hello again,
> This is the second version of the HDCP helper patchset. See version 1
> here: https://patchwork.freedesktop.org/series/94623/
>
> In this second version, I've fixed up the oopsies exposed by 0-day and
> yamllint and incorporated early review feedback from the dt/dts reviews.
>
> Please take a look,
>
> Sean

One question overall on the series:

1) Regarding validation, did you run any secure video to check the
transitions?


Yep, the transitions look good, no visual artifacts.
Unplug/replug/suspend/resume all seem to be behaving as expected.


2) Is running HDCP 1x compliance also part of the validation efforts?


If Qualcomm has the ability to run validation, I'd be very keen to get 
some

help in that regard.


Thanks for letting us know. To assist with (2) we will have to work with 
you on some logistics.

Will sync up on IRC further on how to go about this.



Sean



Thanks

Abhinav

>
> Sean Paul (13):
>   drm/hdcp: Add drm_hdcp_atomic_check()
>   drm/hdcp: Avoid changing crtc state in hdcp atomic check
>   drm/hdcp: Update property value on content type and user changes
>   drm/hdcp: Expand HDCP helper library for enable/disable/check
>   drm/i915/hdcp: Consolidate HDCP setup/state cache
>   drm/i915/hdcp: Retain hdcp_capable return codes
>   drm/i915/hdcp: Use HDCP helpers for i915
>   drm/msm/dpu_kms: Re-order dpu includes
>   drm/msm/dpu: Remove useless checks in dpu_encoder
>   drm/msm/dpu: Remove encoder->enable() hack
>   drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
>   dt-bindings: msm/dp: Add bindings for HDCP registers
>   drm/msm: Implement HDCP 1.x using the new drm HDCP helpers
>
>  .../bindings/display/msm/dp-controller.yaml   |7 +-
>  arch/arm64/boot/dts/qcom/sc7180.dtsi  |4 +-
>  drivers/gpu/drm/drm_hdcp.c| 1197 -
>  drivers/gpu/drm/i915/display/intel_atomic.c   |7 +-
>  drivers/gpu/drm/i915/display/intel_ddi.c  |   29 +-
>  .../drm/i915/display/intel_display_debugfs.c  |   11 +-
>  .../drm/i915/display/intel_display_types.h|   58 +-
>  drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  345 ++---
>  drivers/gpu/drm/i915/display/intel_dp_mst.c   |   17 +-
>  drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++---
>  drivers/gpu/drm/i915/display/intel_hdcp.h |   35 +-
>  drivers/gpu/drm/i915/display/intel_hdmi.c |  256 ++--
>  drivers/gpu/drm/msm/Makefile  |1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   17 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   30 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |2 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |4 -
>  drivers/gpu/drm/msm/dp/dp_debug.c |   49 +-
>  drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
>  drivers/gpu/drm/msm/dp/dp_display.c   |   47 +-
>  drivers/gpu/drm/msm/dp/dp_display.h   |5 +
>  drivers/gpu/drm/msm/dp/dp_drm.c   |   68 +-
>  drivers/gpu/drm/msm/dp/dp_drm.h   |5 +
>  drivers/gpu/drm/msm/dp/dp_hdcp.c  |  433 ++
>  drivers/gpu/drm/msm/dp/dp_hdcp.h  |   27 +
>  drivers/gpu/drm/msm/dp/dp_parser.c|   22 +-
>  drivers/gpu/drm/msm/dp/dp_parser.h|4 +
>  drivers/gpu/drm/msm/dp/dp_reg.h   |   44 +-
>  drivers/gpu/drm/msm/msm_atomic.c  |   15 +
>  include/drm/drm_hdcp.h|  194 +++
>  30 files changed, 2561 insertions(+), 1389 deletions(-)
>  create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
>  create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h


Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-27 Thread abhinavk

On 2021-09-27 18:29, Dmitry Baryshkov wrote:

On 28/09/2021 04:19, abhin...@codeaurora.org wrote:

On 2021-09-27 18:06, Dmitry Baryshkov wrote:

On Tue, 28 Sept 2021 at 03:22,  wrote:


On 2021-09-25 12:43, Dmitry Baryshkov wrote:
> On 21/09/2021 23:52, abhin...@codeaurora.org wrote:
>> On 2021-09-21 10:47, Dmitry Baryshkov wrote:
>>> Hi,
>>>
>>> On Tue, 21 Sept 2021 at 20:01,  wrote:

 On 2021-09-21 09:22, Dmitry Baryshkov wrote:
 > The DSI host might be left in some state by the bootloader. If this
 > state generates an IRQ, it might hang the system by holding the
 > interrupt line before the driver sets up the DSI host to the known
 > state.
 >
 > Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
 > so that we can be sure that the interrupt is delivered when the host is
 > in the known state.
 >
 > Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
 > Signed-off-by: Dmitry Baryshkov 

 This is a valid change and we have seen interrupt storms in
 downstream
 happening
 when like you said the bootloader leaves the DSI host in unknown
 state.
 Just one question below.

 > ---
 >  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
 >  1 file changed, 12 insertions(+), 9 deletions(-)
 >
 > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > index e269df285136..cd842347a6b1 100644
 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
 > mipi_dsi_host *host,
 >   return ret;
 >   }
 >
 > - ret = devm_request_irq(>dev, msm_host->irq,
 > - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 > - "dsi_isr", msm_host);
 > - if (ret < 0) {
 > - DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
 > - msm_host->irq, ret);
 > - return ret;
 > - }
 > -
 >   msm_host->dev = dev;
 >   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
 >   if (ret) {
 > @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
 > *host,
 >   if (msm_host->disp_en_gpio)
 >   gpiod_set_value(msm_host->disp_en_gpio, 1);
 >
 > + ret = devm_request_irq(_host->pdev->dev, msm_host->irq,
 > + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 > + "dsi_isr", msm_host);
 > + if (ret < 0) {
 > + DRM_DEV_ERROR(_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
 > + msm_host->irq, ret);
 > + return ret;
 > + }
 > +
 > +

 Do you want to move this to msm_dsi_host_enable()?
 So without the controller being enabled it is still in unknown
 state?
>>>
>>> msm_dsi_host_power_on() reconfigures the host registers, so the state
>>> is known at the end of the power_on().
>>>
 Also do you want to do this after dsi0 and dsi1 are initialized to
 account for
 dual dsi cases?
>>>
>>> I don't think this should matter. The host won't generate 'extra'
>>> interrupts in such case, will it?
>>>
>> We have seen cases where misconfiguration has caused interrupts to
>> storm only
>> on one DSI in some cases. So yes, I would prefer this is done after
>> both are
>> configured.
>
> I've checked. The power_on is called from dsi_mgr_bridge_pre_enable()
> when both DSI hosts should be bound.

DSI being bound is enough? I thought the issue we are trying to 
address

is that
we need to have called msm_dsi_host_power_on() for both the hosts so
that both are
put in the known state before requesting the irq.

OR in other words move the irq_enable() to below location.

341 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
342 {

364 ret = msm_dsi_host_power_on(host, _shared_timings[id],
is_bonded_dsi, msm_dsi->phy);
365 if (ret) {
366 pr_err("%s: power on host %d failed, %d\n", 
__func__, id, ret);

367 goto host_on_fail;
368 }
369
370 if (is_bonded_dsi && msm_dsi1) {
371 ret = msm_dsi_host_power_on(msm_dsi1->host,
372 _shared_timings[DSI_1], 
is_bonded_dsi, msm_dsi1->phy);

373 if (ret) {
374 pr_err("%s: power on host1 failed, %d\n",
375 __func__, 
ret);

376 goto host1_on_fail;
377 }
378 }

< move the irq enable here >
**


Ah, I see your point. What about moving to msm_dsi_host_enable() 
then?


Yes, I had suggested this a few replies ago. But only at the dsi_msgr 
we know if DSI1 is also done.

So 

Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-27 Thread abhinavk

On 2021-09-27 18:06, Dmitry Baryshkov wrote:

On Tue, 28 Sept 2021 at 03:22,  wrote:


On 2021-09-25 12:43, Dmitry Baryshkov wrote:
> On 21/09/2021 23:52, abhin...@codeaurora.org wrote:
>> On 2021-09-21 10:47, Dmitry Baryshkov wrote:
>>> Hi,
>>>
>>> On Tue, 21 Sept 2021 at 20:01,  wrote:

 On 2021-09-21 09:22, Dmitry Baryshkov wrote:
 > The DSI host might be left in some state by the bootloader. If this
 > state generates an IRQ, it might hang the system by holding the
 > interrupt line before the driver sets up the DSI host to the known
 > state.
 >
 > Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
 > so that we can be sure that the interrupt is delivered when the host is
 > in the known state.
 >
 > Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
 > Signed-off-by: Dmitry Baryshkov 

 This is a valid change and we have seen interrupt storms in
 downstream
 happening
 when like you said the bootloader leaves the DSI host in unknown
 state.
 Just one question below.

 > ---
 >  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
 >  1 file changed, 12 insertions(+), 9 deletions(-)
 >
 > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > index e269df285136..cd842347a6b1 100644
 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
 > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
 > @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
 > mipi_dsi_host *host,
 >   return ret;
 >   }
 >
 > - ret = devm_request_irq(>dev, msm_host->irq,
 > - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 > - "dsi_isr", msm_host);
 > - if (ret < 0) {
 > - DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
 > - msm_host->irq, ret);
 > - return ret;
 > - }
 > -
 >   msm_host->dev = dev;
 >   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
 >   if (ret) {
 > @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
 > *host,
 >   if (msm_host->disp_en_gpio)
 >   gpiod_set_value(msm_host->disp_en_gpio, 1);
 >
 > + ret = devm_request_irq(_host->pdev->dev, msm_host->irq,
 > + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
 > + "dsi_isr", msm_host);
 > + if (ret < 0) {
 > + DRM_DEV_ERROR(_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
 > + msm_host->irq, ret);
 > + return ret;
 > + }
 > +
 > +

 Do you want to move this to msm_dsi_host_enable()?
 So without the controller being enabled it is still in unknown
 state?
>>>
>>> msm_dsi_host_power_on() reconfigures the host registers, so the state
>>> is known at the end of the power_on().
>>>
 Also do you want to do this after dsi0 and dsi1 are initialized to
 account for
 dual dsi cases?
>>>
>>> I don't think this should matter. The host won't generate 'extra'
>>> interrupts in such case, will it?
>>>
>> We have seen cases where misconfiguration has caused interrupts to
>> storm only
>> on one DSI in some cases. So yes, I would prefer this is done after
>> both are
>> configured.
>
> I've checked. The power_on is called from dsi_mgr_bridge_pre_enable()
> when both DSI hosts should be bound.

DSI being bound is enough? I thought the issue we are trying to 
address

is that
we need to have called msm_dsi_host_power_on() for both the hosts so
that both are
put in the known state before requesting the irq.

OR in other words move the irq_enable() to below location.

341 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
342 {

364 ret = msm_dsi_host_power_on(host, _shared_timings[id],
is_bonded_dsi, msm_dsi->phy);
365 if (ret) {
366 pr_err("%s: power on host %d failed, %d\n", __func__, 
id, ret);

367 goto host_on_fail;
368 }
369
370 if (is_bonded_dsi && msm_dsi1) {
371 ret = msm_dsi_host_power_on(msm_dsi1->host,
372 _shared_timings[DSI_1], 
is_bonded_dsi, msm_dsi1->phy);

373 if (ret) {
374 pr_err("%s: power on host1 failed, %d\n",
375 __func__, 
ret);

376 goto host1_on_fail;
377 }
378 }

< move the irq enable here >
**


Ah, I see your point. What about moving to msm_dsi_host_enable() then?


Yes, I had suggested this a few replies ago. But only at the dsi_msgr we 
know if DSI1 is also done.

So you can do it right after it in below location?

427 if (is_dual_dsi && msm_dsi1) {
428 

Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-27 Thread abhinavk

On 2021-09-25 12:43, Dmitry Baryshkov wrote:

On 21/09/2021 23:52, abhin...@codeaurora.org wrote:

On 2021-09-21 10:47, Dmitry Baryshkov wrote:

Hi,

On Tue, 21 Sept 2021 at 20:01,  wrote:


On 2021-09-21 09:22, Dmitry Baryshkov wrote:
> The DSI host might be left in some state by the bootloader. If this
> state generates an IRQ, it might hang the system by holding the
> interrupt line before the driver sets up the DSI host to the known
> state.
>
> Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
> so that we can be sure that the interrupt is delivered when the host is
> in the known state.
>
> Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
> Signed-off-by: Dmitry Baryshkov 

This is a valid change and we have seen interrupt storms in 
downstream

happening
when like you said the bootloader leaves the DSI host in unknown 
state.

Just one question below.

> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
>  1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index e269df285136..cd842347a6b1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
> mipi_dsi_host *host,
>   return ret;
>   }
>
> - ret = devm_request_irq(>dev, msm_host->irq,
> - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> - "dsi_isr", msm_host);
> - if (ret < 0) {
> - DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
> - msm_host->irq, ret);
> - return ret;
> - }
> -
>   msm_host->dev = dev;
>   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
>   if (ret) {
> @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
> *host,
>   if (msm_host->disp_en_gpio)
>   gpiod_set_value(msm_host->disp_en_gpio, 1);
>
> + ret = devm_request_irq(_host->pdev->dev, msm_host->irq,
> + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> + "dsi_isr", msm_host);
> + if (ret < 0) {
> + DRM_DEV_ERROR(_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
> + msm_host->irq, ret);
> + return ret;
> + }
> +
> +

Do you want to move this to msm_dsi_host_enable()?
So without the controller being enabled it is still in unknown 
state?


msm_dsi_host_power_on() reconfigures the host registers, so the state
is known at the end of the power_on().


Also do you want to do this after dsi0 and dsi1 are initialized to
account for
dual dsi cases?


I don't think this should matter. The host won't generate 'extra'
interrupts in such case, will it?

We have seen cases where misconfiguration has caused interrupts to 
storm only
on one DSI in some cases. So yes, I would prefer this is done after 
both are

configured.


I've checked. The power_on is called from dsi_mgr_bridge_pre_enable()
when both DSI hosts should be bound.


DSI being bound is enough? I thought the issue we are trying to address 
is that
we need to have called msm_dsi_host_power_on() for both the hosts so 
that both are

put in the known state before requesting the irq.

OR in other words move the irq_enable() to below location.

341 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
342 {

364 	ret = msm_dsi_host_power_on(host, _shared_timings[id], 
is_bonded_dsi, msm_dsi->phy);

365 if (ret) {
366 pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
367 goto host_on_fail;
368 }
369
370 if (is_bonded_dsi && msm_dsi1) {
371 ret = msm_dsi_host_power_on(msm_dsi1->host,
372 _shared_timings[DSI_1], is_bonded_dsi, 
msm_dsi1->phy);
373 if (ret) {
374 pr_err("%s: power on host1 failed, %d\n",
375 __func__, ret);
376 goto host1_on_fail;
377 }
378 }

< move the irq enable here >
**







>   msm_host->power_on = true;
>   mutex_unlock(_host->dev_mutex);
>
> @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host
> *host)
>   goto unlock_ret;
>   }
>
> + devm_free_irq(_host->pdev->dev, msm_host->irq, msm_host);
> +
>   dsi_ctrl_config(msm_host, false, NULL, NULL);
>
>   if (msm_host->disp_en_gpio)


Re: [Freedreno] [PATCH v2 00/13] drm/hdcp: Pull HDCP auth/exchange/check into helpers

2021-09-21 Thread abhinavk

Hi Sean

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

Hello again,
This is the second version of the HDCP helper patchset. See version 1
here: https://patchwork.freedesktop.org/series/94623/

In this second version, I've fixed up the oopsies exposed by 0-day and
yamllint and incorporated early review feedback from the dt/dts 
reviews.


Please take a look,

Sean


One question overall on the series:

1) Regarding validation, did you run any secure video to check the 
transitions?

2) Is running HDCP 1x compliance also part of the validation efforts?

Thanks

Abhinav



Sean Paul (13):
  drm/hdcp: Add drm_hdcp_atomic_check()
  drm/hdcp: Avoid changing crtc state in hdcp atomic check
  drm/hdcp: Update property value on content type and user changes
  drm/hdcp: Expand HDCP helper library for enable/disable/check
  drm/i915/hdcp: Consolidate HDCP setup/state cache
  drm/i915/hdcp: Retain hdcp_capable return codes
  drm/i915/hdcp: Use HDCP helpers for i915
  drm/msm/dpu_kms: Re-order dpu includes
  drm/msm/dpu: Remove useless checks in dpu_encoder
  drm/msm/dpu: Remove encoder->enable() hack
  drm/msm/dp: Re-order dp_audio_put in deinit_sub_modules
  dt-bindings: msm/dp: Add bindings for HDCP registers
  drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

 .../bindings/display/msm/dp-controller.yaml   |7 +-
 arch/arm64/boot/dts/qcom/sc7180.dtsi  |4 +-
 drivers/gpu/drm/drm_hdcp.c| 1197 -
 drivers/gpu/drm/i915/display/intel_atomic.c   |7 +-
 drivers/gpu/drm/i915/display/intel_ddi.c  |   29 +-
 .../drm/i915/display/intel_display_debugfs.c  |   11 +-
 .../drm/i915/display/intel_display_types.h|   58 +-
 drivers/gpu/drm/i915/display/intel_dp_hdcp.c  |  345 ++---
 drivers/gpu/drm/i915/display/intel_dp_mst.c   |   17 +-
 drivers/gpu/drm/i915/display/intel_hdcp.c | 1011 +++---
 drivers/gpu/drm/i915/display/intel_hdcp.h |   35 +-
 drivers/gpu/drm/i915/display/intel_hdmi.c |  256 ++--
 drivers/gpu/drm/msm/Makefile  |1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   17 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   |   30 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |4 -
 drivers/gpu/drm/msm/dp/dp_debug.c |   49 +-
 drivers/gpu/drm/msm/dp/dp_debug.h |6 +-
 drivers/gpu/drm/msm/dp/dp_display.c   |   47 +-
 drivers/gpu/drm/msm/dp/dp_display.h   |5 +
 drivers/gpu/drm/msm/dp/dp_drm.c   |   68 +-
 drivers/gpu/drm/msm/dp/dp_drm.h   |5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c  |  433 ++
 drivers/gpu/drm/msm/dp/dp_hdcp.h  |   27 +
 drivers/gpu/drm/msm/dp/dp_parser.c|   22 +-
 drivers/gpu/drm/msm/dp/dp_parser.h|4 +
 drivers/gpu/drm/msm/dp/dp_reg.h   |   44 +-
 drivers/gpu/drm/msm/msm_atomic.c  |   15 +
 include/drm/drm_hdcp.h|  194 +++
 30 files changed, 2561 insertions(+), 1389 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h


Re: [Freedreno] [PATCH v2 08/13] drm/msm/dpu_kms: Re-order dpu includes

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

Make includes alphabetical in dpu_kms.c

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-9-s...@poorly.run
#v1

Changes in v2:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index ae48f41821cf..fb0d9f781c66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -21,14 +21,14 @@
 #include "msm_gem.h"
 #include "disp/msm_disp_snapshot.h"

-#include "dpu_kms.h"
 #include "dpu_core_irq.h"
+#include "dpu_crtc.h"
+#include "dpu_encoder.h"
 #include "dpu_formats.h"
 #include "dpu_hw_vbif.h"
-#include "dpu_vbif.h"
-#include "dpu_encoder.h"
+#include "dpu_kms.h"
 #include "dpu_plane.h"
-#include "dpu_crtc.h"
+#include "dpu_vbif.h"

 #define CREATE_TRACE_POINTS
 #include "dpu_trace.h"


Re: [Freedreno] [PATCH v2 13/13] drm/msm: Implement HDCP 1.x using the new drm HDCP helpers

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

This patch adds HDCP 1.x support to msm DP connectors using the new 
HDCP

helpers.

Cc: Stephen Boyd 
Signed-off-by: Sean Paul 
Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run
#v1

Changes in v2:
-Squash [1] into this patch with the following changes (Stephen)
  -Update the sc7180 dtsi file
  -Remove resource names and just use index (Stephen)





[1]
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-14-s...@poorly.run
---
 arch/arm64/boot/dts/qcom/sc7180.dtsi |   4 +-
 drivers/gpu/drm/msm/Makefile |   1 +
 drivers/gpu/drm/msm/dp/dp_debug.c|  49 ++-
 drivers/gpu/drm/msm/dp/dp_debug.h|   6 +-
 drivers/gpu/drm/msm/dp/dp_display.c  |  45 ++-
 drivers/gpu/drm/msm/dp/dp_display.h  |   5 +
 drivers/gpu/drm/msm/dp/dp_drm.c  |  68 -
 drivers/gpu/drm/msm/dp/dp_drm.h  |   5 +
 drivers/gpu/drm/msm/dp/dp_hdcp.c | 433 +++
 drivers/gpu/drm/msm/dp/dp_hdcp.h |  27 ++
 drivers/gpu/drm/msm/dp/dp_parser.c   |  22 +-
 drivers/gpu/drm/msm/dp/dp_parser.h   |   4 +
 drivers/gpu/drm/msm/dp/dp_reg.h  |  44 ++-
 drivers/gpu/drm/msm/msm_atomic.c |  15 +
 14 files changed, 709 insertions(+), 19 deletions(-)
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.c
 create mode 100644 drivers/gpu/drm/msm/dp/dp_hdcp.h

diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi
b/arch/arm64/boot/dts/qcom/sc7180.dtsi
index c8921e2d6480..3ae6fc7a2c01 100644
--- a/arch/arm64/boot/dts/qcom/sc7180.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi
@@ -3088,7 +3088,9 @@ mdss_dp: displayport-controller@ae9 {
compatible = "qcom,sc7180-dp";
status = "disabled";

-   reg = <0 0x0ae9 0 0x1400>;
+   reg = <0 0x0ae9 0 0x1400>,
+ <0 0x0aed1000 0 0x174>,
+ <0 0x0aee1000 0 0x2c>;

interrupt-parent = <>;
interrupts = <12>;
diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index 904535eda0c4..98731fd262d6 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -109,6 +109,7 @@ msm-$(CONFIG_DRM_MSM_DP)+= dp/dp_aux.o \
dp/dp_ctrl.o \
dp/dp_display.o \
dp/dp_drm.o \
+   dp/dp_hdcp.o \
dp/dp_hpd.o \
dp/dp_link.o \
dp/dp_panel.o \
diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 2f6247e80e9d..de16fca8782a 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "dp_parser.h"
 #include "dp_catalog.h"
@@ -15,6 +16,7 @@
 #include "dp_ctrl.h"
 #include "dp_debug.h"
 #include "dp_display.h"
+#include "dp_hdcp.h"

 #define DEBUG_NAME "msm_dp"

@@ -24,6 +26,7 @@ struct dp_debug_private {
struct dp_usbpd *usbpd;
struct dp_link *link;
struct dp_panel *panel;
+   struct dp_hdcp *hdcp;
struct drm_connector **connector;
struct device *dev;
struct drm_device *drm_dev;
@@ -349,6 +352,38 @@ static int dp_test_active_open(struct inode 
*inode,

inode->i_private);
 }

+static ssize_t dp_hdcp_key_write(struct file *file, const char __user 
*ubuf,

+size_t len, loff_t *offp)
+{
+   char *input_buffer;
+   int ret = 0;
+   struct dp_debug_private *debug = file->private_data;
+   struct drm_device *dev;
+
+   dev = debug->drm_dev;
+
+   if (len != (DRM_HDCP_KSV_LEN + DP_HDCP_NUM_KEYS * DP_HDCP_KEY_LEN))
+   return -EINVAL;
+
+   if (!debug->hdcp)
+   return -ENOENT;
+
+   input_buffer = memdup_user_nul(ubuf, len);
+   if (IS_ERR(input_buffer))
+   return PTR_ERR(input_buffer);
+
+   ret = dp_hdcp_ingest_key(debug->hdcp, input_buffer, len);
+
+   kfree(input_buffer);
+   if (ret < 0) {
+   DRM_ERROR("Could not ingest HDCP key, ret=%d\n", ret);
+   return ret;
+   }
+
+   *offp += len;
+   return len;
+}


It seems like the HDCP keys written using debugfs, just for my 
understanding,
are you storing this in some secure partition and the usermode reads 
from it

and writes them here?


+
 static const struct file_operations dp_debug_fops = {
.open = simple_open,
.read = dp_debug_read_info,
@@ -363,6 +398,12 @@ static const struct file_operations 
test_active_fops = {

.write = dp_test_active_write
 };

+static const struct file_operations dp_hdcp_key_fops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .write = dp_hdcp_key_write,
+};
+
 static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor 
*minor)

 {
int rc = 0;
@@ 

Re: [Freedreno] [PATCH v2 04/13] drm/hdcp: Expand HDCP helper library for enable/disable/check

2021-09-21 Thread abhinavk

On 2021-09-15 13:38, Sean Paul wrote:

From: Sean Paul 

This patch expands upon the HDCP helper library to manage HDCP
enable, disable, and check.

Previous to this patch, the majority of the state management and sink
interaction is tucked inside the Intel driver with the understanding
that once a new platform supported HDCP we could make good decisions
about what should be centralized. With the addition of HDCP support
for Qualcomm, it's time to migrate the protocol-specific bits of HDCP
authentication, key exchange, and link checks to the HDCP helper.

In terms of functionality, this migration is 1:1 with the Intel driver,
however things are laid out a bit differently than with intel_hdcp.c,
which is why this is a separate patch from the i915 transition to the
helper. On i915, the "shim" vtable is used to account for HDMI vs. DP
vs. DP-MST differences whereas the helper library uses a LUT to
account for the register offsets and a remote read function to route
the messages. On i915, storing the sink information in the source is
done inline whereas now we use the new drm_hdcp_helper_funcs vtable
to store and fetch information to/from source hw. Finally, instead of
calling enable/disable directly from the driver, we'll leave that
decision to the helper and by calling drm_hdcp_helper_atomic_commit()
from the driver. All told, this will centralize the protocol and state
handling in the helper, ensuring we collect all of our bugs^Wlogic
in one place.

Signed-off-by: Sean Paul 
Link:
https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-5-s...@poorly.run
#v1

Changes in v2:
-Fixed set-but-unused variable identified by 0-day
---
 drivers/gpu/drm/drm_hdcp.c | 1103 
 include/drm/drm_hdcp.h |  191 +++
 2 files changed, 1294 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 742313ce8f6f..47c6e6923a76 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -6,15 +6,20 @@
  * Ramalingam C 
  */

+#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -513,3 +518,1101 @@ bool drm_hdcp_atomic_check(struct drm_connector
*connector,
return old_hdcp != new_hdcp;
 }
 EXPORT_SYMBOL(drm_hdcp_atomic_check);
+
+struct drm_hdcp_helper_data {
+   struct mutex mutex;
+   struct mutex *driver_mutex;
+
+   struct drm_connector *connector;
+   const struct drm_hdcp_helper_funcs *funcs;
+
+   u64 value;
+   unsigned int enabled_type;
+
+   struct delayed_work check_work;
+   struct work_struct prop_work;
+
+   struct drm_dp_aux *aux;
+   const struct drm_hdcp_hdcp1_receiver_reg_lut *hdcp1_lut;
+};
+
+struct drm_hdcp_hdcp1_receiver_reg_lut {
+   unsigned int bksv;
+   unsigned int ri;
+   unsigned int aksv;
+   unsigned int an;
+   unsigned int ainfo;
+   unsigned int v[5];
+   unsigned int bcaps;
+   unsigned int bcaps_mask_repeater_present;
+   unsigned int bstatus;
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_ddc_lut = {

+   .bksv = DRM_HDCP_DDC_BKSV,
+   .ri = DRM_HDCP_DDC_RI_PRIME,
+   .aksv = DRM_HDCP_DDC_AKSV,
+   .an = DRM_HDCP_DDC_AN,
+   .ainfo = DRM_HDCP_DDC_AINFO,
+   .v = { DRM_HDCP_DDC_V_PRIME(0), DRM_HDCP_DDC_V_PRIME(1),
+  DRM_HDCP_DDC_V_PRIME(2), DRM_HDCP_DDC_V_PRIME(3),
+  DRM_HDCP_DDC_V_PRIME(4) },
+   .bcaps = DRM_HDCP_DDC_BCAPS,
+   .bcaps_mask_repeater_present = DRM_HDCP_DDC_BCAPS_REPEATER_PRESENT,
+   .bstatus = DRM_HDCP_DDC_BSTATUS,
+};
+
+static const struct drm_hdcp_hdcp1_receiver_reg_lut 
drm_hdcp_hdcp1_dpcd_lut = {

+   .bksv = DP_AUX_HDCP_BKSV,
+   .ri = DP_AUX_HDCP_RI_PRIME,
+   .aksv = DP_AUX_HDCP_AKSV,
+   .an = DP_AUX_HDCP_AN,
+   .ainfo = DP_AUX_HDCP_AINFO,
+   .v = { DP_AUX_HDCP_V_PRIME(0), DP_AUX_HDCP_V_PRIME(1),
+  DP_AUX_HDCP_V_PRIME(2), DP_AUX_HDCP_V_PRIME(3),
+  DP_AUX_HDCP_V_PRIME(4) },
+   .bcaps = DP_AUX_HDCP_BCAPS,
+   .bcaps_mask_repeater_present = DP_BCAPS_REPEATER_PRESENT,
+
+   /*
+* For some reason the HDMI and DP HDCP specs call this register
+	 * definition by different names. In the HDMI spec, it's called 
BSTATUS,

+* but in DP it's called BINFO.
+*/
+   .bstatus = DP_AUX_HDCP_BINFO,
+};
+
+static int drm_hdcp_remote_ddc_read(struct i2c_adapter *i2c,
+   unsigned int offset, u8 *value, size_t len)
+{
+   int ret;
+   u8 start = offset & 0xff;
+   struct i2c_msg msgs[] = {
+   {
+   .addr = DRM_HDCP_DDC_ADDR,
+   .flags = 0,
+   .len = 1,
+   .buf = ,
+   },
+   {
+   .addr = DRM_HDCP_DDC_ADDR,
+

Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-21 Thread abhinavk

On 2021-09-21 10:47, Dmitry Baryshkov wrote:

Hi,

On Tue, 21 Sept 2021 at 20:01,  wrote:


On 2021-09-21 09:22, Dmitry Baryshkov wrote:
> The DSI host might be left in some state by the bootloader. If this
> state generates an IRQ, it might hang the system by holding the
> interrupt line before the driver sets up the DSI host to the known
> state.
>
> Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
> so that we can be sure that the interrupt is delivered when the host is
> in the known state.
>
> Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
> Signed-off-by: Dmitry Baryshkov 

This is a valid change and we have seen interrupt storms in downstream
happening
when like you said the bootloader leaves the DSI host in unknown 
state.

Just one question below.

> ---
>  drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
>  1 file changed, 12 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
> b/drivers/gpu/drm/msm/dsi/dsi_host.c
> index e269df285136..cd842347a6b1 100644
> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c
> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
> @@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct
> mipi_dsi_host *host,
>   return ret;
>   }
>
> - ret = devm_request_irq(>dev, msm_host->irq,
> - dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> - "dsi_isr", msm_host);
> - if (ret < 0) {
> - DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
> - msm_host->irq, ret);
> - return ret;
> - }
> -
>   msm_host->dev = dev;
>   ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
>   if (ret) {
> @@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host
> *host,
>   if (msm_host->disp_en_gpio)
>   gpiod_set_value(msm_host->disp_en_gpio, 1);
>
> + ret = devm_request_irq(_host->pdev->dev, msm_host->irq,
> + dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
> + "dsi_isr", msm_host);
> + if (ret < 0) {
> + DRM_DEV_ERROR(_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
> + msm_host->irq, ret);
> + return ret;
> + }
> +
> +

Do you want to move this to msm_dsi_host_enable()?
So without the controller being enabled it is still in unknown state?


msm_dsi_host_power_on() reconfigures the host registers, so the state
is known at the end of the power_on().


Also do you want to do this after dsi0 and dsi1 are initialized to
account for
dual dsi cases?


I don't think this should matter. The host won't generate 'extra'
interrupts in such case, will it?

We have seen cases where misconfiguration has caused interrupts to storm 
only
on one DSI in some cases. So yes, I would prefer this is done after both 
are

configured.



>   msm_host->power_on = true;
>   mutex_unlock(_host->dev_mutex);
>
> @@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host
> *host)
>   goto unlock_ret;
>   }
>
> + devm_free_irq(_host->pdev->dev, msm_host->irq, msm_host);
> +
>   dsi_ctrl_config(msm_host, false, NULL, NULL);
>
>   if (msm_host->disp_en_gpio)


Re: [Freedreno] [PATCH] drm/msm/dsi: do not install irq handler before power up the host

2021-09-21 Thread abhinavk

On 2021-09-21 09:22, Dmitry Baryshkov wrote:

The DSI host might be left in some state by the bootloader. If this
state generates an IRQ, it might hang the system by holding the
interrupt line before the driver sets up the DSI host to the known
state.

Move the request/free_irq calls into msm_dsi_host_power_on/_off calls,
so that we can be sure that the interrupt is delivered when the host is
in the known state.

Fixes: a689554ba6ed ("drm/msm: Initial add DSI connector support")
Signed-off-by: Dmitry Baryshkov 


This is a valid change and we have seen interrupt storms in downstream 
happening

when like you said the bootloader leaves the DSI host in unknown state.
Just one question below.


---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 21 -
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e269df285136..cd842347a6b1 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -1951,15 +1951,6 @@ int msm_dsi_host_modeset_init(struct 
mipi_dsi_host *host,

return ret;
}

-   ret = devm_request_irq(>dev, msm_host->irq,
-   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
-   "dsi_isr", msm_host);
-   if (ret < 0) {
-   DRM_DEV_ERROR(>dev, "failed to request IRQ%u: %d\n",
-   msm_host->irq, ret);
-   return ret;
-   }
-
msm_host->dev = dev;
ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
@@ -2413,6 +2404,16 @@ int msm_dsi_host_power_on(struct mipi_dsi_host 
*host,

if (msm_host->disp_en_gpio)
gpiod_set_value(msm_host->disp_en_gpio, 1);

+   ret = devm_request_irq(_host->pdev->dev, msm_host->irq,
+   dsi_host_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+   "dsi_isr", msm_host);
+   if (ret < 0) {
+   DRM_DEV_ERROR(_host->pdev->dev, "failed to request IRQ%u: 
%d\n",
+   msm_host->irq, ret);
+   return ret;
+   }
+
+


Do you want to move this to msm_dsi_host_enable()?
So without the controller being enabled it is still in unknown state?
Also do you want to do this after dsi0 and dsi1 are initialized to 
account for

dual dsi cases?


msm_host->power_on = true;
mutex_unlock(_host->dev_mutex);

@@ -2439,6 +2440,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host 
*host)

goto unlock_ret;
}

+   devm_free_irq(_host->pdev->dev, msm_host->irq, msm_host);
+
dsi_ctrl_config(msm_host, false, NULL, NULL);

if (msm_host->disp_en_gpio)


Re: [Freedreno] [PATCH] drm/msm/dsi/phy: fix clock names in 28nm_8960 phy

2021-09-21 Thread abhinavk

On 2021-09-21 09:22, Dmitry Baryshkov wrote:

The commit 9f91f22aafcd ("drm/msm/dsi: remove duplicate fields from
dsi_pll_Nnm instances") mistakenly changed registered clock names. 
While

the platform is in progress of migration to using clock properties in
the dts rather than the global clock names, we should provide backwards
compatibility. Thus restore registerd global clock names.

Fixes: 9f91f22aafcd ("drm/msm/dsi: remove duplicate fields from
dsi_pll_Nnm instances")
Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
index aaa37456f4ee..71ed4aa0dc67 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c
@@ -428,7 +428,7 @@ static int pll_28nm_register(struct dsi_pll_28nm
*pll_28nm, struct clk_hw **prov
 	bytediv->reg = pll_28nm->phy->pll_base + 
REG_DSI_28nm_8960_PHY_PLL_CTRL_9;


snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id);
-   snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id);
+   snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id + 1);

bytediv_init.name = clk_name;
bytediv_init.ops = _bytediv_ops;
@@ -442,7 +442,7 @@ static int pll_28nm_register(struct dsi_pll_28nm
*pll_28nm, struct clk_hw **prov
return ret;
provided_clocks[DSI_BYTE_PLL_CLK] = >hw;

-   snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id);
+   snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id + 1);
/* DIV3 */
hw = devm_clk_hw_register_divider(dev, clk_name,
parent_name, 0, pll_28nm->phy->pll_base +


Re: [RESEND PATCH v6 13/14] drm/atomic: Use debug category printer for atomic state printer

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

The atomic state is printed if the DRM_UT_STATE is active, but it's
printed at INFO level. This patch converts it to use the debug
category printer so:

a- it's consistent with other DRM_UT_STATE logging
b- it's properly routed through drm_trace when introduced

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 


Changes in v6:
-Added to the set
---
 drivers/gpu/drm/drm_atomic_uapi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
b/drivers/gpu/drm/drm_atomic_uapi.c
index 7e48d40600ff..7615ded60195 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -1322,7 +1322,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_out_fence_state *fence_state;
int ret = 0;
unsigned int i, j, num_fences;
-   struct drm_printer p = drm_info_printer(dev->dev);
+   struct drm_printer p = drm_debug_category_printer(DRM_UT_STATE,
"commit_state");

/* disallow for drivers not supporting atomic: */
if (!drm_core_check_feature(dev, DRIVER_ATOMIC))


Re: [RESEND PATCH v6 10/14] drm/print: Add drm_debug_category_printer

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

This patch adds a new printer which will select the appropriate output
for a given debug category. Currently there is only one output target,
which is syslog. However in the future we'll have tracefs and it will 
be
useful to print to syslog, tracefs, or both. Drivers just need to 
create

the printer for the appropriate category and the printer will decide
where to send the output.

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-11-s...@poorly.run
#v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/drm_print.c |  5 +
 include/drm/drm_print.h | 28 
 2 files changed, 33 insertions(+)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 2ff7a6ecc632..4d984a01b3a3 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -172,6 +172,11 @@ void __drm_printfn_err(struct drm_printer *p,
struct va_format *vaf)
 }
 EXPORT_SYMBOL(__drm_printfn_err);

+void __drm_printfn_noop(struct drm_printer *p, struct va_format *vaf)
+{
+}
+EXPORT_SYMBOL(__drm_printfn_noop);
+
 /**
  * drm_puts - print a const string to a _printer stream
  * @p: the  printer
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 2ea0ffd9c1ce..af31beeb82a1 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -87,6 +87,7 @@ void __drm_puts_seq_file(struct drm_printer *p,
const char *str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
 void __drm_printfn_debug_syslog(struct drm_printer *p, struct 
va_format *vaf);

 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf);
+void __drm_printfn_noop(struct drm_printer *p, struct va_format *vaf);

 __printf(2, 3)
 void drm_printf(struct drm_printer *p, const char *f, ...);
@@ -329,6 +330,33 @@ static inline bool drm_debug_enabled(enum
drm_debug_category category)
return drm_debug_syslog_enabled(category);
 }

+/**
+ * drm_debug_category_printer - construct a _printer that outputs 
to

+ * pr_debug() if enabled for the given category.
+ * @category: the DRM_UT_* message category this message belongs to
+ * @prefix: trace output prefix
+ *
+ * RETURNS:
+ * The _printer object
+ */
+static inline struct drm_printer
+drm_debug_category_printer(enum drm_debug_category category,
+  const char *prefix)
+{
+   struct drm_printer p = {
+   .prefix = prefix
+   };
+
+   if (drm_debug_syslog_enabled(category)) {
+   p.printfn = __drm_printfn_debug_syslog;
+   } else {
+   WARN(1, "Debug category %d is inactive.", category);
+   p.printfn = __drm_printfn_noop;
+   }
+
+   return p;
+}
+
 /*
  * struct device based logging
  *


Re: [RESEND PATCH v6 05/14] drm/print: rename drm_debug* to be more syslog-centric

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

In preparation for tracefs support, rename drm_debug related functions
to reflect that it targets the syslog. This will allow us to 
selectively

target syslog and/or tracefs.

No functional changes here.

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-6-s...@poorly.run
#v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/drm_print.c | 12 ++--
 include/drm/drm_print.h | 13 +
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 111b932cf2a9..2ff7a6ecc632 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -37,11 +37,11 @@
 #include 

 /*
- * __drm_debug: Enable debug output.
+ * __drm_debug_syslog: Enable debug output to system logs
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
  */
-unsigned int __drm_debug;
-EXPORT_SYMBOL(__drm_debug);
+unsigned int __drm_debug_syslog;
+EXPORT_SYMBOL(__drm_debug_syslog);

 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables
a debug category.\n"
 "\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where
each bit enables a debug cat
 "\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
 "\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
-module_param_named(debug, __drm_debug, int, 0600);
+module_param_named(debug, __drm_debug_syslog, int, 0600);

 void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
@@ -160,11 +160,11 @@ void __drm_printfn_info(struct drm_printer *p,
struct va_format *vaf)
 }
 EXPORT_SYMBOL(__drm_printfn_info);

-void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
+void __drm_printfn_debug_syslog(struct drm_printer *p, struct 
va_format *vaf)

 {
pr_debug("%s %pV", p->prefix, vaf);
 }
-EXPORT_SYMBOL(__drm_printfn_debug);
+EXPORT_SYMBOL(__drm_printfn_debug_syslog);

 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 9b66be54dd16..2ea0ffd9c1ce 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -35,7 +35,7 @@
 #include 

 /* Do *not* use outside of drm_print.[ch]! */
-extern unsigned int __drm_debug;
+extern unsigned int __drm_debug_syslog;

 /**
  * DOC: print
@@ -85,7 +85,7 @@ void __drm_puts_coredump(struct drm_printer *p,
const char *str);
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format 
*vaf);

 void __drm_puts_seq_file(struct drm_printer *p, const char *str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
-void __drm_printfn_debug(struct drm_printer *p, struct va_format 
*vaf);
+void __drm_printfn_debug_syslog(struct drm_printer *p, struct 
va_format *vaf);

 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf);

 __printf(2, 3)
@@ -227,7 +227,7 @@ static inline struct drm_printer
drm_info_printer(struct device *dev)
 static inline struct drm_printer drm_debug_printer(const char *prefix)
 {
struct drm_printer p = {
-   .printfn = __drm_printfn_debug,
+   .printfn = __drm_printfn_debug_syslog,
.prefix = prefix
};
return p;
@@ -319,9 +319,14 @@ enum drm_debug_category {
DRM_UT_DRMRES   = 0x200,
 };

+static inline bool drm_debug_syslog_enabled(enum drm_debug_category 
category)

+{
+   return unlikely(__drm_debug_syslog & category);
+}
+
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
-   return unlikely(__drm_debug & category);
+   return drm_debug_syslog_enabled(category);
 }

 /*


Re: [RESEND PATCH v6 05/14] drm/print: rename drm_debug* to be more syslog-centric

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

In preparation for tracefs support, rename drm_debug related functions
to reflect that it targets the syslog. This will allow us to 
selectively

target syslog and/or tracefs.

No functional changes here.

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-6-s...@poorly.run
#v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/drm_print.c | 12 ++--
 include/drm/drm_print.h | 13 +
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 111b932cf2a9..2ff7a6ecc632 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -37,11 +37,11 @@
 #include 

 /*
- * __drm_debug: Enable debug output.
+ * __drm_debug_syslog: Enable debug output to system logs
  * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
  */
-unsigned int __drm_debug;
-EXPORT_SYMBOL(__drm_debug);
+unsigned int __drm_debug_syslog;
+EXPORT_SYMBOL(__drm_debug_syslog);

 MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables
a debug category.\n"
 "\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(debug, "Enable debug output, where
each bit enables a debug cat
 "\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
 "\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
 "\t\tBit 8 (0x100) will enable DP messages (displayport code)");
-module_param_named(debug, __drm_debug, int, 0600);
+module_param_named(debug, __drm_debug_syslog, int, 0600);

 void __drm_puts_coredump(struct drm_printer *p, const char *str)
 {
@@ -160,11 +160,11 @@ void __drm_printfn_info(struct drm_printer *p,
struct va_format *vaf)
 }
 EXPORT_SYMBOL(__drm_printfn_info);

-void __drm_printfn_debug(struct drm_printer *p, struct va_format *vaf)
+void __drm_printfn_debug_syslog(struct drm_printer *p, struct 
va_format *vaf)

 {
pr_debug("%s %pV", p->prefix, vaf);
 }
-EXPORT_SYMBOL(__drm_printfn_debug);
+EXPORT_SYMBOL(__drm_printfn_debug_syslog);

 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf)
 {
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
index 9b66be54dd16..2ea0ffd9c1ce 100644
--- a/include/drm/drm_print.h
+++ b/include/drm/drm_print.h
@@ -35,7 +35,7 @@
 #include 

 /* Do *not* use outside of drm_print.[ch]! */
-extern unsigned int __drm_debug;
+extern unsigned int __drm_debug_syslog;

 /**
  * DOC: print
@@ -85,7 +85,7 @@ void __drm_puts_coredump(struct drm_printer *p,
const char *str);
 void __drm_printfn_seq_file(struct drm_printer *p, struct va_format 
*vaf);

 void __drm_puts_seq_file(struct drm_printer *p, const char *str);
 void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
-void __drm_printfn_debug(struct drm_printer *p, struct va_format 
*vaf);
+void __drm_printfn_debug_syslog(struct drm_printer *p, struct 
va_format *vaf);

 void __drm_printfn_err(struct drm_printer *p, struct va_format *vaf);

 __printf(2, 3)
@@ -227,7 +227,7 @@ static inline struct drm_printer
drm_info_printer(struct device *dev)
 static inline struct drm_printer drm_debug_printer(const char *prefix)
 {
struct drm_printer p = {
-   .printfn = __drm_printfn_debug,
+   .printfn = __drm_printfn_debug_syslog,
.prefix = prefix
};
return p;
@@ -319,9 +319,14 @@ enum drm_debug_category {
DRM_UT_DRMRES   = 0x200,
 };

+static inline bool drm_debug_syslog_enabled(enum drm_debug_category 
category)

+{
+   return unlikely(__drm_debug_syslog & category);
+}
+
 static inline bool drm_debug_enabled(enum drm_debug_category category)
 {
-   return unlikely(__drm_debug & category);
+   return drm_debug_syslog_enabled(category);
 }

 /*


Re: [Freedreno] [RESEND PATCH v6 04/14] drm/msm/dpu: Replace definitions for dpu debug macros

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

The debug messages shouldn't be logged as errors when debug categories
are enabled. Use the drm logging helpers to do the right thing

Signed-off-by: Sean Paul 

Reviewed-by: Abhinav Kumar 

Link:
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-5-s...@poorly.run
#v5

Changes in v5:
-Added to the set
Changes in v6:
-None
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 20 
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 323a6bce9e64..c33164d3944a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -31,27 +31,15 @@
  * DPU_DEBUG - macro for kms/plane/crtc/encoder/connector logs
  * @fmt: Pointer to format string
  */
-#define DPU_DEBUG(fmt, ...)
\

-   do {   \
-   if (drm_debug_enabled(DRM_UT_KMS)) \
-   DRM_DEBUG(fmt, ##__VA_ARGS__); \
-   else   \
-   pr_debug(fmt, ##__VA_ARGS__);  \
-   } while (0)
+#define DPU_DEBUG(fmt, ...) DRM_DEBUG_KMS(fmt, ##__VA_ARGS__)

 /**
  * DPU_DEBUG_DRIVER - macro for hardware driver logging
  * @fmt: Pointer to format string
  */
-#define DPU_DEBUG_DRIVER(fmt, ...) 
\

-   do {   \
-   if (drm_debug_enabled(DRM_UT_DRIVER))  \
-   DRM_ERROR(fmt, ##__VA_ARGS__); \
-   else   \
-   pr_debug(fmt, ##__VA_ARGS__);  \
-   } while (0)
-
-#define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
+#define DPU_DEBUG_DRIVER(fmt, ...) DRM_DEBUG_DRIVER(fmt, 
##__VA_ARGS__)

+
+#define DPU_ERROR(fmt, ...) DRM_ERROR(fmt, ##__VA_ARGS__)

 /**
  * ktime_compare_safe - compare two ktime structures


Re: [RESEND PATCH v6 14/14] drm/print: Add tracefs support to the drm logging helpers

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

This patch adds a new module parameter called drm.trace which accepts
the same mask as drm.debug. When a debug category is enabled, log
messages will be put in a new tracefs instance called drm for
consumption.

Using the new tracefs instance will allow distros to enable drm logging
in production without impacting performance or spamming the system
logs.

Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Pekka Paalanen 
Cc: Rob Clark 
Cc: Steven Rostedt 
Cc: Thomas Zimmermann 
Cc: Ville Syrjälä 
Cc: Chris Wilson 
Cc: Steven Rostedt 
Reported-by: kernel test robot  # warning reported in v6
Acked-by: Pekka Paalanen 
Signed-off-by: Sean Paul 
Link:
https://patchwork.freedesktop.org/patch/msgid/20191010204823.195540-1-s...@poorly.run
#v1
Link:
https://lists.freedesktop.org/archives/dri-devel/2019-November/243230.html
#v2
Link:
https://patchwork.freedesktop.org/patch/msgid/20191212203301.142437-1-s...@poorly.run
#v3
Link:
https://patchwork.freedesktop.org/patch/msgid/20200114172155.215463-1-s...@poorly.run
#v4
Link:
https://patchwork.freedesktop.org/patch/msgid/20200608210505.48519-14-s...@poorly.run
#v5
Link:
https://patchwork.freedesktop.org/patch/msgid/20200818210510.49730-15-s...@poorly.run
#v6

Changes in v5:
-Re-write to use trace_array and the tracefs instance support
Changes in v6:
-Use the new trace_array_init_printk() to initialize global trace
 buffers
Changes in v6.5:
-Fix kernel test robot warning
-Add a trace printf in __drm_err
---
 Documentation/gpu/drm-uapi.rst |   6 +
 drivers/gpu/drm/drm_drv.c  |   3 +
 drivers/gpu/drm/drm_print.c| 223 -
 include/drm/drm_print.h|  63 --
 4 files changed, 255 insertions(+), 40 deletions(-)

diff --git a/Documentation/gpu/drm-uapi.rst 
b/Documentation/gpu/drm-uapi.rst

index 7e51dd40bf6e..ce1ea39fb4b9 100644
--- a/Documentation/gpu/drm-uapi.rst
+++ b/Documentation/gpu/drm-uapi.rst
@@ -424,6 +424,12 @@ Debugfs Support
 .. kernel-doc:: drivers/gpu/drm/drm_debugfs.c
:export:

+DRM Tracing
+---
+
+.. kernel-doc:: drivers/gpu/drm/drm_print.c
+   :doc: DRM Tracing
+
 Sysfs Support
 =

diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 8804ec7d3215..71dc0b161b51 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -1034,12 +1034,15 @@ static void drm_core_exit(void)
drm_sysfs_destroy();
idr_destroy(_minors_idr);
drm_connector_ida_destroy();
+   drm_trace_cleanup();
 }

 static int __init drm_core_init(void)
 {
int ret;

+   drm_trace_init();


Can we move the drm_trace_init() to drm_dev_register()?
The reason is while creating the tracefs node, I think its useful to 
have the drm device id to support
multiple DRM devices. So while creating the tracefs node, we can do 
something like

trace_array_get_by_name("drm_
+
drm_connector_ida_init();
idr_init(_minors_idr);
drm_memcpy_init_early();
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
index 4d984a01b3a3..64d9a724c2df 100644
--- a/drivers/gpu/drm/drm_print.c
+++ b/drivers/gpu/drm/drm_print.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -43,17 +44,34 @@
 unsigned int __drm_debug_syslog;
 EXPORT_SYMBOL(__drm_debug_syslog);

-MODULE_PARM_DESC(debug, "Enable debug output, where each bit enables
a debug category.\n"
-"\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n"
-"\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller 
code)\n"

-"\t\tBit 2 (0x04)  will enable KMS messages (modesetting code)\n"
-"\t\tBit 3 (0x08)  will enable PRIME messages (prime code)\n"
-"\t\tBit 4 (0x10)  will enable ATOMIC messages (atomic code)\n"
-"\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n"
-"\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n"
-"\t\tBit 8 (0x100) will enable DP messages (displayport code)");
+/*
+ * __drm_debug_trace: Enable debug output in drm tracing instance.
+ * Bitmask of DRM_UT_x. See include/drm/drm_print.h for details.
+ */
+unsigned int __drm_debug_trace;
+EXPORT_SYMBOL(__drm_debug_trace);
+
+#define DEBUG_PARM_DESC(dst) \
+"Enable debug output to " dst ", where each bit enables a debug 
category.\n" \

+"\t\tBit 0 (0x01)  will enable CORE messages (drm core code)\n" \
+"\t\tBit 1 (0x02)  will enable DRIVER messages (drm controller 
code)\n" \

+"\t\tBit 2 (0x04)  will enable KMS messages (modesetting code)\n" \
+"\t\tBit 3 (0x08)  will enable PRIME messages (prime code)\n" \
+"\t\tBit 4 (0x10)  will enable ATOMIC messages (atomic code)\n" \
+"\t\tBit 5 (0x20)  will enable VBL messages (vblank code)\n" \
+"\t\tBit 7 (0x80)  will enable LEASE messages (leasing code)\n" \
+"\t\tBit 8 (0x100) will enable DP messages (displayport code)"


This is certainly a great start. Moving forward a bit, is there a 
possibility to subcatergorize


Re: [RESEND PATCH v6 00/14] drm/trace: Mirror DRM debug logs to tracefs

2021-09-17 Thread abhinavk

On 2021-07-21 10:55, Sean Paul wrote:

From: Sean Paul 

Hi all,
I just had the pleasure of rebasing this set on our CrOS downstream
kernel and wanted to resend it for consideration once again. There
hasn't been any resistence to the set AFAIK, just perhaps not enough
motivation for anyone to hit the go bit. There was some interest from
the msm folks about a month ago, and it has been an invaluable tool
on CrOS for the past ~year. Hopefully someone can dig into this and
provide some feedback so we can move this forward.

Thanks!

Sean


Totally agree, This tool has been valuable for us in debugging many 
issues.

FWIW, I will go through the core bits and msm pieces to give my RB.



Changes since last v6:
-Rebased on drm-tip

Original v6 of the set available here:
https://patchwork.freedesktop.org/series/78133/
https://lore.kernel.org/dri-devel/20200818210510.49730-1-s...@poorly.run/

Sean Paul (14):
  drm/mipi_dbi: Convert pr_debug calls to DRM_DEBUG_DRIVER
  drm/sil164: Convert dev_printk to drm_dev_dbg
  drm/i915/utils: Replace dev_printk with drm helpers
  drm/msm/dpu: Replace definitions for dpu debug macros
  drm/print: rename drm_debug* to be more syslog-centric
  drm/amd: Gate i2c transaction logs on drm_debug_syslog
  drm/etnaviv: Change buffer dump checks to target syslog
  drm/nouveau: Change debug checks to specifically target syslog
  drm/i915: Change infoframe debug checks to specify syslog
  drm/print: Add drm_debug_category_printer
  drm/mst: Convert debug printers to debug category printers
  drm/i915: Use debug category printer for welcome message
  drm/atomic: Use debug category printer for atomic state printer
  drm/print: Add tracefs support to the drm logging helpers

 Documentation/gpu/drm-uapi.rst   |   6 +
 drivers/gpu/drm/amd/amdgpu/smu_v11_0_i2c.c   |   4 +-
 drivers/gpu/drm/drm_atomic_uapi.c|   2 +-
 drivers/gpu/drm/drm_dp_mst_topology.c|   9 +-
 drivers/gpu/drm/drm_drv.c|   3 +
 drivers/gpu/drm/drm_mipi_dbi.c   |   8 +-
 drivers/gpu/drm/drm_print.c  | 242 ---
 drivers/gpu/drm/etnaviv/etnaviv_buffer.c |   8 +-
 drivers/gpu/drm/i2c/sil164_drv.c |  12 +-
 drivers/gpu/drm/i915/display/intel_display.c |   4 +-
 drivers/gpu/drm/i915/i915_drv.c  |   3 +-
 drivers/gpu/drm/i915/i915_utils.c|   5 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h  |  20 +-
 drivers/gpu/drm/nouveau/nouveau_drv.h|   4 +-
 include/drm/drm_print.h  |  96 +++-
 15 files changed, 331 insertions(+), 95 deletions(-)


Re: [Freedreno] [PATCH] drm/msm: Do not run snapshot on non-DPU devices

2021-09-16 Thread abhinavk

Hi Fabio

Ah, I did not realize that amd compatible is present in the list and its 
quite a surprise.


/*
 * We don't know what's the best binding to link the gpu with the drm 
device.
 * Fow now, we just hunt for all the possible gpus that we support, and 
add them

 * as components.
 */
static const struct of_device_id msm_gpu_match[] = {
{ .compatible = "qcom,adreno" },
{ .compatible = "qcom,adreno-3xx" },
{ .compatible = "amd,imageon" },
{ .compatible = "qcom,kgsl-3d0" },
{ },
};

https://github.com/torvalds/linux/commit/e6f6d63ed14c20528aa6df05a8f0707c183c6ba3

For this change itself,
Reviewed-by: Abhinav Kumar 

On 2021-09-16 09:24, Fabio Estevam wrote:

Hi Abhinav,

On Thu, Sep 16, 2021 at 1:15 PM  wrote:


Hi Fabio

Thanks for confirming.

Although I have no issues with your change, I am curious why even msm 
is

probing and/or binding.
Your device tree should not be having any mdp/dpu nodes then.


The i.MX53 does have the following GPU node:

compatible = "amd,imageon-200.0", "amd,imageon";

That's why it probes the msm driver.

However, i.MX53 does not have any of the Qualcomm display controllers.

It uses the i.MX IPU display controller instead.

Hope that clarifies.

Please reply with a Reviewed-by if you are happy with my fix.

Thanks


Re: [Freedreno] [PATCH] drm/msm: Do not run snapshot on non-DPU devices

2021-09-16 Thread abhinavk

Hi Fabio

Thanks for confirming.

Although I have no issues with your change, I am curious why even msm is 
probing and/or binding.

Your device tree should not be having any mdp/dpu nodes then.

Thanks

Abhinav
On 2021-09-16 04:42, Fabio Estevam wrote:

Hi Abhinav,

On Wed, Sep 15, 2021 at 11:22 PM  wrote:


Are you not using DPU or are you not using mdp4/mdp5 as well? Even if
you are using any of mdps, kms should
not be NULL. Hence wanted to check the test case.


I am running i.MX53, which is an NXP SoC, not Qualcomm's.

It does not use DPU, nor MDP4/5 and kms is NULL in this case.

Some debug prints to confirm:

--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -557,18 +557,22 @@ static int msm_drm_init(struct device *dev,
const struct drm_driver *drv)
case KMS_MDP4:
kms = mdp4_kms_init(ddev);
priv->kms = kms;
+   pr_err(" KMS_MDP4\n");
break;
case KMS_MDP5:
kms = mdp5_kms_init(ddev);
+   pr_err(" KMS_MDP5\n");
break;
case KMS_DPU:
kms = dpu_kms_init(ddev);
+   pr_err(" KMS_DPU\n");
priv->kms = kms;
break;
default:
/* valid only for the dummy headless case, where 
of_node=NULL */

WARN_ON(dev->of_node);
kms = NULL;
+   pr_err(" KMS is NULL\n");
break;
}

# dmesg | grep KMS
[3.153215]  KMS is NULL


Re: [Freedreno] [PATCH] drm/msm: Do not run snapshot on non-DPU devices

2021-09-15 Thread abhinavk

Hi Fabio

On 2021-09-14 10:48, Fabio Estevam wrote:

Since commit 98659487b845 ("drm/msm: add support to take dpu snapshot")
the following NULL pointer dereference is seen on i.MX53:

[ 3.275493] msm msm: bound 3000.gpu (ops a3xx_ops)
[ 3.287174] [drm] Initialized msm 1.8.0 20130625 for msm on minor 0
[ 3.293915] 8<--- cut here ---
[ 3.297012] Unable to handle kernel NULL pointer dereference at
virtual address 0028
[ 3.305244] pgd = (ptrval)
[ 3.307989] [0028] *pgd=
[ 3.311624] Internal error: Oops: 805 [#1] SMP ARM
[ 3.316430] Modules linked in:
[ 3.319503] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
5.14.0+g682d702b426b #1

[ 3.326652] Hardware name: Freescale i.MX53 (Device Tree Support)
[ 3.332754] PC is at __mutex_init+0x14/0x54
[ 3.336969] LR is at msm_disp_snapshot_init+0x24/0xa0

i.MX53 does not use the DPU controller.

Fix the problem by only calling msm_disp_snapshot_init() on platforms 
that

use the DPU controller.

Cc: sta...@vger.kernel.org
Fixes: 98659487b845 ("drm/msm: add support to take dpu snapshot")
Signed-off-by: Fabio Estevam 
---
 drivers/gpu/drm/msm/msm_drv.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c 
b/drivers/gpu/drm/msm/msm_drv.c

index 2e6fc185e54d..2aa2266454b7 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -630,10 +630,11 @@ static int msm_drm_init(struct device *dev,
const struct drm_driver *drv)
if (ret)
goto err_msm_uninit;

-   ret = msm_disp_snapshot_init(ddev);
-   if (ret)
-   DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", 
ret);
-
+   if (kms) {
+   ret = msm_disp_snapshot_init(ddev);
+   if (ret)
+			DRM_DEV_ERROR(dev, "msm_disp_snapshot_init failed ret = %d\n", 
ret);

+   }
Are you not using DPU or are you not using mdp4/mdp5 as well? Even if 
you are using any of mdps, kms should

not be NULL. Hence wanted to check the test case.


drm_mode_config_reset(ddev);

 #ifdef CONFIG_DRM_FBDEV_EMULATION


Re: [PATCH] drm/msm/dsi: Use division result from div_u64_rem in 7nm and 14nm PLL

2021-09-07 Thread abhinavk

On 2021-09-06 13:25, Marijn Suijten wrote:

div_u64_rem provides the result of the divison and additonally the
remainder; don't use this function to solely calculate the remainder
while calculating the division again with div_u64.

A similar improvement was applied earlier to the 10nm pll in
5c191fef4ce2 ("drm/msm/dsi_pll_10nm: Fix dividing the same numbers
twice").

Signed-off-by: Marijn Suijten 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 4 +---
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c  | 4 +---
 2 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
index 3c1e2106d962..8905f365c932 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c
@@ -213,9 +213,7 @@ static void pll_14nm_dec_frac_calc(struct
dsi_pll_14nm *pll, struct dsi_pll_conf
DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref);

dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref);
-   div_u64_rem(dec_start_multiple, multiplier, _frac_start);
-
-   dec_start = div_u64(dec_start_multiple, multiplier);
+	dec_start = div_u64_rem(dec_start_multiple, multiplier, 
_frac_start);


pconf->dec_start = (u32)dec_start;
pconf->div_frac_start = div_frac_start;
diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
index c77c30628cca..1a5abbd9fb76 100644
--- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
+++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c
@@ -114,9 +114,7 @@ static void dsi_pll_calc_dec_frac(struct
dsi_pll_7nm *pll, struct dsi_pll_config

multiplier = 1 << FRAC_BITS;
dec_multiple = div_u64(pll_freq * multiplier, divider);
-   div_u64_rem(dec_multiple, multiplier, );
-
-   dec = div_u64(dec_multiple, multiplier);
+   dec = div_u64_rem(dec_multiple, multiplier, );

if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1))
config->pll_clock_inverters = 0x28;


Re: [Freedreno] [PATCH v2 7/7] drm/msm/dpu: remove struct dpu_encoder_irq and enum dpu_intr_idx

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:
Drop the wrapping structures and the enum used to index those 
structures

in dpu_kms. Instead of them use IRQ indices and callback functions
directly.

Signed-off-by: Dmitry Baryshkov 


Is this change really needed because I think the enum based approach is 
good.

Even in the diff stats, the LOC reduced is not that significant.
Having one dpu_encoder_irq struct with the information contained seems
reasonable to me.

Can you please explain any redundancy or benefits of this approach that 
i am missing?



---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   | 47 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  | 48 +++---
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 94 +++
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 53 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 12 +--
 5 files changed, 92 insertions(+), 162 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 3d8864df8605..55ae3ede5846 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -241,11 +241,11 @@ static void _dpu_encoder_setup_dither(struct
dpu_hw_pingpong *hw_pp, unsigned bp
 }

 void dpu_encoder_helper_report_irq_timeout(struct dpu_encoder_phys 
*phys_enc,

-   enum dpu_intr_idx intr_idx)
+   int irq_idx)
 {
DRM_ERROR("irq timeout id=%u, intf=%d, pp=%d, intr=%d\n",
  DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0,
- phys_enc->hw_pp->idx - PINGPONG_0, intr_idx);
+ phys_enc->hw_pp->idx - PINGPONG_0, irq_idx);

if (phys_enc->parent_ops->handle_frame_done)
phys_enc->parent_ops->handle_frame_done(
@@ -257,75 +257,70 @@ static int
dpu_encoder_helper_wait_event_timeout(int32_t drm_id,
u32 irq_idx, struct dpu_encoder_wait_info *info);

 int dpu_encoder_helper_wait_for_irq(struct dpu_encoder_phys *phys_enc,
-   enum dpu_intr_idx intr_idx,
+   int irq_idx, void (*irq_cb)(void *, int),
struct dpu_encoder_wait_info *wait_info)
 {
-   struct dpu_encoder_irq *irq;
u32 irq_status;
int ret;

-   if (!wait_info || intr_idx >= INTR_IDX_MAX) {
+   if (!wait_info || irq_idx < 0) {
DPU_ERROR("invalid params\n");
return -EINVAL;
}
-   irq = _enc->irq[intr_idx];

/* note: do master / slave checking outside */

/* return EWOULDBLOCK since we know the wait isn't necessary */
if (phys_enc->enable_state == DPU_ENC_DISABLED) {
-   DRM_ERROR("encoder is disabled id=%u, intr=%d, irq=%d",
- DRMID(phys_enc->parent), intr_idx,
- irq->irq_idx);
+   DRM_ERROR("encoder is disabled id=%u, irq=%d",
+ DRMID(phys_enc->parent), irq_idx);
return -EWOULDBLOCK;
}

-   if (irq->irq_idx < 0) {
-   DRM_DEBUG_KMS("skip irq wait id=%u, intr=%d, irq=%s",
- DRMID(phys_enc->parent), intr_idx,
- irq->name);
+   if (irq_idx < 0) {
+   DRM_DEBUG_KMS("skip irq wait id=%u", DRMID(phys_enc->parent));
return 0;
}

-   DRM_DEBUG_KMS("id=%u, intr=%d, irq=%d, pp=%d, pending_cnt=%d",
- DRMID(phys_enc->parent), intr_idx,
- irq->irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
+   DRM_DEBUG_KMS("id=%u, irq=%d, pp=%d, pending_cnt=%d",
+ DRMID(phys_enc->parent),
+ irq_idx, phys_enc->hw_pp->idx - PINGPONG_0,
  atomic_read(wait_info->atomic_cnt));

ret = dpu_encoder_helper_wait_event_timeout(
DRMID(phys_enc->parent),
-   irq->irq_idx,
+   irq_idx,
wait_info);

if (ret <= 0) {
irq_status = dpu_core_irq_read(phys_enc->dpu_kms,
-   irq->irq_idx, true);
+   irq_idx, true);
if (irq_status) {
unsigned long flags;

-   DRM_DEBUG_KMS("irq not triggered id=%u, intr=%d, "
+   DRM_DEBUG_KMS("irq not triggered id=%u, "
  "irq=%d, pp=%d, atomic_cnt=%d",
- DRMID(phys_enc->parent), intr_idx,
- irq->irq_idx,
+ DRMID(phys_enc->parent),
+ irq_idx,
  phys_enc->hw_pp->idx - PINGPONG_0,
  atomic_read(wait_info->atomic_cnt));
local_irq_save(flags);
-   irq->func(phys_enc, 

Re: [Freedreno] [PATCH v2 6/7] drm/msm/dpu: get rid of dpu_encoder_helper_(un)register_irq

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

Get rid of dpu_encoder_helper_register_irq/unregister_irq helpers, call
dpu_core_register/unregister_callback directly, without surrounding 
them

with helpers.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   | 64 ---
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  | 18 --
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 39 +++
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  | 21 --
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  4 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 29 +++--
 6 files changed, 56 insertions(+), 119 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index d3557b0f4db9..3d8864df8605 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -333,70 +333,6 @@ int dpu_encoder_helper_wait_for_irq(struct
dpu_encoder_phys *phys_enc,
return ret;
 }

-int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
-   enum dpu_intr_idx intr_idx)
-{
-   struct dpu_encoder_irq *irq;
-   int ret = 0;
-
-   if (intr_idx >= INTR_IDX_MAX) {
-   DPU_ERROR("invalid params\n");
-   return -EINVAL;
-   }
-   irq = _enc->irq[intr_idx];
-
-   if (irq->irq_idx < 0) {
-   DPU_ERROR_PHYS(phys_enc,
-   "invalid IRQ index:%d\n", irq->irq_idx);
-   return -EINVAL;
-   }
-
-   ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, irq->irq_idx,
-   irq->func, phys_enc);
-   if (ret) {
-   DPU_ERROR_PHYS(phys_enc,
-   "failed to register IRQ callback for %s\n",
-   irq->name);
-   irq->irq_idx = -EINVAL;
-   return ret;
-   }
-
-   trace_dpu_enc_irq_register_success(DRMID(phys_enc->parent), intr_idx,
-   irq->irq_idx);
-
-   return ret;
-}
-
-int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys 
*phys_enc,

-   enum dpu_intr_idx intr_idx)
-{
-   struct dpu_encoder_irq *irq;
-   int ret;
-
-   irq = _enc->irq[intr_idx];
-
-   /* silently skip irqs that weren't registered */
-   if (irq->irq_idx < 0) {
-   DRM_ERROR("duplicate unregister id=%u, intr=%d, irq=%d",
- DRMID(phys_enc->parent), intr_idx,
- irq->irq_idx);
-   return 0;
-   }
-
-	ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, 
irq->irq_idx,

-   irq->func, phys_enc);
-   if (ret) {
-   DRM_ERROR("unreg cb fail id=%u, intr=%d, irq=%d ret=%d",
- DRMID(phys_enc->parent), intr_idx,
- irq->irq_idx, ret);
-   }
-
-	trace_dpu_enc_irq_unregister_success(DRMID(phys_enc->parent), 
intr_idx,

-irq->irq_idx);
-
-   return 0;
-}
-
 int dpu_encoder_get_frame_count(struct drm_encoder *drm_enc)
 {
struct dpu_encoder_virt *dpu_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 80d87871fd94..ff2218155b44 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -364,22 +364,4 @@ int dpu_encoder_helper_wait_for_irq(struct
dpu_encoder_phys *phys_enc,
enum dpu_intr_idx intr_idx,
struct dpu_encoder_wait_info *wait_info);

-/**
- * dpu_encoder_helper_register_irq - register and enable an irq
- * @phys_enc: Pointer to physical encoder structure
- * @intr_idx: encoder interrupt index
- * @Return: 0 or -ERROR
- */
-int dpu_encoder_helper_register_irq(struct dpu_encoder_phys *phys_enc,
-   enum dpu_intr_idx intr_idx);
-
-/**
- * dpu_encoder_helper_unregister_irq - unregister and disable an irq
- * @phys_enc: Pointer to physical encoder structure
- * @intr_idx: encoder interrupt index
- * @Return: 0 or -ERROR
- */
-int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys 
*phys_enc,

-   enum dpu_intr_idx intr_idx);
-
 #endif /* __dpu_encoder_phys_H__ */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index f921a5c99456..4bfeac821f51 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -211,7 +211,9 @@ static int 
_dpu_encoder_phys_cmd_handle_ppdone_timeout(

  cmd_enc->pp_timeout_report_cnt,
  atomic_read(_enc->pending_kickoff_cnt));
msm_disp_snapshot_state(drm_enc->dev);
-   dpu_encoder_helper_unregister_irq(phys_enc, INTR_IDX_RDPTR);
+   

Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: remove extra wrappers around dpu_core_irq

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:
Remove extra dpu_irq_* wrappers from dpu_kms.c, merge them directly 
into

dpu_core_irq_* functions.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h  | 12 -
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  9 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 27 +++
 3 files changed, 15 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
index 44ab97fb2964..afc8cd546368 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
@@ -10,24 +10,24 @@

 /**
  * dpu_core_irq_preinstall - perform pre-installation of core IRQ 
handler

- * @dpu_kms:   DPU handle
+ * @kms:   MSM KMS handle
  * @return:none
  */
-void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms);
+void dpu_core_irq_preinstall(struct msm_kms *kms);

 /**
  * dpu_core_irq_uninstall - uninstall core IRQ handler
- * @dpu_kms:   DPU handle
+ * @kms:   MSM KMS handle
  * @return:none
  */
-void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms);
+void dpu_core_irq_uninstall(struct msm_kms *kms);

 /**
  * dpu_core_irq - core IRQ handler
- * @dpu_kms:   DPU handle
+ * @kms:   MSM KMS handle
  * @return:interrupt handling status
  */
-irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms);
+irqreturn_t dpu_core_irq(struct msm_kms *kms);

 /**
  * dpu_core_irq_read - IRQ helper function for reading IRQ status
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 7062e7f0e860..9b74cfdf5355 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -140,8 +140,9 @@ static void dpu_core_irq_callback_handler(struct
dpu_kms *dpu_kms, int irq_idx)


dpu_kms->hw_intr->irq_tbl[irq_idx].cb(dpu_kms->hw_intr->irq_tbl[irq_idx].arg,
irq_idx);
 }

-irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms)
+irqreturn_t dpu_core_irq(struct msm_kms *kms)
 {
+   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
struct dpu_hw_intr *intr = dpu_kms->hw_intr;
int reg_idx;
int irq_idx;
@@ -526,8 +527,9 @@ void dpu_debugfs_core_irq_init(struct dpu_kms 
*dpu_kms,

 }
 #endif

-void dpu_core_irq_preinstall(struct dpu_kms *dpu_kms)
+void dpu_core_irq_preinstall(struct msm_kms *kms)
 {
+   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
int i;

pm_runtime_get_sync(_kms->pdev->dev);
@@ -539,8 +541,9 @@ void dpu_core_irq_preinstall(struct dpu_kms 
*dpu_kms)

atomic_set(_kms->hw_intr->irq_tbl[i].count, 0);
 }

-void dpu_core_irq_uninstall(struct dpu_kms *dpu_kms)
+void dpu_core_irq_uninstall(struct msm_kms *kms)
 {
+   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
int i;

pm_runtime_get_sync(_kms->pdev->dev);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 1d3a4f395e74..c1706205a514 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -761,20 +761,6 @@ static void _dpu_kms_set_encoder_mode(struct 
msm_kms *kms,

encoder->base.id, rc);
 }

-static irqreturn_t dpu_irq(struct msm_kms *kms)
-{
-   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-
-   return dpu_core_irq(dpu_kms);
-}
-
-static void dpu_irq_preinstall(struct msm_kms *kms)
-{
-   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-
-   dpu_core_irq_preinstall(dpu_kms);
-}
-
 static int dpu_irq_postinstall(struct msm_kms *kms)
 {
struct msm_drm_private *priv;
@@ -792,13 +778,6 @@ static int dpu_irq_postinstall(struct msm_kms 
*kms)

return 0;
 }

-static void dpu_irq_uninstall(struct msm_kms *kms)
-{
-   struct dpu_kms *dpu_kms = to_dpu_kms(kms);
-
-   dpu_core_irq_uninstall(dpu_kms);
-}
-
 static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state,
struct msm_kms *kms)
 {
int i;
@@ -846,10 +825,10 @@ static void dpu_kms_mdp_snapshot(struct
msm_disp_state *disp_state, struct msm_k

 static const struct msm_kms_funcs kms_funcs = {
.hw_init = dpu_kms_hw_init,
-   .irq_preinstall  = dpu_irq_preinstall,
+   .irq_preinstall  = dpu_core_irq_preinstall,
.irq_postinstall = dpu_irq_postinstall,
-   .irq_uninstall   = dpu_irq_uninstall,
-   .irq = dpu_irq,
+   .irq_uninstall   = dpu_core_irq_uninstall,
+   .irq = dpu_core_irq,
.enable_commit   = dpu_kms_enable_commit,
.disable_commit  = dpu_kms_disable_commit,
.vsync_time  = dpu_kms_vsync_time,


Re: [Freedreno] [PATCH v2 4/7] drm/msm/dpu: allow just single IRQ callback

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

DPU interrupts code allows multiple callbacks per interrut. In reality

/interrupt
none of the interrupts is shared between blocks (and will probably 
never

be). Drop support for registering multiple callbacks per interrupt to
simplify interrupt handling code.

Signed-off-by: Dmitry Baryshkov 


I need to check on why we had this design originally and we still do.
the idx with which we are registering today can generate only one hw 
interrupt.
But i am not sure if something for planned for future use. Will update 
in a day or two.


meanwhile some comments and questions below.


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h  |  18 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |   6 +-
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |   2 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  10 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_vid.c  |   6 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 144 +++---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  12 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  12 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  10 +-
 9 files changed, 86 insertions(+), 134 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
index 90ae6c9ccc95..44ab97fb2964 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.h
@@ -46,10 +46,8 @@ u32 dpu_core_irq_read(
  * interrupt
  * @dpu_kms:   DPU handle
  * @irq_idx:   irq index
- * @irq_cb:IRQ callback structure, containing callback function
- * and argument. Passing NULL for irq_cb will unregister
- * the callback for the given irq_idx
- * This must exist until un-registration.
+ * @irq_cb:IRQ callback funcion.
+ * @irq_arg:   IRQ callback argument.
  * @return:0 for success registering callback, otherwise failure
  *
  * This function supports registration of multiple callbacks for each
interrupt.
@@ -57,17 +55,16 @@ u32 dpu_core_irq_read(
 int dpu_core_irq_register_callback(
struct dpu_kms *dpu_kms,
int irq_idx,
-   struct dpu_irq_callback *irq_cb);
+   void (*irq_cb)(void *arg, int irq_idx),
+   void *irq_arg);

 /**
  * dpu_core_irq_unregister_callback - For unregistering callback
function on IRQ
  * interrupt
  * @dpu_kms:   DPU handle
  * @irq_idx:   irq index
- * @irq_cb:IRQ callback structure, containing callback function
- * and argument. Passing NULL for irq_cb will unregister
- * the callback for the given irq_idx
- * This must match with registration.
+ * @irq_cb:IRQ callback funcion.

/function
this typo is there in multiple places

+ * @irq_arg:   IRQ callback argument.
  * @return:0 for success registering callback, otherwise failure
  *
  * This function supports registration of multiple callbacks for each
interrupt.
@@ -75,7 +72,8 @@ int dpu_core_irq_register_callback(
 int dpu_core_irq_unregister_callback(
struct dpu_kms *dpu_kms,
int irq_idx,
-   struct dpu_irq_callback *irq_cb);
+   void (*irq_cb)(void *arg, int irq_idx),
+   void *irq_arg);

 /**
  * dpu_debugfs_core_irq_init - register core irq debugfs
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1c04b7cce43e..d3557b0f4db9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -310,7 +310,7 @@ int dpu_encoder_helper_wait_for_irq(struct
dpu_encoder_phys *phys_enc,
  phys_enc->hw_pp->idx - PINGPONG_0,
  atomic_read(wait_info->atomic_cnt));
local_irq_save(flags);
-   irq->cb.func(phys_enc, irq->irq_idx);
+   irq->func(phys_enc, irq->irq_idx);
local_irq_restore(flags);
ret = 0;
} else {
@@ -352,7 +352,7 @@ int dpu_encoder_helper_register_irq(struct
dpu_encoder_phys *phys_enc,
}

ret = dpu_core_irq_register_callback(phys_enc->dpu_kms, irq->irq_idx,
-   >cb);
+   irq->func, phys_enc);
if (ret) {
DPU_ERROR_PHYS(phys_enc,
"failed to register IRQ callback for %s\n",
@@ -384,7 +384,7 @@ int dpu_encoder_helper_unregister_irq(struct
dpu_encoder_phys *phys_enc,
}

 	ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms, 
irq->irq_idx,

-   >cb);
+   irq->func, phys_enc);
if (ret) {
   

Re: [Freedreno] [PATCH v2 3/7] drm/msm/dpu: merge struct dpu_irq into struct dpu_hw_intr

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

As dpu_core_irq was merged into dpu_hw_intr, merge data structures too,
removing the need for a separate data structure.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 51 +--
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  5 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   | 13 -
 3 files changed, 28 insertions(+), 41 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 28e9b0d448db..d2b6dca487e3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -127,20 +127,19 @@ static const struct dpu_intr_reg dpu_intr_set[] = 
{

  */
 static void dpu_core_irq_callback_handler(struct dpu_kms *dpu_kms, int 
irq_idx)

 {
-   struct dpu_irq *irq_obj = _kms->irq_obj;
struct dpu_irq_callback *cb;

VERB("irq_idx=%d\n", irq_idx);

-   if (list_empty(_obj->irq_cb_tbl[irq_idx]))
+   if (list_empty(_kms->hw_intr->irq_cb_tbl[irq_idx]))
DRM_ERROR("no registered cb, idx:%d\n", irq_idx);

-   atomic_inc(_obj->irq_counts[irq_idx]);
+   atomic_inc(_kms->hw_intr->irq_counts[irq_idx]);

/*
 * Perform registered function callback
 */
-   list_for_each_entry(cb, _obj->irq_cb_tbl[irq_idx], list)
+   list_for_each_entry(cb, _kms->hw_intr->irq_cb_tbl[irq_idx], list)
if (cb->func)
cb->func(cb->arg, irq_idx);
 }
@@ -420,6 +419,10 @@ void dpu_hw_intr_destroy(struct dpu_hw_intr *intr)
 {
if (intr) {
kfree(intr->cache_irq_mask);
+
+   kfree(intr->irq_cb_tbl);
+   kfree(intr->irq_counts);
+
kfree(intr);
}
 }
@@ -429,7 +432,7 @@ int dpu_core_irq_register_callback(struct dpu_kms
*dpu_kms, int irq_idx,
 {
unsigned long irq_flags;

-   if (!dpu_kms->irq_obj.irq_cb_tbl) {
+   if (!dpu_kms->hw_intr->irq_cb_tbl) {
DPU_ERROR("invalid params\n");
return -EINVAL;
}
@@ -453,9 +456,9 @@ int dpu_core_irq_register_callback(struct dpu_kms
*dpu_kms, int irq_idx,
trace_dpu_core_irq_register_callback(irq_idx, register_irq_cb);
list_del_init(_irq_cb->list);
list_add_tail(_irq_cb->list,
-   _kms->irq_obj.irq_cb_tbl[irq_idx]);
+   _kms->hw_intr->irq_cb_tbl[irq_idx]);
if (list_is_first(_irq_cb->list,
-   _kms->irq_obj.irq_cb_tbl[irq_idx])) {
+   _kms->hw_intr->irq_cb_tbl[irq_idx])) {
int ret = dpu_hw_intr_enable_irq_locked(
dpu_kms->hw_intr,
irq_idx);
@@ -473,7 +476,7 @@ int dpu_core_irq_unregister_callback(struct
dpu_kms *dpu_kms, int irq_idx,
 {
unsigned long irq_flags;

-   if (!dpu_kms->irq_obj.irq_cb_tbl) {
+   if (!dpu_kms->hw_intr->irq_cb_tbl) {
DPU_ERROR("invalid params\n");
return -EINVAL;
}
@@ -497,7 +500,7 @@ int dpu_core_irq_unregister_callback(struct
dpu_kms *dpu_kms, int irq_idx,
trace_dpu_core_irq_unregister_callback(irq_idx, register_irq_cb);
list_del_init(_irq_cb->list);
/* empty callback list but interrupt is still enabled */
-   if (list_empty(_kms->irq_obj.irq_cb_tbl[irq_idx])) {
+   if (list_empty(_kms->hw_intr->irq_cb_tbl[irq_idx])) {
int ret = dpu_hw_intr_disable_irq_locked(
dpu_kms->hw_intr,
irq_idx);
@@ -515,19 +518,18 @@ int dpu_core_irq_unregister_callback(struct
dpu_kms *dpu_kms, int irq_idx,
 static int dpu_debugfs_core_irq_show(struct seq_file *s, void *v)
 {
struct dpu_kms *dpu_kms = s->private;
-   struct dpu_irq *irq_obj = _kms->irq_obj;
struct dpu_irq_callback *cb;
unsigned long irq_flags;
int i, irq_count, cb_count;

-   if (WARN_ON(!irq_obj->irq_cb_tbl))
+   if (WARN_ON(!dpu_kms->hw_intr->irq_cb_tbl))
return 0;

-   for (i = 0; i < irq_obj->total_irqs; i++) {
+   for (i = 0; i < dpu_kms->hw_intr->total_irqs; i++) {
spin_lock_irqsave(_kms->hw_intr->irq_lock, irq_flags);
cb_count = 0;
-   irq_count = atomic_read(_obj->irq_counts[i]);
-   list_for_each_entry(cb, _obj->irq_cb_tbl[i], list)
+   irq_count = atomic_read(_kms->hw_intr->irq_counts[i]);
+   list_for_each_entry(cb, _kms->hw_intr->irq_cb_tbl[i], list)
cb_count++;
spin_unlock_irqrestore(_kms->hw_intr->irq_lock, irq_flags);

@@ -559,14 +561,13 @@ void dpu_core_irq_preinstall(struct dpu_kms 
*dpu_kms)

pm_runtime_put_sync(_kms->pdev->dev);

/* Create irq callbacks for all possible irq_idx */

Re: [Freedreno] [PATCH v2 2/7] drm/msm/dpu: don't clear IRQ register twice

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

We already clear the IRQ status register before processing IRQs, so do
not clear the register again. Especially do not clear the IRQ status
_after_ processing the IRQ as this way we can loose the event.

Signed-off-by: Dmitry Baryshkov 

Reviewed-by: Abhinav Kumar 

---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c   | 17 -
 1 file changed, 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index 2437b0c7c073..28e9b0d448db 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -120,21 +120,6 @@ static const struct dpu_intr_reg dpu_intr_set[] = 
{

 #define DPU_IRQ_REG(irq_idx)   (irq_idx / 32)
 #define DPU_IRQ_MASK(irq_idx)  (BIT(irq_idx % 32))

-static void dpu_hw_intr_clear_intr_status_nolock(struct dpu_hw_intr 
*intr,

-   int irq_idx)
-{
-   int reg_idx;
-
-   if (!intr)
-   return;
-
-   reg_idx = DPU_IRQ_REG(irq_idx);
-   DPU_REG_WRITE(>hw, dpu_intr_set[reg_idx].clr_off,
DPU_IRQ_MASK(irq_idx));
-
-   /* ensure register writes go through */
-   wmb();
-}
-
 /**
  * dpu_core_irq_callback_handler - dispatch core interrupts
  * @arg:   private data of callback handler
@@ -203,8 +188,6 @@ irqreturn_t dpu_core_irq(struct dpu_kms *dpu_kms)

dpu_core_irq_callback_handler(dpu_kms, irq_idx);

-   dpu_hw_intr_clear_intr_status_nolock(intr, irq_idx);
-
/*
 * When callback finish, clear the irq_status
 * with the matching mask. Once irq_status


Re: [Freedreno] [PATCH v2 1/7] drm/msm/dpu: squash dpu_core_irq into dpu_hw_interrupts

2021-08-17 Thread abhinavk

On 2021-06-17 15:20, Dmitry Baryshkov wrote:

With dpu_core_irq being the wrapper around dpu_hw_interrupts, there is
little sense in having them separate. Squash them together to remove
another layer of abstraction (hw_intr ops).

Signed-off-by: Dmitry Baryshkov 

Overall, I think this is a reasonable cleanup,
Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/Makefile  |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c  | 256 -
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 269 ++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  87 --
 4 files changed, 214 insertions(+), 399 deletions(-)
 delete mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c

diff --git a/drivers/gpu/drm/msm/Makefile 
b/drivers/gpu/drm/msm/Makefile

index 2c00aa70b708..a5245e8d0f14 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -51,7 +51,6 @@ msm-y := \
disp/mdp5/mdp5_mixer.o \
disp/mdp5/mdp5_plane.o \
disp/mdp5/mdp5_smp.o \
-   disp/dpu1/dpu_core_irq.o \
disp/dpu1/dpu_core_perf.o \
disp/dpu1/dpu_crtc.o \
disp/dpu1/dpu_encoder.o \
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
deleted file mode 100644
index d2457490930b..
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_irq.c
+++ /dev/null
@@ -1,256 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- */
-
-#define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__
-
-#include 
-#include 
-#include 
-#include 
-
-#include "dpu_core_irq.h"
-#include "dpu_trace.h"
-
-/**
- * dpu_core_irq_callback_handler - dispatch core interrupts
- * @arg:   private data of callback handler
- * @irq_idx:   interrupt index
- */
-static void dpu_core_irq_callback_handler(void *arg, int irq_idx)
-{
-   struct dpu_kms *dpu_kms = arg;
-   struct dpu_irq *irq_obj = _kms->irq_obj;
-   struct dpu_irq_callback *cb;
-
-   VERB("irq_idx=%d\n", irq_idx);
-
-   if (list_empty(_obj->irq_cb_tbl[irq_idx]))
-   DRM_ERROR("no registered cb, idx:%d\n", irq_idx);
-
-   atomic_inc(_obj->irq_counts[irq_idx]);
-
-   /*
-* Perform registered function callback
-*/
-   list_for_each_entry(cb, _obj->irq_cb_tbl[irq_idx], list)
-   if (cb->func)
-   cb->func(cb->arg, irq_idx);
-}
-
-u32 dpu_core_irq_read(struct dpu_kms *dpu_kms, int irq_idx, bool 
clear)

-{
-   if (!dpu_kms->hw_intr ||
-   !dpu_kms->hw_intr->ops.get_interrupt_status)
-   return 0;
-
-   if (irq_idx < 0) {
-   DPU_ERROR("[%pS] invalid irq_idx=%d\n",
-   __builtin_return_address(0), irq_idx);
-   return 0;
-   }
-
-   return dpu_kms->hw_intr->ops.get_interrupt_status(dpu_kms->hw_intr,
-   irq_idx, clear);
-}
-
-int dpu_core_irq_register_callback(struct dpu_kms *dpu_kms, int 
irq_idx,

-   struct dpu_irq_callback *register_irq_cb)
-{
-   unsigned long irq_flags;
-
-   if (!dpu_kms->irq_obj.irq_cb_tbl) {
-   DPU_ERROR("invalid params\n");
-   return -EINVAL;
-   }
-
-   if (!register_irq_cb || !register_irq_cb->func) {
-   DPU_ERROR("invalid irq_cb:%d func:%d\n",
-   register_irq_cb != NULL,
-   register_irq_cb ?
-   register_irq_cb->func != NULL : -1);
-   return -EINVAL;
-   }
-
-   if (irq_idx < 0 || irq_idx >= dpu_kms->hw_intr->total_irqs) {
-   DPU_ERROR("invalid IRQ index: [%d]\n", irq_idx);
-   return -EINVAL;
-   }
-
-   VERB("[%pS] irq_idx=%d\n", __builtin_return_address(0), irq_idx);
-
-   irq_flags = dpu_kms->hw_intr->ops.lock(dpu_kms->hw_intr);
-   trace_dpu_core_irq_register_callback(irq_idx, register_irq_cb);
-   list_del_init(_irq_cb->list);
-   list_add_tail(_irq_cb->list,
-   _kms->irq_obj.irq_cb_tbl[irq_idx]);
-   if (list_is_first(_irq_cb->list,
-   _kms->irq_obj.irq_cb_tbl[irq_idx])) {
-   int ret = dpu_kms->hw_intr->ops.enable_irq_locked(
-   dpu_kms->hw_intr,
-   irq_idx);
-   if (ret)
-   DPU_ERROR("Fail to enable IRQ for irq_idx:%d\n",
-   irq_idx);
-   }
-   dpu_kms->hw_intr->ops.unlock(dpu_kms->hw_intr, irq_flags);
-
-   return 0;
-}
-
-int dpu_core_irq_unregister_callback(struct dpu_kms *dpu_kms, int 
irq_idx,

-   struct dpu_irq_callback *register_irq_cb)
-{
-   unsigned long irq_flags;
-
-   if (!dpu_kms->irq_obj.irq_cb_tbl) {
-   DPU_ERROR("invalid params\n");
-   return 

Re: [Freedreno] [PATCH] drm/msm/dpu: add support for alpha blending properties

2021-08-17 Thread abhinavk

On 2021-06-28 12:19, Dmitry Baryshkov wrote:

Add support for alpha blending properties. Setup the plane blend state
according to those properties.

Signed-off-by: Dmitry Baryshkov 


I think this has already been picked up by Rob but just had a couple of 
comments

below.

Also, how has this been validated? On RB boards i dont think all the 
paths get

executed.


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 43 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 10 --
 2 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 9a5c70c87cc8..768012243b44 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -30,12 +30,6 @@
 #include "dpu_core_perf.h"
 #include "dpu_trace.h"

-#define DPU_DRM_BLEND_OP_NOT_DEFINED0
-#define DPU_DRM_BLEND_OP_OPAQUE 1
-#define DPU_DRM_BLEND_OP_PREMULTIPLIED  2
-#define DPU_DRM_BLEND_OP_COVERAGE   3
-#define DPU_DRM_BLEND_OP_MAX4
-
 /* layer mixer index on dpu_crtc */
 #define LEFT_MIXER 0
 #define RIGHT_MIXER 1
@@ -146,20 +140,43 @@ static void _dpu_crtc_setup_blend_cfg(struct
dpu_crtc_mixer *mixer,
 {
struct dpu_hw_mixer *lm = mixer->hw_lm;
uint32_t blend_op;
+   uint32_t fg_alpha, bg_alpha;

-   /* default to opaque blending */
-   blend_op = DPU_BLEND_FG_ALPHA_FG_CONST |
-   DPU_BLEND_BG_ALPHA_BG_CONST;
+   fg_alpha = pstate->base.alpha >> 8;
+   bg_alpha = 0xff - fg_alpha;

-   if (format->alpha_enable) {
+   /* default to opaque blending */
+   if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PIXEL_NONE ||
+   !format->alpha_enable) {
+   blend_op = DPU_BLEND_FG_ALPHA_FG_CONST |
+   DPU_BLEND_BG_ALPHA_BG_CONST;
+	} else if (pstate->base.pixel_blend_mode == DRM_MODE_BLEND_PREMULTI) 
{

+   blend_op = DPU_BLEND_FG_ALPHA_FG_CONST |
+   DPU_BLEND_BG_ALPHA_FG_PIXEL;
+   if (fg_alpha != 0xff) {
+   bg_alpha = fg_alpha;
+   blend_op |= DPU_BLEND_BG_MOD_ALPHA |
+   DPU_BLEND_BG_INV_MOD_ALPHA;
+   } else {
+   blend_op |= DPU_BLEND_BG_INV_ALPHA;
+   }
+   } else {
/* coverage blending */
blend_op = DPU_BLEND_FG_ALPHA_FG_PIXEL |
-   DPU_BLEND_BG_ALPHA_FG_PIXEL |
-   DPU_BLEND_BG_INV_ALPHA;
+   DPU_BLEND_BG_ALPHA_FG_PIXEL;
+   if (fg_alpha != 0xff) {
+   bg_alpha = fg_alpha;
+   blend_op |= DPU_BLEND_FG_MOD_ALPHA |
+   DPU_BLEND_FG_INV_MOD_ALPHA |
comparing this with the blend rule downstream, is this inversion 
necessary?

I only see below rule downstream:

628 if (fg_alpha != 0xff) {
629 bg_alpha = fg_alpha;
630 blend_op |= SDE_BLEND_FG_MOD_ALPHA |
631 SDE_BLEND_BG_MOD_ALPHA |
632 SDE_BLEND_BG_INV_MOD_ALPHA;


+   DPU_BLEND_BG_MOD_ALPHA |
+   DPU_BLEND_BG_INV_MOD_ALPHA;
+   } else {
+   blend_op |= DPU_BLEND_BG_INV_ALPHA;
+   }
}

lm->ops.setup_blend_config(lm, pstate->stage,
-   0xFF, 0, blend_op);
+   fg_alpha, bg_alpha, blend_op);

DRM_DEBUG_ATOMIC("format:%p4cc, alpha_en:%u blend_op:0x%x\n",
  >base.pixel_format, format->alpha_enable, blend_op);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ec4a6f04394a..c989621209aa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1339,9 +1339,7 @@ static void dpu_plane_reset(struct drm_plane 
*plane)

return;
}

-   pstate->base.plane = plane;
-
-   plane->state = >base;
+   __drm_atomic_helper_plane_reset(plane, >base);
 }

 #ifdef CONFIG_DEBUG_FS
@@ -1647,6 +1645,12 @@ struct drm_plane *dpu_plane_init(struct 
drm_device *dev,

if (ret)
DPU_ERROR("failed to install zpos property, rc = %d\n", ret);

+   drm_plane_create_alpha_property(plane);
+   drm_plane_create_blend_mode_property(plane,
+   BIT(DRM_MODE_BLEND_PIXEL_NONE) |
+   BIT(DRM_MODE_BLEND_PREMULTI) |
+   BIT(DRM_MODE_BLEND_COVERAGE));
+
drm_plane_create_rotation_property(plane,
DRM_MODE_ROTATE_0,
DRM_MODE_ROTATE_0 |


Re: [PATCH v5] drm/msm/dsi: add continuous clock support for 7nm PHY

2021-08-10 Thread abhinavk

On 2021-08-05 10:08, Dmitry Baryshkov wrote:

Unlike previous generations, 7nm PHYs are required to collaborate with
the host for conitnuos clock mode. Add changes neccessary to enable

/continuous
/necessary

continuous clock mode in the 7nm DSI PHYs.

Signed-off-by: Dmitry Baryshkov 
---
Changes since v4:
 - Fix the comment regarding msm_dsi_phy_set_continuous_clock()

Changes since v3:
 - Invert the DSI_LANE_CTRL_HS_REQ_SEL_PHY bit logic, as noted by
   Abhinav.

Changes since v2:
 - Really drop msm_dsi_phy_needs_hs_phy_sel()

Changes since v1:
 - Remove the need for a separate msm_dsi_phy_needs_hs_phy_sel() call
 - Fix setting continuous clock for a dual DSI case.
---
 drivers/gpu/drm/msm/dsi/dsi.h |  3 ++-
 drivers/gpu/drm/msm/dsi/dsi.xml.h |  1 +
 drivers/gpu/drm/msm/dsi/dsi_host.c| 12 
 drivers/gpu/drm/msm/dsi/dsi_manager.c |  4 ++--
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.c |  9 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy.h |  1 +
 drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 17 +
 7 files changed, 40 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.h 
b/drivers/gpu/drm/msm/dsi/dsi.h

index 9b8e9b07eced..58e63bf34fe9 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.h
@@ -109,7 +109,7 @@ int msm_dsi_host_enable(struct mipi_dsi_host 
*host);

 int msm_dsi_host_disable(struct mipi_dsi_host *host);
 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
struct msm_dsi_phy_shared_timings *phy_shared_timings,
-   bool is_dual_dsi);
+   bool is_dual_dsi, struct msm_dsi_phy *phy);
 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);
@@ -175,6 +175,7 @@ int msm_dsi_phy_get_clk_provider(struct msm_dsi_phy 
*phy,

 void msm_dsi_phy_pll_save_state(struct msm_dsi_phy *phy);
 int msm_dsi_phy_pll_restore_state(struct msm_dsi_phy *phy);
 void msm_dsi_phy_snapshot(struct msm_disp_state *disp_state, struct
msm_dsi_phy *phy);
+bool msm_dsi_phy_set_continuous_clock(struct msm_dsi_phy *phy, bool 
enable);


 #endif /* __DSI_CONNECTOR_H__ */

diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h
b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index eadbcc78fd72..473c81605054 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -518,6 +518,7 @@ static inline uint32_t
DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(uint32_t val)
 #define DSI_LANE_STATUS_DLN0_DIRECTION 0x0001

 #define REG_DSI_LANE_CTRL  0x00a8
+#define DSI_LANE_CTRL_HS_REQ_SEL_PHY   0x0100
 #define DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST   0x1000

 #define REG_DSI_LANE_SWAP_CTRL 0x00ac
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index ed504fe5074f..3558e5cd400f 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -834,7 +834,7 @@ static inline enum dsi_cmd_dst_format 
dsi_get_cmd_fmt(

 }

 static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool 
enable,

-   struct msm_dsi_phy_shared_timings *phy_shared_timings)
+   struct msm_dsi_phy_shared_timings *phy_shared_timings, 
struct
msm_dsi_phy *phy)
 {
u32 flags = msm_host->mode_flags;
enum mipi_dsi_pixel_format mipi_fmt = msm_host->format;
@@ -929,6 +929,10 @@ static void dsi_ctrl_config(struct msm_dsi_host
*msm_host, bool enable,

if (!(flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)) {
lane_ctrl = dsi_read(msm_host, REG_DSI_LANE_CTRL);
+
+   if (msm_dsi_phy_set_continuous_clock(phy, enable))
+   lane_ctrl &= ~DSI_LANE_CTRL_HS_REQ_SEL_PHY;
+
dsi_write(msm_host, REG_DSI_LANE_CTRL,
lane_ctrl | DSI_LANE_CTRL_CLKLN_HS_FORCE_REQUEST);
}


While checking downstream code and the HPG, the sequence seems to be to 
program ctrl bits first
and then the PHY bits. Here its reverse. I think it should still work 
but to maintain consistency,
can we change the order here to program controller first and then call 
msm_dsi_phy_set_continuous_clock?


Unrelated to this change itself but while reviewing the sequence, I just 
observed we never clear the continuous
clk bits during disable(). In other words the disable sequence just 
clears the controller and comes out.

As a follow up, I will plan to clean up this a bit.



@@ -2354,7 +2358,7 @@ static void msm_dsi_sfpb_config(struct
msm_dsi_host *msm_host, bool enable)

 int msm_dsi_host_power_on(struct mipi_dsi_host *host,
struct msm_dsi_phy_shared_timings *phy_shared_timings,
-   bool is_dual_dsi)
+   bool 

Re: [Freedreno] [PATCH] drm/msm/dsi: add support for dsi test pattern generator

2021-08-10 Thread abhinavk

Hi Marijn

Thanks for reviewing and testing the latest patchset.

On 2021-08-10 15:59, Marijn Suijten wrote:

Hi Abhinav,

On 7/16/21 2:01 AM, abhin...@codeaurora.org wrote:

Hi Marijn

Sorry for the late response.



Apologies from my side as well.

[...]


+static void msm_dsi_host_cmd_test_pattern_setup(struct msm_dsi_host
*msm_host)
+{
+   u32 reg;
+
+   reg = dsi_read(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL);
+
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CMD_MDP_INIT_VAL0,
0xff);
+
+   reg |= (0x3 << 0x8);
+   dsi_write(msm_host, REG_DSI_TEST_PATTERN_GEN_CTRL, reg);
+   /* draw checkered rectangle pattern */
+   dsi_write(msm_host, REG_DSI_TPG_MAIN_CONTROL2, (0x1 << 0x7));



How about BIT(7)?


You mean BIT(7) of REG_DSI_TPG_MAIN_CONTROL2? Thats what this is 
right?

Did you mean some other bit?



I meant to replace (0x1 << 0x7) with BIT(7), but replacing it with
DSI_TPG_MAIN_CONTROL2_CMD_MDP0_CHECKERED_RECTANGLE_PATTERN is even
better, thanks.





On SM6125 this seems to change the color intensity of the pattern; it
is always colored lines of a few pixels wide alternating R, B and G
from left to right.  Is it possible to document the meaning and
available values of these registers, especially if they differ 
between

SoC / DSI block?



I have requested access for SM6125, will check this register on that 
to

see if there
is any difference.

Are you saying you are not seeing a rectangular checkered pattern 
while

testing?



Correct.  It's fixed now, and this patch already proves its
usefulness!  We had two minor configuration issues, and are now seeing
the squares just like on the other SoCs.  Meaning we can finally move
on to configuring the DPU, thanks!



Thats good to know !


Also are you testing on command mode or video mode?



Command mode, if it's still worth anything.

Thats good to know too, as I had not been able to test command mode.



As requested by Rob, I will add the bit definitions and update the
dsi.xml.h in the
next patchset for the registers and the bits which I am using here.

With that the meaning of these bits will be more clear.

I dont think I will be able to document all the bits because the goal 
of

this patch
was only to draw a test pattern to help with validation. Different 
bits

of the REG_DSI_TPG_MAIN_CONTROL2
register only draw different patterns so the goal wasnt that we can 
draw

any pattern, it was just to
draw some pattern on the screen.

When we add support for all other patterns, we can expose those bits 
as

well but it should not
be required in my opinion.



Understandable.  I'm curious if other patterns are useful in certain
situations, like DSC?  Other than that, knowing that the DSI and PHY
is correct is good enough for us.


The TPG in this patch is only for the DSI block which is after the DSC 
block.
So any pattern we pick from the DSI_TPG_MAIN_CONTROL2 register (using 
any other bit)
will only look different visually but will still be from DSI and no 
other block.

So it will not help to validate DSC block individually.






Kind regards,
Marijn


+   DBG("Cmd test pattern setup done\n");
+}

[...]



Thanks!
Marijn


Re: [Freedreno] [PATCH v2 07/14] drm/msm: Convert to Linux IRQ interfaces

2021-08-03 Thread abhinavk

On 2021-08-03 02:06, Thomas Zimmermann wrote:

Drop the DRM IRQ midlayer in favor of Linux IRQ interfaces. DRM's
IRQ helpers are mostly useful for UMS drivers. Modern KMS drivers
don't benefit from using it.

DRM IRQ callbacks are now being called directly or inlined.

Signed-off-by: Thomas Zimmermann 

Reviewed-by: Abhinav Kumar 

---
 drivers/gpu/drm/msm/msm_drv.c | 113 --
 drivers/gpu/drm/msm/msm_kms.h |   2 +-
 2 files changed, 69 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_drv.c 
b/drivers/gpu/drm/msm/msm_drv.c

index 1594ae39d54f..a332b09a5a11 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -14,7 +14,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -201,6 +200,71 @@ void msm_rmw(void __iomem *addr, u32 mask, u32 or)
msm_writel(val | or, addr);
 }

+static irqreturn_t msm_irq(int irq, void *arg)
+{
+   struct drm_device *dev = arg;
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   BUG_ON(!kms);
+
+   if (kms->funcs->irq_postinstall)
+   return kms->funcs->irq_postinstall(kms);
+
+   return 0;
+}
+
+static int msm_irq_install(struct drm_device *dev, unsigned int irq)
+{
+   int ret;
+
+   if (irq == IRQ_NOTCONNECTED)
+   return -ENOTCONN;
+
+   msm_irq_preinstall(dev);
+
+   ret = request_irq(irq, msm_irq, 0, dev->driver->name, dev);
+   if (ret)
+   return ret;
+
+   ret = msm_irq_postinstall(dev);
+   if (ret) {
+   free_irq(irq, dev);
+   return ret;
+   }
+
+   return 0;
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+   struct msm_drm_private *priv = dev->dev_private;
+   struct msm_kms *kms = priv->kms;
+
+   kms->funcs->irq_uninstall(kms);
+   free_irq(kms->irq, dev);
+}
+
 struct msm_vblank_work {
struct work_struct work;
int crtc_id;
@@ -265,7 +329,7 @@ static int msm_drm_uninit(struct device *dev)
}

/* We must cancel and cleanup any pending vblank enable/disable
-* work before drm_irq_uninstall() to avoid work re-enabling an
+* work before msm_irq_uninstall() to avoid work re-enabling an
 * irq after uninstall has disabled it.
 */

@@ -294,7 +358,7 @@ static int msm_drm_uninit(struct device *dev)
drm_mode_config_cleanup(ddev);

pm_runtime_get_sync(dev);
-   drm_irq_uninstall(ddev);
+   msm_irq_uninstall(ddev);
pm_runtime_put_sync(dev);

if (kms && kms->funcs)
@@ -553,7 +617,7 @@ static int msm_drm_init(struct device *dev, const
struct drm_driver *drv)

if (kms) {
pm_runtime_get_sync(dev);
-   ret = drm_irq_install(ddev, kms->irq);
+   ret = msm_irq_install(ddev, kms->irq);
pm_runtime_put_sync(dev);
if (ret < 0) {
DRM_DEV_ERROR(dev, "failed to install IRQ handler\n");
@@ -662,43 +726,6 @@ static void msm_postclose(struct drm_device *dev,
struct drm_file *file)
context_close(ctx);
 }

-static irqreturn_t msm_irq(int irq, void *arg)
-{
-   struct drm_device *dev = arg;
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   return kms->funcs->irq(kms);
-}
-
-static void msm_irq_preinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_preinstall(kms);
-}
-
-static int msm_irq_postinstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-
-   if (kms->funcs->irq_postinstall)
-   return kms->funcs->irq_postinstall(kms);
-
-   return 0;
-}
-
-static void msm_irq_uninstall(struct drm_device *dev)
-{
-   struct msm_drm_private *priv = dev->dev_private;
-   struct msm_kms *kms = priv->kms;
-   BUG_ON(!kms);
-   kms->funcs->irq_uninstall(kms);
-}
-
 int msm_crtc_enable_vblank(struct drm_crtc *crtc)
 {
struct drm_device *dev = crtc->dev;
@@ -1051,10 +1078,6 @@ static const struct drm_driver msm_driver = {
.open   = msm_open,
.postclose   = msm_postclose,
.lastclose  = drm_fb_helper_lastclose,
-   .irq_handler= msm_irq,

Re: [Freedreno] [PATCH 11/11] drm/msm/dsi: Pass DSC params to drm_panel

2021-08-02 Thread abhinavk

On 2021-07-14 23:52, Vinod Koul wrote:

When DSC is enabled, we need to pass the DSC parameters to panel driver
as well, so add a dsc parameter in panel and set it when DSC is enabled

Signed-off-by: Vinod Koul 


based on the comments on prev patches in the series, this will need to 
be reworked

too as there wont be any priv->dsc anymore.

Also, can you also post the panel changes? Would like to see how you 
will use the

dsc param there.


---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 16 +++-
 include/drm/drm_panel.h|  7 +++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 4e8ab1b1df8b..ee21cda243a7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -2193,6 +2193,7 @@ int msm_dsi_host_modeset_init(struct 
mipi_dsi_host *host,

const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd;
struct platform_device *pdev = msm_host->pdev;
struct msm_drm_private *priv;
+   struct drm_panel *panel;
int ret;

msm_host->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
@@ -2212,8 +2213,21 @@ int msm_dsi_host_modeset_init(struct 
mipi_dsi_host *host,

}

msm_host->dev = dev;
+   panel = msm_dsi_host_get_panel(_host->base);
priv = dev->dev_private;
-   priv->dsc = msm_host->dsc;
+
+   if (panel && panel->dsc) {
+   struct msm_display_dsc_config *dsc = priv->dsc;
+
+   if (!dsc) {
+   dsc = kzalloc(sizeof(*dsc), GFP_KERNEL);
+   if (!dsc)
+   return -ENOMEM;
+   dsc->drm = panel->dsc;
+   priv->dsc = dsc;
+   msm_host->dsc = dsc;
+   }
+   }

ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K);
if (ret) {
diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h
index 33605c3f0eba..27a7808a29f2 100644
--- a/include/drm/drm_panel.h
+++ b/include/drm/drm_panel.h
@@ -171,6 +171,13 @@ struct drm_panel {
 * Panel entry in registry.
 */
struct list_head list;
+
+   /**
+* @dsc:
+*
+* Panel DSC pps payload to be sent
+*/
+   struct drm_dsc_config *dsc;
 };

 void drm_panel_init(struct drm_panel *panel, struct device *dev,


Re: [Freedreno] [PATCH 10/11] drm/msm/dsi: Add support for DSC configuration

2021-08-02 Thread abhinavk

On 2021-07-14 23:52, Vinod Koul wrote:

When DSC is enabled, we need to configure DSI registers accordingly and
configure the respective stream compression registers.

Add support to calculate the register setting based on DSC params and
timing information and configure these registers.

Signed-off-by: Vinod Koul 


same comments as dmitry on this one: 
https://patchwork.freedesktop.org/patch/444082/?series=90413=2

nothing more to add.


---
 drivers/gpu/drm/msm/dsi/dsi.xml.h  |  10 ++
 drivers/gpu/drm/msm/dsi/dsi_host.c | 142 +++--
 2 files changed, 142 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h
b/drivers/gpu/drm/msm/dsi/dsi.xml.h
index 50eb4d1b8fdd..b8e9e608abfc 100644
--- a/drivers/gpu/drm/msm/dsi/dsi.xml.h
+++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h
@@ -2310,4 +2310,14 @@ static inline uint32_t
REG_DSI_7nm_PHY_LN_TX_DCTRL(uint32_t i0) { return 0x0

 #define REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE  0x0260

+#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL0x029c
+
+#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2   0x02a0
+
+#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL  0x02a4
+
+#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 0x02a8
+
+#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3 0x02ac
+
 #endif /* DSI_XML */
diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index e1e5d91809b5..4e8ab1b1df8b 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -942,6 +942,26 @@ static void dsi_ctrl_config(struct msm_dsi_host
*msm_host, bool enable,
dsi_write(msm_host, REG_DSI_CTRL, data);
 }

+static int dsi_dsc_update_pic_dim(struct msm_display_dsc_config *dsc,
+ int pic_width, int pic_height)
+{
+   if (!dsc || !pic_width || !pic_height) {
+   pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n",
pic_width, pic_height);
+   return -EINVAL;
+   }
+
+   if ((pic_width % dsc->drm->slice_width) || (pic_height %
dsc->drm->slice_height)) {
+   pr_err("DSI: pic_dim %dx%d has to be multiple of slice %dx%d\n",
+		   pic_width, pic_height, dsc->drm->slice_width, 
dsc->drm->slice_height);

+   return -EINVAL;
+   }
+
+   dsc->drm->pic_width = pic_width;
+   dsc->drm->pic_height = pic_height;
+
+   return 0;
+}
+
 static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool 
is_dual_dsi)

 {
struct drm_display_mode *mode = msm_host->mode;
@@ -956,6 +976,7 @@ static void dsi_timing_setup(struct msm_dsi_host
*msm_host, bool is_dual_dsi)
u32 va_end = va_start + mode->vdisplay;
u32 hdisplay = mode->hdisplay;
u32 wc;
+   u32 data;

DBG("");

@@ -974,7 +995,73 @@ static void dsi_timing_setup(struct msm_dsi_host
*msm_host, bool is_dual_dsi)
hdisplay /= 2;
}

+   if (msm_host->dsc) {
+   struct msm_display_dsc_config *dsc = msm_host->dsc;
+
+   /* update dsc params with timing params */
+   dsi_dsc_update_pic_dim(dsc, mode->hdisplay, mode->vdisplay);
+   DBG("Mode Width- %d x Height %d\n", dsc->drm->pic_width,
dsc->drm->pic_height);
+
+   /* we do the calculations for dsc parameters here so that
+* panel can use these parameters
+*/
+   dsi_populate_dsc_params(dsc);
+
+   /* Divide the display by 3 but keep back/font porch and
+* pulse width same
+*/
+   h_total -= hdisplay;
+   hdisplay /= 3;
+   h_total += hdisplay;
+   ha_end = ha_start + hdisplay;
+   }
+
if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) {
+   if (msm_host->dsc) {
+   struct msm_display_dsc_config *dsc = msm_host->dsc;
+   u32 reg, intf_width, slice_per_intf, width;
+   u32 total_bytes_per_intf;
+
+   /* first calculate dsc parameters and then program
+* compress mode registers
+*/
+   intf_width = hdisplay;
+   slice_per_intf = DIV_ROUND_UP(intf_width, 
dsc->drm->slice_width);
+
+   /* If slice_count > slice_per_intf, then use 1
+* This can happen during partial update
+*/
+   dsc->drm->slice_count = 1;
+
+   dsc->bytes_in_slice = 
DIV_ROUND_UP(dsc->drm->slice_width * 8, 8);
+   total_bytes_per_intf = dsc->bytes_in_slice * 
slice_per_intf;
+
+   dsc->eol_byte_num = total_bytes_per_intf % 3;
+   dsc->pclk_per_line =  
DIV_ROUND_UP(total_bytes_per_intf, 3);
+ 

Re: [Freedreno] [PATCH 09/11] drm/msm/disp/dpu1: Add support for DSC in topology

2021-08-02 Thread abhinavk

On 2021-07-14 23:52, Vinod Koul wrote:

For DSC to work we typically need a 2,2,1 configuration. This should
suffice for resolutions upto 4k. For more resolutions like 8k this 
won't

work.

The topology information is provided by DTS so we try to deduce the
topology required for DSC.
Furthermore, we can use 1 DSC encoder in lesser resolutions, but that 
is

not power efficient according to Abhinav, it is better to use 2 mixers
as that will split width/2 and is proven to be power efficient.


I think now that we have added the technical reason of why it is better 
to use
2-2-1 ( using 2 LMs is better than one as it will half layer width), we 
can drop my name from the commit text

as it holds less value than the actual reason itself :)
You can still keep my signed-off and co-developed by tag



Also, the panel has been tested only with 2,2,1 configuration, so for
now we blindly create 2,2,1 topology when DSC is enabled

Co-developed-by: Abhinav Kumar 
Signed-off-by: Abhinav Kumar 
Signed-off-by: Vinod Koul 
---
Changes since RFC:
 - Add more details in changelog

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 41140b781e66..8f0a8bd9c8ff 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -573,6 +573,8 @@ static struct msm_display_topology 
dpu_encoder_get_topology(

struct drm_display_mode *mode)
 {
struct msm_display_topology topology = {0};
+   struct drm_encoder *drm_enc;
+   struct msm_drm_private *priv;
int i, intf_count = 0;

for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
@@ -607,8 +609,22 @@ static struct msm_display_topology
dpu_encoder_get_topology(
topology.num_enc = 0;
topology.num_intf = intf_count;

+   drm_enc = _enc->base;
+   priv = drm_enc->dev->dev_private;
+   if (priv && priv->dsc) {

if dsc is moved to the encoder, this will need to be changed too

+   /* In case of Display Stream Compression DSC, we would use
+* 2 encoders, 2 line mixers and 1 interface
+* this is power optimal and can drive upto (including) 4k
+* screens
+*/
+   topology.num_enc = 2;
+   topology.num_intf = 1;
+   topology.num_lm = 2;
+   }
+
return topology;
 }
+
 static int dpu_encoder_virt_atomic_check(
struct drm_encoder *drm_enc,
struct drm_crtc_state *crtc_state,


Re: [Freedreno] [PATCH 08/11] drm/msm/disp/dpu1: Add support for DSC in encoder

2021-08-02 Thread abhinavk

On 2021-07-14 23:52, Vinod Koul wrote:

When DSC is enabled in DT, we need to configure the encoder for DSC
configuration, calculate DSC parameters for the given timing.

This patch adds that support by adding dpu_encoder_prep_dsc() which is
invoked when DSC is enabled in DT
correct me if wrong but this commit text is not valid anymore in my 
opinion.
are there any params you are getting from DT now? I thought its all 
coming from the panel

driver directly.


Signed-off-by: Vinod Koul 
agree with dmitry's comment's 
https://patchwork.freedesktop.org/patch/444078/?series=90413=2


instead of dsc being part of priv->dsc it should be per encoder.

On top of his comment, I also think that like on the newer chipsets, 
moving the dsc related
encoder configuration to a dpu_encoder_dce.c will help for future 
expansion of other topologies

and also for other compression algorithms.


---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 142 +++-
 1 file changed, 141 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 8d942052db8a..41140b781e66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -21,12 +21,17 @@
 #include "dpu_hw_intf.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_dspp.h"
+#include "dpu_hw_dsc.h"
 #include "dpu_formats.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_crtc.h"
 #include "dpu_trace.h"
 #include "dpu_core_irq.h"

+#define DSC_MODE_SPLIT_PANEL   BIT(0)
+#define DSC_MODE_MULTIPLEX BIT(1)
+#define DSC_MODE_VIDEO BIT(2)
+
 #define DPU_DEBUG_ENC(e, fmt, ...) DPU_DEBUG("enc%d " fmt,\
(e) ? (e)->base.base.id : -1, ##__VA_ARGS__)

@@ -135,6 +140,7 @@ enum dpu_enc_rc_states {
  * @cur_slave: As above but for the slave encoder.
  * @hw_pp: Handle to the pingpong blocks used for the display. No.
  * pingpong blocks can be different than num_phys_encs.
+ * @hw_dsc Handle to the DSC blocks used for the display.
  * @intfs_swapped:	Whether or not the phys_enc interfaces have been 
swapped

  * for partial update right-only cases, such as pingpong
  * split where virtual pingpong does not generate IRQs
@@ -180,6 +186,7 @@ struct dpu_encoder_virt {
struct dpu_encoder_phys *cur_master;
struct dpu_encoder_phys *cur_slave;
struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
+   struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];

bool intfs_swapped;

@@ -1008,7 +1015,8 @@ static void dpu_encoder_virt_mode_set(struct
drm_encoder *drm_enc,
struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC];
struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL };
-   int num_lm, num_ctl, num_pp;
+   struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC];
+   int num_lm, num_ctl, num_pp, num_dsc;
int i, j;

if (!drm_enc) {
@@ -1061,11 +1069,16 @@ static void dpu_encoder_virt_mode_set(struct
drm_encoder *drm_enc,
dpu_rm_get_assigned_resources(_kms->rm, global_state,
drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp,
ARRAY_SIZE(hw_dspp));
+   num_dsc = dpu_rm_get_assigned_resources(_kms->rm, global_state,
+   drm_enc->base.id, DPU_HW_BLK_DSC, hw_dsc, ARRAY_SIZE(hw_dsc));

for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i])
: NULL;

+   for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+   dpu_enc->hw_dsc[i] = i < num_dsc ? to_dpu_hw_dsc(hw_dsc[i]) : 
NULL;
+
cstate = to_dpu_crtc_state(drm_crtc->state);

for (i = 0; i < num_lm; i++) {
@@ -1810,10 +1823,133 @@ static void
dpu_encoder_vsync_event_work_handler(struct kthread_work *work)
nsecs_to_jiffies(ktime_to_ns(wakeup_time)));
 }

+static void
+dpu_encoder_dsc_pclk_param_calc(struct msm_display_dsc_config *dsc, 
u32 width)

+{
+   int slice_count, slice_per_intf;
+   int bytes_in_slice, total_bytes_per_intf;
+
+   if (!dsc || !dsc->drm->slice_width || !dsc->drm->slice_count) {
+   DPU_ERROR("Invalid DSC/slices\n");
+   return;
+   }
+
+   slice_count = dsc->drm->slice_count;
+   slice_per_intf = DIV_ROUND_UP(width, dsc->drm->slice_width);
+
+   /*
+* If slice_count is greater than slice_per_intf then default to 1.
+* This can happen during partial update.
+*/
+   if (slice_count > slice_per_intf)
+   slice_count = 1;
+
+   bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width *
+ dsc->drm->bits_per_pixel, 8);
+   total_bytes_per_intf = bytes_in_slice * slice_per_intf;
+
+   dsc->eol_byte_num = 

Re: [Freedreno] [PATCH 07/11] drm/msm/disp/dpu1: Don't use DSC with mode_3d

2021-08-02 Thread abhinavk

On 2021-07-14 23:51, Vinod Koul wrote:

We cannot enable mode_3d when we are using the DSC. So pass
configuration to detect DSC is enabled and not enable mode_3d
when we are using DSC

We add a helper dpu_encoder_helper_get_dsc_mode() to detect dsc
enabled and pass this to .setup_intf_cfg()

This is not entirely correct. This is true only for the 2-2-1 topology 
you are using

on this panel.

When you are using 2-2-1, you are using 2 LMs, 2 DSCs and 1 DSI.
So 3D mux shouldnt be used.

If you are using something like 4-2-1 or 4-2-2, then you have 4LMs,
2 DSCs and 2/1 DSI.

Here you need the 3D mux to convert the data from 4LMs to 2 DSCs.

So please correct the commit text here and also add a check for the 
topology.



Signed-off-by: Vinod Koul 
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c |  2 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c   |  5 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h   |  2 ++
 4 files changed, 18 insertions(+), 2 deletions(-)

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 ecbc4be98980..d43b804528eb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -336,6 +336,17 @@ static inline enum dpu_3d_blend_mode
dpu_encoder_helper_get_3d_blend_mode(
return BLEND_3D_NONE;
 }

+static inline bool dpu_encoder_helper_get_dsc_mode(struct
dpu_encoder_phys *phys_enc)
+{
+   struct drm_encoder *drm_enc = phys_enc->parent;
+   struct msm_drm_private *priv = drm_enc->dev->dev_private;
+
+   if (priv->dsc)
+   return true;
+
+   return false;
+}

Check whether DSC is enabled and only if its 2-2-1 topology.
This needs to be reworked when other topologies are supported.


+
 /**
  * dpu_encoder_helper_split_config - split display configuration
helper function
  * This helper function may be used by physical encoders to configure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index b2be39b9144e..5fe87881c30c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -69,6 +69,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg(
intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD;
intf_cfg.stream_sel = cmd_enc->stream_sel;
intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc);
+   intf_cfg.dsc = dpu_encoder_helper_get_dsc_mode(phys_enc);
+
ctl->ops.setup_intf_cfg(ctl, _cfg);
 }

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 aeea6add61ee..f059416311ee 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -121,7 +121,7 @@ static u32 dpu_hw_ctl_get_pending_flush(struct
dpu_hw_ctl *ctx)
return ctx->pending_flush_mask;
 }

-static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
+static void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
 {
 	DPU_REG_WRITE(>hw, CTL_DSC_FLUSH, BIT(0) | BIT(1) | BIT(2) | 
BIT(3));


@@ -522,7 +522,8 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl 
*ctx,


intf_cfg |= (cfg->intf & 0xF) << 4;

-   if (cfg->mode_3d) {
+   /* In DSC we can't set merge, so check for dsc too */
+   if (cfg->mode_3d && !cfg->dsc) {
intf_cfg |= BIT(19);
intf_cfg |= (cfg->mode_3d - 0x1) << 20;
}
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 806c171e5df2..347a653c1e01 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -39,6 +39,7 @@ struct dpu_hw_stage_cfg {
  * @mode_3d:   3d mux configuration
  * @merge_3d:  3d merge block used
  * @intf_mode_sel: Interface mode, cmd / vid
+ * @dsc:   DSC is enabled
  * @stream_sel:Stream selection for multi-stream 
interfaces

  */
 struct dpu_hw_intf_cfg {
@@ -46,6 +47,7 @@ struct dpu_hw_intf_cfg {
enum dpu_3d_blend_mode mode_3d;
enum dpu_merge_3d merge_3d;
enum dpu_ctl_mode_sel intf_mode_sel;
+   bool dsc;
int stream_sel;
 };


  1   2   3   4   >