Re: [PATCH 2/7] drm/msm/dpu: convert vsync source defines to the enum

2024-05-22 Thread Abhinav Kumar




On 5/22/2024 1:01 PM, Dmitry Baryshkov wrote:

On Wed, 22 May 2024 at 21:41, Abhinav Kumar  wrote:




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Add enum dpu_vsync_source instead of a series of defines. Use this enum
to pass vsync information.

Signed-off-by: Dmitry Baryshkov 
---
   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c |  2 +-
   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h |  2 +-
   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 26 ++
   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h  |  2 +-
   5 files changed, 18 insertions(+), 16 deletions(-)




diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 66759623fc42..a2eff36a2224 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -54,18 +54,20 @@
   #define DPU_BLEND_BG_INV_MOD_ALPHA  (1 << 12)
   #define DPU_BLEND_BG_TRANSP_EN  (1 << 13)

-#define DPU_VSYNC0_SOURCE_GPIO   0
-#define DPU_VSYNC1_SOURCE_GPIO   1
-#define DPU_VSYNC2_SOURCE_GPIO   2
-#define DPU_VSYNC_SOURCE_INTF_0  3
-#define DPU_VSYNC_SOURCE_INTF_1  4
-#define DPU_VSYNC_SOURCE_INTF_2  5
-#define DPU_VSYNC_SOURCE_INTF_3  6
-#define DPU_VSYNC_SOURCE_WD_TIMER_4  11
-#define DPU_VSYNC_SOURCE_WD_TIMER_3  12
-#define DPU_VSYNC_SOURCE_WD_TIMER_2  13
-#define DPU_VSYNC_SOURCE_WD_TIMER_1  14
-#define DPU_VSYNC_SOURCE_WD_TIMER_0  15
+enum dpu_vsync_source {
+ DPU_VSYNC_SOURCE_GPIO_0,
+ DPU_VSYNC_SOURCE_GPIO_1,
+ DPU_VSYNC_SOURCE_GPIO_2,
+ DPU_VSYNC_SOURCE_INTF_0 = 3,


Do we need this assignment to 3?


It is redundant, but it points out that if at some point another GPIO
is added, it should go to the end (or to some other place, having the
proper value).



Ack, makes sense.



Rest LGTM,

Reviewed-by: Abhinav Kumar 




Re: [PATCH 1/7] dt-bindings: display/msm/dsi: allow specifying TE source

2024-05-22 Thread Abhinav Kumar




On 5/22/2024 1:05 PM, Dmitry Baryshkov wrote:

On Wed, 22 May 2024 at 21:38, Abhinav Kumar  wrote:




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Command mode panels provide TE signal back to the DSI host to signal
that the frame display has completed and update of the image will not
cause tearing. Usually it is connected to the first GPIO with the
mdp_vsync function, which is the default. In such case the property can
be skipped.



This is a good addition overall. Some comments below.


Signed-off-by: Dmitry Baryshkov 
---
   .../bindings/display/msm/dsi-controller-main.yaml| 16 

   1 file changed, 16 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 1fa28e976559..c1771c69b247 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -162,6 +162,21 @@ properties:
   items:
 enum: [ 0, 1, 2, 3 ]

+  qcom,te-source:
+$ref: /schemas/types.yaml#/definitions/string
+description:
+  Specifies the source of vsync signal from the panel used for
+  tearing elimination. The default is mdp_gpio0.


panel --> command mode panel?


+enum:
+  - mdp_gpio0
+  - mdp_gpio1
+  - mdp_gpio2


are gpio0, gpio1 and gpio2 referring to the vsync_p, vsync_s and vsync_e
sources?


No idea, unfortunately. They are gpioN or just mdp_vsync all over the
place. For the reference, in case of the SDM845 and Pixel3 the signal
is routed through SoC GPIO12.



GPIO12 on sdm845 is mdp_vsync_e.

Thats why I think its better we use mdp_vsync_p/s/e instead of mdp_gpio0/1/2


In that case wouldnt it be better to name it like that?


+  - timer0
+  - timer1
+  - timer2
+  - timer3
+  - timer4
+


These are indicating watchdog timer sources right?


Yes.




   required:
 - port@0
 - port@1
@@ -452,6 +467,7 @@ examples:
 dsi0_out: endpoint {
  remote-endpoint = <_in>;
  data-lanes = <0 1 2 3>;
+   qcom,te-source = "mdp_gpio2";


I have a basic doubt on this. Should te-source should be in the input
port or the output one for the controller? Because TE is an input to the
DSI. And if the source is watchdog timer then it aligns even more as a
property of the input endpoint.


I don't really want to split this. Both data-lanes and te-source are
properties of the link between the DSI and panel. You can not really
say which side has which property.



TE is an input to the DSI from the panel. Between input and output port, 
I think it belongs more to the input port.


I didnt follow why this is a link property. Sorry , I didnt follow the 
split part.


If we are unsure about input vs output port, do you think its better we 
make it a property of the main dsi node instead?



 };
 };
  };





[PATCH v3 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info

2024-05-22 Thread Rob Clark
From: Rob Clark 

In the case of iova fault triggered devcore dumps, include additional
debug information based on what we think is the current page tables,
including the TTBR0 value (which should match what we have in
adreno_smmu_fault_info unless things have gone horribly wrong), and
the pagetable entries traversed in the process of resolving the
faulting iova.

Signed-off-by: Rob Clark 
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++
 drivers/gpu/drm/msm/msm_gpu.c   | 22 ++
 drivers/gpu/drm/msm/msm_gpu.h   |  8 
 drivers/gpu/drm/msm/msm_iommu.c | 18 ++
 drivers/gpu/drm/msm/msm_mmu.h   |  5 -
 5 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c 
b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index a00241e3373b..3b4c75df0a5f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -861,6 +861,16 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state 
*state,
drm_printf(p, "  - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? 
"WRITE" : "READ");
drm_printf(p, "  - type=%s\n", info->type);
drm_printf(p, "  - source=%s\n", info->block);
+
+   /* Information extracted from what we think are the current
+* pgtables.  Hopefully the TTBR0 matches what we've extracted
+* from the SMMU registers in smmu_info!
+*/
+   drm_puts(p, "pgtable-fault-info:\n");
+   drm_printf(p, "  - ttbr0: %.16llx\n", (u64)info->pgtbl_ttbr0);
+   drm_printf(p, "  - asid: %d\n", info->asid);
+   drm_printf(p, "  - ptes: %.16llx %.16llx %.16llx %.16llx\n",
+  info->ptes[0], info->ptes[1], info->ptes[2], 
info->ptes[3]);
}
 
drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 43cde0590250..647bddc897f2 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -256,6 +256,18 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state 
*state,
state->nr_bos++;
 }
 
+static int pgtable_walk_cb(void *cb_data, void *pte, int level)
+{
+   struct msm_gpu_fault_info *info = cb_data;
+
+   if (level > ARRAY_SIZE(info->ptes))
+   return -EINVAL;
+
+   info->ptes[level] = *(u64 *)pte;
+
+   return 0;
+}
+
 static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
struct msm_gem_submit *submit, char *comm, char *cmd)
 {
@@ -281,6 +293,16 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
if (submit) {
int i;
 
+   if (state->fault_info.ttbr0) {
+   struct msm_gpu_fault_info *info = >fault_info;
+   struct msm_mmu *mmu = submit->aspace->mmu;
+
+   msm_iommu_pagetable_params(mmu, >pgtbl_ttbr0,
+  >asid);
+   msm_iommu_pagetable_walk(mmu, info->iova,
+pgtable_walk_cb, info);
+   }
+
state->bos = kcalloc(submit->nr_bos,
sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 04a696ac4626..82fbb626461a 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -101,6 +101,14 @@ struct msm_gpu_fault_info {
int flags;
const char *type;
const char *block;
+
+   /* Information about what we think/expect is the current SMMU state,
+* for example expected_ttbr0 should match smmu_info.ttbr0 which
+* was read back from SMMU registers.
+*/
+   phys_addr_t pgtbl_ttbr0;
+   u64 ptes[4];
+   int asid;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index d5512037c38b..f46ed4667475 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -195,6 +195,24 @@ struct iommu_domain_geometry 
*msm_iommu_get_geometry(struct msm_mmu *mmu)
return >domain->geometry;
 }
 
+int msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova,
+int (*cb)(void *cb_data, void *pte, int level),
+void *cb_data)
+{
+   struct msm_iommu_pagetable *pagetable;
+
+   if (mmu->type != MSM_MMU_IOMMU_PAGETABLE)
+   return -EINVAL;
+
+   pagetable = to_pagetable(mmu);
+
+   if (!pagetable->pgtbl_ops->pgtable_walk)
+   return -EINVAL;
+
+   return pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova,
+ cb, cb_data);
+}
+
 static const struct msm_mmu_funcs pagetable_funcs = {
.map 

[PATCH v3 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk

2024-05-22 Thread Rob Clark
From: Rob Clark 

Add an io-pgtable method to walk the pgtable returning the raw PTEs that
would be traversed for a given iova access.

Signed-off-by: Rob Clark 
---
 drivers/iommu/io-pgtable-arm.c | 50 --
 include/linux/io-pgtable.h |  4 +++
 2 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f7828a7aad41..86d2b34d6f95 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops 
*ops, unsigned long iov
data->start_level, ptep);
 }
 
-static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-unsigned long iova)
+static int pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
+   int (*cb)(void *cb_data, void *pte, int level),
+   void *cb_data)
 {
struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
arm_lpae_iopte pte, *ptep = data->pgd;
int lvl = data->start_level;
+   int ret;
 
do {
/* Valid IOPTE pointer? */
if (!ptep)
-   return 0;
+   return -EFAULT;
 
/* Grab the IOPTE we're interested in */
ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
@@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct 
io_pgtable_ops *ops,
 
/* Valid entry? */
if (!pte)
-   return 0;
+   return -EFAULT;
+
+   ret = cb(cb_data, , lvl);
+   if (ret)
+   return ret;
 
-   /* Leaf entry? */
+   /* Leaf entry?  If so, we've found the translation */
if (iopte_leaf(pte, lvl, data->iop.fmt))
-   goto found_translation;
+   return 0;
 
/* Take it to the next level */
ptep = iopte_deref(pte, data);
} while (++lvl < ARM_LPAE_MAX_LEVELS);
 
/* Ran out of page tables to walk */
+   return -EFAULT;
+}
+
+struct iova_to_phys_walk_data {
+   arm_lpae_iopte pte;
+   int level;
+};
+
+static int iova_to_phys_walk_cb(void *cb_data, void *pte, int level)
+{
+   struct iova_to_phys_walk_data *d = cb_data;
+
+   d->pte = *(arm_lpae_iopte *)pte;
+   d->level = level;
+
return 0;
+}
+
+static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+unsigned long iova)
+{
+   struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+   struct iova_to_phys_walk_data d;
+   int ret;
+
+   ret = pgtable_walk(ops, iova, iova_to_phys_walk_cb, );
+   if (ret)
+   return 0;
 
-found_translation:
-   iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
-   return iopte_to_paddr(pte, data) | iova;
+   iova &= (ARM_LPAE_BLOCK_SIZE(d.level, data) - 1);
+   return iopte_to_paddr(d.pte, data) | iova;
 }
 
 static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 86cf1f7ae389..261b48af068a 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -177,6 +177,7 @@ struct io_pgtable_cfg {
  * @map_pages:Map a physically contiguous range of pages of the same size.
  * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
  * @iova_to_phys: Translate iova to physical address.
+ * @pgtable_walk: (optional) Perform a page table walk for a given iova.
  *
  * These functions map directly onto the iommu_ops member functions with
  * the same names.
@@ -190,6 +191,9 @@ struct io_pgtable_ops {
  struct iommu_iotlb_gather *gather);
phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
unsigned long iova);
+   int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova,
+   int (*cb)(void *cb_data, void *pte, int level),
+   void *cb_data);
int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
unsigned long iova, size_t size,
unsigned long flags,
-- 
2.45.1



