[PATCH v3 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-27 Thread Tony Lindgren
Commit 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
stopped console from updating for command mode displays because there is
no damage handling in fb_sys_write() unlike we had earlier in
drm_fb_helper_sys_write().

Let's fix the issue by adding FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS and
FB_DMAMEM_HELPERS_DEFERRED as suggested by Thomas. We cannot use the
FB_DEFAULT_DEFERRED_OPS as fb_deferred_io_mmap() won't work properly
for write-combine.

Fixes: 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
Suggested-by: Thomas Zimmermann 
Reviewed-by: Thomas Zimmermann 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/Kconfig  |  2 +-
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 28 ++--
 drivers/video/fbdev/core/Kconfig |  6 ++
 include/linux/fb.h   |  4 
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,7 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
-   select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION
+   select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -78,11 +82,9 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo 
*var,
 
 static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
-   struct drm_fb_helper *helper = info->par;
-   struct drm_framebuffer *fb = helper->fb;
-   struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
+   vma->vm_page_prot = 
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
-   return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
+   return fb_deferred_io_mmap(info, vma);
 }
 
 static void omap_fbdev_fb_destroy(struct fb_info *info)
@@ -94,6 +96,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
DBG();
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(helper);
 
omap_gem_unpin(bo);
@@ -104,15 +107,19 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
kfree(fbdev);
 }
 
+/*
+ * For now, we cannot use FB_DEFAULT_DEFERRED_OPS and fb_deferred_io_mmap()
+ * because we use write-combine.
+ */
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev),
.fb_ioctl   = drm_fb_helper_ioctl,
.fb_mmap= omap_fbdev_fb_mmap,
.fb_destroy = omap_fbdev_fb_destroy,
@@ -213,6 +220,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = dma_addr;
fbi->fix.smem_len = bo->size;
 
+   /* deferred I/O */
+   helper->fbdefio.delay = HZ / 20;
+   helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+   fbi->fbdefio = >fbdefio;
+   ret = fb_deferred_io_init(fbi);
+   if (ret)
+   goto fail;
+
/* if we have DMM, then we can use it for scrolling by just
 * shuffling pages around in DMM rather than doing sw blit.
 */
diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig
--- a/drivers/video/fbdev/core/Kconfig
+++ b/drivers/video/fbdev/core/Kconfig
@@ -144,6 +144,12 @@ config FB_DMAMEM_HELPERS
select FB_SYS_IMAGEBLIT
select FB_SYSMEM_FOPS
 
+config FB_DMAMEM_HELPERS_DEFERRED
+   bool
+   depends on FB_CORE
+   select FB_DEFERRED_IO
+   select FB_DMAMEM_HELPERS
+
 config FB_IOMEM_FOPS
tristate
depends on FB_CORE
diff --git a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -686,6 +686,10 @@ extern int fb_deferred_io_fsync(struct file *file, loff_t 
start,
__FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, sys) \
__FB_GEN_DE

[PATCH v3 1/2] drm/omapdrm: Fix console by implementing fb_dirty

2024-02-27 Thread Tony Lindgren
The framebuffer console stopped updating with commit f231af498c29
("drm/fb-helper: Disconnect damage worker from update logic").

Let's fix the issue by implementing fb_dirty similar to what was done
with commit 039a72ce7e57 ("drm/i915/fbdev: Implement fb_dirty for intel
custom fb helper").

Fixes: f231af498c29 ("drm/fb-helper: Disconnect damage worker from update 
logic")
Reviewed-by: Thomas Zimmermann 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -238,8 +238,20 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
return ret;
 }
 
+static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect 
*clip)
+{
+   if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+   return 0;
+
+   if (helper->fb->funcs->dirty)
+   return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 
1);
+
+   return 0;
+}
+
 static const struct drm_fb_helper_funcs omap_fb_helper_funcs = {
.fb_probe = omap_fbdev_create,
+   .fb_dirty = omap_fbdev_dirty,
 };
 
 static struct drm_fb_helper *get_fb(struct fb_info *fbi)
-- 
2.43.1


[PATCH v3 0/2] Fixes for omapdrm console

2024-02-27 Thread Tony Lindgren
Here are two fixes for omapdrm for missing drm_framebuffer_funcs.dirty
that needs to be paired with omap_framebuffer_dirty(), and to add
FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS so things behave as earlier with
drm_fb_helper_sys_write(). Without these fixes, the console won't update
for the command mode displays. And likely mmap() using writes can miss
updates as noted by Thomas.

Regards,

Tony

Changes since v2:
- Fix cache issue noted by Tomi using custom omap_fbdev_fb_mmap() as
  suggested by Thomas

- Add FB_DMAMEM_HELPERS_DEFERRED Kconfig option and use it for omapdrm
  as noted by Thomas

Changes since v1:

- Add FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS to use with
  FB_DEFAULT_DEFERRED_OPS as suggested by Thomas

Tony Lindgren (2):
  drm/omapdrm: Fix console by implementing fb_dirty
  drm/omapdrm: Fix console with deferred ops

 drivers/gpu/drm/omapdrm/Kconfig  |  2 +-
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 40 +++-
 drivers/video/fbdev/core/Kconfig |  6 +
 include/linux/fb.h   |  4 +++
 4 files changed, 45 insertions(+), 7 deletions(-)

-- 
2.43.1


Re: [PATCH v2 0/2] Fixes for omapdrm console

2024-02-27 Thread Tony Lindgren
* Tony Lindgren  [240227 11:47]:
> * Thomas Zimmermann  [240227 09:16]:
> > I just realized the fb_deferred_io_mmap() is already exported. So please use
> > it instead of duplicating the code in omapdrm.
> > 
> > [1] 
> > https://elixir.bootlin.com/linux/v6.7/source/drivers/video/fbdev/core/fb_defio.c#L237
> 
> Yeah I have now:
> 
> static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct 
> *vma)
> {
>   vma->vm_page_prot = 
> pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
> 
>   return fb_deferred_io_mmap(info, vma);
> }
> 
> > I also noticed that omapdrm does not yet select the correct Kconfig symbols.
> > That can be fixed by
> > 
> >  1) creating Kconfig FB_DMAMEM_HELPERS_DEFERRED that are similar to their
> > SYSMEM equivalent at [2]. The tokens should look like this
> > 
> > configFB_DMAMEM_HELPERS_DEFERRED  
> > <https://elixir.bootlin.com/linux/latest/K/ident/CONFIG_FB_SYSMEM_HELPERS_DEFERRED>
> > bool
> > depends onFB_CORE  
> > <https://elixir.bootlin.com/linux/latest/K/ident/CONFIG_FB_CORE>
> > selectFB_DEFERRED_IO  
> > <https://elixir.bootlin.com/linux/latest/K/ident/CONFIG_FB_DEFERRED_IO>
> > selectFB_DMAMEM_HELPERS  
> > <https://elixir.bootlin.com/linux/latest/K/ident/CONFIG_FB_SYSMEM_HELPERS>
> 
> OK
> 
> >   2) and selecting it instead of FB_DMAMEM_HELPERS under omapdrm's Kconfig
> > symbol.
> 
> OK

So here's what I have now, does that look OK?

Regards,

Tony

8< -
diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,7 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
-   select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION
+   select FB_DMAMEM_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -78,11 +82,9 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo 
*var,
 
 static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
-   struct drm_fb_helper *helper = info->par;
-   struct drm_framebuffer *fb = helper->fb;
-   struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
+   vma->vm_page_prot = 
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
-   return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
+   return fb_deferred_io_mmap(info, vma);
 }
 
 static void omap_fbdev_fb_destroy(struct fb_info *info)
@@ -94,6 +96,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
DBG();
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(helper);
 
omap_gem_unpin(bo);
@@ -104,15 +107,19 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
kfree(fbdev);
 }
 
+/*
+ * For now, we cannot use FB_DEFAULT_DEFERRED_OPS and fb_deferred_io_mmap()
+ * because we use write-combine.
+ */
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev),
.fb_ioctl   = drm_fb_helper_ioctl,
.fb_mmap= omap_fbdev_fb_mmap,
.fb_destroy = omap_fbdev_fb_destroy,
@@ -213,6 +220,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = dma_addr;
fbi->fix.smem_len = bo->size;
 
+   /* deferred I/O */
+   helper->fbdefio.delay = HZ / 20;
+   helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+   fbi->fbdefio = >fbdefio;
+   ret = fb_deferred_io_init(fbi);
+   if (ret)
+   goto fail;
+
/* if we have DMM, then we can use it for scrolling by just
 * shuffling pages around in DMM rather than doing sw blit.

Re: [PATCH v2 0/2] Fixes for omapdrm console

2024-02-27 Thread Tony Lindgren
* Thomas Zimmermann  [240227 09:16]:
> I just realized the fb_deferred_io_mmap() is already exported. So please use
> it instead of duplicating the code in omapdrm.
> 
> [1] 
> https://elixir.bootlin.com/linux/v6.7/source/drivers/video/fbdev/core/fb_defio.c#L237

Yeah I have now:

static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
vma->vm_page_prot = 
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));

return fb_deferred_io_mmap(info, vma);
}

> I also noticed that omapdrm does not yet select the correct Kconfig symbols.
> That can be fixed by
> 
>  1) creating Kconfig FB_DMAMEM_HELPERS_DEFERRED that are similar to their
> SYSMEM equivalent at [2]. The tokens should look like this
> 
> configFB_DMAMEM_HELPERS_DEFERRED  
> 
> bool
> depends onFB_CORE  
> 
> selectFB_DEFERRED_IO  
> 
> selectFB_DMAMEM_HELPERS  
> 

OK

>   2) and selecting it instead of FB_DMAMEM_HELPERS under omapdrm's Kconfig
> symbol.

OK

Regards,

Tony

> [2] 
> https://elixir.bootlin.com/linux/latest/source/drivers/video/fbdev/core/Kconfig#L147


Re: [PATCH v2 0/2] Fixes for omapdrm console

2024-02-27 Thread Tony Lindgren
* Thomas Zimmermann  [240227 07:56]:
> Am 27.02.24 um 08:06 schrieb Tony Lindgren:
> > * Tony Lindgren  [240226 13:26]:
> > > * Thomas Zimmermann  [240226 09:10]:
> > > > Am 26.02.24 um 10:01 schrieb Tomi Valkeinen:
> > > > > On 26/02/2024 10:26, Tomi Valkeinen wrote:
> > > > > > How is it broken? I don't usually use the console (or fbdev) but
> > > > > > enabling it now, it seems to work fine for me, on DRA76 EVM with
> > > > > > HDMI output.
> > > > Omapdrm implements drm_framebuffer_funcs.dirty 
> > > > withomap_framebuffer_dirty().
> > > > AFAIK DRM semantics requires to run the dirty helper after writing to 
> > > > the
> > > > framebuffer's memory. Userspace does this via the DIRTYFB ioctl. [1] 
> > > > But (at
> > > > least) for correctness the console needs to do the same.
> > > > 
> > > > [1] 
> > > > https://elixir.bootlin.com/linux/v6.7.6/source/drivers/gpu/drm/drm_ioctl.c#L679
> > > Yes I noticed console not updating and bisected it down to the two
> > > commits listed. I did the bisect on a droid4 though with command mode
> > > LCD. I did not test with HDMI, will give that a try too.
> > I can reproduce the cache issue with Tomi's omapfb-tests [2] below:
> > 
> > while true;
> >do dd if=/dev/urandom of=/dev/fb0
> >~/src/omapfb-tests/test
> >sleep 1
> > done
> > 
> > That produces short random data stripes on the test image.
> > 
> > > > > After applying your patches, I see a lot of cache-related artifacts on
> > > > > the screen when updating the fb.
> > > > I guess we might need a dma-specific mmap helper to make this work
> > > > correctly.
> > Comparing the difference between drm_gem_mmap_obj() and
> > fb_deferred_io_mmap(), the following test patch makes the cache issue
> > go away for me. Not sure if this can be set based on some flag, or if
> > we need a separate fb_deferred_io_wc_mmap() or something like that?
> > 
> > [2] https://github.com/tomba/omapfb-tests
> > 
> > 8< 
> > diff --git a/drivers/video/fbdev/core/fb_defio.c 
> > b/drivers/video/fbdev/core/fb_defio.c
> > --- a/drivers/video/fbdev/core/fb_defio.c
> > +++ b/drivers/video/fbdev/core/fb_defio.c
> > @@ -224,6 +224,7 @@ static const struct address_space_operations 
> > fb_deferred_io_aops = {
> >   int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
> >   {
> > vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
> > +   vma->vm_page_prot = 
> > pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
> 
> Great, that's exactly what I had in mind!

OK :)

> My proposal is to add this mmap function directly to omapdrm. I'll later
> take care of integrating this into the overall framework. I have a few other
> ideas in mind that are related to this issue. Ok?

OK that sounds good to me, I'll post v3 set of patches.

Regards,

Tony


Re: [PATCH v2 0/2] Fixes for omapdrm console

2024-02-26 Thread Tony Lindgren
* Tony Lindgren  [240226 13:26]:
> * Thomas Zimmermann  [240226 09:10]:
> > Am 26.02.24 um 10:01 schrieb Tomi Valkeinen:
> > > On 26/02/2024 10:26, Tomi Valkeinen wrote:
> > > > How is it broken? I don't usually use the console (or fbdev) but
> > > > enabling it now, it seems to work fine for me, on DRA76 EVM with
> > > > HDMI output.
> > 
> > Omapdrm implements drm_framebuffer_funcs.dirty withomap_framebuffer_dirty().
> > AFAIK DRM semantics requires to run the dirty helper after writing to the
> > framebuffer's memory. Userspace does this via the DIRTYFB ioctl. [1] But (at
> > least) for correctness the console needs to do the same.
> > 
> > [1] 
> > https://elixir.bootlin.com/linux/v6.7.6/source/drivers/gpu/drm/drm_ioctl.c#L679
> 
> Yes I noticed console not updating and bisected it down to the two
> commits listed. I did the bisect on a droid4 though with command mode
> LCD. I did not test with HDMI, will give that a try too.

I can reproduce the cache issue with Tomi's omapfb-tests [2] below:

while true;
  do dd if=/dev/urandom of=/dev/fb0
  ~/src/omapfb-tests/test
  sleep 1
done

That produces short random data stripes on the test image.

> > > After applying your patches, I see a lot of cache-related artifacts on
> > > the screen when updating the fb.
> > 
> > I guess we might need a dma-specific mmap helper to make this work
> > correctly.

Comparing the difference between drm_gem_mmap_obj() and
fb_deferred_io_mmap(), the following test patch makes the cache issue
go away for me. Not sure if this can be set based on some flag, or if
we need a separate fb_deferred_io_wc_mmap() or something like that?

Regards,

Tony

[2] https://github.com/tomba/omapfb-tests

8< 
diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -224,6 +224,7 @@ static const struct address_space_operations 
fb_deferred_io_aops = {
 int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+   vma->vm_page_prot = 
pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 
vma->vm_ops = _deferred_io_vm_ops;
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);


Re: [PATCH v2 0/2] Fixes for omapdrm console

2024-02-26 Thread Tony Lindgren
* Thomas Zimmermann  [240226 09:10]:
> Hi
> 
> Am 26.02.24 um 10:01 schrieb Tomi Valkeinen:
> > On 26/02/2024 10:26, Tomi Valkeinen wrote:
> > > Hi Tony,
> > > 
> > > On 25/02/2024 08:46, Tony Lindgren wrote:
> > > > Here are two fixes for omapdrm console.
> > > 
> > > How is it broken? I don't usually use the console (or fbdev) but
> > > enabling it now, it seems to work fine for me, on DRA76 EVM with
> > > HDMI output.
> 
> Omapdrm implements drm_framebuffer_funcs.dirty withomap_framebuffer_dirty().
> AFAIK DRM semantics requires to run the dirty helper after writing to the
> framebuffer's memory. Userspace does this via the DIRTYFB ioctl. [1] But (at
> least) for correctness the console needs to do the same.
> 
> [1] 
> https://elixir.bootlin.com/linux/v6.7.6/source/drivers/gpu/drm/drm_ioctl.c#L679

Yes I noticed console not updating and bisected it down to the two
commits listed. I did the bisect on a droid4 though with command mode
LCD. I did not test with HDMI, will give that a try too.

> > After applying your patches, I see a lot of cache-related artifacts on
> > the screen when updating the fb.
> 
> I guess we might need a dma-specific mmap helper to make this work
> correctly.

I can easily test this if you have some suggested patch to try.

Hmm so I wonder if we now have double updates happening on HDMI?

Regards,

Tony


[PATCH v2 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-24 Thread Tony Lindgren
Commit 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
broke console because there is no damage handling in fb_sys_write()
unlike we have in drm_fb_helper_sys_write().

Let's fix the issue by adding FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS to
use with FB_DEFAULT_DEFERRED_OPS as suggested by Thomas. We no longer
need omap_fbdev_fb_mmap() as FB_DEFAULT_DEFERRED_OPS sets it to
fb_deferred_io_mmap().

Fixes: 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
Suggested-by: Thomas Zimmermann 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 27 +++
 include/linux/fb.h   |  4 
 2 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -76,15 +80,6 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo 
*var,
return drm_fb_helper_pan_display(var, fbi);
 }
 
-static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-   struct drm_fb_helper *helper = info->par;
-   struct drm_framebuffer *fb = helper->fb;
-   struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
-
-   return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
-}
-
 static void omap_fbdev_fb_destroy(struct fb_info *info)
 {
struct drm_fb_helper *helper = info->par;
@@ -94,6 +89,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
DBG();
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(helper);
 
omap_gem_unpin(bo);
@@ -106,15 +102,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   FB_DEFAULT_DEFERRED_OPS(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
.fb_ioctl   = drm_fb_helper_ioctl,
-   .fb_mmap= omap_fbdev_fb_mmap,
.fb_destroy = omap_fbdev_fb_destroy,
 };
 
@@ -213,6 +207,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = dma_addr;
fbi->fix.smem_len = bo->size;
 
+   /* deferred I/O */
+   helper->fbdefio.delay = HZ / 20;
+   helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+   fbi->fbdefio = >fbdefio;
+   ret = fb_deferred_io_init(fbi);
+   if (ret)
+   goto fail;
+
/* if we have DMM, then we can use it for scrolling by just
 * shuffling pages around in DMM rather than doing sw blit.
 */
