Re: [PATCH 1/2] drm/komeda: Disable slave pipeline support

2019-07-07 Thread james qian wang (Arm Technology China)
On Fri, Jul 05, 2019 at 02:23:48PM +0200, Daniel Vetter wrote:
> On Fri, Jul 05, 2019 at 11:44:16AM +, james qian wang (Arm Technology 
> China) wrote:
> > Since the property slave_planes have been removed, to avoid the resource
> > assignment problem in user disable slave pipeline support temporarily.
> >
> > Signed-off-by: james qian wang (Arm Technology China) 
> > 
>
> I guess the way you have to enumerate the planes listing the slave planes
> wont just automatically work in any fashion and force a lot more fallbacks
> to primary plane only. At least until virtualization of plane hw is done.
> So makes sense to outright disable all the slave plane stuff for now. And
> I think it's ok to keep all the code still, we'll use it again.
>
> Acked-by: Daniel Vetter 
>
> > ---
> >  drivers/gpu/drm/arm/display/komeda/komeda_crtc.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > index f4400788ab94..8ee879ee3ddc 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > @@ -481,7 +481,7 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
> >  master = mdev->pipelines[i];
> >
> >  crtc->master = master;
> > -crtc->slave  = komeda_pipeline_get_slave(master);
>
> This might cause an unused function warning, might need to annotate it
> with __unused.
> -Daniel

If so, I'd like to drop this change.

Since even with this change, that still can not pass all our tests.
we have to update the user tests or the komeda implementation.
Once we finished the updating, we still need to revert this change.
So maybe just drop it is more better.

Thanks
James

> > +crtc->slave  = NULL;
> >
> >  if (crtc->slave)
> >  sprintf(str, "pipe-%d", crtc->slave->id);
> > --
> > 2.20.1
> >
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 2/2] drm/komeda: Computing image enhancer internally

2019-07-07 Thread james qian wang (Arm Technology China)
Enable image enhancer when the input data flow is 2x+ upscaling.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_kms.h| 7 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 4 
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c  | 5 -
 3 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 0c006576a25c..8c89fc245b83 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -47,11 +47,8 @@ struct komeda_plane_state {
/** @zlist_node: zorder list node */
struct list_head zlist_node;
 
-   /* @img_enhancement: on/off image enhancement
-* @layer_split: on/off layer_split
-*/
-   u8 img_enhancement : 1,
-  layer_split : 1;
+   /** @layer_split: on/off layer_split */
+   u8 layer_split : 1;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 972a0f25254d..950235af1e79 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -806,6 +806,10 @@ void komeda_complete_data_flow_cfg(struct komeda_layer 
*layer,
dflow->en_scaling = (w != dflow->out_w) || (h != dflow->out_h);
dflow->is_yuv = fb->format->is_yuv;
 
+   /* try to enable image enhancer if data flow is a 2x+ upscaling */
+   dflow->en_img_enhancement = dflow->out_w >= 2 * w ||
+   dflow->out_h >= 2 * h;
+
/* try to enable split if scaling exceed the scaler's acceptable
 * input/output range.
 */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index b1386438357b..c095af154216 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -18,7 +18,6 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
struct komeda_data_flow_cfg *dflow)
 {
struct komeda_plane *kplane = to_kplane(st->plane);
-   struct komeda_plane_state *kplane_st = to_kplane_st(st);
struct drm_framebuffer *fb = st->fb;
const struct komeda_format_caps *caps = to_kfb(fb)->format_caps;
struct komeda_pipeline *pipe = kplane->layer->base.pipeline;
@@ -57,8 +56,6 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
return -EINVAL;
}
 
-   dflow->en_img_enhancement = !!kplane_st->img_enhancement;
-
komeda_complete_data_flow_cfg(kplane->layer, dflow, fb);
 
return 0;
@@ -174,8 +171,6 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane)
 
old = to_kplane_st(plane->state);
 
-   new->img_enhancement = old->img_enhancement;
-
return &new->base;
 }
 
-- 
2.20.1



[PATCH 1/2] drm/komeda: Computing layer_split internally

2019-07-07 Thread james qian wang (Arm Technology China)
For layer_split no need user to enable/disable it, but compute it in
komeda internally, komeda will enable it if the scaling exceed the
acceptable range of scaler.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h  |  3 ++-
 .../drm/arm/display/komeda/komeda_pipeline_state.c| 11 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_plane.c |  3 +--
 .../gpu/drm/arm/display/komeda/komeda_wb_connector.c  | 10 +-
 4 files changed, 14 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index fc1b8613385e..a90bcbb3cb23 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -537,7 +537,8 @@ void komeda_pipeline_disable(struct komeda_pipeline *pipe,
 void komeda_pipeline_update(struct komeda_pipeline *pipe,
struct drm_atomic_state *old_state);
 
-void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow,
+void komeda_complete_data_flow_cfg(struct komeda_layer *layer,
+  struct komeda_data_flow_cfg *dflow,
   struct drm_framebuffer *fb);
 
 #endif /* _KOMEDA_PIPELINE_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 2b415ef2b7d3..972a0f25254d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -784,9 +784,11 @@ komeda_timing_ctrlr_validate(struct komeda_timing_ctrlr 
*ctrlr,
return 0;
 }
 
-void komeda_complete_data_flow_cfg(struct komeda_data_flow_cfg *dflow,
+void komeda_complete_data_flow_cfg(struct komeda_layer *layer,
+  struct komeda_data_flow_cfg *dflow,
   struct drm_framebuffer *fb)
 {
+   struct komeda_scaler *scaler = layer->base.pipeline->scalers[0];
u32 w = dflow->in_w;
u32 h = dflow->in_h;
 
@@ -803,6 +805,13 @@ void komeda_complete_data_flow_cfg(struct 
komeda_data_flow_cfg *dflow,
 
dflow->en_scaling = (w != dflow->out_w) || (h != dflow->out_h);
dflow->is_yuv = fb->format->is_yuv;
+
+   /* try to enable split if scaling exceed the scaler's acceptable
+* input/output range.
+*/
+   if (dflow->en_scaling && scaler)
+   dflow->en_split = !in_range(&scaler->hsize, dflow->in_w) ||
+ !in_range(&scaler->hsize, dflow->out_w);
 }
 
 static bool merger_is_available(struct komeda_pipeline *pipe,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
index 5bb8553cc117..b1386438357b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c
@@ -58,9 +58,8 @@ komeda_plane_init_data_flow(struct drm_plane_state *st,
}
 
dflow->en_img_enhancement = !!kplane_st->img_enhancement;
-   dflow->en_split = !!kplane_st->layer_split;
 
-   komeda_complete_data_flow_cfg(dflow, fb);
+   komeda_complete_data_flow_cfg(kplane->layer, dflow, fb);
 
return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index bb8a61f6e9a4..617e1f7b8472 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -13,7 +13,6 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
 struct komeda_crtc_state *kcrtc_st,
 struct komeda_data_flow_cfg *dflow)
 {
-   struct komeda_scaler *scaler = wb_layer->base.pipeline->scalers[0];
struct drm_framebuffer *fb = conn_st->writeback_job->fb;
 
memset(dflow, 0, sizeof(*dflow));
@@ -28,14 +27,7 @@ komeda_wb_init_data_flow(struct komeda_layer *wb_layer,
dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;
dflow->rot = DRM_MODE_ROTATE_0;
 
-   komeda_complete_data_flow_cfg(dflow, fb);
-
-   /* if scaling exceed the acceptable scaler input/output range, try to
-* enable split.
-*/
-   if (dflow->en_scaling && scaler)
-   dflow->en_split = !in_range(&scaler->hsize, dflow->in_w) ||
- !in_range(&scaler->hsize, dflow->out_w);
+   komeda_complete_data_flow_cfg(wb_layer, dflow, fb);
 
return 0;
 }
-- 
2.20.1

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

[Bug 109955] amdgpu [RX Vega 64] system freeze while gaming

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109955

--- Comment #39 from Samuel Sieb  ---
(In reply to shadow.archemage from comment #37)
> I tried the kernel parameters above, and the game still crashed for me.

Are you saying that the game is crashing or the graphics device is?

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 1/4] ASoC: hdmi-codec: Add an op to set callback function for plug event

2019-07-07 Thread Cheng-yi Chiang
On Fri, Jul 5, 2019 at 8:12 PM Mark Brown  wrote:
>
> On Fri, Jul 05, 2019 at 03:08:37PM +0800, Tzung-Bi Shih wrote:
> > On Fri, Jul 5, 2019 at 12:26 PM Cheng-Yi Chiang  
> > wrote:
>
> > > +typedef void (*hdmi_codec_plugged_cb)(struct platform_device *dev,
> > > + bool plugged);
> > > +
>
> > The callback prototype is "weird" by struct platform_device.  Is it
> > possible to having snd_soc_component instead of platform_device?
>
> Or if it's got to be a device why not just a generic device so
> we're not tied to a particular bus here?

My intention was to invoke the call in dw-hdmi.c like this:

hdmi->plugged_cb(hdmi->audio,
   result == connector_status_connected);

Here hdmi->audio is a platform_device.
I think dw-hdmi can not get  snd_soc_component easily.
I can use a generic device here so the ops is more general.
The calling will be like
hdmi->plugged_cb(&hdmi->audio->dev,
   result == connector_status_connected);
I will update this in v2.
Thanks!


Re: [PATCH 5/5] RFC: MAINTAINERS: maintain drm/arm drivers in drm-misc for now

2019-07-07 Thread james qian wang (Arm Technology China)
On Fri, Jul 05, 2019 at 09:57:37PM +0800, Liviu Dudau wrote:
> On Fri, Jul 05, 2019 at 02:10:06PM +0200, Daniel Vetter wrote:
> > From discussions with Liviu it sounded like the komeda team would
> > benefit a bit from more cross-review with other drivers. To make sure
> > komeda is aligned with how similar problems are solved in other
> > drivers (in the end everyone ends up with similar ideas on how to
> > solve various display engine design issues).
> > 
> > An option would be to use drm-misc as an incubator for a few kernel
> > releases, at least until the big design items have been tackled: Aside
> > from the four kms properties already landed that we need to take out
> > again there's also a pile of new ones proposed already for komeda.
> > drm-misc seems to work fairly well at encouraging these kind of
> > cross-driver reviews and working on cross-driver infrastructure in drm
> > core. Later on we can move all the drivers out to a dedicated arm tree
> > again (if that's desired).
> > 
> > Of coures that would mean Lowry and James need drm-misc commit rights
> > (all other arm contributors have it already I think).
> > 
> > Cc: Lowry Li (Arm Technology China) 
> > Cc: James Qian Wang (Arm Technology China) 
> > Cc: Liviu Dudau 
> 
> Acked-by: Liviu Dudau 

Acked-by: James Qian Wang (Arm Technology China) 

> > Cc: Mali DP Maintainers 
> > Cc: Brian Starkey 
> > Cc: Dave Airlie 
> > Cc: Maarten Lankhorst 
> > Cc: Maxime Ripard 
> > Cc: Sean Paul 
> > Signed-off-by: Daniel Vetter 
> > ---
> >  MAINTAINERS | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index d119d53e48de..a5319eddcee1 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -1203,7 +1203,7 @@ M:James (Qian) Wang 
> >  M: Liviu Dudau 
> >  L: Mali DP Maintainers 
> >  S: Supported
> > -T: git git://linux-arm.org/linux-ld.git for-upstream/mali-dp
> > +T: git git://anongit.freedesktop.org/drm/drm-misc
> >  F: drivers/gpu/drm/arm/display/include/
> >  F: drivers/gpu/drm/arm/display/komeda/
> >  F: Documentation/devicetree/bindings/display/arm,komeda.txt
> > @@ -1214,7 +1214,7 @@ M:Liviu Dudau 
> >  M: Brian Starkey 
> >  L: Mali DP Maintainers 
> >  S: Supported
> > -T: git git://linux-arm.org/linux-ld.git for-upstream/mali-dp
> > +T: git git://anongit.freedesktop.org/drm/drm-misc
> >  F: drivers/gpu/drm/arm/
> >  F: Documentation/devicetree/bindings/display/arm,malidp.txt
> >  F: Documentation/gpu/afbc.rst
> > -- 
> > 2.20.1
> > 
> 
> -- 
> 
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---
> ¯\_(ツ)_/¯
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

linux-next: build failure after merge of the drm tree

2019-07-07 Thread Stephen Rothwell
Hi all,

After merging the drm tree, today's linux-next build (arm
multi_v7_defconfig) failed like this:

drivers/dma-buf/dma-buf.c: In function 'dma_buf_fs_mount':
drivers/dma-buf/dma-buf.c:65:9: error: implicit declaration of function 
'mount_pseudo'; did you mean 'mount_bdev'? 
[-Werror=implicit-function-declaration]
  return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops,
 ^~~~
 mount_bdev
drivers/dma-buf/dma-buf.c:65:9: warning: returning 'int' from a function with 
return type 'struct dentry *' makes pointer from integer without a cast 
[-Wint-conversion]
  return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops,
 ^~~
DMA_BUF_MAGIC);
~~

Caused by commit

  ed63bb1d1f84 ("dma-buf: give each buffer a full-fledged inode")

interacting with commit

  8d9e46d80777 ("fold mount_pseudo_xattr() into pseudo_fs_get_tree()")

from the vfs tree.

I have added the following merge fix patch for today.

From: Stephen Rothwell 
Date: Mon, 8 Jul 2019 14:36:53 +1000
Subject: [PATCH] dma-buf: convert to new mount api

Signed-off-by: Stephen Rothwell 
---
 drivers/dma-buf/dma-buf.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c
index dc4b2c521d79..e8587c5eedb7 100644
--- a/drivers/dma-buf/dma-buf.c
+++ b/drivers/dma-buf/dma-buf.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -59,16 +60,19 @@ static const struct dentry_operations dma_buf_dentry_ops = {
 
 static struct vfsmount *dma_buf_mnt;
 
-static struct dentry *dma_buf_fs_mount(struct file_system_type *fs_type,
-   int flags, const char *name, void *data)
+static int dma_buf_init_fs_context(struct fs_context *fc)
 {
-   return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops,
-   DMA_BUF_MAGIC);
+   struct pseudo_fs_context *ctx = init_pseudo(fc, DMA_BUF_MAGIC);
+
+   if (!ctx)
+   return -ENOMEM;
+   ctx->dops = &dma_buf_dentry_ops;
+   return 0;
 }
 
 static struct file_system_type dma_buf_fs_type = {
.name = "dmabuf",
-   .mount = dma_buf_fs_mount,
+   .init_fs_context = dma_buf_init_fs_context,
.kill_sb = kill_anon_super,
 };
 
-- 
2.20.1

-- 
Cheers,
Stephen Rothwell


pgpEIqFokpdkl.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

linux-next: manual merge of the drm tree with the vfs tree

2019-07-07 Thread Stephen Rothwell
Hi all,

Today's linux-next merge of the drm tree got a conflict in:

  include/uapi/linux/magic.h

between commit:

  ea8157ab2ae5 ("zsfold: Convert zsfold to use the new mount API")

from the vfs tree and commit:

  ed63bb1d1f84 ("dma-buf: give each buffer a full-fledged inode")

from the drm tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.

-- 
Cheers,
Stephen Rothwell

diff --cc include/uapi/linux/magic.h
index 85c1119d0b0b,665e18627f78..
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@@ -91,6 -91,6 +91,7 @@@
  #define UDF_SUPER_MAGIC   0x15013346
  #define BALLOON_KVM_MAGIC 0x13661366
  #define ZSMALLOC_MAGIC0x58295829
 +#define Z3FOLD_MAGIC  0x33
+ #define DMA_BUF_MAGIC 0x444d4142  /* "DMAB" */
  
  #endif /* __LINUX_MAGIC_H__ */


pgpRX3VKiSG9A.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 110924] Alien: Isolation - Flashing squares in upper half of screen when HDAO enabled

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=110924

Timothy Arceri  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #1 from Timothy Arceri  ---


*** This bug has been marked as a duplicate of bug 108919 ***

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 111082] Severe stutter in CS:GO surf servers, despite ~300fps

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111082

nuc...@hotmail.com changed:

   What|Removed |Added

 Resolution|NOTABUG |FIXED

--- Comment #2 from nuc...@hotmail.com ---
How is this not a graphics driver bug?

Under Windows 10 I connect to the very same server and there is no stutter.

I actually think this is a driver bug. This has nothing to do with my
connection.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 11/19] arm64: dts: renesas: r8a77965: Add CMM units

2019-07-07 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Sat, Jul 06, 2019 at 04:07:38PM +0200, Jacopo Mondi wrote:
> Add CMM units to Renesas R-Car M3-N device tree and reference them from
> the Display Unit they are connected to.
> 
> Signed-off-by: Jacopo Mondi 

Reviewed-by: Laurent Pinchart 