[PATCH v3 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging

2024-05-22 Thread Rob Clark
From: Rob Clark 

This series extends io-pgtable-arm with a method to retrieve the page
table entries traversed in the process of address translation, and then
beefs up drm/msm gpu devcore dump to include this (and additional info)
in the devcore dump.

This is a respin of https://patchwork.freedesktop.org/series/94968/
(minus a patch that was already merged)

v2: Fix an armv7/32b build error in the last patch
v3: Incorperate Will Deacon's suggestion to make the interface
callback based.

Rob Clark (2):
  iommu/io-pgtable-arm: Add way to debug pgtable walk
  drm/msm: Extend gpu devcore dumps with pgtbl info

 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 +
 drivers/gpu/drm/msm/msm_gpu.c   | 22 +++
 drivers/gpu/drm/msm/msm_gpu.h   |  8 
 drivers/gpu/drm/msm/msm_iommu.c | 18 +
 drivers/gpu/drm/msm/msm_mmu.h   |  5 ++-
 drivers/iommu/io-pgtable-arm.c  | 50 -
 include/linux/io-pgtable.h  |  4 ++
 7 files changed, 107 insertions(+), 10 deletions(-)

-- 
2.45.1



Re: [PATCH 1/7] dt-bindings: display/msm/dsi: allow specifying TE source

2024-05-22 Thread Dmitry Baryshkov
On Wed, 22 May 2024 at 21:38, Abhinav Kumar  wrote:
>
>
>
> On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:
> > Command mode panels provide TE signal back to the DSI host to signal
> > that the frame display has completed and update of the image will not
> > cause tearing. Usually it is connected to the first GPIO with the
> > mdp_vsync function, which is the default. In such case the property can
> > be skipped.
> >
>
> This is a good addition overall. Some comments below.
>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   .../bindings/display/msm/dsi-controller-main.yaml| 16 
> > 
> >   1 file changed, 16 insertions(+)
> >
> > diff --git 
> > a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
> > b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> > index 1fa28e976559..c1771c69b247 100644
> > --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> > +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> > @@ -162,6 +162,21 @@ properties:
> >   items:
> > enum: [ 0, 1, 2, 3 ]
> >
> > +  qcom,te-source:
> > +$ref: /schemas/types.yaml#/definitions/string
> > +description:
> > +  Specifies the source of vsync signal from the panel used 
> > for
> > +  tearing elimination. The default is mdp_gpio0.
>
> panel --> command mode panel?
>
> > +enum:
> > +  - mdp_gpio0
> > +  - mdp_gpio1
> > +  - mdp_gpio2
>
> are gpio0, gpio1 and gpio2 referring to the vsync_p, vsync_s and vsync_e
> sources?

No idea, unfortunately. They are gpioN or just mdp_vsync all over the
place. For the reference, in case of the SDM845 and Pixel3 the signal
is routed through SoC GPIO12.

> In that case wouldnt it be better to name it like that?
>
> > +  - timer0
> > +  - timer1
> > +  - timer2
> > +  - timer3
> > +  - timer4
> > +
>
> These are indicating watchdog timer sources right?

Yes.

>
> >   required:
> > - port@0
> > - port@1
> > @@ -452,6 +467,7 @@ examples:
> > dsi0_out: endpoint {
> >  remote-endpoint = <_in>;
> >  data-lanes = <0 1 2 3>;
> > +   qcom,te-source = "mdp_gpio2";
>
> I have a basic doubt on this. Should te-source should be in the input
> port or the output one for the controller? Because TE is an input to the
> DSI. And if the source is watchdog timer then it aligns even more as a
> property of the input endpoint.

I don't really want to split this. Both data-lanes and te-source are
properties of the link between the DSI and panel. You can not really
say which side has which property.

> > };
> > };
> >  };
> >

-- 
With best wishes
Dmitry


Re: [PATCH 2/7] drm/msm/dpu: convert vsync source defines to the enum

2024-05-22 Thread Dmitry Baryshkov
On Wed, 22 May 2024 at 21:41, Abhinav Kumar  wrote:
>
>
>
> On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:
> > Add enum dpu_vsync_source instead of a series of defines. Use this enum
> > to pass vsync information.
> >
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c |  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h |  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 26 
> > ++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h  |  2 +-
> >   5 files changed, 18 insertions(+), 16 deletions(-)
> >

> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > index 66759623fc42..a2eff36a2224 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> > @@ -54,18 +54,20 @@
> >   #define DPU_BLEND_BG_INV_MOD_ALPHA  (1 << 12)
> >   #define DPU_BLEND_BG_TRANSP_EN  (1 << 13)
> >
> > -#define DPU_VSYNC0_SOURCE_GPIO   0
> > -#define DPU_VSYNC1_SOURCE_GPIO   1
> > -#define DPU_VSYNC2_SOURCE_GPIO   2
> > -#define DPU_VSYNC_SOURCE_INTF_0  3
> > -#define DPU_VSYNC_SOURCE_INTF_1  4
> > -#define DPU_VSYNC_SOURCE_INTF_2  5
> > -#define DPU_VSYNC_SOURCE_INTF_3  6
> > -#define DPU_VSYNC_SOURCE_WD_TIMER_4  11
> > -#define DPU_VSYNC_SOURCE_WD_TIMER_3  12
> > -#define DPU_VSYNC_SOURCE_WD_TIMER_2  13
> > -#define DPU_VSYNC_SOURCE_WD_TIMER_1  14
> > -#define DPU_VSYNC_SOURCE_WD_TIMER_0  15
> > +enum dpu_vsync_source {
> > + DPU_VSYNC_SOURCE_GPIO_0,
> > + DPU_VSYNC_SOURCE_GPIO_1,
> > + DPU_VSYNC_SOURCE_GPIO_2,
> > + DPU_VSYNC_SOURCE_INTF_0 = 3,
>
> Do we need this assignment to 3?

It is redundant, but it points out that if at some point another GPIO
is added, it should go to the end (or to some other place, having the
proper value).

>
> Rest LGTM,
>
> Reviewed-by: Abhinav Kumar 

-- 
With best wishes
Dmitry


Re: [PATCH 0/7] drm/msm/dpu: handle non-default TE source pins

2024-05-22 Thread Dmitry Baryshkov
On Wed, 22 May 2024 at 21:39, Abhinav Kumar  wrote:
>
>
>
> On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:
> > Command-mode DSI panels need to signal the display controlller when
> > vsync happens, so that the device can start sending the next frame. Some
> > devices (Google Pixel 3) use a non-default pin, so additional
> > configuration is required. Add a way to specify this information in DT
> > and handle it in the DSI and DPU drivers.
> >
>
> Which pin is the pixel 3 using? Just wanted to know .. is it gpio0 or gpio1?

gpio2. If it was gpio0 then there were no issues at all.

>
> > Signed-off-by: Dmitry Baryshkov 
> > ---
> > Dmitry Baryshkov (7):
> >dt-bindings: display/msm/dsi: allow specifying TE source
> >drm/msm/dpu: convert vsync source defines to the enum
> >drm/msm/dsi: drop unused GPIOs handling
> >drm/msm/dpu: pull the is_cmd_mode out of 
> > _dpu_encoder_update_vsync_source()
> >drm/msm/dpu: rework vsync_source handling
> >drm/msm/dsi: parse vsync source from device tree
> >drm/msm/dpu: support setting the TE source
> >
> >   .../bindings/display/msm/dsi-controller-main.yaml  | 16 
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 11 ++---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  5 +--
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h| 26 ++--
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h |  2 +-
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 44 
> > 
> >   drivers/gpu/drm/msm/dsi/dsi.h  |  1 +
> >   drivers/gpu/drm/msm/dsi/dsi_host.c | 48 
> > +-
> >   drivers/gpu/drm/msm/dsi/dsi_manager.c  |  5 +++
> >   drivers/gpu/drm/msm/msm_drv.h  |  6 +++
> >   12 files changed, 106 insertions(+), 62 deletions(-)
> > ---
> > base-commit: 75fa778d74b786a1608d55d655d42b480a6fa8bd
> > change-id: 20240514-dpu-handle-te-signal-82663c0211bd
> >
> > Best regards,



-- 
With best wishes
Dmitry


Re: [PATCH 5/7] drm/msm/dpu: rework vsync_source handling

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

The struct msm_display_info has is_te_using_watchdog_timer field which
is neither used anywhere nor is flexible enough to specify different
sources. Replace it with the field specifying the vsync source using
enum dpu_vsync_source.

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



Reviewed-by: Abhinav Kumar 



Re: [PATCH 4/7] drm/msm/dpu: pull the is_cmd_mode out of _dpu_encoder_update_vsync_source()

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Setting vsync source makes sense only for DSI CMD panels. Pull the
is_cmd_mode condition out of the function into the calling code, so that
it becomes more explicit.

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



Reviewed-by: Abhinav Kumar 


Re: [PATCH 3/7] drm/msm/dsi: drop unused GPIOs handling

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Neither disp-enable-gpios nor disp-te-gpios are defined in the schema.
None of the board DT files use those GPIO pins. Drop them from the
driver.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/dsi/dsi_host.c | 37 -
  1 file changed, 37 deletions(-)



Reviewed-by: Abhinav Kumar 


Re: [PATCH 2/7] drm/msm/dpu: convert vsync source defines to the enum

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Add enum dpu_vsync_source instead of a series of defines. Use this enum
to pass vsync information.

Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 26 ++
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h  |  2 +-
  5 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 119f3ea50a7c..4988a1029431 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -747,7 +747,7 @@ static void _dpu_encoder_update_vsync_source(struct 
dpu_encoder_virt *dpu_enc,
if (disp_info->is_te_using_watchdog_timer)
vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
else
-   vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
+   vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_GPIO_0;
  
  		hw_mdptop->ops.setup_vsync_source(hw_mdptop, _cfg);
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c

index 225c1c7768ff..96f6160cf607 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -462,7 +462,7 @@ static int dpu_hw_intf_get_vsync_info(struct dpu_hw_intf 
*intf,
  }
  
  static void dpu_hw_intf_vsync_sel(struct dpu_hw_intf *intf,

-   u32 vsync_source)
+ enum dpu_vsync_source vsync_source)
  {
struct dpu_hw_blk_reg_map *c;
  
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h

index f9015c67a574..ac244f0b33fb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -107,7 +107,7 @@ struct dpu_hw_intf_ops {
  
  	int (*connect_external_te)(struct dpu_hw_intf *intf, bool enable_external_te);
  
-	void (*vsync_sel)(struct dpu_hw_intf *intf, u32 vsync_source);

+   void (*vsync_sel)(struct dpu_hw_intf *intf, enum dpu_vsync_source 
vsync_source);
  
  	/**

 * Disable autorefresh if enabled
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 66759623fc42..a2eff36a2224 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -54,18 +54,20 @@
  #define DPU_BLEND_BG_INV_MOD_ALPHA(1 << 12)
  #define DPU_BLEND_BG_TRANSP_EN(1 << 13)
  
-#define DPU_VSYNC0_SOURCE_GPIO		0

-#define DPU_VSYNC1_SOURCE_GPIO 1
-#define DPU_VSYNC2_SOURCE_GPIO 2
-#define DPU_VSYNC_SOURCE_INTF_03
-#define DPU_VSYNC_SOURCE_INTF_14
-#define DPU_VSYNC_SOURCE_INTF_25
-#define DPU_VSYNC_SOURCE_INTF_36
-#define DPU_VSYNC_SOURCE_WD_TIMER_411
-#define DPU_VSYNC_SOURCE_WD_TIMER_312
-#define DPU_VSYNC_SOURCE_WD_TIMER_213
-#define DPU_VSYNC_SOURCE_WD_TIMER_114
-#define DPU_VSYNC_SOURCE_WD_TIMER_015
+enum dpu_vsync_source {
+   DPU_VSYNC_SOURCE_GPIO_0,
+   DPU_VSYNC_SOURCE_GPIO_1,
+   DPU_VSYNC_SOURCE_GPIO_2,
+   DPU_VSYNC_SOURCE_INTF_0 = 3,


Do we need this assignment to 3?

Rest LGTM,

Reviewed-by: Abhinav Kumar 


Re: [PATCH 0/7] drm/msm/dpu: handle non-default TE source pins

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Command-mode DSI panels need to signal the display controlller when
vsync happens, so that the device can start sending the next frame. Some
devices (Google Pixel 3) use a non-default pin, so additional
configuration is required. Add a way to specify this information in DT
and handle it in the DSI and DPU drivers.



Which pin is the pixel 3 using? Just wanted to know .. is it gpio0 or gpio1?


Signed-off-by: Dmitry Baryshkov 
---
Dmitry Baryshkov (7):
   dt-bindings: display/msm/dsi: allow specifying TE source
   drm/msm/dpu: convert vsync source defines to the enum
   drm/msm/dsi: drop unused GPIOs handling
   drm/msm/dpu: pull the is_cmd_mode out of 
_dpu_encoder_update_vsync_source()
   drm/msm/dpu: rework vsync_source handling
   drm/msm/dsi: parse vsync source from device tree
   drm/msm/dpu: support setting the TE source

  .../bindings/display/msm/dsi-controller-main.yaml  | 16 
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 11 ++---
  drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h|  5 +--
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c|  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h|  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h| 26 ++--
  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h |  2 +-
  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 44 
  drivers/gpu/drm/msm/dsi/dsi.h  |  1 +
  drivers/gpu/drm/msm/dsi/dsi_host.c | 48 +-
  drivers/gpu/drm/msm/dsi/dsi_manager.c  |  5 +++
  drivers/gpu/drm/msm/msm_drv.h  |  6 +++
  12 files changed, 106 insertions(+), 62 deletions(-)
---
base-commit: 75fa778d74b786a1608d55d655d42b480a6fa8bd
change-id: 20240514-dpu-handle-te-signal-82663c0211bd

Best regards,


Re: [PATCH 1/7] dt-bindings: display/msm/dsi: allow specifying TE source

2024-05-22 Thread Abhinav Kumar




On 5/20/2024 5:12 AM, Dmitry Baryshkov wrote:

Command mode panels provide TE signal back to the DSI host to signal
that the frame display has completed and update of the image will not
cause tearing. Usually it is connected to the first GPIO with the
mdp_vsync function, which is the default. In such case the property can
be skipped.



This is a good addition overall. Some comments below.


Signed-off-by: Dmitry Baryshkov 
---
  .../bindings/display/msm/dsi-controller-main.yaml| 16 
  1 file changed, 16 insertions(+)

diff --git 
a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
index 1fa28e976559..c1771c69b247 100644
--- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
+++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
@@ -162,6 +162,21 @@ properties:
  items:
enum: [ 0, 1, 2, 3 ]
  
+  qcom,te-source:

+$ref: /schemas/types.yaml#/definitions/string
+description:
+  Specifies the source of vsync signal from the panel used for
+  tearing elimination. The default is mdp_gpio0.


panel --> command mode panel?


+enum:
+  - mdp_gpio0
+  - mdp_gpio1
+  - mdp_gpio2


are gpio0, gpio1 and gpio2 referring to the vsync_p, vsync_s and vsync_e 
sources?


In that case wouldnt it be better to name it like that?


+  - timer0
+  - timer1
+  - timer2
+  - timer3
+  - timer4
+


These are indicating watchdog timer sources right?


  required:
- port@0
- port@1
@@ -452,6 +467,7 @@ examples:
dsi0_out: endpoint {
 remote-endpoint = <_in>;
 data-lanes = <0 1 2 3>;
+   qcom,te-source = "mdp_gpio2";


I have a basic doubt on this. Should te-source should be in the input 
port or the output one for the controller? Because TE is an input to the 
DSI. And if the source is watchdog timer then it aligns even more as a 
property of the input endpoint.



};
};
 };



Re: [PATCH 1/7] dt-bindings: display/msm/dsi: allow specifying TE source

2024-05-22 Thread Rob Herring
On Mon, May 20, 2024 at 03:12:43PM +0300, Dmitry Baryshkov wrote:
> Command mode panels provide TE signal back to the DSI host to signal
> that the frame display has completed and update of the image will not
> cause tearing. Usually it is connected to the first GPIO with the
> mdp_vsync function, which is the default. In such case the property can
> be skipped.
> 
> Signed-off-by: Dmitry Baryshkov 
> ---
>  .../bindings/display/msm/dsi-controller-main.yaml| 16 
> 
>  1 file changed, 16 insertions(+)
> 
> diff --git 
> a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml 
> b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> index 1fa28e976559..c1771c69b247 100644
> --- a/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> +++ b/Documentation/devicetree/bindings/display/msm/dsi-controller-main.yaml
> @@ -162,6 +162,21 @@ properties:
>  items:
>enum: [ 0, 1, 2, 3 ]
>  
> +  qcom,te-source:
> +$ref: /schemas/types.yaml#/definitions/string
> +description:
> +  Specifies the source of vsync signal from the panel used 
> for
> +  tearing elimination. The default is mdp_gpio0.

default: mdp_gpio0

With that,

Reviewed-by: Rob Herring (Arm) 


Re: [PATCH v3 2/3] drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER

2024-05-22 Thread Marijn Suijten
On 2024-05-22 09:25:54, Dmitry Baryshkov wrote:
> This panel driver uses DSC PPS functions and as such depends on the
> DRM_DISPLAY_DP_HELPER. Select this symbol to make required functions

Here and in the title: maybe this is a remnant from v2, but you split out a
DRM_DISPLAY_DSC_HELPER and shouldn't be enabling DP for a DSI panel now.

- Marijn

> available to the driver.
> 
> Reported-by: kernel test robot 
> Closes: 
> https://lore.kernel.org/oe-kbuild-all/202404200800.kysryyli-...@intel.com/
> Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
> Signed-off-by: Dmitry Baryshkov 
> ---
>  drivers/gpu/drm/panel/Kconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
> index 4a2f621433ef..3e3f63479544 100644
> --- a/drivers/gpu/drm/panel/Kconfig
> +++ b/drivers/gpu/drm/panel/Kconfig
> @@ -340,6 +340,8 @@ config DRM_PANEL_LG_SW43408
>   depends on OF
>   depends on DRM_MIPI_DSI
>   depends on BACKLIGHT_CLASS_DEVICE
> + select DRM_DISPLAY_DSC_HELPER
> + select DRM_DISPLAY_HELPER
>   help
> Say Y here if you want to enable support for LG sw43408 panel.
> The panel has a 1080x2160@60Hz resolution and uses 24 bit RGB per
> 
> -- 
> 2.39.2
> 


Re: [PATCH v3 2/3] drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER

2024-05-22 Thread Neil Armstrong

On 22/05/2024 08:25, Dmitry Baryshkov wrote:

This panel driver uses DSC PPS functions and as such depends on the
DRM_DISPLAY_DP_HELPER. Select this symbol to make required functions
available to the driver.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202404200800.kysryyli-...@intel.com/
Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/panel/Kconfig | 2 ++
  1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4a2f621433ef..3e3f63479544 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -340,6 +340,8 @@ config DRM_PANEL_LG_SW43408
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_DISPLAY_DSC_HELPER
+   select DRM_DISPLAY_HELPER
help
  Say Y here if you want to enable support for LG sw43408 panel.
  The panel has a 1080x2160@60Hz resolution and uses 24 bit RGB per



Reviewed-by: Neil Armstrong 


Re: [PATCH v3 3/3] drm/panel/lg-sw43408: mark sw43408_backlight_ops as static

2024-05-22 Thread Neil Armstrong

On 22/05/2024 08:25, Dmitry Baryshkov wrote:

Fix sparse warning regarding symbol 'sw43408_backlight_ops' not being
declared.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202404200739.hbwzvohr-...@intel.com/
Reviewed-by: Neil Armstrong 
Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
Signed-off-by: Dmitry Baryshkov 
---
  drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c 
b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 115f4702d59f..2b3a73696dce 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -182,7 +182,7 @@ static int sw43408_backlight_update_status(struct 
backlight_device *bl)
return mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
  }
  
-const struct backlight_ops sw43408_backlight_ops = {

+static const struct backlight_ops sw43408_backlight_ops = {
.update_status = sw43408_backlight_update_status,
  };
  



Reviewed-by: Neil Armstrong 


[PATCH v2 13/14] drm/msm/hdmi: ensure that HDMI is one if HPD is requested

2024-05-22 Thread Dmitry Baryshkov
The HDMI block needs to be enabled to properly generate HPD events. Make
sure it is not turned off in the disable paths if HPD delivery is enabled.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c| 1 +
 drivers/gpu/drm/msm/hdmi/hdmi.h| 2 ++
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 8 +++-
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c| 9 -
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index a9437054c015..2890196857f8 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -409,6 +409,7 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
hdmi->pdev = pdev;
hdmi->config = config;
spin_lock_init(>reg_lock);
+   mutex_init(>state_mutex);
 
ret = drm_of_find_panel_or_bridge(pdev->dev.of_node, 1, 0, NULL, 
>next_bridge);
if (ret && ret != -ENODEV)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 268ff8604423..7f0ca5252018 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -42,6 +42,8 @@ struct hdmi {
 
/* video state: */
bool power_on;
+   bool hpd_enabled;
+   struct mutex state_mutex; /* protects two booleans */
unsigned long int pixclock;
 
void __iomem *mmio;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index cddba640d292..104107ed47d0 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -117,11 +117,13 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
 
DBG("power up");
 
+   mutex_lock(>state_mutex);
if (!hdmi->power_on) {
msm_hdmi_phy_resource_enable(phy);
msm_hdmi_power_on(bridge);
hdmi->power_on = true;
}
+   mutex_unlock(>state_mutex);
 
if (hdmi->hdmi_mode) {
msm_hdmi_config_avi_infoframe(hdmi);
@@ -147,7 +149,10 @@ static void msm_hdmi_bridge_atomic_post_disable(struct 
drm_bridge *bridge,
msm_hdmi_hdcp_off(hdmi->hdcp_ctrl);
 
DBG("power down");
-   msm_hdmi_set_mode(hdmi, false);
+
+   /* Keep the HDMI enabled if the HPD is enabled */
+   mutex_lock(>state_mutex);
+   msm_hdmi_set_mode(hdmi, hdmi->hpd_enabled);
 
msm_hdmi_phy_powerdown(phy);
 
@@ -158,6 +163,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct 
drm_bridge *bridge,
msm_hdmi_audio_update(hdmi);
msm_hdmi_phy_resource_disable(phy);
}
+   mutex_unlock(>state_mutex);
 }
 
 static void msm_hdmi_bridge_mode_set(struct drm_bridge *bridge,
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index d3353c6148ed..cb89e9e2c6ea 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -73,10 +73,14 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
if (ret)
return ret;
 
+   mutex_lock(>state_mutex);
msm_hdmi_set_mode(hdmi, false);
msm_hdmi_phy_reset(hdmi);
msm_hdmi_set_mode(hdmi, true);
 
+   hdmi->hpd_enabled = true;
+   mutex_unlock(>state_mutex);
+
hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
 
/* enable HPD events: */
@@ -106,7 +110,10 @@ void msm_hdmi_hpd_disable(struct hdmi *hdmi)
/* Disable HPD interrupt */
hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
 
-   msm_hdmi_set_mode(hdmi, false);
+   mutex_lock(>state_mutex);
+   hdmi->hpd_enabled = false;
+   msm_hdmi_set_mode(hdmi, hdmi->power_on);
+   mutex_unlock(>state_mutex);
 
pm_runtime_put(dev);
 }

-- 
2.39.2



[PATCH v2 11/14] drm/msm/hdmi: expand the HDMI_CFG macro

2024-05-22 Thread Dmitry Baryshkov
Expand the HDMI_CFG() macro in HDMI config description. It has no added
value other than hiding some boilerplate declarations.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 16 
 drivers/gpu/drm/msm/hdmi/hdmi.h |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index c39a1f3a7505..e160a23e962e 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -223,24 +223,24 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
  * The hdmi device:
  */
 
-#define HDMI_CFG(item, entry) \
-   .item ## _names = item ##_names_ ## entry, \
-   .item ## _cnt   = ARRAY_SIZE(item ## _names_ ## entry)
-
 static const char *pwr_reg_names_8960[] = {"core-vdda"};
 static const char *pwr_clk_names_8960[] = {"core", "master_iface", 
"slave_iface"};
 
 static const struct hdmi_platform_config hdmi_tx_8960_config = {
-   HDMI_CFG(pwr_reg, 8960),
-   HDMI_CFG(pwr_clk, 8960),
+   .pwr_reg_names = pwr_reg_names_8960,
+   .pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8960),
+   .pwr_clk_names = pwr_clk_names_8960,
+   .pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8960),
 };
 
 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
 static const char *pwr_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
 
 static const struct hdmi_platform_config hdmi_tx_8974_config = {
-   HDMI_CFG(pwr_reg, 8x74),
-   HDMI_CFG(pwr_clk, 8x74),
+   .pwr_reg_names = pwr_reg_names_8x74,
+   .pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names_8x74),
+   .pwr_clk_names = pwr_clk_names_8x74,
+   .pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names_8x74),
 };
 
 /*
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 1e346e697f8e..2a98efa8b6bd 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -89,7 +89,7 @@ struct hdmi_platform_config {
const char **pwr_reg_names;
int pwr_reg_cnt;
 
-   /* clks that need to be on for hpd: */
+   /* clks that need to be on: */
const char **pwr_clk_names;
int pwr_clk_cnt;
 };