diff --git a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -686,6 +686,10 @@ extern int fb_deferred_io_fsync(struct file *file, loff_t 
start,
__FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, sys) \
__FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, sys)
 
+#define FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(__prefix, __damage_range, 
__damage_area) \
+   __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, sys) \
+   __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, sys)
+
 /*
  * Initializes struct fb_ops for deferred I/O.
  */
-- 
2.43.1


[PATCH v2 1/2] drm/omapdrm: Fix console by implementing fb_dirty

2024-02-24 Thread Tony Lindgren
The framebuffer console stopped updating with commit f231af498c29
("drm/fb-helper: Disconnect damage worker from update logic").

Let's fix the issue by implementing fb_dirty similar to what was done
with commit 039a72ce7e57 ("drm/i915/fbdev: Implement fb_dirty for intel
custom fb helper").

Fixes: f231af498c29 ("drm/fb-helper: Disconnect damage worker from update 
logic")
Reviewed-by: Thomas Zimmermann 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -238,8 +238,20 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
return ret;
 }
 
+static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect 
*clip)
+{
+   if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+   return 0;
+
+   if (helper->fb->funcs->dirty)
+   return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 
1);
+
+   return 0;
+}
+
 static const struct drm_fb_helper_funcs omap_fb_helper_funcs = {
.fb_probe = omap_fbdev_create,
+   .fb_dirty = omap_fbdev_dirty,
 };
 
 static struct drm_fb_helper *get_fb(struct fb_info *fbi)
-- 
2.43.1


[PATCH v2 0/2] Fixes for omapdrm console

2024-02-24 Thread Tony Lindgren
Here are two fixes for omapdrm console.

Regards,

Tony

Changes since v1:

- Add FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS to use with
  FB_DEFAULT_DEFERRED_OPS as suggested by Thomas

Tony Lindgren (2):
  drm/omapdrm: Fix console by implementing fb_dirty
  drm/omapdrm: Fix console with deferred ops

 drivers/gpu/drm/omapdrm/omap_fbdev.c | 39 +++-
 include/linux/fb.h   |  4 +++
 2 files changed, 31 insertions(+), 12 deletions(-)

-- 
2.43.1


Re: [PATCH 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-24 Thread Tony Lindgren
* Thomas Zimmermann  [240220 10:42]:
> The changes below look good. You can test by instrumenting
> drm_fb_helper_deferred_io() with printk(). For testing, you can reduce the
> write-back frequency by setting helper->fbdefio.delay to a higher value. If
> you set it to HZ, it should only do a write-back once per second. Then do an
> mmap() from userspace and copy data into the memory region. It should print
> something from drm_fb_helper_deferred_io(). Best regards Thomas

OK thanks I tested with fbtest.c I found [0] with some trace_printk
added and it works nicely :) Will post v2 set of patches.

Regards,

Tony

[0] https://gist.github.com/rafalrusin/1482697


[PATCH v5 10/10] drm/bridge: tc358775: Configure hs_rate and lp_rate

2024-02-24 Thread Tony Lindgren
The hs_rate and lp_rate may be used by the dsi host for timing
calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
tc358765 has maximurate of 800 Mbps per lane.

Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -637,6 +637,19 @@ static int tc_attach_host(struct tc_data *tc)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
  MIPI_DSI_MODE_LPM;
 
+   /*
+* The hs_rate and lp_rate are data rate values. The HS mode is
+* differential, while the LP mode is single ended. As the HS mode
+* uses DDR, the DSI clock frequency is half the hs_rate. The 10 Mbs
+* data rate for LP mode is not specified in the bridge data sheet,
+* but seems to be part of the MIPI DSI spec.
+*/
+   if (tc->type == TC358765)
+   dsi->hs_rate = 8;
+   else
+   dsi->hs_rate = 10;
+   dsi->lp_rate = 1000;
+
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
dev_err(dev, "failed to attach dsi to host\n");
-- 
2.43.1


[PATCH v5 09/10] drm/bridge: tc358775: Add support for tc358765

2024-02-24 Thread Tony Lindgren
The tc358775 bridge is pin compatible with earlier tc358765 according to
the tc358774xbg_datasheet_en_20190118.pdf documentation. Compared to the
tc358765, the tc358775 supports a STBY GPIO and higher data rates.

The tc358765 has a register bit for video event mode vs video pulse mode.
We must set it to video event mode for the LCD output to work, and on the
tc358775, this bit no longer exists.

Looks like the registers seem to match otherwise based on a quick glance
comparing the defines to the earlier Android kernel tc358765 driver.

Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -107,6 +108,7 @@
 #define RDPKTLN 0x0404  /* Command Read Packet Length */
 
 #define VPCTRL  0x0450  /* Video Path Control */
+#define EVTMODEBIT(5)  /* Video event mode enable, tc35876x 
only */
 #define HTIM1   0x0454  /* Horizontal Timing Control 1 */
 #define HTIM2   0x0458  /* Horizontal Timing Control 2 */
 #define VTIM1   0x045C  /* Vertical Timing Control 1 */
@@ -254,6 +256,11 @@ enum tc358775_ports {
TC358775_LVDS_OUT1,
 };
 
+enum tc3587x5_type {
+   TC358765 = 0x65,
+   TC358775 = 0x75,
+};
+
 struct tc_data {
struct i2c_client   *i2c;
struct device   *dev;
@@ -271,6 +278,8 @@ struct tc_data {
struct gpio_desc*stby_gpio;
u8  lvds_link; /* single-link or dual-link */
u8  bpc;
+
+   enum tc3587x5_type  type;
 };
 
 static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
@@ -424,10 +433,16 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
 
+   /* Video event mode vs pulse mode bit, does not exist for tc358775 */
+   if (tc->type == TC358765)
+   val = EVTMODE;
+   else
+   val = 0;
+
if (tc->bpc == 8)
-   val = TC358775_VPCTRL_OPXLFMT(1);
+   val |= TC358775_VPCTRL_OPXLFMT(1);
else /* bpc = 6; */
-   val = TC358775_VPCTRL_MSF(1);
+   val |= TC358775_VPCTRL_MSF(1);
 
dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
clkdiv = dsiclk / (tc->lvds_link == DUAL_LINK ? DIVIDE_BY_6 : 
DIVIDE_BY_3);
@@ -643,6 +658,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->dev = dev;
tc->i2c = client;
+   tc->type = (enum tc3587x5_type)(unsigned 
long)of_device_get_match_data(dev);
 
tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
  TC358775_LVDS_OUT0, 0);
@@ -704,13 +720,15 @@ static void tc_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tc358775_i2c_ids[] = {
-   { "tc358775", 0 },
+   { "tc358765", TC358765, },
+   { "tc358775", TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(i2c, tc358775_i2c_ids);
 
 static const struct of_device_id tc358775_of_ids[] = {
-   { .compatible = "toshiba,tc358775", },
+   { .compatible = "toshiba,tc358765", .data = (void *)TC358765, },
+   { .compatible = "toshiba,tc358775", .data = (void *)TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(of, tc358775_of_ids);
-- 
2.43.1


[PATCH v5 08/10] drm/bridge: tc358775: Enable pre_enable_prev_first flag

2024-02-24 Thread Tony Lindgren
Set pre_enable_prev_first to ensure the previous bridge is enabled
first.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -680,6 +680,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->bridge.funcs = _bridge_funcs;
tc->bridge.of_node = dev->of_node;
+   tc->bridge.pre_enable_prev_first = true;
drm_bridge_add(>bridge);
 
i2c_set_clientdata(client, tc);
-- 
2.43.1


[PATCH v5 07/10] drm/bridge: tc358775: Add burst and low-power modes

2024-02-24 Thread Tony Lindgren
Burst and low-power modes are supported both for tc358765 and tc358775.

Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -619,7 +619,8 @@ static int tc_attach_host(struct tc_data *tc)
 
dsi->lanes = tc->num_dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.43.1


[PATCH v5 06/10] drm/bridge: tc358775: Get bridge data lanes instead of the DSI host lanes

2024-02-24 Thread Tony Lindgren
The current code assumes the data-lanes property is configured on the
DSI host side instead of the bridge side, and assumes DSI host endpoint 1.

Let's standardize on what the other bridge drivers are doing and parse the
data-lanes property for the bridge. Only if data-lanes property is not found,
let's be nice and also check the DSI host for old dtb in use and warn.

And as Dmitry pointed out, the lanes for the host and the bridge may be
different because the lanes may be swapped on the host side.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -525,27 +525,24 @@ tc_mode_valid(struct drm_bridge *bridge,
 static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
 {
struct device_node *endpoint;
-   struct device_node *parent;
struct device_node *remote;
int dsi_lanes = -1;
 
-   /*
-* To get the data-lanes of dsi, we need to access the dsi0_out of port1
-*  of dsi0 endpoint from bridge port0 of d2l_in
-*/
endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
 TC358775_DSI_IN, -1);
-   if (endpoint) {
-   /* dsi0_out node */
-   parent = of_graph_get_remote_port_parent(endpoint);
-   of_node_put(endpoint);
-   if (parent) {
-   /* dsi0 port 1 */
-   dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, 
-1, 1, 4);
-   of_node_put(parent);
-   }
+   dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);
+
+   /* Quirk old dtb: Use data lanes from the DSI host side instead of 
bridge */
+   if (dsi_lanes == -EINVAL || dsi_lanes == -ENODEV) {
+   remote = of_graph_get_remote_endpoint(endpoint);
+   dsi_lanes = drm_of_get_data_lanes_count(remote, 1, 4);
+   of_node_put(remote);
+   if (dsi_lanes >= 1)
+   dev_warn(tc->dev, "no dsi-lanes for the bridge, using 
host lanes\n");
}
 
+   of_node_put(endpoint);
+
if (dsi_lanes < 0)
return dsi_lanes;
 
-- 
2.43.1


[PATCH v5 05/10] drm/bridge: tc358775: make standby GPIO optional

2024-02-24 Thread Tony Lindgren
From: Michael Walle 

The stby pin is optional. It is only needed for power-up and down
sequencing. It is not needed, if the power rails cannot by dynamically
enabled.

Because the GPIO is now optional, remove the error message.

Signed-off-by: Michael Walle 
Reviewed-by: Dmitry Baryshkov 
Acked-by: Krzysztof Kozlowski 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -669,12 +669,9 @@ static int tc_probe(struct i2c_client *client)
return ret;
}
 
-   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
-   if (IS_ERR(tc->stby_gpio)) {
-   ret = PTR_ERR(tc->stby_gpio);
-   dev_err(dev, "cannot get stby-gpio %d\n", ret);
-   return ret;
-   }
+   tc->stby_gpio = devm_gpiod_get_optional(dev, "stby", GPIOD_OUT_HIGH);
+   if (IS_ERR(tc->stby_gpio))
+   return PTR_ERR(tc->stby_gpio);
 
tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(tc->reset_gpio)) {
-- 
2.43.1


[PATCH v5 04/10] drm/bridge: tc358775: fix support for jeida-18 and jeida-24

2024-02-24 Thread Tony Lindgren
From: Michael Walle 

The bridge always uses 24bpp internally. Therefore, for jeida-18
mapping we need to discard the lowest two bits for each channel and thus
starting with LV_[RGB]2. jeida-24 has the same mapping but uses four
lanes instead of three, with the forth pair transmitting the lowest two
bits of each channel. Thus, the mapping between jeida-18 and jeida-24
is actually the same, except that one channel is turned off (by
selecting the RGB666 format in VPCTRL).

While at it, remove the bogus comment about the hardware default because
the default is overwritten in any case.

Tested with a jeida-18 display (Evervision VGG644804).

Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -454,10 +454,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
connector->display_info.bus_formats[0],
tc->bpc);
-   /*
-* Default hardware register settings of tc358775 configured
-* with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
-*/
if (connector->display_info.bus_formats[0] ==
MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
/* VESA-24 */
@@ -468,14 +464,15 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R6));
-   } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
-   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
-   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
LVI_G0));
-   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, 
LVI_B0));
-   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
LVI_B2));
-   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_L0));
+   } else {
+   /* JEIDA-18 and JEIDA-24 */
+   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
LVI_R5));
+   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
LVI_G2));
+   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
LVI_G1));
+   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
LVI_B2));
+   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
LVI_B4));
+   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
LVI_L0));
+   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R0));
}
 
d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-- 
2.43.1