> ---
>  arch/arm64/boot/dts/renesas/r8a77965.dtsi | 25 +++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> index b701aeb4f438..aad9ea67c379 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> @@ -2307,6 +2307,30 @@
>   resets = <&cpg 602>;
>   };
>  
> + cmm0: cmm@fea4 {
> + compatible = "renesas,rcar-gen3-cmm";
> + reg = <0 0xfea4 0 0x1000>;
> + clocks = <&cpg CPG_MOD 711>;
> + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
> + resets = <&cpg 711>;
> + };
> +
> + cmm1: cmm@fea5 {
> + compatible = "renesas,rcar-gen3-cmm";
> + reg = <0 0xfea5 0 0x1000>;
> + clocks = <&cpg CPG_MOD 710>;
> + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
> + resets = <&cpg 710>;
> + };
> +
> + cmm3: cmm@fea7 {
> + compatible = "renesas,rcar-gen3-cmm";
> + reg = <0 0xfea7 0 0x1000>;
> + clocks = <&cpg CPG_MOD 708>;
> + power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
> + resets = <&cpg 708>;
> + };
> +
>   csi20: csi2@fea8 {
>   compatible = "renesas,r8a77965-csi2";
>   reg = <0 0xfea8 0 0x1>;
> @@ -2457,6 +2481,7 @@
>   status = "disabled";
>  
>   vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>;
> + cmms = <&cmm0 &cmm1 &cmm3>;
>  
>   ports {
>   #address-cells = <1>;

-- 
Regards,

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

Re: [PATCH v2 03/19] arm64: renesas: Update 'vsps' property

2019-07-07 Thread Laurent Pinchart
Hi Jacopo,

Thank you for the patch.

On Sat, Jul 06, 2019 at 04:07:30PM +0200, Jacopo Mondi wrote:
> Update the 'vsps' property in the R-Car Gen3 SoC device tree files to
> match what's in in the documentation example.
> 
> Signed-off-by: Jacopo Mondi 

Reviewed-by: Laurent Pinchart 

> ---
>  arch/arm64/boot/dts/renesas/r8a774c0.dtsi | 2 +-
>  arch/arm64/boot/dts/renesas/r8a7795.dtsi  | 2 +-
>  arch/arm64/boot/dts/renesas/r8a77965.dtsi | 2 +-
>  arch/arm64/boot/dts/renesas/r8a77990.dtsi | 2 +-
>  arch/arm64/boot/dts/renesas/r8a77995.dtsi | 2 +-
>  5 files changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
> index 3f86db199dbf..e643f9d3c102 100644
> --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
> @@ -1807,7 +1807,7 @@
>   clocks = <&cpg CPG_MOD 724>,
><&cpg CPG_MOD 723>;
>   clock-names = "du.0", "du.1";
> - vsps = <&vspd0 0 &vspd1 0>;
> + vsps = <&vspd0 0>, <&vspd1 0>;
>   status = "disabled";
>  
>   ports {
> diff --git a/arch/arm64/boot/dts/renesas/r8a7795.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> index 097538cc4b1f..432f4036a8a8 100644
> --- a/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a7795.dtsi
> @@ -3098,7 +3098,7 @@
><&cpg CPG_MOD 722>,
><&cpg CPG_MOD 721>;
>   clock-names = "du.0", "du.1", "du.2", "du.3";
> - vsps = <&vspd0 0 &vspd1 0 &vspd2 0 &vspd0 1>;
> + vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>;
>   status = "disabled";
>  
>   ports {
> diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> index 2554b1742dbf..b701aeb4f438 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
> @@ -2456,7 +2456,7 @@
>   clock-names = "du.0", "du.1", "du.3";
>   status = "disabled";
>  
> - vsps = <&vspd0 0 &vspd1 0 &vspd0 1>;
> + vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>;
>  
>   ports {
>   #address-cells = <1>;
> diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> index 56cb566ffa09..79db5441b7e7 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
> @@ -1764,7 +1764,7 @@
>   clocks = <&cpg CPG_MOD 724>,
><&cpg CPG_MOD 723>;
>   clock-names = "du.0", "du.1";
> - vsps = <&vspd0 0 &vspd1 0>;
> + vsps = <&vspd0 0>, <&vspd1 0>;
>   status = "disabled";
>  
>   ports {
> diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi 
> b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
> index 5bf3af246e14..49a11b4f55bd 100644
> --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi
> +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
> @@ -1001,7 +1001,7 @@
>   clocks = <&cpg CPG_MOD 724>,
><&cpg CPG_MOD 723>;
>   clock-names = "du.0", "du.1";
> - vsps = <&vspd0 0 &vspd1 0>;
> + vsps = <&vspd0 0>, <&vspd1 0>;
>   status = "disabled";
>  
>   ports {

-- 
Regards,

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

[Bug 111082] Severe stutter in CS:GO surf servers, despite ~300fps

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111082

Timothy Arceri  changed:

   What|Removed |Added

 Resolution|--- |NOTABUG
 Status|NEW |RESOLVED

--- Comment #1 from Timothy Arceri  ---
What makes you think this is a driver bug? Are you sure this is not just a slow
connection between you and the community server? Or a slow server or any number
of different things?

Sorry but I'm going to close this bug report as I see nothing to suggest this
is a graphics driver bug.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 111077] link_shader and deserialize_glsl_program suddenly consume huge amount of RAM

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111077

--- Comment #3 from Timothy Arceri  ---
Are you able to build mesa from git and do a git bisect to find the problem
commit?

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 111082] Severe stutter in CS:GO surf servers, despite ~300fps

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111082

Bug ID: 111082
   Summary: Severe stutter in CS:GO surf servers, despite ~300fps
   Product: Mesa
   Version: 19.1
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: normal
  Priority: medium
 Component: Drivers/Gallium/radeonsi
  Assignee: dri-devel@lists.freedesktop.org
  Reporter: nuc...@hotmail.com
QA Contact: dri-devel@lists.freedesktop.org

In general playing CS:GO is going really well, however when joining surf
servers (a popular community game mode), despite having around 300fps the game
stutters really badly.

To test if you can reproduce you will of course need to have CS:GO installed
and join any surf server, for instance -> 217.79.188.156:27165

I hope somebody can reproduce this and maybe help :)

If nobody can, I might provide a video.

I am on archlinux with the following packages:
mesa v19.1.1, xf86-video-amdgpu 19.0.1

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH 1/1] drm/amdgpu: adopt to hmm_range_register API change

2019-07-07 Thread Stephen Rothwell
Hi all,

On Wed, 3 Jul 2019 17:09:16 -0400 Alex Deucher  wrote:
>
> On Wed, Jul 3, 2019 at 5:03 PM Kuehling, Felix  wrote:
> >
> > On 2019-07-03 10:10 a.m., Jason Gunthorpe wrote:  
> > > On Wed, Jul 03, 2019 at 01:55:08AM +, Kuehling, Felix wrote:  
> > >> From: Philip Yang 
> > >>
> > >> In order to pass mirror instead of mm to hmm_range_register, we need
> > >> pass bo instead of ttm to amdgpu_ttm_tt_get_user_pages because mirror
> > >> is part of amdgpu_mn structure, which is accessible from bo.
> > >>
> > >> Signed-off-by: Philip Yang 
> > >> Reviewed-by: Felix Kuehling 
> > >> Signed-off-by: Felix Kuehling 
> > >> CC: Stephen Rothwell 
> > >> CC: Jason Gunthorpe 
> > >> CC: Dave Airlie 
> > >> CC: Alex Deucher 
> > >> ---
> > >>   drivers/gpu/drm/Kconfig  |  1 -
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c |  5 ++---
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c   |  2 +-
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c  |  3 +--
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.c   |  8 
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_mn.h   |  5 +
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c  | 12 ++--
> > >>   drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h  |  5 +++--
> > >>   8 files changed, 30 insertions(+), 11 deletions(-)  
> > > This is too big to use as a conflict resolution, what you could do is
> > > apply the majority of the patch on top of your tree as-is (ie keep
> > > using the old hmm_range_register), then the conflict resolution for
> > > the updated AMD GPU tree can be a simple one line change:
> > >
> > >   -   hmm_range_register(range, mm, start,
> > >   +   hmm_range_register(range, mirror, start,
> > >  start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
> > >
> > > Which is trivial for everone to deal with, and solves the problem.  
> >
> > Good idea.

With the changes added to the amdgpu tree over the weekend, I will
apply the following merge fix patch to the hmm merge today:

From: Philip Yang 
Sibject: drm/amdgpu: adopt to hmm_range_register API change

Signed-off-by: Stephen Rothwell 

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -783,7 +783,7 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct 
page **pages)
0 : range->flags[HMM_PFN_WRITE];
range->pfn_flags_mask = 0;
range->pfns = pfns;
-   hmm_range_register(range, mm, start,
+   hmm_range_register(range, mirror, start,
   start + ttm->num_pages * PAGE_SIZE, PAGE_SHIFT);
 
 retry:

And someone just needs to make sure Linus is aware of this needed merge fix.
-- 
Cheers,
Stephen Rothwell


pgpr9ziZ8P0PA.pgp
Description: OpenPGP digital signature
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 111081] OS Fails to Boot to Runlevel 5

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111081

Bug ID: 111081
   Summary: OS Fails to Boot to Runlevel 5
   Product: DRI
   Version: unspecified
  Hardware: x86-64 (AMD64)
OS: Linux (All)
Status: NEW
  Severity: blocker
  Priority: medium
 Component: DRM/AMDgpu-pro
  Assignee: dri-devel@lists.freedesktop.org
  Reporter: nat.ad...@inventati.org

Created attachment 144717
  --> https://bugs.freedesktop.org/attachment.cgi?id=144717&action=edit
Basic Configurate

After installing, AMD GPU pro driver 19.2 on Ubuntu 18.04 I cannot reboot.This
is a fresh install. I only ran update, upgrade then rebooted then install
driver 19.2. I have reproduced the problem about 3 times. When booting in
verbose mode, I noticed the computer always reaches runlevel 3.

The I followed the bug reporting procedures from
https://amdgpu-install.readthedocs.io/en/latest/install-bugrep.html#generating-a-bug-report
twice. Once after installing the driver, but before rebooting, and once after
rebooting. However, I do not see how to attach all the files. 

In order to reboot I had to downgrade to a previous kernel.

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 60/60] drm/omap: dss: Remove unused omapdss_of_find_connected_device() function

2019-07-07 Thread Laurent Pinchart
The omapdss_of_find_connected_device() function isn't used anymore,
remove it.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/Makefile  |  2 +-
 drivers/gpu/drm/omapdrm/dss/dss-of.c  | 28 ---
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  3 ---
 3 files changed, 1 insertion(+), 32 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/dss/dss-of.c

diff --git a/drivers/gpu/drm/omapdrm/dss/Makefile 
b/drivers/gpu/drm/omapdrm/dss/Makefile
index 904101c5e79d..39e83d6fcb08 100644
--- a/drivers/gpu/drm/omapdrm/dss/Makefile
+++ b/drivers/gpu/drm/omapdrm/dss/Makefile
@@ -2,7 +2,7 @@
 obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
 
 obj-$(CONFIG_OMAP_DSS_BASE) += omapdss-base.o
-omapdss-base-y := base.o display.o dss-of.o output.o
+omapdss-base-y := base.o display.o output.o
 
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 # Core DSS files
diff --git a/drivers/gpu/drm/omapdrm/dss/dss-of.c 
b/drivers/gpu/drm/omapdrm/dss/dss-of.c
deleted file mode 100644
index b7981f3b80ad..
--- a/drivers/gpu/drm/omapdrm/dss/dss-of.c
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Tomi Valkeinen 
- */
-
-#include 
-#include 
-#include 
-
-#include "omapdss.h"
-
-struct omap_dss_device *
-omapdss_of_find_connected_device(struct device_node *node, unsigned int port)
-{
-   struct device_node *remote_node;
-   struct omap_dss_device *dssdev;
-
-   remote_node = of_graph_get_remote_node(node, port, 0);
-   if (!remote_node)
-   return NULL;
-
-   dssdev = omapdss_find_device_by_node(remote_node);
-   of_node_put(remote_node);
-
-   return dssdev ? dssdev : ERR_PTR(-EPROBE_DEFER);
-}
-EXPORT_SYMBOL_GPL(omapdss_of_find_connected_device);
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 7466953de46d..62642fbc2ce9 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -483,9 +483,6 @@ static inline bool omapdss_device_is_enabled(struct 
omap_dss_device *dssdev)
return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE;
 }
 
-struct omap_dss_device *
-omapdss_of_find_connected_device(struct device_node *node, unsigned int port);
-
 enum dss_writeback_channel {
DSS_WB_LCD1_MGR =   0,
DSS_WB_LCD2_MGR =   1,
-- 
Regards,

Laurent Pinchart

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

[PATCH 58/60] drm/omap: dss: Remove unused omap_dss_device operations

2019-07-07 Thread Laurent Pinchart
The omap_dss_device .pre_enable(), .post_disable() and .set_timings()
are not used anymore. Remove them.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c | 26 ---
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |  6 
 drivers/gpu/drm/omapdrm/omap_encoder.c | 44 +++---
 3 files changed, 5 insertions(+), 71 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 2db3bd2f19db..58b333c6b036 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -234,18 +234,6 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
 }
 EXPORT_SYMBOL_GPL(omapdss_device_disconnect);
 
-void omapdss_device_pre_enable(struct omap_dss_device *dssdev)
-{
-   if (!dssdev)
-   return;
-
-   omapdss_device_pre_enable(dssdev->next);
-
-   if (dssdev->ops && dssdev->ops->pre_enable)
-   dssdev->ops->pre_enable(dssdev);
-}
-EXPORT_SYMBOL_GPL(omapdss_device_pre_enable);
-
 void omapdss_device_enable(struct omap_dss_device *dssdev)
 {
if (!dssdev)
@@ -272,20 +260,6 @@ void omapdss_device_disable(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL_GPL(omapdss_device_disable);
 
-void omapdss_device_post_disable(struct omap_dss_device *dssdev)
-{
-   if (!dssdev)
-   return;
-
-   if (dssdev->ops && dssdev->ops->post_disable)
-   dssdev->ops->post_disable(dssdev);
-
-   omapdss_device_post_disable(dssdev->next);
-
-   dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
-}
-EXPORT_SYMBOL_GPL(omapdss_device_post_disable);
-
 unsigned int omapdss_device_connector_type(enum omap_display_type type)
 {
switch (type) {
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 24b421f67406..8d4fed58d97c 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -353,15 +353,11 @@ struct omap_dss_device_ops {
void (*disconnect)(struct omap_dss_device *dssdev,
struct omap_dss_device *dst);
 
-   void (*pre_enable)(struct omap_dss_device *dssdev);
void (*enable)(struct omap_dss_device *dssdev);
void (*disable)(struct omap_dss_device *dssdev);
-   void (*post_disable)(struct omap_dss_device *dssdev);
 
int (*check_timings)(struct omap_dss_device *dssdev,
 struct drm_display_mode *mode);
-   void (*set_timings)(struct omap_dss_device *dssdev,
-   const struct drm_display_mode *mode);
 
int (*get_modes)(struct omap_dss_device *dssdev,
 struct drm_connector *connector);
@@ -461,10 +457,8 @@ int omapdss_device_connect(struct dss_device *dss,
   struct omap_dss_device *dst);
 void omapdss_device_disconnect(struct omap_dss_device *src,
   struct omap_dss_device *dst);
-void omapdss_device_pre_enable(struct omap_dss_device *dssdev);
 void omapdss_device_enable(struct omap_dss_device *dssdev);
 void omapdss_device_disable(struct omap_dss_device *dssdev);
-void omapdss_device_post_disable(struct omap_dss_device *dssdev);
 unsigned int omapdss_device_connector_type(enum omap_display_type type);
 
 int omap_dss_get_num_overlay_managers(void);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 8af889f0af06..82096dce106a 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -122,13 +122,8 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
bus_flags = connector->display_info.bus_flags;
omap_encoder_update_videomode_flags(&vm, bus_flags);
 
-   /* Set timings for all devices in the display pipeline. */
+   /* Set timings for the dss manager. */
dss_mgr_set_timings(output, &vm);
-
-   for (dssdev = output; dssdev; dssdev = dssdev->next) {
-   if (dssdev->ops && dssdev->ops->set_timings)
-   dssdev->ops->set_timings(dssdev, adjusted_mode);
-   }
 }
 
 static void omap_encoder_disable(struct drm_encoder *encoder)
@@ -141,26 +136,10 @@ static void omap_encoder_disable(struct drm_encoder 
*encoder)
 
/*
 * Disable the chain of external devices, starting at the one at the
-* internal encoder's output.
+* internal encoder's output. This is used for DSI outputs only, as
+* dssdev->next is NULL for all other outputs.
 */
omapdss_device_disable(dssdev->next);
-
-   /*
-* Disable the internal encoder. This will disable the DSS output. The
-* DSI is treated as an exception as DSI pipelines still use the legacy
-* flow where the pipeline output controls the encoder.
-*/
-   if (dssdev->type != OMAP_DISPLAY_TYPE_DSI) {
-   if (dssdev->ops && dssdev->ops->disable)
-   dssdev

[PATCH 59/60] drm/omap: dss: Inline the omapdss_display_get() function

2019-07-07 Thread Laurent Pinchart
Inline the omapdss_display_get() in its only caller to simplify the
code.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/display.c | 9 -
 drivers/gpu/drm/omapdrm/dss/omapdss.h | 1 -
 drivers/gpu/drm/omapdrm/omap_drv.c| 7 ---
 3 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/display.c 
b/drivers/gpu/drm/omapdrm/dss/display.c
index e93f61a567a8..babe597106cb 100644
--- a/drivers/gpu/drm/omapdrm/dss/display.c
+++ b/drivers/gpu/drm/omapdrm/dss/display.c
@@ -51,15 +51,6 @@ void omapdss_display_init(struct omap_dss_device *dssdev)
 }
 EXPORT_SYMBOL_GPL(omapdss_display_init);
 
-struct omap_dss_device *omapdss_display_get(struct omap_dss_device *output)
-{
-   while (output->next)
-   output = output->next;
-
-   return omapdss_device_get(output);
-}
-EXPORT_SYMBOL_GPL(omapdss_display_get);
-
 int omapdss_display_get_modes(struct drm_connector *connector,
  const struct videomode *vm)
 {
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 8d4fed58d97c..7466953de46d 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -443,7 +443,6 @@ static inline bool omapdss_is_initialized(void)
 }
 
 void omapdss_display_init(struct omap_dss_device *dssdev);
-struct omap_dss_device *omapdss_display_get(struct omap_dss_device *output);
 int omapdss_display_get_modes(struct drm_connector *connector,
  const struct videomode *vm);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 89a3633b97ad..bc092e9aa5a2 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -211,11 +211,12 @@ static int omap_display_id(struct omap_dss_device *output)
struct device_node *node = NULL;
 
if (output->next) {
-   struct omap_dss_device *display;
+   struct omap_dss_device *display = output;
+
+   while (display->next)
+   display = display->next;
 
-   display = omapdss_display_get(output);
node = display->dev->of_node;
-   omapdss_device_put(display);
} else if (output->bridge) {
struct drm_bridge *bridge = output->bridge;
 
-- 
Regards,

Laurent Pinchart

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

[PATCH 57/60] drm/omap: Simplify connector implementation

2019-07-07 Thread Laurent Pinchart
Now that the omap_connector is used for DSI only we can simplify its
implementation.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 31 ++--
 1 file changed, 2 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 4b8a99be2086..b8f3e246b01f 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -35,22 +35,7 @@ struct omap_connector {
 static enum drm_connector_status omap_connector_detect(
struct drm_connector *connector, bool force)
 {
-   enum drm_connector_status status;
-
-   switch (connector->connector_type) {
-   case DRM_MODE_CONNECTOR_DPI:
-   case DRM_MODE_CONNECTOR_LVDS:
-   case DRM_MODE_CONNECTOR_DSI:
-   status = connector_status_connected;
-   break;
-   default:
-   status = connector_status_unknown;
-   break;
-   }
-
-   VERB("%s: %d (force=%d)", connector->name, status, force);
-
-   return status;
+   return connector_status_connected;
 }
 
 static void omap_connector_destroy(struct drm_connector *connector)
@@ -149,18 +134,6 @@ static const struct drm_connector_helper_funcs 
omap_connector_helper_funcs = {
.mode_valid = omap_connector_mode_valid,
 };
 
-static int omap_connector_get_type(struct omap_dss_device *output)
-{
-   struct omap_dss_device *display;
-   enum omap_display_type type;
-
-   display = omapdss_display_get(output);
-   type = display->type;
-   omapdss_device_put(display);
-
-   return omapdss_device_connector_type(type);
-}
-
 /* initialize connector */
 struct drm_connector *omap_connector_init(struct drm_device *dev,
  struct omap_dss_device *output,
@@ -182,7 +155,7 @@ struct drm_connector *omap_connector_init(struct drm_device 
*dev,
connector->doublescan_allowed = 0;
 
drm_connector_init(dev, connector, &omap_connector_funcs,
-  omap_connector_get_type(output));
+  DRM_MODE_CONNECTOR_DSI);
drm_connector_helper_add(connector, &omap_connector_helper_funcs);
 
return connector;
-- 
Regards,

Laurent Pinchart

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

[PATCH 54/60] drm/omap: dpi: Register a drm_bridge

2019-07-07 Thread Laurent Pinchart
In order to integrate with a chain of drm_bridge, the internal DPI
output has to expose its operations through the drm_bridge API.
Register a bridge at initialisation time to do so and remove the
omap_dss_device operations that are now unused.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 204 ++
 1 file changed, 121 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index a83bcfe588df..ebc258bf56aa 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -32,6 +32,8 @@
 #include 
 #include 
 
+#include 
+
 #include "dss.h"
 #include "omapdss.h"
 
@@ -52,12 +54,10 @@ struct dpi_data {
int data_lines;
 
struct omap_dss_device output;
+   struct drm_bridge bridge;
 };
 
-static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device 
*dssdev)
-{
-   return container_of(dssdev, struct dpi_data, output);
-}
+#define drm_bridge_to_dpi(bridge) container_of(bridge, struct dpi_data, bridge)
 
 /* 
-
  * Clock Handling and PLL
@@ -365,6 +365,32 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
 }
 
+static int dpi_clock_update(struct dpi_data *dpi, unsigned long *clock)
+{
+   int lck_div, pck_div;
+   unsigned long fck;
+   struct dpi_clk_calc_ctx ctx;
+
+   if (dpi->pll) {
+   if (!dpi_pll_clk_calc(dpi, *clock, &ctx))
+   return -EINVAL;
+
+   fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
+   } else {
+   if (!dpi_dss_clk_calc(dpi, *clock, &ctx))
+   return -EINVAL;
+
+   fck = ctx.fck;
+   }
+
+   lck_div = ctx.dispc_cinfo.lck_div;
+   pck_div = ctx.dispc_cinfo.pck_div;
+
+   *clock = fck / lck_div / pck_div;
+
+   return 0;
+}
+
 static int dpi_verify_pll(struct dss_pll *pll)
 {
int r;
@@ -402,29 +428,75 @@ static void dpi_init_pll(struct dpi_data *dpi)
 }
 
 /* 
-
- * omap_dss_device Operations
+ * DRM Bridge Operations
  */
 
-static int dpi_connect(struct omap_dss_device *src,
-  struct omap_dss_device *dst)
+static int dpi_bridge_attach(struct drm_bridge *bridge, bool create_connector)
 {
-   struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
+   struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
+
+   if (create_connector)
+   return -EINVAL;
 
dpi_init_pll(dpi);
 
-   return omapdss_device_connect(dst->dss, dst, dst->next);
+   return drm_bridge_attach(bridge->encoder, dpi->output.next_bridge,
+bridge, false);
 }
 
-static void dpi_disconnect(struct omap_dss_device *src,
-  struct omap_dss_device *dst)
+static enum drm_mode_status
+dpi_bridge_mode_valid(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode)
 {
-   omapdss_device_disconnect(dst, dst->next);
+   struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
+   unsigned long clock = mode->clock * 1000;
+   int ret;
+
+   if (mode->hdisplay % 8 != 0)
+   return MODE_BAD_WIDTH;
+
+   if (mode->clock == 0)
+   return MODE_NOCLOCK;
+
+   ret = dpi_clock_update(dpi, &clock);
+   if (ret < 0)
+   return MODE_CLOCK_RANGE;
+
+   return MODE_OK;
+}
+
+static bool dpi_bridge_mode_fixup(struct drm_bridge *bridge,
+  const struct drm_display_mode *mode,
+  struct drm_display_mode *adjusted_mode)
+{
+   struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
+   unsigned long clock = mode->clock * 1000;
+   int ret;
+
+   ret = dpi_clock_update(dpi, &clock);
+   if (ret < 0)
+   return false;
+
+   adjusted_mode->clock = clock / 1000;
+
+   return true;
+}
+
+static void dpi_bridge_mode_set(struct drm_bridge *bridge,
+const struct drm_display_mode *mode,
+const struct drm_display_mode *adjusted_mode)
+{
+   struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
+
+   mutex_lock(&dpi->lock);
+   dpi->pixelclock = adjusted_mode->clock * 1000;
+   mutex_unlock(&dpi->lock);
 }
 
-static void dpi_display_enable(struct omap_dss_device *dssdev)
+static void dpi_bridge_enable(struct drm_bridge *bridge,
+  struct drm_atomic_state *state)
 {
-   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
-   struct omap_dss_device *out = &dpi->output;
+   struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
int r;
 
mutex_lock(&dpi->lock);
@@ -439,7 +511,7 @@ static void dpi_display_enable(struct omap_d

[PATCH 56/60] drm/omap: sdi: Register a drm_bridge

2019-07-07 Thread Laurent Pinchart
In order to integrate with a chain of drm_bridge, the internal SDI
output has to expose its operations through the drm_bridge API.
Register a bridge at initialisation time to do so and remove the
omap_dss_device operations that are now unused.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/sdi.c | 177 +++---
 1 file changed, 112 insertions(+), 65 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 92c2cd2c0889..154d247b672d 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -26,6 +26,8 @@
 #include 
 #include 
 
+#include 
+
 #include "dss.h"
 #include "omapdss.h"
 
@@ -41,9 +43,11 @@ struct sdi_device {
int datapairs;
 
struct omap_dss_device output;
+   struct drm_bridge bridge;
 };
 
-#define dssdev_to_sdi(dssdev) container_of(dssdev, struct sdi_device, output)
+#define drm_bridge_to_sdi(bridge) \
+   container_of(bridge, struct sdi_device, bridge)
 
 struct sdi_clk_calc_ctx {
struct sdi_device *sdi;
@@ -129,9 +133,81 @@ static void sdi_config_lcd_manager(struct sdi_device *sdi)
dss_mgr_set_lcd_config(&sdi->output, &sdi->mgr_config);
 }
 
-static void sdi_display_enable(struct omap_dss_device *dssdev)
+/* 
-
+ * DRM Bridge Operations
+ */
+
+static int sdi_bridge_attach(struct drm_bridge *bridge, bool create_connector)
 {
-   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
+
+   if (create_connector)
+   return -EINVAL;
+
+   return drm_bridge_attach(bridge->encoder, sdi->output.next_bridge,
+bridge, false);
+}
+
+static enum drm_mode_status
+sdi_bridge_mode_valid(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode)
+{
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
+   unsigned long pixelclock = mode->clock * 1000;
+   struct dispc_clock_info dispc_cinfo;
+   unsigned long fck;
+   int ret;
+
+   if (pixelclock == 0)
+   return MODE_NOCLOCK;
+
+   ret = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo);
+   if (ret < 0)
+   return MODE_CLOCK_RANGE;
+
+   return MODE_OK;
+}
+
+static bool sdi_bridge_mode_fixup(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
+   unsigned long pixelclock = mode->clock * 1000;
+   struct dispc_clock_info dispc_cinfo;
+   unsigned long fck;
+   unsigned long pck;
+   int ret;
+
+   ret = sdi_calc_clock_div(sdi, pixelclock, &fck, &dispc_cinfo);
+   if (ret < 0)
+   return false;
+
+   pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div;
+
+   if (pck != pixelclock)
+   dev_dbg(&sdi->pdev->dev,
+   "pixel clock adjusted from %lu Hz to %lu Hz\n",
+   pixelclock, pck);
+
+   adjusted_mode->clock = pck / 1000;
+
+   return true;
+}
+
+static void sdi_bridge_mode_set(struct drm_bridge *bridge,
+   const struct drm_display_mode *mode,
+   const struct drm_display_mode *adjusted_mode)
+{
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
+
+   sdi->pixelclock = adjusted_mode->clock * 1000;
+}
+
+static void sdi_bridge_enable(struct drm_bridge *bridge,
+ struct drm_atomic_state *state)
+{
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
struct dispc_clock_info dispc_cinfo;
unsigned long fck;
int r;
@@ -192,9 +268,10 @@ static void sdi_display_enable(struct omap_dss_device 
*dssdev)
regulator_disable(sdi->vdds_sdi_reg);
 }
 
-static void sdi_display_disable(struct omap_dss_device *dssdev)
+static void sdi_bridge_disable(struct drm_bridge *bridge,
+  struct drm_atomic_state *state)
 {
-   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
+   struct sdi_device *sdi = drm_bridge_to_sdi(bridge);
 
dss_mgr_disable(&sdi->output);
 
@@ -205,71 +282,40 @@ static void sdi_display_disable(struct omap_dss_device 
*dssdev)
regulator_disable(sdi->vdds_sdi_reg);
 }
 
-static void sdi_set_timings(struct omap_dss_device *dssdev,
-   const struct drm_display_mode *mode)
-{
-   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
-
-   sdi->pixelclock = mode->clock * 1000;
-}
-
-static int sdi_check_timings(struct omap_dss_device *dssdev,
-struct drm_display_mode *mode)
-{
-   struct sdi_device *sdi = dssdev_to_sdi(dssdev);
-   struct dispc_clock_info dispc_cinfo;
-   unsigned long pixelclock 

[PATCH 55/60] drm/omap: sdi: Sort includes alphabetically

2019-07-07 Thread Laurent Pinchart
This makes it easier to quickly locate duplicate includes.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/sdi.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/sdi.c 
b/drivers/gpu/drm/omapdrm/dss/sdi.c
index 2c5eaac9193f..92c2cd2c0889 100644
--- a/drivers/gpu/drm/omapdrm/dss/sdi.c
+++ b/drivers/gpu/drm/omapdrm/dss/sdi.c
@@ -17,17 +17,17 @@
 
 #define DSS_SUBSYS_NAME "SDI"
 
-#include 
 #include 
 #include 
-#include 
 #include 
+#include 
+#include 
 #include 
+#include 
 #include 
-#include 
 
-#include "omapdss.h"
 #include "dss.h"
+#include "omapdss.h"
 
 struct sdi_device {
struct platform_device *pdev;
-- 
Regards,

Laurent Pinchart

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

[PATCH 52/60] drm/omap: dpi: Reorder functions in sections

2019-07-07 Thread Laurent Pinchart
Group functions based on their purpose and split them in sections to
make the source code easier to navigate.

No functional change is included.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 146 --
 1 file changed, 79 insertions(+), 67 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index da7d50cde31d..12a70b7163da 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -59,6 +59,10 @@ static struct dpi_data *dpi_get_data_from_dssdev(struct 
omap_dss_device *dssdev)
return container_of(dssdev, struct dpi_data, output);
 }
 
+/* 
-
+ * Clock Handling and PLL
+ */
+
 static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
  enum omap_channel channel)
 {
@@ -377,6 +381,62 @@ static void dpi_config_lcd_manager(struct dpi_data *dpi)
dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
 }
 
+static int dpi_verify_pll(struct dss_pll *pll)
+{
+   int r;
+
+   /* do initial setup with the PLL to see if it is operational */
+
+   r = dss_pll_enable(pll);
+   if (r)
+   return r;
+
+   dss_pll_disable(pll);
+
+   return 0;
+}
+
+static void dpi_init_pll(struct dpi_data *dpi)
+{
+   struct dss_pll *pll;
+
+   if (dpi->pll)
+   return;
+
+   dpi->clk_src = dpi_get_clk_src(dpi);
+
+   pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
+   if (!pll)
+   return;
+
+   if (dpi_verify_pll(pll)) {
+   DSSWARN("PLL not operational\n");
+   return;
+   }
+
+   dpi->pll = pll;
+}
+
+/* 
-
+ * omap_dss_device Operations
+ */
+
+static int dpi_connect(struct omap_dss_device *src,
+  struct omap_dss_device *dst)
+{
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
+
+   dpi_init_pll(dpi);
+
+   return omapdss_device_connect(dst->dss, dst, dst->next);
+}
+
+static void dpi_disconnect(struct omap_dss_device *src,
+  struct omap_dss_device *dst)
+{
+   omapdss_device_disconnect(dst, dst->next);
+}
+
 static void dpi_display_enable(struct omap_dss_device *dssdev)
 {
struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
@@ -457,20 +517,6 @@ static void dpi_display_disable(struct omap_dss_device 
*dssdev)
mutex_unlock(&dpi->lock);
 }
 
-static void dpi_set_timings(struct omap_dss_device *dssdev,
-   const struct drm_display_mode *mode)
-{
-   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
-
-   DSSDBG("dpi_set_timings\n");
-
-   mutex_lock(&dpi->lock);
-
-   dpi->pixelclock = mode->clock * 1000;
-
-   mutex_unlock(&dpi->lock);
-}
-
 static int dpi_check_timings(struct omap_dss_device *dssdev,
 struct drm_display_mode *mode)
 {
@@ -511,41 +557,30 @@ static int dpi_check_timings(struct omap_dss_device 
*dssdev,
return 0;
 }
 
-static int dpi_verify_pll(struct dss_pll *pll)
+static void dpi_set_timings(struct omap_dss_device *dssdev,
+   const struct drm_display_mode *mode)
 {
-   int r;
+   struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
 
-   /* do initial setup with the PLL to see if it is operational */
+   DSSDBG("dpi_set_timings\n");
 
-   r = dss_pll_enable(pll);
-   if (r)
-   return r;
+   mutex_lock(&dpi->lock);
 
-   dss_pll_disable(pll);
+   dpi->pixelclock = mode->clock * 1000;
 
-   return 0;
+   mutex_unlock(&dpi->lock);
 }
 
-static void dpi_init_pll(struct dpi_data *dpi)
-{
-   struct dss_pll *pll;
-
-   if (dpi->pll)
-   return;
-
-   dpi->clk_src = dpi_get_clk_src(dpi);
+static const struct omap_dss_device_ops dpi_ops = {
+   .connect = dpi_connect,
+   .disconnect = dpi_disconnect,
 
-   pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
-   if (!pll)
-   return;
+   .enable = dpi_display_enable,
+   .disable = dpi_display_disable,
 
-   if (dpi_verify_pll(pll)) {
-   DSSWARN("PLL not operational\n");
-   return;
-   }
-
-   dpi->pll = pll;
-}
+   .check_timings = dpi_check_timings,
+   .set_timings = dpi_set_timings,
+};
 
 /*
  * Return a hardcoded channel for the DPI output. This should work for
@@ -583,33 +618,6 @@ static enum omap_channel dpi_get_channel(struct dpi_data 
*dpi)
}
 }
 
-static int dpi_connect(struct omap_dss_device *src,
-  struct omap_dss_device *dst)
-{
-   struct dpi_data *dpi = dpi_get_data_from_dssdev(dst);
-
-   dpi_init_pll(dpi);
-
-   return omapdss_device_connect(dst->dss, dst, dst->next);
-}
-
-static void

[PATCH 53/60] drm/omap: dpi: Simplify clock setting API

2019-07-07 Thread Laurent Pinchart
The dpi_set_pll_clk() and dpi_set_dispc_clk() return various information
through pointer arguments that are never used by the callers. Remove
them to simplify the clock setting API.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 32 ---
 1 file changed, 8 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index 12a70b7163da..a83bcfe588df 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -298,9 +298,7 @@ static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned 
long pck,
 
 
 
-static int dpi_set_pll_clk(struct dpi_data *dpi, enum omap_channel channel,
-   unsigned long pck_req, unsigned long *fck, int *lck_div,
-   int *pck_div)
+static int dpi_set_pll_clk(struct dpi_data *dpi, unsigned long pck_req)
 {
struct dpi_clk_calc_ctx ctx;
int r;
@@ -314,19 +312,15 @@ static int dpi_set_pll_clk(struct dpi_data *dpi, enum 
omap_channel channel,
if (r)
return r;
 
-   dss_select_lcd_clk_source(dpi->dss, channel, dpi->clk_src);
+   dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
+ dpi->clk_src);
 
dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 
-   *fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
-   *lck_div = ctx.dispc_cinfo.lck_div;
-   *pck_div = ctx.dispc_cinfo.pck_div;
-
return 0;
 }
 
-static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
-   unsigned long *fck, int *lck_div, int *pck_div)
+static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req)
 {
struct dpi_clk_calc_ctx ctx;
int r;
@@ -342,29 +336,19 @@ static int dpi_set_dispc_clk(struct dpi_data *dpi, 
unsigned long pck_req,
 
dpi->mgr_config.clock_info = ctx.dispc_cinfo;
 
-   *fck = ctx.fck;
-   *lck_div = ctx.dispc_cinfo.lck_div;
-   *pck_div = ctx.dispc_cinfo.pck_div;
-
return 0;
 }
 
 static int dpi_set_mode(struct dpi_data *dpi)
 {
-   int lck_div = 0, pck_div = 0;
-   unsigned long fck = 0;
-   int r = 0;
+   int r;
 
if (dpi->pll)
-   r = dpi_set_pll_clk(dpi, dpi->output.dispc_channel,
-   dpi->pixelclock, &fck, &lck_div, &pck_div);
+   r = dpi_set_pll_clk(dpi, dpi->pixelclock);
else
-   r = dpi_set_dispc_clk(dpi, dpi->pixelclock, &fck,
-   &lck_div, &pck_div);
-   if (r)
-   return r;
+   r = dpi_set_dispc_clk(dpi, dpi->pixelclock);
 
-   return 0;
+   return r;
 }
 
 static void dpi_config_lcd_manager(struct dpi_data *dpi)
-- 
Regards,

Laurent Pinchart

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

[PATCH 51/60] drm/omap: dpi: Sort includes alphabetically

2019-07-07 Thread Laurent Pinchart
This makes it easier to quickly locate duplicate includes.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index e1f94a84c9bd..da7d50cde31d 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -20,20 +20,20 @@
 
 #define DSS_SUBSYS_NAME "DPI"
 
-#include 
+#include 
 #include 
-#include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-#include 
-#include 
 #include 
 
-#include "omapdss.h"
 #include "dss.h"
+#include "omapdss.h"
 
 struct dpi_data {
struct platform_device *pdev;
-- 
Regards,

Laurent Pinchart

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

[PATCH 50/60] drm/omap: displays: Remove unused panel drivers

2019-07-07 Thread Laurent Pinchart
drm_panel-based drivers for the ACX565AKM, LB035Q02, LS037V7DW01,
NL8048HL11, TD028TTEC1 and TD043MTEA1 are available, remove the
omapdrm-specific drivers.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/displays/Kconfig  |  38 -
 drivers/gpu/drm/omapdrm/displays/Makefile |   6 -
 .../displays/panel-lgphilips-lb035q02.c   | 254 --
 .../omapdrm/displays/panel-nec-nl8048hl11.c   | 271 ---
 .../displays/panel-sharp-ls037v7dw01.c| 265 --
 .../omapdrm/displays/panel-sony-acx565akm.c   | 766 --
 .../omapdrm/displays/panel-tpo-td028ttec1.c   | 401 -
 .../omapdrm/displays/panel-tpo-td043mtea1.c   | 513 
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   7 -
 9 files changed, 2521 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c

diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig 
b/drivers/gpu/drm/omapdrm/displays/Kconfig
index bb73d49fc3e0..f2be594c7eff 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -7,42 +7,4 @@ config DRM_OMAP_PANEL_DSI_CM
help
  Driver for generic DSI command mode panels.
 
-config DRM_OMAP_PANEL_SONY_ACX565AKM
-   tristate "ACX565AKM Panel"
-   depends on SPI && BACKLIGHT_CLASS_DEVICE
-   help
- This is the LCD panel used on Nokia N900
-
-config DRM_OMAP_PANEL_LGPHILIPS_LB035Q02
-   tristate "LG.Philips LB035Q02 LCD Panel"
-   depends on SPI
-   help
- LCD Panel used on the Gumstix Overo Palo35
-
-config DRM_OMAP_PANEL_SHARP_LS037V7DW01
-tristate "Sharp LS037V7DW01 LCD Panel"
-depends on BACKLIGHT_CLASS_DEVICE
-help
-  LCD Panel used in TI's SDP3430 and EVM boards
-
-config DRM_OMAP_PANEL_TPO_TD028TTEC1
-tristate "TPO TD028TTEC1 LCD Panel"
-depends on SPI
-help
-  LCD panel used in Openmoko.
-
-config DRM_OMAP_PANEL_TPO_TD043MTEA1
-tristate "TPO TD043MTEA1 LCD Panel"
-depends on SPI
-help
-  LCD Panel used in OMAP3 Pandora
-
-config DRM_OMAP_PANEL_NEC_NL8048HL11
-   tristate "NEC NL8048HL11 Panel"
-   depends on SPI
-   depends on BACKLIGHT_CLASS_DEVICE
-   help
-   This NEC NL8048HL11 panel is TFT LCD used in the
-   Zoom2/3/3630 sdp boards.
-
 endmenu
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile 
b/drivers/gpu/drm/omapdrm/displays/Makefile
index 58ddfa9917f8..488ddf153613 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -1,8 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_OMAP_PANEL_DSI_CM) += panel-dsi-cm.o
-obj-$(CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
-obj-$(CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
-obj-$(CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
-obj-$(CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
-obj-$(CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
-obj-$(CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c 
b/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
deleted file mode 100644
index 51eb98e96cde..
--- a/drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * LG.Philips LB035Q02 LCD Panel driver
- *
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Tomi Valkeinen 
- * Based on a driver by: Steve Sakoman 
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-#include 
-#include 
-
-#include "../dss/omapdss.h"
-
-static const struct videomode lb035q02_vm = {
-   .hactive = 320,
-   .vactive = 240,
-
-   .pixelclock = 650,
-
-   .hsync_len  = 2,
-   .hfront_porch   = 20,
-   .hback_porch= 68,
-
-   .vsync_len  = 2,
-   .vfront_porch   = 4,
-   .vback_porch= 18,
-
-   .flags  = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
-};
-
-struct panel_drv_data {
-   struct omap_dss_device dssdev;
-
-   struct spi_device *spi;
-
-   struct videomode vm;
-
-   struct gpio_desc *enable_gpio;
-};
-
-#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
-
-static int lb035q

[PATCH 49/60] drm/omap: hdmi5: Simplify EDID read

2019-07-07 Thread Laurent Pinchart
Now that the omap_dss_device EDID read operation has been removed,
simplify the bridge-based EDID access by merging multiple functions
together.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 86 -
 1 file changed, 35 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 6399ee5bd6d6..effc22aeac4a 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -317,50 +317,6 @@ static void hdmi_core_disable(struct omap_hdmi *hdmi)
mutex_unlock(&hdmi->lock);
 }
 
-static struct edid *
-hdmi_do_read_edid(struct omap_hdmi *hdmi,
- struct edid *(*read)(struct omap_hdmi *hdmi,
-  struct drm_connector *connector),
- struct drm_connector *connector)
-{
-   struct edid *edid;
-   bool need_enable;
-   int idlemode;
-   int r;
-
-   need_enable = hdmi->core_enabled == false;
-
-   if (need_enable) {
-   r = hdmi_core_enable(hdmi);
-   if (r)
-   return NULL;
-   }
-
-   mutex_lock(&hdmi->lock);
-   r = hdmi_runtime_get(hdmi);
-   BUG_ON(r);
-
-   idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
-   /* No-idle mode */
-   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
-
-   hdmi5_core_ddc_init(&hdmi->core);
-
-   edid = read(hdmi, connector);
-
-   hdmi5_core_ddc_uninit(&hdmi->core);
-
-   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
-
-   hdmi_runtime_put(hdmi);
-   mutex_unlock(&hdmi->lock);
-
-   if (need_enable)
-   hdmi_core_disable(hdmi);
-
-   return (struct edid *)edid;
-}
-
 /* 
-
  * DRM Bridge Operations
  */
@@ -477,18 +433,46 @@ static void hdmi5_bridge_disable(struct drm_bridge 
*bridge,
mutex_unlock(&hdmi->lock);
 }
 
-static struct edid *hdmi5_bridge_read_edid(struct omap_hdmi *hdmi,
-  struct drm_connector *connector)
-{
-   return drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
-}
-
 static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
  struct drm_connector *connector)
 {
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+   struct edid *edid;
+   bool need_enable;
+   int idlemode;
+   int r;
 
-   return hdmi_do_read_edid(hdmi, hdmi5_bridge_read_edid, connector);
+   need_enable = hdmi->core_enabled == false;
+
+   if (need_enable) {
+   r = hdmi_core_enable(hdmi);
+   if (r)
+   return NULL;
+   }
+
+   mutex_lock(&hdmi->lock);
+   r = hdmi_runtime_get(hdmi);
+   BUG_ON(r);
+
+   idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
+   /* No-idle mode */
+   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
+
+   hdmi5_core_ddc_init(&hdmi->core);
+
+   edid = drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
+
+   hdmi5_core_ddc_uninit(&hdmi->core);
+
+   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
+
+   hdmi_runtime_put(hdmi);
+   mutex_unlock(&hdmi->lock);
+
+   if (need_enable)
+   hdmi_core_disable(hdmi);
+
+   return (struct edid *)edid;
 }
 
 static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
-- 
Regards,

Laurent Pinchart

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

[PATCH 47/60] drm/omap: venc: Remove omap_dss_device operations

2019-07-07 Thread Laurent Pinchart
Now that the VENC output is driven fully through the drm_bridge API its
omap_dss_device operations are not used anymore. Remove them.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 45 --
 1 file changed, 45 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 66cd75e71939..53c85faaf9be 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -319,7 +319,6 @@ struct venc_device {
struct drm_bridge bridge;
 };
 
-#define dssdev_to_venc(dssdev) container_of(dssdev, struct venc_device, output)
 #define drm_bridge_to_venc(b) container_of(b, struct venc_device, bridge)
 
 static inline void venc_write_reg(struct venc_device *venc, int idx, u32 val)
@@ -492,30 +491,6 @@ static void venc_power_off(struct venc_device *venc)
venc_runtime_put(venc);
 }
 
-static int venc_get_modes(struct omap_dss_device *dssdev,
- struct drm_connector *connector)
-{
-   static const struct drm_display_mode *modes[] = {
-   &omap_dss_pal_mode,
-   &omap_dss_ntsc_mode,
-   };
-   unsigned int i;
-
-   for (i = 0; i < ARRAY_SIZE(modes); ++i) {
-   struct drm_display_mode *mode;
-
-   mode = drm_mode_duplicate(connector->dev, modes[i]);
-   if (!mode)
-   return i;
-
-   mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
-   drm_mode_set_name(mode);
-   drm_mode_probed_add(connector, mode);
-   }
-
-   return ARRAY_SIZE(modes);
-}
-
 static enum venc_videomode venc_get_videomode(const struct drm_display_mode 
*mode)
 {
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
@@ -611,25 +586,6 @@ static int venc_get_clocks(struct venc_device *venc)
return 0;
 }
 
-static int venc_connect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   return omapdss_device_connect(dst->dss, dst, dst->next);
-}
-
-static void venc_disconnect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   omapdss_device_disconnect(dst, dst->next);
-}
-
-static const struct omap_dss_device_ops venc_ops = {
-   .connect = venc_connect,
-   .disconnect = venc_disconnect,
-
-   .get_modes = venc_get_modes,
-};
-
 /* 
-
  * DRM Bridge Operations
  */
@@ -837,7 +793,6 @@ static int venc_init_output(struct venc_device *venc)
out->type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
-   out->ops = &venc_ops;
out->owner = THIS_MODULE;
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
-- 
Regards,

Laurent Pinchart

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

[PATCH 48/60] drm/omap: hdmi4: Simplify EDID read

2019-07-07 Thread Laurent Pinchart
Now that the omap_dss_device EDID read operation has been removed,
simplify the bridge-based EDID access by merging multiple functions
together.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 96 -
 1 file changed, 40 insertions(+), 56 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 70d98f39b8c6..b8a552b25f43 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -319,55 +319,6 @@ void hdmi4_core_disable(struct hdmi_core_data *core)
mutex_unlock(&hdmi->lock);
 }
 
-static struct edid *
-hdmi_do_read_edid(struct omap_hdmi *hdmi,
- struct edid *(*read)(struct omap_hdmi *hdmi,
-  struct drm_connector *connector),
- struct drm_connector *connector)
-{
-   struct edid *edid = NULL;
-   unsigned int cec_addr;
-   bool need_enable;
-   int r;
-
-   need_enable = hdmi->core_enabled == false;
-
-   if (need_enable) {
-   r = hdmi4_core_enable(&hdmi->core);
-   if (r)
-   return NULL;
-   }
-
-   mutex_lock(&hdmi->lock);
-   r = hdmi_runtime_get(hdmi);
-   BUG_ON(r);
-
-   r = hdmi4_core_ddc_init(&hdmi->core);
-   if (r)
-   goto done;
-
-   edid = read(hdmi, connector);
-
-done:
-   hdmi_runtime_put(hdmi);
-   mutex_unlock(&hdmi->lock);
-
-   if (edid && edid->extensions) {
-   unsigned int len = (edid->extensions + 1) * EDID_LENGTH;
-
-   cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL);
-   } else {
-   cec_addr = CEC_PHYS_ADDR_INVALID;
-   }
-
-   hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
-
-   if (need_enable)
-   hdmi4_core_disable(&hdmi->core);
-
-   return edid;
-}
-
 /* 
-
  * DRM Bridge Operations
  */
@@ -491,18 +442,51 @@ static void hdmi4_bridge_lost_hotplug(struct drm_bridge 
*bridge)
hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
 }
 
-static struct edid *hdmi4_bridge_read_edid(struct omap_hdmi *hdmi,
-  struct drm_connector *connector)
-{
-   return drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core);
-}
-
 static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge,
  struct drm_connector *connector)
 {
struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+   struct edid *edid = NULL;
+   unsigned int cec_addr;
+   bool need_enable;
+   int r;
 
-   return hdmi_do_read_edid(hdmi, hdmi4_bridge_read_edid, connector);
+   need_enable = hdmi->core_enabled == false;
+
+   if (need_enable) {
+   r = hdmi4_core_enable(&hdmi->core);
+   if (r)
+   return NULL;
+   }
+
+   mutex_lock(&hdmi->lock);
+   r = hdmi_runtime_get(hdmi);
+   BUG_ON(r);
+
+   r = hdmi4_core_ddc_init(&hdmi->core);
+   if (r)
+   goto done;
+
+   edid = drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core);
+
+done:
+   hdmi_runtime_put(hdmi);
+   mutex_unlock(&hdmi->lock);
+
+   if (edid && edid->extensions) {
+   unsigned int len = (edid->extensions + 1) * EDID_LENGTH;
+
+   cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL);
+   } else {
+   cec_addr = CEC_PHYS_ADDR_INVALID;
+   }
+
+   hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
+
+   if (need_enable)
+   hdmi4_core_disable(&hdmi->core);
+
+   return edid;
 }
 
 static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