-- 
2.39.2



[PATCH v2 14/14] drm/msm/hdmi: wire in hpd_enable/hpd_disable bridge ops

2024-05-22 Thread Dmitry Baryshkov
The HDMI driver already has msm_hdmi_hpd_enable() and
msm_hdmi_hpd_disable() functions. Wire them into the
msm_hdmi_bridge_funcs, so that HPD  can be enabled and disabled
dynamically rather than always having HPD events generation enabled.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c|  9 -
 drivers/gpu/drm/msm/hdmi/hdmi.h|  4 ++--
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |  3 +++
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c| 12 ++--
 4 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 2890196857f8..06adcf4a6544 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -202,12 +202,6 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
goto fail;
}
 
-   ret = msm_hdmi_hpd_enable(hdmi->bridge);
-   if (ret < 0) {
-   DRM_DEV_ERROR(>pdev->dev, "failed to enable HPD: %d\n", 
ret);
-   goto fail;
-   }
-
return 0;
 
 fail:
@@ -377,9 +371,6 @@ static void msm_hdmi_unbind(struct device *dev, struct 
device *master,
if (priv->hdmi->audio_pdev)
platform_device_unregister(priv->hdmi->audio_pdev);
 
-   if (priv->hdmi->bridge)
-   msm_hdmi_hpd_disable(priv->hdmi);
-
msm_hdmi_destroy(priv->hdmi);
priv->hdmi = NULL;
}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 7f0ca5252018..c6519e6f7f2c 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -219,8 +219,8 @@ int msm_hdmi_bridge_init(struct hdmi *hdmi);
 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 *hdmi);
+void msm_hdmi_hpd_enable(struct drm_bridge *bridge);
+void msm_hdmi_hpd_disable(struct drm_bridge *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 104107ed47d0..41722b2e6b44 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -300,6 +300,9 @@ static const struct drm_bridge_funcs msm_hdmi_bridge_funcs 
= {
.mode_valid = msm_hdmi_bridge_mode_valid,
.edid_read = msm_hdmi_bridge_edid_read,
.detect = msm_hdmi_bridge_detect,
+
+   .hpd_enable = msm_hdmi_hpd_enable,
+   .hpd_disable = msm_hdmi_hpd_disable,
 };
 
 static void
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index cb89e9e2c6ea..04d00b6f36fd 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -60,7 +60,7 @@ static void msm_hdmi_phy_reset(struct hdmi *hdmi)
}
 }
 
-int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
+void msm_hdmi_hpd_enable(struct drm_bridge *bridge)
 {
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
@@ -70,8 +70,8 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
unsigned long flags;
 
ret = pm_runtime_resume_and_get(dev);
-   if (ret)
-   return ret;
+   if (WARN_ON(ret))
+   return;
 
mutex_lock(>state_mutex);
msm_hdmi_set_mode(hdmi, false);
@@ -99,12 +99,12 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
spin_unlock_irqrestore(>reg_lock, flags);
-
-   return 0;
 }
 
-void msm_hdmi_hpd_disable(struct hdmi *hdmi)
+void msm_hdmi_hpd_disable(struct drm_bridge *bridge)
 {
+   struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+   struct hdmi *hdmi = hdmi_bridge->hdmi;
struct device *dev = >pdev->dev;
 
/* Disable HPD interrupt */

-- 
2.39.2



[PATCH v2 12/14] drm/msm/hdmi: drop hpd-gpios support

2024-05-22 Thread Dmitry Baryshkov
Supporting simultaneous check of native HPD and the external GPIO proved
to be less stable than just native HPD. Drop the hpd-gpios support,
leaving just the native HPD support. In case the native HPD doesn't work
the user is urged to switch to specifying the HPD property to the
hdmi-connector device.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 14 +++---
 drivers/gpu/drm/msm/hdmi/hdmi.h |  2 --
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c | 53 +++--
 3 files changed, 7 insertions(+), 62 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index e160a23e962e..a9437054c015 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -468,17 +468,9 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk),
 "failed to get extp clock\n");
 
-   hdmi->hpd_gpiod = devm_gpiod_get_optional(>dev, "hpd", GPIOD_IN);
-   /* This will catch e.g. -EPROBE_DEFER */
-   if (IS_ERR(hdmi->hpd_gpiod))
-   return dev_err_probe(dev, PTR_ERR(hdmi->hpd_gpiod),
-"failed to get hpd gpio\n");
-
-   if (!hdmi->hpd_gpiod)
-   DBG("failed to get HPD gpio");
-
-   if (hdmi->hpd_gpiod)
-   gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD");
+   if (of_find_property(dev->of_node, "hpd-gpios", NULL) ||
+   of_find_property(dev->of_node, "hpd-gpio", NULL))
+   dev_warn(dev, "hpd-gpios is not supported anymore, please 
migrate to the hdmi-connector\n");
 
ret = msm_hdmi_get_phy(hdmi);
if (ret) {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 2a98efa8b6bd..268ff8604423 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -52,8 +52,6 @@ struct hdmi {
struct clk_bulk_data *pwr_clks;
struct clk *extp_clk;
 
-   struct gpio_desc *hpd_gpiod;
-
struct hdmi_phy *phy;
struct device *phy_dev;
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index 32e447267e3b..d3353c6148ed 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -69,9 +69,6 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
int ret;
unsigned long flags;
 
-   if (hdmi->hpd_gpiod)
-   gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
-
ret = pm_runtime_resume_and_get(dev);
if (ret)
return ret;
@@ -144,8 +141,11 @@ void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
}
 }
 
-static enum drm_connector_status detect_reg(struct hdmi *hdmi)
+enum drm_connector_status msm_hdmi_bridge_detect(
+   struct drm_bridge *bridge)
 {
+   struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
+   struct hdmi *hdmi = hdmi_bridge->hdmi;
uint32_t hpd_int_status = 0;
int ret;
 
@@ -161,48 +161,3 @@ static enum drm_connector_status detect_reg(struct hdmi 
*hdmi)
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
connector_status_connected : 
connector_status_disconnected;
 }
-
-#define HPD_GPIO_INDEX 2
-static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
-{
-   return gpiod_get_value(hdmi->hpd_gpiod) ?
-   connector_status_connected :
-   connector_status_disconnected;
-}
-
-enum drm_connector_status msm_hdmi_bridge_detect(
-   struct drm_bridge *bridge)
-{
-   struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
-   struct hdmi *hdmi = hdmi_bridge->hdmi;
-   enum drm_connector_status stat_gpio, stat_reg;
-   int retry = 20;
-
-   /*
-* some platforms may not have hpd gpio. Rely only on the status
-* provided by REG_HDMI_HPD_INT_STATUS in this case.
-*/
-   if (!hdmi->hpd_gpiod)
-   return detect_reg(hdmi);
-
-   do {
-   stat_gpio = detect_gpio(hdmi);
-   stat_reg  = detect_reg(hdmi);
-
-   if (stat_gpio == stat_reg)
-   break;
-
-   mdelay(10);
-   } while (--retry);
-
-   /* the status we get from reading gpio seems to be more reliable,
-* so trust that one the most if we didn't manage to get hdmi and
-* gpio status to agree:
-*/
-   if (stat_gpio != stat_reg) {
-   DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
-   DBG("hpd gpio tells us: %d", stat_gpio);
-   }
-
-   return stat_gpio;
-}

-- 
2.39.2



[PATCH v2 10/14] drm/msm/hdmi: rename hpd_clks to pwr_clks

2024-05-22 Thread Dmitry Baryshkov
As these clocks are now used in the runtime PM callbacks, they have no
connection to 'HPD'. Rename corresponding fields to follow clocks
purpose, to power up the HDMI controller.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 26 +-
 drivers/gpu/drm/msm/hdmi/hdmi.h |  6 +++---
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index cc671baad87b..c39a1f3a7505 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -228,19 +228,19 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
.item ## _cnt   = ARRAY_SIZE(item ## _names_ ## entry)
 
 static const char *pwr_reg_names_8960[] = {"core-vdda"};
-static const char *hpd_clk_names_8960[] = {"core", "master_iface", 
"slave_iface"};
+static const char *pwr_clk_names_8960[] = {"core", "master_iface", 
"slave_iface"};
 
 static const struct hdmi_platform_config hdmi_tx_8960_config = {
HDMI_CFG(pwr_reg, 8960),
-   HDMI_CFG(hpd_clk, 8960),
+   HDMI_CFG(pwr_clk, 8960),
 };
 
 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
-static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
+static const char *pwr_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
 
 static const struct hdmi_platform_config hdmi_tx_8974_config = {
HDMI_CFG(pwr_reg, 8x74),
-   HDMI_CFG(hpd_clk, 8x74),
+   HDMI_CFG(pwr_clk, 8x74),
 };
 
 /*
@@ -449,17 +449,17 @@ static int msm_hdmi_dev_probe(struct platform_device 
*pdev)
if (ret)
return dev_err_probe(dev, ret, "failed to get pwr 
regulators\n");
 
-   hdmi->hpd_clks = devm_kcalloc(>dev,
- config->hpd_clk_cnt,
- sizeof(hdmi->hpd_clks[0]),
+   hdmi->pwr_clks = devm_kcalloc(>dev,
+ config->pwr_clk_cnt,
+ sizeof(hdmi->pwr_clks[0]),
  GFP_KERNEL);
-   if (!hdmi->hpd_clks)
+   if (!hdmi->pwr_clks)
return -ENOMEM;
 
-   for (i = 0; i < config->hpd_clk_cnt; i++)
-   hdmi->hpd_clks[i].id = config->hpd_clk_names[i];
+   for (i = 0; i < config->pwr_clk_cnt; i++)
+   hdmi->pwr_clks[i].id = config->pwr_clk_names[i];
 
-   ret = devm_clk_bulk_get(>dev, config->hpd_clk_cnt, 
hdmi->hpd_clks);
+   ret = devm_clk_bulk_get(>dev, config->pwr_clk_cnt, 
hdmi->pwr_clks);
if (ret)
return ret;
 
@@ -517,7 +517,7 @@ static int msm_hdmi_runtime_suspend(struct device *dev)
struct hdmi *hdmi = dev_get_drvdata(dev);
const struct hdmi_platform_config *config = hdmi->config;
 
-   clk_bulk_disable_unprepare(config->hpd_clk_cnt, hdmi->hpd_clks);
+   clk_bulk_disable_unprepare(config->pwr_clk_cnt, hdmi->pwr_clks);
 
pinctrl_pm_select_sleep_state(dev);
 
@@ -540,7 +540,7 @@ static int msm_hdmi_runtime_resume(struct device *dev)
if (ret)
goto fail;
 
-   ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
+   ret = clk_bulk_prepare_enable(config->pwr_clk_cnt, hdmi->pwr_clks);
if (ret)
goto fail;
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index ee5463eb41b6..1e346e697f8e 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -49,7 +49,7 @@ struct hdmi {
phys_addr_t mmio_phy_addr;
 
struct regulator_bulk_data *pwr_regs;
-   struct clk_bulk_data *hpd_clks;
+   struct clk_bulk_data *pwr_clks;
struct clk *extp_clk;
 
struct gpio_desc *hpd_gpiod;
@@ -90,8 +90,8 @@ struct hdmi_platform_config {
int pwr_reg_cnt;
 
/* clks that need to be on for hpd: */
-   const char **hpd_clk_names;
-   int hpd_clk_cnt;
+   const char **pwr_clk_names;
+   int pwr_clk_cnt;
 };
 
 struct hdmi_bridge {

-- 
2.39.2



[PATCH v2 06/14] drm/msm/hdmi: switch to clk_bulk API

2024-05-22 Thread Dmitry Baryshkov
The last platform using legacy clock names for HDMI block (APQ8064)
switched to new clock names in 5.16. It's time to stop caring about old
DT, drop hand-coded helpers and switch to clk_bulk_* API.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 15 +-
 drivers/gpu/drm/msm/hdmi/hdmi.h |  2 +-
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c | 39 +
 3 files changed, 19 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index c14e009f38b1..7ec4ca3b7597 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -469,17 +469,12 @@ static int msm_hdmi_dev_probe(struct platform_device 
*pdev)
if (!hdmi->hpd_clks)
return -ENOMEM;
 
-   for (i = 0; i < config->hpd_clk_cnt; i++) {
-   struct clk *clk;
+   for (i = 0; i < config->hpd_clk_cnt; i++)
+   hdmi->hpd_clks[i].id = config->hpd_clk_names[i];
 
-   clk = msm_clk_get(pdev, config->hpd_clk_names[i]);
-   if (IS_ERR(clk))
-   return dev_err_probe(dev, PTR_ERR(clk),
-"failed to get hpd clk: %s\n",
-config->hpd_clk_names[i]);
-
-   hdmi->hpd_clks[i] = clk;
-   }
+   ret = devm_clk_bulk_get(>dev, config->hpd_clk_cnt, 
hdmi->hpd_clks);
+   if (ret)
+   return ret;
 
hdmi->extp_clk = devm_clk_get_optional(>dev, "extp");
if (IS_ERR(hdmi->extp_clk))
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index c0d60ed23b75..eeba85ffef09 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -50,7 +50,7 @@ struct hdmi {
 
struct regulator_bulk_data *hpd_regs;
struct regulator_bulk_data *pwr_regs;
-   struct clk **hpd_clks;
+   struct clk_bulk_data *hpd_clks;
struct clk *extp_clk;
 
struct gpio_desc *hpd_gpiod;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index 7ae69b14e953..36266aa626dc 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -60,27 +60,6 @@ static void msm_hdmi_phy_reset(struct hdmi *hdmi)
}
 }
 