[PATCH v5 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-24 Thread Tony Lindgren
The tc358765 is similar to tc358775. The tc358765 just an earlier version
of the hardware, and it's pin and register compatible with tc358775 for
most part.

>From the binding point of view the only difference is that the tc358765
does not have stdby-gpios.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -10,7 +10,7 @@ maintainers:
   - Vinay Simha BN 
 
 description: |
-  This binding supports DSI to LVDS bridge TC358775
+  This binding supports DSI to LVDS bridges TC358765 and TC358775
 
   MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
   Video frame size:
@@ -21,7 +21,9 @@ description: |
 
 properties:
   compatible:
-const: toshiba,tc358775
+enum:
+  - toshiba,tc358765
+  - toshiba,tc358775
 
   reg:
 maxItems: 1
@@ -89,6 +91,16 @@ required:
   - reset-gpios
   - ports
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: toshiba,tc358765
+then:
+  properties:
+stby-gpios: false
+
 additionalProperties: false
 
 examples:
-- 
2.43.1


[PATCH v5 02/10] dt-bindings: display: bridge: tc358775: Add data-lanes

2024-02-24 Thread Tony Lindgren
The device uses a clock lane, and 1 to 4 DSI data lanes. Let's add the
data-lanes property starting at 1 similar to what the other bridge
bindings are doing.

Let's also drop the data-lanes properties in the example for the DSI host
controller to avoid confusion. The configuration of the DSI host depends
on the controller used and is unrelated to the bridge binding.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml  | 22 ---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -46,11 +46,27 @@ properties:
 
 properties:
   port@0:
-$ref: /schemas/graph.yaml#/properties/port
+$ref: /schemas/graph.yaml#/$defs/port-base
+unevaluatedProperties: false
 description: |
   DSI Input. The remote endpoint phandle should be a
   reference to a valid mipi_dsi_host device node.
 
+properties:
+  endpoint:
+$ref: /schemas/media/video-interfaces.yaml#
+unevaluatedProperties: false
+
+properties:
+  data-lanes:
+description: array of physical DSI data lane indexes.
+minItems: 1
+items:
+  - const: 1
+  - const: 2
+  - const: 3
+  - const: 4
+
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
 description: |
@@ -107,6 +123,7 @@ examples:
 reg = <0>;
 d2l_in_test: endpoint {
 remote-endpoint = <_out>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -131,7 +148,6 @@ examples:
 reg = <1>;
 dsi0_out: endpoint {
 remote-endpoint = <_in_test>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
@@ -166,6 +182,7 @@ examples:
 reg = <0>;
 d2l_in_dual: endpoint {
 remote-endpoint = <_out_dual>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -197,7 +214,6 @@ examples:
 reg = <1>;
 dsi0_out_dual: endpoint {
 remote-endpoint = <_in_dual>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
-- 
2.43.1


[PATCH v5 01/10] dt-bindings: display: bridge: tc358775: make stby gpio optional

2024-02-24 Thread Tony Lindgren
From: Michael Walle 

For a normal operation, the stby GPIO is not needed.

The reset pin is required because once the PPI (PHY protocol interface)
is started, it can only be stopped by asserting the reset pin.

Signed-off-by: Michael Walle 
Acked-by: Krzysztof Kozlowski 
[t...@atomide.com: dropped regulator related changes]
Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -70,7 +70,6 @@ required:
   - reg
   - vdd-supply
   - vddio-supply
-  - stby-gpios
   - reset-gpios
   - ports
 
-- 
2.43.1


[PATCH v5 00/10] Improvments for tc358775 with support for tc358765

2024-02-24 Thread Tony Lindgren
Hi all,

Here are v5 patches to improve tc358775 driver and add support for
tc358765.

Regards,

Tony

Changes since v4:
- Update devicetree binding to move allOf after required block
  as noted by Krzysztof

Changes since v3:
- Fixed dts binding warnings

Changes since v2:

- Only make stby-gpios optional for tc358775, and disallow them for
  tc358765 as noted by Krzysztof

- Added additionalProperties: false for port-base as noted by Krzysztof

- Updated patch description for why there can be a data-lanes property
  for both the DSI host and the bridge as noted by Dmitry

- Improved the old dtb data-lanes warning as suggested by Michael

- Fix warning on casting of_device_get_match_data() as noted by the
  kernel test robot

Changes since v1:

- After a brief offline discussion with Michael, merge series with
  Michael's patch series to make stby gpio and supplies optional as they
  may be hardwired

- Use Michael's better patch for the jeida timings change

- Parse lanes on the bridge side like other bridge devices do, and if not
  found, also parse on the DSI host side and warn

Michael Walle (3):
  dt-bindings: display: bridge: tc358775: make stby gpio optional
  drm/bridge: tc358775: fix support for jeida-18 and jeida-24
  drm/bridge: tc358775: make standby GPIO optional

Tony Lindgren (7):
  dt-bindings: display: bridge: tc358775: Add data-lanes
  dt-bindings: display: bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Get bridge data lanes instead of the DSI host
lanes
  drm/bridge: tc358775: Add burst and low-power modes
  drm/bridge: tc358775: Enable pre_enable_prev_first flag
  drm/bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Configure hs_rate and lp_rate

 .../display/bridge/toshiba,tc358775.yaml  | 39 ++--
 drivers/gpu/drm/bridge/tc358775.c | 98 ---
 2 files changed, 94 insertions(+), 43 deletions(-)

-- 
2.43.1


Re: [PATCH v4 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-24 Thread Tony Lindgren
* Krzysztof Kozlowski  [240215 18:43]:
> If there is going to be new version, please put allOf: block after
> required: block.

OK will post v5 set.

> Anyway:
> 
> Reviewed-by: Krzysztof Kozlowski 

Thanks,

Tony


Re: [PATCH 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-20 Thread Tony Lindgren
* Thomas Zimmermann  [240220 09:32]:
> Am 20.02.24 um 09:56 schrieb Tony Lindgren:
> > Oh right, yes omapdrm is operating on memory.
> 
> With the latest kernels, you should see a warning if helpers operate on the
> wrong type of memory. [1][2]

OK

> [1] 
> https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/video/fbdev/core/fb_io_fops.c#L16
> [2] 
> https://elixir.bootlin.com/linux/v6.8-rc5/source/drivers/video/fbdev/core/fb_sys_fops.c#L26

> > The following test patch works for me.. Not sure about the tracking though.
> 
> I know that i915 doesn't track mmap'ed pages correctly and I've see systems
> that do not update the framebuffer. IDK how/why this works with omapdrm.

Sounds like the a similar issue might exist on omapdrm too then.

> > Do you mean that tracking needs to be implemented if fb_deferred_io_mmap()
> > did not work?
> 
> omap_fbdev_fb_mmap() appears to mmap the DMA memory pages directly to
> userspace. So the fb_dirty callback won't be invoked when userspace writes
> to this framebuffer memory.
> 
> To implement tracking, you'd need to set fb_mmap to fb_deferred_io_mmap().
> If you init omap_fb_ops with FB_DEFAULT_DEFERRED_OPS(), [3] you'd get that
> automatically. fb_deferred_io_mmap() sets up the tracking whenever
> userspaces writes to a mapped page.   You also need to init the write-back
> mechanisms that calls fb_dirty for the tracked pages. You should be able to
> duplicate the code from [4] into omapdrm.

OK great. Updated test patch below with FB_DEFAULT_DEFERRED_OPS, maybe that's
all there is to it if I follow you :) The fb_dirty part was already done in
patch 1/2.

> [3] https://elixir.bootlin.com/linux/latest/source/include/linux/fb.h#L704
> [4] 
> https://elixir.bootlin.com/linux/latest/source/drivers/gpu/drm/drm_fbdev_generic.c#L119

Regards,

Tony

8< ---
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -76,15 +80,6 @@ static int omap_fbdev_pan_display(struct fb_var_screeninfo 
*var,
return drm_fb_helper_pan_display(var, fbi);
 }
 
-static int omap_fbdev_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-{
-   struct drm_fb_helper *helper = info->par;
-   struct drm_framebuffer *fb = helper->fb;
-   struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
-
-   return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
-}
-
 static void omap_fbdev_fb_destroy(struct fb_info *info)
 {
struct drm_fb_helper *helper = info->par;
@@ -94,6 +89,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
DBG();
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(helper);
 
omap_gem_unpin(bo);
@@ -106,15 +102,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   FB_DEFAULT_DEFERRED_OPS(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
.fb_ioctl   = drm_fb_helper_ioctl,
-   .fb_mmap= omap_fbdev_fb_mmap,
.fb_destroy = omap_fbdev_fb_destroy,
 };
 
@@ -213,6 +207,15 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
fbi->fix.smem_start = dma_addr;
fbi->fix.smem_len = bo->size;
 
+   /* deferred I/O */
+   helper->fbdefio.delay = HZ / 20;
+   helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+   fbi->fbdefio = >fbdefio;
+   ret = fb_deferred_io_init(fbi);
+   if (ret)
+   goto fail;
+
/* if we have DMM, then we can use it for scrolling by just
 * shuffling pages around in DMM rather than doing sw blit.
 */
diff --git a/include/linux/fb.h b/include/linux/fb.h
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -686,6 +686,10 @@ extern int fb_deferred_io_fsync(struct file *file, loff_t 
start,
__FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, sys) \
__FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, sys)
 
+#define FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(__prefix, __damage_range, 
__damage_

Re: [PATCH 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-20 Thread Tony Lindgren
* Thomas Zimmermann  [240219 16:43]:
> Am 19.02.24 um 15:19 schrieb Tony Lindgren:
> > --- a/drivers/gpu/drm/omapdrm/Kconfig
> > +++ b/drivers/gpu/drm/omapdrm/Kconfig
> > @@ -5,6 +5,7 @@ config DRM_OMAP
> > depends on ARCH_OMAP2PLUS
> > select DRM_KMS_HELPER
> > select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION
> > +   select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
> 
> Anything named _IOMEM_ is for framebuffer's in I/O memory space. Just keep
> DMAMEM_HELPERS with the few changes below.

Oh right, yes omapdrm is operating on memory.

> > select VIDEOMODE_HELPERS
> > select HDMI
> > default n
> > diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
> > b/drivers/gpu/drm/omapdrm/omap_fbdev.c
> > --- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
> > +++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
> > @@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
> > omap_gem_roll(bo, fbi->var.yoffset * npages);
> >   }
> > +FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(omap_fbdev,
> > + drm_fb_helper_damage_range,
> > + drm_fb_helper_damage_area)
> > +
> 
> Please create FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS() by duplicating
> FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS() in 

OK

> >   static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
> > struct fb_info *fbi)
> >   {
> > @@ -106,13 +110,13 @@ static void omap_fbdev_fb_destroy(struct fb_info 
> > *info)
> >   static const struct fb_ops omap_fb_ops = {
> > .owner = THIS_MODULE,
> > -   __FB_DEFAULT_DMAMEM_OPS_RDWR,
> > +   __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
> > .fb_check_var   = drm_fb_helper_check_var,
> > .fb_set_par = drm_fb_helper_set_par,
> > .fb_setcmap = drm_fb_helper_setcmap,
> > .fb_blank   = drm_fb_helper_blank,
> > .fb_pan_display = omap_fbdev_pan_display,
> > -   __FB_DEFAULT_DMAMEM_OPS_DRAW,
> > +   __FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev),
> > .fb_ioctl   = drm_fb_helper_ioctl,
> > .fb_mmap= omap_fbdev_fb_mmap,
> 
> The write and draw callbacks track the written pages and flush them to the
> backbuffer. But mmap is a problem here, because mmap needs to do this as
> well. You'd have to use fb_deferred_io_mmap() here and call
> fb_deferred_io_init() in omap's fbdev init. See the generic fbdev in
> drm_fbdev_generic() for a working example. But IDK whether that works easily
> for omap's DMA memory. You have to mmap and track memory pages (i.e., struct
> page).

The following test patch works for me.. Not sure about the tracking though.
Do you mean that tracking needs to be implemented if fb_deferred_io_mmap()
did not work?

> The easy solution is to clear the fb_mmap callback and mmap() will thne not
> be available to userspace.

Sounds like that would break things for userspace.

Regards,

Tony

8< 
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(omap_fbdev,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -80,9 +84,13 @@ static int omap_fbdev_fb_mmap(struct fb_info *info, struct 
vm_area_struct *vma)
 {
struct drm_fb_helper *helper = info->par;
struct drm_framebuffer *fb = helper->fb;
-   struct drm_gem_object *bo = drm_gem_fb_get_obj(fb, 0);
+   struct drm_gem_object *bo;
 
-   return drm_gem_mmap_obj(bo, omap_gem_mmap_size(bo), vma);
+   bo = drm_gem_fb_get_obj(fb, 0);
+   if (!bo)
+   return -EINVAL;
+
+   return fb_deferred_io_mmap(info, vma);
 }
 
 static void omap_fbdev_fb_destroy(struct fb_info *info)
@@ -94,6 +102,7 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
DBG();
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(helper);
 
omap_gem_unpin(bo);
@@ -106,13 +115,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_

[PATCH 2/2] drm/omapdrm: Fix console with deferred ops

2024-02-19 Thread Tony Lindgren
Commit 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
broke console because there is no damage handling in fb_sys_write()
unlike we have in drm_fb_helper_sys_write().

Let's fix the issue by using deferred ops with fb helpers for damage.

Fixes: 95da53d63dcf ("drm/omapdrm: Use regular fbdev I/O helpers")
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/Kconfig  | 1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 8 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -5,6 +5,7 @@ config DRM_OMAP
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
select FB_DMAMEM_HELPERS if DRM_FBDEV_EMULATION
+   select FB_IOMEM_HELPERS if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -51,6 +51,10 @@ static void pan_worker(struct work_struct *work)
omap_gem_roll(bo, fbi->var.yoffset * npages);
 }
 
+FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(omap_fbdev,
+ drm_fb_helper_damage_range,
+ drm_fb_helper_damage_area)
+
 static int omap_fbdev_pan_display(struct fb_var_screeninfo *var,
struct fb_info *fbi)
 {
@@ -106,13 +110,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-   __FB_DEFAULT_DMAMEM_OPS_RDWR,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(omap_fbdev),
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(omap_fbdev),
.fb_ioctl   = drm_fb_helper_ioctl,
.fb_mmap= omap_fbdev_fb_mmap,
.fb_destroy = omap_fbdev_fb_destroy,
-- 
2.43.1


[PATCH 1/2] drm/omapdrm: Fix console by implementing fb_dirty

2024-02-19 Thread Tony Lindgren
The framebuffer console stopped updating with commit f231af498c29
("drm/fb-helper: Disconnect damage worker from update logic").

Let's fix the issue by implementing fb_dirty similar to what was done
with commit 039a72ce7e57 ("drm/i915/fbdev: Implement fb_dirty for intel
custom fb helper").

Fixes: f231af498c29 ("drm/fb-helper: Disconnect damage worker from update 
logic")
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -238,8 +238,20 @@ static int omap_fbdev_create(struct drm_fb_helper *helper,
return ret;
 }
 
+static int omap_fbdev_dirty(struct drm_fb_helper *helper, struct drm_clip_rect 
*clip)
+{
+   if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+   return 0;
+
+   if (helper->fb->funcs->dirty)
+   return helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 
1);
+
+   return 0;
+}
+
 static const struct drm_fb_helper_funcs omap_fb_helper_funcs = {
.fb_probe = omap_fbdev_create,
+   .fb_dirty = omap_fbdev_dirty,
 };
 
 static struct drm_fb_helper *get_fb(struct fb_info *fbi)
-- 
2.43.1


[PATCH v4 10/10] drm/bridge: tc358775: Configure hs_rate and lp_rate

2024-02-15 Thread Tony Lindgren
The hs_rate and lp_rate may be used by the dsi host for timing
calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
tc358765 has maximurate of 800 Mbps per lane.

Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -637,6 +637,19 @@ static int tc_attach_host(struct tc_data *tc)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
  MIPI_DSI_MODE_LPM;
 
+   /*
+* The hs_rate and lp_rate are data rate values. The HS mode is
+* differential, while the LP mode is single ended. As the HS mode
+* uses DDR, the DSI clock frequency is half the hs_rate. The 10 Mbs
+* data rate for LP mode is not specified in the bridge data sheet,
+* but seems to be part of the MIPI DSI spec.
+*/
+   if (tc->type == TC358765)
+   dsi->hs_rate = 8;
+   else
+   dsi->hs_rate = 10;
+   dsi->lp_rate = 1000;
+
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
dev_err(dev, "failed to attach dsi to host\n");
-- 
2.43.1


[PATCH v4 09/10] drm/bridge: tc358775: Add support for tc358765

2024-02-15 Thread Tony Lindgren
The tc358775 bridge is pin compatible with earlier tc358765 according to
the tc358774xbg_datasheet_en_20190118.pdf documentation. Compared to the
tc358765, the tc358775 supports a STBY GPIO and higher data rates.

The tc358765 has a register bit for video event mode vs video pulse mode.
We must set it to video event mode for the LCD output to work, and on the
tc358775, this bit no longer exists.

Looks like the registers seem to match otherwise based on a quick glance
comparing the defines to the earlier Android kernel tc358765 driver.

Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -107,6 +108,7 @@
 #define RDPKTLN 0x0404  /* Command Read Packet Length */
 
 #define VPCTRL  0x0450  /* Video Path Control */
+#define EVTMODEBIT(5)  /* Video event mode enable, tc35876x 
only */
 #define HTIM1   0x0454  /* Horizontal Timing Control 1 */
 #define HTIM2   0x0458  /* Horizontal Timing Control 2 */
 #define VTIM1   0x045C  /* Vertical Timing Control 1 */
@@ -254,6 +256,11 @@ enum tc358775_ports {
TC358775_LVDS_OUT1,
 };
 
+enum tc3587x5_type {
+   TC358765 = 0x65,
+   TC358775 = 0x75,
+};
+
 struct tc_data {
struct i2c_client   *i2c;
struct device   *dev;
@@ -271,6 +278,8 @@ struct tc_data {
struct gpio_desc*stby_gpio;
u8  lvds_link; /* single-link or dual-link */
u8  bpc;
+
+   enum tc3587x5_type  type;
 };
 
 static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
@@ -424,10 +433,16 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
 
+   /* Video event mode vs pulse mode bit, does not exist for tc358775 */
+   if (tc->type == TC358765)
+   val = EVTMODE;
+   else
+   val = 0;
+
if (tc->bpc == 8)
-   val = TC358775_VPCTRL_OPXLFMT(1);
+   val |= TC358775_VPCTRL_OPXLFMT(1);
else /* bpc = 6; */
-   val = TC358775_VPCTRL_MSF(1);
+   val |= TC358775_VPCTRL_MSF(1);
 
dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
clkdiv = dsiclk / (tc->lvds_link == DUAL_LINK ? DIVIDE_BY_6 : 
DIVIDE_BY_3);
@@ -643,6 +658,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->dev = dev;
tc->i2c = client;
+   tc->type = (enum tc3587x5_type)(unsigned 
long)of_device_get_match_data(dev);
 
tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
  TC358775_LVDS_OUT0, 0);
@@ -704,13 +720,15 @@ static void tc_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tc358775_i2c_ids[] = {
-   { "tc358775", 0 },
+   { "tc358765", TC358765, },
+   { "tc358775", TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(i2c, tc358775_i2c_ids);
 
 static const struct of_device_id tc358775_of_ids[] = {
-   { .compatible = "toshiba,tc358775", },
+   { .compatible = "toshiba,tc358765", .data = (void *)TC358765, },
+   { .compatible = "toshiba,tc358775", .data = (void *)TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(of, tc358775_of_ids);
-- 
2.43.1


[PATCH v4 08/10] drm/bridge: tc358775: Enable pre_enable_prev_first flag

2024-02-15 Thread Tony Lindgren
Set pre_enable_prev_first to ensure the previous bridge is enabled
first.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -680,6 +680,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->bridge.funcs = _bridge_funcs;
tc->bridge.of_node = dev->of_node;
+   tc->bridge.pre_enable_prev_first = true;
drm_bridge_add(>bridge);
 
i2c_set_clientdata(client, tc);
-- 
2.43.1


[PATCH v4 07/10] drm/bridge: tc358775: Add burst and low-power modes

2024-02-15 Thread Tony Lindgren
Burst and low-power modes are supported both for tc358765 and tc358775.

Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -619,7 +619,8 @@ static int tc_attach_host(struct tc_data *tc)
 
dsi->lanes = tc->num_dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.43.1


[PATCH v4 06/10] drm/bridge: tc358775: Get bridge data lanes instead of the DSI host lanes

2024-02-15 Thread Tony Lindgren
The current code assumes the data-lanes property is configured on the
DSI host side instead of the bridge side, and assumes DSI host endpoint 1.

Let's standardize on what the other bridge drivers are doing and parse the
data-lanes property for the bridge. Only if data-lanes property is not found,
let's be nice and also check the DSI host for old dtb in use and warn.

And as Dmitry pointed out, the lanes for the host and the bridge may be
different because the lanes may be swapped on the host side.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -525,27 +525,24 @@ tc_mode_valid(struct drm_bridge *bridge,
 static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
 {
struct device_node *endpoint;
-   struct device_node *parent;
struct device_node *remote;
int dsi_lanes = -1;
 
-   /*
-* To get the data-lanes of dsi, we need to access the dsi0_out of port1
-*  of dsi0 endpoint from bridge port0 of d2l_in
-*/
endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
 TC358775_DSI_IN, -1);
-   if (endpoint) {
-   /* dsi0_out node */
-   parent = of_graph_get_remote_port_parent(endpoint);
-   of_node_put(endpoint);
-   if (parent) {
-   /* dsi0 port 1 */
-   dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, 
-1, 1, 4);
-   of_node_put(parent);
-   }
+   dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);
+
+   /* Quirk old dtb: Use data lanes from the DSI host side instead of 
bridge */
+   if (dsi_lanes == -EINVAL || dsi_lanes == -ENODEV) {
+   remote = of_graph_get_remote_endpoint(endpoint);
+   dsi_lanes = drm_of_get_data_lanes_count(remote, 1, 4);
+   of_node_put(remote);
+   if (dsi_lanes >= 1)
+   dev_warn(tc->dev, "no dsi-lanes for the bridge, using 
host lanes\n");
}
 
+   of_node_put(endpoint);
+
if (dsi_lanes < 0)
return dsi_lanes;
 
-- 
2.43.1


[PATCH v4 05/10] drm/bridge: tc358775: make standby GPIO optional

2024-02-15 Thread Tony Lindgren
From: Michael Walle 

The stby pin is optional. It is only needed for power-up and down
sequencing. It is not needed, if the power rails cannot by dynamically
enabled.

Because the GPIO is now optional, remove the error message.

Signed-off-by: Michael Walle 
Reviewed-by: Dmitry Baryshkov 
Acked-by: Krzysztof Kozlowski 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -669,12 +669,9 @@ static int tc_probe(struct i2c_client *client)
return ret;
}
 
-   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
-   if (IS_ERR(tc->stby_gpio)) {
-   ret = PTR_ERR(tc->stby_gpio);
-   dev_err(dev, "cannot get stby-gpio %d\n", ret);
-   return ret;
-   }
+   tc->stby_gpio = devm_gpiod_get_optional(dev, "stby", GPIOD_OUT_HIGH);
+   if (IS_ERR(tc->stby_gpio))
+   return PTR_ERR(tc->stby_gpio);
 
tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(tc->reset_gpio)) {
-- 
2.43.1


[PATCH v4 04/10] drm/bridge: tc358775: fix support for jeida-18 and jeida-24

2024-02-15 Thread Tony Lindgren
From: Michael Walle 

The bridge always uses 24bpp internally. Therefore, for jeida-18
mapping we need to discard the lowest two bits for each channel and thus
starting with LV_[RGB]2. jeida-24 has the same mapping but uses four
lanes instead of three, with the forth pair transmitting the lowest two
bits of each channel. Thus, the mapping between jeida-18 and jeida-24
is actually the same, except that one channel is turned off (by
selecting the RGB666 format in VPCTRL).

While at it, remove the bogus comment about the hardware default because
the default is overwritten in any case.

Tested with a jeida-18 display (Evervision VGG644804).

Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -454,10 +454,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
connector->display_info.bus_formats[0],
tc->bpc);
-   /*
-* Default hardware register settings of tc358775 configured
-* with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
-*/
if (connector->display_info.bus_formats[0] ==
MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
/* VESA-24 */
@@ -468,14 +464,15 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R6));
-   } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
-   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
-   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
LVI_G0));
-   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, 
LVI_B0));
-   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
LVI_B2));
-   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_L0));
+   } else {
+   /* JEIDA-18 and JEIDA-24 */
+   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
LVI_R5));
+   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
LVI_G2));
+   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
LVI_G1));
+   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
LVI_B2));
+   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
LVI_B4));
+   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
LVI_L0));
+   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R0));
}
 