-- 
Regards,

Laurent Pinchart

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

[PATCH 45/60] drm/omap: Remove HPD, detect and EDID omapdss operations

2019-07-07 Thread Laurent Pinchart
Due to the removal of several omapdrm display drivers, the omapdss HPD,
detected and EDID operations are not used anymore. Remove them and all
related code.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  |  59 ---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  |  44 --
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  25 +--
 drivers/gpu/drm/omapdrm/omap_connector.c | 190 +++
 drivers/gpu/drm/omapdrm/omap_connector.h |   2 -
 drivers/gpu/drm/omapdrm/omap_drv.c   |   8 +-
 6 files changed, 22 insertions(+), 306 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index b65afa8b93c6..2feae9ba1729 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -331,45 +331,6 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi,
-   struct drm_connector *connector)
-{
-   u8 *edid;
-   int r;
-
-   edid = kzalloc(512, GFP_KERNEL);
-   if (!edid)
-   return NULL;
-
-   r = hdmi4_core_ddc_read(&hdmi->core, edid, 0, EDID_LENGTH);
-   if (r)
-   goto error;
-
-   if (edid[0x7e] > 0) {
-   char checksum = 0;
-   unsigned int i;
-
-   r = hdmi4_core_ddc_read(&hdmi->core, edid + EDID_LENGTH, 1,
-   EDID_LENGTH);
-   if (r)
-   goto error;
-
-   for (i = 0; i < EDID_LENGTH; ++i)
-   checksum += edid[EDID_LENGTH + i];
-
-   if (checksum != 0) {
-   DSSERR("E-EDID checksum failed!!\n");
-   goto error;
-   }
-   }
-
-   return (struct edid *)edid;
-
-error:
-   kfree(edid);
-   return NULL;
-}
-
 static struct edid *
 hdmi_do_read_edid(struct omap_hdmi *hdmi,
  struct edid *(*read)(struct omap_hdmi *hdmi,
@@ -419,28 +380,9 @@ hdmi_do_read_edid(struct omap_hdmi *hdmi,
return edid;
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
-{
-   return hdmi_do_read_edid(dssdev_to_hdmi(dssdev), hdmi_read_edid_data,
-NULL);
-}
-
-static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
-}
-
 static const struct omap_dss_device_ops hdmi_ops = {
.connect= hdmi_connect,
.disconnect = hdmi_disconnect,
-
-   .read_edid  = hdmi_read_edid,
-
-   .hdmi = {
-   .lost_hotplug   = hdmi_lost_hotplug,
-   },
 };
 
 /* 
-
@@ -805,7 +747,6 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi)
out->ops = &hdmi_ops;
out->owner = THIS_MODULE;
out->of_port = 0;
-   out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 
r = omapdss_device_init_output(out, &hdmi->bridge);
if (r < 0)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index fd386e189ab4..0502e692d646 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -329,41 +329,6 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi,
-   struct drm_connector *connector)
-{
-   struct hdmi_core_data *core = &hdmi->core;
-   int max_ext_blocks = 3;
-   int r, n, i;
-   u8 *edid;
-
-   edid = kzalloc(512, GFP_KERNEL);
-   if (!edid)
-   return NULL;
-
-   r = hdmi5_core_ddc_read(core, edid, 0, EDID_LENGTH);
-   if (r)
-   goto error;
-
-   n = edid[0x7e];
-
-   if (n > max_ext_blocks)
-   n = max_ext_blocks;
-
-   for (i = 1; i <= n; i++) {
-   r = hdmi5_core_ddc_read(core, edid + i * EDID_LENGTH, i,
-   EDID_LENGTH);
-   if (r)
-   goto error;
-   }
-
-   return (struct edid *)edid;
-
-error:
-   kfree(edid);
-   return NULL;
-}
-
 static struct edid *
 hdmi_do_read_edid(struct omap_hdmi *hdmi,
  struct edid *(*read)(struct omap_hdmi *hdmi,
@@ -408,17 +373,9 @@ hdmi_do_read_edid(struct omap_hdmi *hdmi,
return (struct edid *)edid;
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
-{
-   return hdmi_do_read_edid(dssdev_to_hdmi(dssdev), hdmi_read_edid_data,
-NULL);
-}
-
 static const struct omap_dss_device_ops hdmi_ops = {
.connect 

[PATCH 46/60] drm/omap: hdmi: Remove omap_dss_device operations

2019-07-07 Thread Laurent Pinchart
Now that the HDMI outputs are driven fully through the drm_bridge API
their omap_dss_device operations are not used anymore. Remove them.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi.h  |  1 -
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 18 --
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 18 --
 3 files changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h 
b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index d1e3f625eebc..a501cfc21af4 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -391,7 +391,6 @@ struct omap_hdmi {
bool display_enabled;
 };
 
-#define dssdev_to_hdmi(dssdev) container_of(dssdev, struct omap_hdmi, output)
 #define drm_bridge_to_hdmi(b) container_of(b, struct omap_hdmi, bridge)
 
 #endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 2feae9ba1729..70d98f39b8c6 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -319,18 +319,6 @@ void hdmi4_core_disable(struct hdmi_core_data *core)
mutex_unlock(&hdmi->lock);
 }
 
-static int hdmi_connect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   return omapdss_device_connect(dst->dss, dst, dst->next);
-}
-
-static void hdmi_disconnect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   omapdss_device_disconnect(dst, dst->next);
-}
-
 static struct edid *
 hdmi_do_read_edid(struct omap_hdmi *hdmi,
  struct edid *(*read)(struct omap_hdmi *hdmi,
@@ -380,11 +368,6 @@ hdmi_do_read_edid(struct omap_hdmi *hdmi,
return edid;
 }
 
-static const struct omap_dss_device_ops hdmi_ops = {
-   .connect= hdmi_connect,
-   .disconnect = hdmi_disconnect,
-};
-
 /* 
-
  * DRM Bridge Operations
  */
@@ -744,7 +727,6 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi)
out->type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
-   out->ops = &hdmi_ops;
out->owner = THIS_MODULE;
out->of_port = 0;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 0502e692d646..6399ee5bd6d6 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -317,18 +317,6 @@ static void hdmi_core_disable(struct omap_hdmi *hdmi)
mutex_unlock(&hdmi->lock);
 }
 
-static int hdmi_connect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   return omapdss_device_connect(dst->dss, dst, dst->next);
-}
-
-static void hdmi_disconnect(struct omap_dss_device *src,
-   struct omap_dss_device *dst)
-{
-   omapdss_device_disconnect(dst, dst->next);
-}
-
 static struct edid *
 hdmi_do_read_edid(struct omap_hdmi *hdmi,
  struct edid *(*read)(struct omap_hdmi *hdmi,
@@ -373,11 +361,6 @@ hdmi_do_read_edid(struct omap_hdmi *hdmi,
return (struct edid *)edid;
 }
 
-static const struct omap_dss_device_ops hdmi_ops = {
-   .connect= hdmi_connect,
-   .disconnect = hdmi_disconnect,
-};
-
 /* 
-
  * DRM Bridge Operations
  */
@@ -720,7 +703,6 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
out->type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
-   out->ops = &hdmi_ops;
out->owner = THIS_MODULE;
out->of_port = 0;
 
-- 
Regards,

Laurent Pinchart

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

[PATCH 44/60] drm/omap: Switch the HDMI and VENC outputs to drm_bridge

2019-07-07 Thread Laurent Pinchart
The TPD12S015, OPA362 and analog and HDMI connectors are now supported
by DRM bridge drivers, and the omapdrm HDMI and VENC outputs can be
handled through the drm_bridge API. Switch the outputs to drm_brdige by
making the next bridge mandatory and removing the related
omapdrm-specific display drivers.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/displays/Kconfig  |  22 --
 drivers/gpu/drm/omapdrm/displays/Makefile |   4 -
 .../omapdrm/displays/connector-analog-tv.c| 100 
 .../gpu/drm/omapdrm/displays/connector-hdmi.c | 186 ---
 .../gpu/drm/omapdrm/displays/encoder-opa362.c | 140 ---
 .../drm/omapdrm/displays/encoder-tpd12s015.c  | 220 --
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |   4 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |   4 +-
 .../gpu/drm/omapdrm/dss/omapdss-boot-init.c   |   5 -
 drivers/gpu/drm/omapdrm/dss/output.c  |   5 +
 drivers/gpu/drm/omapdrm/dss/venc.c|   4 +-
 11 files changed, 11 insertions(+), 683 deletions(-)
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
 delete mode 100644 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c

diff --git a/drivers/gpu/drm/omapdrm/displays/Kconfig 
b/drivers/gpu/drm/omapdrm/displays/Kconfig
index c2566da32ac4..bb73d49fc3e0 100644
--- a/drivers/gpu/drm/omapdrm/displays/Kconfig
+++ b/drivers/gpu/drm/omapdrm/displays/Kconfig
@@ -1,28 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menu "OMAPDRM External Display Device Drivers"
 
-config DRM_OMAP_ENCODER_OPA362
-   tristate "OPA362 external analog amplifier"
-   help
- Driver for OPA362 external analog TV amplifier controlled
- through a GPIO.
-
-config DRM_OMAP_ENCODER_TPD12S015
-tristate "TPD12S015 HDMI ESD protection and level shifter"
-   help
- Driver for TPD12S015, which offers HDMI ESD protection and level
- shifting.
-
-config DRM_OMAP_CONNECTOR_HDMI
-tristate "HDMI Connector"
-   help
- Driver for a generic HDMI connector.
-
-config DRM_OMAP_CONNECTOR_ANALOG_TV
-tristate "Analog TV Connector"
-   help
- Driver for a generic analog TV connector.
-
 config DRM_OMAP_PANEL_DSI_CM
tristate "Generic DSI Command Mode Panel"
depends on BACKLIGHT_CLASS_DEVICE
diff --git a/drivers/gpu/drm/omapdrm/displays/Makefile 
b/drivers/gpu/drm/omapdrm/displays/Makefile
index 1db34d4fed64..58ddfa9917f8 100644
--- a/drivers/gpu/drm/omapdrm/displays/Makefile
+++ b/drivers/gpu/drm/omapdrm/displays/Makefile
@@ -1,8 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_DRM_OMAP_ENCODER_OPA362) += encoder-opa362.o
-obj-$(CONFIG_DRM_OMAP_ENCODER_TPD12S015) += encoder-tpd12s015.o
-obj-$(CONFIG_DRM_OMAP_CONNECTOR_HDMI) += connector-hdmi.o
-obj-$(CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV) += connector-analog-tv.o
 obj-$(CONFIG_DRM_OMAP_PANEL_DSI_CM) += panel-dsi-cm.o
 obj-$(CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
deleted file mode 100644
index 2ab18744a5d7..
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Analog TV Connector driver
- *
- * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
- * Author: Tomi Valkeinen 
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- */
-
-#include 
-#include 
-#include 
-#include 
-
-#include "../dss/omapdss.h"
-
-struct panel_drv_data {
-   struct omap_dss_device dssdev;
-
-   struct device *dev;
-};
-
-#define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
-
-static int tvc_connect(struct omap_dss_device *src,
-  struct omap_dss_device *dst)
-{
-   return 0;
-}
-
-static void tvc_disconnect(struct omap_dss_device *src,
-  struct omap_dss_device *dst)
-{
-}
-
-static const struct omap_dss_device_ops tvc_ops = {
-   .connect= tvc_connect,
-   .disconnect = tvc_disconnect,
-};
-
-static int tvc_probe(struct platform_device *pdev)
-{
-   struct panel_drv_data *ddata;
-   struct omap_dss_device *dssdev;
-
-   ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
-   if (!ddata)
-   return -ENOMEM;
-
-   platform_set_drvdata(pdev, ddata);
-   ddata->dev = &pdev->dev;
-
-   dssdev = &ddata->dssdev;
-   dssdev->ops = &tvc_ops;
-   dssdev->dev = &pdev->dev;
-   dssdev->type = OMAP_DISPLAY_TYPE_VENC;
-   d

[PATCH 43/60] drm/omap: Create connector for bridges

2019-07-07 Thread Laurent Pinchart
Use the drm_bridge_connector helper to create a connector for pipelines
that use drm_bridge. This allows splitting connector operations across
multiple bridges when necessary, instead of having the last bridge in
the chain creating the connector and handling all connector operations
internally.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 57 ++
 1 file changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 790a2b5a1591..88f9328eda72 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -21,7 +21,9 @@
 
 #include 
 #include 
+#include 
 #include 
+#include 
 #include 
 
 #include "omap_dmm_tiler.h"
@@ -296,9 +298,13 @@ static int omap_modeset_init(struct drm_device *dev)
if (pipe->output->bridge) {
ret = drm_bridge_attach(pipe->encoder,
pipe->output->bridge, NULL,
-   true);
-   if (ret < 0)
+   false);
+   if (ret < 0) {
+   dev_err(priv->dev,
+   "unable to attach bridge %pOF\n",
+   pipe->output->bridge->of_node);
return ret;
+   }
}
 
id = omap_display_id(pipe->output);
@@ -334,8 +340,31 @@ static int omap_modeset_init(struct drm_device *dev)
  encoder);
if (!pipe->connector)
return -ENOMEM;
+   } else {
+   struct drm_bridge *bridge = pipe->output->bridge;
 
-   drm_connector_attach_encoder(pipe->connector, encoder);
+   pipe->connector = drm_bridge_connector_init(dev,
+   bridge);
+   if (IS_ERR(pipe->connector)) {
+   dev_err(priv->dev,
+   "unable to create bridge connector for 
%pOF\n",
+   bridge->of_node);
+   return PTR_ERR(pipe->connector);
+   }
+   }
+
+   drm_connector_attach_encoder(pipe->connector, encoder);
+
+   /*
+* FIXME: drm_panel should not store the drm_connector pointer
+* internally but should receive it in its .get_modes()
+* operation.
+*/
+   if (pipe->output->panel) {
+   ret = drm_panel_attach(pipe->output->panel,
+  pipe->connector);
+   if (ret < 0)
+   return ret;
}
 
crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
@@ -400,8 +429,15 @@ static void omap_modeset_enable_external_hpd(struct 
drm_device *ddev)
unsigned int i;
 
for (i = 0; i < priv->num_pipes; i++) {
-   if (priv->pipes[i].connector)
-   omap_connector_enable_hpd(priv->pipes[i].connector);
+   struct drm_connector *connector = priv->pipes[i].connector;
+
+   if (!connector)
+   continue;
+
+   if (priv->pipes[i].output->next)
+   omap_connector_enable_hpd(connector);
+   else
+   drm_bridge_connector_enable_hpd(connector);
}
 }
 
@@ -414,8 +450,15 @@ static void omap_modeset_disable_external_hpd(struct 
drm_device *ddev)
unsigned int i;
 
for (i = 0; i < priv->num_pipes; i++) {
-   if (priv->pipes[i].connector)
-   omap_connector_disable_hpd(priv->pipes[i].connector);
+   struct drm_connector *connector = priv->pipes[i].connector;
+
+   if (!connector)
+   continue;
+
+   if (priv->pipes[i].output->next)
+   omap_connector_disable_hpd(connector);
+   else
+   drm_bridge_connector_disable_hpd(connector);
}
 }
 
-- 
Regards,

Laurent Pinchart

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

[PATCH 41/60] drm/omap: dss: Remove .set_hdmi_mode() and .set_infoframe() operations

2019-07-07 Thread Laurent Pinchart
The omapdss_hdmi_ops .set_hdmi_mode() and .set_infoframe() operations
operations are not used anymore, remove them.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/omapdss.h  |  3 ---
 drivers/gpu/drm/omapdrm/omap_encoder.c | 26 --
 2 files changed, 29 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index ccdf42617613..5e0a146b2f36 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -298,9 +298,6 @@ struct omap_dss_writeback_info {
 
 struct omapdss_hdmi_ops {
void (*lost_hotplug)(struct omap_dss_device *dssdev);
-   int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
-   int (*set_infoframe)(struct omap_dss_device *dssdev,
-   const struct hdmi_avi_infoframe *avi);
 };
 
 struct omapdss_dsi_ops {
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index fa4e00e65f9d..8af889f0af06 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -79,28 +79,6 @@ static void omap_encoder_update_videomode_flags(struct 
videomode *vm,
}
 }
 
-static void omap_encoder_hdmi_mode_set(struct drm_connector *connector,
-  struct drm_encoder *encoder,
-  struct drm_display_mode *adjusted_mode)
-{
-   struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
-   struct omap_dss_device *dssdev = omap_encoder->output;
-   bool hdmi_mode = connector->display_info.is_hdmi;
-
-   if (dssdev->ops && dssdev->ops->hdmi.set_hdmi_mode)
-   dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
-
-   if (hdmi_mode && dssdev->ops && dssdev->ops->hdmi.set_infoframe) {
-   struct hdmi_avi_infoframe avi;
-   int r;
-
-   r = drm_hdmi_avi_infoframe_from_display_mode(&avi, connector,
-adjusted_mode);
-   if (r == 0)
-   dssdev->ops->hdmi.set_infoframe(dssdev, &avi);
-   }
-}
-
 static void omap_encoder_mode_set(struct drm_encoder *encoder,
  struct drm_display_mode *mode,
  struct drm_display_mode *adjusted_mode)
@@ -151,10 +129,6 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
if (dssdev->ops && dssdev->ops->set_timings)
dssdev->ops->set_timings(dssdev, adjusted_mode);
}
-
-   /* Set the HDMI mode and HDMI infoframe if applicable. */
-   if (output->type == OMAP_DISPLAY_TYPE_HDMI)
-   omap_encoder_hdmi_mode_set(connector, encoder, adjusted_mode);
 }
 
 static void omap_encoder_disable(struct drm_encoder *encoder)
-- 
Regards,

Laurent Pinchart

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

[PATCH 42/60] drm/omap: venc: Register a drm_bridge

2019-07-07 Thread Laurent Pinchart
In order to integrate with a chain of drm_bridge, the internal VENC
encoder has to expose the mode valid, fixup and set, the enable and
disable and the get modes operations through the drm_bridge API.
Register a bridge at initialisation time to do so.

Most of those operations are removed from the omap_dss_device as they
are now called through the drm_bridge API by the DRM atomic helpers. The
only exception is the .get_modes() operation that is still invoked
through the omap_dss_device-based pipeline.

For the time being make the next bridge in the chain optional as the
VENC output is still based on omap_dss_device. The create_connector
argument to the bridge attach function is also ignored for the same
reason. This will be changed later when removing the related
omapdrm-specific display drivers.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/venc.c | 244 +++--
 1 file changed, 160 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/venc.c 
b/drivers/gpu/drm/omapdrm/dss/venc.c
index 0a81dd5c93d6..d9f8208e0ee9 100644
--- a/drivers/gpu/drm/omapdrm/dss/venc.c
+++ b/drivers/gpu/drm/omapdrm/dss/venc.c
@@ -37,6 +37,8 @@
 #include 
 #include 
 
+#include 
+
 #include "omapdss.h"
 #include "dss.h"
 
@@ -314,9 +316,11 @@ struct venc_device {
bool requires_tv_dac_clk;
 
struct omap_dss_device output;
+   struct drm_bridge bridge;
 };
 
 #define dssdev_to_venc(dssdev) container_of(dssdev, struct venc_device, output)
+#define drm_bridge_to_venc(b) container_of(b, struct venc_device, bridge)
 
 static inline void venc_write_reg(struct venc_device *venc, int idx, u32 val)
 {
@@ -488,32 +492,6 @@ static void venc_power_off(struct venc_device *venc)
venc_runtime_put(venc);
 }
 
-static void venc_display_enable(struct omap_dss_device *dssdev)
-{
-   struct venc_device *venc = dssdev_to_venc(dssdev);
-
-   DSSDBG("venc_display_enable\n");
-
-   mutex_lock(&venc->venc_lock);
-
-   venc_power_on(venc);
-
-   mutex_unlock(&venc->venc_lock);
-}
-
-static void venc_display_disable(struct omap_dss_device *dssdev)
-{
-   struct venc_device *venc = dssdev_to_venc(dssdev);
-
-   DSSDBG("venc_display_disable\n");
-
-   mutex_lock(&venc->venc_lock);
-
-   venc_power_off(venc);
-
-   mutex_unlock(&venc->venc_lock);
-}
-
 static int venc_get_modes(struct omap_dss_device *dssdev,
  struct drm_connector *connector)
 {
@@ -556,57 +534,6 @@ static enum venc_videomode venc_get_videomode(const struct 
drm_display_mode *mod
return VENC_MODE_UNKNOWN;
 }
 
-static void venc_set_timings(struct omap_dss_device *dssdev,
-const struct drm_display_mode *mode)
-{
-   struct venc_device *venc = dssdev_to_venc(dssdev);
-   enum venc_videomode venc_mode = venc_get_videomode(mode);
-
-   DSSDBG("venc_set_timings\n");
-
-   mutex_lock(&venc->venc_lock);
-
-   switch (venc_mode) {
-   default:
-   WARN_ON_ONCE(1);
-   /* Fall-through */
-   case VENC_MODE_PAL:
-   venc->config = &venc_config_pal_trm;
-   break;
-
-   case VENC_MODE_NTSC:
-   venc->config = &venc_config_ntsc_trm;
-   break;
-   }
-
-   dispc_set_tv_pclk(venc->dss->dispc, 1350);
-
-   mutex_unlock(&venc->venc_lock);
-}
-
-static int venc_check_timings(struct omap_dss_device *dssdev,
- struct drm_display_mode *mode)
-{
-   DSSDBG("venc_check_timings\n");
-
-   switch (venc_get_videomode(mode)) {
-   case VENC_MODE_PAL:
-   drm_mode_copy(mode, &omap_dss_pal_mode);
-   break;
-
-   case VENC_MODE_NTSC:
-   drm_mode_copy(mode, &omap_dss_ntsc_mode);
-   break;
-
-   default:
-   return -EINVAL;
-   }
-
-   drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-   drm_mode_set_name(mode);
-   return 0;
-}
-
 static int venc_dump_regs(struct seq_file *s, void *p)
 {
struct venc_device *venc = s->private;
@@ -700,15 +627,160 @@ static const struct omap_dss_device_ops venc_ops = {
.connect = venc_connect,
.disconnect = venc_disconnect,
 
-   .enable = venc_display_enable,
-   .disable = venc_display_disable,
-
-   .check_timings = venc_check_timings,
-   .set_timings = venc_set_timings,
-
.get_modes = venc_get_modes,
 };
 
+/* 
-
+ * DRM Bridge Operations
+ */
+
+static int venc_bridge_attach(struct drm_bridge *bridge, bool create_connector)
+{
+   struct venc_device *venc = drm_bridge_to_venc(bridge);
+
+   if (venc->output.next_bridge)
+   return 0;
+
+   return drm_bridge_attach(bridge->encoder, venc->output.next_bridge,
+bridge, false);
+}
+
+static enum drm_mode_status
+venc_bridge_mode_valid

[PATCH 40/60] drm/omap: hdmi4: Implement drm_bridge .lost_hotplug() operation

2019-07-07 Thread Laurent Pinchart
The HDMI4 encoder is transitioning to the drm_bridge API, implement the
last missing operation.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index a8f582c0f387..df56acb5cb27 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -559,6 +559,13 @@ static void hdmi4_bridge_disable(struct drm_bridge *bridge,
mutex_unlock(&hdmi->lock);
 }
 
+static void hdmi4_bridge_lost_hotplug(struct drm_bridge *bridge)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+
+   hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
+}
+
 static struct edid *hdmi4_bridge_read_edid(struct omap_hdmi *hdmi,
   struct drm_connector *connector)
 {
@@ -578,6 +585,7 @@ static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
.mode_set = hdmi4_bridge_mode_set,
.atomic_enable = hdmi4_bridge_enable,
.atomic_disable = hdmi4_bridge_disable,
+   .lost_hotplug = hdmi4_bridge_lost_hotplug,
.get_edid = hdmi4_bridge_get_edid,
 };
 
-- 
Regards,

Laurent Pinchart

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

[PATCH 39/60] drm/omap: hdmi5: Move mode set, enable and disable operations to bridge

2019-07-07 Thread Laurent Pinchart
Move the omap_dss_device .set_timings(), .enable() and .disable()
operations to the drm_bridge functions. As the drm_bridge for the HDMI
encoder is unconditionally registered and attached, those operations
will be called at the appropriate time.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 204 +++-
 1 file changed, 106 insertions(+), 98 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index dd67a604453f..d03f2a415fd4 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -42,6 +42,8 @@
 #include 
 #include 
 
+#include 
+
 #include "omapdss.h"
 #include "hdmi5_core.h"
 #include "dss.h"
@@ -247,20 +249,6 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
hdmi_power_off_core(hdmi);
 }
 
-static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
-const struct drm_display_mode *mode)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   mutex_lock(&hdmi->lock);
-
-   drm_display_mode_to_videomode(mode, &hdmi->cfg.vm);
-
-   dispc_set_tv_pclk(hdmi->dss->dispc, mode->clock * 1000);
-
-   mutex_unlock(&hdmi->lock);
-}
-
 static int hdmi_dump_regs(struct seq_file *s, void *p)
 {
struct omap_hdmi *hdmi = s->private;
@@ -296,62 +284,6 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
 }
 
-static void hdmi_display_enable(struct omap_dss_device *dssdev)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   unsigned long flags;
-   int r;
-
-   DSSDBG("ENTER hdmi_display_enable\n");
-
-   mutex_lock(&hdmi->lock);
-
-   r = hdmi_power_on_full(hdmi);
-   if (r) {
-   DSSERR("failed to power on device\n");
-   goto done;
-   }
-
-   if (hdmi->audio_configured) {
-   r = hdmi5_audio_config(&hdmi->core, &hdmi->wp,
-  &hdmi->audio_config,
-  hdmi->cfg.vm.pixelclock);
-   if (r) {
-   DSSERR("Error restoring audio configuration: %d", r);
-   hdmi->audio_abort_cb(&hdmi->pdev->dev);
-   hdmi->audio_configured = false;
-   }
-   }
-
-   spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
-   if (hdmi->audio_configured && hdmi->audio_playing)
-   hdmi_start_audio_stream(hdmi);
-   hdmi->display_enabled = true;
-   spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
-
-done:
-   mutex_unlock(&hdmi->lock);
-}
-
-static void hdmi_display_disable(struct omap_dss_device *dssdev)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   unsigned long flags;
-
-   DSSDBG("Enter hdmi_display_disable\n");
-
-   mutex_lock(&hdmi->lock);
-
-   spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
-   hdmi_stop_audio_stream(hdmi);
-   hdmi->display_enabled = false;
-   spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
-
-   hdmi_power_off_full(hdmi);
-
-   mutex_unlock(&hdmi->lock);
-}
-
 static int hdmi_core_enable(struct omap_hdmi *hdmi)
 {
int r = 0;
@@ -482,39 +414,11 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
 NULL);
 }
 