-static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
-{
-   const struct hdmi_platform_config *config = hdmi->config;
-   struct device *dev = >pdev->dev;
-   int i, ret;
-
-   if (enable) {
-   for (i = 0; i < config->hpd_clk_cnt; i++) {
-   ret = clk_prepare_enable(hdmi->hpd_clks[i]);
-   if (ret) {
-   DRM_DEV_ERROR(dev,
-   "failed to enable hpd clk: %s (%d)\n",
-   config->hpd_clk_names[i], ret);
-   }
-   }
-   } else {
-   for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
-   clk_disable_unprepare(hdmi->hpd_clks[i]);
-   }
-}
-
 int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
 {
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
@@ -107,7 +86,9 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
 
pm_runtime_get_sync(dev);
-   enable_hpd_clocks(hdmi, true);
+   ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
+   if (ret)
+   goto fail;
 
msm_hdmi_set_mode(hdmi, false);
msm_hdmi_phy_reset(hdmi);
@@ -149,7 +130,7 @@ void msm_hdmi_hpd_disable(struct hdmi *hdmi)
 
msm_hdmi_set_mode(hdmi, false);
 
-   enable_hpd_clocks(hdmi, false);
+   clk_bulk_disable_unprepare(config->hpd_clk_cnt, hdmi->hpd_clks);
pm_runtime_put(dev);
 
ret = pinctrl_pm_select_sleep_state(dev);
@@ -193,14 +174,20 @@ void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
 
 static enum drm_connector_status detect_reg(struct hdmi *hdmi)
 {
-   uint32_t hpd_int_status;
+   const struct hdmi_platform_config *config = hdmi->config;
+   uint32_t hpd_int_status = 0;
+   int ret;
 
pm_runtime_get_sync(>pdev->dev);
-   enable_hpd_clocks(hdmi, true);
+   ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
+   if (ret)
+   goto out;
 
hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
 
-   enable_hpd_clocks(hdmi, false);
+   clk_bulk_disable_unprepare(config->hpd_clk_cnt, hdmi->hpd_clks);
+
+out:
pm_runtime_put(>pdev->dev);
 
return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?

-- 
2.39.2



[PATCH v2 01/14] drm/msm/hdmi: move the alt_iface clock to the hpd list

2024-05-22 Thread Dmitry Baryshkov
According to the vendor kernel [1] , the alt_iface clock should be
enabled together with the rest of HPD clocks, to make HPD to work
properly.

[1] 
https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/e07a5487e521e57f76083c0a6e2f995414ac6d03

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 24abcb7254cc..108c86925780 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -235,9 +235,9 @@ static const struct hdmi_platform_config 
hdmi_tx_8960_config = {
 };
 
 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
-static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"};
-static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"};
-static unsigned long hpd_clk_freq_8x74[] = {0, 1920, 0};
+static const char *pwr_clk_names_8x74[] = {"extp"};
+static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
+static unsigned long hpd_clk_freq_8x74[] = {0, 1920, 0, 0};
 
 static const struct hdmi_platform_config hdmi_tx_8974_config = {
HDMI_CFG(pwr_reg, 8x74),

-- 
2.39.2



[PATCH v2 09/14] drm/msm/hdmi: implement proper runtime PM handling

2024-05-22 Thread Dmitry Baryshkov
It is completely not obvious, but the so-called 'hpd' clocks and
regulators are required for the HDMI host to function properly. Merge
pwr and hpd regulators. Use regulators, clocks and pinctrl to implement
proper runtime PM callbacks.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c| 62 +-
 drivers/gpu/drm/msm/hdmi/hdmi.h|  7 +---
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 12 ---
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c| 42 +--
 4 files changed, 48 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 7ec4ca3b7597..cc671baad87b 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
@@ -226,11 +227,11 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
.item ## _names = item ##_names_ ## entry, \
.item ## _cnt   = ARRAY_SIZE(item ## _names_ ## entry)
 
-static const char *hpd_reg_names_8960[] = {"core-vdda"};
+static const char *pwr_reg_names_8960[] = {"core-vdda"};
 static const char *hpd_clk_names_8960[] = {"core", "master_iface", 
"slave_iface"};
 
 static const struct hdmi_platform_config hdmi_tx_8960_config = {
-   HDMI_CFG(hpd_reg, 8960),
+   HDMI_CFG(pwr_reg, 8960),
HDMI_CFG(hpd_clk, 8960),
 };
 
@@ -434,20 +435,6 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev)
if (hdmi->irq < 0)
return hdmi->irq;
 
-   hdmi->hpd_regs = devm_kcalloc(>dev,
- config->hpd_reg_cnt,
- sizeof(hdmi->hpd_regs[0]),
- GFP_KERNEL);
-   if (!hdmi->hpd_regs)
-   return -ENOMEM;
-
-   for (i = 0; i < config->hpd_reg_cnt; i++)
-   hdmi->hpd_regs[i].supply = config->hpd_reg_names[i];
-
-   ret = devm_regulator_bulk_get(>dev, config->hpd_reg_cnt, 
hdmi->hpd_regs);
-   if (ret)
-   return dev_err_probe(dev, ret, "failed to get hpd 
regulators\n");
-
hdmi->pwr_regs = devm_kcalloc(>dev,
  config->pwr_reg_cnt,
  sizeof(hdmi->pwr_regs[0]),
@@ -525,6 +512,48 @@ static void msm_hdmi_dev_remove(struct platform_device 
*pdev)
msm_hdmi_put_phy(hdmi);
 }
 
+static int msm_hdmi_runtime_suspend(struct device *dev)
+{
+   struct hdmi *hdmi = dev_get_drvdata(dev);
+   const struct hdmi_platform_config *config = hdmi->config;
+
+   clk_bulk_disable_unprepare(config->hpd_clk_cnt, hdmi->hpd_clks);
+
+   pinctrl_pm_select_sleep_state(dev);
+
+   regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs);
+
+   return 0;
+}
+
+static int msm_hdmi_runtime_resume(struct device *dev)
+{
+   struct hdmi *hdmi = dev_get_drvdata(dev);
+   const struct hdmi_platform_config *config = hdmi->config;
+   int ret;
+
+   ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
+   if (ret)
+   return ret;
+
+   ret = pinctrl_pm_select_default_state(dev);
+   if (ret)
+   goto fail;
+
+   ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
+   if (ret)
+   goto fail;
+
+   return 0;
+
+fail:
+   pinctrl_pm_select_sleep_state(dev);
+
+   return ret;
+}
+
+DEFINE_RUNTIME_DEV_PM_OPS(msm_hdmi_pm_ops, msm_hdmi_runtime_suspend, 
msm_hdmi_runtime_resume, NULL);
+
 static const struct of_device_id msm_hdmi_dt_match[] = {
{ .compatible = "qcom,hdmi-tx-8996", .data = _tx_8974_config },
{ .compatible = "qcom,hdmi-tx-8994", .data = _tx_8974_config },
@@ -541,6 +570,7 @@ static struct platform_driver msm_hdmi_driver = {
.driver = {
.name = "hdmi_msm",
.of_match_table = msm_hdmi_dt_match,
+   .pm = _hdmi_pm_ops,
},
 };
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index eeba85ffef09..ee5463eb41b6 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -48,7 +48,6 @@ struct hdmi {
void __iomem *qfprom_mmio;
phys_addr_t mmio_phy_addr;
 
-   struct regulator_bulk_data *hpd_regs;
struct regulator_bulk_data *pwr_regs;
struct clk_bulk_data *hpd_clks;
struct clk *extp_clk;
@@ -86,11 +85,7 @@ struct hdmi {
 
 /* platform config data (ie. from DT, or pdata) */
 struct hdmi_platform_config {
-   /* regulators that need to be on for hpd: */
-   const char **hpd_reg_names;
-   int hpd_reg_cnt;
-
-   /* regulators that need to be on for screen pwr: */
+   /* regulators that need to be on: */
const char **pwr_reg_names;
int pwr_reg_cnt;
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 

[PATCH v2 08/14] drm/msm/hdmi: add runtime PM calls to DDC transfer function

2024-05-22 Thread Dmitry Baryshkov
We must be sure that the HDMI controller is powered on, while performing
the DDC transfer. Add corresponding runtime PM calls to
msm_hdmi_i2c_xfer().

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi_i2c.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c
index 7aa500d24240..ebefea4fb408 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c
@@ -107,11 +107,15 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
if (num == 0)
return num;
 
+   ret = pm_runtime_resume_and_get(>pdev->dev);
+   if (ret)
+   return ret;
+
init_ddc(hdmi_i2c);
 
ret = ddc_clear_irq(hdmi_i2c);
if (ret)
-   return ret;
+   goto fail;
 
for (i = 0; i < num; i++) {
struct i2c_msg *p = [i];
@@ -169,7 +173,7 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS),
hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS),
hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL));
-   return ret;
+   goto fail;
}
 
ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS);
@@ -202,7 +206,13 @@ static int msm_hdmi_i2c_xfer(struct i2c_adapter *i2c,
}
}
 
+   pm_runtime_put(>pdev->dev);
+
return i;
+
+fail:
+   pm_runtime_put(>pdev->dev);
+   return ret;
 }
 
 static u32 msm_hdmi_i2c_func(struct i2c_adapter *adapter)

-- 
2.39.2



[PATCH v2 05/14] drm/msm/hdmi: drop clock frequency assignment

2024-05-22 Thread Dmitry Baryshkov
The only clock which has frequency being set through hpd_freqs is the
"core" aka MDSS_HDMI_CLK clock. It always has the specified frequency,
so we can drop corresponding clk_set_rate() call together with the
hpd_freq infrastructure.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c | 2 --
 drivers/gpu/drm/msm/hdmi/hdmi.h | 1 -
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c | 9 -
 3 files changed, 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 681265e29aa0..c14e009f38b1 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -236,12 +236,10 @@ static const struct hdmi_platform_config 
hdmi_tx_8960_config = {
 
 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
 static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
-static unsigned long hpd_clk_freq_8x74[] = {0, 1920, 0, 0};
 
 static const struct hdmi_platform_config hdmi_tx_8974_config = {
HDMI_CFG(pwr_reg, 8x74),
HDMI_CFG(hpd_clk, 8x74),
-   .hpd_freq  = hpd_clk_freq_8x74,
 };
 
 /*
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index abdbe4779cf9..c0d60ed23b75 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -96,7 +96,6 @@ struct hdmi_platform_config {
 
/* clks that need to be on for hpd: */
const char **hpd_clk_names;
-   const long unsigned *hpd_freq;
int hpd_clk_cnt;
 };
 
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index 9ce0ffa35417..7ae69b14e953 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -68,15 +68,6 @@ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
 
if (enable) {
for (i = 0; i < config->hpd_clk_cnt; i++) {
-   if (config->hpd_freq && config->hpd_freq[i]) {
-   ret = clk_set_rate(hdmi->hpd_clks[i],
-  config->hpd_freq[i]);
-   if (ret)
-   dev_warn(dev,
-"failed to set clk %s (%d)\n",
-config->hpd_clk_names[i], ret);
-   }
-
ret = clk_prepare_enable(hdmi->hpd_clks[i]);
if (ret) {
DRM_DEV_ERROR(dev,

-- 
2.39.2



[PATCH v2 07/14] drm/msm/hdmi: switch to pm_runtime_resume_and_get()

2024-05-22 Thread Dmitry Baryshkov
The pm_runtime_get_sync() function is a bad choise for runtime power
management. Switch HDMI driver to pm_runtime_resume_and_get() and add
proper error handling, while we are at it.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |  2 +-
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c| 12 ++--
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c|  6 +-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index fb99328107dd..d1b35328b6e8 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -19,7 +19,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
const struct hdmi_platform_config *config = hdmi->config;
int ret;
 
-   pm_runtime_get_sync(>pdev->dev);
+   pm_runtime_resume_and_get(>pdev->dev);
 
ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs);
if (ret)
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
index 36266aa626dc..fc21ad3b01dc 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_hpd.c
@@ -85,7 +85,12 @@ int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
if (hdmi->hpd_gpiod)
gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
 
-   pm_runtime_get_sync(dev);
+   ret = pm_runtime_resume_and_get(dev);
+   if (ret) {
+   DRM_DEV_ERROR(dev, "runtime resume failed: %d\n", ret);
+   goto fail;
+   }
+
ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
if (ret)
goto fail;
@@ -178,7 +183,10 @@ static enum drm_connector_status detect_reg(struct hdmi 
*hdmi)
uint32_t hpd_int_status = 0;
int ret;
 
-   pm_runtime_get_sync(>pdev->dev);
+   ret = pm_runtime_resume_and_get(>pdev->dev);
+   if (ret)
+   goto out;
+
ret = clk_bulk_prepare_enable(config->hpd_clk_cnt, hdmi->hpd_clks);
if (ret)
goto out;
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
index 88a3423b7f24..d5acae752300 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c
@@ -58,7 +58,11 @@ int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy)
struct device *dev = >pdev->dev;
int i, ret = 0;
 
-   pm_runtime_get_sync(dev);
+   ret = pm_runtime_resume_and_get(dev);
+   if (ret) {
+   DRM_DEV_ERROR(dev, "runtime resume failed: %d\n", ret);
+   return ret;
+   }
 
ret = regulator_bulk_enable(cfg->num_regs, phy->regs);
if (ret) {

-- 
2.39.2



[PATCH v2 04/14] drm/msm/hdmi: set infoframes on all pre_enable calls

2024-05-22 Thread Dmitry Baryshkov
In consequent modeset calls, the atomic_pre_enable() will be called
several times without calling atomic_post_disable() inbetween. Thus
iframes will not be updated for the next mode. Fix this by setting the
iframe outside of the !power_on check.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 3c6121c57b01..fb99328107dd 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -133,10 +133,11 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct 
drm_bridge *bridge,
msm_hdmi_phy_resource_enable(phy);
msm_hdmi_power_on(bridge);
hdmi->power_on = true;
-   if (hdmi->hdmi_mode) {
-   msm_hdmi_config_avi_infoframe(hdmi);
-   msm_hdmi_audio_update(hdmi);
-   }
+   }
+
+   if (hdmi->hdmi_mode) {
+   msm_hdmi_config_avi_infoframe(hdmi);
+   msm_hdmi_audio_update(hdmi);
}
 
msm_hdmi_phy_powerup(phy, hdmi->pixclock);

-- 
2.39.2



[PATCH v2 03/14] drm/msm/hdmi: switch to atomic_pre_enable/post_disable

2024-05-22 Thread Dmitry Baryshkov
In preparation of reworking the HDMI mode setting, switch pre_enable and
post_disable callbacks to their atomic variants.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 9eb4d06bdc0e..3c6121c57b01 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -120,7 +120,8 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi)
hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val);
 }
 