d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-- 
2.43.1


[PATCH v4 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-15 Thread Tony Lindgren
The tc358765 is similar to tc358775. The tc358765 just an earlier version
of the hardware, and it's pin and register compatible with tc358775 for
most part.

>From the binding point of view the only difference is that the tc358765
does not have stdby-gpios.

Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -10,7 +10,7 @@ maintainers:
   - Vinay Simha BN 
 
 description: |
-  This binding supports DSI to LVDS bridge TC358775
+  This binding supports DSI to LVDS bridges TC358765 and TC358775
 
   MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
   Video frame size:
@@ -21,7 +21,9 @@ description: |
 
 properties:
   compatible:
-const: toshiba,tc358775
+enum:
+  - toshiba,tc358765
+  - toshiba,tc358775
 
   reg:
 maxItems: 1
@@ -81,6 +83,16 @@ properties:
   - port@0
   - port@1
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: toshiba,tc358765
+then:
+  properties:
+stby-gpios: false
+
 required:
   - compatible
   - reg
-- 
2.43.1


[PATCH v4 02/10] dt-bindings: display: bridge: tc358775: Add data-lanes

2024-02-15 Thread Tony Lindgren
The device uses a clock lane, and 1 to 4 DSI data lanes. Let's add the
data-lanes property starting at 1 similar to what the other bridge
bindings are doing.

Let's also drop the data-lanes properties in the example for the DSI host
controller to avoid confusion. The configuration of the DSI host depends
on the controller used and is unrelated to the bridge binding.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml  | 22 ---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -46,11 +46,27 @@ properties:
 
 properties:
   port@0:
-$ref: /schemas/graph.yaml#/properties/port
+$ref: /schemas/graph.yaml#/$defs/port-base
+unevaluatedProperties: false
 description: |
   DSI Input. The remote endpoint phandle should be a
   reference to a valid mipi_dsi_host device node.
 
+properties:
+  endpoint:
+$ref: /schemas/media/video-interfaces.yaml#
+unevaluatedProperties: false
+
+properties:
+  data-lanes:
+description: array of physical DSI data lane indexes.
+minItems: 1
+items:
+  - const: 1
+  - const: 2
+  - const: 3
+  - const: 4
+
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
 description: |
@@ -107,6 +123,7 @@ examples:
 reg = <0>;
 d2l_in_test: endpoint {
 remote-endpoint = <_out>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -131,7 +148,6 @@ examples:
 reg = <1>;
 dsi0_out: endpoint {
 remote-endpoint = <_in_test>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
@@ -166,6 +182,7 @@ examples:
 reg = <0>;
 d2l_in_dual: endpoint {
 remote-endpoint = <_out_dual>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -197,7 +214,6 @@ examples:
 reg = <1>;
 dsi0_out_dual: endpoint {
 remote-endpoint = <_in_dual>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
-- 
2.43.1


[PATCH v4 01/10] dt-bindings: display: bridge: tc358775: make stby gpio optional

2024-02-15 Thread Tony Lindgren
From: Michael Walle 

For a normal operation, the stby GPIO is not needed.

The reset pin is required because once the PPI (PHY protocol interface)
is started, it can only be stopped by asserting the reset pin.

Signed-off-by: Michael Walle 
Acked-by: Krzysztof Kozlowski 
[t...@atomide.com: dropped regulator related changes]
Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -70,7 +70,6 @@ required:
   - reg
   - vdd-supply
   - vddio-supply
-  - stby-gpios
   - reset-gpios
   - ports
 
-- 
2.43.1


[PATCH v4 00/10] Improvments for tc358775 with support for tc358765

2024-02-15 Thread Tony Lindgren
Hi all,

Here are v4 patches to improve tc358775 driver and add support for
tc358765.

Regards,

Tony

Changes since v3:
- Fixed dts binding warnings

Changes since v2:

- Only make stby-gpios optional for tc358775, and disallow them for
  tc358765 as noted by Krzysztof

- Added additionalProperties: false for port-base as noted by Krzysztof

- Updated patch description for why there can be a data-lanes property
  for both the DSI host and the bridge as noted by Dmitry

- Improved the old dtb data-lanes warning as suggested by Michael

- Fix warning on casting of_device_get_match_data() as noted by the
  kernel test robot

Changes since v1:

- After a brief offline discussion with Michael, merge series with
  Michael's patch series to make stby gpio and supplies optional as they
  may be hardwired

- Use Michael's better patch for the jeida timings change

- Parse lanes on the bridge side like other bridge devices do, and if not
  found, also parse on the DSI host side and warn

Michael Walle (3):
  dt-bindings: display: bridge: tc358775: make stby gpio optional
  drm/bridge: tc358775: fix support for jeida-18 and jeida-24
  drm/bridge: tc358775: make standby GPIO optional

Tony Lindgren (7):
  dt-bindings: display: bridge: tc358775: Add data-lanes
  dt-bindings: display: bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Get bridge data lanes instead of the DSI host
lanes
  drm/bridge: tc358775: Add burst and low-power modes
  drm/bridge: tc358775: Enable pre_enable_prev_first flag
  drm/bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Configure hs_rate and lp_rate

 .../display/bridge/toshiba,tc358775.yaml  | 39 ++--
 drivers/gpu/drm/bridge/tc358775.c | 98 ---
 2 files changed, 94 insertions(+), 43 deletions(-)

-- 
2.43.1


Re: [PATCH v3 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-12 Thread Tony Lindgren
* Rob Herring  [240212 13:51]:
> On Mon, Feb 12, 2024 at 12:30:12PM +0100, Krzysztof Kozlowski wrote:
> > On 12/02/2024 09:17, Tony Lindgren wrote:
> > > usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] 
> > > [-f {parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] 
> > > [FILE_OR_DIR ...]
> > > yamllint: error: one of the arguments FILE_OR_DIR - is required
> > >   CHKDT   Documentation/devicetree/bindings/processed-schema.json
> > >   SCHEMA  Documentation/devicetree/bindings/processed-schema.json
> > > 
> > > After removing the ">2&1" from the Makefile, there's some more info:
> > > 
> > > yamllint: error: one of the arguments FILE_OR_DIR - is required
> > > 
> > > Where DT_SCHEMA_FILES ends up empty. I guess dt_binding_check needs
> > > to be now run with just:
> > > 
> > > $ make dt_binding_check DT_SCHEMA_FILES=toshiba,tc358775.yaml
> > > 
> > 
> > Yes, since June last year. Rob later brought (in July) backwards
> > compatible way, but apparently something changed now in Makefile.
> 
> It broke in 6.8-rc1. I have a fix in my tree which I'll send to Linus 
> this week.

OK good to hear, thanks!

Tony


Re: [PATCH v3 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-12 Thread Tony Lindgren
* Krzysztof Kozlowski  [240212 08:06]:
> On 11/02/2024 10:51, Tony Lindgren wrote:
> > The tc358765 is similar to tc358775. The tc358765 just an earlier version
> > of the hardware, and it's pin and register compatible with tc358775 for
> > most part.
> > 
> > From the binding point of view the only difference is that the tc358765
> > does not have stdby-gpios.
> > 
> > Signed-off-by: Tony Lindgren 
> > ---
> 
> It does not look like you tested the bindings, at least after quick
> look. Please run `make dt_binding_check` (see
> Documentation/devicetree/bindings/writing-schema.rst for instructions).
> Maybe you need to update your dtschema and yamllint.

I did.. But I did not notice that this no longer works:

$ make dt_binding_check 
DT_SCHEMA_FILES=Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
  LINTDocumentation/devicetree/bindings
usage: yamllint [-h] [-] [-c CONFIG_FILE | -d CONFIG_DATA] [--list-files] [-f 
{parsable,standard,colored,github,auto}] [-s] [--no-warnings] [-v] [FILE_OR_DIR 
...]
yamllint: error: one of the arguments FILE_OR_DIR - is required
  CHKDT   Documentation/devicetree/bindings/processed-schema.json
  SCHEMA  Documentation/devicetree/bindings/processed-schema.json

After removing the ">2&1" from the Makefile, there's some more info:

yamllint: error: one of the arguments FILE_OR_DIR - is required

Where DT_SCHEMA_FILES ends up empty. I guess dt_binding_check needs
to be now run with just:

$ make dt_binding_check DT_SCHEMA_FILES=toshiba,tc358775.yaml

Regards,

Tony


[PATCH v2 1/2] dt-bindings: display: simple: Add boe, bp082wx1-100 8.2" panel

2024-02-11 Thread Tony Lindgren
This panel is found on Motorola mapphone tablets mz607 to mz609.

Acked-by: Conor Dooley 
Signed-off-by: Tony Lindgren 
---

No changes since v1

---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -73,6 +73,8 @@ properties:
   - auo,t215hvn01
 # Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
   - avic,tm070ddh03
+# BOE BP082WX1-100 8.2" WXGA (1280x800) LVDS panel
+  - boe,bp082wx1-100
 # BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
   - boe,bp101wx1-100
 # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
-- 
2.43.1


[PATCH v2 2/2] drm/panel: simple: Add BOE BP082WX1-100 8.2" panel

2024-02-11 Thread Tony Lindgren
The BOE BP082WX1-100 is a 8.2" panel similar to the 10.1" panel
BP101WX1-100. Both panels use the same timings.

Acked-by: Conor Dooley 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Tony Lindgren 
---

Changes since v1:
- Update viewport dimensions based on panelook values asa suggested
  by Dmitry

---
 drivers/gpu/drm/panel/panel-simple.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1367,6 +1367,23 @@ static const struct drm_display_mode 
boe_bp101wx1_100_mode = {
.vtotal = 800 + 6 + 8 + 2,
 };
 
+static const struct panel_desc boe_bp082wx1_100 = {
+   .modes = _bp101wx1_100_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 177,
+   .height = 110,
+   },
+   .delay = {
+   .enable = 50,
+   .disable = 50,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+   .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct panel_desc boe_bp101wx1_100 = {
.modes = _bp101wx1_100_mode,
.num_modes = 1,
@@ -4343,6 +4360,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "bananapi,s070wv20-ct16",
.data = _s070wv20_ct16,
+   }, {
+   .compatible = "boe,bp082wx1-100",
+   .data = _bp082wx1_100,
}, {
.compatible = "boe,bp101wx1-100",
.data = _bp101wx1_100,
-- 
2.43.1


[PATCH v3 10/10] drm/bridge: tc358775: Configure hs_rate and lp_rate

2024-02-11 Thread Tony Lindgren
The hs_rate and lp_rate may be used by the dsi host for timing
calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
tc358765 has maximurate of 800 Mbps per lane.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -637,6 +637,19 @@ static int tc_attach_host(struct tc_data *tc)
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
  MIPI_DSI_MODE_LPM;
 
+   /*
+* The hs_rate and lp_rate are data rate values. The HS mode is
+* differential, while the LP mode is single ended. As the HS mode
+* uses DDR, the DSI clock frequency is half the hs_rate. The 10 Mbs
+* data rate for LP mode is not specified in the bridge data sheet,
+* but seems to be part of the MIPI DSI spec.
+*/
+   if (tc->type == TC358765)
+   dsi->hs_rate = 8;
+   else
+   dsi->hs_rate = 10;
+   dsi->lp_rate = 1000;
+
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
dev_err(dev, "failed to attach dsi to host\n");
-- 
2.43.0


[PATCH v3 09/10] drm/bridge: tc358775: Add support for tc358765

2024-02-11 Thread Tony Lindgren
The tc358775 bridge is pin compatible with earlier tc358765 according to
the tc358774xbg_datasheet_en_20190118.pdf documentation. Compared to the
tc358765, the tc358775 supports a STBY GPIO and higher data rates.

The tc358765 has a register bit for video event mode vs video pulse mode.
We must set it to video event mode for the LCD output to work, and on the
tc358775, this bit no longer exists.

Looks like the registers seem to match otherwise based on a quick glance
comparing the defines to the earlier Android kernel tc358765 driver.

Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -107,6 +108,7 @@
 #define RDPKTLN 0x0404  /* Command Read Packet Length */
 
 #define VPCTRL  0x0450  /* Video Path Control */
+#define EVTMODEBIT(5)  /* Video event mode enable, tc35876x 
only */
 #define HTIM1   0x0454  /* Horizontal Timing Control 1 */
 #define HTIM2   0x0458  /* Horizontal Timing Control 2 */
 #define VTIM1   0x045C  /* Vertical Timing Control 1 */
@@ -254,6 +256,11 @@ enum tc358775_ports {
TC358775_LVDS_OUT1,
 };
 
+enum tc3587x5_type {
+   TC358765 = 0x65,
+   TC358775 = 0x75,
+};
+
 struct tc_data {
struct i2c_client   *i2c;
struct device   *dev;
@@ -271,6 +278,8 @@ struct tc_data {
struct gpio_desc*stby_gpio;
u8  lvds_link; /* single-link or dual-link */
u8  bpc;
+
+   enum tc3587x5_type  type;
 };
 
 static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
@@ -424,10 +433,16 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
 
+   /* Video event mode vs pulse mode bit, does not exist for tc358775 */
+   if (tc->type == TC358765)
+   val = EVTMODE;
+   else
+   val = 0;
+
if (tc->bpc == 8)
-   val = TC358775_VPCTRL_OPXLFMT(1);
+   val |= TC358775_VPCTRL_OPXLFMT(1);
else /* bpc = 6; */
-   val = TC358775_VPCTRL_MSF(1);
+   val |= TC358775_VPCTRL_MSF(1);
 
dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
clkdiv = dsiclk / (tc->lvds_link == DUAL_LINK ? DIVIDE_BY_6 : 
DIVIDE_BY_3);
@@ -643,6 +658,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->dev = dev;
tc->i2c = client;
+   tc->type = (enum tc3587x5_type)(unsigned 
long)of_device_get_match_data(dev);
 
tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
  TC358775_LVDS_OUT0, 0);
@@ -704,13 +720,15 @@ static void tc_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tc358775_i2c_ids[] = {
-   { "tc358775", 0 },
+   { "tc358765", TC358765, },
+   { "tc358775", TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(i2c, tc358775_i2c_ids);
 
 static const struct of_device_id tc358775_of_ids[] = {
-   { .compatible = "toshiba,tc358775", },
+   { .compatible = "toshiba,tc358765", .data = (void *)TC358765, },
+   { .compatible = "toshiba,tc358775", .data = (void *)TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(of, tc358775_of_ids);
-- 
2.43.0


[PATCH v3 08/10] drm/bridge: tc358775: Enable pre_enable_prev_first flag

2024-02-11 Thread Tony Lindgren
Set pre_enable_prev_first to ensure the previous bridge is enabled
first.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -680,6 +680,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->bridge.funcs = _bridge_funcs;
tc->bridge.of_node = dev->of_node;
+   tc->bridge.pre_enable_prev_first = true;
drm_bridge_add(>bridge);
 
i2c_set_clientdata(client, tc);
-- 
2.43.0


[PATCH v3 07/10] drm/bridge: tc358775: Add burst and low-power modes

2024-02-11 Thread Tony Lindgren
Burst and low-power modes are supported both for tc358765 and tc358775.

Reviewed-by: Michael Walle 
Tested-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -619,7 +619,8 @@ static int tc_attach_host(struct tc_data *tc)
 
dsi->lanes = tc->num_dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+ MIPI_DSI_MODE_LPM;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.43.0


[PATCH v3 06/10] drm/bridge: tc358775: Get bridge data lanes instead of the DSI host lanes

2024-02-11 Thread Tony Lindgren
The current code assumes the data-lanes property is configured on the
DSI host side instead of the bridge side, and assumes DSI host endpoint 1.

Let's standardize on what the other bridge drivers are doing and parse the
data-lanes property for the bridge. Only if data-lanes property is not found,
let's be nice and also check the DSI host for old dtb in use and warn.

And as Dmitry pointed out, the lanes for the host and the bridge may be
different because the lanes may be swapped on the host side.

Reviewed-by: Dmitry Baryshkov 
Reviewed-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -525,27 +525,24 @@ tc_mode_valid(struct drm_bridge *bridge,
 static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
 {
struct device_node *endpoint;
-   struct device_node *parent;
struct device_node *remote;
int dsi_lanes = -1;
 
-   /*
-* To get the data-lanes of dsi, we need to access the dsi0_out of port1
-*  of dsi0 endpoint from bridge port0 of d2l_in
-*/
endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
 TC358775_DSI_IN, -1);
-   if (endpoint) {
-   /* dsi0_out node */
-   parent = of_graph_get_remote_port_parent(endpoint);
-   of_node_put(endpoint);
-   if (parent) {
-   /* dsi0 port 1 */
-   dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, 
-1, 1, 4);
-   of_node_put(parent);
-   }
+   dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);
+
+   /* Quirk old dtb: Use data lanes from the DSI host side instead of 
bridge */
+   if (dsi_lanes == -EINVAL || dsi_lanes == -ENODEV) {
+   remote = of_graph_get_remote_endpoint(endpoint);
+   dsi_lanes = drm_of_get_data_lanes_count(remote, 1, 4);
+   of_node_put(remote);
+   if (dsi_lanes >= 1)
+   dev_warn(tc->dev, "no dsi-lanes for the bridge, using 
host lanes\n");
}
 
+   of_node_put(endpoint);
+
if (dsi_lanes < 0)
return dsi_lanes;
 
-- 
2.43.0


[PATCH v3 05/10] drm/bridge: tc358775: make standby GPIO optional

2024-02-11 Thread Tony Lindgren
From: Michael Walle 

The stby pin is optional. It is only needed for power-up and down
sequencing. It is not needed, if the power rails cannot by dynamically
enabled.

Because the GPIO is now optional, remove the error message.

Signed-off-by: Michael Walle 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -669,12 +669,9 @@ static int tc_probe(struct i2c_client *client)
return ret;
}
 
-   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
-   if (IS_ERR(tc->stby_gpio)) {
-   ret = PTR_ERR(tc->stby_gpio);
-   dev_err(dev, "cannot get stby-gpio %d\n", ret);
-   return ret;
-   }
+   tc->stby_gpio = devm_gpiod_get_optional(dev, "stby", GPIOD_OUT_HIGH);
+   if (IS_ERR(tc->stby_gpio))
+   return PTR_ERR(tc->stby_gpio);
 
tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(tc->reset_gpio)) {
-- 
2.43.0


[PATCH v3 04/10] drm/bridge: tc358775: fix support for jeida-18 and jeida-24

2024-02-11 Thread Tony Lindgren
From: Michael Walle 

The bridge always uses 24bpp internally. Therefore, for jeida-18
mapping we need to discard the lowest two bits for each channel and thus
starting with LV_[RGB]2. jeida-24 has the same mapping but uses four
lanes instead of three, with the forth pair transmitting the lowest two
bits of each channel. Thus, the mapping between jeida-18 and jeida-24
is actually the same, except that one channel is turned off (by
selecting the RGB666 format in VPCTRL).

While at it, remove the bogus comment about the hardware default because
the default is overwritten in any case.

Tested with a jeida-18 display (Evervision VGG644804).

Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -454,10 +454,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
connector->display_info.bus_formats[0],
tc->bpc);
-   /*
-* Default hardware register settings of tc358775 configured
-* with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
-*/
if (connector->display_info.bus_formats[0] ==
MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
/* VESA-24 */
@@ -468,14 +464,15 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R6));
-   } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
-   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
-   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
LVI_G0));
-   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, 
LVI_B0));
-   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
LVI_B2));
-   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_L0));
+   } else {
+   /* JEIDA-18 and JEIDA-24 */
+   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
LVI_R5));
+   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
LVI_G2));
+   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
LVI_G1));
+   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
LVI_B2));
+   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
LVI_B4));
+   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
LVI_L0));
+   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R0));
}
 
d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-- 
2.43.0


[PATCH v3 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2024-02-11 Thread Tony Lindgren
The tc358765 is similar to tc358775. The tc358765 just an earlier version
of the hardware, and it's pin and register compatible with tc358775 for
most part.

>From the binding point of view the only difference is that the tc358765
does not have stdby-gpios.

Signed-off-by: Tony Lindgren 
---
 .../bindings/display/bridge/toshiba,tc358775.yaml | 15 +--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -10,7 +10,7 @@ maintainers:
   - Vinay Simha BN 
 
 description: |
-  This binding supports DSI to LVDS bridge TC358775
+  This binding supports DSI to LVDS bridges TC358765 and TC358775
 
   MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
   Video frame size:
@@ -21,7 +21,9 @@ description: |
 
 properties:
   compatible:
-const: toshiba,tc358775
+enum:
+  - toshiba,tc358765
+  - toshiba,tc358775
 
   reg:
 maxItems: 1
@@ -81,6 +83,15 @@ properties:
   - port@0
   - port@1
 
+allOf:
+  - if:
+properties:
+  compatible:
+contains:
+  const: toshiba,tc358765
+then:
+  stby-gpios: false
+
 required:
   - compatible
   - reg
-- 
2.43.0


[PATCH v3 02/10] dt-bindings: display: bridge: tc358775: Add data-lanes

2024-02-11 Thread Tony Lindgren
The device uses a clock lane, and 1 to 4 DSI data lanes. Let's add the
data-lanes property starting at 1 similar to what the other bridge
bindings are doing.

Let's also drop the data-lanes properties in the example for the DSI host
controller to avoid confusion. The configuration of the DSI host depends
on the controller used and is unrelated to the bridge binding.

Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml  | 22 ---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -46,11 +46,27 @@ properties:
 
 properties:
   port@0:
-$ref: /schemas/graph.yaml#/properties/port
+$ref: /schemas/graph.yaml#/$defs/port-base
+unevaluatedProperties: false
 description: |
   DSI Input. The remote endpoint phandle should be a
   reference to a valid mipi_dsi_host device node.
 
+properties:
+  endpoint:
+$ref: /schemas/media/video-interfaces.yaml#
+unevaluatedProperties: false
+
+properties:
+  data-lanes:
+description: array of physical DSI data lane indexes.
+minItems: 1
+items:
+  - const: 1
+  - const: 2
+  - const: 3
+  - const: 4
+
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
 description: |
@@ -107,6 +123,7 @@ examples:
 reg = <0>;
 d2l_in_test: endpoint {
 remote-endpoint = <_out>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -131,7 +148,6 @@ examples:
 reg = <1>;
 dsi0_out: endpoint {
 remote-endpoint = <_in_test>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
@@ -166,6 +182,7 @@ examples:
 reg = <0>;
 d2l_in_dual: endpoint {
 remote-endpoint = <_out_dual>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -197,7 +214,6 @@ examples:
 reg = <1>;
 dsi0_out_dual: endpoint {
 remote-endpoint = <_in_dual>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
-- 
2.43.0


[PATCH v3 01/10] dt-bindings: display: bridge: tc358775: make stby gpio optional

2024-02-11 Thread Tony Lindgren
From: Michael Walle 

For a normal operation, the stby GPIO is not needed.

The reset pin is required because once the PPI (PHY protocol interface)
is started, it can only be stopped by asserting the reset pin.

Signed-off-by: Michael Walle 
[t...@atomide.com: dropped regulator related changes]
Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml | 1 -
 1 file changed, 1 deletion(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -70,7 +70,6 @@ required:
   - reg
   - vdd-supply
   - vddio-supply
-  - stby-gpios
   - reset-gpios
   - ports
 
-- 
2.43.0


[PATCH v3 00/10] Improvments for tc358775 with support for tc358765

2024-02-11 Thread Tony Lindgren
Hi all,

Here are v3 patches to improve tc358775 driver and add support for
tc358765.

Regards,

Tony

Changes since v2:

- Only make stby-gpios optional for tc358775, and disallow them for
  tc358765 as noted by Krzysztof

- Added additionalProperties: false for port-base as noted by Krzysztof

- Updated patch description for why there can be a data-lanes property
  for both the DSI host and the bridge as noted by Dmitry

- Improved the old dtb data-lanes warning as suggested by Michael

- Fix warning on casting of_device_get_match_data() as noted by the
  kernel test robot


Changes since v1:

- After a brief offline discussion with Michael, merge series with
  Michael's patch series to make stby gpio and supplies optional as they
  may be hardwired

- Use Michael's better patch for the jeida timings change

- Parse lanes on the bridge side like other bridge devices do, and if not
  found, also parse on the DSI host side and warn

Michael Walle (3):
  dt-bindings: display: bridge: tc358775: make stby gpio optional
  drm/bridge: tc358775: fix support for jeida-18 and jeida-24
  drm/bridge: tc358775: make standby GPIO optional

Tony Lindgren (7):
  dt-bindings: display: bridge: tc358775: Add data-lanes
  dt-bindings: display: bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Get bridge data lanes instead of the DSI host
lanes
  drm/bridge: tc358775: Add burst and low-power modes
  drm/bridge: tc358775: Enable pre_enable_prev_first flag
  drm/bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Configure hs_rate and lp_rate

 .../display/bridge/toshiba,tc358775.yaml  | 38 +--
 drivers/gpu/drm/bridge/tc358775.c | 98 ---
 2 files changed, 93 insertions(+), 43 deletions(-)

-- 
2.43.0


Re: [PATCH v2 09/10] drm/bridge: tc358775: Add support for tc358765

2024-01-30 Thread Tony Lindgren
* Michael Walle  [231204 09:52]:
> >> @@ -643,6 +658,7 @@ static int tc_probe(struct i2c_client *client)
> >>
> >> tc->dev = dev;
> >> tc->i2c = client;
> >> +   tc->type = (enum tc3587x5_type)of_device_get_match_data(dev);
> >
> > Would it make sense to use i2c_get_match_data() instead?
> 
> FWIW, I' planning to add a dsi binding for this driver. So I'd
> suggest either the of_ or the device_ variant. Not sure though,
> if the new device supports the DSI commands.

Yeah good point as some hardware may not have i2c wired at all. Let's keep
this as of_device_get_match_data() for now as the driver is currently
completely dependant on devicetree.

I'll update the enumeration to use the hardware id numbering like Dmitry
suggested though.

Regards,

Tony


Re: [PATCH v2 10/10] drm/bridge: tc358775: Configure hs_rate and lp_rate

2024-01-30 Thread Tony Lindgren
* Michael Walle  [231207 16:14]:
> > The hs_rate and lp_rate may be used by the dsi host for timing
> > calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
> > tc358765 has maximurate of 800 Mbps per lane.
> > 
> > Signed-off-by: Tony Lindgren 
> > ---
> >  drivers/gpu/drm/bridge/tc358775.c | 5 +
> >  1 file changed, 5 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/bridge/tc358775.c 
> > b/drivers/gpu/drm/bridge/tc358775.c
> > --- a/drivers/gpu/drm/bridge/tc358775.c
> > +++ b/drivers/gpu/drm/bridge/tc358775.c
> > @@ -636,6 +636,11 @@ static int tc_attach_host(struct tc_data *tc)
> > dsi->format = MIPI_DSI_FMT_RGB888;
> > dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
> > MIPI_DSI_MODE_LPM;
> > +   if (tc->type == TC358765)
> > +   dsi->hs_rate = 8;
> 
> It's not clear to me whether this is the data rate or the frequency. From
> the kernel doc:
> 
>  * @hs_rate: maximum lane frequency for high speed mode in hertz, this should
>  * be set to the real limits of the hardware, zero is only accepted for
>  * legacy drivers
> 
> The tc358775 datasheet lists 1Gbps per lane, which corresponds to a 500MHz DSI
> clock frequency. Not sure how that would correspond to the "maximum lane
> frequency" above. I guess the wording of the comment is just misleading and
> the value is the data rate of the lane.

Yeah seems we're using the data rate of a lane in in hertz and then the
host drivers adapt for the double data rate. Or at least that's my
understanding.. Hopefully we don't have different assumptions in the
host drivers.

> > +   else
> > +   dsi->hs_rate = 10;
> > +   dsi->lp_rate = 1000;
> 
> That I didn't found in the datasheet. Just a T_min_rx (minimum pulse width
> response) which is 20ns. But there are no more details on this.

I think the low power data rate might be specified in the mipi dsi spec.
Maybe somebody familiar with the spec can confirm it.

Regards,

Tony


Re: [PATCH 02/11] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2024-01-26 Thread Tony Lindgren
* Rob Herring  [240119 17:48]:
> On Wed, Jan 10, 2024 at 10:38:57AM +0200, Tony Lindgren wrote:
> > So for merging these, as many of the changes touch the omap variants, I
> > could set up an immutable branch with all the changes after -rc1. Or I can
> > ack the patches too if somebody has better ideas.
> 
> Just take all but patches 10 and 11. I don't think it matters if the 
> binding is there for them as long as it is all there in next. No one is 
> paying that close attention to the warnings I think.

OK I've now applied these except patches 10 and 11 into a sgx-for-v6.9
branch [0].

Regards,

Tony

[0] 
https://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git/log/?h=sgx-for-v6.9


Re: [PATCH 08/11] ARM: dts: DRA7xx: Add device tree entry for SGX GPU

2024-01-25 Thread Tony Lindgren
* Tony Lindgren  [240118 08:57]:
> * Andrew Davis  [240117 15:52]:
> > On 1/10/24 2:29 AM, Tony Lindgren wrote:
> > > * Andrew Davis  [240109 17:20]:
> > > > --- a/arch/arm/boot/dts/ti/omap/dra7.dtsi
> > > > +++ b/arch/arm/boot/dts/ti/omap/dra7.dtsi
> > > > @@ -850,12 +850,19 @@ target-module@5600 {
> > > > ;
> > > > ti,sysc-sidle = ,
> > > > ,
> > > > -   ;
> > > > +   ,
> > > > +   ;
> > > 
> > > You probably checked this already.. But just in case, can you please
> > > confirm this is intentional. The documentation lists the smart wakeup
> > > capability bit as reserved for dra7, maybe the documentation is wrong.
> > > 
> > 
> > It was an intentional change, although I'm not sure it is correct :)
> > 
> > This is how we had it in our "evil vendor tree" for years (back when it
> > was hwmod based), so when converting these nodes to use "ti,sysc" I noticed
> > this bit was set, but as you point out the documentation disagrees.
> > 
> > I'd rather go with what has worked before, but it doesn't seem to
> > break anything either way, so we could also break this change out into
> > its own patch if you would prefer.
> 
> I agree it's best to stick what is known to work. How about let's add
> the related information to the patch description?

I'll update the commit message for it and apply these, no need to repost.

Regards,

Tony


Re: [PATCH 08/11] ARM: dts: DRA7xx: Add device tree entry for SGX GPU

2024-01-18 Thread Tony Lindgren
* Andrew Davis  [240117 15:52]:
> On 1/10/24 2:29 AM, Tony Lindgren wrote:
> > * Andrew Davis  [240109 17:20]:
> > > --- a/arch/arm/boot/dts/ti/omap/dra7.dtsi
> > > +++ b/arch/arm/boot/dts/ti/omap/dra7.dtsi
> > > @@ -850,12 +850,19 @@ target-module@5600 {
> > >   ;
> > >   ti,sysc-sidle = ,
> > >   ,
> > > - ;
> > > + ,
> > > + ;
> > 
> > You probably checked this already.. But just in case, can you please
> > confirm this is intentional. The documentation lists the smart wakeup
> > capability bit as reserved for dra7, maybe the documentation is wrong.
> > 
> 
> It was an intentional change, although I'm not sure it is correct :)
> 
> This is how we had it in our "evil vendor tree" for years (back when it
> was hwmod based), so when converting these nodes to use "ti,sysc" I noticed
> this bit was set, but as you point out the documentation disagrees.
> 
> I'd rather go with what has worked before, but it doesn't seem to
> break anything either way, so we could also break this change out into
> its own patch if you would prefer.

I agree it's best to stick what is known to work. How about let's add
the related information to the patch description?

Regards,

Tony


Re: [PATCH 02/11] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2024-01-10 Thread Tony Lindgren
* Krzysztof Kozlowski  [240109 19:53]:
> On 09/01/2024 18:19, Andrew Davis wrote:
> > The Imagination PowerVR Series5 "SGX" GPU is part of several SoCs from
> > multiple vendors. Describe how the SGX GPU is integrated in these SoC,
> > including register space and interrupts. Clocks, reset, and power domain
> > information is SoC specific.
> > 
> > Signed-off-by: Andrew Davis 
> > Reviewed-by: Javier Martinez Canillas 
> 
> 
> > +  clock-names:
> > +minItems: 1
> > +items:
> > +  - const: core
> > +  - const: mem
> > +  - const: sys
> 
> There are no devices currently using third clock, but I assume it is
> expected or possible.

I think the third clock is typically merged with one of the two clocks but
yeah possibly it's a separate clocke in some cases.

> Reviewed-by: Krzysztof Kozlowski 

Looks good to me too.

So for merging these, as many of the changes touch the omap variants, I
could set up an immutable branch with all the changes after -rc1. Or I can
ack the patches too if somebody has better ideas.

Regards,

Tony


Re: [PATCH 08/11] ARM: dts: DRA7xx: Add device tree entry for SGX GPU

2024-01-10 Thread Tony Lindgren
* Andrew Davis  [240109 17:20]:
> --- a/arch/arm/boot/dts/ti/omap/dra7.dtsi
> +++ b/arch/arm/boot/dts/ti/omap/dra7.dtsi
> @@ -850,12 +850,19 @@ target-module@5600 {
>   ;
>   ti,sysc-sidle = ,
>   ,
> - ;
> + ,
> + ;

You probably checked this already.. But just in case, can you please
confirm this is intentional. The documentation lists the smart wakeup
capability bit as reserved for dra7, maybe the documentation is wrong.

Regards,

Tony



Re: [PATCH RFC 01/10] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2023-12-06 Thread Tony Lindgren
* Andreas Kemnade  [231205 09:43]:
> On Tue, 5 Dec 2023 10:27:56 +0100
> Krzysztof Kozlowski  wrote:
> 
> > On 05/12/2023 10:02, Andreas Kemnade wrote:
> > > On Tue, 5 Dec 2023 09:45:44 +0100
> > > Krzysztof Kozlowski  wrote:
> > >   
> > >>> Sure the clock nodes can be there for the child IP, but they won't do
> > >>> anything. And still need to be managed separately by the device driver 
> > >>> if
> > >>> added.
> > >>
> > >> So if OS does not have runtime PM, the bindings are wrong? Bindings
> > >> should not depend on some particular feature of some particular OS.  
> > > 
> > > Any user of the devicetree sees that there is a parent and the parent 
> > > needs
> > > to be enabled by some mechanism.
> > > E.g. I2c devices do not specify the clocks of the parent (the i2c master) 
> > >  

Yeah the interconnect target module needs to be enabled before the child
IP can be probed for any OS. That is unless the target module is left on
from the bootloader.

But like I said, I have no objection to also having the clocks for the
child SGX device here. I think two out of the tree SGX clocks are merged,
so one of the three clocks would repeat twice in the binding.

We do provide some of the clock aliases, like fck and ick, for the child
ip automatically by the ti-sysc interconnect target module. But likely we
don't want to clock name specific handling in the driver so best to
standardize on SGX specific clock names. That is if the clock properties
are not set optional.

> > If you use this analogy, then compare it with an I2C device which has
> > these clock inputs. Such device must have clocks in the bindings.
> > 
> I would see target-module = i2c master.
> 
> Well, if there is a variant of the i2c device which does not require
> external clocks and a variant which requires it, then clock can be
> optional.

Yes that sounds about right for an analogy :)

Regards,

Tony


Re: [PATCH RFC 01/10] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2023-12-05 Thread Tony Lindgren
* Krzysztof Kozlowski  [231205 08:16]:
> On 05/12/2023 09:10, Tony Lindgren wrote:
> > * Krzysztof Kozlowski  [231205 08:03]:
> >> What does runtime PM have to do with it? If runtime PM enables clocks,
> >> these are real signals and not optional.
> > 
> > Runtime PM propagates to the parent device.
> 
> Then it is not really relevant to the hardware talk here, unless you put
> this device clocks in parent node, but then it's just wrong hardware
> description.

No it's not. The interconnect target module may have one or more separate
devices with the same shared clocks. See for example the am3 usb module that
has usb controllers, phys and dma at target-module@4740 in am33xx.dtsi.

Sure the clock nodes can be there for the child IP, but they won't do
anything. And still need to be managed separately by the device driver if
added.

Regards,

Tony


Re: [PATCH RFC 01/10] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2023-12-05 Thread Tony Lindgren
* Krzysztof Kozlowski  [231205 08:03]:
> What does runtime PM have to do with it? If runtime PM enables clocks,
> these are real signals and not optional.

Runtime PM propagates to the parent device.

Regards,

Tony


Re: [PATCH RFC 01/10] dt-bindings: gpu: Add PowerVR Series5 SGX GPUs

2023-12-04 Thread Tony Lindgren
* Krzysztof Kozlowski  [231205 07:10]:
> On 04/12/2023 19:22, Andrew Davis wrote:
> > @@ -56,6 +76,43 @@ allOf:
> >properties:
> >  clocks:
> >maxItems: 1
> > +  required:
> > +- clocks
> > +- clock-names
> 
> You need to define the clocks for your variants or disallow them. The
> original code should be fixed as well and make the clocks fixed for all
> img-axe cases.

To clarify, the clocks may be optional as they can be hardwired and coming
from the interconnect target wrapper module and enabled with runtime PM.

Regards,

Tony


[PATCH 2/2] drm/panel: simple: Add BOE BP082WX1-100 8.2" panel

2023-12-02 Thread Tony Lindgren
The BOE BP082WX1-100 is a 8.2" panel similar to the 10.1" panel
BP101WX1-100. Both panels use the same timings.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/panel/panel-simple.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1336,6 +1336,23 @@ static const struct drm_display_mode 
boe_bp101wx1_100_mode = {
.vtotal = 800 + 6 + 8 + 2,
 };
 
+static const struct panel_desc boe_bp082wx1_100 = {
+   .modes = _bp101wx1_100_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 180,
+   .height = 114,
+   },
+   .delay = {
+   .enable = 50,
+   .disable = 50,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+   .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct panel_desc boe_bp101wx1_100 = {
.modes = _bp101wx1_100_mode,
.num_modes = 1,
@@ -4281,6 +4298,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "bananapi,s070wv20-ct16",
.data = _s070wv20_ct16,
+   }, {
+   .compatible = "boe,bp082wx1-100",
+   .data = _bp082wx1_100,
}, {
.compatible = "boe,bp101wx1-100",
.data = _bp101wx1_100,
-- 
2.43.0


[PATCH 1/2] dt-bindings: display: simple: Add boe, bp082wx1-100 8.2" panel

2023-12-02 Thread Tony Lindgren
This panel is found on Motorola mapphone tablets mz607 to mz609.

Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -73,6 +73,8 @@ properties:
   - auo,t215hvn01
 # Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
   - avic,tm070ddh03
+# BOE BP082WX1-100 8.2" WXGA (1280x800) LVDS panel
+  - boe,bp082wx1-100
 # BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
   - boe,bp101wx1-100
 # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
-- 
2.43.0


[PATCH v2 10/10] drm/bridge: tc358775: Configure hs_rate and lp_rate

2023-12-02 Thread Tony Lindgren
The hs_rate and lp_rate may be used by the dsi host for timing
calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
tc358765 has maximurate of 800 Mbps per lane.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -636,6 +636,11 @@ static int tc_attach_host(struct tc_data *tc)
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM;
+   if (tc->type == TC358765)
+   dsi->hs_rate = 8;
+   else
+   dsi->hs_rate = 10;
+   dsi->lp_rate = 1000;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.43.0


[PATCH v2 09/10] drm/bridge: tc358775: Add support for tc358765

2023-12-02 Thread Tony Lindgren
The tc358775 bridge is pin compatible with earlier tc358765 according to
the tc358774xbg_datasheet_en_20190118.pdf documentation. Compared to the
tc358765, the tc358775 supports a STBY GPIO and higher data rates.

The tc358765 has a register bit for video event mode vs video pulse mode.
We must set it to video event mode for the LCD output to work, and on the
tc358775, this bit no longer exists.

Looks like the registers seem to match otherwise based on a quick glance
comparing the defines to the earlier Android kernel tc358765 driver.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 26 ++
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -107,6 +108,7 @@
 #define RDPKTLN 0x0404  /* Command Read Packet Length */
 
 #define VPCTRL  0x0450  /* Video Path Control */
+#define EVTMODEBIT(5)  /* Video event mode enable, tc35876x 
only */
 #define HTIM1   0x0454  /* Horizontal Timing Control 1 */
 #define HTIM2   0x0458  /* Horizontal Timing Control 2 */
 #define VTIM1   0x045C  /* Vertical Timing Control 1 */
@@ -254,6 +256,11 @@ enum tc358775_ports {
TC358775_LVDS_OUT1,
 };
 
+enum tc3587x5_type {
+   TC358765,
+   TC358775,
+};
+
 struct tc_data {
struct i2c_client   *i2c;
struct device   *dev;
@@ -271,6 +278,8 @@ struct tc_data {
struct gpio_desc*stby_gpio;
u8  lvds_link; /* single-link or dual-link */
u8  bpc;
+
+   enum tc3587x5_type  type;
 };
 
 static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
@@ -424,10 +433,16 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
 
+   /* Video event mode vs pulse mode bit, does not exist for tc358775 */
+   if (tc->type == TC358765)
+   val = EVTMODE;
+   else
+   val = 0;
+
if (tc->bpc == 8)
-   val = TC358775_VPCTRL_OPXLFMT(1);
+   val |= TC358775_VPCTRL_OPXLFMT(1);
else /* bpc = 6; */
-   val = TC358775_VPCTRL_MSF(1);
+   val |= TC358775_VPCTRL_MSF(1);
 
dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
clkdiv = dsiclk / (tc->lvds_link == DUAL_LINK ? DIVIDE_BY_6 : 
DIVIDE_BY_3);
@@ -643,6 +658,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->dev = dev;
tc->i2c = client;
+   tc->type = (enum tc3587x5_type)of_device_get_match_data(dev);
 
tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
  TC358775_LVDS_OUT0, 0);
@@ -704,13 +720,15 @@ static void tc_remove(struct i2c_client *client)
 }
 
 static const struct i2c_device_id tc358775_i2c_ids[] = {
-   { "tc358775", 0 },
+   { "tc358765", TC358765, },
+   { "tc358775", TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(i2c, tc358775_i2c_ids);
 
 static const struct of_device_id tc358775_of_ids[] = {
-   { .compatible = "toshiba,tc358775", },
+   { .compatible = "toshiba,tc358765", .data = (void *)TC358765, },
+   { .compatible = "toshiba,tc358775", .data = (void *)TC358775, },
{ }
 };
 MODULE_DEVICE_TABLE(of, tc358775_of_ids);
-- 
2.43.0


[PATCH v2 08/10] drm/bridge: tc358775: Enable pre_enable_prev_first flag

2023-12-02 Thread Tony Lindgren
Set pre_enable_prev_first to ensure the previous bridge is enabled
first.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -680,6 +680,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->bridge.funcs = _bridge_funcs;
tc->bridge.of_node = dev->of_node;
+   tc->bridge.pre_enable_prev_first = true;
drm_bridge_add(>bridge);
 
i2c_set_clientdata(client, tc);
-- 
2.43.0


[PATCH v2 07/10] drm/bridge: tc358775: Add burst and low-power modes

2023-12-02 Thread Tony Lindgren
Burst and low-power modes are supported both for tc358765 and tc358775.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -619,7 +619,8 @@ static int tc_attach_host(struct tc_data *tc)
 
dsi->lanes = tc->num_dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+   MIPI_DSI_MODE_LPM;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.43.0


[PATCH v2 06/10] drm/bridge: tc358775: Get bridge data lanes instead of the DSI host lanes

2023-12-02 Thread Tony Lindgren
The current code assumes the data-lanes property is configured on the
DSI host side instead of the bridge side, and assumes DSI host endpoint 1.

Let's standardize on what the other bridge drivers are doing and parse the
data-lanes property for the bridge. Only if data-lanes property is not found,
let's be nice and also check the DSI host for old dtb in use and warn.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 25 +++--
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -525,27 +525,24 @@ tc_mode_valid(struct drm_bridge *bridge,
 static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
 {
struct device_node *endpoint;
-   struct device_node *parent;
struct device_node *remote;
int dsi_lanes = -1;
 
-   /*
-* To get the data-lanes of dsi, we need to access the dsi0_out of port1
-*  of dsi0 endpoint from bridge port0 of d2l_in
-*/
endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
 TC358775_DSI_IN, -1);
-   if (endpoint) {
-   /* dsi0_out node */
-   parent = of_graph_get_remote_port_parent(endpoint);
-   of_node_put(endpoint);
-   if (parent) {
-   /* dsi0 port 1 */
-   dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, 
-1, 1, 4);
-   of_node_put(parent);
-   }
+   dsi_lanes = drm_of_get_data_lanes_count(endpoint, 1, 4);
+
+   /* Quirk old dtb: Use data lanes from the DSI host side instead of 
bridge */
+   if (dsi_lanes == -EINVAL || dsi_lanes == -ENODEV) {
+   remote = of_graph_get_remote_endpoint(endpoint);
+   dsi_lanes = drm_of_get_data_lanes_count(remote, 1, 4);
+   of_node_put(remote);
+   if (dsi_lanes >= 1)
+   dev_warn(tc->dev, "missing dsi-lanes property for the 
bridge\n");
}
 
+   of_node_put(endpoint);
+
if (dsi_lanes < 0)
return dsi_lanes;
 
-- 
2.43.0


[PATCH v2 05/10] drm/bridge: tc358775: make standby GPIO optional

2023-12-02 Thread Tony Lindgren
From: Michael Walle 

The stby pin is optional. It is only needed for power-up and down
sequencing. It is not needed, if the power rails cannot by dynamically
enabled.

Because the GPIO is not optional, remove the error message.

Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -669,12 +669,9 @@ static int tc_probe(struct i2c_client *client)
return ret;
}
 
-   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
-   if (IS_ERR(tc->stby_gpio)) {
-   ret = PTR_ERR(tc->stby_gpio);
-   dev_err(dev, "cannot get stby-gpio %d\n", ret);
-   return ret;
-   }
+   tc->stby_gpio = devm_gpiod_get_optional(dev, "stby", GPIOD_OUT_HIGH);
+   if (IS_ERR(tc->stby_gpio))
+   return PTR_ERR(tc->stby_gpio);
 
tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
if (IS_ERR(tc->reset_gpio)) {
-- 
2.43.0


[PATCH v2 04/10] drm/bridge: tc358775: fix support for jeida-18 and jeida-24

2023-12-02 Thread Tony Lindgren
From: Michael Walle 

The bridge always uses 24bpp internally. Therefore, for jeida-18
mapping we need to discard the lowest two bits for each channel and thus
starting with LV_[RGB]2. jeida-24 has the same mapping but uses four
lanes instead of three, with the forth pair transmitting the lowest two
bits of each channel. Thus, the mapping between jeida-18 and jeida-24
is actually the same, except that one channel is turned off (by
selecting the RGB666 format in VPCTRL).

While at it, remove the bogus comment about the hardware default because
the default is overwritten in any case.

Tested with a jeida-18 display (Evervision VGG644804).

Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -454,10 +454,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
connector->display_info.bus_formats[0],
tc->bpc);
-   /*
-* Default hardware register settings of tc358775 configured
-* with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
-*/
if (connector->display_info.bus_formats[0] ==
MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
/* VESA-24 */
@@ -468,14 +464,15 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R6));
-   } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
-   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
-   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
LVI_G0));
-   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, 
LVI_B0));
-   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
LVI_B2));
-   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
-   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_L0));
+   } else {
+   /* JEIDA-18 and JEIDA-24 */
+   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
LVI_R5));
+   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
LVI_G2));
+   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
LVI_G1));
+   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
LVI_B2));
+   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
LVI_B4));
+   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
LVI_L0));
+   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R0));
}
 
d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-- 
2.43.0


[PATCH v2 03/10] dt-bindings: display: bridge: tc358775: Add support for tc358765

2023-12-01 Thread Tony Lindgren
The tc358765 is similar to tc358775 except for the stdby-gpios.

Signed-off-by: Tony Lindgren 
---
 .../bindings/display/bridge/toshiba,tc358775.yaml   | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -10,7 +10,7 @@ maintainers:
   - Vinay Simha BN 
 
 description: |
-  This binding supports DSI to LVDS bridge TC358775
+  This binding supports DSI to LVDS bridges TC358765 and TC358775
 
   MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
   Video frame size:
@@ -21,7 +21,9 @@ description: |
 
 properties:
   compatible:
-const: toshiba,tc358775
+enum:
+  - toshiba,tc358765
+  - toshiba,tc358775
 
   reg:
 maxItems: 1
-- 
2.43.0


[PATCH v2 02/10] dt-bindings: display: bridge: tc358775: Add data-lanes

2023-12-01 Thread Tony Lindgren
The device uses a clock lane, and 1 to 4 DSI data lanes. Let's add the
data-lanes property starting at 1 similar to what the other bridge
bindings are doing.

Let's also drop the data-lanes properties in the example for the DSI host
controller to avoid confusion. The configuration of the DSI host depends
on the controller used and is unrelated to the bridge binding.

Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml  | 21 ---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -46,11 +46,26 @@ properties:
 
 properties:
   port@0:
-$ref: /schemas/graph.yaml#/properties/port
+$ref: /schemas/graph.yaml#/$defs/port-base
 description: |
   DSI Input. The remote endpoint phandle should be a
   reference to a valid mipi_dsi_host device node.
 
+properties:
+  endpoint:
+$ref: /schemas/media/video-interfaces.yaml#
+unevaluatedProperties: false
+
+properties:
+  data-lanes:
+description: array of physical DSI data lane indexes.
+minItems: 1
+items:
+  - const: 1
+  - const: 2
+  - const: 3
+  - const: 4
+
   port@1:
 $ref: /schemas/graph.yaml#/properties/port
 description: |
@@ -105,6 +120,7 @@ examples:
 reg = <0>;
 d2l_in_test: endpoint {
 remote-endpoint = <_out>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -129,7 +145,6 @@ examples:
 reg = <1>;
 dsi0_out: endpoint {
 remote-endpoint = <_in_test>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
@@ -164,6 +179,7 @@ examples:
 reg = <0>;
 d2l_in_dual: endpoint {
 remote-endpoint = <_out_dual>;
+data-lanes = <1 2 3 4>;
 };
 };
 
@@ -195,7 +211,6 @@ examples:
 reg = <1>;
 dsi0_out_dual: endpoint {
 remote-endpoint = <_in_dual>;
-data-lanes = <0 1 2 3>;
 };
  };
  };
-- 
2.43.0


[PATCH v2 01/10] dt-bindings: display: bridge: tc358775: make stby gpio and vdd supplies optional

2023-12-01 Thread Tony Lindgren
From: Michael Walle 

For a normal operation, the vdd supplies nor the stby GPIO is needed.
There are boards, where these voltages are statically enabled during
board power-up.

The reset pin is required because once the PPI (PHY protocol interface)
is started, it can only be stopped by asserting the reset pin.

Signed-off-by: Michael Walle 
Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/bridge/toshiba,tc358775.yaml   | 3 ---
 1 file changed, 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -68,9 +68,6 @@ properties:
 required:
   - compatible
   - reg
-  - vdd-supply
-  - vddio-supply
-  - stby-gpios
   - reset-gpios
   - ports
 
-- 
2.43.0


[PATCH v2 00/10] Improvments for tc358775 with support for tc358765

2023-12-01 Thread Tony Lindgren
Here's v2 of these changes merged with patches from Michael.

Regards,

Tony

Changes since v1:

- After a brief offline discussion with Michael, merge series with
  Michael's patch series to make stby gpio and supplies optional as they
  may be hardwired

- Use Michael's better patch for the jeida timings change

- Parse lanes on the bridge side like other bridge devices do, and if not
  found, also parse on the DSI host side and warn

Michael Walle (3):
  dt-bindings: display: bridge: tc358775: make stby gpio and vdd
supplies optional
  drm/bridge: tc358775: fix support for jeida-18 and jeida-24
  drm/bridge: tc358775: make standby GPIO optional

Tony Lindgren (7):
  dt-bindings: display: bridge: tc358775: Add data-lanes
  dt-bindings: display: bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Get bridge data lanes instead of the DSI host
lanes
  drm/bridge: tc358775: Add burst and low-power modes
  drm/bridge: tc358775: Enable pre_enable_prev_first flag
  drm/bridge: tc358775: Add support for tc358765
  drm/bridge: tc358775: Configure hs_rate and lp_rate

 .../display/bridge/toshiba,tc358775.yaml  | 30 +--
 drivers/gpu/drm/bridge/tc358775.c | 90 +++
 2 files changed, 75 insertions(+), 45 deletions(-)

-- 
2.43.0


Re: [PATCH 2/6] drm/bridge: tc358775: Fix getting dsi host data lanes

2023-11-27 Thread Tony Lindgren
* Michael Walle  [231127 14:31]:
> + dt maintainers
> 
> > > I actually have the same fix, but with one additional detail, which
> > > I'm
> > > unsure about though: This looks at the data-lanes property of the
> > > *remote*
> > > endpoint whereas other bridge drivers (see tc358767, ti-sn65dsi83,
> > > lt8912b,
> > > anx7625) look at the local endpoint and I'm not sure what is correct.
> > 
> > Yes I've been wondering about that too. Let's just move it over to the
> > bridge node? We could produce a warning if the dsi host node has the
> > data-lanes property.. No current in kernel users AFAIK.
> 
> I haven't found any in-tree users either. In my patch, I first try the
> remote
> end and then the local end. But thinking more about it I don't think
> this is correct. Maybe we can do it the other way around, first try
> data-lanes of the local endpoint and if not found, then try the remote
> one. That way, we would at least be backwards compatible in the driver.
> And for the dt-bindings, make it mandatory to have a local data-lanes.

OK sounds good to me.

Tony


Re: [PATCH 3/6] drm/bridge: tc358775: Add jeida-24 support

2023-11-27 Thread Tony Lindgren
* Michael Walle  [231127 13:25]:
> > The jeida-24 register values are the default hardware settings, but they
> > not listed in the driver. Let's add them.
> 
> jeida-24 and jeida-18 should have the same mapping, jeida-18 is broken in
> this driver. could you test this patch:

Yes great works for me with the tc358765 patches:

Tested-by: Tony Lindgren 

> --snip--
> 
> From 46da1d76d4908e5879ed746cce1faeacd69c432e Mon Sep 17 00:00:00 2001
> From: Michael Walle 
> Date: Wed, 4 Oct 2023 13:52:57 +0200
> Subject: [PATCH] drm/bridge: tc358775: fix support for jeida-18 and jeida-24
> 
> The bridge always uses 24bpp internally. Therefore, for jeida-18
> mapping we need to discard the lowest two bits for each channel and thus
> starting with LV_[RGB]2. jeida-24 has the same mapping but uses four
> lanes instead of three, with the forth pair transmitting the lowest two
> bits of each channel. Thus, the mapping between jeida-18 and jeida-24
> is actually the same, except that one channel is turned off (by
> selecting the RGB666 format in VPCTRL).
> 
> While at it, remove the bogus comment about the hardware default because
> the default is overwritten in any case.
> 
> Tested with a jeida-18 display (Evervision VGG644804).
> 
> Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
> Signed-off-by: Michael Walle 
> ---
>  drivers/gpu/drm/bridge/tc358775.c | 21 +
>  1 file changed, 9 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/bridge/tc358775.c 
> b/drivers/gpu/drm/bridge/tc358775.c
> index 90a89d70d832..592c69c2aedc 100644
> --- a/drivers/gpu/drm/bridge/tc358775.c
> +++ b/drivers/gpu/drm/bridge/tc358775.c
> @@ -454,10 +454,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
>   dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
>   connector->display_info.bus_formats[0],
>   tc->bpc);
> - /*
> -  * Default hardware register settings of tc358775 configured
> -  * with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
> -  */
>   if (connector->display_info.bus_formats[0] ==
>   MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
>   /* VESA-24 */
> @@ -468,14 +464,15 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
>   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
> LVI_B2));
>   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
> LVI_L0));
>   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
> LVI_R6));
> - } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
> - d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
> LVI_R3));
> - d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
> LVI_G0));
> - d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
> LVI_L0));
> - d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, 
> LVI_B0));
> - d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
> LVI_B2));
> - d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
> LVI_L0));
> - d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
> LVI_L0));
> + } else {
> + /* JEIDA-18 and JEIDA-24 */
> + d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
> LVI_R5));
> + d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
> LVI_G2));
> + d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
> LVI_G1));
> + d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
> LVI_B2));
> + d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
> LVI_B4));
> + d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
> LVI_L0));
> + d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
> LVI_R0));
>   }
>  
>   d2l_write(tc->i2c, VFUEN, VFUEN_EN);
> -- 
> 2.39.2
> 


Re: [PATCH 2/6] drm/bridge: tc358775: Fix getting dsi host data lanes

2023-11-27 Thread Tony Lindgren
* Michael Walle  [231127 13:10]:
> I actually have the same fix, but with one additional detail, which I'm
> unsure about though: This looks at the data-lanes property of the *remote*
> endpoint whereas other bridge drivers (see tc358767, ti-sn65dsi83, lt8912b,
> anx7625) look at the local endpoint and I'm not sure what is correct.

Yes I've been wondering about that too. Let's just move it over to the
bridge node? We could produce a warning if the dsi host node has the
data-lanes property.. No current in kernel users AFAIK.

FYI, for omapdrm, we already have a legacy dt property "lanes" for the
wiring that tells number of lanes used and the order of the lanes.

Regards,

Tony


Re: [PATCH 1/6] dt-bindings: tc358775: Add support for tc358765

2023-11-27 Thread Tony Lindgren
* Michael Walle  [231127 12:44]:
> Hi,
> 
> > The tc358765 is similar to tc358775 except for the stdby-gpios.
> 
> Bad timing (for me). I'm about to send a bigger patch series for the
> tc358775 which fixes the (completely) broken initialialization. And also
> contains some of your fixes.

OK cool, let's merge patches as needed then. Maybe ack the patches that
can already be merged, and put together some merged set for the rest of
the patches? Or let me know what you prefer, I'll be glad to test and
tweak as needed for tc358765.

> That being said, I intend to make the standby gpio optional also for the
> tc358755, because it might just be hardwired on the board.

OK that sounds good to me.

> But second, I'm really curious if this bridge is working for you correctly
> as it is at the moment. One particular thing I've noticed is that you must
> release the reset while both the clock and the data lanes are in LP11 mode.
> Otherwise, the bridge won't work properly (i.e. horizontally shifted
> picture, or no picture at all).

Yes things are working for me. But then again the bridge is initialized
by the bootloader, and then Android kernel, and then I kexec to the
mainline kernel. And this is with a tc358765 if that might make a
difference.

So I have not seen your reset issue. Andreas may be seeing it on another
tc bridge variant though, so adding Andreas to the loop also.

> What DSI host controller are you using?

This is an old motorola mz617 tablet with a tc358765 bridge, so omapdrm.
I do have one pending patch for omapdrm dsi to change the init order a
bit so tc358765 probes reliably. But seems that's a separate issue from
your reset issue, I'll post that to the lists too to discuss.

What's the dsi host you have? Do you also have some separate i2c eeprom
that's needed for initializing something or is that lcd panel specific?
No idea what the eeprom is really doing here..

Regards,

Tony


[PATCH 2/2] drm/panel: simple: Add BOE BP101WX1-100 panel

2023-11-26 Thread Tony Lindgren
This panel is found on Motorola mapphone tablets from mz615 to mz617.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/panel/panel-simple.c | 32 
 1 file changed, 32 insertions(+)

diff --git a/drivers/gpu/drm/panel/panel-simple.c 
b/drivers/gpu/drm/panel/panel-simple.c
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1324,6 +1324,35 @@ static const struct panel_desc bananapi_s070wv20_ct16 = {
},
 };
 
+static const struct drm_display_mode boe_bp101wx1_100_mode = {
+   .clock = 78945,
+   .hdisplay = 1280,
+   .hsync_start = 1280 + 0,
+   .hsync_end = 1280 + 0 + 2,
+   .htotal = 1280 + 62 + 0 + 2,
+   .vdisplay = 800,
+   .vsync_start = 800 + 8,
+   .vsync_end = 800 + 8 + 2,
+   .vtotal = 800 + 6 + 8 + 2,
+};
+
+static const struct panel_desc boe_bp101wx1_100 = {
+   .modes = _bp101wx1_100_mode,
+   .num_modes = 1,
+   .bpc = 8,
+   .size = {
+   .width = 217,
+   .height = 136,
+   },
+   .delay = {
+   .enable = 50,
+   .disable = 50,
+   },
+   .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA,
+   .bus_flags = DRM_BUS_FLAG_DE_HIGH,
+   .connector_type = DRM_MODE_CONNECTOR_LVDS,
+};
+
 static const struct display_timing boe_ev121wxm_n10_1850_timing = {
.pixelclock = { 69922000, 7100, 72293000 },
.hactive = { 1280, 1280, 1280 },
@@ -4252,6 +4281,9 @@ static const struct of_device_id platform_of_match[] = {
}, {
.compatible = "bananapi,s070wv20-ct16",
.data = _s070wv20_ct16,
+   }, {
+   .compatible = "boe,bp101wx1-100",
+   .data = _bp101wx1_100,
}, {
.compatible = "boe,ev121wxm-n10-1850",
.data = _ev121wxm_n10_1850,
-- 
2.42.1


[PATCH 1/2] dt-bindings: display: simple: Add boe,bp101wx1-100 panel

2023-11-26 Thread Tony Lindgren
This panel is found on Motorola mapphone tablets mz615 to mz617.

Signed-off-by: Tony Lindgren 
---
 .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml 
b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
--- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
+++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml
@@ -73,6 +73,8 @@ properties:
   - auo,t215hvn01
 # Shanghai AVIC Optoelectronics 7" 1024x600 color TFT-LCD panel
   - avic,tm070ddh03
+# BOE BP101WX1-100 10.1" WXGA (1280x800) LVDS panel
+  - boe,bp101wx1-100
 # BOE EV121WXM-N10-1850 12.1" WXGA (1280x800) TFT LCD panel
   - boe,ev121wxm-n10-1850
 # BOE HV070WSA-100 7.01" WSVGA TFT LCD panel
-- 
2.42.1


[PATCH 6/6] drm/bridge: tc358775: Configure hs_rate and lp_rate

2023-11-26 Thread Tony Lindgren
The hs_rate and lp_rate may be used by the dsi host for timing
calculations. The tc358775 has a maximum bit rate of 1 Gbps/lane,
tc358765 has maximurate of 800 Mbps per lane.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -653,6 +653,11 @@ static int tc_attach_host(struct tc_data *tc)
dsi->format = MIPI_DSI_FMT_RGB888;
dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
MIPI_DSI_MODE_LPM;
+   if (tc->type == TC358765)
+   dsi->hs_rate = 8;
+   else
+   dsi->hs_rate = 10;
+   dsi->lp_rate = 1000;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.42.1


[PATCH 5/6] drm/bridge: tc358775: Add support for tc358765

2023-11-26 Thread Tony Lindgren
Looks like tc358775 is pin compatible with earlier tc358765 according to
the tc358774xbg_datasheet_en_20190118.pdf documentation. On tc358775,
there is an extra GPIO for STBY pin added, and few other improvments.

The tc358765 has a register bit for video event mode that we must set for
the LCD output to work. On tc358775, this bit no longer exists.

Looks like the registers seem to match otherwise based on a quick glance
comparing the defines to the earlier Android kernel tc358765 driver.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 55 +++
 1 file changed, 42 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -107,6 +108,7 @@
 #define RDPKTLN 0x0404  /* Command Read Packet Length */
 
 #define VPCTRL  0x0450  /* Video Path Control */
+#define EVTMODEBIT(5)  /* Video event mode enable, tc35876x 
only */
 #define HTIM1   0x0454  /* Horizontal Timing Control 1 */
 #define HTIM2   0x0458  /* Horizontal Timing Control 2 */
 #define VTIM1   0x045C  /* Vertical Timing Control 1 */
@@ -254,6 +256,11 @@ enum tc358775_ports {
TC358775_LVDS_OUT1,
 };
 
+enum tc3587x5_type {
+   TC358765,
+   TC358775,
+};
+
 struct tc_data {
struct i2c_client   *i2c;
struct device   *dev;
@@ -271,6 +278,8 @@ struct tc_data {
struct gpio_desc*stby_gpio;
u8  lvds_link; /* single-link or dual-link */
u8  bpc;
+
+   enum tc3587x5_type  type;
 };
 
 static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
@@ -294,8 +303,10 @@ static void tc_bridge_pre_enable(struct drm_bridge *bridge)
dev_err(dev, "regulator vdd enable failed, %d\n", ret);
usleep_range(1, 11000);
 
-   gpiod_set_value(tc->stby_gpio, 0);
-   usleep_range(1, 11000);
+   if (!IS_ERR(tc->stby_gpio)) {
+   gpiod_set_value(tc->stby_gpio, 0);
+   usleep_range(1, 11000);
+   }
 
gpiod_set_value(tc->reset_gpio, 0);
usleep_range(10, 20);
@@ -310,8 +321,10 @@ static void tc_bridge_post_disable(struct drm_bridge 
*bridge)
gpiod_set_value(tc->reset_gpio, 1);
usleep_range(10, 20);
 
-   gpiod_set_value(tc->stby_gpio, 1);
-   usleep_range(1, 11000);
+   if (!IS_ERR(tc->stby_gpio)) {
+   gpiod_set_value(tc->stby_gpio, 1);
+   usleep_range(1, 11000);
+   }
 
ret = regulator_disable(tc->vdd);
if (ret < 0)
@@ -424,10 +437,16 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
 
+   /* Video event mode, this bit does not exist for tc358775 */
+   if (tc->type == TC358765)
+   val = EVTMODE;
+   else
+   val = 0;
+
if (tc->bpc == 8)
-   val = TC358775_VPCTRL_OPXLFMT(1);
+   val |= TC358775_VPCTRL_OPXLFMT(1);
else /* bpc = 6; */
-   val = TC358775_VPCTRL_MSF(1);
+   val |= TC358775_VPCTRL_MSF(1);
 
dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
clkdiv = dsiclk / (tc->lvds_link == DUAL_LINK ? DIVIDE_BY_6 : 
DIVIDE_BY_3);
@@ -656,6 +675,7 @@ static int tc_probe(struct i2c_client *client)
 
tc->dev = dev;
tc->i2c = client;
+   tc->type = (enum tc3587x5_type)of_device_get_match_data(dev);
 
tc->panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node,
  TC358775_LVDS_OUT0, 0);
@@ -680,11 +700,15 @@ static int tc_probe(struct i2c_client *client)
return ret;
}
 
-   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
-   if (IS_ERR(tc->stby_gpio)) {
-   ret = PTR_ERR(tc->stby_gpio);
-   dev_err(dev, "cannot get stby-gpio %d\n", ret);
-   return ret;
+   if (tc->type == TC358775) {
+   tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
+   if (IS_ERR(tc->stby_gpio)) {
+   ret = PTR_ERR(tc->stby_gpio);
+   dev_err(dev, "cannot get stby-gpio %d\n", ret);
+   return ret;
+   }
+   } else {
+   tc->stby_gpio = ERR_PTR(-ENODEV);
}
 
tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
@@ -696,6 +720,7 @@ static int tc_probe(struct i2c_client *client)
 

[PATCH 4/6] drm/bridge: tc358775: Add burst and low-power modes

2023-11-26 Thread Tony Lindgren
Burst and low-power modes are supported both for tc358765 and tc358775.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -632,7 +632,8 @@ static int tc_attach_host(struct tc_data *tc)
 
dsi->lanes = tc->num_dsi_lanes;
dsi->format = MIPI_DSI_FMT_RGB888;
-   dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
+   dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
+   MIPI_DSI_MODE_LPM;
 
ret = devm_mipi_dsi_attach(dev, dsi);
if (ret < 0) {
-- 
2.42.1


[PATCH 3/6] drm/bridge: tc358775: Add jeida-24 support

2023-11-26 Thread Tony Lindgren
The jeida-24 register values are the default hardware settings, but they
not listed in the driver. Let's add them.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 21 ++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -458,8 +458,18 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
 * Default hardware register settings of tc358775 configured
 * with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
 */
-   if (connector->display_info.bus_formats[0] ==
-   MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
+   switch (connector->display_info.bus_formats[0]) {
+   case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
+   /* JEIDA-24 */
+   d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R2, LVI_R3, LVI_R4, 
LVI_R5));
+   d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R6, LVI_R1, LVI_R7, 
LVI_G2));
+   d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G3, LVI_G4, LVI_G0, 
LVI_G1));
+   d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G5, LVI_G6, LVI_G7, 
LVI_B2));
+   d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B0, LVI_B1, LVI_B3, 
LVI_B4));
+   d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B5, LVI_B6, LVI_B7, 
LVI_L0));
+   d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R0));
+   break;
+   case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
/* VESA-24 */
d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, 
LVI_G0));
@@ -468,7 +478,9 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_R6));
-   } else { /*  MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
+   break;
+   case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+   /* JEIDA-18 */
d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, 
LVI_R3));
d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, 
LVI_G0));
d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, 
LVI_L0));
@@ -476,6 +488,9 @@ static void tc_bridge_enable(struct drm_bridge *bridge)
d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, 
LVI_B2));
d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, 
LVI_L0));
d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, 
LVI_L0));
+   break;
+   default:
+   break;
}
 