-static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
-   const struct hdmi_avi_infoframe *avi)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   hdmi->cfg.infoframe = *avi;
-   return 0;
-}
-
-static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
-   bool hdmi_mode)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
-   return 0;
-}
-
 static const struct omap_dss_device_ops hdmi_ops = {
.connect= hdmi_connect,
.disconnect = hdmi_disconnect,
 
-   .enable = hdmi_display_enable,
-   .disable= hdmi_display_disable,
-
-   .set_timings= hdmi_display_set_timings,
-
.read_edid  = hdmi_read_edid,
-
-   .hdmi = {
-   .set_infoframe  = hdmi_set_infoframe,
-   .set_hdmi_mode  = hdmi_set_hdmi_mode,
-   },
 };
 
 /* 
-
@@ -532,6 +436,107 @@ static int hdmi5_bridge_attach(struct drm_bridge *bridge, 
bool create_connector)
 bridge, false);
 }
 
+static void hdmi5_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to

[PATCH 38/60] drm/omap: hdmi4: Move mode set, enable and disable operations to bridge

2019-07-07 Thread Laurent Pinchart
Move the omap_dss_device .set_timings(), .enable() and .disable()
operations to the drm_bridge functions. As the drm_bridge for the HDMI
encoder is unconditionally registered and attached, those operations
will be called at the appropriate time.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 201 +++-
 1 file changed, 106 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 3084a200911b..a8f582c0f387 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -39,6 +39,8 @@
 #include 
 #include 
 
+#include 
+
 #include "omapdss.h"
 #include "hdmi4_core.h"
 #include "hdmi4_cec.h"
@@ -248,20 +250,6 @@ static void hdmi_power_off_full(struct omap_hdmi *hdmi)
hdmi_power_off_core(hdmi);
 }
 
-static void hdmi_display_set_timings(struct omap_dss_device *dssdev,
-const struct drm_display_mode *mode)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   mutex_lock(&hdmi->lock);
-
-   drm_display_mode_to_videomode(mode, &hdmi->cfg.vm);
-
-   dispc_set_tv_pclk(hdmi->dss->dispc, mode->clock * 1000);
-
-   mutex_unlock(&hdmi->lock);
-}
-
 static int hdmi_dump_regs(struct seq_file *s, void *p)
 {
struct omap_hdmi *hdmi = s->private;
@@ -295,62 +283,6 @@ static void hdmi_stop_audio_stream(struct omap_hdmi *hd)
hdmi_wp_audio_enable(&hd->wp, false);
 }
 
-static void hdmi_display_enable(struct omap_dss_device *dssdev)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   unsigned long flags;
-   int r;
-
-   DSSDBG("ENTER hdmi_display_enable\n");
-
-   mutex_lock(&hdmi->lock);
-
-   r = hdmi_power_on_full(hdmi);
-   if (r) {
-   DSSERR("failed to power on device\n");
-   goto done;
-   }
-
-   if (hdmi->audio_configured) {
-   r = hdmi4_audio_config(&hdmi->core, &hdmi->wp,
-  &hdmi->audio_config,
-  hdmi->cfg.vm.pixelclock);
-   if (r) {
-   DSSERR("Error restoring audio configuration: %d", r);
-   hdmi->audio_abort_cb(&hdmi->pdev->dev);
-   hdmi->audio_configured = false;
-   }
-   }
-
-   spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
-   if (hdmi->audio_configured && hdmi->audio_playing)
-   hdmi_start_audio_stream(hdmi);
-   hdmi->display_enabled = true;
-   spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
-
-done:
-   mutex_unlock(&hdmi->lock);
-}
-
-static void hdmi_display_disable(struct omap_dss_device *dssdev)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   unsigned long flags;
-
-   DSSDBG("Enter hdmi_display_disable\n");
-
-   mutex_lock(&hdmi->lock);
-
-   spin_lock_irqsave(&hdmi->audio_playing_lock, flags);
-   hdmi_stop_audio_stream(hdmi);
-   hdmi->display_enabled = false;
-   spin_unlock_irqrestore(&hdmi->audio_playing_lock, flags);
-
-   hdmi_power_off_full(hdmi);
-
-   mutex_unlock(&hdmi->lock);
-}
-
 int hdmi4_core_enable(struct hdmi_core_data *core)
 {
struct omap_hdmi *hdmi = container_of(core, struct omap_hdmi, core);
@@ -500,39 +432,14 @@ static void hdmi_lost_hotplug(struct omap_dss_device 
*dssdev)
hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
 }
 
-static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
-   const struct hdmi_avi_infoframe *avi)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   hdmi->cfg.infoframe = *avi;
-   return 0;
-}
-
-static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
-   bool hdmi_mode)
-{
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-
-   hdmi->cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
-   return 0;
-}
-
 static const struct omap_dss_device_ops hdmi_ops = {
.connect= hdmi_connect,
.disconnect = hdmi_disconnect,
 
-   .enable = hdmi_display_enable,
-   .disable= hdmi_display_disable,
-
-   .set_timings= hdmi_display_set_timings,
-
.read_edid  = hdmi_read_edid,
 
.hdmi = {
.lost_hotplug   = hdmi_lost_hotplug,
-   .set_infoframe  = hdmi_set_infoframe,
-   .set_hdmi_mode  = hdmi_set_hdmi_mode,
},
 };
 
@@ -551,6 +458,107 @@ static int hdmi4_bridge_attach(struct drm_bridge *bridge, 
bool create_connector)
 bridge, false);
 }
 
+static void hdmi4_bridge_mode_set(struct drm_bridge *bridge,
+ const struct drm_display_mode *mode,
+ const struct drm_display_mode *adjusted_mode)
+{
+   str

[PATCH 36/60] drm/omap: hdmi4: Register a drm_bridge for EDID read

2019-07-07 Thread Laurent Pinchart
In order to integrate with a chain of drm_bridge, the internal HDMI4
encoder has to expose the EDID read operation through the drm_bridge
API. Register a bridge at initialisation time to do so.

For the time being make the next bridge in the chain optional as the
HDMI output is still based on omap_dss_device. The create_connector
argument to the bridge attach function is also ignored for the same
reason. This will be changed later when removing the related
omapdrm-specific display drivers.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi.h  |  3 ++
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 73 +++--
 2 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi.h 
b/drivers/gpu/drm/omapdrm/dss/hdmi.h
index 7f0dc490a31d..d1e3f625eebc 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi.h
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi.h
@@ -25,6 +25,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "omapdss.h"
 #include "dss.h"
@@ -375,6 +376,7 @@ struct omap_hdmi {
bool core_enabled;
 
struct omap_dss_device output;
+   struct drm_bridge bridge;
 
struct platform_device *audio_pdev;
void (*audio_abort_cb)(struct device *dev);
@@ -390,5 +392,6 @@ struct omap_hdmi {
 };
 
 #define dssdev_to_hdmi(dssdev) container_of(dssdev, struct omap_hdmi, output)
+#define drm_bridge_to_hdmi(b) container_of(b, struct omap_hdmi, bridge)
 
 #endif
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 5d7b17b52dc0..3084a200911b 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -399,7 +399,8 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi)
+static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi,
+   struct drm_connector *connector)
 {
u8 *edid;
int r;
@@ -437,9 +438,12 @@ static struct edid *hdmi_read_edid_data(struct omap_hdmi 
*hdmi)
return NULL;
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+static struct edid *
+hdmi_do_read_edid(struct omap_hdmi *hdmi,
+ struct edid *(*read)(struct omap_hdmi *hdmi,
+  struct drm_connector *connector),
+ struct drm_connector *connector)
 {
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
struct edid *edid = NULL;
unsigned int cec_addr;
bool need_enable;
@@ -461,7 +465,7 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
if (r)
goto done;
 
-   edid = hdmi_read_edid_data(hdmi);
+   edid = read(hdmi, connector);
 
 done:
hdmi_runtime_put(hdmi);
@@ -483,6 +487,12 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
return edid;
 }
 
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+{
+   return hdmi_do_read_edid(dssdev_to_hdmi(dssdev), hdmi_read_edid_data,
+NULL);
+}
+
 static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
@@ -526,6 +536,55 @@ static const struct omap_dss_device_ops hdmi_ops = {
},
 };
 
+/* 
-
+ * DRM Bridge Operations
+ */
+
+static int hdmi4_bridge_attach(struct drm_bridge *bridge, bool 
create_connector)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+
+   if (!hdmi->output.next_bridge)
+   return 0;
+
+   return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge,
+bridge, false);
+}
+
+static struct edid *hdmi4_bridge_read_edid(struct omap_hdmi *hdmi,
+  struct drm_connector *connector)
+{
+   return drm_do_get_edid(connector, hdmi4_core_ddc_read, &hdmi->core);
+}
+
+static struct edid *hdmi4_bridge_get_edid(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+
+   return hdmi_do_read_edid(hdmi, hdmi4_bridge_read_edid, connector);
+}
+
+static const struct drm_bridge_funcs hdmi4_bridge_funcs = {
+   .attach = hdmi4_bridge_attach,
+   .get_edid = hdmi4_bridge_get_edid,
+};
+
+static void hdmi4_bridge_init(struct omap_hdmi *hdmi)
+{
+   hdmi->bridge.funcs = &hdmi4_bridge_funcs;
+   hdmi->bridge.of_node = hdmi->pdev->dev.of_node;
+   hdmi->bridge.ops = DRM_BRIDGE_OP_EDID;
+   hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+
+   drm_bridge_add(&hdmi->bridge);
+}
+
+static void hdmi4_bridge_cleanup(struct omap_hdmi *hdmi)
+{
+   drm_bridge_remove(&hdmi->bridge);
+}
+
 /* 
-

[PATCH 37/60] drm/omap: hdmi5: Register a drm_bridge for EDID read

2019-07-07 Thread Laurent Pinchart
In order to integrate with a chain of drm_bridge, the internal HDMI5
encoder has to expose the EDID read operation through the drm_bridge
API. Register a bridge at initialisation time to do so.

For the time being make the next bridge in the chain optional as the
HDMI output is still based on omap_dss_device. The create_connector
argument to the bridge attach function is also ignored for the same
reason. This will be changed later when removing the related
omapdrm-specific display drivers.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 74 +++--
 1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 2dfcacdc072e..dd67a604453f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -397,8 +397,10 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid_data(struct hdmi_core_data *core)
+static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi,
+   struct drm_connector *connector)
 {
+   struct hdmi_core_data *core = &hdmi->core;
int max_ext_blocks = 3;
int r, n, i;
u8 *edid;
@@ -430,9 +432,12 @@ static struct edid *hdmi_read_edid_data(struct 
hdmi_core_data *core)
return NULL;
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+static struct edid *
+hdmi_do_read_edid(struct omap_hdmi *hdmi,
+ struct edid *(*read)(struct omap_hdmi *hdmi,
+  struct drm_connector *connector),
+ struct drm_connector *connector)
 {
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
struct edid *edid;
bool need_enable;
int idlemode;
@@ -456,7 +461,7 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
 
hdmi5_core_ddc_init(&hdmi->core);
 
-   edid = hdmi_read_edid_data(&hdmi->core);
+   edid = read(hdmi, connector);
 
hdmi5_core_ddc_uninit(&hdmi->core);
 
@@ -471,6 +476,12 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
return (struct edid *)edid;
 }
 
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+{
+   return hdmi_do_read_edid(dssdev_to_hdmi(dssdev), hdmi_read_edid_data,
+NULL);
+}
+
 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
const struct hdmi_avi_infoframe *avi)
 {
@@ -506,6 +517,55 @@ static const struct omap_dss_device_ops hdmi_ops = {
},
 };
 
+/* 
-
+ * DRM Bridge Operations
+ */
+
+static int hdmi5_bridge_attach(struct drm_bridge *bridge, bool 
create_connector)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+
+   if (!hdmi->output.next_bridge)
+   return 0;
+
+   return drm_bridge_attach(bridge->encoder, hdmi->output.next_bridge,
+bridge, false);
+}
+
+static struct edid *hdmi5_bridge_read_edid(struct omap_hdmi *hdmi,
+  struct drm_connector *connector)
+{
+   return drm_do_get_edid(connector, hdmi5_core_ddc_read, &hdmi->core);
+}
+
+static struct edid *hdmi5_bridge_get_edid(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+   struct omap_hdmi *hdmi = drm_bridge_to_hdmi(bridge);
+
+   return hdmi_do_read_edid(hdmi, hdmi5_bridge_read_edid, connector);
+}
+
+static const struct drm_bridge_funcs hdmi5_bridge_funcs = {
+   .attach = hdmi5_bridge_attach,
+   .get_edid = hdmi5_bridge_get_edid,
+};
+
+static void hdmi5_bridge_init(struct omap_hdmi *hdmi)
+{
+   hdmi->bridge.funcs = &hdmi5_bridge_funcs;
+   hdmi->bridge.of_node = hdmi->pdev->dev.of_node;
+   hdmi->bridge.ops = DRM_BRIDGE_OP_EDID;
+   hdmi->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+
+   drm_bridge_add(&hdmi->bridge);
+}
+
+static void hdmi5_bridge_cleanup(struct omap_hdmi *hdmi)
+{
+   drm_bridge_remove(&hdmi->bridge);
+}
+
 /* 
-
  * Audio Callbacks
  */
@@ -688,6 +748,8 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
struct omap_dss_device *out = &hdmi->output;
int r;
 
+   hdmi5_bridge_init(hdmi);
+
out->dev = &hdmi->pdev->dev;
out->id = OMAP_DSS_OUTPUT_HDMI;
out->type = OMAP_DISPLAY_TYPE_HDMI;
@@ -698,7 +760,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 
-   r = omapdss_device_init_output(out, NULL);
+   r = omapdss_device_init_output(out, &hdmi->bridge);
if (r < 0)
return r;
 
@@ -713,6 +775,8 @@ st

[PATCH 35/60] drm/omap: hdmi5: Rework EDID read to isolate data read

2019-07-07 Thread Laurent Pinchart
In preparation of adding DRM bridge support to the hdmi5 encoder code,
rework the EDID read to isolate data read.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  | 89 ++--
 drivers/gpu/drm/omapdrm/dss/hdmi5_core.c | 48 +++--
 drivers/gpu/drm/omapdrm/dss/hdmi5_core.h |  5 +-
 3 files changed, 65 insertions(+), 77 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 60d146ac8fd0..2dfcacdc072e 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -282,30 +282,6 @@ static int hdmi_dump_regs(struct seq_file *s, void *p)
return 0;
 }
 