-static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge)
+static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge,
+ struct drm_bridge_state 
*old_bridge_state)
 {
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
@@ -146,7 +147,8 @@ static void msm_hdmi_bridge_pre_enable(struct drm_bridge 
*bridge)
msm_hdmi_hdcp_on(hdmi->hdcp_ctrl);
 }
 
-static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge)
+static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge,
+   struct drm_bridge_state 
*old_bridge_state)
 {
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
@@ -292,8 +294,13 @@ static enum drm_mode_status 
msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge
 }
 
 static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = {
-   .pre_enable = msm_hdmi_bridge_pre_enable,
-   .post_disable = msm_hdmi_bridge_post_disable,
+   .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
+   .atomic_reset = drm_atomic_helper_bridge_reset,
+
+   .atomic_pre_enable = msm_hdmi_bridge_atomic_pre_enable,
+   .atomic_post_disable = msm_hdmi_bridge_atomic_post_disable,
+
.mode_set = msm_hdmi_bridge_mode_set,
.mode_valid = msm_hdmi_bridge_mode_valid,
.edid_read = msm_hdmi_bridge_edid_read,

-- 
2.39.2



[PATCH v2 02/14] drm/msm/hdmi: simplify extp clock handling

2024-05-22 Thread Dmitry Baryshkov
With the extp being the only "power" clock left, remove the surrounding
loops and handle the extp clock directly.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/msm/hdmi/hdmi.c| 24 
 drivers/gpu/drm/msm/hdmi/hdmi.h|  6 +-
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 33 +
 3 files changed, 18 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
index 108c86925780..681265e29aa0 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.c
@@ -235,13 +235,11 @@ static const struct hdmi_platform_config 
hdmi_tx_8960_config = {
 };
 
 static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"};
-static const char *pwr_clk_names_8x74[] = {"extp"};
 static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", 
"alt_iface"};
 static unsigned long hpd_clk_freq_8x74[] = {0, 1920, 0, 0};
 
 static const struct hdmi_platform_config hdmi_tx_8974_config = {
HDMI_CFG(pwr_reg, 8x74),
-   HDMI_CFG(pwr_clk, 8x74),
HDMI_CFG(hpd_clk, 8x74),
.hpd_freq  = hpd_clk_freq_8x74,
 };
@@ -485,24 +483,10 @@ static int msm_hdmi_dev_probe(struct platform_device 
*pdev)
hdmi->hpd_clks[i] = clk;
}
 
-   hdmi->pwr_clks = devm_kcalloc(>dev,
- config->pwr_clk_cnt,
- sizeof(hdmi->pwr_clks[0]),
- GFP_KERNEL);
-   if (!hdmi->pwr_clks)
-   return -ENOMEM;
-
-   for (i = 0; i < config->pwr_clk_cnt; i++) {
-   struct clk *clk;
-
-   clk = msm_clk_get(pdev, config->pwr_clk_names[i]);
-   if (IS_ERR(clk))
-   return dev_err_probe(dev, PTR_ERR(clk),
-"failed to get pwr clk: %s\n",
-config->pwr_clk_names[i]);
-
-   hdmi->pwr_clks[i] = clk;
-   }
+   hdmi->extp_clk = devm_clk_get_optional(>dev, "extp");
+   if (IS_ERR(hdmi->extp_clk))
+   return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk),
+"failed to get extp clock\n");
 
hdmi->hpd_gpiod = devm_gpiod_get_optional(>dev, "hpd", GPIOD_IN);
/* This will catch e.g. -EPROBE_DEFER */
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
index 4586baf36415..abdbe4779cf9 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi.h
+++ b/drivers/gpu/drm/msm/hdmi/hdmi.h
@@ -51,7 +51,7 @@ struct hdmi {
struct regulator_bulk_data *hpd_regs;
struct regulator_bulk_data *pwr_regs;
struct clk **hpd_clks;
-   struct clk **pwr_clks;
+   struct clk *extp_clk;
 
struct gpio_desc *hpd_gpiod;
 
@@ -98,10 +98,6 @@ struct hdmi_platform_config {
const char **hpd_clk_names;
const long unsigned *hpd_freq;
int hpd_clk_cnt;
-
-   /* clks that need to be on for screen pwr (ie pixel clk): */
-   const char **pwr_clk_names;
-   int pwr_clk_cnt;
 };
 
 struct hdmi_bridge {
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c 
b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
index 4a5b5112227f..9eb4d06bdc0e 100644
--- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
+++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c
@@ -17,7 +17,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
struct hdmi *hdmi = hdmi_bridge->hdmi;
const struct hdmi_platform_config *config = hdmi->config;
-   int i, ret;
+   int ret;
 
pm_runtime_get_sync(>pdev->dev);
 
@@ -25,21 +25,15 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge)
if (ret)
DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", 
ret);
 
-   if (config->pwr_clk_cnt > 0) {
+   if (hdmi->extp_clk) {
DBG("pixclock: %lu", hdmi->pixclock);
-   ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock);
-   if (ret) {
-   DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s 
(%d)\n",
-   config->pwr_clk_names[0], ret);
-   }
-   }
+   ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock);
+   if (ret)
+   DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: 
%d\n", ret);
 
-   for (i = 0; i < config->pwr_clk_cnt; i++) {
-   ret = clk_prepare_enable(hdmi->pwr_clks[i]);
-   if (ret) {
-   DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s 
(%d)\n",
-   config->pwr_clk_names[i], ret);
-   }
+   ret = clk_prepare_enable(hdmi->extp_clk);
+   if (ret)
+   DRM_DEV_ERROR(dev->dev, 

[PATCH v2 00/14] drm/msm/hdmi: rework and fix the HPD even generation

2024-05-22 Thread Dmitry Baryshkov
The MSM HDMI driver is plagued with the long-standing bug. If HDMI cable
is disconnected, in most of the cases cable reconnection will not be
detected properly. We have been carrying the patch from [1] in our
integration tree for ages. The time has come to fix the long-standing
bug and implement proper HPD handling.

This series was tested on msm8996 and apq8064 boards. Previously HPD
handling sometimes could trigger in the CRTC event handling, however I
can no longer reproduce it now.

[1] 
https://lore.kernel.org/linux-arm-msm/20171027105732.19235-2-arch...@codeaurora.org/

---
Dmitry Baryshkov (14):
  drm/msm/hdmi: move the alt_iface clock to the hpd list
  drm/msm/hdmi: simplify extp clock handling
  drm/msm/hdmi: switch to atomic_pre_enable/post_disable
  drm/msm/hdmi: set infoframes on all pre_enable calls
  drm/msm/hdmi: drop clock frequency assignment
  drm/msm/hdmi: switch to clk_bulk API
  drm/msm/hdmi: switch to pm_runtime_resume_and_get()
  drm/msm/hdmi: add runtime PM calls to DDC transfer function
  drm/msm/hdmi: implement proper runtime PM handling
  drm/msm/hdmi: rename hpd_clks to pwr_clks
  drm/msm/hdmi: expand the HDMI_CFG macro
  drm/msm/hdmi: drop hpd-gpios support
  drm/msm/hdmi: ensure that HDMI is one if HPD is requested
  drm/msm/hdmi: wire in hpd_enable/hpd_disable bridge ops

 drivers/gpu/drm/msm/hdmi/hdmi.c| 145 -
 drivers/gpu/drm/msm/hdmi/hdmi.h|  26 ++
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c |  80 +-
 drivers/gpu/drm/msm/hdmi/hdmi_hpd.c| 142 ++--
 drivers/gpu/drm/msm/hdmi/hdmi_i2c.c|  14 +++-
 drivers/gpu/drm/msm/hdmi/hdmi_phy.c|   6 +-
 6 files changed, 157 insertions(+), 256 deletions(-)
---
base-commit: 8314289a8d50a4e05d8ece1ae0445a3b57bb4d3b
change-id: 20240522-fd-hdmi-hpd-e3868deb6ae0

Best regards,
-- 
Dmitry Baryshkov 



[PATCH v2] Revert "drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set"

2024-05-22 Thread Dmitry Baryshkov
In the DPU driver blank IRQ handling is called from a vblank worker and
can happen outside of the irq_enable / irq_disable pair. Using the
worker makes that completely asynchronous with the rest of the code.
Revert commit d13f638c9b88 ("drm/msm/dpu: drop
dpu_encoder_phys_ops.atomic_mode_set") to fix vblank IRQ assignment for
CMD DSI panels.

Call trace:
 dpu_encoder_phys_cmd_control_vblank_irq+0x218/0x294
  dpu_encoder_toggle_vblank_for_crtc+0x160/0x194
  dpu_crtc_vblank+0xbc/0x228
  dpu_kms_enable_vblank+0x18/0x24
  vblank_ctrl_worker+0x34/0x6c
  process_one_work+0x218/0x620
  worker_thread+0x1ac/0x37c
  kthread+0x114/0x118
  ret_from_fork+0x10/0x20

Fixes: d13f638c9b88 ("drm/msm/dpu: drop dpu_encoder_phys_ops.atomic_mode_set")
Signed-off-by: Dmitry Baryshkov 
---
Changes in v2:
- Expanded commit message to describe the reason for revert and added a
  call trace (Abhinav)
- Link to v1: 
https://lore.kernel.org/r/20240514-dpu-revert-ams-v1-1-b13623d6c...@linaro.org
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c|  2 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h   |  5 
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c   | 32 --
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c   | 13 +++--
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 11 +++-
 5 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 119f3ea50a7c..a7d8ecf3f5be 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1200,6 +1200,8 @@ static void dpu_encoder_virt_atomic_mode_set(struct 
drm_encoder *drm_enc,
phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]);
 
phys->cached_mode = crtc_state->adjusted_mode;
+   if (phys->ops.atomic_mode_set)
+   phys->ops.atomic_mode_set(phys, crtc_state, conn_state);
}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h 
b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index 002e89cc1705..30470cd15a48 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -69,6 +69,8 @@ struct dpu_encoder_phys;
  * @is_master: Whether this phys_enc is the current master
  * encoder. Can be switched at enable time. Based
  * on split_role and current mode (CMD/VID).
+ * @atomic_mode_set:   DRM Call. Set a DRM mode.
+ * This likely caches the mode, for use at enable.
  * @enable:DRM Call. Enable a DRM mode.
  * @disable:   DRM Call. Disable mode.
  * @control_vblank_irq Register/Deregister for VBLANK IRQ
@@ -93,6 +95,9 @@ struct dpu_encoder_phys;
 struct dpu_encoder_phys_ops {
void (*prepare_commit)(struct dpu_encoder_phys *encoder);
bool (*is_master)(struct dpu_encoder_phys *encoder);
+   void (*atomic_mode_set)(struct dpu_encoder_phys *encoder,
+   struct drm_crtc_state *crtc_state,
+   struct drm_connector_state *conn_state);
void (*enable)(struct dpu_encoder_phys *encoder);
void (*disable)(struct dpu_encoder_phys *encoder);
int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable);
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 489be1c0c704..95cd39b49668 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
@@ -142,6 +142,23 @@ static void dpu_encoder_phys_cmd_underrun_irq(void *arg)
dpu_encoder_underrun_callback(phys_enc->parent, phys_enc);
 }
 
+static void dpu_encoder_phys_cmd_atomic_mode_set(
+   struct dpu_encoder_phys *phys_enc,
+   struct drm_crtc_state *crtc_state,
+   struct drm_connector_state *conn_state)
+{
+   phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
+
+   phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
+
+   if (phys_enc->has_intf_te)
+   phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_intf->cap->intr_tear_rd_ptr;
+   else
+   phys_enc->irq[INTR_IDX_RDPTR] = 
phys_enc->hw_pp->caps->intr_rdptr;
+
+   phys_enc->irq[INTR_IDX_UNDERRUN] = 
phys_enc->hw_intf->cap->intr_underrun;
+}
+
 static int _dpu_encoder_phys_cmd_handle_ppdone_timeout(
struct dpu_encoder_phys *phys_enc)
 {
@@ -280,14 +297,6 @@ static void dpu_encoder_phys_cmd_irq_enable(struct 
dpu_encoder_phys *phys_enc)
  phys_enc->hw_pp->idx - PINGPONG_0,
  phys_enc->vblank_refcount);
 
-   phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
-   

[PATCH v3 3/3] drm/panel/lg-sw43408: mark sw43408_backlight_ops as static

2024-05-22 Thread Dmitry Baryshkov
Fix sparse warning regarding symbol 'sw43408_backlight_ops' not being
declared.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202404200739.hbwzvohr-...@intel.com/
Reviewed-by: Neil Armstrong 
Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/panel/panel-lg-sw43408.c 
b/drivers/gpu/drm/panel/panel-lg-sw43408.c
index 115f4702d59f..2b3a73696dce 100644
--- a/drivers/gpu/drm/panel/panel-lg-sw43408.c
+++ b/drivers/gpu/drm/panel/panel-lg-sw43408.c
@@ -182,7 +182,7 @@ static int sw43408_backlight_update_status(struct 
backlight_device *bl)
return mipi_dsi_dcs_set_display_brightness_large(dsi, brightness);
 }
 
-const struct backlight_ops sw43408_backlight_ops = {
+static const struct backlight_ops sw43408_backlight_ops = {
.update_status = sw43408_backlight_update_status,
 };
 

-- 
2.39.2



[PATCH v3 1/3] drm/display: split DSC helpers from DP helpers

2024-05-22 Thread Dmitry Baryshkov
Currently the DRM DSC functions are selected by the
DRM_DISPLAY_DP_HELPER Kconfig symbol. This is not optimal, since the DSI
code (both panel and host drivers) end up selecting the seemingly
irrelevant DP helpers. Split the DSC code to be guarded by the separate
DRM_DISPLAY_DSC_HELPER Kconfig symbol.

Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/amd/amdgpu/Kconfig | 1 +
 drivers/gpu/drm/display/Kconfig| 6 ++
 drivers/gpu/drm/display/Makefile   | 3 ++-
 drivers/gpu/drm/i915/Kconfig   | 1 +
 drivers/gpu/drm/msm/Kconfig| 1 +
 drivers/gpu/drm/panel/Kconfig  | 4 ++--
 6 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 22d88f8ef527..b69d5c4a5367 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -6,6 +6,7 @@ config DRM_AMDGPU
depends on !UML
select FW_LOADER
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 864a6488bfdf..f524cf95dec3 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -59,6 +59,12 @@ config DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG
 
  If in doubt, say "N".
 
+config DRM_DISPLAY_DSC_HELPER
+   bool
+   depends on DRM_DISPLAY_HELPER
+   help
+ DRM display helpers for VESA DSC (used by DSI and DisplayPort).
+
 config DRM_DISPLAY_HDCP_HELPER
bool
depends on DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 17d2cc73ff56..2ec71e15c3cb 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -6,7 +6,8 @@ drm_display_helper-y := drm_display_helper_mod.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \
drm_dp_dual_mode_helper.o \
drm_dp_helper.o \
-   drm_dp_mst_topology.o \
+   drm_dp_mst_topology.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \
drm_dsc_helper.o
 drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \
drm_dp_tunnel.o
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index 5932024f8f95..117b84260b1c 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -11,6 +11,7 @@ config DRM_I915
select SHMEM
select TMPFS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 1931ecf73e32..6dcd26180611 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -111,6 +111,7 @@ config DRM_MSM_DSI
depends on DRM_MSM
select DRM_PANEL
select DRM_MIPI_DSI
+   select DRM_DISPLAY_DSC_HELPER
default y
help
  Choose this option if you have a need for MIPI DSI connector
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 982324ef5a41..4a2f621433ef 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -547,7 +547,7 @@ config DRM_PANEL_RAYDIUM_RM692E5
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
-   select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HELPER
help
  Say Y here if you want to enable support for Raydium RM692E5-based
@@ -905,7 +905,7 @@ config DRM_PANEL_VISIONOX_R66451
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
-   select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HELPER
help
  Say Y here if you want to enable support for Visionox

-- 
2.39.2



[PATCH v3 2/3] drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER

2024-05-22 Thread Dmitry Baryshkov
This panel driver uses DSC PPS functions and as such depends on the
DRM_DISPLAY_DP_HELPER. Select this symbol to make required functions
available to the driver.

Reported-by: kernel test robot 
Closes: 
https://lore.kernel.org/oe-kbuild-all/202404200800.kysryyli-...@intel.com/
Fixes: 069a6c0e94f9 ("drm: panel: Add LG sw43408 panel driver")
Signed-off-by: Dmitry Baryshkov 
---
 drivers/gpu/drm/panel/Kconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 4a2f621433ef..3e3f63479544 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -340,6 +340,8 @@ config DRM_PANEL_LG_SW43408
depends on OF
depends on DRM_MIPI_DSI
depends on BACKLIGHT_CLASS_DEVICE
+   select DRM_DISPLAY_DSC_HELPER
+   select DRM_DISPLAY_HELPER
help
  Say Y here if you want to enable support for LG sw43408 panel.
  The panel has a 1080x2160@60Hz resolution and uses 24 bit RGB per

-- 
2.39.2



[PATCH v3 0/3] drm/panel: two fixes for lg-sw43408

2024-05-22 Thread Dmitry Baryshkov
Fix two issues with the panel-lg-sw43408 driver reported by the kernel
test robot.

To: Neil Armstrong 
To: Jessica Zhang 
To: Sam Ravnborg 
To: Maarten Lankhorst 
To: Maxime Ripard 
To: Thomas Zimmermann 
To: David Airlie 
To: Daniel Vetter 
To: Sumit Semwal 
To: Caleb Connolly 
To: Alex Deucher 
To: Christian König 
To: Pan, Xinhui 
To: Jani Nikula 
To: Joonas Lahtinen 
To: Rodrigo Vivi 
To: Tvrtko Ursulin 
To: Rob Clark 
To: Abhinav Kumar 
To: Sean Paul 
To: Marijn Suijten 
To: Vinod Koul 
To: Caleb Connolly 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc: amd-...@lists.freedesktop.org
Cc: intel-...@lists.freedesktop.org
Cc: linux-arm-...@vger.kernel.org
Cc: freedreno@lists.freedesktop.org
Signed-off-by: Dmitry Baryshkov 

Changes in v3:
- Split DRM_DISPLAY_DSC_HELPER from DRM_DISPLAY_DP_HELPER
- Added missing Fixes tags
- Link to v2: 
https://lore.kernel.org/r/20240510-panel-sw43408-fix-v2-0-d1ef91ee1...@linaro.org

Changes in v2:
- use SELECT instead of DEPEND to follow the reverted Kconfig changes
- Link to v1: 
https://lore.kernel.org/r/20240420-panel-sw43408-fix-v1-0-b282ff725...@linaro.org

---
Dmitry Baryshkov (3):
  drm/display: split DSC helpers from DP helpers
  drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER
  drm/panel/lg-sw43408: mark sw43408_backlight_ops as static

 drivers/gpu/drm/amd/amdgpu/Kconfig   | 1 +
 drivers/gpu/drm/display/Kconfig  | 6 ++
 drivers/gpu/drm/display/Makefile | 3 ++-
 drivers/gpu/drm/i915/Kconfig | 1 +
 drivers/gpu/drm/msm/Kconfig  | 1 +
 drivers/gpu/drm/panel/Kconfig| 6 --
 drivers/gpu/drm/panel/panel-lg-sw43408.c | 2 +-
 7 files changed, 16 insertions(+), 4 deletions(-)
---
base-commit: 8314289a8d50a4e05d8ece1ae0445a3b57bb4d3b
change-id: 20240420-panel-sw43408-fix-ff6549c121be

Best regards,
-- 
Dmitry Baryshkov