d2l_write(tc->i2c, VFUEN, VFUEN_EN);
-- 
2.42.1


[PATCH 2/6] drm/bridge: tc358775: Fix getting dsi host data lanes

2023-11-26 Thread Tony Lindgren
The current code assume hardcoded dsi host endpoint 1, which may not
be the case. Let's fix that and simplify the code by getting the dsi
endpoint with of_graph_get_remote_endpoint() that does not assume any
endpoint numbering.

Fixes: b26975593b17 ("display/drm/bridge: TC358775 DSI/LVDS driver")
Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/bridge/tc358775.c | 16 
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/bridge/tc358775.c 
b/drivers/gpu/drm/bridge/tc358775.c
--- a/drivers/gpu/drm/bridge/tc358775.c
+++ b/drivers/gpu/drm/bridge/tc358775.c
@@ -528,25 +528,17 @@ tc_mode_valid(struct drm_bridge *bridge,
 static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
 {
struct device_node *endpoint;
-   struct device_node *parent;
struct device_node *remote;
int dsi_lanes = -1;
 
-   /*
-* To get the data-lanes of dsi, we need to access the dsi0_out of port1
-*  of dsi0 endpoint from bridge port0 of d2l_in
-*/
endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
 TC358775_DSI_IN, -1);
if (endpoint) {
-   /* dsi0_out node */
-   parent = of_graph_get_remote_port_parent(endpoint);
+   /* Get the configured data lanes on the dsi host side */
+   remote = of_graph_get_remote_endpoint(endpoint);
of_node_put(endpoint);
-   if (parent) {
-   /* dsi0 port 1 */
-   dsi_lanes = drm_of_get_data_lanes_count_ep(parent, 1, 
-1, 1, 4);
-   of_node_put(parent);
-   }
+   dsi_lanes = drm_of_get_data_lanes_count(remote, 1, 4);
+   of_node_put(remote);
}
 
if (dsi_lanes < 0)
-- 
2.42.1


[PATCH 1/6] dt-bindings: tc358775: Add support for tc358765

2023-11-26 Thread Tony Lindgren
The tc358765 is similar to tc358775 except for the stdby-gpios.

Signed-off-by: Tony Lindgren 
---
 .../display/bridge/toshiba,tc358775.yaml| 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git 
a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml 
b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
--- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
+++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml
@@ -10,7 +10,7 @@ maintainers:
   - Vinay Simha BN 
 
 description: |
-  This binding supports DSI to LVDS bridge TC358775
+  This binding supports DSI to LVDS bridges TC358765 and TC358775
 
   MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
   Video frame size:
@@ -21,7 +21,9 @@ description: |
 
 properties:
   compatible:
-const: toshiba,tc358775
+enum:
+  - toshiba,tc358765
+  - toshiba,tc358775
 
   reg:
 maxItems: 1
@@ -70,12 +72,21 @@ required:
   - reg
   - vdd-supply
   - vddio-supply
-  - stby-gpios
   - reset-gpios
   - ports
 
 additionalProperties: false
 
+allOf:
+  - if:
+  properties:
+compatible:
+  contains:
+const: toshiba,tc358775
+then:
+  required:
+- stby-gpios
+
 examples:
   - |
 #include 
-- 
2.42.1


Re: [PATCH] omap: dsi: do not WARN on detach if dsidev was never attached

2023-09-21 Thread Tony Lindgren
* Tomi Valkeinen  [230921 10:53]:
> I sent a patch to the DSI framework code,
> "[PATCH] drm/mipi-dsi: Fix detach call without attach".
> 
> If that fixes the issue (please test, I don't have a suitable platform),
> perhaps it's a better fix as detach really shouldn't be called if attach has
> not been called.

Yup that works for me, replied with my Tested-by on that thread.

Thanks,

Tony


Re: [PATCH] drm/mipi-dsi: Fix detach call without attach

2023-09-21 Thread Tony Lindgren
* Tomi Valkeinen  [230921 10:51]:
> mipi_dsi_host_unregister() will call two functions for all its DSI
> peripheral devices: mipi_dsi_detach() and mipi_dsi_device_unregister().
> The latter makes sense, as the device exists, but the former may be
> wrong as attach has not necessarily been done.
> 
> To fix this, track the attached state of the peripheral, and only detach
> from mipi_dsi_host_unregister() if the peripheral was attached.
> 
> Note that I have only tested this with a board with an i2c DSI
> peripheral, not with a "pure" DSI peripheral.

Thanks this fixes the deferred probe warning I've been seeing:

Tested-by: Tony Lindgren 


Re: [PATCH] omap: dsi: do not WARN on detach if dsidev was never attached

2023-09-19 Thread Tony Lindgren
* H. Nikolaus Schaller  [230919 13:38]:
> dsi_init_output() called by dsi_probe() may fail. In that
> case mipi_dsi_host_unregister() is called which may call
> omap_dsi_host_detach() with uninitialized dsi->dsidev
> because omap_dsi_host_attach() was never called before.
> 
> This happens if the panel driver asks for an EPROBE_DEFER.
> 
> So let's suppress the WARN() in this special case.

Reviewed-by: Tony Lindgren 

Thanks,

Tony


Re: [PATCH] drm/omap: dsi: Fix deferred probe warnings

2023-09-17 Thread Tony Lindgren
* H. Nikolaus Schaller  [230916 12:50]:
> Hi Tomi and Tony,
> 
> > Am 13.09.2023 um 13:59 schrieb Tomi Valkeinen 
> > :
> > 
> > On 12/04/2023 10:39, Tony Lindgren wrote:
> >> We may not have dsi->dsidev initialized during probe, and that can
> >> lead into various dsi related warnings as omap_dsi_host_detach() gets
> >> called with dsi->dsidev set to NULL.
> >> The warnings can be "Fixed dependency cycle(s)" followed by a
> >> WARNING: CPU: 0 PID: 787 at drivers/gpu/drm/omapdrm/dss/dsi.c:4414.
> >> Let's fix the warnings by checking for a valid dsi->dsidev.
> >> Signed-off-by: Tony Lindgren 
> >> ---
> >>  drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
> >> b/drivers/gpu/drm/omapdrm/dss/dsi.c
> >> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> >> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> >> @@ -4411,7 +4411,7 @@ static int omap_dsi_host_detach(struct mipi_dsi_host 
> >> *host,
> >>  {
> >>struct dsi_data *dsi = host_to_omap(host);
> >>  - if (WARN_ON(dsi->dsidev != client))
> >> +  if (dsi->dsidev && WARN_ON(dsi->dsidev != client))
> >>return -EINVAL;
> >>cancel_delayed_work_sync(>dsi_disable_work);
> > 
> > Shouldn't this rather be
> > 
> > if (!dsi->dsidev)
> > return 0;
> > 
> > before the if (WARN_ON(dsi->dsidev != client)) line?
> 
> Yes you are right. We have a different variant in our Pyra kernel:
> 
> What we currently have in our Pyra tree is: 
> https://git.goldelico.com/?p=letux-kernel.git;a=commitdiff;h=5bf7bd64eec1eb924e794e8d6600919f0dae8c5a;hp=27a0cd6263194d1465e9c53293d35f8c8c988f9d
> 
> struct dsi_data *dsi = host_to_omap(host);
>  
> -   if (WARN_ON(dsi->dsidev != client))
> +printk("%s\n", __func__);
> +
> +   if (!dsi->dsidev || WARN_ON(dsi->dsidev != client))
> return -EINVAL;
>  
> cancel_delayed_work_sync(>dsi_disable_work);
> 
> > 
> > If dsi->dsidev is NULL, then attach hasn't been called, and we shouldn't do 
> > anything in the detach callback either.
> > 
> > With your change we'll end up doing all the work in the detach callback, 
> > without ever doing their counterpart in the attach side.
> 
> If useful, I can post above mentioned patch (without printk).

Sounds good to me.

Thanks,

Tony


Re: [PATCH] drm/omap: dsi: Fix deferred probe warnings

2023-09-13 Thread Tony Lindgren
* Tomi Valkeinen  [230913 11:59]:
> On 12/04/2023 10:39, Tony Lindgren wrote:
> > We may not have dsi->dsidev initialized during probe, and that can
> > lead into various dsi related warnings as omap_dsi_host_detach() gets
> > called with dsi->dsidev set to NULL.
> > 
> > The warnings can be "Fixed dependency cycle(s)" followed by a
> > WARNING: CPU: 0 PID: 787 at drivers/gpu/drm/omapdrm/dss/dsi.c:4414.
> > 
> > Let's fix the warnings by checking for a valid dsi->dsidev.
> > 
> > Signed-off-by: Tony Lindgren 
> > ---
> >   drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
> > b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> > +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > @@ -4411,7 +4411,7 @@ static int omap_dsi_host_detach(struct mipi_dsi_host 
> > *host,
> >   {
> > struct dsi_data *dsi = host_to_omap(host);
> > -   if (WARN_ON(dsi->dsidev != client))
> > +   if (dsi->dsidev && WARN_ON(dsi->dsidev != client))
> > return -EINVAL;
> > cancel_delayed_work_sync(>dsi_disable_work);
> 
> Shouldn't this rather be
> 
> if (!dsi->dsidev)
>   return 0;
> 
> before the if (WARN_ON(dsi->dsidev != client)) line?
> 
> If dsi->dsidev is NULL, then attach hasn't been called, and we shouldn't do
> anything in the detach callback either.
> 
> With your change we'll end up doing all the work in the detach callback,
> without ever doing their counterpart in the attach side.

Oops, I'll check that thanks.

Tony


Re: [RFC PATCH] drm: omapdrm: dsi: add refsel also for omap4

2023-09-13 Thread Tony Lindgren
* Tomi Valkeinen  [230913 12:11]:
> I'm somewhat sure that the upstream driver used to work on omap4 sdp, which
> has two DSI panels. But I can't even remember what omap4 version it had.

I think those were both dsi command mode panels though, not video mode?

Regards,

Tony


Re: [PATCH] drm/omap: dsi: Fix deferred probe warnings

2023-09-13 Thread Tony Lindgren
* Laurent Pinchart  [230412 11:59]:
> On Wed, Apr 12, 2023 at 11:55:34AM +0300, Tomi Valkeinen wrote:
> > On 12/04/2023 11:50, Laurent Pinchart wrote:
> > > Hi Tony,
> > > 
> > > Thank you for the patch.
> > > 
> > > On Wed, Apr 12, 2023 at 10:39:53AM +0300, Tony Lindgren wrote:
> > >> We may not have dsi->dsidev initialized during probe, and that can
> > >> lead into various dsi related warnings as omap_dsi_host_detach() gets
> > >> called with dsi->dsidev set to NULL.
> > >>
> > >> The warnings can be "Fixed dependency cycle(s)" followed by a
> > >> WARNING: CPU: 0 PID: 787 at drivers/gpu/drm/omapdrm/dss/dsi.c:4414.
> > > 
> > > How can this happen ? I assume .detach() can't be called without a
> > > priori successful call to .attach(), that that sets dsi->dsidev.
> > 
> > I had a quick look, and the driver calls mipi_dsi_host_register() in 
> > probe, and mipi_dsi_host_unregister() in remove.
> > 
> > mipi_dsi_host_unregister() always calls mipi_dsi_detach(), but I don't 
> > think mipi_dsi_host_register() always calls attach, which happens later 
> > when the peripheral probes.
> 
> Is this something that should be addressed in the DRM MIPI DSI helpers,
> to only detach after an attach ?

Tomi, any comments on detach after attach?

Regards,

Tony

> > >> Let's fix the warnings by checking for a valid dsi->dsidev.
> > >>
> > >> Signed-off-by: Tony Lindgren 
> > >> ---
> > >>   drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
> > >>   1 file changed, 1 insertion(+), 1 deletion(-)
> > >>
> > >> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
> > >> b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > >> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> > >> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> > >> @@ -4411,7 +4411,7 @@ static int omap_dsi_host_detach(struct 
> > >> mipi_dsi_host *host,
> > >>   {
> > >>  struct dsi_data *dsi = host_to_omap(host);
> > >>   
> > >> -if (WARN_ON(dsi->dsidev != client))
> > >> +if (dsi->dsidev && WARN_ON(dsi->dsidev != client))
> > >>  return -EINVAL;
> > >>   
> > >>  cancel_delayed_work_sync(>dsi_disable_work);
> 
> -- 
> Regards,
> 
> Laurent Pinchart
> 


Re: [RFC PATCH] drm: omapdrm: dsi: add refsel also for omap4

2023-09-13 Thread Tony Lindgren
* Andreas Kemnade  [230913 06:59]:
> Some 3.0 source has it set behind a if (omap4).
> Maybe it is helpful maybe not, at least in the omap4460
> trm these bits are marked as reserved.
> But maybe some dsi video mode panel starts magically working.

Interesting. So Andreas mentioned that dsi video mode works on omap5
but not on omap4. Adding Sebastian to the list too.

Regards,

Tony

> 
> Signed-off-by: Andreas Kemnade 
> ---
>  drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
> b/drivers/gpu/drm/omapdrm/dss/dsi.c
> index 60189a23506a1..e2f576cd9f63c 100644
> --- a/drivers/gpu/drm/omapdrm/dss/dsi.c
> +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
> @@ -4505,7 +4505,7 @@ static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
>   .has_stopmode = true,
>   .has_freqsel = false,
>   .has_selfreqdco = false,
> - .has_refsel = false,
> + .has_refsel = true,
>  };
>  
>  static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
> -- 
> 2.39.2
> 


[PATCH] drm/omap: dsi: Fix deferred probe warnings

2023-04-12 Thread Tony Lindgren
We may not have dsi->dsidev initialized during probe, and that can
lead into various dsi related warnings as omap_dsi_host_detach() gets
called with dsi->dsidev set to NULL.

The warnings can be "Fixed dependency cycle(s)" followed by a
WARNING: CPU: 0 PID: 787 at drivers/gpu/drm/omapdrm/dss/dsi.c:4414.

Let's fix the warnings by checking for a valid dsi->dsidev.

Signed-off-by: Tony Lindgren 
---
 drivers/gpu/drm/omapdrm/dss/dsi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c 
b/drivers/gpu/drm/omapdrm/dss/dsi.c
--- a/drivers/gpu/drm/omapdrm/dss/dsi.c
+++ b/drivers/gpu/drm/omapdrm/dss/dsi.c
@@ -4411,7 +4411,7 @@ static int omap_dsi_host_detach(struct mipi_dsi_host 
*host,
 {
struct dsi_data *dsi = host_to_omap(host);
 
-   if (WARN_ON(dsi->dsidev != client))
+   if (dsi->dsidev && WARN_ON(dsi->dsidev != client))
return -EINVAL;
 
cancel_delayed_work_sync(>dsi_disable_work);
-- 
2.40.0


Re: [PATCH v3 4/6] ARM: dts: omap: Use new media bus type macros

2023-01-19 Thread Tony Lindgren
* Laurent Pinchart  [230114 15:37]:
> Tony, could you take this patch in your tree for v6.3 ? The two patches
> that it depends on have both been merged in v6.2.

OK applying into omap-for-v6.3/dt.

Thanks,

Tony


  1   2   3   4   >