-static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
-{
-   int r;
-   int idlemode;
-
-   mutex_lock(&hdmi->lock);
-
-   r = hdmi_runtime_get(hdmi);
-   BUG_ON(r);
-
-   idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
-   /* No-idle mode */
-   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
-
-   r = hdmi5_read_edid(&hdmi->core,  buf, len);
-
-   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
-
-   hdmi_runtime_put(hdmi);
-   mutex_unlock(&hdmi->lock);
-
-   return r;
-}
-
 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
 {
REG_FLD_MOD(hd->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
@@ -421,32 +397,73 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+static struct edid *hdmi_read_edid_data(struct hdmi_core_data *core)
 {
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   bool need_enable;
+   int max_ext_blocks = 3;
+   int r, n, i;
u8 *edid;
-   int r;
 
edid = kzalloc(512, GFP_KERNEL);
if (!edid)
return NULL;
 
+   r = hdmi5_core_ddc_read(core, edid, 0, EDID_LENGTH);
+   if (r)
+   goto error;
+
+   n = edid[0x7e];
+
+   if (n > max_ext_blocks)
+   n = max_ext_blocks;
+
+   for (i = 1; i <= n; i++) {
+   r = hdmi5_core_ddc_read(core, edid + i * EDID_LENGTH, i,
+   EDID_LENGTH);
+   if (r)
+   goto error;
+   }
+
+   return (struct edid *)edid;
+
+error:
+   kfree(edid);
+   return NULL;
+}
+
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+{
+   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
+   struct edid *edid;
+   bool need_enable;
+   int idlemode;
+   int r;
+
need_enable = hdmi->core_enabled == false;
 
if (need_enable) {
r = hdmi_core_enable(hdmi);
-   if (r) {
-   kfree(edid);
+   if (r)
return NULL;
-   }
}
 
-   r = read_edid(hdmi, edid, 512);
-   if (r < 0) {
-   kfree(edid);
-   edid = NULL;
-   }
+   mutex_lock(&hdmi->lock);
+   r = hdmi_runtime_get(hdmi);
+   BUG_ON(r);
+
+   idlemode = REG_GET(hdmi->wp.base, HDMI_WP_SYSCONFIG, 3, 2);
+   /* No-idle mode */
+   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
+
+   hdmi5_core_ddc_init(&hdmi->core);
+
+   edid = hdmi_read_edid_data(&hdmi->core);
+
+   hdmi5_core_ddc_uninit(&hdmi->core);
+
+   REG_FLD_MOD(hdmi->wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
+
+   hdmi_runtime_put(hdmi);
+   mutex_unlock(&hdmi->lock);
 
if (need_enable)
hdmi_core_disable(hdmi);
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
index 02efabc7ed76..00782654ac86 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5_core.c
@@ -46,7 +46,7 @@ static const struct csc_table csc_table_deepcolor[] = {
[3] = { 8192, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 8192, 0, },
 };
 
-static void hdmi_core_ddc_init(struct hdmi_core_data *core)
+void hdmi5_core_ddc_init(struct hdmi_core_data *core)
 {
void __iomem *base = core->base;
const unsigned long long iclk = 26600;  /* DSS L3 ICLK */
@@ -125,7 +125,7 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x0, 2, 2);
 }
 
-static void hdmi_core_ddc_uninit(struct hdmi_core_data *core)
+void hdmi5_core_ddc_uninit(struct hdmi_core_data *core)
 {
void __iomem *base = core->base;
 
@@ -135,14 +135,14 @@ static void hdmi_core_ddc_uninit(struct hdmi_core_data 
*core)
REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2);
 }
 
-static int hdmi_core_ddc_edid(struct hdmi_core_data *core, u8 *pedid, u8 ext)
+int hdmi5_core_ddc_read(void *data, u8 *buf, unsigned int block, size_t len)
 {
+   struct hdmi_core_data *core = data;
void __iomem *base = core->

[PATCH 34/60] drm/omap: hdmi4: Rework EDID read to isolate data read

2019-07-07 Thread Laurent Pinchart
In preparation of adding DRM bridge support to the hdmi4 encoder code,
rework the EDID read to isolate data read.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  | 94 +++-
 drivers/gpu/drm/omapdrm/dss/hdmi4_core.c | 59 +++
 drivers/gpu/drm/omapdrm/dss/hdmi4_core.h |  4 +-
 3 files changed, 73 insertions(+), 84 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index f0586108b41e..5d7b17b52dc0 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -283,23 +283,6 @@ static int hdmi_dump_regs(struct seq_file *s, void *p)
return 0;
 }
 
-static int read_edid(struct omap_hdmi *hdmi, u8 *buf, int len)
-{
-   int r;
-
-   mutex_lock(&hdmi->lock);
-
-   r = hdmi_runtime_get(hdmi);
-   BUG_ON(r);
-
-   r = hdmi4_read_edid(&hdmi->core,  buf, len);
-
-   hdmi_runtime_put(hdmi);
-   mutex_unlock(&hdmi->lock);
-
-   return r;
-}
-
 static void hdmi_start_audio_stream(struct omap_hdmi *hd)
 {
hdmi_wp_audio_enable(&hd->wp, true);
@@ -416,10 +399,8 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+static struct edid *hdmi_read_edid_data(struct omap_hdmi *hdmi)
 {
-   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
-   bool need_enable;
u8 *edid;
int r;
 
@@ -427,32 +408,79 @@ static struct edid *hdmi_read_edid(struct omap_dss_device 
*dssdev)
if (!edid)
return NULL;
 
+   r = hdmi4_core_ddc_read(&hdmi->core, edid, 0, EDID_LENGTH);
+   if (r)
+   goto error;
+
+   if (edid[0x7e] > 0) {
+   char checksum = 0;
+   unsigned int i;
+
+   r = hdmi4_core_ddc_read(&hdmi->core, edid + EDID_LENGTH, 1,
+   EDID_LENGTH);
+   if (r)
+   goto error;
+
+   for (i = 0; i < EDID_LENGTH; ++i)
+   checksum += edid[EDID_LENGTH + i];
+
+   if (checksum != 0) {
+   DSSERR("E-EDID checksum failed!!\n");
+   goto error;
+   }
+   }
+
+   return (struct edid *)edid;
+
+error:
+   kfree(edid);
+   return NULL;
+}
+
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
+{
+   struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
+   struct edid *edid = NULL;
+   unsigned int cec_addr;
+   bool need_enable;
+   int r;
+
need_enable = hdmi->core_enabled == false;
 
if (need_enable) {
r = hdmi4_core_enable(&hdmi->core);
-   if (r) {
-   kfree(edid);
+   if (r)
return NULL;
-   }
}
 
-   r = read_edid(hdmi, edid, 512);
-   if (r < 0) {
-   kfree(edid);
-   edid = NULL;
+   mutex_lock(&hdmi->lock);
+   r = hdmi_runtime_get(hdmi);
+   BUG_ON(r);
+
+   r = hdmi4_core_ddc_init(&hdmi->core);
+   if (r)
+   goto done;
+
+   edid = hdmi_read_edid_data(hdmi);
+
+done:
+   hdmi_runtime_put(hdmi);
+   mutex_unlock(&hdmi->lock);
+
+   if (edid && edid->extensions) {
+   unsigned int len = (edid->extensions + 1) * EDID_LENGTH;
+
+   cec_addr = cec_get_edid_phys_addr((u8 *)edid, len, NULL);
} else {
-   unsigned int cec_addr;
-
-   cec_addr = r >= 256 ? cec_get_edid_phys_addr(edid, r, NULL)
-: CEC_PHYS_ADDR_INVALID;
-   hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
+   cec_addr = CEC_PHYS_ADDR_INVALID;
}
 
+   hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
+
if (need_enable)
hdmi4_core_disable(&hdmi->core);
 
-   return (struct edid *)edid;
+   return edid;
 }
 
 static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
index e384b95ad857..b51697b25c70 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4_core.c
@@ -43,7 +43,7 @@ static inline void __iomem *hdmi_av_base(struct 
hdmi_core_data *core)
return core->base + HDMI_CORE_AV;
 }
 
-static int hdmi_core_ddc_init(struct hdmi_core_data *core)
+int hdmi4_core_ddc_init(struct hdmi_core_data *core)
 {
void __iomem *base = core->base;
 
@@ -85,13 +85,11 @@ static int hdmi_core_ddc_init(struct hdmi_core_data *core)
return 0;
 }
 
-static int hdmi_core_ddc_edid(struct hdmi_core_data *core,
-   u8 *pedid, int ext)
+int hdmi4_core_ddc_read(void *data, u8 *buf, unsigned int block, size_t len)
 {
+   struct hdmi_core_data *core = data;
void __iomem

[PATCH 33/60] drm/omap: hdmi: Allocate EDID in the .read_edid() operation

2019-07-07 Thread Laurent Pinchart
Bring the omapdss-specific .read_edid() operation in sync with the
drm_bridge .get_edid() operation to ease code reuse.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/hdmi4.c  | 34 
 drivers/gpu/drm/omapdrm/dss/hdmi5.c  | 22 ++-
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  2 +-
 drivers/gpu/drm/omapdrm/omap_connector.c | 12 +++--
 4 files changed, 43 insertions(+), 27 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index 0a0bda7f686f..f0586108b41e 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -416,31 +416,43 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
-   u8 *edid, int len)
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable;
+   u8 *edid;
int r;
 
+   edid = kzalloc(512, GFP_KERNEL);
+   if (!edid)
+   return NULL;
+
need_enable = hdmi->core_enabled == false;
 
if (need_enable) {
r = hdmi4_core_enable(&hdmi->core);
-   if (r)
-   return r;
+   if (r) {
+   kfree(edid);
+   return NULL;
+   }
+   }
+
+   r = read_edid(hdmi, edid, 512);
+   if (r < 0) {
+   kfree(edid);
+   edid = NULL;
+   } else {
+   unsigned int cec_addr;
+
+   cec_addr = r >= 256 ? cec_get_edid_phys_addr(edid, r, NULL)
+: CEC_PHYS_ADDR_INVALID;
+   hdmi4_cec_set_phys_addr(&hdmi->core, cec_addr);
}
 
-   r = read_edid(hdmi, edid, len);
-   if (r >= 256)
-   hdmi4_cec_set_phys_addr(&hdmi->core,
-   cec_get_edid_phys_addr(edid, r, NULL));
-   else
-   hdmi4_cec_set_phys_addr(&hdmi->core, CEC_PHYS_ADDR_INVALID);
if (need_enable)
hdmi4_core_disable(&hdmi->core);
 
-   return r;
+   return (struct edid *)edid;
 }
 
 static void hdmi_lost_hotplug(struct omap_dss_device *dssdev)
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 07e6d8347689..60d146ac8fd0 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -421,27 +421,37 @@ static void hdmi_disconnect(struct omap_dss_device *src,
omapdss_device_disconnect(dst, dst->next);
 }
 
-static int hdmi_read_edid(struct omap_dss_device *dssdev,
-   u8 *edid, int len)
+static struct edid *hdmi_read_edid(struct omap_dss_device *dssdev)
 {
struct omap_hdmi *hdmi = dssdev_to_hdmi(dssdev);
bool need_enable;
+   u8 *edid;
int r;
 
+   edid = kzalloc(512, GFP_KERNEL);
+   if (!edid)
+   return NULL;
+
need_enable = hdmi->core_enabled == false;
 
if (need_enable) {
r = hdmi_core_enable(hdmi);
-   if (r)
-   return r;
+   if (r) {
+   kfree(edid);
+   return NULL;
+   }
}
 
-   r = read_edid(hdmi, edid, len);
+   r = read_edid(hdmi, edid, 512);
+   if (r < 0) {
+   kfree(edid);
+   edid = NULL;
+   }
 
if (need_enable)
hdmi_core_disable(hdmi);
 
-   return r;
+   return (struct edid *)edid;
 }
 
 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 8cc08a3290de..ccdf42617613 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -378,7 +378,7 @@ struct omap_dss_device_ops {
void *cb_data);
void (*unregister_hpd_cb)(struct omap_dss_device *dssdev);
 
-   int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
+   struct edid *(*read_edid)(struct omap_dss_device *dssdev);
 
int (*get_modes)(struct omap_dss_device *dssdev,
 struct drm_connector *connector);
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 3f913c8cf344..f8b2e63d9e74 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -164,25 +164,19 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
kfree(omap_connector);
 }
 
-#define MAX_EDID  512
-
 static int omap_connector_get_modes_edid(struct drm_connector *connector,
 struct omap_dss_device *dssdev)
 {
enum drm_connector_status status;
-   void *edid;
+   s

[PATCH 31/60] drm/omap: Add infrastructure to support drm_bridge local to DSS outputs

2019-07-07 Thread Laurent Pinchart
In order to support drm_bridge-based pipeline, the internal HDMI
encoders will need to expose the EDID read operation through the
drm_bridge API, and thus to expose a drm_bridge instance corresponding
to the encoder. The HDMI encoders are however handled as omap_dss_device
instances, which conflicts with this requirement.

In order to move forward with the drm_bridge transition, add support for
creating drm_bridge instances local to DSS outputs. If a local bridge is
passed to the omapdss_device_init_output() function, it is used as the
first bridge in the chain, and the omap_dss_device.next_bridge field is
set to the next bridge for the use of the internal encoders' bridges.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/dpi.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c   |  2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c   |  2 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h |  4 +++-
 drivers/gpu/drm/omapdrm/dss/output.c  | 20 
 drivers/gpu/drm/omapdrm/dss/sdi.c |  2 +-
 drivers/gpu/drm/omapdrm/dss/venc.c|  2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c|  2 +-
 9 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dpi.c 
b/drivers/gpu/drm/omapdrm/dss/dpi.c
index c28b84fb11f0..e1f94a84c9bd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dpi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dpi.c
@@ -640,7 +640,7 @@ static int dpi_init_output_port(struct dpi_data *dpi, 
struct device_node *port)
out->ops = &dpi_ops;
out->owner = THIS_MODULE;
 
-   r = omapdss_device_init_output(out);
+   r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
index c5904935a519..2b024666a2fd 100644
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -5133,7 +5133,7 @@ static int dsi_init_output(struct dsi_data *dsi)
   | DRM_BUS_FLAG_DE_HIGH
   | DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
 
-   r = omapdss_device_init_output(out);
+   r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi4.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
index b429677b47cd..0a0bda7f686f 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi4.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi4.c
@@ -687,7 +687,7 @@ static int hdmi4_init_output(struct omap_hdmi *hdmi)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 
-   r = omapdss_device_init_output(out);
+   r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/hdmi5.c 
b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
index 9235273a0ff3..07e6d8347689 100644
--- a/drivers/gpu/drm/omapdrm/dss/hdmi5.c
+++ b/drivers/gpu/drm/omapdrm/dss/hdmi5.c
@@ -671,7 +671,7 @@ static int hdmi5_init_output(struct omap_hdmi *hdmi)
out->of_port = 0;
out->ops_flags = OMAP_DSS_DEVICE_OP_EDID;
 
-   r = omapdss_device_init_output(out);
+   r = omapdss_device_init_output(out, NULL);
if (r < 0)
return r;
 
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 5bf6e0da6cd5..8cc08a3290de 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -411,6 +411,7 @@ struct omap_dss_device {
struct dss_device *dss;
struct omap_dss_device *next;
struct drm_bridge *bridge;
+   struct drm_bridge *next_bridge;
struct drm_panel *panel;
 
struct list_head list;
@@ -499,7 +500,8 @@ int omap_dss_get_num_overlays(void);
 #define for_each_dss_output(d) \
while ((d = omapdss_device_next_output(d)) != NULL)
 struct omap_dss_device *omapdss_device_next_output(struct omap_dss_device 
*from);
-int omapdss_device_init_output(struct omap_dss_device *out);
+int omapdss_device_init_output(struct omap_dss_device *out,
+  struct drm_bridge *local_bridge);
 void omapdss_device_cleanup_output(struct omap_dss_device *out);
 
 typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c 
b/drivers/gpu/drm/omapdrm/dss/output.c
index 70ccb10c11e9..71693d1abea8 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -27,7 +27,8 @@
 #include "dss.h"
 #include "omapdss.h"
 
-int omapdss_device_init_output(struct omap_dss_device *out)
+int omapdss_device_init_output(struct omap_dss_device *out,
+  struct drm_bridge *local_bridge)
 {
struct device_node *remote_node;
int ret;
@@ -70,10 +71,20 @@ int omapdss_device_init_output(struct omap_dss_device *out)
out->bridge = bridge;
}
 
-   return out->next || out->bridge ? 0 : -EPROBE_D

[PATCH 32/60] drm/omap: dss: Make omap_dss_device_ops optional

2019-07-07 Thread Laurent Pinchart
As part of the move to drm_bridge ops for some of the internal encoders
will be removed. Make them optional in the driver to ease the
transition.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c   | 21 -
 drivers/gpu/drm/omapdrm/dss/dss.c|  3 ++-
 drivers/gpu/drm/omapdrm/omap_connector.c |  2 +-
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 12 +++-
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index 80d48936d177..2db3bd2f19db 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -195,10 +195,12 @@ int omapdss_device_connect(struct dss_device *dss,
 
dst->dss = dss;
 
-   ret = dst->ops->connect(src, dst);
-   if (ret < 0) {
-   dst->dss = NULL;
-   return ret;
+   if (dst->ops && dst->ops->connect) {
+   ret = dst->ops->connect(src, dst);
+   if (ret < 0) {
+   dst->dss = NULL;
+   return ret;
+   }
}
 
return 0;
@@ -226,7 +228,8 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
 
WARN_ON(dst->state != OMAP_DSS_DISPLAY_DISABLED);
 
-   dst->ops->disconnect(src, dst);
+   if (dst->ops && dst->ops->disconnect)
+   dst->ops->disconnect(src, dst);
dst->dss = NULL;
 }
 EXPORT_SYMBOL_GPL(omapdss_device_disconnect);
@@ -238,7 +241,7 @@ void omapdss_device_pre_enable(struct omap_dss_device 
*dssdev)
 
omapdss_device_pre_enable(dssdev->next);
 
-   if (dssdev->ops->pre_enable)
+   if (dssdev->ops && dssdev->ops->pre_enable)
dssdev->ops->pre_enable(dssdev);
 }
 EXPORT_SYMBOL_GPL(omapdss_device_pre_enable);
@@ -248,7 +251,7 @@ void omapdss_device_enable(struct omap_dss_device *dssdev)
if (!dssdev)
return;
 
-   if (dssdev->ops->enable)
+   if (dssdev->ops && dssdev->ops->enable)
dssdev->ops->enable(dssdev);
 
omapdss_device_enable(dssdev->next);
@@ -264,7 +267,7 @@ void omapdss_device_disable(struct omap_dss_device *dssdev)
 
omapdss_device_disable(dssdev->next);
 
-   if (dssdev->ops->disable)
+   if (dssdev->ops && dssdev->ops->disable)
dssdev->ops->disable(dssdev);
 }
 EXPORT_SYMBOL_GPL(omapdss_device_disable);
@@ -274,7 +277,7 @@ void omapdss_device_post_disable(struct omap_dss_device 
*dssdev)
if (!dssdev)
return;
 
-   if (dssdev->ops->post_disable)
+   if (dssdev->ops && dssdev->ops->post_disable)
dssdev->ops->post_disable(dssdev);
 
omapdss_device_post_disable(dssdev->next);
diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c 
b/drivers/gpu/drm/omapdrm/dss/dss.c
index 55e68863ef15..a5cf15b7e630 100644
--- a/drivers/gpu/drm/omapdrm/dss/dss.c
+++ b/drivers/gpu/drm/omapdrm/dss/dss.c
@@ -1561,7 +1561,8 @@ static void dss_shutdown(struct platform_device *pdev)
DSSDBG("shutdown\n");
 
for_each_dss_output(dssdev) {
-   if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+   if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE &&
+   dssdev->ops && dssdev->ops->disable)
dssdev->ops->disable(dssdev);
}
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 3d1f740037c8..3f913c8cf344 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -239,7 +239,7 @@ enum drm_mode_status omap_connector_mode_fixup(struct 
omap_dss_device *dssdev,
drm_mode_copy(adjusted_mode, mode);
 
for (; dssdev; dssdev = dssdev->next) {
-   if (!dssdev->ops->check_timings)
+   if (!dssdev->ops || !dssdev->ops->check_timings)
continue;
 
ret = dssdev->ops->check_timings(dssdev, adjusted_mode);
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 510888413068..fa4e00e65f9d 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -87,10 +87,10 @@ static void omap_encoder_hdmi_mode_set(struct drm_connector 
*connector,
struct omap_dss_device *dssdev = omap_encoder->output;
bool hdmi_mode = connector->display_info.is_hdmi;
 
-   if (dssdev->ops->hdmi.set_hdmi_mode)
+   if (dssdev->ops && dssdev->ops->hdmi.set_hdmi_mode)
dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
 
-   if (hdmi_mode && dssdev->ops->hdmi.set_infoframe) {
+   if (hdmi_mode && dssdev->ops && dssdev->ops->hdmi.set_infoframe) {
struct hdmi_avi_infoframe avi;
int r;
 
@@ -148,7 +148,7 @@ static void omap_encoder_mode_set(struct drm_encoder 
*encoder,
dss_mgr_set_timings(output, &vm);
 
for (dssdev = output; dss

[PATCH 30/60] drm/omap: dss: Fix output next device lookup in DT

2019-07-07 Thread Laurent Pinchart
The DSS core looks up the next device connected to an output by
traversing the OF graph. It currently hardcodes the local port number to
0, which breaks any output with a different port number (SDI on OMAP3
and any DPI output but the first one). Fix this by repurposing the
currently unused of_ports bitmask in omap_dss_device with an of_port
output port number, and use it to traverse the OF graph.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c  | 2 +-
 drivers/gpu/drm/omapdrm/displays/connector-hdmi.c   | 2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-opa362.c   | 2 +-
 drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c| 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-lgphilips-lb035q02.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-nec-nl8048hl11.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-sharp-ls037v7dw01.c  | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-sony-acx565akm.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 2 +-
 drivers/gpu/drm/omapdrm/displays/panel-tpo-td043mtea1.c | 2 +-
 drivers/gpu/drm/omapdrm/dss/dpi.c   | 2 +-
 drivers/gpu/drm/omapdrm/dss/dsi.c   | 2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi4.c | 2 +-
 drivers/gpu/drm/omapdrm/dss/hdmi5.c | 2 +-
 drivers/gpu/drm/omapdrm/dss/omapdss.h   | 4 ++--
 drivers/gpu/drm/omapdrm/dss/output.c| 3 ++-
 drivers/gpu/drm/omapdrm/dss/sdi.c   | 2 +-
 drivers/gpu/drm/omapdrm/dss/venc.c  | 2 +-
 19 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c 
b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
index 6c0561101874..2ab18744a5d7 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-analog-tv.c
@@ -58,7 +58,7 @@ static int tvc_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_VENC;
dssdev->display = true;
dssdev->owner = THIS_MODULE;
-   dssdev->of_ports = BIT(0);
+   dssdev->of_port = 0;
 
omapdss_display_init(dssdev);
omapdss_device_register(dssdev);
diff --git a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c 
b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
index 68d6f6e44b03..5d2dc103c6b1 100644
--- a/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
+++ b/drivers/gpu/drm/omapdrm/displays/connector-hdmi.c
@@ -142,7 +142,7 @@ static int hdmic_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->display = true;
dssdev->owner = THIS_MODULE;
-   dssdev->of_ports = BIT(0);
+   dssdev->of_port = 0;
dssdev->ops_flags = ddata->hpd_gpio
  ? OMAP_DSS_DEVICE_OP_DETECT | OMAP_DSS_DEVICE_OP_HPD
  : 0;
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
index 29a5a130ebd1..fa2ff7174259 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-opa362.c
@@ -89,7 +89,7 @@ static int opa362_probe(struct platform_device *pdev)
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_VENC;
dssdev->owner = THIS_MODULE;
-   dssdev->of_ports = BIT(1) | BIT(0);
+   dssdev->of_port = 1;
 
dssdev->next = omapdss_of_find_connected_device(pdev->dev.of_node, 1);
if (IS_ERR(dssdev->next)) {
diff --git a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c 
b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
index bc03752d2762..b0e62ed3fce4 100644
--- a/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
+++ b/drivers/gpu/drm/omapdrm/displays/encoder-tpd12s015.c
@@ -168,7 +168,7 @@ static int tpd_probe(struct platform_device *pdev)
dssdev->dev = &pdev->dev;
dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
dssdev->owner = THIS_MODULE;
-   dssdev->of_ports = BIT(1) | BIT(0);
+   dssdev->of_port = 1;
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_DETECT
  | OMAP_DSS_DEVICE_OP_HPD;
 
diff --git a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c 
b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
index 913e8291a917..5a618e536a32 100644
--- a/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
+++ b/drivers/gpu/drm/omapdrm/displays/panel-dsi-cm.c
@@ -1268,7 +1268,7 @@ static int dsicm_probe(struct platform_device *pdev)
dssdev->type = OMAP_DISPLAY_TYPE_DSI;
dssdev->display = true;
dssdev->owner = THIS_MODULE;
-   dssdev->of_ports = BIT(0);
+   dssdev->of_port = 0;
dssdev->ops_flags = OMAP_DSS_DEVICE_OP_MODES;
 
dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_

[PATCH 29/60] drm/omap: Use the drm_panel_bridge API

2019-07-07 Thread Laurent Pinchart
Replace the manual panel handling code by a drm_panel_bridge. This
simplifies the driver and allows all components in the display pipeline
to be treated as bridges, paving the way to generic connector handling.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c   | 12 -
 drivers/gpu/drm/omapdrm/dss/output.c | 33 +---
 drivers/gpu/drm/omapdrm/omap_connector.c |  9 ---
 drivers/gpu/drm/omapdrm/omap_drv.c   | 13 --
 drivers/gpu/drm/omapdrm/omap_encoder.c   | 13 --
 5 files changed, 34 insertions(+), 46 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index cae5687822e2..80d48936d177 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -149,8 +149,7 @@ struct omap_dss_device *omapdss_device_next_output(struct 
omap_dss_device *from)
goto done;
}
 
-   if (dssdev->id &&
-   (dssdev->next || dssdev->bridge || dssdev->panel))
+   if (dssdev->id && (dssdev->next || dssdev->bridge))
goto done;
}
 
@@ -185,11 +184,10 @@ int omapdss_device_connect(struct dss_device *dss,
if (!dst) {
/*
 * The destination is NULL when the source is connected to a
-* bridge or panel instead of a DSS device. Stop here, we will
-* attach the bridge or panel later when we will have a DRM
-* encoder.
+* bridge instead of a DSS device. Stop here, we will attach
+* the bridge later when we will have a DRM encoder.
 */
-   return src && (src->bridge || src->panel) ? 0 : -EINVAL;
+   return src && src->bridge ? 0 : -EINVAL;
}
 
if (omapdss_device_is_connected(dst))
@@ -217,7 +215,7 @@ void omapdss_device_disconnect(struct omap_dss_device *src,
dst ? dev_name(dst->dev) : "NULL");
 
if (!dst) {
-   WARN_ON(!src->bridge && !src->panel);
+   WARN_ON(!src->bridge);
return;
}
 
diff --git a/drivers/gpu/drm/omapdrm/dss/output.c 
b/drivers/gpu/drm/omapdrm/dss/output.c
index 10a9ee5cdc61..4f71a20bc7c7 100644
--- a/drivers/gpu/drm/omapdrm/dss/output.c
+++ b/drivers/gpu/drm/omapdrm/dss/output.c
@@ -30,6 +30,7 @@
 int omapdss_device_init_output(struct omap_dss_device *out)
 {
struct device_node *remote_node;
+   int ret;
 
remote_node = of_graph_get_remote_node(out->dev->of_node, 0, 0);
if (!remote_node) {
@@ -47,17 +48,41 @@ int omapdss_device_init_output(struct omap_dss_device *out)
 
if (out->next && out->type != out->next->type) {
dev_err(out->dev, "output type and display type don't match\n");
-   omapdss_device_put(out->next);
-   out->next = NULL;
-   return -EINVAL;
+   ret = -EINVAL;
+   goto error;
}
 
-   return out->next || out->bridge || out->panel ? 0 : -EPROBE_DEFER;
+   if (out->panel) {
+   unsigned int connector_type;
+   struct drm_bridge *bridge;
+
+   connector_type = omapdss_device_connector_type(out->type);
+   bridge = drm_panel_bridge_add(out->panel, connector_type);
+   if (IS_ERR(bridge)) {
+   dev_err(out->dev,
+   "unable to create panel bridge (%ld)\n",
+   PTR_ERR(bridge));
+   ret = PTR_ERR(bridge);
+   goto error;
+   }
+
+   out->bridge = bridge;
+   }
+
+   return out->next || out->bridge ? 0 : -EPROBE_DEFER;
+
+error:
+   omapdss_device_put(out->next);
+   out->next = NULL;
+   return ret;
 }
 EXPORT_SYMBOL(omapdss_device_init_output);
 
 void omapdss_device_cleanup_output(struct omap_dss_device *out)
 {
+   if (out->bridge && out->panel)
+   drm_panel_bridge_remove(out->bridge);
+
if (out->next)
omapdss_device_put(out->next);
 }
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 322158ef15f6..3d1f740037c8 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -17,7 +17,6 @@
 
 #include 
 #include 
-#include 
 #include 
 
 #include "omap_drv.h"
@@ -201,7 +200,6 @@ static int omap_connector_get_modes_edid(struct 
drm_connector *connector,
 
 static int omap_connector_get_modes(struct drm_connector *connector)
 {
-   struct omap_connector *omap_connector = to_omap_connector(connector);
struct omap_dss_device *dssdev;
 
DBG("%s", connector->name);
@@ -224,13 +222,6 @@ static int omap_connector_get_modes(struct drm_connector 
*connector)
if (dssdev)
return dssdev->ops->get_mode

[PATCH 28/60] drm/omap: Factor out display type to connector type conversion

2019-07-07 Thread Laurent Pinchart
Move the code that computes the DRM connector type for the
omapdss_device display type to a new omapdss_device_connector_type()
function for later reuse.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/dss/base.c   | 23 +++
 drivers/gpu/drm/omapdrm/dss/omapdss.h|  1 +
 drivers/gpu/drm/omapdrm/omap_connector.c | 19 +--
 3 files changed, 25 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/base.c 
b/drivers/gpu/drm/omapdrm/dss/base.c
index a1970b9db6ab..cae5687822e2 100644
--- a/drivers/gpu/drm/omapdrm/dss/base.c
+++ b/drivers/gpu/drm/omapdrm/dss/base.c
@@ -285,6 +285,29 @@ void omapdss_device_post_disable(struct omap_dss_device 
*dssdev)
 }
 EXPORT_SYMBOL_GPL(omapdss_device_post_disable);
 
+unsigned int omapdss_device_connector_type(enum omap_display_type type)
+{
+   switch (type) {
+   case OMAP_DISPLAY_TYPE_HDMI:
+   return DRM_MODE_CONNECTOR_HDMIA;
+   case OMAP_DISPLAY_TYPE_DVI:
+   return DRM_MODE_CONNECTOR_DVID;
+   case OMAP_DISPLAY_TYPE_DSI:
+   return DRM_MODE_CONNECTOR_DSI;
+   case OMAP_DISPLAY_TYPE_DPI:
+   case OMAP_DISPLAY_TYPE_DBI:
+   return DRM_MODE_CONNECTOR_DPI;
+   case OMAP_DISPLAY_TYPE_VENC:
+   /* TODO: This could also be composite */
+   return DRM_MODE_CONNECTOR_SVIDEO;
+   case OMAP_DISPLAY_TYPE_SDI:
+   return DRM_MODE_CONNECTOR_LVDS;
+   default:
+   return DRM_MODE_CONNECTOR_Unknown;
+   }
+}
+EXPORT_SYMBOL_GPL(omapdss_device_connector_type);
+
 /* 
-
  * Components Handling
  */
diff --git a/drivers/gpu/drm/omapdrm/dss/omapdss.h 
b/drivers/gpu/drm/omapdrm/dss/omapdss.h
index 0c734d1f89e1..0063477b670f 100644
--- a/drivers/gpu/drm/omapdrm/dss/omapdss.h
+++ b/drivers/gpu/drm/omapdrm/dss/omapdss.h
@@ -490,6 +490,7 @@ void omapdss_device_pre_enable(struct omap_dss_device 
*dssdev);
 void omapdss_device_enable(struct omap_dss_device *dssdev);
 void omapdss_device_disable(struct omap_dss_device *dssdev);
 void omapdss_device_post_disable(struct omap_dss_device *dssdev);
+unsigned int omapdss_device_connector_type(enum omap_display_type type);
 
 int omap_dss_get_num_overlay_managers(void);
 
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index a59cca2883b1..322158ef15f6 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -306,24 +306,7 @@ static int omap_connector_get_type(struct omap_dss_device 
*output)
type = display->type;
omapdss_device_put(display);
 
-   switch (type) {
-   case OMAP_DISPLAY_TYPE_HDMI:
-   return DRM_MODE_CONNECTOR_HDMIA;
-   case OMAP_DISPLAY_TYPE_DVI:
-   return DRM_MODE_CONNECTOR_DVID;
-   case OMAP_DISPLAY_TYPE_DSI:
-   return DRM_MODE_CONNECTOR_DSI;
-   case OMAP_DISPLAY_TYPE_DPI:
-   case OMAP_DISPLAY_TYPE_DBI:
-   return DRM_MODE_CONNECTOR_DPI;
-   case OMAP_DISPLAY_TYPE_VENC:
-   /* TODO: This could also be composite */
-   return DRM_MODE_CONNECTOR_SVIDEO;
-   case OMAP_DISPLAY_TYPE_SDI:
-   return DRM_MODE_CONNECTOR_LVDS;
-   default:
-   return DRM_MODE_CONNECTOR_Unknown;
-   }
+   return omapdss_device_connector_type(type);
 }
 
 /* initialize connector */
-- 
Regards,

Laurent Pinchart

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

[PATCH 27/60] drm/omap: Simplify HDMI mode and infoframe configuration

2019-07-07 Thread Laurent Pinchart
Remove the omap_connector_get_hdmi_mode() function as the HDMI mode can
be accessed directly from the connector's display info.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/omap_connector.c | 11 ---
 drivers/gpu/drm/omapdrm/omap_connector.h |  1 -
 drivers/gpu/drm/omapdrm/omap_encoder.c   |  4 +---
 3 files changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c 
b/drivers/gpu/drm/omapdrm/omap_connector.c
index 5967283934e1..a59cca2883b1 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -32,7 +32,6 @@ struct omap_connector {
struct drm_connector base;
struct omap_dss_device *output;
struct omap_dss_device *hpd;
-   bool hdmi_mode;
 };
 
 static void omap_connector_hpd_notify(struct drm_connector *connector,
@@ -95,13 +94,6 @@ void omap_connector_disable_hpd(struct drm_connector 
*connector)
hpd->ops->unregister_hpd_cb(hpd);
 }
 
-bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
-{
-   struct omap_connector *omap_connector = to_omap_connector(connector);
-
-   return omap_connector->hdmi_mode;
-}
-
 static struct omap_dss_device *
 omap_connector_find_device(struct drm_connector *connector,
   enum omap_dss_device_ops_flag op)
@@ -178,7 +170,6 @@ static void omap_connector_destroy(struct drm_connector 
*connector)
 static int omap_connector_get_modes_edid(struct drm_connector *connector,
 struct omap_dss_device *dssdev)
 {
-   struct omap_connector *omap_connector = to_omap_connector(connector);
enum drm_connector_status status;
void *edid;
int n;
@@ -200,8 +191,6 @@ static int omap_connector_get_modes_edid(struct 
drm_connector *connector,
drm_connector_update_edid_property(connector, edid);
n = drm_add_edid_modes(connector, edid);
 
-   omap_connector->hdmi_mode = drm_detect_hdmi_monitor(edid);
-
kfree(edid);
return n;
 
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.h 
b/drivers/gpu/drm/omapdrm/omap_connector.h
index 608085219336..a23b3a80657b 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.h
+++ b/drivers/gpu/drm/omapdrm/omap_connector.h
@@ -32,7 +32,6 @@ struct omap_dss_device;
 struct drm_connector *omap_connector_init(struct drm_device *dev,
  struct omap_dss_device *output,
  struct drm_encoder *encoder);
-bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
 void omap_connector_enable_hpd(struct drm_connector *connector);
 void omap_connector_disable_hpd(struct drm_connector *connector);
 enum drm_mode_status omap_connector_mode_fixup(struct omap_dss_device *dssdev,
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c 
b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 40512419642b..8cae2af1438f 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -86,9 +86,7 @@ static void omap_encoder_hdmi_mode_set(struct drm_connector 
*connector,
 {
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
struct omap_dss_device *dssdev = omap_encoder->output;
-   bool hdmi_mode;
-
-   hdmi_mode = omap_connector_get_hdmi_mode(connector);
+   bool hdmi_mode = connector->display_info.is_hdmi;
 
if (dssdev->ops->hdmi.set_hdmi_mode)
dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode);
-- 
Regards,

Laurent Pinchart

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

[PATCH 26/60] drm/omap: Detach from panels at remove time

2019-07-07 Thread Laurent Pinchart
The omapdrm driver attaches to panels with drm_panel_attach() at probe
time but never calls drm_panel_detach(). Fix it.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/omapdrm/omap_drv.c | 24 +++-
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c 
b/drivers/gpu/drm/omapdrm/omap_drv.c
index 837d0cd20dd1..97512d4cf664 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -387,6 +387,23 @@ static int omap_modeset_init(struct drm_device *dev)
return 0;
 }
 
+static void omap_modeset_fini(struct drm_device *ddev)
+{
+   struct omap_drm_private *priv = ddev->dev_private;
+   unsigned int i;
+
+   omap_drm_irq_uninstall(ddev);
+
+   for (i = 0; i < priv->num_pipes; i++) {
+   struct omap_drm_pipeline *pipe = &priv->pipes[i];
+
+   if (pipe->output->panel)
+   drm_panel_detach(pipe->output->panel);
+   }
+
+   drm_mode_config_cleanup(ddev);
+}
+
 /*
  * Enable the HPD in external components if supported
  */
@@ -634,8 +651,7 @@ static int omapdrm_init(struct omap_drm_private *priv, 
struct device *dev)
 
omap_fbdev_fini(ddev);
 err_cleanup_modeset:
-   drm_mode_config_cleanup(ddev);
-   omap_drm_irq_uninstall(ddev);
+   omap_modeset_fini(ddev);
 err_gem_deinit:
omap_gem_deinit(ddev);
destroy_workqueue(priv->wq);
@@ -660,9 +676,7 @@ static void omapdrm_cleanup(struct omap_drm_private *priv)
 
drm_atomic_helper_shutdown(ddev);
 
-   drm_mode_config_cleanup(ddev);
-
-   omap_drm_irq_uninstall(ddev);
+   omap_modeset_fini(ddev);
omap_gem_deinit(ddev);
 
destroy_workqueue(priv->wq);
-- 
Regards,

Laurent Pinchart

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

[PATCH 24/60] drm/panel: Add driver for the Toppology TD043MTEA1 panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the OMAP3 Pandora.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig|   7 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-tpo-td043mtea1.c | 510 +++
 3 files changed, 518 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-tpo-td043mtea1.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index b7099d211061..8f3660c73044 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -312,6 +312,13 @@ config DRM_PANEL_TPO_TD028TTEC1
  Say Y here if you want to enable support for TPO TD028TTEC1 480x640
  2.8" panel.
 
+config DRM_PANEL_TPO_TD043MTEA1
+   tristate "TPO TD043MTEA1 panel driver"
+   depends on GPIOLIB && OF && REGULATOR && SPI
+   help
+ Say Y here if you want to enable support for TPO TD043MTEA1 800x480
+ 4.3" panel.
+
 config DRM_PANEL_TPO_TPG110
tristate "TPO TPG 800x400 panel"
depends on OF && SPI && GPIOLIB
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index a1d4de64c0b1..bf76fcea7d22 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -33,5 +33,6 @@ obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += 
panel-sitronix-st7701.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
 obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
+obj-$(CONFIG_DRM_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o
 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
diff --git a/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c 
b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
new file mode 100644
index ..6b17e47582b8
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-tpo-td043mtea1.c
@@ -0,0 +1,510 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Toppology TD043MTEA1 Panel Driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-tpo-td043mtea1 driver
+ *
+ * Author: Gražvydas Ignotas 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define TPO_R02_MODE(x)((x) & 7)
+#define TPO_R02_MODE_800x480   7
+#define TPO_R02_NCLK_RISINGBIT(3)
+#define TPO_R02_HSYNC_HIGH BIT(4)
+#define TPO_R02_VSYNC_HIGH BIT(5)
+
+#define TPO_R03_NSTANDBY   BIT(0)
+#define TPO_R03_EN_CP_CLK  BIT(1)
+#define TPO_R03_EN_VGL_PUMPBIT(2)
+#define TPO_R03_EN_PWM BIT(3)
+#define TPO_R03_DRIVING_CAP_100BIT(4)
+#define TPO_R03_EN_PRE_CHARGE  BIT(6)
+#define TPO_R03_SOFTWARE_CTL   BIT(7)
+
+#define TPO_R04_NFLIP_HBIT(0)
+#define TPO_R04_NFLIP_VBIT(1)
+#define TPO_R04_CP_CLK_FREQ_1H BIT(2)
+#define TPO_R04_VGL_FREQ_1HBIT(4)
+
+#define TPO_R03_VAL_NORMAL \
+   (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | TPO_R03_EN_VGL_PUMP | \
+TPO_R03_EN_PWM | TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
+TPO_R03_SOFTWARE_CTL)
+
+#define TPO_R03_VAL_STANDBY \
+   (TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \
+TPO_R03_SOFTWARE_CTL)
+
+static const u16 td043mtea1_def_gamma[12] = {
+   105, 315, 381, 431, 490, 537, 579, 686, 780, 837, 880, 1023
+};
+
+struct td043mtea1_device {
+   struct drm_panel panel;
+
+   struct spi_device *spi;
+   struct regulator *vcc_reg;
+   struct gpio_desc *reset_gpio;
+
+   unsigned int mode;
+   u16 gamma[12];
+   bool vmirror;
+   bool powered_on;
+   bool spi_suspended;
+   bool power_on_resume;
+};
+
+#define to_td043mtea1_device(p) container_of(p, struct td043mtea1_device, 
panel)
+
+/* 
-
+ * Hardware Access
+ */
+
+static int td043mtea1_write(struct td043mtea1_device *lcd, u8 addr, u8 value)
+{
+   struct spi_message msg;
+   struct spi_transfer xfer;
+   u16 data;
+   int ret;
+
+   spi_message_init(&msg);
+
+   memset(&xfer, 0, sizeof(xfer));
+
+   data = ((u16)addr << 10) | (1 << 8) | value;
+   xfer.tx_buf = &data;
+   xfer.bits_per_word = 16;
+   xfer.len = 2;
+   spi_message_add_tail(&xfer, &msg);
+
+   ret = spi_sync(lcd->spi, &msg);
+   if (ret < 0)
+   dev_warn(&lcd->spi->dev, "failed to write to LCD reg (%d)\n",
+ret);
+
+   return ret;
+}
+
+static void td043mtea1_write_gamma(struct td043mtea1_device *lcd)
+{
+   const u16 *gamma = lcd->gamma;
+   unsigned int i;
+   u8 val;
+
+   /* gamma bits [9:8] */
+   for (val = i = 0; i < 4; i++)
+   val |= (gamma[i] & 0x300) >> ((i + 1) * 2);
+  

[PATCH 25/60] drm: Add helper to create a connector for a chain of bridges

2019-07-07 Thread Laurent Pinchart
Most bridge drivers create a DRM connector to model the connector at the
output of the bridge. This model is historical and has worked pretty
well so far, but causes several issues:

- It prevents supporting more complex display pipelines where DRM
connector operations are split over multiple components. For instance a
pipeline with a bridge connected to the DDC signals to read EDID data,
and another one connected to the HPD signal to detect connection and
disconnection, will not be possible to support through this model.

- It requires every bridge driver to implement similar connector
handling code, resulting in code duplication.

- It assumes that a bridge will either be wired to a connector or to
another bridge, but doesn't support bridges that can be used in both
positions very well (although there is some ad-hoc support for this in
the analogix_dp bridge driver).

In order to solve these issues, ownership of the connector needs to be
moved to the display controller driver.

To avoid code duplication in display controller drivers, add a new
helper to create and manage a DRM connector backed by a chain of
bridges. All connector operations are delegating to the appropriate
bridge in the chain.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/Makefile   |   3 +-
 drivers/gpu/drm/drm_bridge_connector.c | 385 +
 include/drm/drm_bridge_connector.h |  18 ++
 3 files changed, 405 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_bridge_connector.c
 create mode 100644 include/drm/drm_bridge_connector.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 9f0d2ee35794..1b74653c9db9 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -37,7 +37,8 @@ drm_vram_helper-y := drm_gem_vram_helper.o \
 drm_vram_mm_helper.o
 obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
 
-drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o 
drm_probe_helper.o \
+drm_kms_helper-y := drm_bridge_connector.o drm_crtc_helper.o drm_dp_helper.o \
+   drm_dsc.o drm_probe_helper.o \
drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drm_simple_kms_helper.o drm_modeset_helper.o \
diff --git a/drivers/gpu/drm/drm_bridge_connector.c 
b/drivers/gpu/drm/drm_bridge_connector.c
new file mode 100644
index ..09f2d6bfb561
--- /dev/null
+++ b/drivers/gpu/drm/drm_bridge_connector.c
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Laurent Pinchart 
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/**
+ * DOC: overview
+ *
+ * The DRM bridge connector helper object provides a DRM connector
+ * implementation that wraps a chain of &struct drm_bridge. The connector
+ * operations are fully implemented based on the operations of the bridges in
+ * the chain, and don't require any intervention from the display controller
+ * driver at runtime.
+ *
+ * To use the helper, display controller drivers create a bridge connector with
+ * a call to drm_bridge_connector_init(). This associates the newly created
+ * connector with the chain of bridges passed to the function and registers it
+ * with the DRM device. At that point the connector becomes fully usable, no
+ * further operation is needed.
+ *
+ * The DRM bridge connector operations are implemented based on the operations
+ * provided by the bridges in the chain. Each connector operation is delegated
+ * to the bridge closest to the connector (at the end of the chain) that
+ * provides the relevant functionality.
+ *
+ * To make use of this helper, all bridges in the chain shall report bridge
+ * operation flags (&drm_bridge->ops) and bridge output type
+ * (&drm_bridge->type), and none of them may create a DRM connector directly.
+ */
+
+/**
+ * struct drm_bridge_connector - A connector backed by a chain of bridges
+ */
+struct drm_bridge_connector {
+   /**
+* @base: The base DRM connector
+*/
+   struct drm_connector base;
+   /**
+* @bridge:
+*
+* The first bridge in the chain (connected to the output of the CRTC).
+*/
+   struct drm_bridge *bridge;
+   /**
+* @bridge_edid:
+*
+* The last bridge in the chain (closest to the connector) that provides
+* EDID read support, if any (see &DRM_BRIDGE_OP_EDID).
+*/
+   struct drm_bridge *bridge_edid;
+   /**
+* @bridge_hpd:
+*
+* The last bridge in the chain (closest to the connector) that provides
+* hot-plug detection notification, if any (see &DRM_BRIDGE_OP_HPD).
+*/
+   struct drm_bridge *bridge_hpd;
+   /**
+* @bridge_detect:
+*
+* The last bridge in the chain (closest to the connector) that

[PATCH 22/60] drm/panel: Add driver for the Sony ACX565AKM panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the Nokia N900.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig|   8 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-sony-acx565akm.c | 691 +++
 3 files changed, 700 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-sony-acx565akm.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 04fd152efe4c..dc10f727689a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -296,6 +296,14 @@ config DRM_PANEL_SITRONIX_ST7789V
  Say Y here if you want to enable support for the Sitronix
  ST7789V controller for 240x320 LCD panels
 
+config DRM_PANEL_SONY_ACX565AKM
+   tristate "Sony ACX565AKM panel"
+   depends on GPIOLIB && OF && SPI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for the Sony ACX565AKM
+ 800x600 3.5" panel.
+
 config DRM_PANEL_TPO_TPG110
tristate "TPO TPG 800x400 panel"
depends on OF && SPI && GPIOLIB
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 12dcd76eb87c..84cbc069f6cd 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -31,5 +31,6 @@ obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += 
panel-sharp-ls037v7dw01.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
+obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
diff --git a/drivers/gpu/drm/panel/panel-sony-acx565akm.c 
b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
new file mode 100644
index ..e7292648ac06
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-sony-acx565akm.c
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sony ACX565AKM LCD Panel driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-sony-acx565akm driver
+ *
+ * Copyright (C) 2010 Nokia Corporation
+ * Author: Imre Deak 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define CTRL_DISP_BRIGHTNESS_CTRL_ON   (1 << 5)
+#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON(1 << 4)
+#define CTRL_DISP_BACKLIGHT_ON (1 << 2)
+#define CTRL_DISP_AUTO_BRIGHTNESS_ON   (1 << 1)
+
+#define MIPID_CMD_WRITE_CABC   0x55
+#define MIPID_CMD_READ_CABC0x56
+
+#define MIPID_VER_LPH8923  3
+#define MIPID_VER_LS041Y3  4
+#define MIPID_VER_L4F00311 8
+#define MIPID_VER_ACX565AKM9
+
+struct acx565akm_device {
+   struct drm_panel panel;
+
+   struct spi_device *spi;
+   struct gpio_desc *reset_gpio;
+   struct backlight_device *backlight;
+
+   struct mutex mutex;
+
+   const char *name;
+   u8 display_id[3];
+   int model;
+   int revision;
+   bool has_bc;
+   bool has_cabc;
+
+   bool enabled;
+   unsigned int cabc_mode;
+   /*
+* Next value of jiffies when we can issue the next sleep in/out
+* command.
+*/
+   unsigned long hw_guard_end;
+   unsigned long hw_guard_wait;/* max guard time in jiffies */
+};
+
+#define to_acx565akm_device(p) container_of(p, struct acx565akm_device, panel)
+
+static void acx565akm_transfer(struct acx565akm_device *lcd, int cmd,
+ const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+   struct spi_message  m;
+   struct spi_transfer *x, xfer[5];
+   int ret;
+
+   spi_message_init(&m);
+
+   memset(xfer, 0, sizeof(xfer));
+   x = &xfer[0];
+
+   cmd &=  0xff;
+   x->tx_buf = &cmd;
+   x->bits_per_word = 9;
+   x->len = 2;
+
+   if (rlen > 1 && wlen == 0) {
+   /*
+* Between the command and the response data there is a
+* dummy clock cycle. Add an extra bit after the command
+* word to account for this.
+*/
+   x->bits_per_word = 10;
+   cmd <<= 1;
+   }
+   spi_message_add_tail(x, &m);
+
+   if (wlen) {
+   x++;
+   x->tx_buf = wbuf;
+   x->len = wlen;
+   x->bits_per_word = 9;
+   spi_message_add_tail(x, &m);
+   }
+
+   if (rlen) {
+   x++;
+   x->rx_buf   = rbuf;
+   x->len  = rlen;
+   spi_message_add_tail(x, &m);
+   }
+
+   ret = spi_sync(lcd->spi, &m);
+   if (ret < 0)
+   dev_dbg(&lcd->spi->dev, "spi_sync 

[PATCH 23/60] drm/panel: Add driver for the Toppology TD028TTEC1 panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the OpenMoko Neo FreeRunner and Neo 1973.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig|   8 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-tpo-td028ttec1.c | 382 +++
 3 files changed, 391 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-tpo-td028ttec1.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index dc10f727689a..b7099d211061 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -304,6 +304,14 @@ config DRM_PANEL_SONY_ACX565AKM
  Say Y here if you want to enable support for the Sony ACX565AKM
  800x600 3.5" panel.
 
+config DRM_PANEL_TPO_TD028TTEC1
+   tristate "TPO TD028TTEC1 panel driver"
+   depends on OF && SPI
+   depends on BACKLIGHT_CLASS_DEVICE
+   help
+ Say Y here if you want to enable support for TPO TD028TTEC1 480x640
+ 2.8" panel.
+
 config DRM_PANEL_TPO_TPG110
tristate "TPO TPG 800x400 panel"
depends on OF && SPI && GPIOLIB
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 84cbc069f6cd..a1d4de64c0b1 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -32,5 +32,6 @@ obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += 
panel-sharp-ls043t1le01.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
 obj-$(CONFIG_DRM_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o
+obj-$(CONFIG_DRM_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o
 obj-$(CONFIG_DRM_PANEL_TPO_TPG110) += panel-tpo-tpg110.o
 obj-$(CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA) += panel-truly-nt35597.o
diff --git a/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c 
b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
new file mode 100644
index ..05af9ea6339c
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-tpo-td028ttec1.c
@@ -0,0 +1,382 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Toppoly TD028TTEC1 Panel Driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-tpo-td028ttec1 driver
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen 
+ *
+ * Neo 1973 code (jbt6k74.c):
+ * Copyright (C) 2006-2007 OpenMoko, Inc.
+ * Author: Harald Welte 
+ *
+ * Ported and adapted from Neo 1973 U-Boot by:
+ * H. Nikolaus Schaller 
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#define JBT_COMMAND0x000
+#define JBT_DATA   0x100
+
+#define JBT_REG_SLEEP_IN   0x10
+#define JBT_REG_SLEEP_OUT  0x11
+
+#define JBT_REG_DISPLAY_OFF0x28
+#define JBT_REG_DISPLAY_ON 0x29
+
+#define JBT_REG_RGB_FORMAT 0x3a
+#define JBT_REG_QUAD_RATE  0x3b
+
+#define JBT_REG_POWER_ON_OFF   0xb0
+#define JBT_REG_BOOSTER_OP 0xb1
+#define JBT_REG_BOOSTER_MODE   0xb2
+#define JBT_REG_BOOSTER_FREQ   0xb3
+#define JBT_REG_OPAMP_SYSCLK   0xb4
+#define JBT_REG_VSC_VOLTAGE0xb5
+#define JBT_REG_VCOM_VOLTAGE   0xb6
+#define JBT_REG_EXT_DISPL  0xb7
+#define JBT_REG_OUTPUT_CONTROL 0xb8
+#define JBT_REG_DCCLK_DCEV 0xb9
+#define JBT_REG_DISPLAY_MODE1  0xba
+#define JBT_REG_DISPLAY_MODE2  0xbb
+#define JBT_REG_DISPLAY_MODE   0xbc
+#define JBT_REG_ASW_SLEW   0xbd
+#define JBT_REG_DUMMY_DISPLAY  0xbe
+#define JBT_REG_DRIVE_SYSTEM   0xbf
+
+#define JBT_REG_SLEEP_OUT_FR_A 0xc0
+#define JBT_REG_SLEEP_OUT_FR_B 0xc1
+#define JBT_REG_SLEEP_OUT_FR_C 0xc2
+#define JBT_REG_SLEEP_IN_LCCNT_D   0xc3
+#define JBT_REG_SLEEP_IN_LCCNT_E   0xc4
+#define JBT_REG_SLEEP_IN_LCCNT_F   0xc5
+#define JBT_REG_SLEEP_IN_LCCNT_G   0xc6
+
+#define JBT_REG_GAMMA1_FINE_1  0xc7
+#define JBT_REG_GAMMA1_FINE_2  0xc8
+#define JBT_REG_GAMMA1_INCLINATION 0xc9
+#define JBT_REG_GAMMA1_BLUE_OFFSET 0xca
+
+#define JBT_REG_BLANK_CONTROL  0xcf
+#define JBT_REG_BLANK_TH_TV0xd0
+#define JBT_REG_CKV_ON_OFF 0xd1
+#define JBT_REG_CKV_1_20xd2
+#define JBT_REG_OEV_TIMING 0xd3
+#define JBT_REG_ASW_TIMING_1   0xd4
+#define JBT_REG_ASW_TIMING_2   0xd5
+
+#define JBT_REG_HCLOCK_VGA 0xec
+#define JBT_REG_HCLOCK_QVGA0xed
+
+struct td028ttec1_device {
+   struct drm_panel panel;
+
+   struct spi_device *spi;
+   struct backlight_device *backlight;
+};
+
+#define to_td028ttec1_device(p) container_of(p, struct td028ttec1_device, 
panel)
+
+static int jbt_ret_write_0(struct td028ttec1_device *lcd, u8 reg, int *err)
+{
+   struct spi_device *spi = lcd->spi;
+   u16 tx_buf = JBT_COMMAND | reg;
+   int ret;
+
+   

[PATCH 21/60] drm/panel: Add driver for the Sharp LS037V7DW01 panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the SDP3430.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig |   7 +
 drivers/gpu/drm/panel/Makefile|   1 +
 .../gpu/drm/panel/panel-sharp-ls037v7dw01.c   | 231 ++
 3 files changed, 239 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index da613c04b835..04fd152efe4c 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -271,6 +271,13 @@ config DRM_PANEL_SHARP_LS043T1LE01
  Say Y here if you want to enable support for Sharp LS043T1LE01 qHD
  (540x960) DSI panel as found on the Qualcomm APQ8074 Dragonboard
 
+config DRM_PANEL_SHARP_LS037V7DW01
+   tristate "Sharp LS037V7DW01 VGA LCD panel"
+   depends on GPIOLIB && OF && REGULATOR
+   help
+ Say Y here if you want to enable support for Sharp LS037V7DW01 VGA
+ (480x640) LCD panel.
+
 config DRM_PANEL_SITRONIX_ST7701
tristate "Sitronix ST7701 panel driver"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index e81ed1535024..12dcd76eb87c 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += 
panel-samsung-s6e63m0.o
 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
 obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
+obj-$(CONFIG_DRM_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
 obj-$(CONFIG_DRM_PANEL_SHARP_LS043T1LE01) += panel-sharp-ls043t1le01.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7701) += panel-sitronix-st7701.o
 obj-$(CONFIG_DRM_PANEL_SITRONIX_ST7789V) += panel-sitronix-st7789v.o
diff --git a/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c 
b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c
new file mode 100644
index ..4532455b4161
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Sharp LS037V7DW01 LCD Panel Driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-sharp-ls037v7dw01 driver
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ * Author: Tomi Valkeinen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct ls037v7dw01_device {
+   struct drm_panel panel;
+   struct platform_device *pdev;
+
+   struct regulator *vcc;
+   struct gpio_desc *resb_gpio;/* low = reset active min 20 us */
+   struct gpio_desc *ini_gpio; /* high = power on */
+   struct gpio_desc *mo_gpio;  /* low = 480x640, high = 240x320 */
+   struct gpio_desc *lr_gpio;  /* high = conventional horizontal 
scanning */
+   struct gpio_desc *ud_gpio;  /* high = conventional vertical 
scanning */
+};
+
+#define to_ls037v7dw01_device(p) \
+   container_of(p, struct ls037v7dw01_device, panel)
+
+static int ls037v7dw01_disable(struct drm_panel *panel)
+{
+   struct ls037v7dw01_device *lcd = to_ls037v7dw01_device(panel);
+
+   gpiod_set_value_cansleep(lcd->ini_gpio, 0);
+   gpiod_set_value_cansleep(lcd->resb_gpio, 0);
+
+   /* Wait at least 5 vsyncs after disabling the LCD. */
+   msleep(100);
+
+   return 0;
+}
+
+static int ls037v7dw01_unprepare(struct drm_panel *panel)
+{
+   struct ls037v7dw01_device *lcd = to_ls037v7dw01_device(panel);
+
+   if (lcd->vcc)
+   regulator_disable(lcd->vcc);
+
+   return 0;
+}
+
+static int ls037v7dw01_prepare(struct drm_panel *panel)
+{
+   struct ls037v7dw01_device *lcd = to_ls037v7dw01_device(panel);
+   int ret;
+
+   if (!lcd->vcc)
+   return 0;
+
+   ret = regulator_enable(lcd->vcc);
+   if (ret < 0)
+   dev_err(&lcd->pdev->dev, "%s: failed to enable regulator\n",
+   __func__);
+
+   return ret;
+}
+
+static int ls037v7dw01_enable(struct drm_panel *panel)
+{
+   struct ls037v7dw01_device *lcd = to_ls037v7dw01_device(panel);
+
+   /* Wait couple of vsyncs before enabling the LCD. */
+   msleep(50);
+
+   gpiod_set_value_cansleep(lcd->resb_gpio, 1);
+   gpiod_set_value_cansleep(lcd->ini_gpio, 1);
+
+   return 0;
+}
+
+static const struct drm_display_mode ls037v7dw01_mode = {
+   .clock = 19200,
+   .hdisplay = 480,
+   .hsync_start = 480 + 1,
+   .hsync_end = 480 + 1 + 2,
+   .htotal = 480 + 1 + 2 + 28,
+   .vdisplay = 640,
+   .vsync_start = 640 + 1,
+   .vsync_end = 640 + 1 + 1,
+   .vtotal = 640 + 1 + 1 + 1,
+   .vrefresh = 58,
+   .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
+   .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
+};
+
+static int ls037v7dw01_get_mo

[PATCH 20/60] drm/panel: Add driver for the NEC NL8048HL11 panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the Zoom2/3/3630 SDP boards.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig|   7 +
 drivers/gpu/drm/panel/Makefile   |   1 +
 drivers/gpu/drm/panel/panel-nec-nl8048hl11.c | 249 +++
 3 files changed, 257 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-nec-nl8048hl11.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index 1843135cbeb1..da613c04b835 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -118,6 +118,13 @@ config DRM_PANEL_LG_LG4573
  Say Y here if you want to enable support for LG4573 RGB panel.
  To compile this driver as a module, choose M here.
 
+config DRM_PANEL_NEC_NL8048HL11
+   tristate "NEC NL8048HL11 RGB panel"
+   depends on GPIOLIB && OF && SPI
+   help
+ Say Y here if you want to enable support for the NEC NL8048HL11 RGB
+ panel. To compile this driver as a module, choose M here.
+
 config DRM_PANEL_OLIMEX_LCD_OLINUXINO
tristate "Olimex LCD-OLinuXino panel"
depends on OF
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index 675b5696c685..e81ed1535024 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += 
panel-jdi-lt070me05000.o
 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o
 obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
+obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
 obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
 obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
 obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o
diff --git a/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c 
b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
new file mode 100644
index ..99da665d9b4b
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-nec-nl8048hl11.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * NEC NL8048HL11 Panel Driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-nec-nl8048hl11 driver
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Erik Gilling 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct nl8048_device {
+   struct drm_panel panel;
+
+   struct spi_device *spi;
+   struct gpio_desc *reset_gpio;
+};
+
+#define to_nl8048_device(p) container_of(p, struct nl8048_device, panel)
+
+static int nl8048_write(struct nl8048_device *lcd, unsigned char addr,
+   unsigned char value)
+{
+   u8 data[4] = { value, 0x01, addr, 0x00 };
+   int ret;
+
+   ret = spi_write(lcd->spi, data, sizeof(data));
+   if (ret)
+   dev_err(&lcd->spi->dev, "SPI write to %u failed: %d\n",
+   addr, ret);
+
+   return ret;
+}
+
+static int nl8048_init(struct nl8048_device *lcd)
+{
+   static const struct {
+   unsigned char addr;
+   unsigned char data;
+   } nl8048_init_seq[] = {
+   {   3, 0x01 }, {   0, 0x00 }, {   1, 0x01 }, {   4, 0x00 },
+   {   5, 0x14 }, {   6, 0x24 }, {  16, 0xd7 }, {  17, 0x00 },
+   {  18, 0x00 }, {  19, 0x55 }, {  20, 0x01 }, {  21, 0x70 },
+   {  22, 0x1e }, {  23, 0x25 }, {  24, 0x25 }, {  25, 0x02 },
+   {  26, 0x02 }, {  27, 0xa0 }, {  32, 0x2f }, {  33, 0x0f },
+   {  34, 0x0f }, {  35, 0x0f }, {  36, 0x0f }, {  37, 0x0f },
+   {  38, 0x0f }, {  39, 0x00 }, {  40, 0x02 }, {  41, 0x02 },
+   {  42, 0x02 }, {  43, 0x0f }, {  44, 0x0f }, {  45, 0x0f },
+   {  46, 0x0f }, {  47, 0x0f }, {  48, 0x0f }, {  49, 0x0f },
+   {  50, 0x00 }, {  51, 0x02 }, {  52, 0x02 }, {  53, 0x02 },
+   {  80, 0x0c }, {  83, 0x42 }, {  84, 0x42 }, {  85, 0x41 },
+   {  86, 0x14 }, {  89, 0x88 }, {  90, 0x01 }, {  91, 0x00 },
+   {  92, 0x02 }, {  93, 0x0c }, {  94, 0x1c }, {  95, 0x27 },
+   {  98, 0x49 }, {  99, 0x27 }, { 102, 0x76 }, { 103, 0x27 },
+   { 112, 0x01 }, { 113, 0x0e }, { 114, 0x02 }, { 115, 0x0c },
+   { 118, 0x0c }, { 121, 0x30 }, { 130, 0x00 }, { 131, 0x00 },
+   { 132, 0xfc }, { 134, 0x00 }, { 136, 0x00 }, { 138, 0x00 },
+   { 139, 0x00 }, { 140, 0x00 }, { 141, 0xfc }, { 143, 0x00 },
+   { 145, 0x00 }, { 147, 0x00 }, { 148, 0x00 }, { 149, 0x00 },
+   { 150, 0xfc }, { 152, 0x00 }, { 154, 0x00 }, { 156, 0x00 },
+   { 157, 0x00 },
+   };
+
+   unsigned int i;
+   int ret;
+
+   for (i = 0; i < ARRAY_SIZE(nl8048_init_seq); ++i) {
+   re

[PATCH 19/60] drm/panel: Add driver for the LG Philips LB035Q02 panel

2019-07-07 Thread Laurent Pinchart
This panel is used on the Gumstix Overo Palo35.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/panel/Kconfig |   7 +
 drivers/gpu/drm/panel/Makefile|   1 +
 drivers/gpu/drm/panel/panel-lg-lb035q02.c | 235 ++
 3 files changed, 243 insertions(+)
 create mode 100644 drivers/gpu/drm/panel/panel-lg-lb035q02.c

diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index d9d931aa6e26..1843135cbeb1 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -103,6 +103,13 @@ config DRM_PANEL_SAMSUNG_LD9040
depends on OF && SPI
select VIDEOMODE_HELPERS
 
+config DRM_PANEL_LG_LB035Q02
+   tristate "LG LB035Q024573 RGB panel"
+   depends on GPIOLIB && OF && SPI
+   help
+ Say Y here if you want to enable support for the LB035Q02 RGB panel.
+ To compile this driver as a module, choose M here.
+
 config DRM_PANEL_LG_LG4573
tristate "LG4573 RGB/SPI panel"
depends on OF && SPI
diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile
index fb0cb3aaa9e6..675b5696c685 100644
--- a/drivers/gpu/drm/panel/Makefile
+++ b/drivers/gpu/drm/panel/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += 
panel-ilitek-ili9881c.o
 obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o
 obj-$(CONFIG_DRM_PANEL_JDI_LT070ME05000) += panel-jdi-lt070me05000.o
 obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o
+obj-$(CONFIG_DRM_PANEL_LG_LB035Q02) += panel-lg-lb035q02.o
 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
 obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
 obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
diff --git a/drivers/gpu/drm/panel/panel-lg-lb035q02.c 
b/drivers/gpu/drm/panel/panel-lg-lb035q02.c
new file mode 100644
index ..d8a8c3a3a8c5
--- /dev/null
+++ b/drivers/gpu/drm/panel/panel-lg-lb035q02.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * LG.Philips LB035Q02 LCD Panel Driver
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated
+ *
+ * Based on the omapdrm-specific panel-lg-lb035q02 driver
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ * Author: Tomi Valkeinen 
+ *
+ * Based on a driver by: Steve Sakoman 
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct lb035q02_device {
+   struct drm_panel panel;
+
+   struct spi_device *spi;
+   struct gpio_desc *enable_gpio;
+};
+
+#define to_lb035q02_device(p) container_of(p, struct lb035q02_device, panel)
+
+static int lb035q02_write(struct lb035q02_device *lcd, u16 reg, u16 val)
+{
+   struct spi_message msg;
+   struct spi_transfer index_xfer = {
+   .len= 3,
+   .cs_change  = 1,
+   };
+   struct spi_transfer value_xfer = {
+   .len= 3,
+   };
+   u8  buffer[16];
+
+   spi_message_init(&msg);
+
+   /* register index */
+   buffer[0] = 0x70;
+   buffer[1] = 0x00;
+   buffer[2] = reg & 0x7f;
+   index_xfer.tx_buf = buffer;
+   spi_message_add_tail(&index_xfer, &msg);
+
+   /* register value */
+   buffer[4] = 0x72;
+   buffer[5] = val >> 8;
+   buffer[6] = val;
+   value_xfer.tx_buf = buffer + 4;
+   spi_message_add_tail(&value_xfer, &msg);
+
+   return spi_sync(lcd->spi, &msg);
+}
+
+static int lb035q02_init(struct lb035q02_device *lcd)
+{
+   /* Init sequence from page 28 of the lb035q02 spec. */
+   static const struct {
+   u16 index;
+   u16 value;
+   } init_data[] = {
+   { 0x01, 0x6300 },
+   { 0x02, 0x0200 },
+   { 0x03, 0x0177 },
+   { 0x04, 0x04c7 },
+   { 0x05, 0xffc0 },
+   { 0x06, 0xe806 },
+   { 0x0a, 0x4008 },
+   { 0x0b, 0x },
+   { 0x0d, 0x0030 },
+   { 0x0e, 0x2800 },
+   { 0x0f, 0x },
+   { 0x16, 0x9f80 },
+   { 0x17, 0x0a0f },
+   { 0x1e, 0x00c1 },
+   { 0x30, 0x0300 },
+   { 0x31, 0x0007 },
+   { 0x32, 0x },
+   { 0x33, 0x },
+   { 0x34, 0x0707 },
+   { 0x35, 0x0004 },
+   { 0x36, 0x0302 },
+   { 0x37, 0x0202 },
+   { 0x3a, 0x0a0d },
+   { 0x3b, 0x0806 },
+   };
+
+   unsigned int i;
+   int ret;
+
+   for (i = 0; i < ARRAY_SIZE(init_data); ++i) {
+   ret = lb035q02_write(lcd, init_data[i].index,
+init_data[i].value);
+   if (ret < 0)
+   return ret;
+   }
+
+   return 0;
+}
+
+static int lb035q02_disable(struct drm_panel *panel)
+{
+   struct lb035q02_device *lcd = to_lb035q02_device(panel);
+
+   

[PATCH 18/60] dt-bindings: display: panel: Add bindings for NEC NL8048HL11 panel

2019-07-07 Thread Laurent Pinchart
The NEC NL8048HL11 is a 10.4cm WVGA (800x480) panel with a 24-bit RGB
parallel data interface and an SPI control interface.

Signed-off-by: Laurent Pinchart 
---
 .../bindings/display/panel/nec,nl8048hl11.txt | 38 +++
 1 file changed, 38 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.txt

diff --git a/Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.txt 
b/Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.txt
new file mode 100644
index ..a2559c74a45b
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/nec,nl8048hl11.txt
@@ -0,0 +1,38 @@
+NEC NL8048HL11 Panel
+
+
+The NEC NL8048HL11 is a 10.4cm WVGA (800x480) panel with a 24-bit RGB parallel
+data interface and an SPI control interface.
+
+Required properties:
+- compatible: Shall contain "nec,nl8048hl11".
+- reset-gpios: The panel reset GPIO specifier.
+
+Optional properties:
+- label: A symbolic name for the panel.
+
+Required nodes:
+- Video port for DPI input
+
+The device node shall contain one 'port' child node corresponding to the DPI
+input, with one child 'endpoint' node, according to the bindings defined in
+[1].
+
+[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
+
+Example
+---
+
+lcd-panel: panel@0 {
+   compatible = "nec,nl8048hl11";
+   reg = <0>;
+   spi-max-frequency = <1000>;
+
+   reset-gpios = <&gpio7 7 GPIO_ACTIVE_LOW>;
+
+   port {
+   lcd_in: endpoint {
+   remote-endpoint = <&dpi_out>;
+   };
+   };
+};
-- 
Regards,

Laurent Pinchart

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

[PATCH 17/60] dt-bindings: Add legacy 'toppoly' vendor prefix

2019-07-07 Thread Laurent Pinchart
The 'toppoly' vendor prefix is in use and refers to TPO, whose DT vendor
prefix is already defined as 'tpo'. Add 'toppoly' as an alternative and
document it as legacy.

Signed-off-by: Laurent Pinchart 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 2514463f2c63..d78527eb8254 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -867,6 +867,8 @@ patternProperties:
 description: Tecon Microprocessor Technologies, LLC.
   "^topeet,.*":
 description: Topeet
+  "^toppoly,.*":
+description: TPO (legacy prefix, see 'tpo')
   "^toradex,.*":
 description: Toradex AG
   "^toshiba,.*":
-- 
Regards,

Laurent Pinchart

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

[PATCH 16/60] dt-bindings: Add vendor prefix for LG Display

2019-07-07 Thread Laurent Pinchart
LG Display is an LCD display manufacturer. Originally formed as a joint
venture by LG Electronics and Philips Electronics, it was formerly known
as LG.Philips LCD, hence the DT vendor prefix lgphilips (which is
already in active use in the kernel).

More information is available at
https://en.wikipedia.org/wiki/LG_Display.

Signed-off-by: Laurent Pinchart 
---
 Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml 
b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f0bcff033ecc..2514463f2c63 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -471,6 +471,8 @@ patternProperties:
 description: Lenovo Group Ltd.
   "^lg,.*":
 description: LG Corporation
+  "^lgphilips,.*":
+description: LG Display
   "^libretech,.*":
 description: Shenzhen Libre Technology Co., Ltd
   "^licheepi,.*":
-- 
Regards,

Laurent Pinchart

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

[PATCH 15/60] drm/bridge: tfp410: Allow operation without drm_connector

2019-07-07 Thread Laurent Pinchart
The tfp410 driver can operate as part of a pipeline where the
drm_connector is created by the display controller. Enable this mode of
operation by skipping creation of a drm_connector internally.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index e94c4956731d..38d2d2bde4a0 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -136,7 +136,7 @@ static int tfp410_attach(struct drm_bridge *bridge, bool 
create_connector)
return ret;
 
if (!create_connector)
-   return -EINVAL;
+   return 0;
 
if (!bridge->encoder) {
dev_err(dvi->dev, "Missing encoder\n");
-- 
Regards,

Laurent Pinchart

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

[PATCH 14/60] drm/bridge: tfp410: Replace manual connector handling with bridge

2019-07-07 Thread Laurent Pinchart
Now that a driver is available for display connectors, replace the
manual connector handling code with usage of the DRM bridge API. The
tfp410 driver doesn't deal with the display connector directly anymore,
but still delegates drm_connector operations to the next bridge. This
brings us one step closer to having the tfp410 driver handling the
TFP410 only.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 193 ++---
 1 file changed, 67 insertions(+), 126 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index a1cad777b057..e94c4956731d 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -8,14 +8,12 @@
  *
  */
 
-#include 
-#include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -28,16 +26,13 @@
 struct tfp410 {
struct drm_bridge   bridge;
struct drm_connectorconnector;
-   unsigned intconnector_type;
 
u32 bus_format;
-   struct i2c_adapter  *ddc;
-   struct gpio_desc*hpd;
-   int hpd_irq;
struct delayed_work hpd_work;
struct gpio_desc*powerdown;
 
struct drm_bridge_timings timings;
+   struct drm_bridge   *next_bridge;
 
struct device *dev;
 };
@@ -60,10 +55,10 @@ static int tfp410_get_modes(struct drm_connector *connector)
struct edid *edid;
int ret;
 
-   if (!dvi->ddc)
+   if (!(dvi->next_bridge->ops & DRM_BRIDGE_OP_EDID))
goto fallback;
 
-   edid = drm_get_edid(connector, dvi->ddc);
+   edid = dvi->next_bridge->funcs->get_edid(dvi->next_bridge, connector);
if (!edid) {
dev_info(dvi->dev,
 "EDID read failed. Fallback to standard modes\n");
@@ -97,21 +92,10 @@ tfp410_connector_detect(struct drm_connector *connector, 
bool force)
 {
struct tfp410 *dvi = drm_connector_to_tfp410(connector);
 
-   if (dvi->hpd) {
-   if (gpiod_get_value_cansleep(dvi->hpd))
-   return connector_status_connected;
-   else
-   return connector_status_disconnected;
-   }
+   if (!(dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT))
+   return connector_status_unknown;
 
-   if (dvi->ddc) {
-   if (drm_probe_ddc(dvi->ddc))
-   return connector_status_connected;
-   else
-   return connector_status_disconnected;
-   }
-
-   return connector_status_unknown;
+   return dvi->next_bridge->funcs->detect(dvi->next_bridge);
 }
 
 static const struct drm_connector_funcs tfp410_con_funcs = {
@@ -123,11 +107,34 @@ static const struct drm_connector_funcs tfp410_con_funcs 
= {
.atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
 };
 
+static void tfp410_hpd_work_func(struct work_struct *work)
+{
+   struct tfp410 *dvi;
+
+   dvi = container_of(work, struct tfp410, hpd_work.work);
+
+   if (dvi->bridge.dev)
+   drm_helper_hpd_irq_event(dvi->bridge.dev);
+}
+
+static void tfp410_hpd_callback(void *arg, enum drm_connector_status status)
+{
+   struct tfp410 *dvi = arg;
+
+   mod_delayed_work(system_wq, &dvi->hpd_work,
+msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
+}
+
 static int tfp410_attach(struct drm_bridge *bridge, bool create_connector)
 {
struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
int ret;
 
+   ret = drm_bridge_attach(bridge->encoder, dvi->next_bridge, bridge,
+   false);
+   if (ret < 0)
+   return ret;
+
if (!create_connector)
return -EINVAL;
 
@@ -136,15 +143,21 @@ static int tfp410_attach(struct drm_bridge *bridge, bool 
create_connector)
return -ENODEV;
}
 
-   if (dvi->hpd_irq >= 0)
+   if (dvi->next_bridge->ops & DRM_BRIDGE_OP_DETECT)
dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
else
dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | 
DRM_CONNECTOR_POLL_DISCONNECT;
 
+   if (dvi->next_bridge->ops & DRM_BRIDGE_OP_HPD) {
+   INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
+   drm_bridge_hpd_enable(dvi->next_bridge, tfp410_hpd_callback,
+ dvi);
+   }
+
drm_connector_helper_add(&dvi->connector,
 &tfp410_con_helper_funcs);
ret = drm_connector_init(bridge->dev, &dvi->connector,
-&tfp410_con_funcs, dvi->connector_type);
+&tfp410_con_funcs, dvi->next_bridge->type);
if (ret) {
dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
return ret;
@@ -

[PATCH 13/60] drm/bridge: tfp410: Don't include drmP.h

2019-07-07 Thread Laurent Pinchart
The drmP.h header is deprecated, replace it with the headers
specifically needed by the tfp410 driver. While at it, replace the DRM
print macros with dev_info() and dev_err() instead of including
drm_print.h

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/ti-tfp410.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c 
b/drivers/gpu/drm/bridge/ti-tfp410.c
index 8d4690e436c3..a1cad777b057 100644
--- a/drivers/gpu/drm/bridge/ti-tfp410.c
+++ b/drivers/gpu/drm/bridge/ti-tfp410.c
@@ -18,6 +18,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -64,7 +65,8 @@ static int tfp410_get_modes(struct drm_connector *connector)
 
edid = drm_get_edid(connector, dvi->ddc);
if (!edid) {
-   DRM_INFO("EDID read failed. Fallback to standard modes\n");
+   dev_info(dvi->dev,
+"EDID read failed. Fallback to standard modes\n");
goto fallback;
}
 
@@ -365,7 +367,7 @@ static int tfp410_init(struct device *dev, bool i2c)
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"hdmi-hpd", dvi);
if (ret) {
-   DRM_ERROR("failed to register hpd interrupt\n");
+   dev_err(dev, "failed to register hpd interrupt\n");
goto fail;
}
}
-- 
Regards,

Laurent Pinchart

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

[PATCH 12/60] drm/bridge: panel: Implement bridge connector operations

2019-07-07 Thread Laurent Pinchart
Implement the newly added bridge connector operations, allowing the
usage of drm_bridge_panel with drm_bridge_connector.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/panel.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/panel.c b/drivers/gpu/drm/bridge/panel.c
index 98ad4abf2409..628e37babb09 100644
--- a/drivers/gpu/drm/bridge/panel.c
+++ b/drivers/gpu/drm/bridge/panel.c
@@ -59,7 +59,7 @@ static int panel_bridge_attach(struct drm_bridge *bridge, 
bool create_connector)
int ret;
 
if (!create_connector)
-   return -EINVAL;
+   return 0;
 
if (!bridge->encoder) {
DRM_ERROR("Missing encoder\n");
@@ -122,6 +122,18 @@ static void panel_bridge_post_disable(struct drm_bridge 
*bridge)
drm_panel_unprepare(panel_bridge->panel);
 }
 
+static int panel_bridge_get_modes(struct drm_bridge *bridge,
+ struct drm_connector *connector)
+{
+   struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
+
+   /*
+* FIXME: drm_panel_get_modes() should take the connector as an
+* argument.
+*/
+   return drm_panel_get_modes(panel_bridge->panel);
+}
+
 static const struct drm_bridge_funcs panel_bridge_bridge_funcs = {
.attach = panel_bridge_attach,
.detach = panel_bridge_detach,
@@ -129,6 +141,7 @@ static const struct drm_bridge_funcs 
panel_bridge_bridge_funcs = {
.enable = panel_bridge_enable,
.disable = panel_bridge_disable,
.post_disable = panel_bridge_post_disable,
+   .get_modes = panel_bridge_get_modes,
 };
 
 /**
@@ -174,6 +187,9 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel 
*panel,
 #ifdef CONFIG_OF
panel_bridge->bridge.of_node = panel->dev->of_node;
 #endif
+   panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
+   /* FIXME: The panel should report its type. */
+   panel_bridge->bridge.type = DRM_MODE_CONNECTOR_DPI;
 
drm_bridge_add(&panel_bridge->bridge);
 
-- 
Regards,

Laurent Pinchart

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

[PATCH 11/60] drm/bridge: Add driver for the TI TPD12S015 HDMI level shifter

2019-07-07 Thread Laurent Pinchart
The TI TPD12S015 is an HDMI level shifter and ESD protector controlled
through GPIOs. Add a DRM bridge driver for the device.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/Kconfig|   8 +
 drivers/gpu/drm/bridge/Makefile   |   1 +
 drivers/gpu/drm/bridge/ti-tpd12s015.c | 204 ++
 3 files changed, 213 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/ti-tpd12s015.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index 295a62f65ef9..3928651a0819 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -159,6 +159,14 @@ config DRM_TI_SN65DSI86
help
  Texas Instruments SN65DSI86 DSI to eDP Bridge driver
 
+config DRM_TI_TPD12S015
+   tristate "TI TPD12S015 HDMI level shifter and ESD protection"
+   depends on OF
+   select DRM_KMS_HELPER
+   help
+ Texas Instruments TPD12S015 HDMI level shifter and ESD protection
+ driver.
+
 source "drivers/gpu/drm/bridge/analogix/Kconfig"
 
 source "drivers/gpu/drm/bridge/adv7511/Kconfig"
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index e5987b3aaf62..ce635651e31b 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
 obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
 obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
 obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
+obj-$(CONFIG_DRM_TI_TPD12S015) += ti-tpd12s015.o
 obj-y += synopsys/
diff --git a/drivers/gpu/drm/bridge/ti-tpd12s015.c 
b/drivers/gpu/drm/bridge/ti-tpd12s015.c
new file mode 100644
index ..d01f0c4133a2
--- /dev/null
+++ b/drivers/gpu/drm/bridge/ti-tpd12s015.c
@@ -0,0 +1,204 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * TPD12S015 HDMI ESD protection & level shifter chip driver
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated
+ * Author: Tomi Valkeinen 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+struct tpd12s015_device {
+   struct drm_bridge bridge;
+
+   struct gpio_desc *ct_cp_hpd_gpio;
+   struct gpio_desc *ls_oe_gpio;
+   struct gpio_desc *hpd_gpio;
+   int hpd_irq;
+
+   struct drm_bridge *next_bridge;
+};
+
+static inline struct tpd12s015_device *to_tpd12s015(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct tpd12s015_device, bridge);
+}
+
+static int tpd12s015_attach(struct drm_bridge *bridge, bool create_connector)
+{
+   struct tpd12s015_device *tpd = to_tpd12s015(bridge);
+   int ret;
+
+   if (create_connector)
+   return -EINVAL;
+
+   ret = drm_bridge_attach(bridge->encoder, tpd->next_bridge,
+   bridge, false);
+   if (ret < 0)
+   return ret;
+
+   gpiod_set_value_cansleep(tpd->ct_cp_hpd_gpio, 1);
+   gpiod_set_value_cansleep(tpd->ls_oe_gpio, 1);
+
+   /* DC-DC converter needs at max 300us to get to 90% of 5V. */
+   usleep_range(300, 1000);
+
+   return 0;
+}
+
+static void tpd12s015_detach(struct drm_bridge *bridge)
+{
+   struct tpd12s015_device *tpd = to_tpd12s015(bridge);
+
+   gpiod_set_value_cansleep(tpd->ct_cp_hpd_gpio, 0);
+   gpiod_set_value_cansleep(tpd->ls_oe_gpio, 0);
+}
+
+static enum drm_connector_status tpd12s015_detect(struct drm_bridge *bridge)
+{
+   struct tpd12s015_device *tpd = to_tpd12s015(bridge);
+
+   if (gpiod_get_value_cansleep(tpd->hpd_gpio))
+   return connector_status_connected;
+   else
+   return connector_status_disconnected;
+}
+
+static void tpd12s015_hpd_enable(struct drm_bridge *bridge)
+{
+}
+
+static void tpd12s015_hpd_disable(struct drm_bridge *bridge)
+{
+}
+
+static const struct drm_bridge_funcs tpd12s015_bridge_funcs = {
+   .attach = tpd12s015_attach,
+   .detach = tpd12s015_detach,
+   .detect = tpd12s015_detect,
+   .hpd_enable = tpd12s015_hpd_enable,
+   .hpd_disable= tpd12s015_hpd_disable,
+};
+
+static irqreturn_t tpd12s015_hpd_isr(int irq, void *data)
+{
+   struct tpd12s015_device *tpd = data;
+   struct drm_bridge *bridge = &tpd->bridge;
+
+   drm_bridge_hpd_notify(bridge, tpd12s015_detect(bridge));
+
+   return IRQ_HANDLED;
+}
+
+static int tpd12s015_probe(struct platform_device *pdev)
+{
+   struct tpd12s015_device *tpd;
+   struct device_node *node;
+   struct gpio_desc *gpio;
+   int ret;
+
+   tpd = devm_kzalloc(&pdev->dev, sizeof(*tpd), GFP_KERNEL);
+   if (!tpd)
+   return -ENOMEM;
+
+   platform_set_drvdata(pdev, tpd);
+
+   tpd->bridge.funcs = &tpd12s015_bridge_funcs;
+   tpd->bridge.of_node = pdev->dev.of_node;
+   tpd->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
+   tpd->bridge.ops = DRM_BRIDGE_OP_DETECT;
+
+   /* Get the next bridge,

[PATCH 10/60] drm/bridge: Add bridge driver for display connectors

2019-07-07 Thread Laurent Pinchart
Display connectors are modelled in DT as a device node, but have so far
been handled manually in several bridge drivers. This resulted in
duplicate code in several bridge drivers, with slightly different (and
thus confusing) logics.

In order to fix this, implement a bridge driver for display connectors.
The driver centralises logic for the DVI, HDMI, VGAn composite and
S-video connectors and exposes corresponding bridge operations.

This driver in itself doesn't solve the issue completely, changes in
bridge and display controller drivers are needed to make use of the new
connector driver.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/Kconfig |  11 +
 drivers/gpu/drm/bridge/Makefile|   1 +
 drivers/gpu/drm/bridge/display-connector.c | 327 +
 3 files changed, 339 insertions(+)
 create mode 100644 drivers/gpu/drm/bridge/display-connector.c

diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index a78392e2dbb9..295a62f65ef9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -37,6 +37,17 @@ config DRM_CDNS_DSI
  Support Cadence DPI to DSI bridge. This is an internal
  bridge and is meant to be directly embedded in a SoC.
 
+config DRM_DISPLAY_CONNECTOR
+   tristate "Display connector support"
+   depends on OF
+   help
+ Driver for display connectors with support for DDC and hot-plug
+ detection. Most display controller handle display connectors
+ internally and don't need this driver, but the DRM subsystem is
+ moving towards separating connector handling from display controllers
+ on ARM-based platforms. Saying Y here when this driver is not needed
+ will not cause any issue.
+
 config DRM_LVDS_ENCODER
tristate "Transparent parallel to LVDS encoder support"
depends on OF
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile
index 6ff7f2adbb0e..e5987b3aaf62 100644
--- a/drivers/gpu/drm/bridge/Makefile
+++ b/drivers/gpu/drm/bridge/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_DRM_ANALOGIX_ANX78XX) += analogix-anx78xx.o
 obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
+obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
 obj-$(CONFIG_DRM_LVDS_ENCODER) += lvds-encoder.o
 obj-$(CONFIG_DRM_MEGACHIPS_STDP_GE_B850V3_FW) += 
megachips-stdp-ge-b850v3-fw.o
 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
diff --git a/drivers/gpu/drm/bridge/display-connector.c 
b/drivers/gpu/drm/bridge/display-connector.c
new file mode 100644
index ..2e1e7ee89275
--- /dev/null
+++ b/drivers/gpu/drm/bridge/display-connector.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Laurent Pinchart 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct display_connector {
+   struct drm_bridge   bridge;
+
+   const char  *label;
+   struct i2c_adapter  *ddc;
+   struct gpio_desc*hpd_gpio;
+   int hpd_irq;
+};
+
+static inline struct display_connector *
+to_display_connector(struct drm_bridge *bridge)
+{
+   return container_of(bridge, struct display_connector, bridge);
+}
+
+static int display_connector_attach(struct drm_bridge *bridge,
+   bool create_connector)
+{
+   return create_connector ? -EINVAL : 0;
+}
+
+static enum drm_connector_status
+display_connector_detect(struct drm_bridge *bridge)
+{
+   struct display_connector *conn = to_display_connector(bridge);
+
+   if (conn->hpd_gpio) {
+   if (gpiod_get_value_cansleep(conn->hpd_gpio))
+   return connector_status_connected;
+   else
+   return connector_status_disconnected;
+   }
+
+   if (conn->ddc && drm_probe_ddc(conn->ddc))
+   return connector_status_connected;
+
+   switch (conn->bridge.type) {
+   case DRM_MODE_CONNECTOR_DVIA:
+   case DRM_MODE_CONNECTOR_DVID:
+   case DRM_MODE_CONNECTOR_DVII:
+   case DRM_MODE_CONNECTOR_HDMIA:
+   case DRM_MODE_CONNECTOR_HDMIB:
+   /*
+* For DVI and HDMI connectors a DDC probe failure indicates
+* that no cable is connected.
+*/
+   return connector_status_disconnected;
+
+   case DRM_MODE_CONNECTOR_Composite:
+   case DRM_MODE_CONNECTOR_SVIDEO:
+   case DRM_MODE_CONNECTOR_VGA:
+   default:
+   /*
+* Composite and S-Video connectors have no other detection
+* mean than the HPD GPIO. For VGA connectors, even if we have
+* an I2C bus, we can't assume that the cable is disconnected
+* if drm_probe_ddc fails, as some cables don't wire the DDC
+* pins.
+*

[PATCH 09/60] drm/bridge: Add connector-related bridge operations and data

2019-07-07 Thread Laurent Pinchart
To support implementation of DRM connectors on top of DRM bridges
instead of by bridges, the drm_bridge needs to expose new operations and
data:

- Output detection, hot-plug notification, mode retrieval and EDID
  retrieval operations
- Bitmask of supported operations
- Bridge output type

Add and document these.

Three new bridge helper functions are also added to handle hot plug
notification in a way that is as transparent as possible for the
bridges.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/drm_bridge.c |  92 +++
 include/drm/drm_bridge.h | 170 ++-
 2 files changed, 261 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index 519577f363e3..3c2a255df7af 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -70,6 +70,8 @@ static LIST_HEAD(bridge_list);
  */
 void drm_bridge_add(struct drm_bridge *bridge)
 {
+   mutex_init(&bridge->hpd_mutex);
+
mutex_lock(&bridge_lock);
list_add_tail(&bridge->list, &bridge_list);
mutex_unlock(&bridge_lock);
@@ -86,6 +88,8 @@ void drm_bridge_remove(struct drm_bridge *bridge)
mutex_lock(&bridge_lock);
list_del_init(&bridge->list);
mutex_unlock(&bridge_lock);
+
+   mutex_destroy(&bridge->hpd_mutex);
 }
 EXPORT_SYMBOL(drm_bridge_remove);
 
@@ -463,6 +467,94 @@ void drm_atomic_bridge_enable(struct drm_bridge *bridge,
 }
 EXPORT_SYMBOL(drm_atomic_bridge_enable);
 
+/**
+ * drm_bridge_hpd_enable - enable hot plug detection for the bridge
+ * @bridge: bridge control structure
+ * @cb: hot-plug detection callback
+ * @data: data to be passed to the hot-plug detection callback
+ *
+ * Call &drm_bridge_funcs.hpd_enable and register the given @cb and @data as
+ * hot plug notification callback. From now on the @cb will be called with
+ * @data when an output status change is detected by the bridge, until hot plug
+ * notification gets disabled with drm_bridge_hpd_disable().
+ *
+ * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in
+ * bridge->ops. This function shall not be called when the flag is not set.
+ *
+ * Only one hot plug detection callback can be registered at a time, it is an
+ * error to call this function when hot plug detection is already enabled for
+ * the bridge.
+ */
+void drm_bridge_hpd_enable(struct drm_bridge *bridge,
+  void (*cb)(void *data,
+ enum drm_connector_status status),
+  void *data)
+{
+   if (!bridge || !bridge->funcs->hpd_enable)
+   return;
+
+   mutex_lock(&bridge->hpd_mutex);
+
+   if (WARN(bridge->hpd_cb, "Hot plug detection already enabled\n"))
+   goto unlock;
+
+   bridge->hpd_cb = cb;
+   bridge->hpd_data = data;
+
+   bridge->funcs->hpd_enable(bridge);
+
+unlock:
+   mutex_unlock(&bridge->hpd_mutex);
+}
+EXPORT_SYMBOL_GPL(drm_bridge_hpd_enable);
+
+/**
+ * drm_bridge_hpd_disable - disable hot plug detection for the bridge
+ * @bridge: bridge control structure
+ *
+ * Call &drm_bridge_funcs.hpd_disable and unregister the hot plug detection
+ * callback previously registered with drm_bridge_hpd_enable(). Once this
+ * function returns the callback will not be called by the bridge when an
+ * output status change occurs.
+ *
+ * Hot plug detection is supported only if the DRM_BRIDGE_OP_HPD flag is set in
+ * bridge->ops. This function shall not be called when the flag is not set.
+ */
+void drm_bridge_hpd_disable(struct drm_bridge *bridge)
+{
+   if (!bridge || !bridge->funcs->hpd_disable)
+   return;
+
+   mutex_lock(&bridge->hpd_mutex);
+   bridge->funcs->hpd_disable(bridge);
+
+   bridge->hpd_cb = NULL;
+   bridge->hpd_data = NULL;
+   mutex_unlock(&bridge->hpd_mutex);
+}
+EXPORT_SYMBOL_GPL(drm_bridge_hpd_disable);
+
+/**
+ * drm_bridge_hpd_notify - notify hot plug detection events
+ * @bridge: bridge control structure
+ * @status: output connection status
+ *
+ * Bridge drivers shall call this function to report hot plug events when they
+ * detect a change in the output status, when hot plug detection has been
+ * enabled by the &drm_bridge_funcs.hpd_enable callback.
+ *
+ * This function shall be called in a context that can sleep.
+ */
+void drm_bridge_hpd_notify(struct drm_bridge *bridge,
+  enum drm_connector_status status)
+{
+   mutex_lock(&bridge->hpd_mutex);
+   if (bridge->hpd_cb)
+   bridge->hpd_cb(bridge->hpd_data, status);
+   mutex_unlock(&bridge->hpd_mutex);
+}
+EXPORT_SYMBOL_GPL(drm_bridge_hpd_notify);
+
 #ifdef CONFIG_OF
 /**
  * of_drm_find_bridge - find the bridge corresponding to the device node in
diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
index 08dc15f93ded..b9445aa5b1ef 100644
--- a/include/drm/drm_bridge.h
+++ b/include/drm/drm_bridge.h
@@ -23,8 +23,9 @@

[PATCH 07/60] drm/bridge: simple-bridge: Add support for the TI OP362

2019-07-07 Thread Laurent Pinchart
The TI OP362 is an analog video amplifier controlled through a GPIO. Add
support for it to the simple-bridge driver.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/simple-bridge.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/simple-bridge.c 
b/drivers/gpu/drm/bridge/simple-bridge.c
index a7edf3c39627..7495b9bef865 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -296,6 +296,11 @@ static const struct of_device_id simple_bridge_match[] = {
.timings = &default_bridge_timings,
.type = DRM_MODE_CONNECTOR_VGA,
},
+   }, {
+   .compatible = "ti,opa362",
+   .data = &(const struct simple_bridge_info) {
+   .type = DRM_MODE_CONNECTOR_Composite,
+   },
}, {
.compatible = "ti,ths8135",
.data = &(const struct simple_bridge_info) {
-- 
Regards,

Laurent Pinchart

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

[PATCH 08/60] drm/bridge: Extend bridge API to disable connector creation

2019-07-07 Thread Laurent Pinchart
Most bridge drivers create a DRM connector to model the connector at the
output of the bridge. This model is historical and has worked pretty
well so far, but causes several issues:

- It prevents supporting more complex display pipelines where DRM
connector operations are split over multiple components. For instance a
pipeline with a bridge connected to the DDC signals to read EDID data,
and another one connected to the HPD signal to detect connection and
disconnection, will not be possible to support through this model.

- It requires every bridge driver to implement similar connector
handling code, resulting in code duplication.

- It assumes that a bridge will either be wired to a connector or to
another bridge, but doesn't support bridges that can be used in both
positions very well (although there is some ad-hoc support for this in
the analogix_dp bridge driver).

In order to solve these issues, ownership of the connector should be
moved to the display controller driver (where it can be implemented
using helpers provided by the core).

Extend the bridge API to allow disabling connector creation in bridge
drivers as a first step towards the new model. The new create_connector
argument to the bridge .attach() operation tells the bridge driver
whether to create a connector. Set the argument to true unconditionally,
and modify all existing bridge drivers to return an error when connector
creation is not requested as they don't support this feature yet.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/arc/arcpgu_hdmi.c| 2 +-
 drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_output.c | 2 +-
 drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 +-
 drivers/gpu/drm/bridge/analogix-anx78xx.c| 6 +-
 drivers/gpu/drm/bridge/analogix/analogix_dp_core.c   | 8 ++--
 drivers/gpu/drm/bridge/cdns-dsi.c| 6 --
 drivers/gpu/drm/bridge/lvds-encoder.c| 4 ++--
 drivers/gpu/drm/bridge/megachips-stdp-ge-b850v3-fw.c | 6 +-
 drivers/gpu/drm/bridge/nxp-ptn3460.c | 6 +-
 drivers/gpu/drm/bridge/panel.c   | 5 -
 drivers/gpu/drm/bridge/parade-ps8622.c   | 5 -
 drivers/gpu/drm/bridge/sii902x.c | 6 +-
 drivers/gpu/drm/bridge/sil-sii8620.c | 2 +-
 drivers/gpu/drm/bridge/simple-bridge.c   | 6 +-
 drivers/gpu/drm/bridge/synopsys/dw-hdmi.c| 8 ++--
 drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c| 8 +---
 drivers/gpu/drm/bridge/tc358764.c| 5 -
 drivers/gpu/drm/bridge/tc358767.c| 5 -
 drivers/gpu/drm/bridge/thc63lvd1024.c| 5 +++--
 drivers/gpu/drm/bridge/ti-sn65dsi86.c| 5 -
 drivers/gpu/drm/bridge/ti-tfp410.c   | 5 -
 drivers/gpu/drm/drm_bridge.c | 5 +++--
 drivers/gpu/drm/drm_simple_kms_helper.c  | 2 +-
 drivers/gpu/drm/exynos/exynos_dp.c   | 3 ++-
 drivers/gpu/drm/exynos/exynos_drm_dsi.c  | 4 ++--
 drivers/gpu/drm/exynos/exynos_hdmi.c | 2 +-
 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c| 2 +-
 drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c | 2 +-
 drivers/gpu/drm/i2c/tda998x_drv.c| 8 ++--
 drivers/gpu/drm/imx/imx-ldb.c| 2 +-
 drivers/gpu/drm/imx/parallel-display.c   | 2 +-
 drivers/gpu/drm/mcde/mcde_dsi.c  | 6 +-
 drivers/gpu/drm/mediatek/mtk_dpi.c   | 2 +-
 drivers/gpu/drm/mediatek/mtk_dsi.c   | 2 +-
 drivers/gpu/drm/mediatek/mtk_hdmi.c  | 8 ++--
 drivers/gpu/drm/msm/dsi/dsi_manager.c| 4 ++--
 drivers/gpu/drm/msm/edp/edp_bridge.c | 2 +-
 drivers/gpu/drm/msm/hdmi/hdmi_bridge.c   | 2 +-
 drivers/gpu/drm/omapdrm/omap_drv.c   | 3 ++-
 drivers/gpu/drm/rcar-du/rcar_du_encoder.c| 2 +-
 drivers/gpu/drm/rcar-du/rcar_lvds.c  | 7 +--
 drivers/gpu/drm/rockchip/rockchip_lvds.c | 2 +-
 drivers/gpu/drm/rockchip/rockchip_rgb.c  | 2 +-
 drivers/gpu/drm/sti/sti_dvo.c| 2 +-
 drivers/gpu/drm/sti/sti_hda.c| 2 +-
 drivers/gpu/drm/sti/sti_hdmi.c   | 2 +-
 drivers/gpu/drm/stm/ltdc.c   | 2 +-
 drivers/gpu/drm/sun4i/sun4i_lvds.c   | 2 +-
 drivers/gpu/drm/sun4i/sun4i_rgb.c| 2 +-
 drivers/gpu/drm/tilcdc/tilcdc_external.c | 2 +-
 drivers/gpu/drm/vc4/vc4_dpi.c| 2 +-
 drivers/gpu/drm/vc4/vc4_dsi.c| 2 +-
 in

Re: [PATCH 02/60] video: hdmi: Change return type of hdmi_avi_infoframe_init() to void

2019-07-07 Thread Ilia Mirkin
On Sun, Jul 7, 2019 at 2:15 PM Laurent Pinchart
 wrote:
>
> Sorry, forgot to CC Bartlomiej on this patch.
>
> On Sun, Jul 07, 2019 at 09:07:54PM +0300, Laurent Pinchart wrote:
> > The hdmi_avi_infoframe_init() never needs to return an error, change its
> > return type to void.
> >
> > Signed-off-by: Laurent Pinchart 
> > ---
> >  drivers/gpu/drm/drm_edid.c | 5 +
> >  drivers/video/hdmi.c   | 9 ++---
> >  include/linux/hdmi.h   | 2 +-
> >  3 files changed, 4 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> > index b939bc28d886..54fb7cf11d1a 100644
> > --- a/drivers/video/hdmi.c
> > +++ b/drivers/video/hdmi.c
> > @@ -56,15 +56,13 @@ static void hdmi_infoframe_set_checksum(void *buffer, 
> > size_t size)
> >   *
> >   * Returns 0 on success or a negative error code on failure.

Probably want to adjust this text too, then?

[I have no opinion on whether this patch is good or bad, just happened
to notice the inconsistency.]

Cheers,

  -ilia

> >   */
> > -int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> > +void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> >  {
> >   memset(frame, 0, sizeof(*frame));
> >
> >   frame->type = HDMI_INFOFRAME_TYPE_AVI;
> >   frame->version = 2;
> >   frame->length = HDMI_AVI_INFOFRAME_SIZE;
> > -
> > - return 0;
> >  }
> >  EXPORT_SYMBOL(hdmi_avi_infoframe_init);
> >
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH 06/60] drm/bridge: simple-bridge: Add support for enable GPIO

2019-07-07 Thread Laurent Pinchart
If an enable GPIO is declared in the firmware, assert it when enabling
the bridge and deassert it when disabling it.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/simple-bridge.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/simple-bridge.c 
b/drivers/gpu/drm/bridge/simple-bridge.c
index bff240cf283d..a7edf3c39627 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -6,6 +6,7 @@
  * Maxime Ripard 
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -29,6 +30,7 @@ struct simple_bridge {
 
struct i2c_adapter  *ddc;
struct regulator*vdd;
+   struct gpio_desc*enable;
 };
 
 static inline struct simple_bridge *
@@ -135,19 +137,23 @@ static int simple_bridge_attach(struct drm_bridge *bridge)
 static void simple_bridge_enable(struct drm_bridge *bridge)
 {
struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge);
-   int ret = 0;
+   int ret;
 
-   if (sbridge->vdd)
+   if (sbridge->vdd) {
ret = regulator_enable(sbridge->vdd);
+   if (ret)
+   DRM_ERROR("Failed to enable vdd regulator: %d\n", ret);
+   }
 
-   if (ret)
-   DRM_ERROR("Failed to enable vdd regulator: %d\n", ret);
+   gpiod_set_value_cansleep(sbridge->enable, 1);
 }
 
 static void simple_bridge_disable(struct drm_bridge *bridge)
 {
struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge);
 
+   gpiod_set_value_cansleep(sbridge->enable, 0);
+
if (sbridge->vdd)
regulator_disable(sbridge->vdd);
 }
@@ -200,6 +206,14 @@ static int simple_bridge_probe(struct platform_device 
*pdev)
dev_dbg(&pdev->dev, "No vdd regulator found: %d\n", ret);
}
 
+   sbridge->enable = devm_gpiod_get_optional(&pdev->dev, "enable",
+ GPIOD_OUT_LOW);
+   if (IS_ERR(sbridge->enable)) {
+   if (PTR_ERR(sbridge->enable) != -EPROBE_DEFER)
+   dev_err(&pdev->dev, "Unable to retrieve enable GPIO\n");
+   return PTR_ERR(sbridge->enable);
+   }
+
sbridge->ddc = simple_bridge_retrieve_ddc(&pdev->dev);
if (IS_ERR(sbridge->ddc)) {
if (PTR_ERR(sbridge->ddc) == -ENODEV) {
-- 
Regards,

Laurent Pinchart

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

[PATCH 05/60] drm/bridge: simple-bridge: Add support for non-VGA bridges

2019-07-07 Thread Laurent Pinchart
Create a new simple_bridge_info structure that stores information about
the bridge model, and store the bridge timings in there, along with the
connector type. Use that new structure for of_device_id data. This
enables support for non-VGA bridges.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/simple-bridge.c | 41 ++
 1 file changed, 29 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/simple-bridge.c 
b/drivers/gpu/drm/bridge/simple-bridge.c
index da5479bd5878..bff240cf283d 100644
--- a/drivers/gpu/drm/bridge/simple-bridge.c
+++ b/drivers/gpu/drm/bridge/simple-bridge.c
@@ -16,10 +16,17 @@
 #include 
 #include 
 
+struct simple_bridge_info {
+   const struct drm_bridge_timings *timings;
+   unsigned int type;
+};
+
 struct simple_bridge {
struct drm_bridge   bridge;
struct drm_connectorconnector;
 
+   const struct simple_bridge_info *info;
+
struct i2c_adapter  *ddc;
struct regulator*vdd;
 };
@@ -113,7 +120,7 @@ static int simple_bridge_attach(struct drm_bridge *bridge)
 &simple_bridge_con_helper_funcs);
ret = drm_connector_init(bridge->dev, &sbridge->connector,
 &simple_bridge_con_funcs,
-DRM_MODE_CONNECTOR_VGA);
+sbridge->info->type);
if (ret) {
DRM_ERROR("Failed to initialize connector\n");
return ret;
@@ -182,6 +189,8 @@ static int simple_bridge_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, sbridge);
 
+   sbridge->info = of_device_get_match_data(&pdev->dev);
+
sbridge->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
if (IS_ERR(sbridge->vdd)) {
int ret = PTR_ERR(sbridge->vdd);
@@ -204,7 +213,7 @@ static int simple_bridge_probe(struct platform_device *pdev)
 
sbridge->bridge.funcs = &simple_bridge_bridge_funcs;
sbridge->bridge.of_node = pdev->dev.of_node;
-   sbridge->bridge.timings = of_device_get_match_data(&pdev->dev);
+   sbridge->bridge.timings = sbridge->info->timings;
 
drm_bridge_add(&sbridge->bridge);
 
@@ -264,19 +273,27 @@ static const struct drm_bridge_timings 
ti_ths8135_bridge_timings = {
 static const struct of_device_id simple_bridge_match[] = {
{
.compatible = "dumb-vga-dac",
-   .data = NULL,
-   },
-   {
+   .data = &(const struct simple_bridge_info) {
+   .type = DRM_MODE_CONNECTOR_VGA,
+   },
+   }, {
.compatible = "adi,adv7123",
-   .data = &default_bridge_timings,
-   },
-   {
+   .data = &(const struct simple_bridge_info) {
+   .timings = &default_bridge_timings,
+   .type = DRM_MODE_CONNECTOR_VGA,
+   },
+   }, {
.compatible = "ti,ths8135",
-   .data = &ti_ths8135_bridge_timings,
-   },
-   {
+   .data = &(const struct simple_bridge_info) {
+   .timings = &ti_ths8135_bridge_timings,
+   .type = DRM_MODE_CONNECTOR_VGA,
+   },
+   }, {
.compatible = "ti,ths8134",
-   .data = &ti_ths8134_bridge_timings,
+   .data = &(const struct simple_bridge_info) {
+   .timings = &ti_ths8134_bridge_timings,
+   .type = DRM_MODE_CONNECTOR_VGA,
+   },
},
{},
 };
-- 
Regards,

Laurent Pinchart

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

[PATCH 04/60] drm/bridge: dumb-vga-dac: Rename driver to simple-bridge

2019-07-07 Thread Laurent Pinchart
The dumb-vga-dac driver can support simple DRM bridges without being
limited to VGA DACs. Rename it to simple-bridge.

Signed-off-by: Laurent Pinchart 
---
 arch/arm/configs/davinci_all_defconfig   |  2 +-
 arch/arm/configs/integrator_defconfig|  2 +-
 arch/arm/configs/multi_v7_defconfig  |  2 +-
 arch/arm/configs/shmobile_defconfig  |  2 +-
 arch/arm/configs/sunxi_defconfig |  2 +-
 arch/arm/configs/versatile_defconfig |  2 +-
 drivers/gpu/drm/bridge/Kconfig   | 16 
 drivers/gpu/drm/bridge/Makefile  |  2 +-
 .../bridge/{dumb-vga-dac.c => simple-bridge.c}   |  2 +-
 9 files changed, 16 insertions(+), 16 deletions(-)
 rename drivers/gpu/drm/bridge/{dumb-vga-dac.c => simple-bridge.c} (99%)

diff --git a/arch/arm/configs/davinci_all_defconfig 
b/arch/arm/configs/davinci_all_defconfig
index 4a8cad4d3707..f422d34a4e4e 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -154,7 +154,7 @@ CONFIG_VIDEO_TVP514X=m
 CONFIG_VIDEO_ADV7343=m
 CONFIG_DRM=m
 CONFIG_DRM_TILCDC=m
-CONFIG_DRM_DUMB_VGA_DAC=m
+CONFIG_DRM_SIMPLE_BRIDGE=m
 CONFIG_DRM_TINYDRM=m
 CONFIG_TINYDRM_ST7586=m
 CONFIG_FB=y
diff --git a/arch/arm/configs/integrator_defconfig 
b/arch/arm/configs/integrator_defconfig
index 747550c7af2f..4d265a689655 100644
--- a/arch/arm/configs/integrator_defconfig
+++ b/arch/arm/configs/integrator_defconfig
@@ -55,7 +55,7 @@ CONFIG_SMC91X=y
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_DRM=y
-CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_MATROX=y
diff --git a/arch/arm/configs/multi_v7_defconfig 
b/arch/arm/configs/multi_v7_defconfig
index 6b748f214eae..634e029a5736 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -643,11 +643,11 @@ CONFIG_DRM_PANEL_ORISETECH_OTM8009A=m
 CONFIG_DRM_PANEL_RAYDIUM_RM68200=m
 CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
 CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
-CONFIG_DRM_DUMB_VGA_DAC=m
 CONFIG_DRM_NXP_PTN3460=m
 CONFIG_DRM_PARADE_PS8622=m
 CONFIG_DRM_SII902X=m
 CONFIG_DRM_SII9234=m
+CONFIG_DRM_SIMPLE_BRIDGE=m
 CONFIG_DRM_TOSHIBA_TC358764=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
diff --git a/arch/arm/configs/shmobile_defconfig 
b/arch/arm/configs/shmobile_defconfig
index eb02ba9ec6e6..771074e399fb 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -125,8 +125,8 @@ CONFIG_VIDEO_ADV7604=y
 CONFIG_VIDEO_ML86V7667=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
-CONFIG_DRM_DUMB_VGA_DAC=y
 CONFIG_DRM_SII902X=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_I2C_ADV7511=y
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
 CONFIG_FB_SH_MOBILE_LCDC=y
diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index df433abfcb02..19cccae84a19 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -99,7 +99,7 @@ CONFIG_RC_DEVICES=y
 CONFIG_IR_SUNXI=y
 CONFIG_DRM=y
 CONFIG_DRM_SUN4I=y
-CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_FB_SIMPLE=y
 CONFIG_SOUND=y
 CONFIG_SND=y
diff --git a/arch/arm/configs/versatile_defconfig 
b/arch/arm/configs/versatile_defconfig
index 5282324c7cef..afc44c99e7f9 100644
--- a/arch/arm/configs/versatile_defconfig
+++ b/arch/arm/configs/versatile_defconfig
@@ -59,7 +59,7 @@ CONFIG_GPIO_PL061=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_ARM_VERSATILE=y
 CONFIG_DRM_PANEL_SIMPLE=y
-CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_SIMPLE_BRIDGE=y
 CONFIG_DRM_PL111=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_BACKLIGHT_LCD_SUPPORT=y
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig
index ee777469293a..a78392e2dbb9 100644
--- a/drivers/gpu/drm/bridge/Kconfig
+++ b/drivers/gpu/drm/bridge/Kconfig
@@ -37,14 +37,6 @@ config DRM_CDNS_DSI
  Support Cadence DPI to DSI bridge. This is an internal
  bridge and is meant to be directly embedded in a SoC.
 
-config DRM_DUMB_VGA_DAC
-   tristate "Dumb VGA DAC Bridge support"
-   depends on OF
-   select DRM_KMS_HELPER
-   help
- Support for non-programmable RGB to VGA DAC bridges, such as ADI
- ADV7123, TI THS8134 and THS8135 or passive resistor ladder DACs.
-
 config DRM_LVDS_ENCODER
tristate "Transparent parallel to LVDS encoder support"
depends on OF
@@ -108,6 +100,14 @@ config DRM_SII9234
  It is an I2C driver, that detects connection of MHL bridge
  and starts encapsulation of HDMI signal.
 
+config DRM_SIMPLE_BRIDGE
+   tristate "Simple DRM bridge support"
+   depends on OF
+   select DRM_KMS_HELPER
+   help
+ Support for non-programmable DRM bridges, such as ADI ADV7123, TI
+ THS8134 and THS8135 or passive resistor ladder DACs.
+
 config DRM_THINE_THC63LVD1024
tristate "Thine THC63LVD1024 LVDS decoder bridge"
depends on OF
diff --

Re: [PATCH 02/60] video: hdmi: Change return type of hdmi_avi_infoframe_init() to void

2019-07-07 Thread Laurent Pinchart
Sorry, forgot to CC Bartlomiej on this patch.

On Sun, Jul 07, 2019 at 09:07:54PM +0300, Laurent Pinchart wrote:
> The hdmi_avi_infoframe_init() never needs to return an error, change its
> return type to void.
> 
> Signed-off-by: Laurent Pinchart 
> ---
>  drivers/gpu/drm/drm_edid.c | 5 +
>  drivers/video/hdmi.c   | 9 ++---
>  include/linux/hdmi.h   | 2 +-
>  3 files changed, 4 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
> index d2e7a5334c3f..a7d3189ea8f3 100644
> --- a/drivers/gpu/drm/drm_edid.c
> +++ b/drivers/gpu/drm/drm_edid.c
> @@ -5086,14 +5086,11 @@ drm_hdmi_avi_infoframe_from_display_mode(struct 
> hdmi_avi_infoframe *frame,
>const struct drm_display_mode *mode)
>  {
>   enum hdmi_picture_aspect picture_aspect;
> - int err;
>  
>   if (!frame || !mode)
>   return -EINVAL;
>  
> - err = hdmi_avi_infoframe_init(frame);
> - if (err < 0)
> - return err;
> + hdmi_avi_infoframe_init(frame);
>  
>   if (mode->flags & DRM_MODE_FLAG_DBLCLK)
>   frame->pixel_repeat = 1;
> diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
> index b939bc28d886..54fb7cf11d1a 100644
> --- a/drivers/video/hdmi.c
> +++ b/drivers/video/hdmi.c
> @@ -56,15 +56,13 @@ static void hdmi_infoframe_set_checksum(void *buffer, 
> size_t size)
>   *
>   * Returns 0 on success or a negative error code on failure.
>   */
> -int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
> +void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
>  {
>   memset(frame, 0, sizeof(*frame));
>  
>   frame->type = HDMI_INFOFRAME_TYPE_AVI;
>   frame->version = 2;
>   frame->length = HDMI_AVI_INFOFRAME_SIZE;
> -
> - return 0;
>  }
>  EXPORT_SYMBOL(hdmi_avi_infoframe_init);
>  
> @@ -1553,7 +1551,6 @@ static int hdmi_avi_infoframe_unpack(struct 
> hdmi_avi_infoframe *frame,
>const void *buffer, size_t size)
>  {
>   const u8 *ptr = buffer;
> - int ret;
>  
>   if (size < HDMI_INFOFRAME_SIZE(AVI))
>   return -EINVAL;
> @@ -1566,9 +1563,7 @@ static int hdmi_avi_infoframe_unpack(struct 
> hdmi_avi_infoframe *frame,
>   if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
>   return -EINVAL;
>  
> - ret = hdmi_avi_infoframe_init(frame);
> - if (ret)
> - return ret;
> + hdmi_avi_infoframe_init(frame);
>  
>   ptr += HDMI_INFOFRAME_HEADER_SIZE;
>  
> diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
> index 9918a6c910c5..9613d796cfb1 100644
> --- a/include/linux/hdmi.h
> +++ b/include/linux/hdmi.h
> @@ -207,7 +207,7 @@ struct hdmi_drm_infoframe {
>   u16 max_fall;
>  };
>  
> -int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
> +void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
>  ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void 
> *buffer,
>   size_t size);
>  ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel

-- 
Regards,

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

[PATCH 03/60] drm/bridge: dumb-vga-dac: Rename internal symbols to simple-bridge

2019-07-07 Thread Laurent Pinchart
The dumb-vga-dac driver is a simple DRM bridge driver for simple VGA
DACs that don't require configuration. Other non-VGA bridges fall in a
similar category, and would benefit from a common driver. Prepare for
this by renaming the internal symbols from dumb-vga-dac to
simple-bridge.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/bridge/dumb-vga-dac.c | 149 +-
 1 file changed, 75 insertions(+), 74 deletions(-)

diff --git a/drivers/gpu/drm/bridge/dumb-vga-dac.c 
b/drivers/gpu/drm/bridge/dumb-vga-dac.c
index d32885b906ae..d46e461ae039 100644
--- a/drivers/gpu/drm/bridge/dumb-vga-dac.c
+++ b/drivers/gpu/drm/bridge/dumb-vga-dac.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 
-struct dumb_vga {
+struct simple_bridge {
struct drm_bridge   bridge;
struct drm_connectorconnector;
 
@@ -24,28 +24,28 @@ struct dumb_vga {
struct regulator*vdd;
 };
 
-static inline struct dumb_vga *
-drm_bridge_to_dumb_vga(struct drm_bridge *bridge)
+static inline struct simple_bridge *
+drm_bridge_to_simple_bridge(struct drm_bridge *bridge)
 {
-   return container_of(bridge, struct dumb_vga, bridge);
+   return container_of(bridge, struct simple_bridge, bridge);
 }
 
-static inline struct dumb_vga *
-drm_connector_to_dumb_vga(struct drm_connector *connector)
+static inline struct simple_bridge *
+drm_connector_to_simple_bridge(struct drm_connector *connector)
 {
-   return container_of(connector, struct dumb_vga, connector);
+   return container_of(connector, struct simple_bridge, connector);
 }
 
-static int dumb_vga_get_modes(struct drm_connector *connector)
+static int simple_bridge_get_modes(struct drm_connector *connector)
 {
-   struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
+   struct simple_bridge *sbridge = 
drm_connector_to_simple_bridge(connector);
struct edid *edid;
int ret;
 
-   if (IS_ERR(vga->ddc))
+   if (IS_ERR(sbridge->ddc))
goto fallback;
 
-   edid = drm_get_edid(connector, vga->ddc);
+   edid = drm_get_edid(connector, sbridge->ddc);
if (!edid) {
DRM_INFO("EDID readout failed, falling back to standard 
modes\n");
goto fallback;
@@ -69,14 +69,14 @@ static int dumb_vga_get_modes(struct drm_connector 
*connector)
return ret;
 }
 
-static const struct drm_connector_helper_funcs dumb_vga_con_helper_funcs = {
-   .get_modes  = dumb_vga_get_modes,
+static const struct drm_connector_helper_funcs simple_bridge_con_helper_funcs 
= {
+   .get_modes  = simple_bridge_get_modes,
 };
 
 static enum drm_connector_status
-dumb_vga_connector_detect(struct drm_connector *connector, bool force)
+simple_bridge_connector_detect(struct drm_connector *connector, bool force)
 {
-   struct dumb_vga *vga = drm_connector_to_dumb_vga(connector);
+   struct simple_bridge *sbridge = 
drm_connector_to_simple_bridge(connector);
 
/*
 * Even if we have an I2C bus, we can't assume that the cable
@@ -84,14 +84,14 @@ dumb_vga_connector_detect(struct drm_connector *connector, 
bool force)
 * wire the DDC pins, or the I2C bus might not be working at
 * all.
 */
-   if (!IS_ERR(vga->ddc) && drm_probe_ddc(vga->ddc))
+   if (!IS_ERR(sbridge->ddc) && drm_probe_ddc(sbridge->ddc))
return connector_status_connected;
 
return connector_status_unknown;
 }
 
-static const struct drm_connector_funcs dumb_vga_con_funcs = {
-   .detect = dumb_vga_connector_detect,
+static const struct drm_connector_funcs simple_bridge_con_funcs = {
+   .detect = simple_bridge_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy= drm_connector_cleanup,
.reset  = drm_atomic_helper_connector_reset,
@@ -99,9 +99,9 @@ static const struct drm_connector_funcs dumb_vga_con_funcs = {
.atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
 };
 
-static int dumb_vga_attach(struct drm_bridge *bridge)
+static int simple_bridge_attach(struct drm_bridge *bridge)
 {
-   struct dumb_vga *vga = drm_bridge_to_dumb_vga(bridge);
+   struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge);
int ret;
 
if (!bridge->encoder) {
@@ -109,48 +109,49 @@ static int dumb_vga_attach(struct drm_bridge *bridge)
return -ENODEV;
}
 
-   drm_connector_helper_add(&vga->connector,
-&dumb_vga_con_helper_funcs);
-   ret = drm_connector_init(bridge->dev, &vga->connector,
-&dumb_vga_con_funcs, DRM_MODE_CONNECTOR_VGA);
+   drm_connector_helper_add(&sbridge->connector,
+&simple_bridge_con_helper_funcs);
+   ret = drm_connector_init(bridge->dev, &sbridge->connector,
+&simple_brid

[PATCH 02/60] video: hdmi: Change return type of hdmi_avi_infoframe_init() to void

2019-07-07 Thread Laurent Pinchart
The hdmi_avi_infoframe_init() never needs to return an error, change its
return type to void.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/drm_edid.c | 5 +
 drivers/video/hdmi.c   | 9 ++---
 include/linux/hdmi.h   | 2 +-
 3 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index d2e7a5334c3f..a7d3189ea8f3 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -5086,14 +5086,11 @@ drm_hdmi_avi_infoframe_from_display_mode(struct 
hdmi_avi_infoframe *frame,
 const struct drm_display_mode *mode)
 {
enum hdmi_picture_aspect picture_aspect;
-   int err;
 
if (!frame || !mode)
return -EINVAL;
 
-   err = hdmi_avi_infoframe_init(frame);
-   if (err < 0)
-   return err;
+   hdmi_avi_infoframe_init(frame);
 
if (mode->flags & DRM_MODE_FLAG_DBLCLK)
frame->pixel_repeat = 1;
diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c
index b939bc28d886..54fb7cf11d1a 100644
--- a/drivers/video/hdmi.c
+++ b/drivers/video/hdmi.c
@@ -56,15 +56,13 @@ static void hdmi_infoframe_set_checksum(void *buffer, 
size_t size)
  *
  * Returns 0 on success or a negative error code on failure.
  */
-int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
+void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
 {
memset(frame, 0, sizeof(*frame));
 
frame->type = HDMI_INFOFRAME_TYPE_AVI;
frame->version = 2;
frame->length = HDMI_AVI_INFOFRAME_SIZE;
-
-   return 0;
 }
 EXPORT_SYMBOL(hdmi_avi_infoframe_init);
 
@@ -1553,7 +1551,6 @@ static int hdmi_avi_infoframe_unpack(struct 
hdmi_avi_infoframe *frame,
 const void *buffer, size_t size)
 {
const u8 *ptr = buffer;
-   int ret;
 
if (size < HDMI_INFOFRAME_SIZE(AVI))
return -EINVAL;
@@ -1566,9 +1563,7 @@ static int hdmi_avi_infoframe_unpack(struct 
hdmi_avi_infoframe *frame,
if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
return -EINVAL;
 
-   ret = hdmi_avi_infoframe_init(frame);
-   if (ret)
-   return ret;
+   hdmi_avi_infoframe_init(frame);
 
ptr += HDMI_INFOFRAME_HEADER_SIZE;
 
diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h
index 9918a6c910c5..9613d796cfb1 100644
--- a/include/linux/hdmi.h
+++ b/include/linux/hdmi.h
@@ -207,7 +207,7 @@ struct hdmi_drm_infoframe {
u16 max_fall;
 };
 
-int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
+void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
 ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
size_t size);
 ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
-- 
Regards,

Laurent Pinchart

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

[PATCH 00/60] drm/omap: Replace custom display drivers with drm_bridge and drm_panel

2019-07-07 Thread Laurent Pinchart
Hello,

This patch series (nearly, see [1]) completes the rework of the omapdrm
driver to move to drm_bridge and drm_panel.

What a journey. This work was started more than a year ago, and this
last piece is perhaps the one that will generate the most bikeshedding
as it touches the DRM core. I'm braced for the impact, but please be
gentle :-)

Let's start with some context to understand the problem. omapdrm
contains custom drivers for external encoders, panels and connectors
(collectively referred to as display drivers). It combines them to
create output pipelines abstracted by a drm_encoder and a drm_connector,
with the ability to delegate the encoder and connector operations to the
component in the pipeline that implements them. For instance, for an
HDMI output pipeline, the hot plug detection and the EDID read can be
implemented by two different components, when they are handled by two
different devices at the hardware level.

DRM/KMS uses drm_bridge and drm_panel to abstract external encoders and
panels. The model is however simpler than what omapdrm provides, as
bridges were designed to be simple add-ons at the output of a
drm_encoder. The ability to chain bridges exists, but a bridge driver
hardcodes in its design its position in the pipeline : bridges that
expect to terminate the pipeline create a drm_connector, while bridges
that expect to be an intermediate component in the pipeline do not
create a connector. In addition to not supporting bridges that can be
either internal or a termination point in the pipeline depending on the
hardware design, implementing the drm_connector inside a bridge driver
makes it impossible to support hardware where bridge operations are
handled by different hardware components, as explained above.

The omapdrm driver has received support for drm_bridge and drm_panel,
but these issues prevented completely moving away from the omapdrm
custom display drivers. This patch series thus first reworks the
drm_bridge infrastructure to support the omapdrm use cases, and then
transitions the omapdrm driver.

The series starts by 01/60 that adds a new flag to the drm_display_info
structure to identify HDMI sinks. This is a feature needed by the OMAP4
and OMAP5 HDMI encoders, and I believe it can be useful to other HDMI
encoders as well. 02/60 is then a small drive-by cleanup.

The first sizeable change follows with the rename of the dumb-vga-dac
driver to simple-bridge (03/60 and 04/60) and support for non-VGA
bridges (05/60). This doesn't change the spirit of the driver that still
focusses on transparent bridges, but prepares it to support an analog
video amplifier. Patches 06/60 then add support for an enable GPIO, and
07/60 support for the OPA362 video amplifier itself.

The next two patches address the drm_bridge issues explained above.
Patch 08/60 makes it possible to attach to a bridge without having the
bridge create a connector. The connector is expected to be created by
the display controller driver. Patch 09/60 adds connector-related
operations to drm_bridge to make this possible.

The approach taken here is slightly intrusive as path 08/60 adds a
parameter to tbe bridge .attach() operation, and thus touches all bridge
drivers, even if the changes are very simple (as a consequence I haven't
CC'ed all the individual bridge maintainers as the CC list was too
large). Other options may be possible, what matters most to me is the
feature, not so much its implementation. Please note that I envision the
parameter to be removed down the road once all bridge drivers will be
converted to the new model (but this will likely take time, and both
models can co-exist for as long as necessary).

The next six patches make use of these new features: patches 10/60 and
11/60 add new bridge drivers for display connectors and for the TI
TPD12S015 HDMI level shifter respectively, patch 12/60 supports the new
API in the panel bridge driver, and patches 13/60 to 15/60 do the same
in the ti-tfp410 driver.

The nine patches that follow add support for six new panels, with the
related DT bindings (16/60 to 18/60) and the drm_panel drivers (19/60 to
24/60). The code originates from the corresponding omapdrm-specific
panel drivers (which explains why only three DT patches are needed as
most of the bindings are already present).

Patch 25/60 is possibly the most remarkable one in the series, with the
drm_bridge operations extension, as it provides a helper for display
controller drivers to construct a drm_connector entirerly backed by a
chain of bridges. This offsets the complexity of the additional bridge
operations by handling it all in a single place. An example usage for
omapdrm can be found in patch 43/60. Don't let its diffstat mislead you,
usage of the helper would remove lots of code if it wasn't for the fact
that the legacy implementation still has to be kept for the DSI panel
(see [1]). Down the road this helper and the new operation paradigm
should remove code from both display controller an

[PATCH 01/60] drm/edid: Add flag to drm_display_info to identify HDMI sinks

2019-07-07 Thread Laurent Pinchart
The drm_display_info structure contains many fields related to HDMI
sinks, but none that identifies if a sink compliant with CEA-861 (EDID)
shall be treated as an HDMI sink or a DVI sink. Add such a flag, and
populate it according to section 8.3.3 ("DVI/HDMI Device
Discrimination") of the HDMI v1.3 specification.

Signed-off-by: Laurent Pinchart 
---
 drivers/gpu/drm/drm_edid.c  | 3 +++
 include/drm/drm_connector.h | 5 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 82a4ceed3fcf..d2e7a5334c3f 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -4559,6 +4559,8 @@ drm_parse_hdmi_vsdb_video(struct drm_connector 
*connector, const u8 *db)
struct drm_display_info *info = &connector->display_info;
u8 len = cea_db_payload_len(db);
 
+   info->is_hdmi = true;
+
if (len >= 6)
info->dvi_dual = db[6] & 1;
if (len >= 7)
@@ -4627,6 +4629,7 @@ drm_reset_display_info(struct drm_connector *connector)
info->cea_rev = 0;
info->max_tmds_clock = 0;
info->dvi_dual = false;
+   info->is_hdmi = false;
info->has_hdmi_infoframe = false;
info->rgb_quant_range_selectable = false;
memset(&info->hdmi, 0, sizeof(info->hdmi));
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ca745d9feaf5..e80ca0d149e5 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -426,6 +426,11 @@ struct drm_display_info {
 */
bool dvi_dual;
 
+   /**
+* @is_hdmi: True if the sink is an HDMI device.
+*/
+   bool is_hdmi;
+
/**
 * @has_hdmi_infoframe: Does the sink support the HDMI infoframe?
 */
-- 
Regards,

Laurent Pinchart

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

[Bug 111077] link_shader and deserialize_glsl_program suddenly consume huge amount of RAM

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=111077

--- Comment #2 from rol...@rptd.ch  ---
I don't know what other information can help so I collected information about
the state that worked (before the update) and the state that does not work
anymore (after the update):

before update (working state):
media-libs/mesa-18.2.8
- x11-drivers/xf86-video-amdgpu-18.1.0
- x11-libs/libdrm-2.4.96
- sys-devel/llvm-6.0.1
- sys-devel/llvmgold-6
- sys-devel/llvm-common-6.0.1

after update (memory consumption bug present):
- media-libs/mesa-18.3.6 (I also tested media-libs/mesa-19.0.6 and
  media-libs/mesa-19.1.1 with same result)
- x11-drivers/xf86-video-amdgpu-19.0.1
- x11-libs/libdrm-2.4.97
- sys-devel/llvm-7.1.0
- sys-devel/llvmgold-7
- sys-devel/llvm-common-7.1.0

Is there anything else that can help?

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [Bug 109955] amdgpu [RX Vega 64] system freeze while gaming

2019-07-07 Thread sylvain . bertrand
On Sun, Jul 07, 2019 at 05:31:34AM +, bugzilla-dae...@freedesktop.org wrote:
> 2. Valve sponsored an interesting project that removes dependency of AMD Mesa
> from LLVM. And instead uses ACO. Valve made this available for Arch based
> systems via AUR, and Ubuntu based system via PPA. If you want to test it, you
> can check the posts below. I am going to test this myself on both Arch and
> Ubuntu. 
> https://steamcommunity.com/games/221410/announcements/detail/1602634609636894200
> https://steamcommunity.com/app/221410/discussions/0/1640915206474070669/

Huho!

Cons:
- it's c++
- only GFX8 and GFX9 (I have GFX6 :( )
- some nasty python scripts (there are tons in mesa)

Pros:
- it's several orders of magnitude less brain f*cked than llvm.
- it is actual working code which does disjoint mesa from llvm.

conclusion:
- for GFX8 and GFX9, it's less worse than llvm.
- I was asking for a clean GCN ABI definition document from shaders
  perspective, maybe this code will help to write one (or it is an AMD
  confidential document??).

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

[Bug 109955] amdgpu [RX Vega 64] system freeze while gaming

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109955

--- Comment #38 from Sylvain BERTRAND  ---
On Sun, Jul 07, 2019 at 05:31:34AM +, bugzilla-dae...@freedesktop.org
wrote:
> 2. Valve sponsored an interesting project that removes dependency of AMD Mesa
> from LLVM. And instead uses ACO. Valve made this available for Arch based
> systems via AUR, and Ubuntu based system via PPA. If you want to test it, you
> can check the posts below. I am going to test this myself on both Arch and
> Ubuntu. 
> https://steamcommunity.com/games/221410/announcements/detail/1602634609636894200
> https://steamcommunity.com/app/221410/discussions/0/1640915206474070669/

Huho!

Cons:
- it's c++
- only GFX8 and GFX9 (I have GFX6 :( )
- some nasty python scripts (there are tons in mesa)

Pros:
- it's several orders of magnitude less brain f*cked than llvm.
- it is actual working code which does disjoint mesa from llvm.

conclusion:
- for GFX8 and GFX9, it's less worse than llvm.
- I was asking for a clean GCN ABI definition document from shaders
  perspective, maybe this code will help to write one (or it is an AMD
  confidential document??).

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 3/6] drm/fb-helper: Instanciate shadow FB if configured in device's mode_config

2019-07-07 Thread Thomas Zimmermann
Hi

Am 07.07.19 um 16:37 schrieb Noralf Trønnes:
> 
> 
> Den 05.07.2019 11.26, skrev Thomas Zimmermann:
>> Generic framebuffer emulation uses a shadow buffer for framebuffers with
>> dirty() function. If drivers want to use the shadow FB without such a
>> function, they can now set prefer_shadow or prefer_shadow_fbdev in their
>> mode_config structures. The former flag is exported to userspace, the latter
>> flag is fbdev-only.
>>
>> Signed-off-by: Thomas Zimmermann 
>> ---
>>  drivers/gpu/drm/drm_fb_helper.c | 19 ++-
>>  include/drm/drm_mode_config.h   |  5 +
>>  2 files changed, 19 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_fb_helper.c 
>> b/drivers/gpu/drm/drm_fb_helper.c
>> index 7ba6a0255821..56ef169e1814 100644
>> --- a/drivers/gpu/drm/drm_fb_helper.c
>> +++ b/drivers/gpu/drm/drm_fb_helper.c
>> @@ -421,7 +421,9 @@ static void drm_fb_helper_dirty_work(struct work_struct 
>> *work)
>>  return;
>>  drm_fb_helper_dirty_blit_real(helper, &clip_copy);
>>  }
>> -helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
>> +if (helper->fb->funcs->dirty)
>> +helper->fb->funcs->dirty(helper->fb, NULL, 0, 0,
>> + &clip_copy, 1);
>>  
>>  if (helper->buffer)
>>  drm_client_buffer_vunmap(helper->buffer);
>> @@ -620,9 +622,6 @@ static void drm_fb_helper_dirty(struct fb_info *info, 
>> u32 x, u32 y,
>>  struct drm_clip_rect *clip = &helper->dirty_clip;
>>  unsigned long flags;
>>  
>> -if (!helper->fb->funcs->dirty)
>> -return;
> 
> drm_fb_helper_dirty() is called unconditionally by
> drm_fb_helper_sys_imageblit() et al, so we need check with
> drm_fbdev_use_shadow_fb() here.
> 
>> -
>>  spin_lock_irqsave(&helper->dirty_lock, flags);
>>  clip->x1 = min_t(u32, clip->x1, x);
>>  clip->y1 = min_t(u32, clip->y1, y);
>> @@ -2166,6 +2165,16 @@ static struct fb_deferred_io drm_fbdev_defio = {
>>  .deferred_io= drm_fb_helper_deferred_io,
>>  };
>>  
>> +static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
>> +{
>> +struct drm_device *dev = fb_helper->dev;
>> +struct drm_framebuffer *fb = fb_helper->fb;
>> +
>> +return dev->mode_config.prefer_shadow_fbdev |
>> +   dev->mode_config.prefer_shadow |
> 
> Use logical OR here
> 
>> +   !!fb->funcs->dirty;
> 
> and you can drop the the double NOT here.
> 
>> +}
>> +
>>  /**
>>   * drm_fb_helper_generic_probe - Generic fbdev emulation probe helper
>>   * @fb_helper: fbdev helper structure
>> @@ -2213,7 +,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper 
>> *fb_helper,
>>  
>>  drm_fb_helper_fill_info(fbi, fb_helper, sizes);
>>  
>> -if (fb->funcs->dirty) {
>> +if (drm_fbdev_use_shadow_fb(fb_helper)) {
>>  struct fb_ops *fbops;
>>  void *shadow;
>>  
>> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
>> index 759d462d028b..e1c751aca353 100644
>> --- a/include/drm/drm_mode_config.h
>> +++ b/include/drm/drm_mode_config.h
>> @@ -347,6 +347,8 @@ struct drm_mode_config_funcs {
>>   * @output_poll_work: delayed work for polling in process context
>>   * @preferred_depth: preferred RBG pixel depth, used by fb helpers
>>   * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
>> + * @prefer_shadow_fbdev: hint to framebuffer emulation to prefer shadow-fb \
>> +rendering
> 
> It's preferred to have the doc together with the struct member.

I just tried to follow the file's existing style, but OK, I don't mind.

> it's less likely to be forgotten when things change. And we don't use
> line cont. when the doc line is too long. Just continue on the next line
> after an asterix.
> 
>>   * @cursor_width: hint to userspace for max cursor width
>>   * @cursor_height: hint to userspace for max cursor height
>>   * @helper_private: mid-layer private data
>> @@ -852,6 +854,9 @@ struct drm_mode_config {
>>  /* dumb ioctl parameters */
>>  uint32_t preferred_depth, prefer_shadow;
>>  
>> +/* fbdev parameters */
> 
> No need for this comment.
> 
> Doc can look like this, I've done s/framebuffer/fbdev/:
>   /**
>* @prefer_shadow_fbdev:
>*
>* Hint to fbdev emulation to prefer shadow-fb rendering.
>*/
> 
>> +uint32_t prefer_shadow_fbdev;
> 
> Use bool here.
> 
> With that:
> 
> Reviewed-by: Noralf Trønnes 
> 
> I have tested this on 2 drivers that use generic fbdev: vc4 (no shadow
> buf) and mi0283qt which has a dirty callback.
> 
> Tested-by: Noralf Trønnes 

Thanks for reviewing and testing the patches.

Best regards
Thomas

> 
>> +
>>  /**
>>   * @quirk_addfb_prefer_xbgr_30bpp:
>>   *
>>
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/li

Re: [PATCH v2 3/6] drm/fb-helper: Instanciate shadow FB if configured in device's mode_config

2019-07-07 Thread Noralf Trønnes


Den 05.07.2019 11.26, skrev Thomas Zimmermann:
> Generic framebuffer emulation uses a shadow buffer for framebuffers with
> dirty() function. If drivers want to use the shadow FB without such a
> function, they can now set prefer_shadow or prefer_shadow_fbdev in their
> mode_config structures. The former flag is exported to userspace, the latter
> flag is fbdev-only.
> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/drm_fb_helper.c | 19 ++-
>  include/drm/drm_mode_config.h   |  5 +
>  2 files changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 7ba6a0255821..56ef169e1814 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -421,7 +421,9 @@ static void drm_fb_helper_dirty_work(struct work_struct 
> *work)
>   return;
>   drm_fb_helper_dirty_blit_real(helper, &clip_copy);
>   }
> - helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
> + if (helper->fb->funcs->dirty)
> + helper->fb->funcs->dirty(helper->fb, NULL, 0, 0,
> +  &clip_copy, 1);
>  
>   if (helper->buffer)
>   drm_client_buffer_vunmap(helper->buffer);
> @@ -620,9 +622,6 @@ static void drm_fb_helper_dirty(struct fb_info *info, u32 
> x, u32 y,
>   struct drm_clip_rect *clip = &helper->dirty_clip;
>   unsigned long flags;
>  
> - if (!helper->fb->funcs->dirty)
> - return;

drm_fb_helper_dirty() is called unconditionally by
drm_fb_helper_sys_imageblit() et al, so we need check with
drm_fbdev_use_shadow_fb() here.

> -
>   spin_lock_irqsave(&helper->dirty_lock, flags);
>   clip->x1 = min_t(u32, clip->x1, x);
>   clip->y1 = min_t(u32, clip->y1, y);
> @@ -2166,6 +2165,16 @@ static struct fb_deferred_io drm_fbdev_defio = {
>   .deferred_io= drm_fb_helper_deferred_io,
>  };
>  
> +static bool drm_fbdev_use_shadow_fb(struct drm_fb_helper *fb_helper)
> +{
> + struct drm_device *dev = fb_helper->dev;
> + struct drm_framebuffer *fb = fb_helper->fb;
> +
> + return dev->mode_config.prefer_shadow_fbdev |
> +dev->mode_config.prefer_shadow |

Use logical OR here

> +!!fb->funcs->dirty;

and you can drop the the double NOT here.

> +}
> +
>  /**
>   * drm_fb_helper_generic_probe - Generic fbdev emulation probe helper
>   * @fb_helper: fbdev helper structure
> @@ -2213,7 +,7 @@ int drm_fb_helper_generic_probe(struct drm_fb_helper 
> *fb_helper,
>  
>   drm_fb_helper_fill_info(fbi, fb_helper, sizes);
>  
> - if (fb->funcs->dirty) {
> + if (drm_fbdev_use_shadow_fb(fb_helper)) {
>   struct fb_ops *fbops;
>   void *shadow;
>  
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 759d462d028b..e1c751aca353 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -347,6 +347,8 @@ struct drm_mode_config_funcs {
>   * @output_poll_work: delayed work for polling in process context
>   * @preferred_depth: preferred RBG pixel depth, used by fb helpers
>   * @prefer_shadow: hint to userspace to prefer shadow-fb rendering
> + * @prefer_shadow_fbdev: hint to framebuffer emulation to prefer shadow-fb \
> + rendering

It's preferred to have the doc together with the struct member. This way
it's less likely to be forgotten when things change. And we don't use
line cont. when the doc line is too long. Just continue on the next line
after an asterix.

>   * @cursor_width: hint to userspace for max cursor width
>   * @cursor_height: hint to userspace for max cursor height
>   * @helper_private: mid-layer private data
> @@ -852,6 +854,9 @@ struct drm_mode_config {
>   /* dumb ioctl parameters */
>   uint32_t preferred_depth, prefer_shadow;
>  
> + /* fbdev parameters */

No need for this comment.

Doc can look like this, I've done s/framebuffer/fbdev/:
/**
 * @prefer_shadow_fbdev:
 *
 * Hint to fbdev emulation to prefer shadow-fb rendering.
 */

> + uint32_t prefer_shadow_fbdev;

Use bool here.

With that:

Reviewed-by: Noralf Trønnes 

I have tested this on 2 drivers that use generic fbdev: vc4 (no shadow
buf) and mi0283qt which has a dirty callback.

Tested-by: Noralf Trønnes 

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

Re: [PATCH v2 2/6] drm/fb-helper: Map DRM client buffer only when required

2019-07-07 Thread Noralf Trønnes


Den 05.07.2019 11.26, skrev Thomas Zimmermann:
> This patch changes DRM clients to not map the buffer by default. The
> buffer, like any buffer object, should be mapped and unmapped when
> needed.
> 
> An unmapped buffer object can be evicted to system memory and does
> not consume video ram until displayed. This allows to use generic fbdev
> emulation with drivers for low-memory devices, such as ast and mgag200.
> 
> This change affects the generic framebuffer console. HW-based consoles
> map their console buffer once and keep it mapped. Userspace can mmap this
> buffer into its address space. The shadow-buffered framebuffer console
> only needs the buffer object to be mapped during updates. While not being
> updated from the shadow buffer, the buffer object can remain unmapped.
> Userspace will always mmap the shadow buffer.
> 
> v2:
>   * change DRM client to not map buffer by default
>   * manually map client buffer for fbdev with HW framebuffer
> 
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Noralf Trønnes 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v2 1/6] drm/client: Support unmapping of DRM client buffers

2019-07-07 Thread Noralf Trønnes


Den 05.07.2019 11.26, skrev Thomas Zimmermann:
> DRM clients, such as the fbdev emulation, have their buffer objects
> mapped by default. Mapping a buffer implicitly prevents its relocation.
> Hence, the buffer may permanently consume video memory while it's
> allocated. This is a problem for drivers of low-memory devices, such as
> ast, mgag200 or older framebuffer hardware, which will then not have
> enough memory to display other content (e.g., X11).
> 
> This patch introduces drm_client_buffer_vmap() and _vunmap(). Internal
> DRM clients can use these functions to unmap and remap buffer objects
> as needed.
> 
> There's no reference counting for vmap operations. Callers are expected
> to either keep buffers mapped (as it is now), or call vmap and vunmap
> in pairs around code that accesses the mapped memory.
> 
> v2:
>   * remove several duplicated NULL-pointer checks
> 
> Signed-off-by: Thomas Zimmermann 
> ---
>  drivers/gpu/drm/drm_client.c | 67 ++--
>  include/drm/drm_client.h |  3 ++
>  2 files changed, 60 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
> index 410572f14257..66d8d645ac79 100644
> --- a/drivers/gpu/drm/drm_client.c
> +++ b/drivers/gpu/drm/drm_client.c
> @@ -281,6 +281,43 @@ drm_client_buffer_create(struct drm_client_dev *client, 
> u32 width, u32 height, u
>  
>   buffer->gem = obj;
>  
> + vaddr = drm_client_buffer_vmap(buffer);
> + if (IS_ERR(vaddr)) {
> + ret = PTR_ERR(vaddr);
> + goto err_delete;
> + }
> +
> + return buffer;
> +
> +err_delete:
> + drm_client_buffer_delete(buffer);
> +
> + return ERR_PTR(ret);
> +}
> +
> +/**
> + * drm_client_buffer_vmap - Map DRM client buffer into address space
> + * @buffer: DRM client buffer
> + *
> + * This function maps a client buffer into kernel address space. If the
> + * buffer is already mapped, it returns the mapping's address.
> + *
> + * Client buffer mappings are not ref'counted. Each call to
> + * drm_client_buffer_vmap() should be followed by a call to
> + * drm_client_buffer_vunmap(); or the client buffer should be mapped
> + * throughout its lifetime. The latter is the default.
> + *
> + * Returns:
> + *   The mapped memory's address
> + */
> +void *
> +drm_client_buffer_vmap(struct drm_client_buffer *buffer)

I prefer to have this on one line.

> +{
> + void *vaddr;
> +
> + if (buffer->vaddr)
> + return buffer->vaddr;
> +
>   /*
>* FIXME: The dependency on GEM here isn't required, we could
>* convert the driver handle to a dma-buf instead and use the
> @@ -289,21 +326,31 @@ drm_client_buffer_create(struct drm_client_dev *client, 
> u32 width, u32 height, u
>* fd_install step out of the driver backend hooks, to make that
>* final step optional for internal users.
>*/
> - vaddr = drm_gem_vmap(obj);
> - if (IS_ERR(vaddr)) {
> - ret = PTR_ERR(vaddr);
> - goto err_delete;
> - }
> + vaddr = drm_gem_vmap(buffer->gem);
> + if (IS_ERR(vaddr))
> + return vaddr;
>  
>   buffer->vaddr = vaddr;
>  
> - return buffer;
> -
> -err_delete:
> - drm_client_buffer_delete(buffer);
> + return vaddr;
> +}
> +EXPORT_SYMBOL(drm_client_buffer_vmap);
>  
> - return ERR_PTR(ret);
> +/**
> + * drm_client_buffer_vunmap - Unmap DRM client buffer
> + * @buffer: DRM client buffer
> + *
> + * This function removes a client buffer's memory mmapping. This

s/mmapping/mapping/

> + * function is only required by clients that manage their buffers
> + * by themselves. By default, DRM client buffers are mapped throughout
> + * their entire lifetime.
> + */
> +void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
> +{
> + drm_gem_vunmap(buffer->gem, buffer->vaddr);
> + buffer->vaddr = NULL;
>  }
> +EXPORT_SYMBOL(drm_client_buffer_vunmap);
>  
>  static void drm_client_buffer_rmfb(struct drm_client_buffer *buffer)
>  {
> diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
> index 72d51d1e9dd9..e1db1d9da0bf 100644
> --- a/include/drm/drm_client.h
> +++ b/include/drm/drm_client.h
> @@ -149,6 +149,9 @@ struct drm_client_buffer {
>  struct drm_client_buffer *
>  drm_client_framebuffer_create(struct drm_client_dev *client, u32 width, u32 
> height, u32 format);
>  void drm_client_framebuffer_delete(struct drm_client_buffer *buffer);
> +void *
> +drm_client_buffer_vmap(struct drm_client_buffer *buffer);

Prefer to have this on one line.

Reviewed-by: Noralf Trønnes 

> +void drm_client_buffer_vunmap(struct drm_client_buffer *buffer);
>  
>  int drm_client_modeset_create(struct drm_client_dev *client);
>  void drm_client_modeset_free(struct drm_client_dev *client);
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[Bug 109955] amdgpu [RX Vega 64] system freeze while gaming

2019-07-07 Thread bugzilla-daemon
https://bugs.freedesktop.org/show_bug.cgi?id=109955

--- Comment #37 from shadow.archem...@gmail.com ---
(In reply to Mauro Gaspari from comment #36)
> (In reply to shadow.archemage from comment #35) 
> I am not an expert, but I am quite sure shaders have a big part in this. If
> you can, disable shader caching.
> There are a few tests you can do:
> 1. Did you try with the kernel parameters I posted above? I always ran all
> the parameters together. GPU+CPU and at the time, I did not have crashes for
> weeks on my Vega64. I am using a RadeonVII now and it seems those parameters
> are not needed.

I tried the kernel parameters above, and the game still crashed for me.

> 2. Valve sponsored an interesting project that removes dependency of AMD
> Mesa from LLVM. And instead uses ACO. Valve made this available for Arch
> based systems via AUR, and Ubuntu based system via PPA. If you want to test
> it, you can check the posts below. I am going to test this myself on both
> Arch and Ubuntu. 
> https://steamcommunity.com/games/221410/announcements/detail/
> 1602634609636894200
> https://steamcommunity.com/app/221410/discussions/0/1640915206474070669/

Will check this out, but will also keep an eye on this thread about the results
of your tests. Thanks!

-- 
You are receiving this mail because:
You are the assignee for the bug.___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel