Re: [PATCH] drm/komeda: Drop local dma_parms

2020-09-13 Thread james qian wang (Arm Technology China)
On Thu, Sep 03, 2020 at 10:26:50PM +0100, Robin Murphy wrote:
> On 2020-09-03 21:36, Robin Murphy wrote:
> > Since commit 9495b7e92f71 ("driver core: platform: Initialize dma_parms
> > for platform devices"), struct platform_device already provides a
> > dma_parms structure, so we can save allocating another one.
> > 
> > Signed-off-by: Robin Murphy 
> > ---
> > 
> > FYI, get_maintainer.pl seems to be choking on your L: entry somehow,
> > since it just shows " (open list:ARM KOMEDA DRM-KMS DRIVER)" without the
> > description or address, not sure what's up with that.
> > 
> >   drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 1 -
> >   drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 2 --
> >   2 files changed, 3 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > index 1d767473ba8a..e7bb905062d9 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > @@ -261,7 +261,6 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
> > goto disable_clk;
> > }
> > 
> > -   dev->dma_parms = >dma_parms;
> > dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
> 
> Oops, I missed my "Also the DMA segment size is simply a size, not a
> bitmask" bit here - ideally this should be changed to UINT_MAX while we're
> cleaning up. Maybe that could just be fixed up when applying, but let me
> know if you'd like a resend.

Don't worry, I can fix it when applying. :)

And thank you for this patch.

Reviewed-by: James Qian Wang 

> Cheers,
> Robin.
> 
> > mdev->iommu = iommu_get_domain_for_dev(mdev->dev);
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > index ce27f2f27c24..5b536f0cb548 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > @@ -163,8 +163,6 @@ struct komeda_dev {
> > struct device *dev;
> > /** @reg_base: the base address of komeda io space */
> > u32 __iomem   *reg_base;
> > -   /** @dma_parms: the dma parameters of komeda */
> > -   struct device_dma_parameters dma_parms;
> > 
> > /** @chip: the basic chip information */
> > struct komeda_chip_info chip;
> > --
> > 2.28.0.dirty
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> > 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH -next] drm/komeda: Convert to DEFINE_SHOW_ATTRIBUTE

2020-07-17 Thread james qian wang (Arm Technology China)
On Fri, Jul 17, 2020 at 09:06:57AM +0200, Daniel Vetter wrote:
> On Fri, Jul 17, 2020 at 8:40 AM james qian wang (Arm Technology China)
>  wrote:
> >
> > On Thu, Jul 16, 2020 at 05:03:33PM +0800, Qinglang Miao wrote:
> > > From: Liu Shixin 
> > >
> > > Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.
> > >
> > > Signed-off-by: Liu Shixin 
> > > ---
> > >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 13 +
> > >  1 file changed, 1 insertion(+), 12 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> > > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > > index 0246b2e94..4a10e6b9e 100644
> > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > > @@ -41,18 +41,7 @@ static int komeda_register_show(struct seq_file *sf, 
> > > void *x)
> > >   return 0;
> > >  }
> > >
> > > -static int komeda_register_open(struct inode *inode, struct file *filp)
> > > -{
> > > - return single_open(filp, komeda_register_show, inode->i_private);
> > > -}
> > > -
> > > -static const struct file_operations komeda_register_fops = {
> > > - .owner  = THIS_MODULE,
> > > - .open   = komeda_register_open,
> > > - .read_iter  = seq_read_iter,

-   .read   = seq_read,
+   .read_iter  = seq_read_iter,

> > > - .llseek = seq_lseek,
> > > - .release= single_release,
> > > -};
> > > +DEFINE_SHOW_ATTRIBUTE(komeda_register);
> > >
> >
> > Hi Shixin & Qinglang
> >
> > Thanks for your patch.
> >
> > Reviewed-by: James Qian Wang 
> >
> > Since your patch is not for drm-misc-next, so seems better
> > to leave it to you to merge it. :)
> 
> I do think it's for drm-misc-next, what other tree would it be for?
> Some people put -next in their patch tag to differentiate from -fixes,
> so maintainers know what to do with the patch. It's also not part of a
> series, hence I think this is on you to apply it.
> 
> Cheers, Daniel

Hi Daniel:

I tried to apply this patch to drm-misc-next, but failed, and found
this patch is actually based on linux-next, and the code base of
linux-next is a little different with our drm-misc-next.
and one of the difference is linux-next has a patch (call it patch-A):

seq_file: switch over direct seq_read method calls to seq_read_iter
https://lkml.org/lkml/2020/7/7/1267

which changed code like below:

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 1d767473ba8a06..0246b2e94d8cbd 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -49,7 +49,7 @@ static int komeda_register_open(struct inode *inode, struct 
file *filp)
 static const struct file_operations komeda_register_fops = {
.owner  = THIS_MODULE,
.open   = komeda_register_open,
-   .read   = seq_read,
+   .read_iter  = seq_read_iter,
.llseek = seq_lseek,
.release= single_release,
 };

And these code will be deleted by this patch, if we merge this patch into
drm-misc-next firstly before the patch-A, that may import a conflict when
we merge our misc into upstreams.

if we want it to be merged into drm-misc, I think we'd better to wait the
upstream (the patch-A) has been synced back to drm-misc.

And what's your opinion ?

Thanks
James

> >
> > Thanks
> > James
> >
> > >  #ifdef CONFIG_DEBUG_FS
> > >  static void komeda_debugfs_init(struct komeda_dev *mdev)
> > > --
> > > 2.17.1
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
> 
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH -next] drm/komeda: Convert to DEFINE_SHOW_ATTRIBUTE

2020-07-17 Thread james qian wang (Arm Technology China)
On Thu, Jul 16, 2020 at 05:03:33PM +0800, Qinglang Miao wrote:
> From: Liu Shixin 
> 
> Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code.
> 
> Signed-off-by: Liu Shixin 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.c | 13 +
>  1 file changed, 1 insertion(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> index 0246b2e94..4a10e6b9e 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> @@ -41,18 +41,7 @@ static int komeda_register_show(struct seq_file *sf, void 
> *x)
>   return 0;
>  }
>  
> -static int komeda_register_open(struct inode *inode, struct file *filp)
> -{
> - return single_open(filp, komeda_register_show, inode->i_private);
> -}
> -
> -static const struct file_operations komeda_register_fops = {
> - .owner  = THIS_MODULE,
> - .open   = komeda_register_open,
> - .read_iter  = seq_read_iter,
> - .llseek = seq_lseek,
> - .release= single_release,
> -};
> +DEFINE_SHOW_ATTRIBUTE(komeda_register);
>

Hi Shixin & Qinglang

Thanks for your patch.

Reviewed-by: James Qian Wang 

Since your patch is not for drm-misc-next, so seems better
to leave it to you to merge it. :)

Thanks
James

>  #ifdef CONFIG_DEBUG_FS
>  static void komeda_debugfs_init(struct komeda_dev *mdev)
> -- 
> 2.17.1
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 06/20] Documentation: gpu/komeda-kms: eliminate duplicated word

2020-07-08 Thread james qian wang (Arm Technology China)
On Tue, Jul 07, 2020 at 11:04:00AM -0700, Randy Dunlap wrote:
> Drop the doubled word "and".
> 
> Signed-off-by: Randy Dunlap 
> Cc: Jonathan Corbet 
> Cc: linux-...@vger.kernel.org
> Cc: James (Qian) Wang 
> Cc: Liviu Dudau 
> Cc: Mihail Atanassov 
> Cc: Mali DP Maintainers 
> ---
>  Documentation/gpu/komeda-kms.rst |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- linux-next-20200701.orig/Documentation/gpu/komeda-kms.rst
> +++ linux-next-20200701/Documentation/gpu/komeda-kms.rst
> @@ -41,7 +41,7 @@ Compositor blends multiple layers or pix
>  frame. its output frame can be fed into post image processor for showing it 
> on
>  the monitor or fed into wb_layer and written to memory at the same time.
>  user can also insert a scaler between compositor and wb_layer to down scale
> -the display frame first and and then write to memory.
> +the display frame first and then write to memory.
>

Thank you Randy

Reviewed-by: James Qian Wang 

>  Writeback Layer (wb_layer)
>  --
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 07/25] drm/komdea: Annotate dma-fence critical section in commit path

2020-07-07 Thread james qian wang (Arm Technology China)
On Tue, Jul 07, 2020 at 10:12:11PM +0200, Daniel Vetter wrote:
> Like the helpers, nothing special. Well except not, because we the
> critical section extends until after hw_done(), since that's the last
> thing which could hold up a subsequent atomic commit. That means the
> wait_for_flip_done is included, but that's not a problem, we're
> allowed to call dma_fence_wait() from signalling critical sections.
> Even on our own fence (which this does), it's just a bit confusing.
> But in a way those last 2 function calls are already part of the fence
> signalling critical section for the next atomic commit.
> 
> Reading this I'm wondering why komeda waits for flip_done() before
> calling hw_done(), which is a bit backwards (but hey hw can be
> special). Might be good to throw a comment in there that explains why,
> because the original commit that added this just doesn't.

Hi Daniel:

It's a typo, thank you for pointing this out, and I'll give a fix after
this series have been merged.

for this patch

Reviewed-by: James Qian Wang 

> Cc: "James (Qian) Wang" 
> Cc: Liviu Dudau 
> Cc: Mihail Atanassov 
> Signed-off-by: Daniel Vetter 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 1f6682032ca4..cc5b5915bc5e 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -73,6 +73,7 @@ static struct drm_driver komeda_kms_driver = {
>  static void komeda_kms_commit_tail(struct drm_atomic_state *old_state)
>  {
>   struct drm_device *dev = old_state->dev;
> + bool fence_cookie = dma_fence_begin_signalling();
>  
>   drm_atomic_helper_commit_modeset_disables(dev, old_state);
>  
> @@ -85,6 +86,8 @@ static void komeda_kms_commit_tail(struct drm_atomic_state 
> *old_state)
>  
>   drm_atomic_helper_commit_hw_done(old_state);
>  
> + dma_fence_end_signalling(fence_cookie);
> +
>   drm_atomic_helper_cleanup_planes(dev, old_state);
>  }
>  
> -- 
> 2.27.0
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 06/20] Documentation: gpu/komeda-kms: eliminate duplicated word

2020-07-07 Thread james qian wang (Arm Technology China)
Hi Randy

On Tue, Jul 07, 2020 at 11:04:00AM -0700, Randy Dunlap wrote:
> Drop the doubled word "and".
> 
> Signed-off-by: Randy Dunlap 
> Cc: Jonathan Corbet 
> Cc: linux-...@vger.kernel.org
> Cc: James (Qian) Wang 
> Cc: Liviu Dudau 
> Cc: Mihail Atanassov 
> Cc: Mali DP Maintainers 
> ---
>  Documentation/gpu/komeda-kms.rst |2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> --- linux-next-20200701.orig/Documentation/gpu/komeda-kms.rst
> +++ linux-next-20200701/Documentation/gpu/komeda-kms.rst
> @@ -41,7 +41,7 @@ Compositor blends multiple layers or pix
>  frame. its output frame can be fed into post image processor for showing it 
> on
>  the monitor or fed into wb_layer and written to memory at the same time.
>  user can also insert a scaler between compositor and wb_layer to down scale
> -the display frame first and and then write to memory.
> +the display frame first and then write to memory.

Thank you for the patch.

Reviewed-by: James Qian Wang 

>  Writeback Layer (wb_layer)
>  --
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 36/44] drm/komeda: use devm_drm_dev_alloc

2020-04-08 Thread james qian wang (Arm Technology China)
On Fri, Apr 03, 2020 at 09:58:20PM +0800, Daniel Vetter wrote:
> Komeda uses the component framework, which does open/close a new
> devres group around all the bind callbacks. Which means we can use
> devm_ functions for managing the drm_device cleanup, with leaking
> stuff in case of deferred probes or other reasons to unbind
> components, or the component_master.
> 
> Also note that this fixes a double-free in the probe unroll code, bot
> drm_dev_put and kfree(kms) result in the kms allocation getting freed.
> 
> Aside: komeda_bind could be cleaned up a lot, devm_kfree is a bit
> redundant. Plus I'm not clear on why there's suballocations for
> mdrv->mdev and mdrv->kms. Plus I'm not sure the lifetimes are correct
> with all that devm_kzalloc usage ... That structure layout is also the
> reason why komeda still uses drm_device->dev_private and can't easily
> be replaced with a proper container_of upcasting. I'm pretty sure that
> there's endless amounts of hotunplug/hotremove bugs in there with all
> the unprotected dereferencing of drm_device->dev_private.

Hi Daniel:

Thank you for the patch.

Reviewed-by: James Qian Wang 

For why komeda has two devices komeda_dev and komeda_kms_dev. 
That because komeda treats drm_crtc/plane as virtual, which pick the real
komeda resources to satify the user's requirement. In the initial driver
design we want to clear the difference of these two class structures
so we defined two devices:

- komeda_dev:
  managing the real komeda device and resources.

- komeda_kms_dev
  the virtual device managing the drm related stuff like
  komeda_crtc/plane.

And yes, even for that we don't need two sub-allocations, we are planing
to move the komeda_dev into the komeda_kms_dev or just merge two devices
together.

Thanks
James

> Signed-off-by: Daniel Vetter 
> Cc: "James (Qian) Wang" 
> Cc: Liviu Dudau 
> Cc: Mihail Atanassov 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_kms.c | 16 +---
>  1 file changed, 5 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> index 16dfd5cdb66c..6b85d5f4caa8 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c
> @@ -261,18 +261,16 @@ static void komeda_kms_mode_config_init(struct 
> komeda_kms_dev *kms,
>  
>  struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
>  {
> - struct komeda_kms_dev *kms = kzalloc(sizeof(*kms), GFP_KERNEL);
> + struct komeda_kms_dev *kms;
>   struct drm_device *drm;
>   int err;
>  
> - if (!kms)
> - return ERR_PTR(-ENOMEM);
> + kms = devm_drm_dev_alloc(mdev->dev, _kms_driver,
> +  struct komeda_kms_dev, base);
> + if (IS_ERR(kms))
> + return kms;
>  
>   drm = >base;
> - err = drm_dev_init(drm, _kms_driver, mdev->dev);
> - if (err)
> - goto free_kms;
> - drmm_add_final_kfree(drm, kms);
>  
>   drm->dev_private = mdev;
>  
> @@ -329,9 +327,6 @@ struct komeda_kms_dev *komeda_kms_attach(struct 
> komeda_dev *mdev)
>   drm_mode_config_cleanup(drm);
>   komeda_kms_cleanup_private_objs(kms);
>   drm->dev_private = NULL;
> - drm_dev_put(drm);
> -free_kms:
> - kfree(kms);
>   return ERR_PTR(err);
>  }
>  
> @@ -348,5 +343,4 @@ void komeda_kms_detach(struct komeda_kms_dev *kms)
>   drm_mode_config_cleanup(drm);
>   komeda_kms_cleanup_private_objs(kms);
>   drm->dev_private = NULL;
> - drm_dev_put(drm);
>  }
> -- 
> 2.25.1
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv7 2/6] drm/core: Add drm_afbc_framebuffer and a corresponding helper

2020-03-16 Thread james qian wang (Arm Technology China)
On Wed, Mar 11, 2020 at 10:55:37PM +0800, Andrzej Pietrasiewicz wrote:
> The new struct contains afbc-specific data.
> 
> The new function can be used by drivers which support afbc to complete
> the preparation of struct drm_afbc_framebuffer. It must be called after
> allocating the said struct and calling drm_gem_fb_init_with_funcs().
> 
> Signed-off-by: Andrzej Pietrasiewicz 

Looks good to me.

Reviewed-by: James Qian Wang 

Thanks
James
> ---
>  Documentation/gpu/todo.rst   |  15 +++
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 108 +++
>  include/drm/drm_framebuffer.h|  45 
>  include/drm/drm_gem_framebuffer_helper.h |  10 ++
>  4 files changed, 178 insertions(+)
> 
> diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
> index 439656f55c5d..37a3a023c114 100644
> --- a/Documentation/gpu/todo.rst
> +++ b/Documentation/gpu/todo.rst
> @@ -404,6 +404,21 @@ Contact: Laurent Pinchart, respective driver maintainers
>  
>  Level: Intermediate
>  
> +Encode cpp properly in malidp
> +-
> +
> +cpp (chars per pixel) is not encoded properly in malidp, zero is
> +used instead. afbc implementation needs bpp or cpp, but if it is
> +zero it needs to be provided elsewhere, and so the bpp field exists
> +in struct drm_afbc_framebuffer.
> +
> +Properly encode cpp in malidp and remove the bpp field in struct
> +drm_afbc_framebuffer.
> +
> +Contact: malidp maintainers
> +
> +Level: Intermediate
> +
>  Core refactorings
>  =
>  
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 86c1907c579a..7e3982c36baa 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -21,6 +21,13 @@
>  #include 
>  #include 
>  
> +#define AFBC_HEADER_SIZE 16
> +#define AFBC_TH_LAYOUT_ALIGNMENT 8
> +#define AFBC_HDR_ALIGN   64
> +#define AFBC_SUPERBLOCK_PIXELS   256
> +#define AFBC_SUPERBLOCK_ALIGNMENT128
> +#define AFBC_TH_BODY_START_ALIGNMENT 4096
> +
>  /**
>   * DOC: overview
>   *
> @@ -302,6 +309,107 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, 
> struct drm_file *file,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
>  
> +static int drm_gem_afbc_min_size(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd,
> +  struct drm_afbc_framebuffer *afbc_fb)
> +{
> + const struct drm_format_info *info;
> + __u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
> + /* remove bpp when all users properly encode cpp in drm_format_info */
> + __u32 bpp;
> +
> + switch (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> + afbc_fb->block_width = 16;
> + afbc_fb->block_height = 16;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> + afbc_fb->block_width = 32;
> + afbc_fb->block_height = 8;
> + break;
> + /* no user exists yet - fall through */
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> + default:
> + DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> +   mode_cmd->modifier[0]
> +   & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> + return -EINVAL;
> + }
> +
> + /* tiled header afbc */
> + w_alignment = afbc_fb->block_width;
> + h_alignment = afbc_fb->block_height;
> + hdr_alignment = AFBC_HDR_ALIGN;
> + if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
> + w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
> + h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
> + hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT;
> + }
> +
> + afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment);
> + afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
> + afbc_fb->offset = mode_cmd->offsets[0];
> +
> + info = drm_get_format_info(dev, mode_cmd);
> + /*
> +  * Change to always using info->cpp[0]
> +  * when all users properly encode it
> +  */
> + bpp = info->cpp[0] ? info->cpp[0] * 8 : afbc_fb->bpp;
> +
> + n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height)
> +/ AFBC_SUPERBLOCK_PIXELS;
> + afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
> + afbc_fb->afbc_size += n_blocks * ALIGN(bpp * AFBC_SUPERBLOCK_PIXELS / 8,
> +AFBC_SUPERBLOCK_ALIGNMENT);
> +
> + return 0;
> +}
> +
> +/**
> + * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to
> + *   fill and validate all the afbc-specific
> + *   struct drm_afbc_framebuffer members
> + *
> + 

Re: [PATCHv7 1/6] drm/core: Allow drivers allocate a subclass of struct drm_framebuffer

2020-03-16 Thread james qian wang (Arm Technology China)
On Wed, Mar 11, 2020 at 10:55:36PM +0800, Andrzej Pietrasiewicz wrote:
> Allow allocating a specialized version of struct drm_framebuffer
> by moving the actual fb allocation out of drm_gem_fb_create_with_funcs();
> the respective functions names are adjusted to reflect that fact.
> Please note, though, that standard size checks are performed on buffers,
> so the drm_gem_fb_init_with_funcs() is useful for cases where those
> standard size checks are appropriate or at least don't conflict the
> checks to be performed in the specialized case.
> 
> Thanks to this change the drivers can call drm_gem_fb_init_with_funcs()
> having allocated their special version of struct drm_framebuffer, exactly
> the way the new version of drm_gem_fb_create_with_funcs() does.
> 
> Signed-off-by: Andrzej Pietrasiewicz 

Looks good to me. :)

Reviewed-by: James Qian Wang 

Thanks
James

> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 87 ++--
>  include/drm/drm_gem_framebuffer_helper.h |  5 ++
>  2 files changed, 67 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 3a7ace19a902..86c1907c579a 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -54,19 +54,15 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
> drm_framebuffer *fb,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
>  
> -static struct drm_framebuffer *
> -drm_gem_fb_alloc(struct drm_device *dev,
> +static int
> +drm_gem_fb_init(struct drm_device *dev,
> +  struct drm_framebuffer *fb,
>const struct drm_mode_fb_cmd2 *mode_cmd,
>struct drm_gem_object **obj, unsigned int num_planes,
>const struct drm_framebuffer_funcs *funcs)
>  {
> - struct drm_framebuffer *fb;
>   int ret, i;
>  
> - fb = kzalloc(sizeof(*fb), GFP_KERNEL);
> - if (!fb)
> - return ERR_PTR(-ENOMEM);
> -
>   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
>  
>   for (i = 0; i < num_planes; i++)
> @@ -76,10 +72,9 @@ drm_gem_fb_alloc(struct drm_device *dev,
>   if (ret) {
>   drm_err(dev, "Failed to init framebuffer: %d\n", ret);
>   kfree(fb);
> - return ERR_PTR(ret);
>   }
>  
> - return fb;
> + return ret;
>  }
>  
>  /**
> @@ -123,10 +118,13 @@ int drm_gem_fb_create_handle(struct drm_framebuffer 
> *fb, struct drm_file *file,
>  EXPORT_SYMBOL(drm_gem_fb_create_handle);
>  
>  /**
> - * drm_gem_fb_create_with_funcs() - Helper function for the
> - *  _mode_config_funcs.fb_create
> - *  callback
> + * drm_gem_fb_init_with_funcs() - Helper function for implementing
> + * _mode_config_funcs.fb_create
> + * callback in cases when the driver
> + * allocates a subclass of
> + * struct drm_framebuffer
>   * @dev: DRM device
> + * @fb: framebuffer object
>   * @file: DRM file that holds the GEM handle(s) backing the framebuffer
>   * @mode_cmd: Metadata from the userspace framebuffer creation request
>   * @funcs: vtable to be used for the new framebuffer object
> @@ -134,23 +132,26 @@ EXPORT_SYMBOL(drm_gem_fb_create_handle);
>   * This function can be used to set _framebuffer_funcs for drivers that 
> need
>   * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
>   * change _framebuffer_funcs. The function does buffer size validation.
> + * The buffer size validation is for a general case, though, so users should
> + * pay attention to the checks being appropriate for them or, at least,
> + * non-conflicting.
>   *
>   * Returns:
> - * Pointer to a _framebuffer on success or an error pointer on failure.
> + * Zero or a negative error code.
>   */
> -struct drm_framebuffer *
> -drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
> -  const struct drm_mode_fb_cmd2 *mode_cmd,
> -  const struct drm_framebuffer_funcs *funcs)
> +int drm_gem_fb_init_with_funcs(struct drm_device *dev,
> +struct drm_framebuffer *fb,
> +struct drm_file *file,
> +const struct drm_mode_fb_cmd2 *mode_cmd,
> +const struct drm_framebuffer_funcs *funcs)
>  {
>   const struct drm_format_info *info;
>   struct drm_gem_object *objs[4];
> - struct drm_framebuffer *fb;
>   int ret, i;
>  
>   info = drm_get_format_info(dev, mode_cmd);
>   if (!info)
> - return ERR_PTR(-EINVAL);
> + return -EINVAL;
>  
>   for (i = 0; i < info->num_planes; i++) {
>   unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> @@ -175,19 +176,55 @@ drm_gem_fb_create_with_funcs(struct 

Re: [PATCH] drm: komeda: Make rt_pm_ops dependent on CONFIG_PM

2020-03-05 Thread james qian wang (Arm Technology China)
On Fri, Mar 06, 2020 at 02:42:55AM +0800, Liviu Dudau wrote:
> On Wed, Mar 04, 2020 at 02:54:12PM +, Vincenzo Frascino wrote:
> > komeda_rt_pm_suspend() and komeda_rt_pm_resume() are compiled only when
> > CONFIG_PM is enabled. Having it disabled triggers the following warning
> > at compile time:
> > 
> > linux/drivers/gpu/drm/arm/display/komeda/komeda_drv.c:156:12:
> > warning: ‘komeda_rt_pm_resume’ defined but not used [-Wunused-function]
> >  static int komeda_rt_pm_resume(struct device *dev)
> > ^~~
> > linux/drivers/gpu/drm/arm/display/komeda/komeda_drv.c:149:12:
> > warning: ‘komeda_rt_pm_suspend’ defined but not used [-Wunused-function]
> >  static int komeda_rt_pm_suspend(struct device *dev)
> > 
> > Make komeda_rt_pm_suspend() and komeda_rt_pm_resume() dependent on
> > CONFIG_PM to address the issue.
> > 
> > Cc: "James (Qian) Wang" 
> > Cc: Liviu Dudau 
> > Cc: Mihail Atanassov 
> > Cc: Brian Starkey 
> > Cc: David Airlie 
> > Cc: Daniel Vetter 
> > Signed-off-by: Vincenzo Frascino 
>

Hi Vincenzo:

Thanks for the patch.

and Vincenzo & Liviu, sorry

Since there is a patch for this problem already:
https://patchwork.freedesktop.org/series/71721/

And I have pushed that old fix to drm-misc-fixes just before I saw
this mail. sorry.

> Acked-by: Liviu Dudau 
> 
> Thanks for the patch, I will push it into drm-misc-fixes tomorrow.
> 
> Best regards,
> Liviu
> 
> > ---
> >  drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 2 ++
> >  1 file changed, 2 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > index ea5cd1e17304..dd3ae3d88687 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> > @@ -146,6 +146,7 @@ static const struct of_device_id komeda_of_match[] = {
> >  
> >  MODULE_DEVICE_TABLE(of, komeda_of_match);
> >  
> > +#ifdef CONFIG_PM
> >  static int komeda_rt_pm_suspend(struct device *dev)
> >  {
> > struct komeda_drv *mdrv = dev_get_drvdata(dev);
> > @@ -159,6 +160,7 @@ static int komeda_rt_pm_resume(struct device *dev)
> >  
> > return komeda_dev_resume(mdrv->mdev);
> >  }
> > +#endif /* CONFIG_PM */
> >  
> >  static int __maybe_unused komeda_pm_suspend(struct device *dev)
> >  {
> > -- 
> > 2.25.1
> > 
> 
> -- 
> 
> | I would like to |
> | fix the world,  |
> | but they're not |
> | giving me the   |
>  \ source code!  /
>   ---
> ¯\_(ツ)_/¯
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: drm/komeda: mark PM functions as __maybe_unused

2020-03-05 Thread james qian wang (Arm Technology China)
On Tue, Jan 07, 2020 at 10:53:19PM +0100, Arnd Bergmann wrote:
> Without this, we get a couple of warnings when CONFIG_PM
> is disabled:
> 
> drivers/gpu/drm/arm/display/komeda/komeda_drv.c:156:12: error: 
> 'komeda_rt_pm_resume' defined but not used [-Werror=unused-function]
>  static int komeda_rt_pm_resume(struct device *dev)
> ^~~
> drivers/gpu/drm/arm/display/komeda/komeda_drv.c:149:12: error: 
> 'komeda_rt_pm_suspend' defined but not used [-Werror=unused-function]
>  static int komeda_rt_pm_suspend(struct device *dev)
> ^~~~
> 
> Fixes: efb465088518 ("drm/komeda: Add runtime_pm support")
> Signed-off-by: Arnd Bergmann 
> Reviewed-by: James Qian Wang (Arm Technology China) 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_drv.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> index ea5cd1e17304..e7933930a657 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c
> @@ -146,14 +146,14 @@ static const struct of_device_id komeda_of_match[] = {
>  
>  MODULE_DEVICE_TABLE(of, komeda_of_match);
>  
> -static int komeda_rt_pm_suspend(struct device *dev)
> +static int __maybe_unused komeda_rt_pm_suspend(struct device *dev)
>  {
>   struct komeda_drv *mdrv = dev_get_drvdata(dev);
>  
>   return komeda_dev_suspend(mdrv->mdev);
>  }
>  
> -static int komeda_rt_pm_resume(struct device *dev)
> +static int __maybe_unused komeda_rt_pm_resume(struct device *dev)
>  {
>   struct komeda_drv *mdrv = dev_get_drvdata(dev);
>

Applied to drm-misc-fixes 9803aac7b5508718989e4cde11b854fc01037b01
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv6,2/6] drm/core: Add drm_afbc_framebuffer and a corresponding helper

2020-03-04 Thread james qian wang (Arm Technology China)
On Tue, Mar 03, 2020 at 01:01:32PM +0100, Andrzej Pietrasiewicz wrote:
> The new struct contains afbc-specific data.
> 
> The new function can be used by drivers which support afbc to complete
> the preparation of struct drm_afbc_framebuffer. It must be called after
> allocating the said struct and calling drm_gem_fb_init_with_funcs().
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> Reported-by: kbuild test robot 
> Reported-by: kbuild test robot 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 121 +++
>  include/drm/drm_framebuffer.h|  45 +++
>  include/drm/drm_gem_framebuffer_helper.h |  11 ++
>  3 files changed, 177 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 388a080cd2df..2a30f5b6829f 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -21,6 +21,13 @@
>  #include 
>  #include 
>  
> +#define AFBC_HEADER_SIZE 16
> +#define AFBC_TH_LAYOUT_ALIGNMENT 8
> +#define AFBC_HDR_ALIGN   64
> +#define AFBC_SUPERBLOCK_PIXELS   256
> +#define AFBC_SUPERBLOCK_ALIGNMENT128
> +#define AFBC_TH_BODY_START_ALIGNMENT 4096
> +
>  /**
>   * DOC: overview
>   *
> @@ -302,6 +309,120 @@ drm_gem_fb_create_with_dirty(struct drm_device *dev, 
> struct drm_file *file,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_dirty);
>  
> +/**
> + * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
> + * @modifier: the modifier to be looked at
> + * @w: address of a place to store the block width
> + * @h: address of a place to store the block height
> + *
> + * Returns: true if the modifier describes a supported block size
> + */
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
> +{
> + switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> + *w = 16;
> + *h = 16;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> + *w = 32;
> + *h = 8;
> + break;
> + /* no user exists yet - fall through */
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> + default:
> + DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> +   modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> + return false;
> + }
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(drm_afbc_get_superblock_wh);
> +

In this new series, seems we no need to build this get_block_wh to be
an individual func but can directly put them into the following func.

> +static int drm_gem_afbc_min_size(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd,
> +  struct drm_afbc_framebuffer *afbc_fb)
> +{
> + const struct drm_format_info *info;
> + u32 n_blocks, w_alignment, h_alignment, hdr_alignment;
> + u32 tmp_bpp; /* remove when all users properly encode cpp in 
> drm_format_info */
> +
> + if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
> _fb->block_width, _fb->block_height))
> + return -EINVAL;
> +
> + /* tiled header afbc */
> + w_alignment = afbc_fb->block_width;
> + h_alignment = afbc_fb->block_height;
> + hdr_alignment = AFBC_HDR_ALIGN;
> + if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
> + w_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
> + h_alignment *= AFBC_TH_LAYOUT_ALIGNMENT;
> + hdr_alignment = AFBC_TH_BODY_START_ALIGNMENT;
> + }
> +
> + afbc_fb->aligned_width = ALIGN(mode_cmd->width, w_alignment);
> + afbc_fb->aligned_height = ALIGN(mode_cmd->height, h_alignment);
> + afbc_fb->offset = mode_cmd->offsets[0];
> +
> + /* Change to always using info->cpp[0] when all users properly encode 
> it */
> + info = drm_get_format_info(dev, mode_cmd);
> + tmp_bpp = info->cpp[0] ? info->cpp[0] * 8 : afbc_fb->bpp;
> +
> + n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height) / 
> AFBC_SUPERBLOCK_PIXELS;
> + afbc_fb->afbc_size = ALIGN(n_blocks * AFBC_HEADER_SIZE, hdr_alignment);
> + afbc_fb->afbc_size += n_blocks * ALIGN(tmp_bpp * AFBC_SUPERBLOCK_PIXELS 
> / 8, AFBC_SUPERBLOCK_ALIGNMENT);
> +
> + return 0;
> +}
> +
> +/**
> + * drm_gem_fb_afbc_init() - Helper function for drivers using afbc to
> + *   fill and validate all the afbc-specific
> + *   struct drm_afbc_framebuffer members
> + *
> + * @dev: DRM device
> + * @afbc_fb: afbc-specific framebuffer
> + * @mode_cmd: Metadata from the userspace framebuffer creation request
> + * @afbc_fb: afbc framebuffer
> + *
> + * This function can be used by drivers which support afbc to complete
> + * the preparation of struct drm_afbc_framebuffer. It must be called after
> + * 

Re: [PATCHv6,1/6] drm/core: Allow drivers allocate a subclass of struct drm_framebuffer

2020-03-04 Thread james qian wang (Arm Technology China)
On Tue, Mar 03, 2020 at 01:01:31PM +0100, Andrzej Pietrasiewicz wrote:
> Allow allocating a specialized version of struct drm_framebuffer
> by moving the actual fb allocation out of drm_gem_fb_create_with_funcs();
> the respective functions names are adjusted to reflect that fact.
> Please note, though, that standard size checks are performed on buffers,
> so the drm_gem_fb_init_with_funcs() is useful for cases where those
> standard size checks are appropriate or at least don't conflict the
> checks to be performed in the specialized case.
> 
> Thanks to this change the drivers can call drm_gem_fb_init_with_funcs()
> having allocated their special version of struct drm_framebuffer, exactly
> the way the new version of drm_gem_fb_create_with_funcs() does.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 65 +++-
>  include/drm/drm_gem_framebuffer_helper.h |  5 ++
>  2 files changed, 56 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 3a7ace19a902..388a080cd2df 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -55,18 +55,14 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
> drm_framebuffer *fb,
>  EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
>  
>  static struct drm_framebuffer *
> -drm_gem_fb_alloc(struct drm_device *dev,
> +drm_gem_fb_init(struct drm_device *dev,
> +  struct drm_framebuffer *fb,
>const struct drm_mode_fb_cmd2 *mode_cmd,
>struct drm_gem_object **obj, unsigned int num_planes,
>const struct drm_framebuffer_funcs *funcs)
>  {
> - struct drm_framebuffer *fb;
>   int ret, i;
>  
> - fb = kzalloc(sizeof(*fb), GFP_KERNEL);
> - if (!fb)
> - return ERR_PTR(-ENOMEM);
> -
>   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
>  
>   for (i = 0; i < num_planes; i++)
> @@ -123,10 +119,13 @@ int drm_gem_fb_create_handle(struct drm_framebuffer 
> *fb, struct drm_file *file,
>  EXPORT_SYMBOL(drm_gem_fb_create_handle);
>  
>  /**
> - * drm_gem_fb_create_with_funcs() - Helper function for the
> - *  _mode_config_funcs.fb_create
> - *  callback
> + * drm_gem_fb_init_with_funcs() - Helper function for implementing
> + * _mode_config_funcs.fb_create
> + * callback in cases when the driver
> + * allocates a subclass of
> + * struct drm_framebuffer
>   * @dev: DRM device
> + * @fb: framebuffer object
>   * @file: DRM file that holds the GEM handle(s) backing the framebuffer
>   * @mode_cmd: Metadata from the userspace framebuffer creation request
>   * @funcs: vtable to be used for the new framebuffer object
> @@ -134,18 +133,21 @@ EXPORT_SYMBOL(drm_gem_fb_create_handle);
>   * This function can be used to set _framebuffer_funcs for drivers that 
> need
>   * custom framebuffer callbacks. Use drm_gem_fb_create() if you don't need to
>   * change _framebuffer_funcs. The function does buffer size validation.
> + * The buffer size validation is for a general case, though, so users should
> + * pay attention to the checks being appropriate for them or, at least,
> + * non-conflicting.
>   *
>   * Returns:
>   * Pointer to a _framebuffer on success or an error pointer on failure.
>   */
>  struct drm_framebuffer *
> -drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
> -  const struct drm_mode_fb_cmd2 *mode_cmd,
> -  const struct drm_framebuffer_funcs *funcs)
> +drm_gem_fb_init_with_funcs(struct drm_device *dev, struct drm_framebuffer 
> *fb,
> +struct drm_file *file,
> +const struct drm_mode_fb_cmd2 *mode_cmd,
> +const struct drm_framebuffer_funcs *funcs)

For these two new added funcs: fb_init()/fb_init_with_funcs(), can we change
the return type "struct drm_framebuffer *" to "int".

>  {
>   const struct drm_format_info *info;
>   struct drm_gem_object *objs[4];
> - struct drm_framebuffer *fb;
>   int ret, i;
>  
>   info = drm_get_format_info(dev, mode_cmd);
> @@ -175,7 +177,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, 
> struct drm_file *file,
>   }
>   }
>  
> - fb = drm_gem_fb_alloc(dev, mode_cmd, objs, i, funcs);
> + fb = drm_gem_fb_init(dev, fb, mode_cmd, objs, i, funcs);
>   if (IS_ERR(fb)) {
>   ret = PTR_ERR(fb);
>   goto err_gem_object_put;
> @@ -189,6 +191,41 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, 
> struct drm_file *file,
>  
>   return ERR_PTR(ret);
>  }
> +EXPORT_SYMBOL_GPL(drm_gem_fb_init_with_funcs);
> +
> +/**
> + * drm_gem_fb_create_with_funcs() - 

Re: [PATCHv5 04/34] drm/gem-fb-helper: Add generic afbc size checks

2020-02-17 Thread james qian wang (Arm Technology China)
Hi Andrzej:

On Tue, Dec 17, 2019 at 03:49:50PM +0100, Andrzej Pietrasiewicz wrote:
> Extend the size-checking special function to handle afbc.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 49 +--
>  include/drm/drm_framebuffer.h| 50 
>  include/drm/drm_gem_framebuffer_helper.h |  1 +
>  3 files changed, 96 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index d2fce1ec8f37..5fe9032a5ee8 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -21,6 +21,11 @@
>  #include 
>  #include 
>  
> +#define AFBC_HEADER_SIZE 16
> +#define AFBC_TH_LAYOUT_ALIGNMENT 8
> +#define AFBC_SUPERBLOCK_PIXELS   256
> +#define AFBC_SUPERBLOCK_ALIGNMENT128
> +
>  /**
>   * DOC: overview
>   *
> @@ -299,6 +304,34 @@ int drm_gem_fb_lookup(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>  
> +static int drm_gem_afbc_min_size(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd,
> +  struct drm_afbc_framebuffer *afbc_fb)
> +{
> + u32 n_blocks;
> +
> + if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0], 
> _fb->block_width, _fb->block_height))
> + return -EINVAL;
> +
> + /* tiled header afbc */
> + if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
> + afbc_fb->block_width *= AFBC_TH_LAYOUT_ALIGNMENT;
> + afbc_fb->block_height *= AFBC_TH_LAYOUT_ALIGNMENT;
> + }

TBH, here caculated afbc_fb->block_with/height are not
block_width/height, but fb w/h alignment.
Per my understanding, afbc only has block size: 16x16, 32x8, 64x4 ...
generally the afbc w/h alignment according the the block_size, but once the
tiled header enabled, since one tiled header describes 8x8 superblocks,
so the alignment of w/h need to mutiple 8.

So I think we'd better name the variable to width/height_alignment.


BTW: no matter block_w/h or w/h_alignmtent are only for size
calculation, seems no need to store them to afbc_fb.

> +
> + afbc_fb->aligned_width = ALIGN(mode_cmd->width, afbc_fb->block_width);
> + afbc_fb->aligned_height = ALIGN(mode_cmd->height, 
> afbc_fb->block_height);
> + afbc_fb->offset = mode_cmd->offsets[0];
> +
> + n_blocks = (afbc_fb->aligned_width * afbc_fb->aligned_height) / 
> AFBC_SUPERBLOCK_PIXELS;
> + afbc_fb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE, 
> afbc_fb->alignment_header);
> +

After check the references in malidp, rockchip and komeda, seems this
afbc->alignment_header is dedicated for komeda only and a pass in
argument.

This is not true. Per afbc HW spec alignment is essential for
all afbc usage. according to the spec the requiremnt are:

  AFBC1.0/1.1: 64 byte alignment both for header and body buffer.
  AFBC1.2 (tiled header enabled): 4096 alignment.

So this alignement is not a vendor specific value, but afbc feature
requirement, can be determined by afbc modifier.
(malidp and komeda obeys this spec, not sure about Rockchip, but I
think it should be)

But you may see, komeda uses 1024 (not 64) for none-tiled-header afbc,
that's because GPU(MALI) changed this value to 1024 for bus
performance (sorry I don't know the detail), and komeda changed to
1024 to follow.

Back to alignment_header here, I think we can just follow the spec, use 64
for none-tiled-header, 4096 for tiled-header, and no need to let the caller
to specify it

> + afbc_fb->afbc_size = afbc_fb->offset_payload
> ++ n_blocks * ALIGN(afbc_fb->bpp * 
> AFBC_SUPERBLOCK_PIXELS / 8, AFBC_SUPERBLOCK_ALIGNMENT);
> +
> + return 0;
> +}
> +
>  /**
>   * drm_gem_fb_size_check2() - Helper function for use in
>   * _mode_config_funcs.fb_create implementations
> @@ -334,19 +367,27 @@ int drm_gem_fb_size_check2(struct drm_device *dev,
>   check->pitch_modulo)
>   return -EINVAL;
>  
> - if (check && check->use_min_size)
> + if (check && check->use_min_size) {
>   min_size = check->min_size[i];
> - else
> + } else if (check && check->data && 
> drm_is_afbc(mode_cmd->modifier[0])) {
> + struct drm_afbc_framebuffer *afbc_fb;
> + int ret;
> +
> + afbc_fb = check->data;
> + ret = drm_gem_afbc_min_size(dev, mode_cmd, afbc_fb);
> + if (ret < 0)
> + return ret;
> + min_size = ret;
> + } else {
>   min_size = (height - 1) * pitch
>+ drm_format_info_min_pitch(info, i, width)
>+ 

Re: [PATCHv5 03/34] drm/gem-fb-helper: Add special version of drm_gem_fb_size_check

2020-02-17 Thread james qian wang (Arm Technology China)
On Tue, Dec 17, 2019 at 03:49:49PM +0100, Andrzej Pietrasiewicz wrote:
> The new version accepts a struct describing deviations from standard way of
> doing the size checks. The caller must provide the respective values.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 46 
>  include/drm/drm_gem_framebuffer_helper.h | 16 +++
>  2 files changed, 54 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index b3494f6b66bb..d2fce1ec8f37 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -300,8 +300,8 @@ int drm_gem_fb_lookup(struct drm_device *dev,
>  EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>  
>  /**
> - * drm_gem_fb_size_check() - Helper function for use in
> - *_mode_config_funcs.fb_create implementations
> + * drm_gem_fb_size_check2() - Helper function for use in
> + * _mode_config_funcs.fb_create implementations
>   * @dev: DRM device
>   * @mode_cmd: Metadata from the userspace framebuffer creation request
>   *
> @@ -311,9 +311,10 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>   * Returns:
>   * Zero on success or a negative error code on failure.
>   */
> -int drm_gem_fb_size_check(struct drm_device *dev,
> -   const struct drm_mode_fb_cmd2 *mode_cmd,
> -   struct drm_gem_object **objs)
> +int drm_gem_fb_size_check2(struct drm_device *dev,

[nit-pick]: how about name it to drm_gem_fb_custom_size_check()

Reviewed-by: James Qian Wang (Arm Technology China) 
James.

> +const struct drm_mode_fb_cmd2 *mode_cmd,
> +const struct drm_size_check *check,
> +struct drm_gem_object **objs)
>  {
>   const struct drm_format_info *info;
>   int i;
> @@ -326,10 +327,19 @@ int drm_gem_fb_size_check(struct drm_device *dev,
>   unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
>   unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>   unsigned int min_size;
> + u32 pitch = mode_cmd->pitches[i];
> +
> + if (check && check->use_pitch_multiplier)
> + if ((pitch * check->pitch_multiplier[i]) %
> + check->pitch_modulo)
> + return -EINVAL;
>  
> - min_size = (height - 1) * mode_cmd->pitches[i]
> -  + drm_format_info_min_pitch(info, i, width)
> -  + mode_cmd->offsets[i];
> + if (check && check->use_min_size)
> + min_size = check->min_size[i];
> + else
> + min_size = (height - 1) * pitch
> +  + drm_format_info_min_pitch(info, i, width)
> +  + mode_cmd->offsets[i];
>  
>   if (objs[i]->size < min_size)
>   return -EINVAL;
> @@ -338,6 +348,26 @@ int drm_gem_fb_size_check(struct drm_device *dev,
>   return 0;
>  
>  }
> +EXPORT_SYMBOL_GPL(drm_gem_fb_size_check2);
> +
> +/**
> + * drm_gem_fb_size_check() - Helper function for use in
> + *_mode_config_funcs.fb_create implementations
> + * @dev: DRM device
> + * @mode_cmd: Metadata from the userspace framebuffer creation request
> + *
> + * This function can be used to verify buffer sizes for all planes.
> + * It is caller's responsibility to put the objects on failure.
> + *
> + * Returns:
> + * Zero on success or a negative error code on failure.
> + */
> +int drm_gem_fb_size_check(struct drm_device *dev,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs)
> +{
> + return drm_gem_fb_size_check2(dev, mode_cmd, NULL, objs);
> +}
>  EXPORT_SYMBOL_GPL(drm_gem_fb_size_check);
>  
>  static const struct drm_framebuffer_funcs drm_gem_fb_funcs_dirtyfb = {
> diff --git a/include/drm/drm_gem_framebuffer_helper.h 
> b/include/drm/drm_gem_framebuffer_helper.h
> index c85d4b152e91..4955af96d6c3 100644
> --- a/include/drm/drm_gem_framebuffer_helper.h
> +++ b/include/drm/drm_gem_framebuffer_helper.h
> @@ -11,6 +11,18 @@ struct drm_mode_fb_cmd2;
>  struct drm_plane;
>  struct drm_plane_state;
>  struct drm_simple_display_pipe;
> +struct drm_size_check;
> +
> +/**
> + * struct drm_size_check - Description of special requirements for size 
> checks.
> + */
> +struct drm_siz

Re: [PATCHv5 02/34] drm/gem-fb-helper: Allow drivers to allocate struct drm_framebuffer on their own

2020-02-17 Thread james qian wang (Arm Technology China)
ace framebuffer creation request
> + *
> + * This function can be used to verify buffer sizes for all planes.
> + * It is caller's responsibility to put the objects on failure.
> + *
> + * Returns:
> + * Zero on success or a negative error code on failure.
> + */
> +int drm_gem_fb_size_check(struct drm_device *dev,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs)
> +{
> + const struct drm_format_info *info;
> + int i;
> +
> + info = drm_get_format_info(dev, mode_cmd);
> + if (!info)
> + return -EINVAL;
> +
> + for (i = 0; i < info->num_planes; i++) {
> + unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
> + unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
> + unsigned int min_size;
> +
> + min_size = (height - 1) * mode_cmd->pitches[i]
> +  + drm_format_info_min_pitch(info, i, width)
> +  + mode_cmd->offsets[i];
> +
> + if (objs[i]->size < min_size)
> + return -EINVAL;
> + }
> +
> + return 0;
> +
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_fb_size_check);
> +
>  static const struct drm_framebuffer_funcs drm_gem_fb_funcs_dirtyfb = {
>   .destroy= drm_gem_fb_destroy,
>   .create_handle  = drm_gem_fb_create_handle,
> diff --git a/include/drm/drm_gem_framebuffer_helper.h 
> b/include/drm/drm_gem_framebuffer_helper.h
> index d9f13fd25b0a..c85d4b152e91 100644
> --- a/include/drm/drm_gem_framebuffer_helper.h
> +++ b/include/drm/drm_gem_framebuffer_helper.h
> @@ -14,10 +14,27 @@ struct drm_simple_display_pipe;
>  
>  struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
> unsigned int plane);
> +int drm_gem_fb_init_with_funcs(struct drm_framebuffer *fb,
> +struct drm_device *dev,
> +const struct drm_mode_fb_cmd2 *mode_cmd,
> +struct drm_gem_object **obj,
> +unsigned int num_planes,
> +const struct drm_framebuffer_funcs *funcs);
> +int drm_gem_fb_init(struct drm_framebuffer *fb,
> + struct drm_device *dev,
> + const struct drm_mode_fb_cmd2 *mode_cmd,
> + struct drm_gem_object **obj, unsigned int num_planes);
>  void drm_gem_fb_destroy(struct drm_framebuffer *fb);
>  int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file 
> *file,
>unsigned int *handle);
>  
> +int drm_gem_fb_lookup(struct drm_device *dev,
> +   struct drm_file *file,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs);
> +int drm_gem_fb_size_check(struct drm_device *dev,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs);
>  struct drm_framebuffer *
>  drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
>const struct drm_mode_fb_cmd2 *mode_cmd,
Reviewed-by: James Qian Wang (Arm Technology China) 

James.

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


Re: [PATCHv5 01/34] drm/core: Add afbc helper functions

2020-02-17 Thread james qian wang (Arm Technology China)
Hi Andrzej:

On Tue, Dec 17, 2019 at 03:49:47PM +0100, Andrzej Pietrasiewicz wrote:
> Add checking if a modifier is afbc and getting afbc block size.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_fourcc.c | 53 
>  include/drm/drm_fourcc.h |  4 +++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index b234bfaeda06..d14dd7c86020 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -29,6 +29,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  static char printable_char(int c)
>  {
> @@ -393,3 +394,55 @@ uint64_t drm_format_info_min_pitch(const struct 
> drm_format_info *info,
>   drm_format_info_block_height(info, plane));
>  }
>  EXPORT_SYMBOL(drm_format_info_min_pitch);
> +
> +/**
> + * drm_is_afbc - test if the modifier describes an afbc buffer
> + * @modifier - modifier to be tested
> + *
> + * Returns: true if the modifier describes an afbc buffer
> + */
> +bool drm_is_afbc(u64 modifier)
> +{
> + /* is it ARM AFBC? */
> + if ((modifier & DRM_FORMAT_MOD_ARM_AFBC(0)) == 0)
> + return false;
> +
> + /* Block size must be known */
> + if ((modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) == 0)
> + return false;

Do we really need this block size check here ?
Since modifier with ARM AFBC modifier but have no BLOCK_SIZE which
should be an error, but this check returns such error to NONE-AFBC.

And I saw you already have such error check in func
get_superblock_wh(), so I think we can del this size check in this
func.

James.

> +
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(drm_is_afbc);
> +
> +/**
> + * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
> + * @modifier: the modifier to be looked at
> + * @w: address of a place to store the block width
> + * @h: address of a place to store the block height
> + *
> + * Returns: true if the modifier describes a supported block size
> + */
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
> +{
> + switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> + *w = 16;
> + *h = 16;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> + *w = 32;
> + *h = 8;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> + /* fall through */
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> + /* fall through */
> + default:
> + DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> +   modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> + return false;
> + }
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(drm_afbc_get_superblock_wh);
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 306d1efeb5e0..7eb23062bf45 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -320,4 +320,8 @@ uint64_t drm_format_info_min_pitch(const struct 
> drm_format_info *info,
>  int plane, unsigned int buffer_width);
>  const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf 
> *buf);
>  
> +bool drm_is_afbc(u64 modifier);
> +
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h);
> +
>  #endif /* __DRM_FOURCC_H__ */
> -- 
> 2.17.1
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv4,04/36] drm/gem-fb-helper: Add special version of drm_gem_fb_size_check

2020-02-17 Thread james qian wang (Arm Technology China)
On Mon, Feb 17, 2020 at 11:55:50AM +0100, Andrzej Pietrasiewicz wrote:
> Hi James,
> 
> Thank you for the review.
> 
> Did you intentionally review patches from the v4 series or you simply
> didn't notice the v5? There are some differences, the most notable one
> is using proper way of subclassing a drm_framebuffer.
> The v5 series was sent on 17th December 2019.

Hi Andrzej:
Sorry, I did the review based pathwork:
https://patchwork.freedesktop.org/series/70889/#rev35
seems it has problem which only have V4.

I will re-do the review for V5 ASAP.

Sorry again.

James.

> Andrzej
> 
> W dniu 17.02.2020 o�09:16, james qian wang (Arm Technology China) pisze:
> > Hi Andrzej:
> > 
> > Really a good idea for introducing this custom size check, it's very
> > useful for some Komeda/malidp format, espcially pitch_multiplier, maybe
> > in future we can add it into into the drm_format_info.
> > 
> > On Fri, Dec 13, 2019 at 04:58:35PM +0100, Andrzej Pietrasiewicz wrote:
> > > The new version accepts a struct describing deviations from standard way 
> > > of
> > > doing the size checks. The caller must provide the respective values.
> > > 
> > > Signed-off-by: Andrzej Pietrasiewicz 
> > > ---
> > >   drivers/gpu/drm/drm_gem_framebuffer_helper.c | 47 
> > >   include/drm/drm_gem_framebuffer_helper.h | 16 +++
> > >   2 files changed, 55 insertions(+), 8 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> > > b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> > > index 787edb9a916b..4201dc1f32a5 100644
> > > --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> > > +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> > > @@ -201,8 +201,9 @@ int drm_gem_fb_lookup(struct drm_device *dev,
> > >   EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
> > >   /**
> > > - * drm_gem_fb_size_check() - Helper function for use in
> > > - *_mode_config_funcs.fb_create 
> > > implementations
> > > + * drm_gem_fb_size_check_special() - Helper function for use in
> > > + *_mode_config_funcs.fb_create
> > > + *implementations
> > >* @dev: DRM device
> > >* @mode_cmd: Metadata from the userspace framebuffer creation request
> > >*
> > > @@ -212,9 +213,10 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
> > >* Returns:
> > >* Zero on success or a negative error code on failure.
> > >*/
> > > -int drm_gem_fb_size_check(struct drm_device *dev,
> > > -   const struct drm_mode_fb_cmd2 *mode_cmd,
> > > -   struct drm_gem_object **objs)
> > > +int drm_gem_fb_size_check_special(struct drm_device *dev,
> > 
> > How about name it to drm_gem_fb_custom_size_check()
> > 
> > > +   const struct drm_mode_fb_cmd2 *mode_cmd,
> > > +   const struct drm_size_check *check,
> > > +   struct drm_gem_object **objs)
> > >   {
> > >   const struct drm_format_info *info;
> > >   int i;
> > > @@ -227,10 +229,19 @@ int drm_gem_fb_size_check(struct drm_device *dev,
> > >   unsigned int width = mode_cmd->width / (i ? info->hsub 
> > > : 1);
> > >   unsigned int height = mode_cmd->height / (i ? 
> > > info->vsub : 1);
> > >   unsigned int min_size;
> > > + u32 pitch = mode_cmd->pitches[i];
> > > +
> > > + if (check && check->use_pitch_multiplier)
> > > + if ((pitch * check->pitch_multiplier[i]) %
> > > + check->pitch_modulo)
> > > + return -EINVAL;
> > > - min_size = (height - 1) * mode_cmd->pitches[i]
> > > -  + drm_format_info_min_pitch(info, i, width)
> > > -  + mode_cmd->offsets[i];
> > > + if (check && check->use_min_size)
> > > + min_size = check->min_size[i];
> > > + else
> > > + min_size = (height - 1) * pitch
> > > +  + drm_format_info_min_pitch(info, i, width)
> > > +  + mode_cmd->offsets[i];
> > >   if (objs[i]->size < min_size)
> > >   return -EINVAL;
> > >

Re: [PATCHv4,05/36] drm/gem-fb-helper: Add generic afbc size checks

2020-02-17 Thread james qian wang (Arm Technology China)
Hi Andrzej:

On Fri, Dec 13, 2019 at 04:58:36PM +0100, Andrzej Pietrasiewicz wrote:
> Extend the size-checking special function to handle afbc.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_fourcc.c | 10 +++-
>  drivers/gpu/drm/drm_framebuffer.c|  3 +
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 60 ++--
>  include/drm/drm_gem_framebuffer_helper.h | 16 ++
>  4 files changed, 82 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index d14dd7c86020..9ac2175c5bee 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -323,8 +323,14 @@ drm_get_format_info(struct drm_device *dev,
>  {
>   const struct drm_format_info *info = NULL;
>  
> - if (dev->mode_config.funcs->get_format_info)
> - info = dev->mode_config.funcs->get_format_info(mode_cmd);
> + /* bypass driver callback if afbc */
> + if (!drm_is_afbc(mode_cmd->modifier[0]))
> + if (dev->mode_config.funcs->get_format_info) {
> + const struct drm_mode_config_funcs *funcs;
> +
> + funcs = dev->mode_config.funcs;
> + info = funcs->get_format_info(mode_cmd);
> + }
>  
>   if (!info)
>   info = drm_format_info(mode_cmd->pixel_format);
> diff --git a/drivers/gpu/drm/drm_framebuffer.c 
> b/drivers/gpu/drm/drm_framebuffer.c
> index 57564318ceea..33b741cc73e8 100644
> --- a/drivers/gpu/drm/drm_framebuffer.c
> +++ b/drivers/gpu/drm/drm_framebuffer.c
> @@ -204,6 +204,9 @@ static int framebuffer_check(struct drm_device *dev,
>   unsigned int block_size = info->char_per_block[i];
>   u64 min_pitch = drm_format_info_min_pitch(info, i, width);
>  
> + if (drm_is_afbc(r->modifier[i]))
> + block_size = 0;
> +
>   if (!block_size && (r->modifier[i] == DRM_FORMAT_MOD_LINEAR)) {
>   DRM_DEBUG_KMS("Format requires non-linear modifier for 
> plane %d\n", i);
>   return -EINVAL;
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 4201dc1f32a5..e20f4d00b0a5 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -21,6 +21,11 @@
>  #include 
>  #include 
>  
> +#define AFBC_HEADER_SIZE 16
> +#define AFBC_TH_LAYOUT_ALIGNMENT 8
> +#define AFBC_SUPERBLOCK_PIXELS   256
> +#define AFBC_SUPERBLOCK_ALIGNMENT128
> +
>  /**
>   * DOC: overview
>   *
> @@ -200,6 +205,40 @@ int drm_gem_fb_lookup(struct drm_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>  
> +static int drm_gem_afbc_min_size(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd,
> +  struct drm_afbc *afbc)
> +{
> + u32 n_blocks;
> +
> + if (!drm_afbc_get_superblock_wh(mode_cmd->modifier[0],
> + >block_width,
> + >block_height)) {
> + return -EINVAL;
> + }
> +
> + /* tiled header afbc */
> + if (mode_cmd->modifier[0] & AFBC_FORMAT_MOD_TILED) {
> + afbc->block_width *= AFBC_TH_LAYOUT_ALIGNMENT;
> + afbc->block_height *= AFBC_TH_LAYOUT_ALIGNMENT;
> + }
> +
> + afbc->aligned_width = ALIGN(mode_cmd->width, afbc->block_width);
> + afbc->aligned_height = ALIGN(mode_cmd->height, afbc->block_height);
> + afbc->offset = mode_cmd->offsets[0];
> +
> + n_blocks = (afbc->aligned_width * afbc->aligned_height)
> +  / AFBC_SUPERBLOCK_PIXELS;
> + afbc->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE,
> +  afbc->alignment_header);

After check the references in malidp, rockchip and komeda, seems this
afbc->alignment_header is dedicated for komeda only.

This is not true. Per afbc HW spec alignment is essential for
all afbc usage. according to the spec the requiremnt are:

  AFBC1.0/1.1: 64 byte alignment both for header and body buffer.
  AFBC1.2 (tiled header enabled): 4096 alignment.

So this alignement is not a vendor specific value, but afbc feature
requirement, can be determined by afbc modifier.
(malidp and komeda obeys this spec, not sure about Rockchip, but I
think it should be)

But you may see, komeda uses 1024 (not 64) for none-tiled-header afbc,
that's because GPU(MALI) changed this value to 1024 for bus
performance (sorry I don't know the detail), and komeda changed to
1024 to follow.

Back to display alignment, I think we can just follow the spec, use 64
for none-tiled-header, 4096 for tiled-header, but no need to caller to
pass a value.

> +
> + afbc->afbc_size = afbc->offset_payload + n_blocks *
> +   ALIGN(afbc->bpp * AFBC_SUPERBLOCK_PIXELS / 8,
> +   

Re: [PATCHv4,04/36] drm/gem-fb-helper: Add special version of drm_gem_fb_size_check

2020-02-17 Thread james qian wang (Arm Technology China)
Hi Andrzej:

Really a good idea for introducing this custom size check, it's very
useful for some Komeda/malidp format, espcially pitch_multiplier, maybe
in future we can add it into into the drm_format_info.

On Fri, Dec 13, 2019 at 04:58:35PM +0100, Andrzej Pietrasiewicz wrote:
> The new version accepts a struct describing deviations from standard way of
> doing the size checks. The caller must provide the respective values.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 47 
>  include/drm/drm_gem_framebuffer_helper.h | 16 +++
>  2 files changed, 55 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index 787edb9a916b..4201dc1f32a5 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -201,8 +201,9 @@ int drm_gem_fb_lookup(struct drm_device *dev,
>  EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>  
>  /**
> - * drm_gem_fb_size_check() - Helper function for use in
> - *_mode_config_funcs.fb_create implementations
> + * drm_gem_fb_size_check_special() - Helper function for use in
> + *_mode_config_funcs.fb_create
> + *implementations
>   * @dev: DRM device
>   * @mode_cmd: Metadata from the userspace framebuffer creation request
>   *
> @@ -212,9 +213,10 @@ EXPORT_SYMBOL_GPL(drm_gem_fb_lookup);
>   * Returns:
>   * Zero on success or a negative error code on failure.
>   */
> -int drm_gem_fb_size_check(struct drm_device *dev,
> -   const struct drm_mode_fb_cmd2 *mode_cmd,
> -   struct drm_gem_object **objs)
> +int drm_gem_fb_size_check_special(struct drm_device *dev,

How about name it to drm_gem_fb_custom_size_check()

> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   const struct drm_size_check *check,
> +   struct drm_gem_object **objs)
>  {
>   const struct drm_format_info *info;
>   int i;
> @@ -227,10 +229,19 @@ int drm_gem_fb_size_check(struct drm_device *dev,
>   unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
>   unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
>   unsigned int min_size;
> + u32 pitch = mode_cmd->pitches[i];
> +
> + if (check && check->use_pitch_multiplier)
> + if ((pitch * check->pitch_multiplier[i]) %
> + check->pitch_modulo)
> + return -EINVAL;
>  
> - min_size = (height - 1) * mode_cmd->pitches[i]
> -  + drm_format_info_min_pitch(info, i, width)
> -  + mode_cmd->offsets[i];
> + if (check && check->use_min_size)
> + min_size = check->min_size[i];
> + else
> + min_size = (height - 1) * pitch
> +  + drm_format_info_min_pitch(info, i, width)
> +  + mode_cmd->offsets[i];
>  
>   if (objs[i]->size < min_size)
>   return -EINVAL;
> @@ -239,6 +250,26 @@ int drm_gem_fb_size_check(struct drm_device *dev,
>   return 0;
>  
>  }
> +EXPORT_SYMBOL_GPL(drm_gem_fb_size_check_special);
> +
> +/**
> + * drm_gem_fb_size_check() - Helper function for use in
> + *_mode_config_funcs.fb_create implementations
> + * @dev: DRM device
> + * @mode_cmd: Metadata from the userspace framebuffer creation request
> + *
> + * This function can be used to verify buffer sizes for all planes.
> + * It is caller's responsibility to put the objects on failure.
> + *
> + * Returns:
> + * Zero on success or a negative error code on failure.
> + */
> +int drm_gem_fb_size_check(struct drm_device *dev,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs)
> +{
> + return drm_gem_fb_size_check_special(dev, mode_cmd, NULL, objs);
> +}
>  EXPORT_SYMBOL_GPL(drm_gem_fb_size_check);
>  
>  /**
> diff --git a/include/drm/drm_gem_framebuffer_helper.h 
> b/include/drm/drm_gem_framebuffer_helper.h
> index c85d4b152e91..74304a268694 100644
> --- a/include/drm/drm_gem_framebuffer_helper.h
> +++ b/include/drm/drm_gem_framebuffer_helper.h
> @@ -11,6 +11,18 @@ struct drm_mode_fb_cmd2;
>  struct drm_plane;
>  struct drm_plane_state;
>  struct drm_simple_display_pipe;
> +struct drm_size_check;
> +
> +/**
> + * struct drm_size_check - Description of special requirements for size 
> checks.
> + */
> +struct drm_size_check {
> + unsigned int min_size[4];
> + bool use_min_size;
> + u32 pitch_multiplier[4];
> + u32 pitch_modulo;
> + bool use_pitch_multiplier;
> +};
>  
>  struct drm_gem_object 

Re: [PATCHv4,03/36] drm/gem-fb-helper: Allow drivers to allocate struct drm_framebuffer on their own

2020-02-16 Thread james qian wang (Arm Technology China)
_framebuffer_funcs. The function does buffer size validation.
> + *
> + * Returns:
> + * Pointer to a _framebuffer on success or an error pointer on failure.
> + */
> +struct drm_framebuffer *
> +drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
> +  const struct drm_mode_fb_cmd2 *mode_cmd,
> +  const struct drm_framebuffer_funcs *funcs)
> +{
> + struct drm_gem_object *objs[4];
> + struct drm_framebuffer *fb;
> + int ret, num_planes;
> +
> + ret = drm_gem_fb_lookup(dev, file, mode_cmd, objs);
> + if (ret < 0)
> + return ERR_PTR(ret);
> + num_planes = ret;
> +
> + ret = drm_gem_fb_size_check(dev, mode_cmd, objs);
> + if (ret)
> + fb = ERR_PTR(ret);
> + else
> + fb = drm_gem_fb_alloc(dev, mode_cmd, objs, num_planes, funcs);
>  
> - return ERR_PTR(ret);
> + if (IS_ERR(fb))
> + for (num_planes--; num_planes >= 0; num_planes--)
> + drm_gem_object_put_unlocked(objs[num_planes]);
> +
> + return fb;
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_create_with_funcs);
>  
> -static const struct drm_framebuffer_funcs drm_gem_fb_funcs = {
> - .destroy= drm_gem_fb_destroy,
> - .create_handle  = drm_gem_fb_create_handle,
> -};
> -
>  /**
>   * drm_gem_fb_create() - Helper function for the
>   *   _mode_config_funcs.fb_create callback
> diff --git a/include/drm/drm_gem_framebuffer_helper.h 
> b/include/drm/drm_gem_framebuffer_helper.h
> index d9f13fd25b0a..c85d4b152e91 100644
> --- a/include/drm/drm_gem_framebuffer_helper.h
> +++ b/include/drm/drm_gem_framebuffer_helper.h
> @@ -14,10 +14,27 @@ struct drm_simple_display_pipe;
>  
>  struct drm_gem_object *drm_gem_fb_get_obj(struct drm_framebuffer *fb,
> unsigned int plane);
> +int drm_gem_fb_init_with_funcs(struct drm_framebuffer *fb,
> +struct drm_device *dev,
> +const struct drm_mode_fb_cmd2 *mode_cmd,
> +struct drm_gem_object **obj,
> +unsigned int num_planes,
> +const struct drm_framebuffer_funcs *funcs);
> +int drm_gem_fb_init(struct drm_framebuffer *fb,
> +     struct drm_device *dev,
> + const struct drm_mode_fb_cmd2 *mode_cmd,
> + struct drm_gem_object **obj, unsigned int num_planes);
>  void drm_gem_fb_destroy(struct drm_framebuffer *fb);
>  int drm_gem_fb_create_handle(struct drm_framebuffer *fb, struct drm_file 
> *file,
>unsigned int *handle);
>  
> +int drm_gem_fb_lookup(struct drm_device *dev,
> +   struct drm_file *file,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs);
> +int drm_gem_fb_size_check(struct drm_device *dev,
> +   const struct drm_mode_fb_cmd2 *mode_cmd,
> +   struct drm_gem_object **objs);
>  struct drm_framebuffer *
>  drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file,
>const struct drm_mode_fb_cmd2 *mode_cmd,

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

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


Re: [PATCHv4,02/36] drm/core: Add afbc helper functions

2020-02-16 Thread james qian wang (Arm Technology China)
On Fri, Dec 13, 2019 at 04:58:33PM +0100, Andrzej Pietrasiewicz wrote:
> Add checking if a modifier is afbc and getting afbc block size.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_fourcc.c | 53 
>  include/drm/drm_fourcc.h |  4 +++
>  2 files changed, 57 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> index b234bfaeda06..d14dd7c86020 100644
> --- a/drivers/gpu/drm/drm_fourcc.c
> +++ b/drivers/gpu/drm/drm_fourcc.c
> @@ -29,6 +29,7 @@
>  
>  #include 
>  #include 
> +#include 
>  
>  static char printable_char(int c)
>  {
> @@ -393,3 +394,55 @@ uint64_t drm_format_info_min_pitch(const struct 
> drm_format_info *info,
>   drm_format_info_block_height(info, plane));
>  }
>  EXPORT_SYMBOL(drm_format_info_min_pitch);
> +
> +/**
> + * drm_is_afbc - test if the modifier describes an afbc buffer
> + * @modifier - modifier to be tested
> + *
> + * Returns: true if the modifier describes an afbc buffer
> + */
> +bool drm_is_afbc(u64 modifier)
> +{
> + /* is it ARM AFBC? */
> + if ((modifier & DRM_FORMAT_MOD_ARM_AFBC(0)) == 0)
> + return false;
> +
> + /* Block size must be known */
> + if ((modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) == 0)
> + return false;

Do we really need this block size check here ?
Since modifier with ARM AFBC modifier but have no BLOCK_SIZE which
should be an error, but this check returns such error to NONE-AFBC.
And i saw you already have such error check in func
get_superblock_wh(), so I think we can del this size check in this
func.

James.
> +
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(drm_is_afbc);
> +
> +/**
> + * drm_afbc_get_superblock_wh - extract afbc block width/height from modifier
> + * @modifier: the modifier to be looked at
> + * @w: address of a place to store the block width
> + * @h: address of a place to store the block height
> + *
> + * Returns: true if the modifier describes a supported block size
> + */
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h)
> +{
> + switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> + *w = 16;
> + *h = 16;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> + *w = 32;
> + *h = 8;
> + break;
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> + /* fall through */
> + case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> + /* fall through */
> + default:
> + DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> +   modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> + return false;
> + }
> + return true;
> +}
> +EXPORT_SYMBOL_GPL(drm_afbc_get_superblock_wh);
> diff --git a/include/drm/drm_fourcc.h b/include/drm/drm_fourcc.h
> index 306d1efeb5e0..7eb23062bf45 100644
> --- a/include/drm/drm_fourcc.h
> +++ b/include/drm/drm_fourcc.h
> @@ -320,4 +320,8 @@ uint64_t drm_format_info_min_pitch(const struct 
> drm_format_info *info,
>  int plane, unsigned int buffer_width);
>  const char *drm_get_format_name(uint32_t format, struct drm_format_name_buf 
> *buf);
>  
> +bool drm_is_afbc(u64 modifier);
> +
> +bool drm_afbc_get_superblock_wh(u64 modifier, u32 *w, u32 *h);
> +
>  #endif /* __DRM_FOURCC_H__ */
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCHv4,01/36] drm/framebuffer: Add optional modifier info

2020-02-16 Thread james qian wang (Arm Technology China)
Hi Andrzej:

Sorry for late due to the outbreak of coronavirus in china.

Reviewed-by: James Qian Wang 

James.

On Fri, Dec 13, 2019 at 04:58:32PM +0100, Andrzej Pietrasiewicz wrote:
> modifier_info is a pointer to an optional modifier-related information.
> Managing the memory needed for that information is the responsibility
> of drivers.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  include/drm/drm_framebuffer.h | 16 
>  1 file changed, 16 insertions(+)
> 
> diff --git a/include/drm/drm_framebuffer.h b/include/drm/drm_framebuffer.h
> index c0e0256e3e98..2b3341b526d7 100644
> --- a/include/drm/drm_framebuffer.h
> +++ b/include/drm/drm_framebuffer.h
> @@ -29,6 +29,7 @@
>  
>  #include 
>  
> +struct drm_afbc;
>  struct drm_clip_rect;
>  struct drm_device;
>  struct drm_file;
> @@ -139,6 +140,21 @@ struct drm_framebuffer {
>* @format: framebuffer format information
>*/
>   const struct drm_format_info *format;
> +
> + union {
> + /**
> +  * @modifier_info: pointer to an optional modifier-related
> +  * information. Managing the memory holding that information
> +  * is driver's responsibility.
> +  */
> + void *modifier_info;
> +
> + /**
> +  * @afbc_info: afbc-specific pointer
> +  */
> + struct drm_afbc *afbc_info;
> + };
> +
>   /**
>* @funcs: framebuffer vfunc table
>*/
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [6/8] drm/atomic: convert to drm device based logging

2019-12-12 Thread james qian wang (Arm Technology China)
On Tue, Dec 10, 2019 at 02:30:48PM +0200, Jani Nikula wrote:
> Prefer drm_dbg_atomic().
> 
> Signed-off-by: Jani Nikula 
> ---
>  drivers/gpu/drm/drm_agpsupport.c |   4 +-
>  drivers/gpu/drm/drm_atomic.c | 187 +--
>  2 files changed, 102 insertions(+), 89 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_agpsupport.c 
> b/drivers/gpu/drm/drm_agpsupport.c
> index 4c7ad46fdd21..cd675e58de50 100644
> --- a/drivers/gpu/drm/drm_agpsupport.c
> +++ b/drivers/gpu/drm/drm_agpsupport.c
> @@ -330,8 +330,8 @@ int drm_agp_bind(struct drm_device *dev, struct 
> drm_agp_binding *request)
>   if (retcode)
>   return retcode;
>   entry->bound = dev->agp->base + (page << PAGE_SHIFT);
> - DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
> -   dev->agp->base, entry->bound);
> + drm_dbg_core(dev, "base = 0x%lx entry->bound = 0x%lx\n",
> +  dev->agp->base, entry->bound);
>   return 0;
>  }
>  EXPORT_SYMBOL(drm_agp_bind);
> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
> index 14aeaf736321..8494b1c29bf0 100644
> --- a/drivers/gpu/drm/drm_atomic.c
> +++ b/drivers/gpu/drm/drm_atomic.c
> @@ -99,7 +99,7 @@ drm_atomic_state_init(struct drm_device *dev, struct 
> drm_atomic_state *state)
>  
>   state->dev = dev;
>  
> - DRM_DEBUG_ATOMIC("Allocated atomic state %p\n", state);
> + drm_dbg_atomic(dev, "Allocated atomic state %p\n", state);
>  
>   return 0;
>  fail:
> @@ -150,7 +150,7 @@ void drm_atomic_state_default_clear(struct 
> drm_atomic_state *state)
>   struct drm_mode_config *config = >mode_config;
>   int i;
>  
> - DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
> + drm_dbg_atomic(dev, "Clearing atomic state %p\n", state);
>  
>   for (i = 0; i < state->num_connector; i++) {
>   struct drm_connector *connector = state->connectors[i].ptr;
> @@ -256,11 +256,12 @@ EXPORT_SYMBOL(drm_atomic_state_clear);
>  void __drm_atomic_state_free(struct kref *ref)
>  {
>   struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
> - struct drm_mode_config *config = >dev->mode_config;
> + struct drm_device *dev = state->dev;
> + struct drm_mode_config *config = >mode_config;
>  
>   drm_atomic_state_clear(state);
>  
> - DRM_DEBUG_ATOMIC("Freeing atomic state %p\n", state);
> + drm_dbg_atomic(dev, "Freeing atomic state %p\n", state);
>  
>   if (config->funcs->atomic_state_free) {
>   config->funcs->atomic_state_free(state);
> @@ -290,8 +291,9 @@ struct drm_crtc_state *
>  drm_atomic_get_crtc_state(struct drm_atomic_state *state,
> struct drm_crtc *crtc)
>  {
> - int ret, index = drm_crtc_index(crtc);
> + struct drm_device *dev = state->dev;
>   struct drm_crtc_state *crtc_state;
> + int ret, index = drm_crtc_index(crtc);
>  
>   WARN_ON(!state->acquire_ctx);
>  
> @@ -313,8 +315,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
>   state->crtcs[index].ptr = crtc;
>   crtc_state->state = state;
>  
> - DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
> -  crtc->base.id, crtc->name, crtc_state, state);
> + drm_dbg_atomic(dev, "Added [CRTC:%d:%s] %p state to %p\n",
> +crtc->base.id, crtc->name, crtc_state, state);
>  
>   return crtc_state;
>  }
> @@ -324,6 +326,7 @@ static int drm_atomic_crtc_check(const struct 
> drm_crtc_state *old_crtc_state,
>const struct drm_crtc_state *new_crtc_state)
>  {
>   struct drm_crtc *crtc = new_crtc_state->crtc;
> + struct drm_device *dev = crtc->dev;
>  
>   /* NOTE: we explicitly don't enforce constraints such as primary
>* layer covering entire screen, since that is something we want
> @@ -334,25 +337,25 @@ static int drm_atomic_crtc_check(const struct 
> drm_crtc_state *old_crtc_state,
>*/
>  
>   if (new_crtc_state->active && !new_crtc_state->enable) {
> - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] active without enabled\n",
> -  crtc->base.id, crtc->name);
> + drm_dbg_atomic(dev, "[CRTC:%d:%s] active without enabled\n",
> +crtc->base.id, crtc->name);

Can we add a new dedicated print level for these atomic check error msg,
In practice we more care about the atomic check errors, it is annoy to
pick it out from (so many) DRM_DEBUG_ATOMIC() msgs.

Thanks
James

>   return -EINVAL;
>   }
>  
>   /* The state->enable vs. state->mode_blob checks can be WARN_ON,
>* as this is a kernel-internal detail that userspace should never
>* be able to trigger. */
> - if (drm_core_check_feature(crtc->dev, DRIVER_ATOMIC) &&
> + if (drm_core_check_feature(dev, DRIVER_ATOMIC) &&
>   WARN_ON(new_crtc_state->enable && !new_crtc_state->mode_blob)) {
> - DRM_DEBUG_ATOMIC("[CRTC:%d:%s] 

[PATCH] drm/komeda: Add runtime_pm support

2019-12-11 Thread james qian wang (Arm Technology China)
- Add pm_runtime_get/put to crtc_enable/disable along with the real
  display usage
- Add runtime_get/put to register_show, since register_show() will
  access register, need to wakeup HW.
- For the case that PM is not enabled or configured, manually wakeup HW

Signed-off-by: james qian wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  3 +
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 55 +--
 .../gpu/drm/arm/display/komeda/komeda_drv.c   | 42 --
 .../gpu/drm/arm/display/komeda/komeda_kms.c   |  6 --
 4 files changed, 53 insertions(+), 53 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 1c452ea75999..56bd938961ee 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -5,6 +5,7 @@
  *
  */
 #include 
+#include 
 #include 
 
 #include 
@@ -274,6 +275,7 @@ static void
 komeda_crtc_atomic_enable(struct drm_crtc *crtc,
  struct drm_crtc_state *old)
 {
+   pm_runtime_get_sync(crtc->dev->dev);
komeda_crtc_prepare(to_kcrtc(crtc));
drm_crtc_vblank_on(crtc);
WARN_ON(drm_crtc_vblank_get(crtc));
@@ -372,6 +374,7 @@ komeda_crtc_atomic_disable(struct drm_crtc *crtc,
drm_crtc_vblank_put(crtc);
drm_crtc_vblank_off(crtc);
komeda_crtc_unprepare(kcrtc);
+   pm_runtime_put(crtc->dev->dev);
 }
 
 static void
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 38b832804bad..1d767473ba8a 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #ifdef CONFIG_DEBUG_FS
 #include 
@@ -27,12 +28,16 @@ static int komeda_register_show(struct seq_file *sf, void 
*x)
 
seq_puts(sf, "\n== Komeda register dump =\n");
 
+   pm_runtime_get_sync(mdev->dev);
+
if (mdev->funcs->dump_register)
mdev->funcs->dump_register(mdev, sf);
 
for (i = 0; i < mdev->n_pipelines; i++)
komeda_pipeline_dump_register(mdev->pipelines[i], sf);
 
+   pm_runtime_put(mdev->dev);
+
return 0;
 }
 
@@ -263,15 +268,6 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
if (!mdev->iommu)
DRM_INFO("continue without IOMMU support!\n");
 
-   if (mdev->iommu && mdev->funcs->connect_iommu) {
-   err = mdev->funcs->connect_iommu(mdev);
-   if (err) {
-   DRM_ERROR("connect iommu failed.\n");
-   mdev->iommu = NULL;
-   goto disable_clk;
-   }
-   }
-
clk_disable_unprepare(mdev->aclk);
 
err = sysfs_create_group(>kobj, _sysfs_attr_group);
@@ -310,11 +306,6 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
if (mdev->aclk)
clk_prepare_enable(mdev->aclk);
 
-   if (mdev->iommu && mdev->funcs->disconnect_iommu)
-   if (mdev->funcs->disconnect_iommu(mdev))
-   DRM_ERROR("disconnect iommu failed.\n");
-   mdev->iommu = NULL;
-
for (i = 0; i < mdev->n_pipelines; i++) {
komeda_pipeline_destroy(mdev, mdev->pipelines[i]);
mdev->pipelines[i] = NULL;
@@ -343,44 +334,26 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
 
 int komeda_dev_resume(struct komeda_dev *mdev)
 {
-   int ret = 0;
-
clk_prepare_enable(mdev->aclk);
 
-   if (mdev->iommu && mdev->funcs->connect_iommu) {
-   ret = mdev->funcs->connect_iommu(mdev);
-   if (ret < 0) {
-   DRM_ERROR("connect iommu failed.\n");
-   goto disable_clk;
-   }
-   }
-
-   ret = mdev->funcs->enable_irq(mdev);
+   mdev->funcs->enable_irq(mdev);
 
-disable_clk:
-   clk_disable_unprepare(mdev->aclk);
+   if (mdev->iommu && mdev->funcs->connect_iommu)
+   if (mdev->funcs->connect_iommu(mdev))
+   DRM_ERROR("connect iommu failed.\n");
 
-   return ret;
+   return 0;
 }
 
 int komeda_dev_suspend(struct komeda_dev *mdev)
 {
-   int ret = 0;
-
-   clk_prepare_enable(mdev->aclk);
-
-   if (mdev->iommu && mdev->funcs->disconnect_iommu) {
-   ret = mdev->funcs->disconnect_iommu(mdev);
-   if (ret < 0) {
+   if (mdev->iommu && mdev->funcs->disconnect_iommu)
+   if (mdev->funcs->disconnect_iommu(mdev))
DRM_ERROR(&quo

[PATCH] drm/komeda: Add event handling for EMPTY/FULL

2019-12-11 Thread james qian wang (Arm Technology China)
EMPTY/FULL are HW input/output FIFO condition identifer, which are
useful information for addressing the problem, so expose them.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c  | 13 -
 drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h |  3 +++
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h   |  5 -
 drivers/gpu/drm/arm/display/komeda/komeda_event.c |  2 ++
 4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index dd1ecf4276d3..00fa56c29b3e 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -20,8 +20,10 @@ static u64 get_lpu_event(struct d71_pipeline *d71_pipeline)
evts |= KOMEDA_EVENT_IBSY;
if (raw_status & LPU_IRQ_EOW)
evts |= KOMEDA_EVENT_EOW;
+   if (raw_status & LPU_IRQ_OVR)
+   evts |= KOMEDA_EVENT_OVR;
 
-   if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY)) {
+   if (raw_status & (LPU_IRQ_ERR | LPU_IRQ_IBSY | LPU_IRQ_OVR)) {
u32 restore = 0, tbu_status;
/* Check error of LPU status */
status = malidp_read32(reg, BLK_STATUS);
@@ -45,6 +47,15 @@ static u64 get_lpu_event(struct d71_pipeline *d71_pipeline)
restore |= LPU_STATUS_ACE3;
evts |= KOMEDA_ERR_ACE3;
}
+   if (status & LPU_STATUS_FEMPTY) {
+   restore |= LPU_STATUS_FEMPTY;
+   evts |= KOMEDA_EVENT_EMPTY;
+   }
+   if (status & LPU_STATUS_FFULL) {
+   restore |= LPU_STATUS_FFULL;
+   evts |= KOMEDA_EVENT_FULL;
+   }
+
if (restore != 0)
malidp_write32_mask(reg, BLK_STATUS, restore, 0);
 
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
index 81de6a23e7f3..e80172a0b320 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
@@ -175,6 +175,7 @@
 #define TBU_DOUTSTDCAPB_MASK   0x3F
 
 /* LPU_IRQ_BITS */
+#define LPU_IRQ_OVRBIT(9)
 #define LPU_IRQ_IBSY   BIT(10)
 #define LPU_IRQ_ERRBIT(11)
 #define LPU_IRQ_EOWBIT(12)
@@ -185,6 +186,8 @@
 #define LPU_STATUS_AXIEBIT(4)
 #define LPU_STATUS_AXIRP   BIT(5)
 #define LPU_STATUS_AXIWP   BIT(6)
+#define LPU_STATUS_FEMPTY  BIT(11)
+#define LPU_STATUS_FFULL   BIT(14)
 #define LPU_STATUS_ACE0BIT(16)
 #define LPU_STATUS_ACE1BIT(17)
 #define LPU_STATUS_ACE2BIT(18)
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 4a67a80d5fcf..ce27f2f27c24 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -20,6 +20,8 @@
 #define KOMEDA_EVENT_OVR   BIT_ULL(4)
 #define KOMEDA_EVENT_EOW   BIT_ULL(5)
 #define KOMEDA_EVENT_MODE  BIT_ULL(6)
+#define KOMEDA_EVENT_FULL  BIT_ULL(7)
+#define KOMEDA_EVENT_EMPTY BIT_ULL(8)
 
 #define KOMEDA_ERR_TETOBIT_ULL(14)
 #define KOMEDA_ERR_TEMRBIT_ULL(15)
@@ -49,7 +51,8 @@
KOMEDA_ERR_ZME  | KOMEDA_ERR_MERR   | KOMEDA_ERR_TCF |\
KOMEDA_ERR_TTNG | KOMEDA_ERR_TTF)
 
-#define KOMEDA_WARN_EVENTS KOMEDA_ERR_CSCE
+#define KOMEDA_WARN_EVENTS \
+   (KOMEDA_ERR_CSCE | KOMEDA_EVENT_FULL | KOMEDA_EVENT_EMPTY)
 
 #define KOMEDA_INFO_EVENTS (0 \
| KOMEDA_EVENT_VSYNC \
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
index 977c38d516da..53f944e66dfc 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
@@ -78,6 +78,8 @@ static void evt_str(struct komeda_str *str, u64 events)
 
/* LPU errors or events */
evt_sprintf(str, events & KOMEDA_EVENT_IBSY, "IBSY|");
+   evt_sprintf(str, events & KOMEDA_EVENT_EMPTY, "EMPTY|");
+   evt_sprintf(str, events & KOMEDA_EVENT_FULL, "FULL|");
evt_sprintf(str, events & KOMEDA_ERR_AXIE, "AXIE|");
evt_sprintf(str, events & KOMEDA_ERR_ACE0, "ACE0|");
evt_sprintf(str, events & KOMEDA_ERR_ACE1, "ACE1|");
-- 
2.20.1

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


Re: [PATCH v1 2/2] drm/komeda: Refactor sysfs node "config_id"

2019-12-10 Thread james qian wang (Arm Technology China)
On Tue, Nov 26, 2019 at 01:08:05PM +0100, Daniel Vetter wrote:
> On Tue, Nov 26, 2019 at 10:54:47AM +0000, james qian wang (Arm Technology 
> China) wrote:
> > From: "James Qian Wang (Arm Technology China)" 
> >
> > Split sysfs config_id bitfiles to multiple separated sysfs files.
> >
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
>
> I guess Dave questions werent quite clear, this looks like uapi that's
> consumed by hwc, so the userspace needs to be open source. Plus it needs
> to be discussed/reviewed like any other kms uapi extensions, with a
> critical eye whether this makes sense to add to a supposedly cross-vendor
> interface.
>

Hi Dave & Daniel:

I think some komeda sysfs nodes can be added as cross-vendor.

  - core_id:
which actually is like vendor_id/subsystem_device_id/revision in
PCI dev, Maybe we can add a util funcs to fake these sysfs nodes
for none PCI-dev like komeda

device_info_sysfs_add(struct device *dev,
u16 vendor, u16 subsystem_vendor,
u16 subsystem_device, u8 revision);

The arguments:
  vendor: I'd like to use the PCI vendor_ID, since with that user
  can see a unique ID, and easy to indentify different devices.
  subsystem_vendor/device/revision: device specific.

  - line_size.
This actually is mode_config->max_width, but current drm still use
this value to restrict the fb->width, but our HW supports crop, we
don't have such limition. we can not set the real line_size to
max_width.
And I saw there is a fix:
https://patchwork.freedesktop.org/patch/333454/
with this fix, we can directly use mode_config->max_width

Beside that we still needs some komeda specific node like:
 - aclk_hz: for expose display engine clock.
 - num_scalers: per pipeline scalers
 - num_pipes: number of display pipelines.

For the open sourced user space, we're trying to switch to
drm_hwcomposer, and drop our internal hwcomposer. but that may need time.
Can we start from porting our specific test to IGT for komeda private uapi
coverage.

Thanks
James
> I suspect the right thing to do here is to push the revert. From a quick
> look at git history this landed together with the other kms properties in
> komeda which we reverted already.
> -Daniel
>
> > ---
> >  .../drm/arm/display/include/malidp_product.h  | 13 ---
> >  .../gpu/drm/arm/display/komeda/komeda_sysfs.c | 80 ++-
> >  2 files changed, 62 insertions(+), 31 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
> > b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > index dbd3d4765065..b21f4aa15c95 100644
> > --- a/drivers/gpu/drm/arm/display/include/malidp_product.h
> > +++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > @@ -21,17 +21,4 @@
> >  #define MALIDP_D71_PRODUCT_ID  0x0071
> >  #define MALIDP_D32_PRODUCT_ID  0x0032
> >
> > -union komeda_config_id {
> > -   struct {
> > -   __u32   max_line_sz:16,
> > -   n_pipelines:2,
> > -   n_scalers:2, /* number of scalers per pipeline */
> > -   n_layers:3, /* number of layers per pipeline */
> > -   n_richs:3, /* number of rich layers per pipeline */
> > -   side_by_side:1, /* if HW works on side_by_side mode */
> > -   reserved_bits:5;
> > -   };
> > -   __u32 value;
> > -};
> > -
> >  #endif /* _MALIDP_PRODUCT_H_ */
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
> > index 740f095b4ca5..5effab795dc1 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
> > @@ -18,28 +18,67 @@ core_id_show(struct device *dev, struct 
> > device_attribute *attr, char *buf)
> >  static DEVICE_ATTR_RO(core_id);
> >
> >  static ssize_t
> > -config_id_show(struct device *dev, struct device_attribute *attr, char 
> > *buf)
> > +line_size_show(struct device *dev, struct device_attribute *attr, char 
> > *buf)
> >  {
> > struct komeda_dev *mdev = dev_to_mdev(dev);
> > struct komeda_pipeline *pipe = mdev->pipelines[0];
> > -   union komeda_config_id config_id;
> > -   int i;
> > -
> > -   memset(_id, 0, sizeof(config_id));
> > -
> > -   config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
> > -   config_id.side_by_side = mdev->side_by_side;
> > -   config_id.n_pipelines = mdev->n_pipelines;
> > -   config_id.n_scalers = pipe->n_scalers;
> > -   confi

[PATCH v3 2/2] drm/komeda: Enable new product D32 support

2019-12-10 Thread james qian wang (Arm Technology China)
D32 is simple version of D71, the difference is:
- Only has one pipeline
- Drop the periph block and merge it to GCU

v2: Rebase.
v3: Isolate the block counting fix to a new patch

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/include/malidp_product.h  |  3 +-
 .../arm/display/komeda/d71/d71_component.c|  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 39 ---
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 +++
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  1 +
 5 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
b/drivers/gpu/drm/arm/display/include/malidp_product.h
index 1053b11352eb..16a8a2c22c42 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -18,7 +18,8 @@
 #define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 0xFF)
 
 /* Mali-display product IDs */
-#define MALIDP_D71_PRODUCT_ID   0x0071
+#define MALIDP_D71_PRODUCT_ID  0x0071
+#define MALIDP_D32_PRODUCT_ID  0x0032
 
 union komeda_config_id {
struct {
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index b6517c46e670..8a02ade369db 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1270,7 +1270,7 @@ static int d71_timing_ctrlr_init(struct d71_dev *d71,
 
ctrlr = to_ctrlr(c);
 
-   ctrlr->supports_dual_link = true;
+   ctrlr->supports_dual_link = d71->supports_dual_link;
 
return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 7e79c2e88421..dd1ecf4276d3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -371,23 +371,33 @@ static int d71_enum_resources(struct komeda_dev *mdev)
goto err_cleanup;
}
 
-   /* probe PERIPH */
+   /* Only the legacy HW has the periph block, the newer merges the periph
+* into GCU
+*/
value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
-   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH) {
-   DRM_ERROR("access blk periph but got blk: %d.\n",
- BLOCK_INFO_BLK_TYPE(value));
-   err = -EINVAL;
-   goto err_cleanup;
+   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
+   d71->periph_addr = NULL;
+
+   if (d71->periph_addr) {
+   /* probe PERIPHERAL in legacy HW */
+   value = malidp_read32(d71->periph_addr, 
PERIPH_CONFIGURATION_ID);
+
+   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 
2048;
+   d71->max_vsize  = 4096;
+   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 
1;
+   d71->supports_dual_link = !!(value & PERIPH_SPLIT_EN);
+   d71->integrates_tbu = !!(value & PERIPH_TBU_EN);
+   } else {
+   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
+   d71->max_line_size  = GCU_MAX_LINE_SIZE(value);
+   d71->max_vsize  = GCU_MAX_NUM_LINES(value);
+
+   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
+   d71->num_rich_layers= GCU_NUM_RICH_LAYERS(value);
+   d71->supports_dual_link = GCU_DISPLAY_SPLIT_EN(value);
+   d71->integrates_tbu = GCU_DISPLAY_TBU_EN(value);
}
 
-   value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);
-
-   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
-   d71->max_vsize  = 4096;
-   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
-   d71->supports_dual_link = value & PERIPH_SPLIT_EN ? true : false;
-   d71->integrates_tbu = value & PERIPH_TBU_EN ? true : false;
-
for (i = 0; i < d71->num_pipelines; i++) {
pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
   _pipeline_funcs);
@@ -606,6 +616,7 @@ d71_identify(u32 __iomem *reg_base, struct komeda_chip_info 
*chip)
 
switch (product_id) {
case MALIDP_D71_PRODUCT_ID:
+   case MALIDP_D32_PRODUCT_ID:
funcs = _chip_funcs;
break;
default:
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
index 1727dc993909..81de6a23e7f3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_regs.h
@@ -72,6 +72,19 @@
 #

[PATCH v3 1/2] drm/komeda: Update the chip identify

2019-12-10 Thread james qian wang (Arm Technology China)
1. Drop komeda-CORE product id comparison and put it into the d71_identify
2. Update pipeline node DT-binding:
   (a). Skip the needless pipeline DT node.
   (b). Return fail if the essential pipeline DT node is missing.

With these changes, for chips in same family no need to change the DT.

v2: Rebase
v3: Address Mihail's comments.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 19 +-
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 61 ++-
 .../gpu/drm/arm/display/komeda/komeda_dev.h   | 14 +
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  9 +--
 4 files changed, 54 insertions(+), 49 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index d53f95dea0a1..7e79c2e88421 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -597,10 +597,25 @@ static const struct komeda_dev_funcs d71_chip_funcs = {
 const struct komeda_dev_funcs *
 d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
 {
+   const struct komeda_dev_funcs *funcs;
+   u32 product_id;
+
+   chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
+
+   product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
+
+   switch (product_id) {
+   case MALIDP_D71_PRODUCT_ID:
+   funcs = _chip_funcs;
+   break;
+   default:
+   DRM_ERROR("Unsupported product: 0x%x\n", product_id);
+   return NULL;
+   }
+
chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
-   chip->core_id   = malidp_read32(reg_base, GLB_CORE_ID);
chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
chip->bus_width = D71_BUS_WIDTH_16_BYTES;
 
-   return _chip_funcs;
+   return funcs;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 4e46f650fddf..38b832804bad 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -115,22 +115,14 @@ static struct attribute_group komeda_sysfs_attr_group = {
.attrs = komeda_sysfs_entries,
 };
 
-static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node 
*np)
+static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe)
 {
-   struct komeda_pipeline *pipe;
+   struct device_node *np = pipe->of_node;
struct clk *clk;
-   u32 pipe_id;
-   int ret = 0;
-
-   ret = of_property_read_u32(np, "reg", _id);
-   if (ret != 0 || pipe_id >= mdev->n_pipelines)
-   return -EINVAL;
-
-   pipe = mdev->pipelines[pipe_id];
 
clk = of_clk_get_by_name(np, "pxclk");
if (IS_ERR(clk)) {
-   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe_id);
+   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe->id);
return PTR_ERR(clk);
}
pipe->pxlclk = clk;
@@ -144,7 +136,6 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, 
struct device_node *np)
of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT);
 
pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1];
-   pipe->of_node = of_node_get(np);
 
return 0;
 }
@@ -153,7 +144,9 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct device_node *child, *np = dev->of_node;
-   int ret;
+   struct komeda_pipeline *pipe;
+   u32 pipe_id = U32_MAX;
+   int ret = -1;
 
mdev->irq  = platform_get_irq(pdev, 0);
if (mdev->irq < 0) {
@@ -168,28 +161,42 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
ret = 0;
 
for_each_available_child_of_node(np, child) {
-   if (of_node_cmp(child->name, "pipeline") == 0) {
-   ret = komeda_parse_pipe_dt(mdev, child);
-   if (ret) {
-   DRM_ERROR("parse pipeline dt error!\n");
-   of_node_put(child);
-   break;
+   if (of_node_name_eq(child, "pipeline")) {
+   of_property_read_u32(child, "reg", _id);
+   if (pipe_id >= mdev->n_pipelines) {
+   DRM_WARN("Skip the redundant DT node: 
pipeline-%u.\n",
+pipe_id);
+   continue;
}
+   mdev->pipelines[pipe_id]->of_node = of_node_get(child);
}
  

[PATCH v3 0/2] drm/komeda: Add new product "D32" support

2019-12-10 Thread james qian wang (Arm Technology China)
Hi All:

This series enables new product "D32" support

v2: Rebase
v3: Address Mihail's review comments.

james qian wang (Arm Technology China) (2):
  drm/komeda: Update the chip identify
  drm/komeda: Enable new product D32 support

 .../drm/arm/display/include/malidp_product.h  |  3 +-
 .../arm/display/komeda/d71/d71_component.c|  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 58 +-
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 61 ++-
 .../gpu/drm/arm/display/komeda/komeda_dev.h   | 14 +
 .../gpu/drm/arm/display/komeda/komeda_drv.c   | 10 +--
 7 files changed, 96 insertions(+), 65 deletions(-)

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


[PATCH] drm/komeda: Correct d71 register block counting

2019-12-09 Thread james qian wang (Arm Technology China)
Per HW, d71->num_blocks includes reserved blocks but no PERIPH block,
correct the block counting accordingly.
D71 happens to only have one reserved block and periph block, which
hides this counting error.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 822b23a1ce75..d53f95dea0a1 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -414,8 +414,11 @@ static int d71_enum_resources(struct komeda_dev *mdev)
d71->pipes[i] = to_d71_pipeline(pipe);
}
 
-   /* loop the register blks and probe */
-   i = 2; /* exclude GCU and PERIPH */
+   /* loop the register blks and probe.
+* NOTE: d71->num_blocks includes reserved blocks.
+* d71->num_blocks = GCU + valid blocks + reserved blocks
+*/
+   i = 1; /* exclude GCU */
offset = D71_BLOCK_SIZE; /* skip GCU */
while (i < d71->num_blocks) {
blk_base = mdev->reg_base + (offset >> 2);
@@ -425,9 +428,9 @@ static int d71_enum_resources(struct komeda_dev *mdev)
err = d71_probe_block(d71, , blk_base);
if (err)
goto err_cleanup;
-   i++;
}
 
+   i++;
offset += D71_BLOCK_SIZE;
}
 
-- 
2.20.1

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


Re: [PATCH v2 2/2] drm/komeda: Enable new product D32 support

2019-12-05 Thread james qian wang (Arm Technology China)
On Tue, Dec 03, 2019 at 09:59:57AM +, Mihail Atanassov wrote:
> On Tuesday, 3 December 2019 06:46:06 GMT james qian wang (Arm Technology 
> China) wrote:
> > On Mon, Dec 02, 2019 at 11:07:52AM +, Mihail Atanassov wrote:
> > > On Thursday, 21 November 2019 08:17:45 GMT james qian wang (Arm 
> > > Technology China) wrote:
> > > > D32 is simple version of D71, the difference is:
> > > > - Only has one pipeline
> > > > - Drop the periph block and merge it to GCU
> > > > 
> > > > v2: Rebase.
> > > > 
> > > > Signed-off-by: James Qian Wang (Arm Technology China) 
> > > > 
> > > > ---
> > > >  .../drm/arm/display/include/malidp_product.h  |  3 +-
> > > >  .../arm/display/komeda/d71/d71_component.c|  2 +-
> > > >  .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 43 ---
> > > >  .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 ++
> > > >  .../gpu/drm/arm/display/komeda/komeda_drv.c   |  1 +
> > > >  5 files changed, 44 insertions(+), 18 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
> > > > b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > > > index 96e2e4016250..dbd3d4765065 100644
> > > > --- a/drivers/gpu/drm/arm/display/include/malidp_product.h
> > > > +++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > > > @@ -18,7 +18,8 @@
> > > >  #define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 
> > > > 0xFF)
> > > >  
> > > >  /* Mali-display product IDs */
> > > > -#define MALIDP_D71_PRODUCT_ID   0x0071
> > > > +#define MALIDP_D71_PRODUCT_ID  0x0071
> > > > +#define MALIDP_D32_PRODUCT_ID  0x0032
> > > >  
> > > >  union komeda_config_id {
> > > > struct {
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
> > > > b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > > > index 6dadf4413ef3..c7f7e9c545c7 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > > > @@ -1274,7 +1274,7 @@ static int d71_timing_ctrlr_init(struct d71_dev 
> > > > *d71,
> > > >  
> > > > ctrlr = to_ctrlr(c);
> > > >  
> > > > -   ctrlr->supports_dual_link = true;
> > > > +   ctrlr->supports_dual_link = d71->supports_dual_link;
> > > >  
> > > > return 0;
> > > >  }
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > > > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > > > index 9b3bf353b6cc..2d429e310e5b 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > > > @@ -371,23 +371,33 @@ static int d71_enum_resources(struct komeda_dev 
> > > > *mdev)
> > > > goto err_cleanup;
> > > > }
> > > >  
> > > > -   /* probe PERIPH */
> > > > +   /* Only the legacy HW has the periph block, the newer merges 
> > > > the periph
> > > > +* into GCU
> > > > +*/
> > > > value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
> > > > -   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH) {
> > > > -   DRM_ERROR("access blk periph but got blk: %d.\n",
> > > > - BLOCK_INFO_BLK_TYPE(value));
> > > > -   err = -EINVAL;
> > > > -   goto err_cleanup;
> > > > +   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
> > > > +   d71->periph_addr = NULL;
> > > > +
> > > > +   if (d71->periph_addr) {
> > > > +   /* probe PERIPHERAL in legacy HW */
> > > > +   value = malidp_read32(d71->periph_addr, 
> > > > PERIPH_CONFIGURATION_ID);
> > > > +
> > > > +   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE 
> > > > ? 4096 : 2048;
> > > > +   d71->max_vsize  = 4096;
> > > > +   d71->num_rich_layers= value & 
> > > > PERIPH_NUM_RI

[PATCH v5 1/5] drm/komeda: Add side by side assembling

2019-12-05 Thread james qian wang (Arm Technology China)
Komeda HW can support side by side, which splits the internal display
processing to two single halves (LEFT/RIGHT) and handle them by two
pipelines separately.
komeda "side by side" is enabled by DT property: "side_by_side_master",
once DT configured side by side, komeda need to verify it with HW's
configuration, and assemble it for the further usage.

v3: Correct a typo.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 13 -
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  4 ++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  9 
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  3 ++
 .../drm/arm/display/komeda/komeda_pipeline.c  | 50 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 6 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 1c452ea75999..cee9a1692e71 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -561,21 +561,30 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
kms->n_crtcs = 0;
 
for (i = 0; i < mdev->n_pipelines; i++) {
+   /* if sbs, one komeda_dev only can represent one CRTC */
+   if (mdev->side_by_side && i != mdev->side_by_side_master)
+   continue;
+
crtc = >crtcs[kms->n_crtcs];
master = mdev->pipelines[i];
 
crtc->master = master;
crtc->slave  = komeda_pipeline_get_slave(master);
+   crtc->side_by_side = mdev->side_by_side;
 
if (crtc->slave)
sprintf(str, "pipe-%d", crtc->slave->id);
else
sprintf(str, "None");
 
-   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
-kms->n_crtcs, master->id, str);
+   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s) sbs(%s).\n",
+kms->n_crtcs, master->id, str,
+crtc->side_by_side ? "On" : "Off");
 
kms->n_crtcs++;
+
+   if (mdev->side_by_side)
+   break;
}
 
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 4e46f650fddf..0d0e8e4ebc9d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -178,6 +178,10 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
}
}
 
+   /* this DT node is experimental hence undocumented */
+   mdev->side_by_side = !of_property_read_u32(np, "side_by_side_master",
+  >side_by_side_master);
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index d406a4d83352..471604b42431 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -183,6 +183,15 @@ struct komeda_dev {
 
/** @irq: irq number */
int irq;
+   /**
+* @side_by_side:
+*
+* on sbs the whole display frame will be split to two halves (1:2),
+* master pipeline handles the left part, slave for the right part
+*/
+   bool side_by_side;
+   /** @side_by_side_master: master pipe id for side by side */
+   int side_by_side_master;
 
/** @lock: used to protect dpmode */
struct mutex lock;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 456f3c435719..ae6654fe95e2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -76,6 +76,9 @@ struct komeda_crtc {
 */
struct komeda_pipeline *slave;
 
+   /** @side_by_side: if the master and slave works on side by side mode */
+   bool side_by_side;
+
/** @slave_planes: komeda slave planes mask */
u32 slave_planes;
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 452e505a1fd3..104e27cc1dc3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -326,14 +326,56 @@ static void komeda_pipeline_assemble(struct 
komeda_pipeline *pipe)
 struct komeda_pipeline *
 komeda_pipeline_get_slave(struct komeda_pipeline *master)
 {
-   struct komeda_component *slave;
+   struct komeda_dev *mdev = master->mdev;
+

[PATCH v5 4/5] drm/komeda: Add side by side support for writeback

2019-12-05 Thread james qian wang (Arm Technology China)
In side by side mode, the master pipeline writeback the left frame and the
slave writeback the right part, the data flow as below:

  slave.compiz -> slave.wb_layer -> fb (right-part)
  master.compiz -> master.wb_layer -> fb (left-part)

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  4 ++
 .../display/komeda/komeda_pipeline_state.c| 42 +++
 .../arm/display/komeda/komeda_wb_connector.c  |  6 ++-
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 59a81b4476df..76621a972803 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -564,6 +564,10 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow);
 
 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
   struct komeda_crtc_state *kcrtc_st);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index b1e90feb5c55..79f7e7b6526f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1377,6 +1377,48 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
 
+/* writeback side by side split data path:
+ *
+ * slave.compiz -> slave.wb_layer - > fb (right-part)
+ * master.compiz -> master.wb_layer -> fb (left-part)
+ */
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow)
+{
+   struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave = kcrtc->slave;
+   struct komeda_data_flow_cfg m_dflow, s_dflow;
+   int err;
+
+   if (wb_dflow->en_scaling || wb_dflow->en_img_enhancement) {
+   DRM_DEBUG_ATOMIC("sbs doesn't support WB_scaling\n");
+   return -EINVAL;
+   }
+
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+
+   /* master writeout the left part */
+   m_dflow.in_w >>= 1;
+   m_dflow.out_w >>= 1;
+   m_dflow.input.component = >compiz->base;
+
+   /* slave writeout the right part */
+   s_dflow.in_w >>= 1;
+   s_dflow.out_w >>= 1;
+   s_dflow.in_x += m_dflow.in_w;
+   s_dflow.out_x += m_dflow.out_w;
+   s_dflow.input.component = >compiz->base;
+
+   err = komeda_wb_layer_validate(master->wb_layer, conn_st, _dflow);
+   if (err)
+   return err;
+
+   return komeda_wb_layer_validate(slave->wb_layer, conn_st, _dflow);
+}
+
 /* build display output data flow, the data path is:
  * compiz -> improc -> timing_ctrlr
  */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 17ea021488aa..44e628747654 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -37,6 +37,7 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_st,
   struct drm_connector_state *conn_st)
 {
+   struct komeda_crtc *kcrtc = to_kcrtc(crtc_st->crtc);
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
struct drm_writeback_job *writeback_job = conn_st->writeback_job;
struct komeda_layer *wb_layer;
@@ -65,7 +66,10 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
if (err)
return err;
 
-   if (dflow.en_split)
+   if (kcrtc->side_by_side)
+   err = komeda_build_wb_sbs_data_flow(kcrtc,
+   conn_st, kcrtc_st, );
+   else if (dflow.en_split)
err = komeda_build_wb_split_data_flow(wb_layer,
conn_st, kcrtc_st, );
else
-- 
2.20.1

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

[PATCH v5 2/5] drm/komeda: Add side by side plane_state split

2019-12-05 Thread james qian wang (Arm Technology China)
On side by side mode, The full display frame will be split into two parts
(Left/Right), and each part will be handled by a single pipeline separately
master pipeline for left part, slave for right.

To simplify the usage and implementation, komeda use the following scheme
to do the side by side split
1. The planes also have been grouped into two classes:
   master-planes and slave-planes.
2. The master plane can display its image on any location of the final/full
   display frame, komeda will help to split the plane configuration to two
   parts and fed them into master and slave pipelines.
3. The slave plane only can put its display rect on the right part of the
   final display frame, and its data is only can be fed into the slave
   pipeline.

From the perspective of resource usage and assignment:
The master plane can use the resources from the master pipeline and slave
pipeline both, but slave plane only can use the slave pipeline resources.

With such scheme, the usage of master planes are same as the none
side_by_side mode. user can easily skip the slave planes and no need to
consider side_by_side for them.

v4: Address Mihail's review comments.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  33 ++-
 .../display/komeda/komeda_pipeline_state.c| 188 ++
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 3 files changed, 220 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 20a076cce635..4c0946fbaac1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -521,6 +521,20 @@ komeda_component_pickup_output(struct komeda_component *c, 
u32 avail_comps)
return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
 }
 
+static inline const char *
+komeda_data_flow_msg(struct komeda_data_flow_cfg *config)
+{
+   static char str[128];
+
+   snprintf(str, sizeof(str),
+"rot: %x src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
+config->rot,
+config->in_x, config->in_y, config->in_w, config->in_h,
+config->out_x, config->out_y, config->out_w, config->out_h);
+
+   return str;
+}
+
 struct komeda_plane_state;
 struct komeda_crtc_state;
 struct komeda_crtc;
@@ -532,22 +546,27 @@ int komeda_build_layer_data_flow(struct komeda_layer 
*layer,
 struct komeda_plane_state *kplane_st,
 struct komeda_crtc_state *kcrtc_st,
 struct komeda_data_flow_cfg *dflow);
-int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
- struct drm_connector_state *conn_st,
- struct komeda_crtc_state *kcrtc_st,
- struct komeda_data_flow_cfg *dflow);
-int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
-  struct komeda_crtc_state *kcrtc_st);
-
 int komeda_build_layer_split_data_flow(struct komeda_layer *left,
   struct komeda_plane_state *kplane_st,
   struct komeda_crtc_state *kcrtc_st,
   struct komeda_data_flow_cfg *dflow);
+int komeda_build_layer_sbs_data_flow(struct komeda_layer *layer,
+struct komeda_plane_state *kplane_st,
+struct komeda_crtc_state *kcrtc_st,
+struct komeda_data_flow_cfg *dflow);
+
+int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *dflow);
 int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
 
+int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
+  struct komeda_crtc_state *kcrtc_st);
+
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
   struct komeda_crtc_state *kcrtc_st);
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 0930234abb9d..10a0dc9291b8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1130,6 +1130,194 @@ int komeda_build_layer_split_data_flow(struct 
komeda_layer *

[PATCH v5 5/5] drm/komeda: Update writeback signal for side_by_side

2019-12-05 Thread james qian wang (Arm Technology China)
In side by side mode, a writeback job is completed by two pipelines: left
by master and right by slave, we need to wait both pipeline finished (EOW),
then can signal the writeback job completion.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 23 ++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  5 
 .../arm/display/komeda/komeda_wb_connector.c  |  3 +++
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 24928b922fbd..78351b7135f8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -193,27 +193,28 @@ komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
return err;
 }
 
-void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
+void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
  struct komeda_events *evts)
 {
struct drm_crtc *crtc = >base;
+   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
u32 events = evts->pipes[kcrtc->master->id];
 
if (events & KOMEDA_EVENT_VSYNC)
drm_crtc_handle_vblank(crtc);
 
-   if (events & KOMEDA_EVENT_EOW) {
-   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
+   /* handles writeback event */
+   if (events & KOMEDA_EVENT_EOW)
+   wb_conn->complete_pipes |= BIT(kcrtc->master->id);
 
-   if (wb_conn)
-   drm_writeback_signal_completion(_conn->base, 0);
-   else
-   DRM_WARN("CRTC[%d]: EOW happen but no wb_connector.\n",
-drm_crtc_index(>base));
+   if (kcrtc->side_by_side &&
+   (evts->pipes[kcrtc->slave->id] & KOMEDA_EVENT_EOW))
+   wb_conn->complete_pipes |= BIT(kcrtc->slave->id);
+
+   if (wb_conn->expected_pipes == wb_conn->complete_pipes) {
+   wb_conn->complete_pipes = 0;
+   drm_writeback_signal_completion(_conn->base, 0);
}
-   /* will handle it together with the write back support */
-   if (events & KOMEDA_EVENT_EOW)
-   DRM_DEBUG("EOW.\n");
 
if (events & KOMEDA_EVENT_FLIP) {
unsigned long flags;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index ae6654fe95e2..174fb0a0b49b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -58,6 +58,11 @@ struct komeda_wb_connector {
 
/** @wb_layer: represents associated writeback pipeline of komeda */
struct komeda_layer *wb_layer;
+
+   /** @expected_pipes: pipelines are used for the writeback job */
+   u32 expected_pipes;
+   /** @complete_pipes: pipelines which have finished writeback */
+   u32 complete_pipes;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 44e628747654..d6833ea3b822 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -157,6 +157,9 @@ static int komeda_wb_connector_add(struct komeda_kms_dev 
*kms,
return -ENOMEM;
 
kwb_conn->wb_layer = kcrtc->master->wb_layer;
+   kwb_conn->expected_pipes = BIT(kcrtc->master->id);
+   if (kcrtc->side_by_side)
+   kwb_conn->expected_pipes |= BIT(kcrtc->slave->id);
 
wb_conn = _conn->base;
wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(>base));
-- 
2.20.1

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

[PATCH v5 3/5] drm/komeda: Build side by side display output pipeline

2019-12-05 Thread james qian wang (Arm Technology China)
For side by side, the slave pipeline merges to master via image processor

 slave-layers -> slave-compiz-> slave-improc-
 \
 master-layers -> master-compiz -> master-improc ->

v3: Rebase.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c|  4 ++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 18 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 .../display/komeda/komeda_pipeline_state.c| 51 ++-
 .../arm/display/komeda/komeda_wb_connector.c  |  2 +-
 5 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index b6517c46e670..6dadf4413ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1085,6 +1085,10 @@ static void d71_improc_update(struct komeda_component *c,
else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
ctrl |= IPS_CTRL_YUV;
 
+   /* slave input has been enabled, means side by side */
+   if (has_bit(1, state->active_inputs))
+   ctrl |= IPS_CTRL_SBS;
+
malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cee9a1692e71..24928b922fbd 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -385,15 +385,23 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc,
komeda_crtc_do_flush(crtc, old);
 }
 
-/* Returns the minimum frequency of the aclk rate (main engine clock) in Hz */
+/*
+ * Returns the minimum frequency of the aclk rate (main engine clock) in Hz.
+ *
+ * The DPU output can be split into two halves, to stay within the bandwidth
+ * capabilities of the external link (dual-link mode).
+ * In these cases, each output link runs at half the pixel clock rate of the
+ * combined display, and has half the number of pixels.
+ * Beside split the output, the DPU internal pixel processing also can be split
+ * into two halves (LEFT/RIGHT) and handles by two pipelines simultaneously.
+ * So if side by side, the pipeline (main engine clock) also can run at half
+ * the clock rate of the combined display.
+ */
 static unsigned long
 komeda_calc_min_aclk_rate(struct komeda_crtc *kcrtc,
  unsigned long pxlclk)
 {
-   /* Once dual-link one display pipeline drives two display outputs,
-* the aclk needs run on the double rate of pxlclk
-*/
-   if (kcrtc->master->dual_link)
+   if (kcrtc->master->dual_link && !kcrtc->side_by_side)
return pxlclk * 2;
else
return pxlclk;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 4c0946fbaac1..59a81b4476df 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -540,6 +540,7 @@ struct komeda_crtc_state;
 struct komeda_crtc;
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize);
 
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 10a0dc9291b8..b1e90feb5c55 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -654,12 +654,13 @@ komeda_merger_validate(struct komeda_merger *merger,
 }
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize)
 {
struct drm_display_mode *m = _st->base.adjusted_mode;
 
if (hsize)
-   *hsize = m->hdisplay;
+   *hsize = side_by_side ? m->hdisplay / 2 : m->hdisplay;
if (vsize)
*vsize = m->vdisplay;
 }
@@ -670,12 +671,14 @@ komeda_compiz_set_input(struct komeda_compiz *compiz,
struct komeda_data_flow_cfg *dflow)
 {
struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+   struct drm_crtc *crtc = kcrtc_st->base.crtc;
struct komeda_component_state *c_st, *old_st;
struct komeda_compiz_input_cfg *cin;
u16 compiz_w, compiz_h;
int idx = dflow->blending_zorder;
 
-   pipeline_composition_size(kcrtc_st, _w, _h);
+   pipeline_composition_size(kcrtc_st, to_kcrtc(crtc)->side_by_side,
+ _w, _h);
/* ch

[PATCH v5 0/5] arm/komeda: Add side_by_side support

2019-12-05 Thread james qian wang (Arm Technology China)
Hi: All

Komeda HW (two pipelines) can work on side by side mode, which splits the
internal display processing to two halves (LEFT/RIGHT) and handle them by
two pipelines separately and simultaneously.
And since one single pipeline only handles the half display frame, so the
main engine clock requirement can also be halved.

The data flow of side_by_side as blow:

 slave.layer0 ->\  /-> slave.wb_layer -> mem.fb.right_part
 ... -> slave.compiz ->
 slave.layer3 ->/  \-> slave.improcessor->
  \   /-> output-link0
 master.layer0 ->\   /-> master.improcessor ->\-> output-link1
 ...  -> master.compiz ->
 master.layer3 ->/   \-> master.wb_layer -> mem.fb.left_part

v3: Rebase
v5: Drop the patch: Expose side_by_side by sysfs/config_id

james qian wang (Arm Technology China) (5):
  drm/komeda: Add side by side assembling
  drm/komeda: Add side by side plane_state split
  drm/komeda: Build side by side display output pipeline
  drm/komeda: Add side by side support for writeback
  drm/komeda: Update writeback signal for side_by_side

 .../arm/display/komeda/d71/d71_component.c|   4 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  54 ++--
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |   4 +
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |   9 +
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   8 +
 .../drm/arm/display/komeda/komeda_pipeline.c  |  50 +++-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  39 ++-
 .../display/komeda/komeda_pipeline_state.c| 277 +-
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 .../arm/display/komeda/komeda_wb_connector.c  |  11 +-
 10 files changed, 419 insertions(+), 44 deletions(-)

-- 
2.20.1

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

Re: [PATCH v2 1/2] drm/komeda: Update the chip identify

2019-12-02 Thread james qian wang (Arm Technology China)
On Mon, Dec 02, 2019 at 11:07:54AM +, Mihail Atanassov wrote:
> On Thursday, 21 November 2019 08:17:39 GMT james qian wang (Arm Technology 
> China) wrote:
> > 1. Drop komeda-CORE product id comparison and put it into the d71_identify
> > 2. Update pipeline node DT-binding:
> >(a). Skip the needless pipeline DT node.
> >(b). Return fail if the essential pipeline DT node is missing.
> > 
> > With these changes, for one family chips no need to change the DT.
> > 
> > v2: Rebase
> > 
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
> > ---
> >  .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 27 +++--
> >  .../gpu/drm/arm/display/komeda/komeda_dev.c   | 60 ++-
> >  .../gpu/drm/arm/display/komeda/komeda_dev.h   | 14 +
> >  .../gpu/drm/arm/display/komeda/komeda_drv.c   |  9 +--
> >  4 files changed, 58 insertions(+), 52 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > index 822b23a1ce75..9b3bf353b6cc 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > @@ -594,10 +594,27 @@ static const struct komeda_dev_funcs d71_chip_funcs = 
> > {
> >  const struct komeda_dev_funcs *
> >  d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
> >  {
> > -   chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
> > -   chip->core_id   = malidp_read32(reg_base, GLB_CORE_ID);
> > -   chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
> > -   chip->bus_width = D71_BUS_WIDTH_16_BYTES;
> > +   const struct komeda_dev_funcs *funcs;
> > +   u32 product_id;
> >  
> > -   return _chip_funcs;
> > +   chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
> > +
> > +   product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
> > +
> > +   switch (product_id) {
> > +   case MALIDP_D71_PRODUCT_ID:
> > +   funcs = _chip_funcs;
> > +   break;
> > +   default:
> > +   funcs = NULL;
> 
> [bikeshed] I'd just 'return NULL;' after printing the error...

Good idea, and then no need to check the func in the following code.

> > +   DRM_ERROR("Unsupported product: 0x%x\n", product_id);
> > +   }
> > +
> > +   if (funcs) {
> 
> ... and save myself the branch and indent level here.
> 
> > +   chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
> > +   chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
> > +   chip->bus_width = D71_BUS_WIDTH_16_BYTES;
> > +   }
> > +
> > +   return funcs;
> >  }
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > index 4dd4699d4e3d..8e0bce46555b 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > @@ -116,22 +116,14 @@ static struct attribute_group komeda_sysfs_attr_group 
> > = {
> > .attrs = komeda_sysfs_entries,
> >  };
> >  
> > -static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct 
> > device_node *np)
> > +static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe)
> >  {
> > -   struct komeda_pipeline *pipe;
> > +   struct device_node *np = pipe->of_node;
> > struct clk *clk;
> > -   u32 pipe_id;
> > -   int ret = 0;
> > -
> > -   ret = of_property_read_u32(np, "reg", _id);
> > -   if (ret != 0 || pipe_id >= mdev->n_pipelines)
> > -   return -EINVAL;
> > -
> > -   pipe = mdev->pipelines[pipe_id];
> >  
> > clk = of_clk_get_by_name(np, "pxclk");
> > if (IS_ERR(clk)) {
> > -   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe_id);
> > +   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe->id);
> > return PTR_ERR(clk);
> > }
> > pipe->pxlclk = clk;
> > @@ -145,7 +137,6 @@ static int komeda_parse_pipe_dt(struct komeda_dev 
> > *mdev, struct device_node *np)
> > of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT);
> >  
> > pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1];
> > -   pipe->of_node = of_node_get(np);
> >  
> > return 0;
> >  }
> > @@ -154,7 +145,9 @@ static int komeda_parse_dt(struct device *dev, struct 
> >

Re: [PATCH v2 2/2] drm/komeda: Enable new product D32 support

2019-12-02 Thread james qian wang (Arm Technology China)
On Mon, Dec 02, 2019 at 11:07:52AM +, Mihail Atanassov wrote:
> On Thursday, 21 November 2019 08:17:45 GMT james qian wang (Arm Technology 
> China) wrote:
> > D32 is simple version of D71, the difference is:
> > - Only has one pipeline
> > - Drop the periph block and merge it to GCU
> > 
> > v2: Rebase.
> > 
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
> > ---
> >  .../drm/arm/display/include/malidp_product.h  |  3 +-
> >  .../arm/display/komeda/d71/d71_component.c|  2 +-
> >  .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 43 ---
> >  .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 ++
> >  .../gpu/drm/arm/display/komeda/komeda_drv.c   |  1 +
> >  5 files changed, 44 insertions(+), 18 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
> > b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > index 96e2e4016250..dbd3d4765065 100644
> > --- a/drivers/gpu/drm/arm/display/include/malidp_product.h
> > +++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > @@ -18,7 +18,8 @@
> >  #define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 0xFF)
> >  
> >  /* Mali-display product IDs */
> > -#define MALIDP_D71_PRODUCT_ID   0x0071
> > +#define MALIDP_D71_PRODUCT_ID  0x0071
> > +#define MALIDP_D32_PRODUCT_ID  0x0032
> >  
> >  union komeda_config_id {
> > struct {
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > index 6dadf4413ef3..c7f7e9c545c7 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
> > @@ -1274,7 +1274,7 @@ static int d71_timing_ctrlr_init(struct d71_dev *d71,
> >  
> > ctrlr = to_ctrlr(c);
> >  
> > -   ctrlr->supports_dual_link = true;
> > +   ctrlr->supports_dual_link = d71->supports_dual_link;
> >  
> > return 0;
> >  }
> > diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > index 9b3bf353b6cc..2d429e310e5b 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
> > @@ -371,23 +371,33 @@ static int d71_enum_resources(struct komeda_dev *mdev)
> > goto err_cleanup;
> > }
> >  
> > -   /* probe PERIPH */
> > +   /* Only the legacy HW has the periph block, the newer merges the periph
> > +* into GCU
> > +*/
> > value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
> > -   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH) {
> > -   DRM_ERROR("access blk periph but got blk: %d.\n",
> > - BLOCK_INFO_BLK_TYPE(value));
> > -   err = -EINVAL;
> > -   goto err_cleanup;
> > +   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
> > +   d71->periph_addr = NULL;
> > +
> > +   if (d71->periph_addr) {
> > +   /* probe PERIPHERAL in legacy HW */
> > +   value = malidp_read32(d71->periph_addr, 
> > PERIPH_CONFIGURATION_ID);
> > +
> > +   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 
> > 2048;
> > +   d71->max_vsize  = 4096;
> > +   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 
> > 1;
> > +   d71->supports_dual_link = !!(value & PERIPH_SPLIT_EN);
> > +   d71->integrates_tbu = !!(value & PERIPH_TBU_EN);
> > +   } else {
> > +   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
> > +   d71->max_line_size  = GCU_MAX_LINE_SIZE(value);
> > +   d71->max_vsize  = GCU_MAX_NUM_LINES(value);
> > +
> > +   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
> > +   d71->num_rich_layers= GCU_NUM_RICH_LAYERS(value);
> > +   d71->supports_dual_link = GCU_DISPLAY_SPLIT_EN(value);
> > +   d71->integrates_tbu = GCU_DISPLAY_TBU_EN(value);
> > }
> >  
> > -   value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);
> > -
> > -   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
> > -   d71->max_vsize  = 4096;
> > -   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
> > -   d71-&g

Re: [01/30] drm: Introduce drm_bridge_init()

2019-12-02 Thread james qian wang (Arm Technology China)
On Mon, Dec 02, 2019 at 09:49:35AM +0100, Daniel Vetter wrote:
> On Mon, Dec 02, 2019 at 05:55:06AM +0000, james qian wang (Arm Technology 
> China) wrote:
> > On Tue, Nov 26, 2019 at 01:15:59PM +, Mihail Atanassov wrote:
> > > A simple convenience function to initialize the struct drm_bridge.
> > >
> > > Signed-off-by: Mihail Atanassov 
> > > ---
> > >  drivers/gpu/drm/drm_bridge.c | 29 +
> > >  include/drm/drm_bridge.h |  4 
> > >  2 files changed, 33 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> > > index cba537c99e43..cbe680aa6eac 100644
> > > --- a/drivers/gpu/drm/drm_bridge.c
> > > +++ b/drivers/gpu/drm/drm_bridge.c
> > > @@ -89,6 +89,35 @@ void drm_bridge_remove(struct drm_bridge *bridge)
> > >  }
> > >  EXPORT_SYMBOL(drm_bridge_remove);
> > >
> > > +/**
> > > + * drm_bridge_init - initialise a drm_bridge structure
> > > + *
> > > + * @bridge: bridge control structure
> > > + * @funcs: control functions
> > > + * @dev: device
> > > + * @timings: timing specification for the bridge; optional (may be NULL)
> > > + * @driver_private: pointer to the bridge driver internal context (may 
> > > be NULL)
> > > + */
> > > +void drm_bridge_init(struct drm_bridge *bridge, struct device *dev,
> > > +  const struct drm_bridge_funcs *funcs,
> > > +  const struct drm_bridge_timings *timings,
> > > +  void *driver_private)
> > > +{
> > > + WARN_ON(!funcs);
> > > +
> > > + bridge->dev = NULL;
> > > + bridge->encoder = NULL;
> > > + bridge->next = NULL;
> > > +
> > > +#ifdef CONFIG_OF
> > > + bridge->of_node = dev->of_node;
> > > +#endif
> > > + bridge->timings = timings;
> > > + bridge->funcs = funcs;
> > > + bridge->driver_private = driver_private;
> >
> > Can we directly put drm_bridge_add() here. then
> > - User always need to call bridge_init and add together.
> > - Consistent with others like drm_plane/crtc_init which directly has
> >   drm_mode_object_add() in it.
>
> Uh no, the trouble here is that drm_bridge_add should actually be called
> _register, because it publishes the bridge to the world. I think we even
> have a todo item to rename _add to _register ... Once that's done the
> bridge can't be changed anymore, all init code must have completed. So
> often you need a bit of code between _init() and _register().
>
> drm_mode_object_add is different since for mode objects it doesn't publish
> it to the world, that's done with drm_dev_register and
> drm_connector_register. drm_mode_object_add just does a bit of internal
> house keeping.
> -Daniel
>

Yes, the name _register() is more better.

And thank you for such detailed explanation.

Thanks
James

> >
> > James.
> > > +}
> > > +EXPORT_SYMBOL(drm_bridge_init);
> > > +
> > >  /**
> > >   * drm_bridge_attach - attach the bridge to an encoder's chain
> > >   *
> > > diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> > > index c0a2286a81e9..d6d9d5301551 100644
> > > --- a/include/drm/drm_bridge.h
> > > +++ b/include/drm/drm_bridge.h
> > > @@ -402,6 +402,10 @@ struct drm_bridge {
> > >
> > >  void drm_bridge_add(struct drm_bridge *bridge);
> > >  void drm_bridge_remove(struct drm_bridge *bridge);
> > > +void drm_bridge_init(struct drm_bridge *bridge, struct device *dev,
> > > +  const struct drm_bridge_funcs *funcs,
> > > +  const struct drm_bridge_timings *timings,
> > > +  void *driver_private);
> > >  struct drm_bridge *of_drm_find_bridge(struct device_node *np);
> > >  int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge 
> > > *bridge,
> > > struct drm_bridge *previous);
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [01/30] drm: Introduce drm_bridge_init()

2019-12-01 Thread james qian wang (Arm Technology China)
On Tue, Nov 26, 2019 at 01:15:59PM +, Mihail Atanassov wrote:
> A simple convenience function to initialize the struct drm_bridge.
> 
> Signed-off-by: Mihail Atanassov 
> ---
>  drivers/gpu/drm/drm_bridge.c | 29 +
>  include/drm/drm_bridge.h |  4 
>  2 files changed, 33 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
> index cba537c99e43..cbe680aa6eac 100644
> --- a/drivers/gpu/drm/drm_bridge.c
> +++ b/drivers/gpu/drm/drm_bridge.c
> @@ -89,6 +89,35 @@ void drm_bridge_remove(struct drm_bridge *bridge)
>  }
>  EXPORT_SYMBOL(drm_bridge_remove);
>  
> +/**
> + * drm_bridge_init - initialise a drm_bridge structure
> + *
> + * @bridge: bridge control structure
> + * @funcs: control functions
> + * @dev: device
> + * @timings: timing specification for the bridge; optional (may be NULL)
> + * @driver_private: pointer to the bridge driver internal context (may be 
> NULL)
> + */
> +void drm_bridge_init(struct drm_bridge *bridge, struct device *dev,
> +  const struct drm_bridge_funcs *funcs,
> +  const struct drm_bridge_timings *timings,
> +  void *driver_private)
> +{
> + WARN_ON(!funcs);
> +
> + bridge->dev = NULL;
> + bridge->encoder = NULL;
> + bridge->next = NULL;
> +
> +#ifdef CONFIG_OF
> + bridge->of_node = dev->of_node;
> +#endif
> + bridge->timings = timings;
> + bridge->funcs = funcs;
> + bridge->driver_private = driver_private;

Can we directly put drm_bridge_add() here. then
- User always need to call bridge_init and add together.
- Consistent with others like drm_plane/crtc_init which directly has
  drm_mode_object_add() in it.

James.
> +}
> +EXPORT_SYMBOL(drm_bridge_init);
> +
>  /**
>   * drm_bridge_attach - attach the bridge to an encoder's chain
>   *
> diff --git a/include/drm/drm_bridge.h b/include/drm/drm_bridge.h
> index c0a2286a81e9..d6d9d5301551 100644
> --- a/include/drm/drm_bridge.h
> +++ b/include/drm/drm_bridge.h
> @@ -402,6 +402,10 @@ struct drm_bridge {
>  
>  void drm_bridge_add(struct drm_bridge *bridge);
>  void drm_bridge_remove(struct drm_bridge *bridge);
> +void drm_bridge_init(struct drm_bridge *bridge, struct device *dev,
> +  const struct drm_bridge_funcs *funcs,
> +  const struct drm_bridge_timings *timings,
> +  void *driver_private);
>  struct drm_bridge *of_drm_find_bridge(struct device_node *np);
>  int drm_bridge_attach(struct drm_encoder *encoder, struct drm_bridge *bridge,
> struct drm_bridge *previous);
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCHv3/RFC 1/4] drm/arm: Factor out generic afbc helpers

2019-11-28 Thread james qian wang (Arm Technology China)
On Mon, Nov 25, 2019 at 09:55:06AM +0100, Daniel Vetter wrote:
> On Thu, Nov 21, 2019 at 06:22:44PM +0100, Andrzej Pietrasiewicz wrote:
> > These are useful for other users of afbc, e.g. rockchip.
> > 
> > Signed-off-by: Andrzej Pietrasiewicz 
> > ---
> >  drivers/gpu/drm/Makefile  |  2 +-
> >  drivers/gpu/drm/drm_afbc.c| 84 +++
> >  drivers/gpu/drm/drm_fourcc.c  | 11 +++-
> >  drivers/gpu/drm/drm_framebuffer.c | 71 +-
> >  include/drm/drm_afbc.h| 35 +
> >  5 files changed, 199 insertions(+), 4 deletions(-)
> >  create mode 100644 drivers/gpu/drm/drm_afbc.c
> >  create mode 100644 include/drm/drm_afbc.h
> > 
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index d9bcc9f2a0a4..3a58f30b83a6 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -44,7 +44,7 @@ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o 
> > drm_dsc.o drm_probe_helper
> > drm_simple_kms_helper.o drm_modeset_helper.o \
> > drm_scdc_helper.o drm_gem_framebuffer_helper.o \
> > drm_atomic_state_helper.o drm_damage_helper.o \
> > -   drm_format_helper.o drm_self_refresh_helper.o
> > +   drm_format_helper.o drm_self_refresh_helper.o drm_afbc.o
> 
> Just a quick drive-by:
> - you can't put this into helpers and call from core code. This should be
>   core code. Also, I'd have just stuffed it into drm_format.c.
> 
> - If you want to keep your separate file, please include it in the doc
>   template, next to the format handling functions.
> >  
> >  drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
> >  drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
> > diff --git a/drivers/gpu/drm/drm_afbc.c b/drivers/gpu/drm/drm_afbc.c
> > new file mode 100644
> > index ..f308c4719546
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_afbc.c
> > @@ -0,0 +1,84 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * (C) 2019 Collabora Ltd.
> > + *
> > + * author: Andrzej Pietrasiewicz 
> > + *
> > + */
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +/**
> > + * drm_afbc_get_superblk_wh - extract afbc block width/height from modifier
> > + * @modifier: the modifier to be looked at
> > + * @w: address of a place to store the block width
> > + * @h: address of a place to store the block height
> > + *
> > + * Returns: true if the modifier describes a supported block size
> > + */
> > +bool drm_afbc_get_superblk_wh(u64 modifier, u32 *w, u32 *h)
> > +{
> > +   switch (modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> > +   *w = 16;
> > +   *h = 16;
> > +   break;
> > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> > +   *w = 32;
> > +   *h = 8;
> > +   break;
> > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_64x4:
> > +   /* fall through */
> > +   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8_64x4:
> > +   /* fall through */
> > +   default:
> > +   DRM_DEBUG_KMS("Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> > + modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> > +   return false;
> > +   }
> > +   return true;
> > +}
> > +EXPORT_SYMBOL_GPL(drm_afbc_get_superblk_wh);
> > +
> > +/**
> > + * drm_afbc_get_parameters - extract afbc parameters from mode command
> > + * @mode_cmd: mode command to be looked at
> > + * @afbc: address of a struct to be filled in
> > + */
> > +void drm_afbc_get_parameters(const struct drm_mode_fb_cmd2 *mode_cmd,
> > +struct drm_afbc *afbc)
> > +{
> > +   drm_afbc_get_superblk_wh(mode_cmd->modifier[0],
> > +>tile_w, >tile_h);
> > +   afbc->width = mode_cmd->pitches[0];
> > +   afbc->height =
> > +   DIV_ROUND_UP(mode_cmd->height, afbc->tile_h) * afbc->tile_h;
> > +   afbc->offset = mode_cmd->offsets[0];
> > +}
> > +EXPORT_SYMBOL(drm_afbc_get_parameters);
> > +
> > +/**
> > + * drm_is_afbc - test if the modifier describes an afbc buffer
> > + * @modifier - modifier to be tested
> > + *
> > + * Returns: true if the modifier describes an afbc buffer
> > + */
> > +bool drm_is_afbc(u64 modifier)
> > +{
> > +   /* is it ARM AFBC? */
> > +   if ((modifier & DRM_FORMAT_MOD_ARM_AFBC(0)) == 0)
> > +   return false;
> > +
> > +   /* Block size must be known */
> > +   if ((modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) == 0)
> > +   return false;
> > +
> > +   return true;
> > +}
> > +EXPORT_SYMBOL_GPL(drm_is_afbc);
> > diff --git a/drivers/gpu/drm/drm_fourcc.c b/drivers/gpu/drm/drm_fourcc.c
> > index c630064ccf41..8d9f197cc0ab 100644
> > --- a/drivers/gpu/drm/drm_fourcc.c
> > +++ b/drivers/gpu/drm/drm_fourcc.c
> > @@ -27,6 +27,7 @@
> >  #include 
> >  #include 
> >  
> > +#include 
> >  #include 
> >  #include 
> >  
> > @@ -322,8 +323,14 @@ 

[PATCH v1 2/2] drm/komeda: Refactor sysfs node "config_id"

2019-11-26 Thread james qian wang (Arm Technology China)
From: "James Qian Wang (Arm Technology China)" 

Split sysfs config_id bitfiles to multiple separated sysfs files.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/include/malidp_product.h  | 13 ---
 .../gpu/drm/arm/display/komeda/komeda_sysfs.c | 80 ++-
 2 files changed, 62 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
b/drivers/gpu/drm/arm/display/include/malidp_product.h
index dbd3d4765065..b21f4aa15c95 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -21,17 +21,4 @@
 #define MALIDP_D71_PRODUCT_ID  0x0071
 #define MALIDP_D32_PRODUCT_ID  0x0032
 
-union komeda_config_id {
-   struct {
-   __u32   max_line_sz:16,
-   n_pipelines:2,
-   n_scalers:2, /* number of scalers per pipeline */
-   n_layers:3, /* number of layers per pipeline */
-   n_richs:3, /* number of rich layers per pipeline */
-   side_by_side:1, /* if HW works on side_by_side mode */
-   reserved_bits:5;
-   };
-   __u32 value;
-};
-
 #endif /* _MALIDP_PRODUCT_H_ */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
index 740f095b4ca5..5effab795dc1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
@@ -18,28 +18,67 @@ core_id_show(struct device *dev, struct device_attribute 
*attr, char *buf)
 static DEVICE_ATTR_RO(core_id);
 
 static ssize_t
-config_id_show(struct device *dev, struct device_attribute *attr, char *buf)
+line_size_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
struct komeda_dev *mdev = dev_to_mdev(dev);
struct komeda_pipeline *pipe = mdev->pipelines[0];
-   union komeda_config_id config_id;
-   int i;
-
-   memset(_id, 0, sizeof(config_id));
-
-   config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
-   config_id.side_by_side = mdev->side_by_side;
-   config_id.n_pipelines = mdev->n_pipelines;
-   config_id.n_scalers = pipe->n_scalers;
-   config_id.n_layers = pipe->n_layers;
-   config_id.n_richs = 0;
-   for (i = 0; i < pipe->n_layers; i++) {
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", pipe->layers[0]->hsize_in.end);
+}
+static DEVICE_ATTR_RO(line_size);
+
+static ssize_t
+n_pipelines_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+   struct komeda_dev *mdev = dev_to_mdev(dev);
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", mdev->n_pipelines);
+}
+static DEVICE_ATTR_RO(n_pipelines);
+
+static ssize_t
+n_layers_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+   struct komeda_dev *mdev = dev_to_mdev(dev);
+   struct komeda_pipeline *pipe = mdev->pipelines[0];
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", pipe->n_layers);
+}
+static DEVICE_ATTR_RO(n_layers);
+
+static ssize_t
+n_rich_layers_show(struct device *dev, struct device_attribute *attr, char 
*buf)
+{
+   struct komeda_dev *mdev = dev_to_mdev(dev);
+   struct komeda_pipeline *pipe = mdev->pipelines[0];
+   int i, n_richs = 0;
+
+   for (i = 0; i < pipe->n_layers; i++)
if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER)
-   config_id.n_richs++;
-   }
-   return snprintf(buf, PAGE_SIZE, "0x%08x\n", config_id.value);
+   n_richs++;
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", n_richs);
+}
+static DEVICE_ATTR_RO(n_rich_layers);
+
+static ssize_t
+n_scalers_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+   struct komeda_dev *mdev = dev_to_mdev(dev);
+   struct komeda_pipeline *pipe = mdev->pipelines[0];
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", pipe->n_scalers);
+}
+static DEVICE_ATTR_RO(n_scalers);
+
+static ssize_t
+side_by_side_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+   struct komeda_dev *mdev = dev_to_mdev(dev);
+
+   return snprintf(buf, PAGE_SIZE, "%d\n", mdev->side_by_side);
 }
-static DEVICE_ATTR_RO(config_id);
+static DEVICE_ATTR_RO(side_by_side);
 
 static ssize_t
 aclk_hz_show(struct device *dev, struct device_attribute *attr, char *buf)
@@ -52,7 +91,12 @@ static DEVICE_ATTR_RO(aclk_hz);
 
 static struct attribute *komeda_sysfs_entries[] = {
_attr_core_id.attr,
-   _attr_config_id.attr,
+   _attr_line_size.attr,
+   _attr_n_pipelines.attr,
+   _attr_n_layers.attr,
+   _attr_n_rich_layers.attr,
+   _attr_n_scalers.attr,
+   _attr_side_by_side.attr,
_attr_aclk_hz.attr,
NULL,
 };
-- 
2.20.1

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

[PATCH v1 0/2] drm/komeda: refactor sysfs node "config_id"

2019-11-26 Thread james qian wang (Arm Technology China)
Split sysfs node "config_id" to multiple files.

James Qian Wang (Arm Technology China) (2):
  drm/komeda: Add a new file komeda_sysfs.c
  drm/komeda: Refactor sysfs node "config_id"

 .../drm/arm/display/include/malidp_product.h  |  13 --
 drivers/gpu/drm/arm/display/komeda/Makefile   |   1 +
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  61 +
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |   3 +
 .../gpu/drm/arm/display/komeda/komeda_sysfs.c | 125 ++
 5 files changed, 132 insertions(+), 71 deletions(-)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c

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

[PATCH v1 1/2] drm/komeda: Add a new file komeda_sysfs.c

2019-11-26 Thread james qian wang (Arm Technology China)
From: "James Qian Wang (Arm Technology China)" 

Add a new file komeda_sysfs.c and move all sysfs related code to it.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/Makefile   |  1 +
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 61 +-
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  3 +
 .../gpu/drm/arm/display/komeda/komeda_sysfs.c | 81 +++
 4 files changed, 88 insertions(+), 58 deletions(-)
 create mode 100644 drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c

diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile 
b/drivers/gpu/drm/arm/display/komeda/Makefile
index 1931a7fa1a14..706674ca5928 100644
--- a/drivers/gpu/drm/arm/display/komeda/Makefile
+++ b/drivers/gpu/drm/arm/display/komeda/Makefile
@@ -7,6 +7,7 @@ ccflags-y := \
 komeda-y := \
komeda_drv.o \
komeda_dev.o \
+   komeda_sysfs.o \
komeda_format_caps.o \
komeda_color_mgmt.o \
komeda_pipeline.o \
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 8e0bce46555b..734b88b88d94 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -63,59 +63,6 @@ static void komeda_debugfs_init(struct komeda_dev *mdev)
 }
 #endif
 
-static ssize_t
-core_id_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-   struct komeda_dev *mdev = dev_to_mdev(dev);
-
-   return snprintf(buf, PAGE_SIZE, "0x%08x\n", mdev->chip.core_id);
-}
-static DEVICE_ATTR_RO(core_id);
-
-static ssize_t
-config_id_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-   struct komeda_dev *mdev = dev_to_mdev(dev);
-   struct komeda_pipeline *pipe = mdev->pipelines[0];
-   union komeda_config_id config_id;
-   int i;
-
-   memset(_id, 0, sizeof(config_id));
-
-   config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
-   config_id.side_by_side = mdev->side_by_side;
-   config_id.n_pipelines = mdev->n_pipelines;
-   config_id.n_scalers = pipe->n_scalers;
-   config_id.n_layers = pipe->n_layers;
-   config_id.n_richs = 0;
-   for (i = 0; i < pipe->n_layers; i++) {
-   if (pipe->layers[i]->layer_type == KOMEDA_FMT_RICH_LAYER)
-   config_id.n_richs++;
-   }
-   return snprintf(buf, PAGE_SIZE, "0x%08x\n", config_id.value);
-}
-static DEVICE_ATTR_RO(config_id);
-
-static ssize_t
-aclk_hz_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-   struct komeda_dev *mdev = dev_to_mdev(dev);
-
-   return snprintf(buf, PAGE_SIZE, "%lu\n", clk_get_rate(mdev->aclk));
-}
-static DEVICE_ATTR_RO(aclk_hz);
-
-static struct attribute *komeda_sysfs_entries[] = {
-   _attr_core_id.attr,
-   _attr_config_id.attr,
-   _attr_aclk_hz.attr,
-   NULL,
-};
-
-static struct attribute_group komeda_sysfs_attr_group = {
-   .attrs = komeda_sysfs_entries,
-};
-
 static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe)
 {
struct device_node *np = pipe->of_node;
@@ -277,11 +224,9 @@ struct komeda_dev *komeda_dev_create(struct device *dev)
 
clk_disable_unprepare(mdev->aclk);
 
-   err = sysfs_create_group(>kobj, _sysfs_attr_group);
-   if (err) {
-   DRM_ERROR("create sysfs group failed.\n");
+   err = komeda_dev_sysfs_init(mdev);
+   if (err)
goto err_cleanup;
-   }
 
mdev->err_verbosity = KOMEDA_DEV_PRINT_ERR_EVENTS;
 
@@ -304,7 +249,7 @@ void komeda_dev_destroy(struct komeda_dev *mdev)
const struct komeda_dev_funcs *funcs = mdev->funcs;
int i;
 
-   sysfs_remove_group(>kobj, _sysfs_attr_group);
+   komeda_dev_sysfs_destroy(mdev);
 
 #ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(mdev->debugfs_root);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index dacdb00153e9..6183e0f394f0 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -248,4 +248,7 @@ void komeda_print_events(struct komeda_events *evts, struct 
drm_device *dev);
 int komeda_dev_resume(struct komeda_dev *mdev);
 int komeda_dev_suspend(struct komeda_dev *mdev);
 
+int komeda_dev_sysfs_init(struct komeda_dev *mdev);
+void komeda_dev_sysfs_destroy(struct komeda_dev *mdev);
+
 #endif /*_KOMEDA_DEV_H_*/
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
new file mode 100644
index ..740f095b4ca5
--- /dev/null
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_sysfs.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * (C) COPYRIGHT 2019 ARM Limited. All rights reserved.
+ * Author: James.Qian.Wang 
+ *
+ */
+#include

Re: [PATCH v4 6/6] drm/komeda: Expose side_by_side by sysfs/config_id

2019-11-21 Thread james qian wang (Arm Technology China)
On Thu, Nov 21, 2019 at 10:49:26AM +0100, Daniel Vetter wrote:
> On Thu, Nov 21, 2019 at 07:12:55AM +0000, james qian wang (Arm Technology 
> China) wrote:
> > There are some restrictions if HW works on side_by_side, expose it via
> > config_id to user.
> >
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
> > ---
> >  drivers/gpu/drm/arm/display/include/malidp_product.h | 3 ++-
> >  drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 1 +
> >  2 files changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
> > b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > index 1053b11352eb..96e2e4016250 100644
> > --- a/drivers/gpu/drm/arm/display/include/malidp_product.h
> > +++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
> > @@ -27,7 +27,8 @@ union komeda_config_id {
> > n_scalers:2, /* number of scalers per pipeline */
> > n_layers:3, /* number of layers per pipeline */
> > n_richs:3, /* number of rich layers per pipeline */
> > -   reserved_bits:6;
> > +   side_by_side:1, /* if HW works on side_by_side mode */
> > +   reserved_bits:5;
> > };
> > __u32 value;
> >  };
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > index c3fa4835cb8d..4dd4699d4e3d 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
> > @@ -83,6 +83,7 @@ config_id_show(struct device *dev, struct 
> > device_attribute *attr, char *buf)
>
> Uh, this sysfs file here looks a lot like uapi for some compositor to
> decide what to do. Do you have the userspace for this?

Yes, our HWC driver uses this config_id and product_id for identifying the
HW caps.

> Also a few more thoughts on this:
> - You can't just add more fields to uapi structs.
> - This doesn't really feel like it was ever reviewed to fit into atomic.
> - sysfs should be one value per file, not a smorgasbrod of things stuffed
>   into a binary structure.

I will sent a series and split this struct to multiple files.

| This doesn't really feel like it was ever reviewed to fit into atomic

These values don't have atomic problem, since config_id is for
representing the HW caps info, which are not configurable.

Thanks
James

> -Daniel
>
> > memset(_id, 0, sizeof(config_id));
> >
> > config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
> > +   config_id.side_by_side = mdev->side_by_side;
> > config_id.n_pipelines = mdev->n_pipelines;
> > config_id.n_scalers = pipe->n_scalers;
> > config_id.n_layers = pipe->n_layers;
> > --
> > 2.20.1
> >
> > ___
> > dri-devel mailing list
> > dri-devel@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/dri-devel
>
> --
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v2 2/2] drm/komeda: Enable new product D32 support

2019-11-21 Thread james qian wang (Arm Technology China)
D32 is simple version of D71, the difference is:
- Only has one pipeline
- Drop the periph block and merge it to GCU

v2: Rebase.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/include/malidp_product.h  |  3 +-
 .../arm/display/komeda/d71/d71_component.c|  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 43 ---
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 ++
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  1 +
 5 files changed, 44 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
b/drivers/gpu/drm/arm/display/include/malidp_product.h
index 96e2e4016250..dbd3d4765065 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -18,7 +18,8 @@
 #define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 0xFF)
 
 /* Mali-display product IDs */
-#define MALIDP_D71_PRODUCT_ID   0x0071
+#define MALIDP_D71_PRODUCT_ID  0x0071
+#define MALIDP_D32_PRODUCT_ID  0x0032
 
 union komeda_config_id {
struct {
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index 6dadf4413ef3..c7f7e9c545c7 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1274,7 +1274,7 @@ static int d71_timing_ctrlr_init(struct d71_dev *d71,
 
ctrlr = to_ctrlr(c);
 
-   ctrlr->supports_dual_link = true;
+   ctrlr->supports_dual_link = d71->supports_dual_link;
 
return 0;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 9b3bf353b6cc..2d429e310e5b 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -371,23 +371,33 @@ static int d71_enum_resources(struct komeda_dev *mdev)
goto err_cleanup;
}
 
-   /* probe PERIPH */
+   /* Only the legacy HW has the periph block, the newer merges the periph
+* into GCU
+*/
value = malidp_read32(d71->periph_addr, BLK_BLOCK_INFO);
-   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH) {
-   DRM_ERROR("access blk periph but got blk: %d.\n",
- BLOCK_INFO_BLK_TYPE(value));
-   err = -EINVAL;
-   goto err_cleanup;
+   if (BLOCK_INFO_BLK_TYPE(value) != D71_BLK_TYPE_PERIPH)
+   d71->periph_addr = NULL;
+
+   if (d71->periph_addr) {
+   /* probe PERIPHERAL in legacy HW */
+   value = malidp_read32(d71->periph_addr, 
PERIPH_CONFIGURATION_ID);
+
+   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 
2048;
+   d71->max_vsize  = 4096;
+   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 
1;
+   d71->supports_dual_link = !!(value & PERIPH_SPLIT_EN);
+   d71->integrates_tbu = !!(value & PERIPH_TBU_EN);
+   } else {
+   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID0);
+   d71->max_line_size  = GCU_MAX_LINE_SIZE(value);
+   d71->max_vsize  = GCU_MAX_NUM_LINES(value);
+
+   value = malidp_read32(d71->gcu_addr, GCU_CONFIGURATION_ID1);
+   d71->num_rich_layers= GCU_NUM_RICH_LAYERS(value);
+   d71->supports_dual_link = GCU_DISPLAY_SPLIT_EN(value);
+   d71->integrates_tbu = GCU_DISPLAY_TBU_EN(value);
}
 
-   value = malidp_read32(d71->periph_addr, PERIPH_CONFIGURATION_ID);
-
-   d71->max_line_size  = value & PERIPH_MAX_LINE_SIZE ? 4096 : 2048;
-   d71->max_vsize  = 4096;
-   d71->num_rich_layers= value & PERIPH_NUM_RICH_LAYERS ? 2 : 1;
-   d71->supports_dual_link = value & PERIPH_SPLIT_EN ? true : false;
-   d71->integrates_tbu = value & PERIPH_TBU_EN ? true : false;
-
for (i = 0; i < d71->num_pipelines; i++) {
pipe = komeda_pipeline_add(mdev, sizeof(struct d71_pipeline),
   _pipeline_funcs);
@@ -415,7 +425,7 @@ static int d71_enum_resources(struct komeda_dev *mdev)
}
 
/* loop the register blks and probe */
-   i = 2; /* exclude GCU and PERIPH */
+   i = 1; /* exclude GCU */
offset = D71_BLOCK_SIZE; /* skip GCU */
while (i < d71->num_blocks) {
blk_base = mdev->reg_base + (offset >> 2);
@@ -425,9 +435,9 @@ static int d71_enum_resources(struct komeda_dev *mdev)
err = d71_probe_block(d71, , blk_base);
if (err)
goto err_cleanup;
-   i+

[PATCH v2 0/2] drm/komeda: Add new product "D32" support

2019-11-21 Thread james qian wang (Arm Technology China)
Hi All:

This series enables new product "D32" support

v2: Rebase

james qian wang (Arm Technology China) (2):
  drm/komeda: Update the chip identify
  drm/komeda: Enable new product D32 support

 .../drm/arm/display/include/malidp_product.h  |  3 +-
 .../arm/display/komeda/d71/d71_component.c|  2 +-
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 70 +--
 .../gpu/drm/arm/display/komeda/d71/d71_regs.h | 13 
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 60 
 .../gpu/drm/arm/display/komeda/komeda_dev.h   | 14 +---
 .../gpu/drm/arm/display/komeda/komeda_drv.c   | 10 +--
 7 files changed, 102 insertions(+), 70 deletions(-)

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

[PATCH v2 1/2] drm/komeda: Update the chip identify

2019-11-21 Thread james qian wang (Arm Technology China)
1. Drop komeda-CORE product id comparison and put it into the d71_identify
2. Update pipeline node DT-binding:
   (a). Skip the needless pipeline DT node.
   (b). Return fail if the essential pipeline DT node is missing.

With these changes, for one family chips no need to change the DT.

v2: Rebase

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/d71/d71_dev.c  | 27 +++--
 .../gpu/drm/arm/display/komeda/komeda_dev.c   | 60 ++-
 .../gpu/drm/arm/display/komeda/komeda_dev.h   | 14 +
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |  9 +--
 4 files changed, 58 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
index 822b23a1ce75..9b3bf353b6cc 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_dev.c
@@ -594,10 +594,27 @@ static const struct komeda_dev_funcs d71_chip_funcs = {
 const struct komeda_dev_funcs *
 d71_identify(u32 __iomem *reg_base, struct komeda_chip_info *chip)
 {
-   chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
-   chip->core_id   = malidp_read32(reg_base, GLB_CORE_ID);
-   chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
-   chip->bus_width = D71_BUS_WIDTH_16_BYTES;
+   const struct komeda_dev_funcs *funcs;
+   u32 product_id;
 
-   return _chip_funcs;
+   chip->core_id = malidp_read32(reg_base, GLB_CORE_ID);
+
+   product_id = MALIDP_CORE_ID_PRODUCT_ID(chip->core_id);
+
+   switch (product_id) {
+   case MALIDP_D71_PRODUCT_ID:
+   funcs = _chip_funcs;
+   break;
+   default:
+   funcs = NULL;
+   DRM_ERROR("Unsupported product: 0x%x\n", product_id);
+   }
+
+   if (funcs) {
+   chip->arch_id   = malidp_read32(reg_base, GLB_ARCH_ID);
+   chip->core_info = malidp_read32(reg_base, GLB_CORE_INFO);
+   chip->bus_width = D71_BUS_WIDTH_16_BYTES;
+   }
+
+   return funcs;
 }
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 4dd4699d4e3d..8e0bce46555b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -116,22 +116,14 @@ static struct attribute_group komeda_sysfs_attr_group = {
.attrs = komeda_sysfs_entries,
 };
 
-static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node 
*np)
+static int komeda_parse_pipe_dt(struct komeda_pipeline *pipe)
 {
-   struct komeda_pipeline *pipe;
+   struct device_node *np = pipe->of_node;
struct clk *clk;
-   u32 pipe_id;
-   int ret = 0;
-
-   ret = of_property_read_u32(np, "reg", _id);
-   if (ret != 0 || pipe_id >= mdev->n_pipelines)
-   return -EINVAL;
-
-   pipe = mdev->pipelines[pipe_id];
 
clk = of_clk_get_by_name(np, "pxclk");
if (IS_ERR(clk)) {
-   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe_id);
+   DRM_ERROR("get pxclk for pipeline %d failed!\n", pipe->id);
return PTR_ERR(clk);
}
pipe->pxlclk = clk;
@@ -145,7 +137,6 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, 
struct device_node *np)
of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT);
 
pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1];
-   pipe->of_node = of_node_get(np);
 
return 0;
 }
@@ -154,7 +145,9 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
 {
struct platform_device *pdev = to_platform_device(dev);
struct device_node *child, *np = dev->of_node;
-   int ret;
+   struct komeda_pipeline *pipe;
+   u32 pipe_id = U32_MAX;
+   int ret = -1;
 
mdev->irq  = platform_get_irq(pdev, 0);
if (mdev->irq < 0) {
@@ -169,31 +162,44 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
ret = 0;
 
for_each_available_child_of_node(np, child) {
-   if (of_node_cmp(child->name, "pipeline") == 0) {
-   ret = komeda_parse_pipe_dt(mdev, child);
-   if (ret) {
-   DRM_ERROR("parse pipeline dt error!\n");
-   of_node_put(child);
-   break;
+   if (of_node_name_eq(child, "pipeline")) {
+   of_property_read_u32(child, "reg", _id);
+   if (pipe_id >= mdev->n_pipelines) {
+   DRM_WARN("Skip the redundant DT node: 
pipeline-%u.\n",
+ 

[PATCH v4 6/6] drm/komeda: Expose side_by_side by sysfs/config_id

2019-11-20 Thread james qian wang (Arm Technology China)
There are some restrictions if HW works on side_by_side, expose it via
config_id to user.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/include/malidp_product.h | 3 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
b/drivers/gpu/drm/arm/display/include/malidp_product.h
index 1053b11352eb..96e2e4016250 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -27,7 +27,8 @@ union komeda_config_id {
n_scalers:2, /* number of scalers per pipeline */
n_layers:3, /* number of layers per pipeline */
n_richs:3, /* number of rich layers per pipeline */
-   reserved_bits:6;
+   side_by_side:1, /* if HW works on side_by_side mode */
+   reserved_bits:5;
};
__u32 value;
 };
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index c3fa4835cb8d..4dd4699d4e3d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -83,6 +83,7 @@ config_id_show(struct device *dev, struct device_attribute 
*attr, char *buf)
memset(_id, 0, sizeof(config_id));
 
config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
+   config_id.side_by_side = mdev->side_by_side;
config_id.n_pipelines = mdev->n_pipelines;
config_id.n_scalers = pipe->n_scalers;
config_id.n_layers = pipe->n_layers;
-- 
2.20.1

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

[PATCH v4 5/6] drm/komeda: Update writeback signal for side_by_side

2019-11-20 Thread james qian wang (Arm Technology China)
In side by side mode, a writeback job is completed by two pipelines: left
by master and right by slave, we need to wait both pipeline finished (EOW),
then can signal the writeback job completion.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 23 ++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  5 
 .../arm/display/komeda/komeda_wb_connector.c  |  3 +++
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 24928b922fbd..78351b7135f8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -193,27 +193,28 @@ komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
return err;
 }
 
-void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
+void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
  struct komeda_events *evts)
 {
struct drm_crtc *crtc = >base;
+   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
u32 events = evts->pipes[kcrtc->master->id];
 
if (events & KOMEDA_EVENT_VSYNC)
drm_crtc_handle_vblank(crtc);
 
-   if (events & KOMEDA_EVENT_EOW) {
-   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
+   /* handles writeback event */
+   if (events & KOMEDA_EVENT_EOW)
+   wb_conn->complete_pipes |= BIT(kcrtc->master->id);
 
-   if (wb_conn)
-   drm_writeback_signal_completion(_conn->base, 0);
-   else
-   DRM_WARN("CRTC[%d]: EOW happen but no wb_connector.\n",
-drm_crtc_index(>base));
+   if (kcrtc->side_by_side &&
+   (evts->pipes[kcrtc->slave->id] & KOMEDA_EVENT_EOW))
+   wb_conn->complete_pipes |= BIT(kcrtc->slave->id);
+
+   if (wb_conn->expected_pipes == wb_conn->complete_pipes) {
+   wb_conn->complete_pipes = 0;
+   drm_writeback_signal_completion(_conn->base, 0);
}
-   /* will handle it together with the write back support */
-   if (events & KOMEDA_EVENT_EOW)
-   DRM_DEBUG("EOW.\n");
 
if (events & KOMEDA_EVENT_FLIP) {
unsigned long flags;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index ae6654fe95e2..174fb0a0b49b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -58,6 +58,11 @@ struct komeda_wb_connector {
 
/** @wb_layer: represents associated writeback pipeline of komeda */
struct komeda_layer *wb_layer;
+
+   /** @expected_pipes: pipelines are used for the writeback job */
+   u32 expected_pipes;
+   /** @complete_pipes: pipelines which have finished writeback */
+   u32 complete_pipes;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 44e628747654..d6833ea3b822 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -157,6 +157,9 @@ static int komeda_wb_connector_add(struct komeda_kms_dev 
*kms,
return -ENOMEM;
 
kwb_conn->wb_layer = kcrtc->master->wb_layer;
+   kwb_conn->expected_pipes = BIT(kcrtc->master->id);
+   if (kcrtc->side_by_side)
+   kwb_conn->expected_pipes |= BIT(kcrtc->slave->id);
 
wb_conn = _conn->base;
wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(>base));
-- 
2.20.1

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

[PATCH v4 4/6] drm/komeda: Add side by side support for writeback

2019-11-20 Thread james qian wang (Arm Technology China)
In side by side mode, the master pipeline writeback the left frame and the
slave writeback the right part, the data flow as below:

  slave.compiz -> slave.wb_layer -> fb (right-part)
  master.compiz -> master.wb_layer -> fb (left-part)

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  4 ++
 .../display/komeda/komeda_pipeline_state.c| 42 +++
 .../arm/display/komeda/komeda_wb_connector.c  |  6 ++-
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 59a81b4476df..76621a972803 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -564,6 +564,10 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow);
 
 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
   struct komeda_crtc_state *kcrtc_st);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index b1e90feb5c55..79f7e7b6526f 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1377,6 +1377,48 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
 
+/* writeback side by side split data path:
+ *
+ * slave.compiz -> slave.wb_layer - > fb (right-part)
+ * master.compiz -> master.wb_layer -> fb (left-part)
+ */
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow)
+{
+   struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave = kcrtc->slave;
+   struct komeda_data_flow_cfg m_dflow, s_dflow;
+   int err;
+
+   if (wb_dflow->en_scaling || wb_dflow->en_img_enhancement) {
+   DRM_DEBUG_ATOMIC("sbs doesn't support WB_scaling\n");
+   return -EINVAL;
+   }
+
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+
+   /* master writeout the left part */
+   m_dflow.in_w >>= 1;
+   m_dflow.out_w >>= 1;
+   m_dflow.input.component = >compiz->base;
+
+   /* slave writeout the right part */
+   s_dflow.in_w >>= 1;
+   s_dflow.out_w >>= 1;
+   s_dflow.in_x += m_dflow.in_w;
+   s_dflow.out_x += m_dflow.out_w;
+   s_dflow.input.component = >compiz->base;
+
+   err = komeda_wb_layer_validate(master->wb_layer, conn_st, _dflow);
+   if (err)
+   return err;
+
+   return komeda_wb_layer_validate(slave->wb_layer, conn_st, _dflow);
+}
+
 /* build display output data flow, the data path is:
  * compiz -> improc -> timing_ctrlr
  */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 17ea021488aa..44e628747654 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -37,6 +37,7 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_st,
   struct drm_connector_state *conn_st)
 {
+   struct komeda_crtc *kcrtc = to_kcrtc(crtc_st->crtc);
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
struct drm_writeback_job *writeback_job = conn_st->writeback_job;
struct komeda_layer *wb_layer;
@@ -65,7 +66,10 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
if (err)
return err;
 
-   if (dflow.en_split)
+   if (kcrtc->side_by_side)
+   err = komeda_build_wb_sbs_data_flow(kcrtc,
+   conn_st, kcrtc_st, );
+   else if (dflow.en_split)
err = komeda_build_wb_split_data_flow(wb_layer,
conn_st, kcrtc_st, );
else
-- 
2.20.1

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

[PATCH v4 3/6] drm/komeda: Build side by side display output pipeline

2019-11-20 Thread james qian wang (Arm Technology China)
For side by side, the slave pipeline merges to master via image processor

 slave-layers -> slave-compiz-> slave-improc-
 \
 master-layers -> master-compiz -> master-improc ->

v3: Rebase.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c|  4 ++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 18 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 .../display/komeda/komeda_pipeline_state.c| 51 ++-
 .../arm/display/komeda/komeda_wb_connector.c  |  2 +-
 5 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index b6517c46e670..6dadf4413ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1085,6 +1085,10 @@ static void d71_improc_update(struct komeda_component *c,
else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
ctrl |= IPS_CTRL_YUV;
 
+   /* slave input has been enabled, means side by side */
+   if (has_bit(1, state->active_inputs))
+   ctrl |= IPS_CTRL_SBS;
+
malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cee9a1692e71..24928b922fbd 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -385,15 +385,23 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc,
komeda_crtc_do_flush(crtc, old);
 }
 
-/* Returns the minimum frequency of the aclk rate (main engine clock) in Hz */
+/*
+ * Returns the minimum frequency of the aclk rate (main engine clock) in Hz.
+ *
+ * The DPU output can be split into two halves, to stay within the bandwidth
+ * capabilities of the external link (dual-link mode).
+ * In these cases, each output link runs at half the pixel clock rate of the
+ * combined display, and has half the number of pixels.
+ * Beside split the output, the DPU internal pixel processing also can be split
+ * into two halves (LEFT/RIGHT) and handles by two pipelines simultaneously.
+ * So if side by side, the pipeline (main engine clock) also can run at half
+ * the clock rate of the combined display.
+ */
 static unsigned long
 komeda_calc_min_aclk_rate(struct komeda_crtc *kcrtc,
  unsigned long pxlclk)
 {
-   /* Once dual-link one display pipeline drives two display outputs,
-* the aclk needs run on the double rate of pxlclk
-*/
-   if (kcrtc->master->dual_link)
+   if (kcrtc->master->dual_link && !kcrtc->side_by_side)
return pxlclk * 2;
else
return pxlclk;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 4c0946fbaac1..59a81b4476df 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -540,6 +540,7 @@ struct komeda_crtc_state;
 struct komeda_crtc;
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize);
 
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 10a0dc9291b8..b1e90feb5c55 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -654,12 +654,13 @@ komeda_merger_validate(struct komeda_merger *merger,
 }
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize)
 {
struct drm_display_mode *m = _st->base.adjusted_mode;
 
if (hsize)
-   *hsize = m->hdisplay;
+   *hsize = side_by_side ? m->hdisplay / 2 : m->hdisplay;
if (vsize)
*vsize = m->vdisplay;
 }
@@ -670,12 +671,14 @@ komeda_compiz_set_input(struct komeda_compiz *compiz,
struct komeda_data_flow_cfg *dflow)
 {
struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+   struct drm_crtc *crtc = kcrtc_st->base.crtc;
struct komeda_component_state *c_st, *old_st;
struct komeda_compiz_input_cfg *cin;
u16 compiz_w, compiz_h;
int idx = dflow->blending_zorder;
 
-   pipeline_composition_size(kcrtc_st, _w, _h);
+   pipeline_composition_size(kcrtc_st, to_kcrtc(crtc)->side_by_side,
+ _w, _h);
/* ch

[PATCH v4 1/6] drm/komeda: Add side by side assembling

2019-11-20 Thread james qian wang (Arm Technology China)
Komeda HW can support side by side, which splits the internal display
processing to two single halves (LEFT/RIGHT) and handle them by two
pipelines separately.
komeda "side by side" is enabled by DT property: "side_by_side_master",
once DT configured side by side, komeda need to verify it with HW's
configuration, and assemble it for the further usage.

v3: Correct a typo.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 13 -
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  3 ++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  9 
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  3 ++
 .../drm/arm/display/komeda/komeda_pipeline.c  | 50 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 6 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 1c452ea75999..cee9a1692e71 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -561,21 +561,30 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
kms->n_crtcs = 0;
 
for (i = 0; i < mdev->n_pipelines; i++) {
+   /* if sbs, one komeda_dev only can represent one CRTC */
+   if (mdev->side_by_side && i != mdev->side_by_side_master)
+   continue;
+
crtc = >crtcs[kms->n_crtcs];
master = mdev->pipelines[i];
 
crtc->master = master;
crtc->slave  = komeda_pipeline_get_slave(master);
+   crtc->side_by_side = mdev->side_by_side;
 
if (crtc->slave)
sprintf(str, "pipe-%d", crtc->slave->id);
else
sprintf(str, "None");
 
-   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
-kms->n_crtcs, master->id, str);
+   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s) sbs(%s).\n",
+kms->n_crtcs, master->id, str,
+crtc->side_by_side ? "On" : "Off");
 
kms->n_crtcs++;
+
+   if (mdev->side_by_side)
+   break;
}
 
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 4e46f650fddf..c3fa4835cb8d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -178,6 +178,9 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
}
}
 
+   mdev->side_by_side = !of_property_read_u32(np, "side_by_side_master",
+  >side_by_side_master);
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index d406a4d83352..471604b42431 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -183,6 +183,15 @@ struct komeda_dev {
 
/** @irq: irq number */
int irq;
+   /**
+* @side_by_side:
+*
+* on sbs the whole display frame will be split to two halves (1:2),
+* master pipeline handles the left part, slave for the right part
+*/
+   bool side_by_side;
+   /** @side_by_side_master: master pipe id for side by side */
+   int side_by_side_master;
 
/** @lock: used to protect dpmode */
struct mutex lock;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 456f3c435719..ae6654fe95e2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -76,6 +76,9 @@ struct komeda_crtc {
 */
struct komeda_pipeline *slave;
 
+   /** @side_by_side: if the master and slave works on side by side mode */
+   bool side_by_side;
+
/** @slave_planes: komeda slave planes mask */
u32 slave_planes;
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 452e505a1fd3..104e27cc1dc3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -326,14 +326,56 @@ static void komeda_pipeline_assemble(struct 
komeda_pipeline *pipe)
 struct komeda_pipeline *
 komeda_pipeline_get_slave(struct komeda_pipeline *master)
 {
-   struct komeda_component *slave;
+   struct komeda_dev *mdev = master->mdev;
+   struct komeda_component *comp, *slave;
+   u32 avail_inputs;
+

[PATCH v4 2/6] drm/komeda: Add side by side plane_state split

2019-11-20 Thread james qian wang (Arm Technology China)
On side by side mode, The full display frame will be split into two parts
(Left/Right), and each part will be handled by a single pipeline separately
master pipeline for left part, slave for right.

To simplify the usage and implementation, komeda use the following scheme
to do the side by side split
1. The planes also have been grouped into two classes:
   master-planes and slave-planes.
2. The master plane can display its image on any location of the final/full
   display frame, komeda will help to split the plane configuration to two
   parts and fed them into master and slave pipelines.
3. The slave plane only can put its display rect on the right part of the
   final display frame, and its data is only can be fed into the slave
   pipeline.

From the perspective of resource usage and assignment:
The master plane can use the resources from the master pipeline and slave
pipeline both, but slave plane only can use the slave pipeline resources.

With such scheme, the usage of master planes are same as the none
side_by_side mode. user can easily skip the slave planes and no need to
consider side_by_side for them.

v4: Address Mihail's review comments.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  33 ++-
 .../display/komeda/komeda_pipeline_state.c| 188 ++
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 3 files changed, 220 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 20a076cce635..4c0946fbaac1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -521,6 +521,20 @@ komeda_component_pickup_output(struct komeda_component *c, 
u32 avail_comps)
return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
 }
 
+static inline const char *
+komeda_data_flow_msg(struct komeda_data_flow_cfg *config)
+{
+   static char str[128];
+
+   snprintf(str, sizeof(str),
+"rot: %x src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
+config->rot,
+config->in_x, config->in_y, config->in_w, config->in_h,
+config->out_x, config->out_y, config->out_w, config->out_h);
+
+   return str;
+}
+
 struct komeda_plane_state;
 struct komeda_crtc_state;
 struct komeda_crtc;
@@ -532,22 +546,27 @@ int komeda_build_layer_data_flow(struct komeda_layer 
*layer,
 struct komeda_plane_state *kplane_st,
 struct komeda_crtc_state *kcrtc_st,
 struct komeda_data_flow_cfg *dflow);
-int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
- struct drm_connector_state *conn_st,
- struct komeda_crtc_state *kcrtc_st,
- struct komeda_data_flow_cfg *dflow);
-int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
-  struct komeda_crtc_state *kcrtc_st);
-
 int komeda_build_layer_split_data_flow(struct komeda_layer *left,
   struct komeda_plane_state *kplane_st,
   struct komeda_crtc_state *kcrtc_st,
   struct komeda_data_flow_cfg *dflow);
+int komeda_build_layer_sbs_data_flow(struct komeda_layer *layer,
+struct komeda_plane_state *kplane_st,
+struct komeda_crtc_state *kcrtc_st,
+struct komeda_data_flow_cfg *dflow);
+
+int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *dflow);
 int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
 
+int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
+  struct komeda_crtc_state *kcrtc_st);
+
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
   struct komeda_crtc_state *kcrtc_st);
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 0930234abb9d..10a0dc9291b8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1130,6 +1130,194 @@ int komeda_build_layer_split_data_flow(struct 
komeda_layer *

[PATCH v4 0/6] arm/komeda: Add side_by_side support

2019-11-20 Thread james qian wang (Arm Technology China)
Hi: All

Komeda HW (two pipelines) can work on side by side mode, which splits the
internal display processing to two halves (LEFT/RIGHT) and handle them by
two pipelines separately and simultaneously.
And since one single pipeline only handles the half display frame, so the
main engine clock requirement can also be halved.

The data flow of side_by_side as blow:

 slave.layer0 ->\  /-> slave.wb_layer -> mem.fb.right_part
 ... -> slave.compiz ->
 slave.layer3 ->/  \-> slave.improcessor->
  \   /-> output-link0
 master.layer0 ->\   /-> master.improcessor ->\-> output-link1
 ...  -> master.compiz ->
 master.layer3 ->/   \-> master.wb_layer -> mem.fb.left_part

v3: Rebase

james qian wang (Arm Technology China) (6):
  drm/komeda: Add side by side assembling
  drm/komeda: Add side by side plane_state split
  drm/komeda: Build side by side display output pipeline
  drm/komeda: Add side by side support for writeback
  drm/komeda: Update writeback signal for side_by_side
  drm/komeda: Expose side_by_side by sysfs/config_id

 .../drm/arm/display/include/malidp_product.h  |   3 +-
 .../arm/display/komeda/d71/d71_component.c|   4 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  54 ++--
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |   4 +
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |   9 +
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   8 +
 .../drm/arm/display/komeda/komeda_pipeline.c  |  50 +++-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  39 ++-
 .../display/komeda/komeda_pipeline_state.c| 277 +-
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 .../arm/display/komeda/komeda_wb_connector.c  |  11 +-
 11 files changed, 421 insertions(+), 45 deletions(-)

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

Re: drm/komeda: Remove unnecessary komeda_wb_connector_detect

2019-11-20 Thread james qian wang (Arm Technology China)
On Wed, Nov 20, 2019 at 12:03:55PM +, Mihail Atanassov wrote:
> The func is optional and the connector will report as always connected,
> i.e. no change in behaviour.
> 
> Signed-off-by: Mihail Atanassov 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 7 ---
>  1 file changed, 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> index e465cc4879c9..c89ecdba8c28 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
> @@ -107,12 +107,6 @@ static const struct drm_connector_helper_funcs 
> komeda_wb_conn_helper_funcs = {
>   .mode_valid = komeda_wb_connector_mode_valid,
>  };
>  
> -static enum drm_connector_status
> -komeda_wb_connector_detect(struct drm_connector *connector, bool force)
> -{
> - return connector_status_connected;
> -}
> -
>  static int
>  komeda_wb_connector_fill_modes(struct drm_connector *connector,
>  uint32_t maxX, uint32_t maxY)
> @@ -128,7 +122,6 @@ static void komeda_wb_connector_destroy(struct 
> drm_connector *connector)
>  
>  static const struct drm_connector_funcs komeda_wb_connector_funcs = {
>   .reset  = drm_atomic_helper_connector_reset,
> - .detect = komeda_wb_connector_detect,
>   .fill_modes = komeda_wb_connector_fill_modes,
>   .destroy= komeda_wb_connector_destroy,
>   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,

Looks good to me.

Reviewed-by: James Qian Wang (Arm Technology China) 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [PATCH v3 1/6] drm/komeda: Add side by side assembling

2019-11-19 Thread james qian wang (Arm Technology China)
On Fri, Nov 15, 2019 at 12:02:00AM +, Mihail Atanassov wrote:
> Hi James,
> 
> On Thursday, 14 November 2019 08:37:24 GMT james qian wang (Arm Technology 
> China) wrote:
> > Komeda HW can support side by side, which splits the internal display
> > processing to two single halves (LEFT/RIGHT) and handle them by two
> > pipelines separately.
> > komeda "side by side" is enabled by DT property: "side_by_side_master",
> > once DT configured side by side, komeda need to verify it with HW's
> > configuration, and assemble it for the further usage.
> 
> A few problems I see with this approach:
>  - This property doesn't scale to >2 pipes;
>  - Our HW is capable of dynamically switching between SBS and non-SBS
> modes, with this DT property you're effectively denying the opportunity
> to use the second pipe when the first one can be satisfied with
> 4 planes and 1px/clk.
> 
> If we only want to fix the first problem, then at least we need this
> to be a property of the pipeline node with a phandle linking slave to
> master (or bidirectional).

I had consider this way before, but consider we have no product (now
and in next 2/3 years) can support >2 pipes. So for DT I decide to
focus on current, but you may see I add two side_by_side flags.

  - mdev->side_by_side.
  - crtc->side_by_side.

And beside the DT parse we use mdev->side_by_side, the real SBS
operation actually based on crtc->side_by_side, then once the HW
changed, we only need to update the SBS assemble/decision code, but no
need to update the real sbs logic.

thanks
James

> For the second, why not do the SBS decision at modeset time?
> If the first CRTC has dual-link output and the commit:
>  - only drives one CRTC
>  - uses up to 4 planes
>  - doesn't meet clk requirements without SBS but does with SBS
> then we can switch SBS on dynamically.
> And we can tweak that decision with power use in mind later on since
> there's no user-visible knob.

Yes, you're right, current implementation just use simplest way to
show the feature, and for dynamic enable/disable sbs will be added
when we have the real usage case.

> We can still keep a DT property if we have a use case for it (e.g.
> forcing SBS on for some reason), but we might want to name it slightly
> more conservatively then, so it doesn't imply that we never do SBS
> when it's not there.
> 
> Lastly, maintaining that property in combination with the dynamic
> modeset-time SBS decision tree means extra code for more or less the
> same functionality. <2c>I'm not 100% sure it's worth it.

I think we'd add such support when we have the real use case. :)

> > 
> > v3: Correct a typo.
> > 
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
> > ---
> >  .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 13 -
> >  .../gpu/drm/arm/display/komeda/komeda_dev.c   |  3 ++
> >  .../gpu/drm/arm/display/komeda/komeda_dev.h   |  9 
> >  .../gpu/drm/arm/display/komeda/komeda_kms.h   |  3 ++
> >  .../drm/arm/display/komeda/komeda_pipeline.c  | 50 +--
> >  .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
> >  6 files changed, 73 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > index 1c452ea75999..cee9a1692e71 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
> > @@ -561,21 +561,30 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
> > kms->n_crtcs = 0;
> >  
> > for (i = 0; i < mdev->n_pipelines; i++) {
> > +   /* if sbs, one komeda_dev only can represent one CRTC */
> > +   if (mdev->side_by_side && i != mdev->side_by_side_master)
> > +   continue;
> > +
> > crtc = >crtcs[kms->n_crtcs];
> > master = mdev->pipelines[i];
> >  
> > crtc->master = master;
> > crtc->slave  = komeda_pipeline_get_slave(master);
> > +   crtc->side_by_side = mdev->side_by_side;
> >  
> > if (crtc->slave)
> > sprintf(str, "pipe-%d", crtc->slave->id);
> > else
> > sprintf(str, "None");
> >  
> > -   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
> > -kms->n_crtcs, master->id, str);
> > +   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s) sbs(%s).\n",
> > +kms->n_crtcs, master-&

Re: [PATCH v3 2/6] drm/komeda: Add side by side plane_state split

2019-11-19 Thread james qian wang (Arm Technology China)
On Fri, Nov 15, 2019 at 12:00:01AM +, Mihail Atanassov wrote:
> On Thursday, 14 November 2019 08:37:31 GMT james qian wang (Arm Technology 
> China) wrote:
> > On side by side mode, The full display frame will be split into two parts
> > (Left/Right), and each part will be handled by a single pipeline separately
> > master pipeline for left part, slave for right.
> > 
> > To simplify the usage and implementation, komeda use the following scheme
> > to do the side by side split
> > 1. The planes also have been grouped into two classes:
> >master-planes and slave-planes.
> > 2. The master plane can display its image on any location of the final/full
> >display frame, komeda will help to split the plane configuration to two
> >parts and fed them into master and slave pipelines.
> > 3. The slave plane only can put its display rect on the right part of the
> >final display frame, and its data is only can be fed into the slave
> >pipeline.
> > 
> > From the perspective of resource usage and assignment:
> > The master plane can use the resources from the master pipeline and slave
> > pipeline both, but slave plane only can use the slave pipeline resources.
> > 
> > With such scheme, the usage of master planes are same as the none
> > side_by_side mode. user can easily skip the slave planes and no need to
> > consider side_by_side for them.
> > 
> > Signed-off-by: James Qian Wang (Arm Technology China) 
> > 
> > ---
> >  .../drm/arm/display/komeda/komeda_pipeline.h  |  33 ++-
> >  .../display/komeda/komeda_pipeline_state.c| 188 ++
> >  .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
> >  3 files changed, 220 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > index 20a076cce635..4c0946fbaac1 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
> > @@ -521,6 +521,20 @@ komeda_component_pickup_output(struct komeda_component 
> > *c, u32 avail_comps)
> > return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
> >  }
> >  
> > +static inline const char *
> > +komeda_data_flow_msg(struct komeda_data_flow_cfg *config)
> > +{
> > +   static char str[128];
> > +
> > +   snprintf(str, sizeof(str),
> > +"rot: %x src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
> > +config->rot,
> > +config->in_x, config->in_y, config->in_w, config->in_h,
> > +config->out_x, config->out_y, config->out_w, config->out_h);
> > +
> > +   return str;
> > +}
> > +
> >  struct komeda_plane_state;
> >  struct komeda_crtc_state;
> >  struct komeda_crtc;
> > @@ -532,22 +546,27 @@ int komeda_build_layer_data_flow(struct komeda_layer 
> > *layer,
> >  struct komeda_plane_state *kplane_st,
> >  struct komeda_crtc_state *kcrtc_st,
> >  struct komeda_data_flow_cfg *dflow);
> > -int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
> > - struct drm_connector_state *conn_st,
> > - struct komeda_crtc_state *kcrtc_st,
> > - struct komeda_data_flow_cfg *dflow);
> > -int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
> > -  struct komeda_crtc_state *kcrtc_st);
> > -
> >  int komeda_build_layer_split_data_flow(struct komeda_layer *left,
> >struct komeda_plane_state *kplane_st,
> >struct komeda_crtc_state *kcrtc_st,
> >struct komeda_data_flow_cfg *dflow);
> > +int komeda_build_layer_sbs_data_flow(struct komeda_layer *layer,
> > +struct komeda_plane_state *kplane_st,
> > +struct komeda_crtc_state *kcrtc_st,
> > +struct komeda_data_flow_cfg *dflow);
> > +
> > +int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
> > + struct drm_connector_state *conn_st,
> > + struct komeda_crtc_state *kcrtc_st,
> > + struct komeda_data_flow_cfg *dflow);
> >  int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
> > 

Re: [PATCHv2 3/4] drm/komeda: use afbc helpers

2019-11-19 Thread james qian wang (Arm Technology China)
On Mon, Nov 18, 2019 at 10:51:36AM +0100, Daniel Vetter wrote:
> On Mon, Nov 18, 2019 at 07:09:56AM +0000, james qian wang (Arm Technology 
> China) wrote:
> > On Thu, Nov 14, 2019 at 11:12:13AM +0100, Daniel Vetter wrote:
> > > On Thu, Nov 14, 2019 at 2:52 AM james qian wang (Arm Technology China)
> > >  wrote:
> > > > On Wed, Nov 13, 2019 at 12:39:54PM +0100, Daniel Vetter wrote:
> > > > > On Wed, Nov 13, 2019 at 02:01:53AM +, james qian wang (Arm 
> > > > > Technology China) wrote:
> > > > > > On Fri, Nov 08, 2019 at 04:09:54PM +, Ayan Halder wrote:
> > > > > > > On Mon, Nov 04, 2019 at 11:12:27PM +0100, Andrzej Pietrasiewicz 
> > > > > > > wrote:
> > > > > > > > There are afbc helpers available.
> > > > > > > >
> > > > > > > > Signed-off-by: Andrzej Pietrasiewicz 
> > > > > > > > ---
> > > > > > > >  .../arm/display/komeda/komeda_format_caps.h   |  1 -
> > > > > > > >  .../arm/display/komeda/komeda_framebuffer.c   | 44 
> > > > > > > > +++
> > > > > > > >  2 files changed, 17 insertions(+), 28 deletions(-)
> > > > > > > >
> > > > > > > > diff --git 
> > > > > > > > a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
> > > > > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > > > index 32273cf18f7c..607eea80e60c 100644
> > > > > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > > > @@ -33,7 +33,6 @@
> > > > > > > >
> > > > > > > >  #define AFBC_TH_LAYOUT_ALIGNMENT   8
> > > > > > > >  #define AFBC_HEADER_SIZE   16
> > > > > > > > -#define AFBC_SUPERBLK_ALIGNMENT128
> > > > > > > >  #define AFBC_SUPERBLK_PIXELS   256
> > > > > > > >  #define AFBC_BODY_START_ALIGNMENT  1024
> > > > > > > >  #define AFBC_TH_BODY_START_ALIGNMENT   4096
> > > > > > > > diff --git 
> > > > > > > > a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
> > > > > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > > > index 1b01a625f40e..e9c87551a5b8 100644
> > > > > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > > > @@ -4,6 +4,7 @@
> > > > > > > >   * Author: James.Qian.Wang 
> > > > > > > >   *
> > > > > > > >   */
> > > > > > > > +#include 
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > >  #include 
> > > > > > > > @@ -43,8 +44,7 @@ komeda_fb_afbc_size_check(struct komeda_fb 
> > > > > > > > *kfb, struct drm_file *file,
> > > > > > > > struct drm_framebuffer *fb = >base;
> > > > > > > > const struct drm_format_info *info = fb->format;
> > > > > > > > struct drm_gem_object *obj;
> > > > > > > > -   u32 alignment_w = 0, alignment_h = 0, alignment_header, 
> > > > > > > > n_blocks, bpp;
> > > > > > > > -   u64 min_size;
> > > > > > > > +   u32 alignment_w = 0, alignment_h = 0, alignment_header, 
> > > > > > > > bpp;
> > > > > > > >
> > > > > > > > obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
> > > > > > > > if (!obj) {
> > > > > > > > @@ -52,19 +52,15 @@ komeda_fb_afbc_size_check(struct komeda_fb 
> > > > > > > > *kfb, struct drm_file *file,
> > > > > > > > return -ENOENT;
> > > > > > > > }
> > > > > > > >
> > > > > > > > -   switch (fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) 
> > > > > >

Re: [PATCHv2 3/4] drm/komeda: use afbc helpers

2019-11-17 Thread james qian wang (Arm Technology China)
On Thu, Nov 14, 2019 at 11:12:13AM +0100, Daniel Vetter wrote:
> On Thu, Nov 14, 2019 at 2:52 AM james qian wang (Arm Technology China)
>  wrote:
> > On Wed, Nov 13, 2019 at 12:39:54PM +0100, Daniel Vetter wrote:
> > > On Wed, Nov 13, 2019 at 02:01:53AM +0000, james qian wang (Arm Technology 
> > > China) wrote:
> > > > On Fri, Nov 08, 2019 at 04:09:54PM +, Ayan Halder wrote:
> > > > > On Mon, Nov 04, 2019 at 11:12:27PM +0100, Andrzej Pietrasiewicz wrote:
> > > > > > There are afbc helpers available.
> > > > > >
> > > > > > Signed-off-by: Andrzej Pietrasiewicz 
> > > > > > ---
> > > > > >  .../arm/display/komeda/komeda_format_caps.h   |  1 -
> > > > > >  .../arm/display/komeda/komeda_framebuffer.c   | 44 
> > > > > > +++
> > > > > >  2 files changed, 17 insertions(+), 28 deletions(-)
> > > > > >
> > > > > > diff --git 
> > > > > > a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
> > > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > index 32273cf18f7c..607eea80e60c 100644
> > > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > > > @@ -33,7 +33,6 @@
> > > > > >
> > > > > >  #define AFBC_TH_LAYOUT_ALIGNMENT   8
> > > > > >  #define AFBC_HEADER_SIZE   16
> > > > > > -#define AFBC_SUPERBLK_ALIGNMENT128
> > > > > >  #define AFBC_SUPERBLK_PIXELS   256
> > > > > >  #define AFBC_BODY_START_ALIGNMENT  1024
> > > > > >  #define AFBC_TH_BODY_START_ALIGNMENT   4096
> > > > > > diff --git 
> > > > > > a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
> > > > > > b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > index 1b01a625f40e..e9c87551a5b8 100644
> > > > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > > > @@ -4,6 +4,7 @@
> > > > > >   * Author: James.Qian.Wang 
> > > > > >   *
> > > > > >   */
> > > > > > +#include 
> > > > > >  #include 
> > > > > >  #include 
> > > > > >  #include 
> > > > > > @@ -43,8 +44,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, 
> > > > > > struct drm_file *file,
> > > > > > struct drm_framebuffer *fb = >base;
> > > > > > const struct drm_format_info *info = fb->format;
> > > > > > struct drm_gem_object *obj;
> > > > > > -   u32 alignment_w = 0, alignment_h = 0, alignment_header, 
> > > > > > n_blocks, bpp;
> > > > > > -   u64 min_size;
> > > > > > +   u32 alignment_w = 0, alignment_h = 0, alignment_header, bpp;
> > > > > >
> > > > > > obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
> > > > > > if (!obj) {
> > > > > > @@ -52,19 +52,15 @@ komeda_fb_afbc_size_check(struct komeda_fb 
> > > > > > *kfb, struct drm_file *file,
> > > > > > return -ENOENT;
> > > > > > }
> > > > > >
> > > > > > -   switch (fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> > > > > > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> > > > > > -   alignment_w = 32;
> > > > > > -   alignment_h = 8;
> > > > > > -   break;
> > > > > > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> > > > > > -   alignment_w = 16;
> > > > > > -   alignment_h = 16;
> > > > > > -   break;
> > > > > > -   default:
> > > > > > -   WARN(1, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: 
> > > > > > %lld.\n",
> > > > > > -fb->modifier & 
> > > > > > AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> > > > > >

[PATCH] drm/komeda: Clean warnings: candidate for 'gnu_printf’ format attribute

2019-11-14 Thread james qian wang (Arm Technology China)
komeda/komeda_event.c: In function ‘komeda_sprintf’:
komeda/komeda_event.c:31:2: warning: function ‘komeda_sprintf’ might be a 
candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
  num = vsnprintf(str->str + str->len, free_sz, fmt, args);

v2: Update the comment msg.

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_event.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
index bf269683f811..977c38d516da 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
@@ -17,6 +17,7 @@ struct komeda_str {
 
 /* return 0 on success,  < 0 on no space.
  */
+__printf(2, 3)
 static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
 {
va_list args;
-- 
2.20.1

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

Re: [PATCH] drm/komeda: Clean warnings: candidate for 'gnu_printf’ format attribute

2019-11-14 Thread james qian wang (Arm Technology China)
On Thu, Nov 14, 2019 at 08:47:58AM +, Mihail Atanassov wrote:
> Hi James,
> 
> On Thursday, 14 November 2019 07:18:56 GMT james qian wang (Arm Technology 
> China) wrote:
> > komeda/komeda_pipeline.c: In function ‘komeda_component_add’:
> > komeda/komeda_pipeline.c:213:3: warning: function ‘komeda_component_add’ 
> > might be a candidate for ‘gnu_printf’ format attribute 
> > [-Wsuggest-attribute=format]
> >vsnprintf(c->name, sizeof(c->name), name_fmt, args);
> >^
> 
> The fix for this one isn't in the patch below.

Because the upstream code already have it, But I forgot to update the
comment msg, will send v2 to fix it.

Thanks
James

> > 
> > komeda/komeda_event.c: In function ‘komeda_sprintf’:
> > komeda/komeda_event.c:31:2: warning: function ‘komeda_sprintf’ might be a 
> > candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
> >   num = vsnprintf(str->str + str->len, free_sz, fmt, args);
> > 
> > Signed-off-by: james qian wang (Arm Technology China) 
> > 
> > ---
> >  drivers/gpu/drm/arm/display/komeda/komeda_event.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > index bf269683f811..977c38d516da 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > @@ -17,6 +17,7 @@ struct komeda_str {
> >  
> >  /* return 0 on success,  < 0 on no space.
> >   */
> > +__printf(2, 3)
> >  static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
> >  {
> > va_list args;
> > -- 
> > 2.20.1
> > 
> > 
> 
> 
> -- 
> Mihail
> 
> 
> 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v3 5/6] drm/komeda: Update writeback signal for side_by_side

2019-11-14 Thread james qian wang (Arm Technology China)
In side by side mode, a writeback job is completed by two pipelines: left
by master and right by slave, we need to wait both pipeline finished (EOW),
then can signal the writeback job completion.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 23 ++-
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  5 
 .../arm/display/komeda/komeda_wb_connector.c  |  3 +++
 3 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 24928b922fbd..78351b7135f8 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -193,27 +193,28 @@ komeda_crtc_unprepare(struct komeda_crtc *kcrtc)
return err;
 }
 
-void komeda_crtc_handle_event(struct komeda_crtc   *kcrtc,
+void komeda_crtc_handle_event(struct komeda_crtc *kcrtc,
  struct komeda_events *evts)
 {
struct drm_crtc *crtc = >base;
+   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
u32 events = evts->pipes[kcrtc->master->id];
 
if (events & KOMEDA_EVENT_VSYNC)
drm_crtc_handle_vblank(crtc);
 
-   if (events & KOMEDA_EVENT_EOW) {
-   struct komeda_wb_connector *wb_conn = kcrtc->wb_conn;
+   /* handles writeback event */
+   if (events & KOMEDA_EVENT_EOW)
+   wb_conn->complete_pipes |= BIT(kcrtc->master->id);
 
-   if (wb_conn)
-   drm_writeback_signal_completion(_conn->base, 0);
-   else
-   DRM_WARN("CRTC[%d]: EOW happen but no wb_connector.\n",
-drm_crtc_index(>base));
+   if (kcrtc->side_by_side &&
+   (evts->pipes[kcrtc->slave->id] & KOMEDA_EVENT_EOW))
+   wb_conn->complete_pipes |= BIT(kcrtc->slave->id);
+
+   if (wb_conn->expected_pipes == wb_conn->complete_pipes) {
+   wb_conn->complete_pipes = 0;
+   drm_writeback_signal_completion(_conn->base, 0);
}
-   /* will handle it together with the write back support */
-   if (events & KOMEDA_EVENT_EOW)
-   DRM_DEBUG("EOW.\n");
 
if (events & KOMEDA_EVENT_FLIP) {
unsigned long flags;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index ae6654fe95e2..174fb0a0b49b 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -58,6 +58,11 @@ struct komeda_wb_connector {
 
/** @wb_layer: represents associated writeback pipeline of komeda */
struct komeda_layer *wb_layer;
+
+   /** @expected_pipes: pipelines are used for the writeback job */
+   u32 expected_pipes;
+   /** @complete_pipes: pipelines which have finished writeback */
+   u32 complete_pipes;
 };
 
 /**
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 44e628747654..d6833ea3b822 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -157,6 +157,9 @@ static int komeda_wb_connector_add(struct komeda_kms_dev 
*kms,
return -ENOMEM;
 
kwb_conn->wb_layer = kcrtc->master->wb_layer;
+   kwb_conn->expected_pipes = BIT(kcrtc->master->id);
+   if (kcrtc->side_by_side)
+   kwb_conn->expected_pipes |= BIT(kcrtc->slave->id);
 
wb_conn = _conn->base;
wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(>base));
-- 
2.20.1

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

[PATCH v3 6/6] drm/komeda: Expose side_by_side by sysfs/config_id

2019-11-14 Thread james qian wang (Arm Technology China)
There are some restrictions if HW works on side_by_side, expose it via
config_id to user.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/include/malidp_product.h | 3 ++-
 drivers/gpu/drm/arm/display/komeda/komeda_dev.c  | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/include/malidp_product.h 
b/drivers/gpu/drm/arm/display/include/malidp_product.h
index 1053b11352eb..96e2e4016250 100644
--- a/drivers/gpu/drm/arm/display/include/malidp_product.h
+++ b/drivers/gpu/drm/arm/display/include/malidp_product.h
@@ -27,7 +27,8 @@ union komeda_config_id {
n_scalers:2, /* number of scalers per pipeline */
n_layers:3, /* number of layers per pipeline */
n_richs:3, /* number of rich layers per pipeline */
-   reserved_bits:6;
+   side_by_side:1, /* if HW works on side_by_side mode */
+   reserved_bits:5;
};
__u32 value;
 };
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index c3fa4835cb8d..4dd4699d4e3d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -83,6 +83,7 @@ config_id_show(struct device *dev, struct device_attribute 
*attr, char *buf)
memset(_id, 0, sizeof(config_id));
 
config_id.max_line_sz = pipe->layers[0]->hsize_in.end;
+   config_id.side_by_side = mdev->side_by_side;
config_id.n_pipelines = mdev->n_pipelines;
config_id.n_scalers = pipe->n_scalers;
config_id.n_layers = pipe->n_layers;
-- 
2.20.1

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

[PATCH v3 3/6] drm/komeda: Build side by side display output pipeline

2019-11-14 Thread james qian wang (Arm Technology China)
For side by side, the slave pipeline merges to master via image processor

 slave-layers -> slave-compiz-> slave-improc-
 \
 master-layers -> master-compiz -> master-improc ->

v3: Rebase.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../arm/display/komeda/d71/d71_component.c|  4 ++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 18 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 .../display/komeda/komeda_pipeline_state.c| 51 ++-
 .../arm/display/komeda/komeda_wb_connector.c  |  2 +-
 5 files changed, 56 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index b6517c46e670..6dadf4413ef3 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1085,6 +1085,10 @@ static void d71_improc_update(struct komeda_component *c,
else if (st->color_format == DRM_COLOR_FORMAT_YCRCB444)
ctrl |= IPS_CTRL_YUV;
 
+   /* slave input has been enabled, means side by side */
+   if (has_bit(1, state->active_inputs))
+   ctrl |= IPS_CTRL_SBS;
+
malidp_write32_mask(reg, BLK_CONTROL, mask, ctrl);
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index cee9a1692e71..24928b922fbd 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -385,15 +385,23 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc,
komeda_crtc_do_flush(crtc, old);
 }
 
-/* Returns the minimum frequency of the aclk rate (main engine clock) in Hz */
+/*
+ * Returns the minimum frequency of the aclk rate (main engine clock) in Hz.
+ *
+ * The DPU output can be split into two halves, to stay within the bandwidth
+ * capabilities of the external link (dual-link mode).
+ * In these cases, each output link runs at half the pixel clock rate of the
+ * combined display, and has half the number of pixels.
+ * Beside split the output, the DPU internal pixel processing also can be split
+ * into two halves (LEFT/RIGHT) and handles by two pipelines simultaneously.
+ * So if side by side, the pipeline (main engine clock) also can run at half
+ * the clock rate of the combined display.
+ */
 static unsigned long
 komeda_calc_min_aclk_rate(struct komeda_crtc *kcrtc,
  unsigned long pxlclk)
 {
-   /* Once dual-link one display pipeline drives two display outputs,
-* the aclk needs run on the double rate of pxlclk
-*/
-   if (kcrtc->master->dual_link)
+   if (kcrtc->master->dual_link && !kcrtc->side_by_side)
return pxlclk * 2;
else
return pxlclk;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 4c0946fbaac1..59a81b4476df 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -540,6 +540,7 @@ struct komeda_crtc_state;
 struct komeda_crtc;
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize);
 
 int komeda_build_layer_data_flow(struct komeda_layer *layer,
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 5de0d231a1c3..4dbf71455d1d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -654,12 +654,13 @@ komeda_merger_validate(struct komeda_merger *merger,
 }
 
 void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,
+  bool side_by_side,
   u16 *hsize, u16 *vsize)
 {
struct drm_display_mode *m = _st->base.adjusted_mode;
 
if (hsize)
-   *hsize = m->hdisplay;
+   *hsize = side_by_side ? m->hdisplay / 2 : m->hdisplay;
if (vsize)
*vsize = m->vdisplay;
 }
@@ -670,12 +671,14 @@ komeda_compiz_set_input(struct komeda_compiz *compiz,
struct komeda_data_flow_cfg *dflow)
 {
struct drm_atomic_state *drm_st = kcrtc_st->base.state;
+   struct drm_crtc *crtc = kcrtc_st->base.crtc;
struct komeda_component_state *c_st, *old_st;
struct komeda_compiz_input_cfg *cin;
u16 compiz_w, compiz_h;
int idx = dflow->blending_zorder;
 
-   pipeline_composition_size(kcrtc_st, _w, _h);
+   pipeline_composition_size(kcrtc_st, to_kcrtc(crtc)->side_by_side,
+ _w, _h);
/* ch

[PATCH v3 4/6] drm/komeda: Add side by side support for writeback

2019-11-14 Thread james qian wang (Arm Technology China)
In side by side mode, the master pipeline writeback the left frame and the
slave writeback the right part, the data flow as below:

  slave.compiz -> slave.wb_layer -> fb (right-part)
  master.compiz -> master.wb_layer -> fb (left-part)

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  4 ++
 .../display/komeda/komeda_pipeline_state.c| 42 +++
 .../arm/display/komeda/komeda_wb_connector.c  |  6 ++-
 3 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 59a81b4476df..76621a972803 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -564,6 +564,10 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow);
 
 int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
   struct komeda_crtc_state *kcrtc_st);
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 4dbf71455d1d..ab4d9ad79083 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1377,6 +1377,48 @@ int komeda_build_wb_split_data_flow(struct komeda_layer 
*wb_layer,
return komeda_wb_layer_validate(wb_layer, conn_st, dflow);
 }
 
+/* writeback side by side split data path:
+ *
+ * slave.compiz -> slave.wb_layer - > fb (right-part)
+ * master.compiz -> master.wb_layer -> fb (left-part)
+ */
+int komeda_build_wb_sbs_data_flow(struct komeda_crtc *kcrtc,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *wb_dflow)
+{
+   struct komeda_pipeline *master = kcrtc->master;
+   struct komeda_pipeline *slave = kcrtc->slave;
+   struct komeda_data_flow_cfg m_dflow, s_dflow;
+   int err;
+
+   if (wb_dflow->en_scaling || wb_dflow->en_img_enhancement) {
+   DRM_DEBUG_ATOMIC("sbs doesn't support WB_scaling\n");
+   return -EINVAL;
+   }
+
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+   memcpy(_dflow, wb_dflow, sizeof(*wb_dflow));
+
+   /* master writeout the left part */
+   m_dflow.in_w >>= 1;
+   m_dflow.out_w >>= 1;
+   m_dflow.input.component = >compiz->base;
+
+   /* slave writeout the right part */
+   s_dflow.in_w >>= 1;
+   s_dflow.out_w >>= 1;
+   s_dflow.in_x += m_dflow.in_w;
+   s_dflow.out_x += m_dflow.out_w;
+   s_dflow.input.component = >compiz->base;
+
+   err = komeda_wb_layer_validate(master->wb_layer, conn_st, _dflow);
+   if (err)
+   return err;
+
+   return komeda_wb_layer_validate(slave->wb_layer, conn_st, _dflow);
+}
+
 /* build display output data flow, the data path is:
  * compiz -> improc -> timing_ctrlr
  */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
index 17ea021488aa..44e628747654 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
@@ -37,6 +37,7 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
   struct drm_crtc_state *crtc_st,
   struct drm_connector_state *conn_st)
 {
+   struct komeda_crtc *kcrtc = to_kcrtc(crtc_st->crtc);
struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
struct drm_writeback_job *writeback_job = conn_st->writeback_job;
struct komeda_layer *wb_layer;
@@ -65,7 +66,10 @@ komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,
if (err)
return err;
 
-   if (dflow.en_split)
+   if (kcrtc->side_by_side)
+   err = komeda_build_wb_sbs_data_flow(kcrtc,
+   conn_st, kcrtc_st, );
+   else if (dflow.en_split)
err = komeda_build_wb_split_data_flow(wb_layer,
conn_st, kcrtc_st, );
else
-- 
2.20.1

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

[PATCH v3 2/6] drm/komeda: Add side by side plane_state split

2019-11-14 Thread james qian wang (Arm Technology China)
On side by side mode, The full display frame will be split into two parts
(Left/Right), and each part will be handled by a single pipeline separately
master pipeline for left part, slave for right.

To simplify the usage and implementation, komeda use the following scheme
to do the side by side split
1. The planes also have been grouped into two classes:
   master-planes and slave-planes.
2. The master plane can display its image on any location of the final/full
   display frame, komeda will help to split the plane configuration to two
   parts and fed them into master and slave pipelines.
3. The slave plane only can put its display rect on the right part of the
   final display frame, and its data is only can be fed into the slave
   pipeline.

From the perspective of resource usage and assignment:
The master plane can use the resources from the master pipeline and slave
pipeline both, but slave plane only can use the slave pipeline resources.

With such scheme, the usage of master planes are same as the none
side_by_side mode. user can easily skip the slave planes and no need to
consider side_by_side for them.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../drm/arm/display/komeda/komeda_pipeline.h  |  33 ++-
 .../display/komeda/komeda_pipeline_state.c| 188 ++
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 3 files changed, 220 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index 20a076cce635..4c0946fbaac1 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -521,6 +521,20 @@ komeda_component_pickup_output(struct komeda_component *c, 
u32 avail_comps)
return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
 }
 
+static inline const char *
+komeda_data_flow_msg(struct komeda_data_flow_cfg *config)
+{
+   static char str[128];
+
+   snprintf(str, sizeof(str),
+"rot: %x src[x/y:%d/%d, w/h:%d/%d] disp[x/y:%d/%d, w/h:%d/%d]",
+config->rot,
+config->in_x, config->in_y, config->in_w, config->in_h,
+config->out_x, config->out_y, config->out_w, config->out_h);
+
+   return str;
+}
+
 struct komeda_plane_state;
 struct komeda_crtc_state;
 struct komeda_crtc;
@@ -532,22 +546,27 @@ int komeda_build_layer_data_flow(struct komeda_layer 
*layer,
 struct komeda_plane_state *kplane_st,
 struct komeda_crtc_state *kcrtc_st,
 struct komeda_data_flow_cfg *dflow);
-int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
- struct drm_connector_state *conn_st,
- struct komeda_crtc_state *kcrtc_st,
- struct komeda_data_flow_cfg *dflow);
-int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
-  struct komeda_crtc_state *kcrtc_st);
-
 int komeda_build_layer_split_data_flow(struct komeda_layer *left,
   struct komeda_plane_state *kplane_st,
   struct komeda_crtc_state *kcrtc_st,
   struct komeda_data_flow_cfg *dflow);
+int komeda_build_layer_sbs_data_flow(struct komeda_layer *layer,
+struct komeda_plane_state *kplane_st,
+struct komeda_crtc_state *kcrtc_st,
+struct komeda_data_flow_cfg *dflow);
+
+int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,
+ struct drm_connector_state *conn_st,
+ struct komeda_crtc_state *kcrtc_st,
+ struct komeda_data_flow_cfg *dflow);
 int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,
struct drm_connector_state *conn_st,
struct komeda_crtc_state *kcrtc_st,
struct komeda_data_flow_cfg *dflow);
 
+int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,
+  struct komeda_crtc_state *kcrtc_st);
+
 int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,
   struct komeda_crtc_state *kcrtc_st);
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 0930234abb9d..5de0d231a1c3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -1130,6 +1130,194 @@ int komeda_build_layer_split_data_flow(struct 
komeda_layer *left,
return err;
 }
 
+/* split

[PATCH v3 1/6] drm/komeda: Add side by side assembling

2019-11-14 Thread james qian wang (Arm Technology China)
Komeda HW can support side by side, which splits the internal display
processing to two single halves (LEFT/RIGHT) and handle them by two
pipelines separately.
komeda "side by side" is enabled by DT property: "side_by_side_master",
once DT configured side by side, komeda need to verify it with HW's
configuration, and assemble it for the further usage.

v3: Correct a typo.

Signed-off-by: James Qian Wang (Arm Technology China) 
---
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  | 13 -
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |  3 ++
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |  9 
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |  3 ++
 .../drm/arm/display/komeda/komeda_pipeline.c  | 50 +--
 .../drm/arm/display/komeda/komeda_pipeline.h  |  1 +
 6 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 1c452ea75999..cee9a1692e71 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -561,21 +561,30 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms,
kms->n_crtcs = 0;
 
for (i = 0; i < mdev->n_pipelines; i++) {
+   /* if sbs, one komeda_dev only can represent one CRTC */
+   if (mdev->side_by_side && i != mdev->side_by_side_master)
+   continue;
+
crtc = >crtcs[kms->n_crtcs];
master = mdev->pipelines[i];
 
crtc->master = master;
crtc->slave  = komeda_pipeline_get_slave(master);
+   crtc->side_by_side = mdev->side_by_side;
 
if (crtc->slave)
sprintf(str, "pipe-%d", crtc->slave->id);
else
sprintf(str, "None");
 
-   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n",
-kms->n_crtcs, master->id, str);
+   DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s) sbs(%s).\n",
+kms->n_crtcs, master->id, str,
+crtc->side_by_side ? "On" : "Off");
 
kms->n_crtcs++;
+
+   if (mdev->side_by_side)
+   break;
}
 
return 0;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
index 4e46f650fddf..c3fa4835cb8d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c
@@ -178,6 +178,9 @@ static int komeda_parse_dt(struct device *dev, struct 
komeda_dev *mdev)
}
}
 
+   mdev->side_by_side = !of_property_read_u32(np, "side_by_side_master",
+  >side_by_side_master);
+
return ret;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index d406a4d83352..471604b42431 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -183,6 +183,15 @@ struct komeda_dev {
 
/** @irq: irq number */
int irq;
+   /**
+* @side_by_side:
+*
+* on sbs the whole display frame will be split to two halves (1:2),
+* master pipeline handles the left part, slave for the right part
+*/
+   bool side_by_side;
+   /** @side_by_side_master: master pipe id for side by side */
+   int side_by_side_master;
 
/** @lock: used to protect dpmode */
struct mutex lock;
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
index 456f3c435719..ae6654fe95e2 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h
@@ -76,6 +76,9 @@ struct komeda_crtc {
 */
struct komeda_pipeline *slave;
 
+   /** @side_by_side: if the master and slave works on side by side mode */
+   bool side_by_side;
+
/** @slave_planes: komeda slave planes mask */
u32 slave_planes;
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
index 452e505a1fd3..104e27cc1dc3 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c
@@ -326,14 +326,56 @@ static void komeda_pipeline_assemble(struct 
komeda_pipeline *pipe)
 struct komeda_pipeline *
 komeda_pipeline_get_slave(struct komeda_pipeline *master)
 {
-   struct komeda_component *slave;
+   struct komeda_dev *mdev = master->mdev;
+   struct komeda_component *comp, *slave;
+   u32 avail_inputs;
+

[PATCH v3 0/6] arm/komeda: Add side_by_side support

2019-11-14 Thread james qian wang (Arm Technology China)
Komeda HW (two pipelines) can work on side by side mode, which splits the
internal display processing to two halves (LEFT/RIGHT) and handle them by
two pipelines separately and simultaneously.
And since one single pipeline only handles the half display frame, so the
main engine clock requirement can also be halved.

The data flow of side_by_side as blow:

 slave.layer0 ->\  /-> slave.wb_layer -> mem.fb.right_part
 ... -> slave.compiz ->
 slave.layer3 ->/  \-> slave.improcessor->
  \   /-> output-link0
 master.layer0 ->\   /-> master.improcessor ->\-> output-link1
 ...  -> master.compiz ->
 master.layer3 ->/   \-> master.wb_layer -> mem.fb.left_part

v3: Rebase

james qian wang (Arm Technology China) (6):
  drm/komeda: Add side by side assembling
  drm/komeda: Add side by side plane_state split
  drm/komeda: Build side by side display output pipeline
  drm/komeda: Add side by side support for writeback
  drm/komeda: Update writeback signal for side_by_side
  drm/komeda: Expose side_by_side by sysfs/config_id

 .../drm/arm/display/include/malidp_product.h  |   3 +-
 .../arm/display/komeda/d71/d71_component.c|   4 +
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  54 ++--
 .../gpu/drm/arm/display/komeda/komeda_dev.c   |   4 +
 .../gpu/drm/arm/display/komeda/komeda_dev.h   |   9 +
 .../gpu/drm/arm/display/komeda/komeda_kms.h   |   8 +
 .../drm/arm/display/komeda/komeda_pipeline.c  |  50 +++-
 .../drm/arm/display/komeda/komeda_pipeline.h  |  39 ++-
 .../display/komeda/komeda_pipeline_state.c| 277 +-
 .../gpu/drm/arm/display/komeda/komeda_plane.c |   7 +-
 .../arm/display/komeda/komeda_wb_connector.c  |  11 +-
 11 files changed, 421 insertions(+), 45 deletions(-)

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

[PATCH] drm/komeda: Clean warnings: candidate for 'gnu_printf’ format attribute

2019-11-13 Thread james qian wang (Arm Technology China)
komeda/komeda_pipeline.c: In function ‘komeda_component_add’:
komeda/komeda_pipeline.c:213:3: warning: function ‘komeda_component_add’ might 
be a candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
   vsnprintf(c->name, sizeof(c->name), name_fmt, args);
   ^

komeda/komeda_event.c: In function ‘komeda_sprintf’:
komeda/komeda_event.c:31:2: warning: function ‘komeda_sprintf’ might be a 
candidate for ‘gnu_printf’ format attribute [-Wsuggest-attribute=format]
  num = vsnprintf(str->str + str->len, free_sz, fmt, args);

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_event.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
index bf269683f811..977c38d516da 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
@@ -17,6 +17,7 @@ struct komeda_str {
 
 /* return 0 on success,  < 0 on no space.
  */
+__printf(2, 3)
 static int komeda_sprintf(struct komeda_str *str, const char *fmt, ...)
 {
va_list args;
-- 
2.20.1

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

Re: [PATCHv2 3/4] drm/komeda: use afbc helpers

2019-11-13 Thread james qian wang (Arm Technology China)
On Wed, Nov 13, 2019 at 12:39:54PM +0100, Daniel Vetter wrote:
> On Wed, Nov 13, 2019 at 02:01:53AM +0000, james qian wang (Arm Technology 
> China) wrote:
> > On Fri, Nov 08, 2019 at 04:09:54PM +, Ayan Halder wrote:
> > > On Mon, Nov 04, 2019 at 11:12:27PM +0100, Andrzej Pietrasiewicz wrote:
> > > > There are afbc helpers available.
> > > > 
> > > > Signed-off-by: Andrzej Pietrasiewicz 
> > > > ---
> > > >  .../arm/display/komeda/komeda_format_caps.h   |  1 -
> > > >  .../arm/display/komeda/komeda_framebuffer.c   | 44 +++
> > > >  2 files changed, 17 insertions(+), 28 deletions(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
> > > > b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > index 32273cf18f7c..607eea80e60c 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > > > @@ -33,7 +33,6 @@
> > > >  
> > > >  #define AFBC_TH_LAYOUT_ALIGNMENT   8
> > > >  #define AFBC_HEADER_SIZE   16
> > > > -#define AFBC_SUPERBLK_ALIGNMENT128
> > > >  #define AFBC_SUPERBLK_PIXELS   256
> > > >  #define AFBC_BODY_START_ALIGNMENT  1024
> > > >  #define AFBC_TH_BODY_START_ALIGNMENT   4096
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
> > > > b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > index 1b01a625f40e..e9c87551a5b8 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > > > @@ -4,6 +4,7 @@
> > > >   * Author: James.Qian.Wang 
> > > >   *
> > > >   */
> > > > +#include 
> > > >  #include 
> > > >  #include 
> > > >  #include 
> > > > @@ -43,8 +44,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, 
> > > > struct drm_file *file,
> > > > struct drm_framebuffer *fb = >base;
> > > > const struct drm_format_info *info = fb->format;
> > > > struct drm_gem_object *obj;
> > > > -   u32 alignment_w = 0, alignment_h = 0, alignment_header, 
> > > > n_blocks, bpp;
> > > > -   u64 min_size;
> > > > +   u32 alignment_w = 0, alignment_h = 0, alignment_header, bpp;
> > > >  
> > > > obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
> > > > if (!obj) {
> > > > @@ -52,19 +52,15 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, 
> > > > struct drm_file *file,
> > > > return -ENOENT;
> > > > }
> > > >  
> > > > -   switch (fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> > > > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> > > > -   alignment_w = 32;
> > > > -   alignment_h = 8;
> > > > -   break;
> > > > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> > > > -   alignment_w = 16;
> > > > -   alignment_h = 16;
> > > > -   break;
> > > > -   default:
> > > > -   WARN(1, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> > > > -fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> > > > -   break;
> > > > +   if (!drm_afbc_get_superblk_wh(fb->modifier, _w, 
> > > > _h))
> > > > +   return -EINVAL;
> > > > +
> > > > +   if ((alignment_w != 16 || alignment_h != 16) &&
> > > > +   (alignment_w != 32 || alignment_h != 8)) {
> > > > +   DRM_DEBUG_KMS("Unsupported afbc tile w/h [%d/%d]\n",
> > > > + alignment_w, alignment_h);
> > > > +
> > > > +   return -EINVAL;
> > > To be honest, the previous code looks much more readable
> > > > }
> > > >  
> > > > /* tiled header afbc */
> > > > @@ -84,20 +80,14 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, 
> > > > struct drm_file *file,
> > > > goto check_failed;
> > > > }
> > 

Re: [PATCHv2 3/4] drm/komeda: use afbc helpers

2019-11-12 Thread james qian wang (Arm Technology China)
On Fri, Nov 08, 2019 at 04:09:54PM +, Ayan Halder wrote:
> On Mon, Nov 04, 2019 at 11:12:27PM +0100, Andrzej Pietrasiewicz wrote:
> > There are afbc helpers available.
> > 
> > Signed-off-by: Andrzej Pietrasiewicz 
> > ---
> >  .../arm/display/komeda/komeda_format_caps.h   |  1 -
> >  .../arm/display/komeda/komeda_framebuffer.c   | 44 +++
> >  2 files changed, 17 insertions(+), 28 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > index 32273cf18f7c..607eea80e60c 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h
> > @@ -33,7 +33,6 @@
> >  
> >  #define AFBC_TH_LAYOUT_ALIGNMENT   8
> >  #define AFBC_HEADER_SIZE   16
> > -#define AFBC_SUPERBLK_ALIGNMENT128
> >  #define AFBC_SUPERBLK_PIXELS   256
> >  #define AFBC_BODY_START_ALIGNMENT  1024
> >  #define AFBC_TH_BODY_START_ALIGNMENT   4096
> > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c 
> > b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > index 1b01a625f40e..e9c87551a5b8 100644
> > --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c
> > @@ -4,6 +4,7 @@
> >   * Author: James.Qian.Wang 
> >   *
> >   */
> > +#include 
> >  #include 
> >  #include 
> >  #include 
> > @@ -43,8 +44,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct 
> > drm_file *file,
> > struct drm_framebuffer *fb = >base;
> > const struct drm_format_info *info = fb->format;
> > struct drm_gem_object *obj;
> > -   u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp;
> > -   u64 min_size;
> > +   u32 alignment_w = 0, alignment_h = 0, alignment_header, bpp;
> >  
> > obj = drm_gem_object_lookup(file, mode_cmd->handles[0]);
> > if (!obj) {
> > @@ -52,19 +52,15 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct 
> > drm_file *file,
> > return -ENOENT;
> > }
> >  
> > -   switch (fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK) {
> > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_32x8:
> > -   alignment_w = 32;
> > -   alignment_h = 8;
> > -   break;
> > -   case AFBC_FORMAT_MOD_BLOCK_SIZE_16x16:
> > -   alignment_w = 16;
> > -   alignment_h = 16;
> > -   break;
> > -   default:
> > -   WARN(1, "Invalid AFBC_FORMAT_MOD_BLOCK_SIZE: %lld.\n",
> > -fb->modifier & AFBC_FORMAT_MOD_BLOCK_SIZE_MASK);
> > -   break;
> > +   if (!drm_afbc_get_superblk_wh(fb->modifier, _w, _h))
> > +   return -EINVAL;
> > +
> > +   if ((alignment_w != 16 || alignment_h != 16) &&
> > +   (alignment_w != 32 || alignment_h != 8)) {
> > +   DRM_DEBUG_KMS("Unsupported afbc tile w/h [%d/%d]\n",
> > + alignment_w, alignment_h);
> > +
> > +   return -EINVAL;
> To be honest, the previous code looks much more readable
> > }
> >  
> > /* tiled header afbc */
> > @@ -84,20 +80,14 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct 
> > drm_file *file,
> > goto check_failed;
> > }
> >  
> > -   n_blocks = (kfb->aligned_w * kfb->aligned_h) / AFBC_SUPERBLK_PIXELS;
> > -   kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE,
> > -   alignment_header);
> > -
> > bpp = komeda_get_afbc_format_bpp(info, fb->modifier);
> > -   kfb->afbc_size = kfb->offset_payload + n_blocks *
> > -ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8,
> > -  AFBC_SUPERBLK_ALIGNMENT);
> > -   min_size = kfb->afbc_size + fb->offsets[0];
> > -   if (min_size > obj->size) {
> > -   DRM_DEBUG_KMS("afbc size check failed, obj_size: 0x%zx. 
> > min_size 0x%llx.\n",
> > - obj->size, min_size);
> We need kfb->offset_payload and kfb->afbc_size to set some registers
> in d71_layer_update(). At this moment I feel like punching myself for
> making the suggestion to consider abstracting some of the komeda's afbc
> checks. To me it does not look like komeda(in the current shape) can take
> much advantage of the generic _afbc_fb_check() function (as was suggested
> previously by Danvet).
> 
> However, I will let james.qian.w...@arm.com,
> mihail.atanas...@arm.com, ben.da...@arm.com comment here to see if
> there could be a way of abstracting the afbc bits from komeda.
>

Hi all:

Since the current generic drm_afbc helpers only support afbc_1.1, but
komeda needs support both afbc1.1/1.2, so I think we can:
- Add afbc1.2 support to drm afbc helpers.
- for the afbc_payload_offset, can we add this member to
  drm_framebuffer ?
- The aligned_w/h are important for afbc, so can we have them in
  drm_framebuffer ?  

Thanks
James

> Thanks anyways for taking a stab at this.
> -Ayan
> > +
> > +   if 

Re: [PATCH v2 5/5] drm/komeda: add rate limiting disable to err_verbosity

2019-11-12 Thread james qian wang (Arm Technology China)
On Tue, Nov 12, 2019 at 07:24:16PM +0100, Daniel Vetter wrote:
> On Tue, Nov 12, 2019 at 2:00 PM Mihail Atanassov
>  wrote:
> >
> > On Monday, 11 November 2019 15:53:14 GMT Liviu Dudau wrote:
> > > On Thu, Nov 07, 2019 at 11:42:44AM +, Mihail Atanassov wrote:
> > > > It's possible to get multiple events in a single frame/flip, so add an
> > > > option to print them all.
> > > >
> > > > Reviewed-by: James Qian Wang (Arm Technology China) 
> > > > 
> > > > Signed-off-by: Mihail Atanassov 
> > >
> > > For the whole series:
> > >
> > > Acked-by: Liviu Dudau 
> >
> > Thanks, applied to drm-misc-next.
> 
> And now komeda doesn't even compile anymore. I'm ... impressed.
> 
> I mean generally people break other people's driver, not their own.
> -Daniel

Hi Daniel:

Real Real sorry, we will find a way to avoid such stupid problem.

And the fix is: https://patchwork.freedesktop.org/series/69386/

Best regards,
James
> > >
> > > Best regards,
> > > Liviu
> > >
> > > > ---
> > > >
> > > >  v2: Clean up continuation line warning from checkpatch.
> > > >
> > > >  drivers/gpu/drm/arm/display/komeda/komeda_dev.h   | 2 ++
> > > >  drivers/gpu/drm/arm/display/komeda/komeda_event.c | 2 +-
> > > >  2 files changed, 3 insertions(+), 1 deletion(-)
> > > >
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> > > > b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > > > index d9fc9c48859a..15f52e304c08 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> > > > @@ -224,6 +224,8 @@ struct komeda_dev {
> > > >  #define KOMEDA_DEV_PRINT_INFO_EVENTS BIT(2)
> > > > /* Dump DRM state on an error or warning event. */
> > > >  #define KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT BIT(8)
> > > > +   /* Disable rate limiting of event prints (normally one per commit) 
> > > > */
> > > > +#define KOMEDA_DEV_PRINT_DISABLE_RATELIMIT BIT(12)
> > > >  };
> > > >
> > > >  static inline bool
> > > > diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
> > > > b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > > > index 7fd624761a2b..bf269683f811 100644
> > > > --- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > > > +++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> > > > @@ -119,7 +119,7 @@ void komeda_print_events(struct komeda_events 
> > > > *evts, struct drm_device *dev)
> > > > /* reduce the same msg print, only print the first evt for one 
> > > > frame */
> > > > if (evts->global || is_new_frame(evts))
> > > > en_print = true;
> > > > -   if (!en_print)
> > > > +   if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT) && 
> > > > !en_print)
> > > > return;
> > > >
> > > > if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
> > > > --
> > > > 2.23.0
> > > >
> > >
> > > --
> > > 
> > > | I would like to |
> > > | fix the world,  |
> > > | but they're not |
> > > | giving me the   |
> > >  \ source code!  /
> > >   ---
> > > ¯\_(ツ)_/¯
> > >
> >
> >
> > --
> > Mihail
> >
> >
> >
> 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> +41 (0) 79 365 57 48 - http://blog.ffwll.ch
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH] drm/komeda: Fix komeda driver build error

2019-11-12 Thread james qian wang (Arm Technology China)
Fix the build errors lead by

'commit 4039f0293bbd ("drm/komeda: Add option to print WARN- and INFO-level IRQ 
events")'

Signed-off-by: james qian wang (Arm Technology China) 
---
 drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
index 15f52e304c08..d406a4d83352 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
@@ -51,12 +51,12 @@
 
 #define KOMEDA_WARN_EVENTS KOMEDA_ERR_CSCE
 
-#define KOMEDA_INFO_EVENTS ({0 \
+#define KOMEDA_INFO_EVENTS (0 \
| KOMEDA_EVENT_VSYNC \
| KOMEDA_EVENT_FLIP \
| KOMEDA_EVENT_EOW \
| KOMEDA_EVENT_MODE \
-   })
+   )
 
 /* malidp device id */
 enum {
-- 
2.20.1

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

[PATCH v10 4/4] drm/komeda: Adds gamma and color-transform support for DOU-IPS

2019-11-12 Thread james qian wang (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds gamma and color-transform support for DOU-IPS.
Adds two caps members fgamma_coeffs and ctm_coeffs to komeda_improc_state.
If color management changed, set gamma and color-transform accordingly.

v5: Rebase with drm-misc-next

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/d71/d71_component.c| 20 +++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +++
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 4 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index f0ba26e282c3..b6517c46e670 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1044,7 +1044,9 @@ static int d71_merger_init(struct d71_dev *d71,
 static void d71_improc_update(struct komeda_component *c,
  struct komeda_component_state *state)
 {
+   struct drm_crtc_state *crtc_st = state->crtc->state;
struct komeda_improc_state *st = to_improc_st(state);
+   struct d71_pipeline *pipe = to_d71_pipeline(c->pipeline);
u32 __iomem *reg = c->reg;
u32 index, mask = 0, ctrl = 0;
 
@@ -1055,6 +1057,24 @@ static void d71_improc_update(struct komeda_component *c,
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, IPS_DEPTH, st->color_depth);
 
+   if (crtc_st->color_mgmt_changed) {
+   mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
+
+   if (crtc_st->gamma_lut) {
+   malidp_write_group(pipe->dou_ft_coeff_addr, FT_COEFF0,
+  KOMEDA_N_GAMMA_COEFFS,
+  st->fgamma_coeffs);
+   ctrl |= IPS_CTRL_FT; /* enable gamma */
+   }
+
+   if (crtc_st->ctm) {
+   malidp_write_group(reg, IPS_RGB_RGB_COEFF0,
+  KOMEDA_N_CTM_COEFFS,
+  st->ctm_coeffs);
+   ctrl |= IPS_CTRL_RGB; /* enable gamut */
+   }
+   }
+
mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
 
/* config color format */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 252015210fbc..1c452ea75999 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -617,6 +617,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
crtc->port = kcrtc->master->of_output_port;
 
+   drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
+
return err;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bd6ca7c87037..ac8725e24853 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include "malidp_utils.h"
+#include "komeda_color_mgmt.h"
 
 #define KOMEDA_MAX_PIPELINES   2
 #define KOMEDA_PIPELINE_MAX_LAYERS 4
@@ -327,6 +328,8 @@ struct komeda_improc_state {
struct komeda_component_state base;
u8 color_format, color_depth;
u16 hsize, vsize;
+   u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];
+   u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];
 };
 
 /* display timing controller */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 42bdc63dcffa..0930234abb9d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -802,6 +802,12 @@ komeda_improc_validate(struct komeda_improc *improc,
st->color_format = BIT(__ffs(avail_formats));
}
 
+   if (kcrtc_st->base.color_mgmt_changed) {
+   drm_lut_to_fgamma_coeffs(kcrtc_st->base.gamma_lut,
+st->fgamma_coeffs);
+   drm_ctm_to_coeffs(kcrtc_st->base.ctm, st->ctm_coeffs);
+   }
+
komeda_component_add_input(>base, >input, 0);
komeda_component_set_output(>input, >base, 0);
 
-- 
2.20.1

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

[PATCH v10 1/4] drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()

2019-11-12 Thread james qian wang (Arm Technology China)
Add a new helper function drm_color_ctm_s31_32_to_qm_n() for driver to
convert S31.32 sign-magnitude to Qm.n 2's complement that supported by
hardware.

V4: Address Mihai, Daniel and Ilia's review comments.
V5: Includes the sign bit in the value of m (Qm.n).
V6: Allows m = 0 according to Mihail's comments.
V7: Address Mihail's comments.
V8: Use type 'u32' to replace 'uint32_t'
V9: Rebase.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_color_mgmt.c | 34 
 include/drm/drm_color_mgmt.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 4ce5c6d8de99..ba71e3b827f1 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -132,6 +132,40 @@ uint32_t drm_color_lut_extract(uint32_t user_input, 
uint32_t bit_precision)
 }
 EXPORT_SYMBOL(drm_color_lut_extract);
 
+/**
+ * drm_color_ctm_s31_32_to_qm_n
+ *
+ * @user_input: input value
+ * @m: number of integer bits, only support m <= 32, include the sign-bit
+ * @n: number of fractional bits, only support n <= 32
+ *
+ * Convert and clamp S31.32 sign-magnitude to Qm.n (signed 2's complement).
+ * The sign-bit BIT(m+n-1) and above are 0 for positive value and 1 for 
negative
+ * the range of value is [-2^(m-1), 2^(m-1) - 2^-n]
+ *
+ * For example
+ * A Q3.12 format number:
+ * - required bit: 3 + 12 = 15bits
+ * - range: [-2^2, 2^2 - 2^−15]
+ *
+ * NOTE: the m can be zero if all bit_precision are used to present fractional
+ *   bits like Q0.32
+ */
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n)
+{
+   u64 mag = (user_input & ~BIT_ULL(63)) >> (32 - n);
+   bool negative = !!(user_input & BIT_ULL(63));
+   s64 val;
+
+   WARN_ON(m > 32 || n > 32);
+
+   val = clamp_val(mag, 0, negative ?
+   BIT_ULL(n + m - 1) : BIT_ULL(n + m - 1) - 1);
+
+   return negative ? -val : val;
+}
+EXPORT_SYMBOL(drm_color_ctm_s31_32_to_qm_n);
+
 /**
  * drm_crtc_enable_color_mgmt - enable color management properties
  * @crtc: DRM CRTC
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index d1c662d92ab7..997a42ab29f5 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -30,6 +30,7 @@ struct drm_crtc;
 struct drm_plane;
 
 uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n);
 
 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
-- 
2.20.1

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

[PATCH v10 3/4] drm/komeda: Add drm_ctm_to_coeffs()

2019-11-12 Thread james qian wang (Arm Technology China)
This function is for converting drm_color_ctm matrix to komeda hardware
required required Q2.12 2's complement CSC matrix.

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 14 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index c180ce70c26c..d8e449e6ebda 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -117,3 +117,17 @@ void drm_lut_to_fgamma_coeffs(struct drm_property_blob 
*lut_blob, u32 *coeffs)
 {
drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
 }
+
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs)
+{
+   struct drm_color_ctm *ctm;
+   u32 i;
+
+   if (!ctm_blob)
+   return;
+
+   ctm = ctm_blob->data;
+
+   for (i = 0; i < KOMEDA_N_CTM_COEFFS; i++)
+   coeffs[i] = drm_color_ctm_s31_32_to_qm_n(ctm->matrix[i], 3, 12);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index 08ab69281648..2f4668466112 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -18,6 +18,7 @@
 #define KOMEDA_N_CTM_COEFFS9
 
 void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-- 
2.20.1

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

[PATCH v10 2/4] drm/komeda: Add drm_lut_to_fgamma_coeffs()

2019-11-12 Thread james qian wang (Arm Technology China)
This function is used to convert drm color lut to komeda HW required curve
coeffs values.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/komeda_color_mgmt.c| 52 +++
 .../arm/display/komeda/komeda_color_mgmt.h|  9 +++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index 9d14a92dbb17..c180ce70c26c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -65,3 +65,55 @@ const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, 
u32 color_range)
 
return coeffs;
 }
+
+struct gamma_curve_sector {
+   u32 boundary_start;
+   u32 num_of_segments;
+   u32 segment_width;
+};
+
+struct gamma_curve_segment {
+   u32 start;
+   u32 end;
+};
+
+static struct gamma_curve_sector sector_tbl[] = {
+   { 0,4,  4   },
+   { 16,   4,  4   },
+   { 32,   4,  8   },
+   { 64,   4,  16  },
+   { 128,  4,  32  },
+   { 256,  4,  64  },
+   { 512,  16, 32  },
+   { 1024, 24, 128 },
+};
+
+static void
+drm_lut_to_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs,
+ struct gamma_curve_sector *sector_tbl, u32 num_sectors)
+{
+   struct drm_color_lut *lut;
+   u32 i, j, in, num = 0;
+
+   if (!lut_blob)
+   return;
+
+   lut = lut_blob->data;
+
+   for (i = 0; i < num_sectors; i++) {
+   for (j = 0; j < sector_tbl[i].num_of_segments; j++) {
+   in = sector_tbl[i].boundary_start +
+j * sector_tbl[i].segment_width;
+
+   coeffs[num++] = drm_color_lut_extract(lut[in].red,
+   KOMEDA_COLOR_PRECISION);
+   }
+   }
+
+   coeffs[num] = BIT(KOMEDA_COLOR_PRECISION);
+}
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs)
+{
+   drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index a2df218f58e7..08ab69281648 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -11,7 +11,14 @@
 #include 
 
 #define KOMEDA_N_YUV2RGB_COEFFS12
+#define KOMEDA_N_RGB2YUV_COEFFS12
+#define KOMEDA_COLOR_PRECISION 12
+#define KOMEDA_N_GAMMA_COEFFS  65
+#define KOMEDA_COLOR_LUT_SIZE  BIT(KOMEDA_COLOR_PRECISION)
+#define KOMEDA_N_CTM_COEFFS9
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-#endif
+#endif /*_KOMEDA_COLOR_MGMT_H_*/
-- 
2.20.1

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

[PATCH v10 0/4] drm/komeda: Enable CRTC color-mgmt

2019-11-12 Thread james qian wang (Arm Technology China)
This series actually are regrouped from:
- drm/komeda: Enable layer/plane color-mgmt:
  https://patchwork.freedesktop.org/series/60893/

- drm/komeda: Enable CRTC color-mgmt
  https://patchwork.freedesktop.org/series/61370/

For removing the dependence on:
- https://patchwork.freedesktop.org/series/30876/

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm/komeda: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

v4:
  Address review comments from Mihai, Daniel and Ilia.

V5:
- Includes the sign bit in the value of m (Qm.n).
- Rebase with drm-misc-next

v6:
  Allows m == 0 according to Mihail's comments.

v9:
  Rebase

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

 .../arm/display/komeda/d71/d71_component.c| 20 ++
 .../arm/display/komeda/komeda_color_mgmt.c| 66 +++
 .../arm/display/komeda/komeda_color_mgmt.h| 10 ++-
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 drivers/gpu/drm/drm_color_mgmt.c  | 34 ++
 include/drm/drm_color_mgmt.h  |  1 +
 8 files changed, 141 insertions(+), 1 deletion(-)

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

[PATCH v9 2/4] drm/komeda: Add drm_lut_to_fgamma_coeffs()

2019-11-12 Thread james qian wang (Arm Technology China)
This function is used to convert drm color lut to komeda HW required curve
coeffs values.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/komeda_color_mgmt.c| 52 +++
 .../arm/display/komeda/komeda_color_mgmt.h|  9 +++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index 9d14a92dbb17..c180ce70c26c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -65,3 +65,55 @@ const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, 
u32 color_range)
 
return coeffs;
 }
+
+struct gamma_curve_sector {
+   u32 boundary_start;
+   u32 num_of_segments;
+   u32 segment_width;
+};
+
+struct gamma_curve_segment {
+   u32 start;
+   u32 end;
+};
+
+static struct gamma_curve_sector sector_tbl[] = {
+   { 0,4,  4   },
+   { 16,   4,  4   },
+   { 32,   4,  8   },
+   { 64,   4,  16  },
+   { 128,  4,  32  },
+   { 256,  4,  64  },
+   { 512,  16, 32  },
+   { 1024, 24, 128 },
+};
+
+static void
+drm_lut_to_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs,
+ struct gamma_curve_sector *sector_tbl, u32 num_sectors)
+{
+   struct drm_color_lut *lut;
+   u32 i, j, in, num = 0;
+
+   if (!lut_blob)
+   return;
+
+   lut = lut_blob->data;
+
+   for (i = 0; i < num_sectors; i++) {
+   for (j = 0; j < sector_tbl[i].num_of_segments; j++) {
+   in = sector_tbl[i].boundary_start +
+j * sector_tbl[i].segment_width;
+
+   coeffs[num++] = drm_color_lut_extract(lut[in].red,
+   KOMEDA_COLOR_PRECISION);
+   }
+   }
+
+   coeffs[num] = BIT(KOMEDA_COLOR_PRECISION);
+}
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs)
+{
+   drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index a2df218f58e7..08ab69281648 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -11,7 +11,14 @@
 #include 
 
 #define KOMEDA_N_YUV2RGB_COEFFS12
+#define KOMEDA_N_RGB2YUV_COEFFS12
+#define KOMEDA_COLOR_PRECISION 12
+#define KOMEDA_N_GAMMA_COEFFS  65
+#define KOMEDA_COLOR_LUT_SIZE  BIT(KOMEDA_COLOR_PRECISION)
+#define KOMEDA_N_CTM_COEFFS9
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-#endif
+#endif /*_KOMEDA_COLOR_MGMT_H_*/
-- 
2.20.1

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

[PATCH v9 0/4] drm/komeda: Enable CRTC color-mgmt

2019-11-12 Thread james qian wang (Arm Technology China)
This series actually are regrouped from:
- drm/komeda: Enable layer/plane color-mgmt:
  https://patchwork.freedesktop.org/series/60893/

- drm/komeda: Enable CRTC color-mgmt
  https://patchwork.freedesktop.org/series/61370/

For removing the dependence on:
- https://patchwork.freedesktop.org/series/30876/

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm/komeda: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

v4:
  Address review comments from Mihai, Daniel and Ilia.

V5:
- Includes the sign bit in the value of m (Qm.n).
- Rebase with drm-misc-next

v6:
  Allows m == 0 according to Mihail's comments.

v9:
  Rebase

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

 .../arm/display/komeda/d71/d71_component.c| 20 ++
 .../arm/display/komeda/komeda_color_mgmt.c| 66 +++
 .../arm/display/komeda/komeda_color_mgmt.h| 10 ++-
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 drivers/gpu/drm/drm_color_mgmt.c  | 35 ++
 include/drm/drm_color_mgmt.h  |  1 +
 8 files changed, 142 insertions(+), 1 deletion(-)

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

[PATCH v9 4/4] drm/komeda: Adds gamma and color-transform support for DOU-IPS

2019-11-12 Thread james qian wang (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds gamma and color-transform support for DOU-IPS.
Adds two caps members fgamma_coeffs and ctm_coeffs to komeda_improc_state.
If color management changed, set gamma and color-transform accordingly.

v5: Rebase with drm-misc-next

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/d71/d71_component.c| 20 +++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +++
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 4 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index f0ba26e282c3..b6517c46e670 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1044,7 +1044,9 @@ static int d71_merger_init(struct d71_dev *d71,
 static void d71_improc_update(struct komeda_component *c,
  struct komeda_component_state *state)
 {
+   struct drm_crtc_state *crtc_st = state->crtc->state;
struct komeda_improc_state *st = to_improc_st(state);
+   struct d71_pipeline *pipe = to_d71_pipeline(c->pipeline);
u32 __iomem *reg = c->reg;
u32 index, mask = 0, ctrl = 0;
 
@@ -1055,6 +1057,24 @@ static void d71_improc_update(struct komeda_component *c,
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, IPS_DEPTH, st->color_depth);
 
+   if (crtc_st->color_mgmt_changed) {
+   mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
+
+   if (crtc_st->gamma_lut) {
+   malidp_write_group(pipe->dou_ft_coeff_addr, FT_COEFF0,
+  KOMEDA_N_GAMMA_COEFFS,
+  st->fgamma_coeffs);
+   ctrl |= IPS_CTRL_FT; /* enable gamma */
+   }
+
+   if (crtc_st->ctm) {
+   malidp_write_group(reg, IPS_RGB_RGB_COEFF0,
+  KOMEDA_N_CTM_COEFFS,
+  st->ctm_coeffs);
+   ctrl |= IPS_CTRL_RGB; /* enable gamut */
+   }
+   }
+
mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
 
/* config color format */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 252015210fbc..1c452ea75999 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -617,6 +617,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
crtc->port = kcrtc->master->of_output_port;
 
+   drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
+
return err;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bd6ca7c87037..ac8725e24853 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include "malidp_utils.h"
+#include "komeda_color_mgmt.h"
 
 #define KOMEDA_MAX_PIPELINES   2
 #define KOMEDA_PIPELINE_MAX_LAYERS 4
@@ -327,6 +328,8 @@ struct komeda_improc_state {
struct komeda_component_state base;
u8 color_format, color_depth;
u16 hsize, vsize;
+   u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];
+   u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];
 };
 
 /* display timing controller */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 42bdc63dcffa..0930234abb9d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -802,6 +802,12 @@ komeda_improc_validate(struct komeda_improc *improc,
st->color_format = BIT(__ffs(avail_formats));
}
 
+   if (kcrtc_st->base.color_mgmt_changed) {
+   drm_lut_to_fgamma_coeffs(kcrtc_st->base.gamma_lut,
+st->fgamma_coeffs);
+   drm_ctm_to_coeffs(kcrtc_st->base.ctm, st->ctm_coeffs);
+   }
+
komeda_component_add_input(>base, >input, 0);
komeda_component_set_output(>input, >base, 0);
 
-- 
2.20.1

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

[PATCH v9 3/4] drm/komeda: Add drm_ctm_to_coeffs()

2019-11-12 Thread james qian wang (Arm Technology China)
This function is for converting drm_color_ctm matrix to komeda hardware
required required Q2.12 2's complement CSC matrix.

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 14 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index c180ce70c26c..d8e449e6ebda 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -117,3 +117,17 @@ void drm_lut_to_fgamma_coeffs(struct drm_property_blob 
*lut_blob, u32 *coeffs)
 {
drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
 }
+
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs)
+{
+   struct drm_color_ctm *ctm;
+   u32 i;
+
+   if (!ctm_blob)
+   return;
+
+   ctm = ctm_blob->data;
+
+   for (i = 0; i < KOMEDA_N_CTM_COEFFS; i++)
+   coeffs[i] = drm_color_ctm_s31_32_to_qm_n(ctm->matrix[i], 3, 12);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index 08ab69281648..2f4668466112 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -18,6 +18,7 @@
 #define KOMEDA_N_CTM_COEFFS9
 
 void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-- 
2.20.1

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

[PATCH v9 1/4] drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()

2019-11-12 Thread james qian wang (Arm Technology China)
Add a new helper function drm_color_ctm_s31_32_to_qm_n() for driver to
convert S31.32 sign-magnitude to Qm.n 2's complement that supported by
hardware.

V4: Address Mihai, Daniel and Ilia's review comments.
V5: Includes the sign bit in the value of m (Qm.n).
V6: Allows m = 0 according to Mihail's comments.
V7: Address Mihail's comments.
V8: Use type 'u32' to replace 'uint32_t'
v9: Rebase

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_color_mgmt.c | 35 
 include/drm/drm_color_mgmt.h |  1 +
 2 files changed, 36 insertions(+)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 4ce5c6d8de99..9de10abc7a96 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -132,9 +132,44 @@ uint32_t drm_color_lut_extract(uint32_t user_input, 
uint32_t bit_precision)
 }
 EXPORT_SYMBOL(drm_color_lut_extract);

+/**
+ * drm_color_ctm_s31_32_to_qm_n
+ *
+ * @user_input: input value
+ * @m: number of integer bits, only support m <= 32, include the sign-bit
+ * @n: number of fractional bits, only support n <= 32
+ *
+ * Convert and clamp S31.32 sign-magnitude to Qm.n (signed 2's complement).
+ * The sign-bit BIT(m+n-1) and above are 0 for positive value and 1 for 
negative
+ * the range of value is [-2^(m-1), 2^(m-1) - 2^-n]
+ *
+ * For example
+ * A Q3.12 format number:
+ * - required bit: 3 + 12 = 15bits
+ * - range: [-2^2, 2^2 - 2^−15]
+ *
+ * NOTE: the m can be zero if all bit_precision are used to present fractional
+ *   bits like Q0.32
+ */
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n)
+{
+   u64 mag = (user_input & ~BIT_ULL(63)) >> (32 - n);
+   bool negative = !!(user_input & BIT_ULL(63));
+   s64 val;
+
+   WARN_ON(m > 32 || n > 32);
+
+   val = clamp_val(mag, 0, negative ?
+   BIT_ULL(n + m - 1) : BIT_ULL(n + m - 1) - 1);
+
+   return negative ? -val : val;
+}
+EXPORT_SYMBOL(drm_color_ctm_s31_32_to_qm_n);
+
 /**
  * drm_crtc_enable_color_mgmt - enable color management properties
  * @crtc: DRM CRTC
+ *
  * @degamma_lut_size: the size of the degamma lut (before CSC)
  * @has_ctm: whether to attach ctm_property for CSC matrix
  * @gamma_lut_size: the size of the gamma lut (after CSC)
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index d1c662d92ab7..997a42ab29f5 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -30,6 +30,7 @@ struct drm_crtc;
 struct drm_plane;

 uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n);

 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
--
2.20.1
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [5/5] drm/komeda: add rate limiting disable to err_verbosity

2019-11-01 Thread james qian wang (Arm Technology China)
On Mon, Oct 21, 2019 at 04:47:35PM +, Mihail Atanassov wrote:
> It's possible to get multiple events in a single frame/flip, so add an
> option to print them all.
> 
> Signed-off-by: Mihail Atanassov 
Reviewed-by: James Qian Wang (Arm Technology China) 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.h   | 2 ++
>  drivers/gpu/drm/arm/display/komeda/komeda_event.c | 3 ++-
>  2 files changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> index d9fc9c48859a..15f52e304c08 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> @@ -224,6 +224,8 @@ struct komeda_dev {
>  #define KOMEDA_DEV_PRINT_INFO_EVENTS BIT(2)
>   /* Dump DRM state on an error or warning event. */
>  #define KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT BIT(8)
> + /* Disable rate limiting of event prints (normally one per commit) */
> +#define KOMEDA_DEV_PRINT_DISABLE_RATELIMIT BIT(12)
>  };
>  
>  static inline bool
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> index bf88463bb4d9..86e33fed8a91 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> @@ -119,7 +119,8 @@ void komeda_print_events(struct komeda_events *evts, 
> struct drm_device *dev)
>   /* reduce the same msg print, only print the first evt for one frame */
>   if (evts->global || is_new_frame(evts))
>   en_print = true;
> - if (!en_print)
> + if (!(err_verbosity & KOMEDA_DEV_PRINT_DISABLE_RATELIMIT)
> + && !en_print)
>   return;
>  
>   if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [4/5] drm/komeda: Add option to print WARN- and INFO-level IRQ events

2019-11-01 Thread james qian wang (Arm Technology China)
On Mon, Oct 21, 2019 at 04:47:29PM +, Mihail Atanassov wrote:
> Extra detail (normally off) almost never hurts.
> 
> Signed-off-by: Mihail Atanassov 

Reviewed-by: James Qian Wang (Arm Technology China) 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.h   | 11 +++
>  drivers/gpu/drm/arm/display/komeda/komeda_event.c |  4 
>  2 files changed, 15 insertions(+)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> index 4809000c1efb..d9fc9c48859a 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> @@ -51,6 +51,13 @@
>  
>  #define KOMEDA_WARN_EVENTS   KOMEDA_ERR_CSCE
>  
> +#define KOMEDA_INFO_EVENTS ({0 \
> + | KOMEDA_EVENT_VSYNC \
> + | KOMEDA_EVENT_FLIP \
> + | KOMEDA_EVENT_EOW \
> + | KOMEDA_EVENT_MODE \
> + })
> +
>  /* malidp device id */
>  enum {
>   MALI_D71 = 0,
> @@ -211,6 +218,10 @@ struct komeda_dev {
>   u16 err_verbosity;
>   /* Print a single line per error per frame with error events. */
>  #define KOMEDA_DEV_PRINT_ERR_EVENTS BIT(0)
> + /* Print a single line per warning per frame with error events. */
> +#define KOMEDA_DEV_PRINT_WARN_EVENTS BIT(1)
> + /* Print a single line per info event per frame with error events. */
> +#define KOMEDA_DEV_PRINT_INFO_EVENTS BIT(2)
>   /* Dump DRM state on an error or warning event. */
>  #define KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT BIT(8)
>  };
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> index 5da61e7d75d5..bf88463bb4d9 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> @@ -124,6 +124,10 @@ void komeda_print_events(struct komeda_events *evts, 
> struct drm_device *dev)
>  
>   if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
>   print_evts |= KOMEDA_ERR_EVENTS;
> + if (err_verbosity & KOMEDA_DEV_PRINT_WARN_EVENTS)
> + print_evts |= KOMEDA_WARN_EVENTS;
> + if (err_verbosity & KOMEDA_DEV_PRINT_INFO_EVENTS)
> + print_evts |= KOMEDA_INFO_EVENTS;
>  
>   if (evts_mask & print_evts) {
>   char msg[256];
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [2/5] drm/komeda: Remove CONFIG_KOMEDA_ERROR_PRINT

2019-11-01 Thread james qian wang (Arm Technology China)
On Mon, Oct 21, 2019 at 04:47:19PM +, Mihail Atanassov wrote:
> Now that there's a debugfs node to control the same, remove the
> config option.
> 
> Signed-off-by: Mihail Atanassov 
> ---
>  drivers/gpu/drm/arm/display/Kconfig | 6 --
>  drivers/gpu/drm/arm/display/komeda/Makefile | 5 ++---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.h | 6 --
>  3 files changed, 2 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/Kconfig 
> b/drivers/gpu/drm/arm/display/Kconfig
> index e87ff8623076..cec0639e3aa1 100644
> --- a/drivers/gpu/drm/arm/display/Kconfig
> +++ b/drivers/gpu/drm/arm/display/Kconfig
> @@ -12,9 +12,3 @@ config DRM_KOMEDA
> Processor driver. It supports the D71 variants of the hardware.
>  
> If compiled as a module it will be called komeda.
> -
> -config DRM_KOMEDA_ERROR_PRINT
> - bool "Enable komeda error print"
> - depends on DRM_KOMEDA
> - help
> -   Choose this option to enable error printing.
> diff --git a/drivers/gpu/drm/arm/display/komeda/Makefile 
> b/drivers/gpu/drm/arm/display/komeda/Makefile
> index f095a1c68ac7..1931a7fa1a14 100644
> --- a/drivers/gpu/drm/arm/display/komeda/Makefile
> +++ b/drivers/gpu/drm/arm/display/komeda/Makefile
> @@ -16,12 +16,11 @@ komeda-y := \
>   komeda_crtc.o \
>   komeda_plane.o \
>   komeda_wb_connector.o \
> - komeda_private_obj.o
> + komeda_private_obj.o \
> + komeda_event.o
>  
>  komeda-y += \
>   d71/d71_dev.o \
>   d71/d71_component.o
>  
> -komeda-$(CONFIG_DRM_KOMEDA_ERROR_PRINT) += komeda_event.o
> -
>  obj-$(CONFIG_DRM_KOMEDA) += komeda.o
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> index b5bd3d5898ee..831c375180f8 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> @@ -226,13 +226,7 @@ void komeda_dev_destroy(struct komeda_dev *mdev);
>  
>  struct komeda_dev *dev_to_mdev(struct device *dev);
>  
> -#ifdef CONFIG_DRM_KOMEDA_ERROR_PRINT
>  void komeda_print_events(struct komeda_events *evts, struct drm_device *dev);
> -#else
> -static inline void komeda_print_events(struct komeda_events *evts,
> -struct drm_device *dev)
> -{}
> -#endif
>

Reviewed-by: James Qian Wang (Arm Technology China) 
>  int komeda_dev_resume(struct komeda_dev *mdev);
>  int komeda_dev_suspend(struct komeda_dev *mdev);
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [3/5] drm/komeda: Optionally dump DRM state on interrupts

2019-11-01 Thread james qian wang (Arm Technology China)
On Mon, Oct 21, 2019 at 04:47:24PM +, Mihail Atanassov wrote:
> It's potentially useful information when diagnosing error/warn IRQs, so
> dump it to dmesg with a drm_info_printer. Hide this extra debug dumping
> behind another komeda_dev->err_verbosity bit.
> 
> Note that there's not much sense in dumping it for INFO events,
> since the VSYNC event will swamp the log.
> 
> Signed-off-by: Mihail Atanassov 

Reviewed-by: James Qian Wang (Arm Technology China) 
> ---
>  drivers/gpu/drm/arm/display/komeda/komeda_dev.h   | 5 -
>  drivers/gpu/drm/arm/display/komeda/komeda_event.c | 8 +++-
>  2 files changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h 
> b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> index 831c375180f8..4809000c1efb 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.h
> @@ -205,11 +205,14 @@ struct komeda_dev {
>   /**
>* @err_verbosity: bitmask for how much extra info to print on error
>*
> -  * See KOMEDA_DEV_* macros for details.
> +  * See KOMEDA_DEV_* macros for details. Low byte contains the debug
> +  * level categories, the high byte contains extra debug options.
>*/
>   u16 err_verbosity;
>   /* Print a single line per error per frame with error events. */
>  #define KOMEDA_DEV_PRINT_ERR_EVENTS BIT(0)
> + /* Dump DRM state on an error or warning event. */
> +#define KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT BIT(8)
>  };
>  
>  static inline bool
> diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_event.c 
> b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> index 575ed4df74ed..5da61e7d75d5 100644
> --- a/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> +++ b/drivers/gpu/drm/arm/display/komeda/komeda_event.c
> @@ -4,6 +4,7 @@
>   * Author: James.Qian.Wang 
>   *
>   */
> +#include 
>  #include 
>  
>  #include "komeda_dev.h"
> @@ -113,6 +114,7 @@ void komeda_print_events(struct komeda_events *evts, 
> struct drm_device *dev)
>   static bool en_print = true;
>   struct komeda_dev *mdev = dev->dev_private;
>   u16 const err_verbosity = mdev->err_verbosity;
> + u64 evts_mask = evts->global | evts->pipes[0] | evts->pipes[1];
>  
>   /* reduce the same msg print, only print the first evt for one frame */
>   if (evts->global || is_new_frame(evts))
> @@ -123,9 +125,10 @@ void komeda_print_events(struct komeda_events *evts, 
> struct drm_device *dev)
>   if (err_verbosity & KOMEDA_DEV_PRINT_ERR_EVENTS)
>   print_evts |= KOMEDA_ERR_EVENTS;
>  
> - if ((evts->global | evts->pipes[0] | evts->pipes[1]) & print_evts) {
> + if (evts_mask & print_evts) {
>   char msg[256];
>   struct komeda_str str;
> + struct drm_printer p = drm_info_printer(dev->dev);
>  
>   str.str = msg;
>   str.sz  = sizeof(msg);
> @@ -139,6 +142,9 @@ void komeda_print_events(struct komeda_events *evts, 
> struct drm_device *dev)
>   evt_str(, evts->pipes[1]);
>  
>   DRM_ERROR("err detect: %s\n", msg);
> + if ((err_verbosity & KOMEDA_DEV_PRINT_DUMP_STATE_ON_EVENT)
> + && (evts_mask & (KOMEDA_ERR_EVENTS | KOMEDA_WARN_EVENTS)))
> + drm_state_dump(dev, );
>  
>   en_print = false;
>   }
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Re: [1/5] drm/komeda: Add debugfs node to control error verbosity

2019-11-01 Thread james qian wang (Arm Technology China)
_print_events();
> + komeda_print_events(, drm);
>  
>   /* Notify the crtc to handle the events */
>   for (i = 0; i < kms->n_crtcs; i++)

thank you for the patch, looks good to me.

BTW: for you question: 
 | These patches are overall quite tiny, and I was considering just
 | squashing them into one, but I opted to keep them separate for an easier
 | review experience; please let me know whether you prefer a single patch.

I like the current single patch. :)

Reviewed-by: James Qian Wang (Arm Technology China) 
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

[PATCH v8 3/4] drm/komeda: Add drm_ctm_to_coeffs()

2019-11-01 Thread james qian wang (Arm Technology China)
This function is for converting drm_color_ctm matrix to komeda hardware
required required Q2.12 2's complement CSC matrix.

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 14 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index c180ce70c26c..d8e449e6ebda 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -117,3 +117,17 @@ void drm_lut_to_fgamma_coeffs(struct drm_property_blob 
*lut_blob, u32 *coeffs)
 {
drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
 }
+
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs)
+{
+   struct drm_color_ctm *ctm;
+   u32 i;
+
+   if (!ctm_blob)
+   return;
+
+   ctm = ctm_blob->data;
+
+   for (i = 0; i < KOMEDA_N_CTM_COEFFS; i++)
+   coeffs[i] = drm_color_ctm_s31_32_to_qm_n(ctm->matrix[i], 3, 12);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index 08ab69281648..2f4668466112 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -18,6 +18,7 @@
 #define KOMEDA_N_CTM_COEFFS9
 
 void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-- 
2.20.1

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

[PATCH v8 0/4] drm/komeda: Enable CRTC color-mgmt

2019-11-01 Thread james qian wang (Arm Technology China)
This series actually are regrouped from:
- drm/komeda: Enable layer/plane color-mgmt:
  https://patchwork.freedesktop.org/series/60893/

- drm/komeda: Enable CRTC color-mgmt
  https://patchwork.freedesktop.org/series/61370/

For removing the dependence on:
- https://patchwork.freedesktop.org/series/30876/

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm/komeda: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

v4:
  Address review comments from Mihai, Daniel and Ilia.

V5:
- Includes the sign bit in the value of m (Qm.n).
- Rebase with drm-misc-next

v6:
  Allows m == 0 according to Mihail's comments.

Lowry Li (Arm Technology China) (1):
  drm/komeda: Adds gamma and color-transform support for DOU-IPS

james qian wang (Arm Technology China) (3):
  drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()
  drm/komeda: Add drm_lut_to_fgamma_coeffs()
  drm/komeda: Add drm_ctm_to_coeffs()

 .../arm/display/komeda/d71/d71_component.c| 20 ++
 .../arm/display/komeda/komeda_color_mgmt.c| 66 +++
 .../arm/display/komeda/komeda_color_mgmt.h| 10 ++-
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 +
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 drivers/gpu/drm/drm_color_mgmt.c  | 34 ++
 include/drm/drm_color_mgmt.h  |  1 +
 8 files changed, 141 insertions(+), 1 deletion(-)

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

[PATCH v8 1/4] drm: Add a new helper drm_color_ctm_s31_32_to_qm_n()

2019-11-01 Thread james qian wang (Arm Technology China)
Add a new helper function drm_color_ctm_s31_32_to_qm_n() for driver to
convert S31.32 sign-magnitude to Qm.n 2's complement that supported by
hardware.

V4: Address Mihai, Daniel and Ilia's review comments.
V5: Includes the sign bit in the value of m (Qm.n).
V6: Allows m = 0 according to Mihail's comments.
V7: Address Mihail's comments.
V8: Use type 'u32' to replace 'uint32_t'

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
Reviewed-by: Daniel Vetter 
---
 drivers/gpu/drm/drm_color_mgmt.c | 34 
 include/drm/drm_color_mgmt.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/drivers/gpu/drm/drm_color_mgmt.c b/drivers/gpu/drm/drm_color_mgmt.c
index 4ce5c6d8de99..ba71e3b827f1 100644
--- a/drivers/gpu/drm/drm_color_mgmt.c
+++ b/drivers/gpu/drm/drm_color_mgmt.c
@@ -132,6 +132,40 @@ uint32_t drm_color_lut_extract(uint32_t user_input, 
uint32_t bit_precision)
 }
 EXPORT_SYMBOL(drm_color_lut_extract);
 
+/**
+ * drm_color_ctm_s31_32_to_qm_n
+ *
+ * @user_input: input value
+ * @m: number of integer bits, only support m <= 32, include the sign-bit
+ * @n: number of fractional bits, only support n <= 32
+ *
+ * Convert and clamp S31.32 sign-magnitude to Qm.n (signed 2's complement).
+ * The sign-bit BIT(m+n-1) and above are 0 for positive value and 1 for 
negative
+ * the range of value is [-2^(m-1), 2^(m-1) - 2^-n]
+ *
+ * For example
+ * A Q3.12 format number:
+ * - required bit: 3 + 12 = 15bits
+ * - range: [-2^2, 2^2 - 2^−15]
+ *
+ * NOTE: the m can be zero if all bit_precision are used to present fractional
+ *   bits like Q0.32
+ */
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n)
+{
+   u64 mag = (user_input & ~BIT_ULL(63)) >> (32 - n);
+   bool negative = !!(user_input & BIT_ULL(63));
+   s64 val;
+
+   WARN_ON(m > 32 || n > 32);
+
+   val = clamp_val(mag, 0, negative ?
+   BIT_ULL(n + m - 1) : BIT_ULL(n + m - 1) - 1);
+
+   return negative ? -val : val;
+}
+EXPORT_SYMBOL(drm_color_ctm_s31_32_to_qm_n);
+
 /**
  * drm_crtc_enable_color_mgmt - enable color management properties
  * @crtc: DRM CRTC
diff --git a/include/drm/drm_color_mgmt.h b/include/drm/drm_color_mgmt.h
index d1c662d92ab7..997a42ab29f5 100644
--- a/include/drm/drm_color_mgmt.h
+++ b/include/drm/drm_color_mgmt.h
@@ -30,6 +30,7 @@ struct drm_crtc;
 struct drm_plane;
 
 uint32_t drm_color_lut_extract(uint32_t user_input, uint32_t bit_precision);
+u64 drm_color_ctm_s31_32_to_qm_n(u64 user_input, u32 m, u32 n);
 
 void drm_crtc_enable_color_mgmt(struct drm_crtc *crtc,
uint degamma_lut_size,
-- 
2.20.1

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

[PATCH v8 4/4] drm/komeda: Adds gamma and color-transform support for DOU-IPS

2019-11-01 Thread james qian wang (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds gamma and color-transform support for DOU-IPS.
Adds two caps members fgamma_coeffs and ctm_coeffs to komeda_improc_state.
If color management changed, set gamma and color-transform accordingly.

v5: Rebase with drm-misc-next

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/d71/d71_component.c| 20 +++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +++
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 4 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index f0ba26e282c3..b6517c46e670 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1044,7 +1044,9 @@ static int d71_merger_init(struct d71_dev *d71,
 static void d71_improc_update(struct komeda_component *c,
  struct komeda_component_state *state)
 {
+   struct drm_crtc_state *crtc_st = state->crtc->state;
struct komeda_improc_state *st = to_improc_st(state);
+   struct d71_pipeline *pipe = to_d71_pipeline(c->pipeline);
u32 __iomem *reg = c->reg;
u32 index, mask = 0, ctrl = 0;
 
@@ -1055,6 +1057,24 @@ static void d71_improc_update(struct komeda_component *c,
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, IPS_DEPTH, st->color_depth);
 
+   if (crtc_st->color_mgmt_changed) {
+   mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
+
+   if (crtc_st->gamma_lut) {
+   malidp_write_group(pipe->dou_ft_coeff_addr, FT_COEFF0,
+  KOMEDA_N_GAMMA_COEFFS,
+  st->fgamma_coeffs);
+   ctrl |= IPS_CTRL_FT; /* enable gamma */
+   }
+
+   if (crtc_st->ctm) {
+   malidp_write_group(reg, IPS_RGB_RGB_COEFF0,
+  KOMEDA_N_CTM_COEFFS,
+  st->ctm_coeffs);
+   ctrl |= IPS_CTRL_RGB; /* enable gamut */
+   }
+   }
+
mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
 
/* config color format */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 252015210fbc..1c452ea75999 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -617,6 +617,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
crtc->port = kcrtc->master->of_output_port;
 
+   drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
+
return err;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bd6ca7c87037..ac8725e24853 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include "malidp_utils.h"
+#include "komeda_color_mgmt.h"
 
 #define KOMEDA_MAX_PIPELINES   2
 #define KOMEDA_PIPELINE_MAX_LAYERS 4
@@ -327,6 +328,8 @@ struct komeda_improc_state {
struct komeda_component_state base;
u8 color_format, color_depth;
u16 hsize, vsize;
+   u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];
+   u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];
 };
 
 /* display timing controller */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 42bdc63dcffa..0930234abb9d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -802,6 +802,12 @@ komeda_improc_validate(struct komeda_improc *improc,
st->color_format = BIT(__ffs(avail_formats));
}
 
+   if (kcrtc_st->base.color_mgmt_changed) {
+   drm_lut_to_fgamma_coeffs(kcrtc_st->base.gamma_lut,
+st->fgamma_coeffs);
+   drm_ctm_to_coeffs(kcrtc_st->base.ctm, st->ctm_coeffs);
+   }
+
komeda_component_add_input(>base, >input, 0);
komeda_component_set_output(>input, >base, 0);
 
-- 
2.20.1

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

[PATCH v8 2/4] drm/komeda: Add drm_lut_to_fgamma_coeffs()

2019-11-01 Thread james qian wang (Arm Technology China)
This function is used to convert drm color lut to komeda HW required curve
coeffs values.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/komeda_color_mgmt.c| 52 +++
 .../arm/display/komeda/komeda_color_mgmt.h|  9 +++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index 9d14a92dbb17..c180ce70c26c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -65,3 +65,55 @@ const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, 
u32 color_range)
 
return coeffs;
 }
+
+struct gamma_curve_sector {
+   u32 boundary_start;
+   u32 num_of_segments;
+   u32 segment_width;
+};
+
+struct gamma_curve_segment {
+   u32 start;
+   u32 end;
+};
+
+static struct gamma_curve_sector sector_tbl[] = {
+   { 0,4,  4   },
+   { 16,   4,  4   },
+   { 32,   4,  8   },
+   { 64,   4,  16  },
+   { 128,  4,  32  },
+   { 256,  4,  64  },
+   { 512,  16, 32  },
+   { 1024, 24, 128 },
+};
+
+static void
+drm_lut_to_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs,
+ struct gamma_curve_sector *sector_tbl, u32 num_sectors)
+{
+   struct drm_color_lut *lut;
+   u32 i, j, in, num = 0;
+
+   if (!lut_blob)
+   return;
+
+   lut = lut_blob->data;
+
+   for (i = 0; i < num_sectors; i++) {
+   for (j = 0; j < sector_tbl[i].num_of_segments; j++) {
+   in = sector_tbl[i].boundary_start +
+j * sector_tbl[i].segment_width;
+
+   coeffs[num++] = drm_color_lut_extract(lut[in].red,
+   KOMEDA_COLOR_PRECISION);
+   }
+   }
+
+   coeffs[num] = BIT(KOMEDA_COLOR_PRECISION);
+}
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs)
+{
+   drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index a2df218f58e7..08ab69281648 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -11,7 +11,14 @@
 #include 
 
 #define KOMEDA_N_YUV2RGB_COEFFS12
+#define KOMEDA_N_RGB2YUV_COEFFS12
+#define KOMEDA_COLOR_PRECISION 12
+#define KOMEDA_N_GAMMA_COEFFS  65
+#define KOMEDA_COLOR_LUT_SIZE  BIT(KOMEDA_COLOR_PRECISION)
+#define KOMEDA_N_CTM_COEFFS9
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-#endif
+#endif /*_KOMEDA_COLOR_MGMT_H_*/
-- 
2.20.1

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

Re: [RFC,3/3] drm/komeda: Allow non-component drm_bridge only endpoints

2019-10-23 Thread james qian wang (Arm Technology China)
On Tue, Oct 22, 2019 at 10:50:42AM +0200, Daniel Vetter wrote:
> On Tue, Oct 22, 2019 at 10:48 AM Russell King - ARM Linux admin
>  wrote:
> >
> > On Tue, Oct 22, 2019 at 10:42:10AM +0200, Daniel Vetter wrote:
> > > On Thu, Oct 17, 2019 at 12:41:37PM +0100, Russell King - ARM Linux admin 
> > > wrote:
> > > > On Thu, Oct 17, 2019 at 10:48:12AM +, Brian Starkey wrote:
> > > > > On Thu, Oct 17, 2019 at 10:21:03AM +, james qian wang (Arm 
> > > > > Technology China) wrote:
> > > > > > On Thu, Oct 17, 2019 at 08:20:56AM +0000, Brian Starkey wrote:
> > > > > > > On Thu, Oct 17, 2019 at 03:07:59AM +, james qian wang (Arm 
> > > > > > > Technology China) wrote:
> > > > > > > > On Wed, Oct 16, 2019 at 04:22:07PM +, Brian Starkey wrote:
> > > > > > > > >
> > > > > > > > > If James is strongly against merging this, maybe we just swap
> > > > > > > > > wholesale to bridge? But for me, the pragmatic approach would 
> > > > > > > > > be this
> > > > > > > > > stop-gap.
> > > > > > > > >
> > > > > > > >
> > > > > > > > This is a good idea, and I vote +ULONG_MAX :)
> > > > > > > >
> > > > > > > > and I also checked tda998x driver, it supports bridge. so swap 
> > > > > > > > the
> > > > > > > > wholesale to brige is perfect. :)
> > > > > > > >
> > > > > > >
> > > > > > > Well, as Mihail wrote, it's definitely not perfect.
> > > > > > >
> > > > > > > Today, if you rmmod tda998x with the DPU driver still loaded,
> > > > > > > everything will be unbound gracefully.
> > > > > > >
> > > > > > > If we swap to bridge, then rmmod'ing tda998x (or any other bridge
> > > > > > > driver the DPU is using) with the DPU driver still loaded will 
> > > > > > > result
> > > > > > > in a crash.
> > > > > >
> > > > > > I haven't read the bridge code, but seems this is a bug of 
> > > > > > drm_bridge,
> > > > > > since if the bridge is still in using by others, the rmmod should 
> > > > > > fail
> > > > > >
> > > > >
> > > > > Correct, but there's no fix for that today. You can also take a look
> > > > > at the thread linked from Mihail's cover letter.
> > > > >
> > > > > > And personally opinion, if the bridge doesn't handle the dependence.
> > > > > > for us:
> > > > > >
> > > > > > - add such support to bridge
> > > > >
> > > > > That would certainly be helpful. I don't know if there's consensus on
> > > > > how to do that.
> > > > >
> > > > > >   or
> > > > > > - just do the insmod/rmmod in correct order.
> > > > > >
> > > > > > > So, there really are proper benefits to sticking with the 
> > > > > > > component
> > > > > > > code for tda998x, which is why I'd like to understand why you're 
> > > > > > > so
> > > > > > > against this patch?
> > > > > > >
> > > > > >
> > > > > > This change handles two different connectors in komeda internally, 
> > > > > > compare
> > > > > > with one interface, it increases the complexity, more risk of bug 
> > > > > > and more
> > > > > > cost of maintainance.
> > > > > >
> > > > >
> > > > > Well, it's only about how to bind the drivers - two different methods
> > > > > of binding, not two different connectors. I would argue that carrying
> > > > > our out-of-tree patches to support both platforms is a larger
> > > > > maintenance burden.
> > > > >
> > > > > Honestly this looks like a win-win to me. We get the superior approach
> > > > > when its supported, and still get to support bridges which are more
> > > > > common.
> > > > >
> > > > > As/when improvements are made to the bridge code we can remove the
> > > > > 

[PATCH v7 4/4] drm/komeda: Adds gamma and color-transform support for DOU-IPS

2019-10-23 Thread james qian wang (Arm Technology China)
From: "Lowry Li (Arm Technology China)" 

Adds gamma and color-transform support for DOU-IPS.
Adds two caps members fgamma_coeffs and ctm_coeffs to komeda_improc_state.
If color management changed, set gamma and color-transform accordingly.

v5: Rebase with drm-misc-next

Signed-off-by: Lowry Li (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/d71/d71_component.c| 20 +++
 .../gpu/drm/arm/display/komeda/komeda_crtc.c  |  2 ++
 .../drm/arm/display/komeda/komeda_pipeline.h  |  3 +++
 .../display/komeda/komeda_pipeline_state.c|  6 ++
 4 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c 
b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
index f0ba26e282c3..b6517c46e670 100644
--- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
+++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c
@@ -1044,7 +1044,9 @@ static int d71_merger_init(struct d71_dev *d71,
 static void d71_improc_update(struct komeda_component *c,
  struct komeda_component_state *state)
 {
+   struct drm_crtc_state *crtc_st = state->crtc->state;
struct komeda_improc_state *st = to_improc_st(state);
+   struct d71_pipeline *pipe = to_d71_pipeline(c->pipeline);
u32 __iomem *reg = c->reg;
u32 index, mask = 0, ctrl = 0;
 
@@ -1055,6 +1057,24 @@ static void d71_improc_update(struct komeda_component *c,
malidp_write32(reg, BLK_SIZE, HV_SIZE(st->hsize, st->vsize));
malidp_write32(reg, IPS_DEPTH, st->color_depth);
 
+   if (crtc_st->color_mgmt_changed) {
+   mask |= IPS_CTRL_FT | IPS_CTRL_RGB;
+
+   if (crtc_st->gamma_lut) {
+   malidp_write_group(pipe->dou_ft_coeff_addr, FT_COEFF0,
+  KOMEDA_N_GAMMA_COEFFS,
+  st->fgamma_coeffs);
+   ctrl |= IPS_CTRL_FT; /* enable gamma */
+   }
+
+   if (crtc_st->ctm) {
+   malidp_write_group(reg, IPS_RGB_RGB_COEFF0,
+  KOMEDA_N_CTM_COEFFS,
+  st->ctm_coeffs);
+   ctrl |= IPS_CTRL_RGB; /* enable gamut */
+   }
+   }
+
mask |= IPS_CTRL_YUV | IPS_CTRL_CHD422 | IPS_CTRL_CHD420;
 
/* config color format */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
index 252015210fbc..1c452ea75999 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c
@@ -617,6 +617,8 @@ static int komeda_crtc_add(struct komeda_kms_dev *kms,
 
crtc->port = kcrtc->master->of_output_port;
 
+   drm_crtc_enable_color_mgmt(crtc, 0, true, KOMEDA_COLOR_LUT_SIZE);
+
return err;
 }
 
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
index bd6ca7c87037..ac8725e24853 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include "malidp_utils.h"
+#include "komeda_color_mgmt.h"
 
 #define KOMEDA_MAX_PIPELINES   2
 #define KOMEDA_PIPELINE_MAX_LAYERS 4
@@ -327,6 +328,8 @@ struct komeda_improc_state {
struct komeda_component_state base;
u8 color_format, color_depth;
u16 hsize, vsize;
+   u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];
+   u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];
 };
 
 /* display timing controller */
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
index 42bdc63dcffa..0930234abb9d 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c
@@ -802,6 +802,12 @@ komeda_improc_validate(struct komeda_improc *improc,
st->color_format = BIT(__ffs(avail_formats));
}
 
+   if (kcrtc_st->base.color_mgmt_changed) {
+   drm_lut_to_fgamma_coeffs(kcrtc_st->base.gamma_lut,
+st->fgamma_coeffs);
+   drm_ctm_to_coeffs(kcrtc_st->base.ctm, st->ctm_coeffs);
+   }
+
komeda_component_add_input(>base, >input, 0);
komeda_component_set_output(>input, >base, 0);
 
-- 
2.20.1



[PATCH v7 2/4] drm/komeda: Add drm_lut_to_fgamma_coeffs()

2019-10-23 Thread james qian wang (Arm Technology China)
This function is used to convert drm color lut to komeda HW required curve
coeffs values.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../arm/display/komeda/komeda_color_mgmt.c| 52 +++
 .../arm/display/komeda/komeda_color_mgmt.h|  9 +++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index 9d14a92dbb17..c180ce70c26c 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -65,3 +65,55 @@ const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, 
u32 color_range)
 
return coeffs;
 }
+
+struct gamma_curve_sector {
+   u32 boundary_start;
+   u32 num_of_segments;
+   u32 segment_width;
+};
+
+struct gamma_curve_segment {
+   u32 start;
+   u32 end;
+};
+
+static struct gamma_curve_sector sector_tbl[] = {
+   { 0,4,  4   },
+   { 16,   4,  4   },
+   { 32,   4,  8   },
+   { 64,   4,  16  },
+   { 128,  4,  32  },
+   { 256,  4,  64  },
+   { 512,  16, 32  },
+   { 1024, 24, 128 },
+};
+
+static void
+drm_lut_to_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs,
+ struct gamma_curve_sector *sector_tbl, u32 num_sectors)
+{
+   struct drm_color_lut *lut;
+   u32 i, j, in, num = 0;
+
+   if (!lut_blob)
+   return;
+
+   lut = lut_blob->data;
+
+   for (i = 0; i < num_sectors; i++) {
+   for (j = 0; j < sector_tbl[i].num_of_segments; j++) {
+   in = sector_tbl[i].boundary_start +
+j * sector_tbl[i].segment_width;
+
+   coeffs[num++] = drm_color_lut_extract(lut[in].red,
+   KOMEDA_COLOR_PRECISION);
+   }
+   }
+
+   coeffs[num] = BIT(KOMEDA_COLOR_PRECISION);
+}
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs)
+{
+   drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index a2df218f58e7..08ab69281648 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -11,7 +11,14 @@
 #include 
 
 #define KOMEDA_N_YUV2RGB_COEFFS12
+#define KOMEDA_N_RGB2YUV_COEFFS12
+#define KOMEDA_COLOR_PRECISION 12
+#define KOMEDA_N_GAMMA_COEFFS  65
+#define KOMEDA_COLOR_LUT_SIZE  BIT(KOMEDA_COLOR_PRECISION)
+#define KOMEDA_N_CTM_COEFFS9
+
+void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-#endif
+#endif /*_KOMEDA_COLOR_MGMT_H_*/
-- 
2.20.1

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

[PATCH v7 3/4] drm/komeda: Add drm_ctm_to_coeffs()

2019-10-23 Thread james qian wang (Arm Technology China)
This function is for converting drm_color_ctm matrix to komeda hardware
required required Q2.12 2's complement CSC matrix.

v2:
  Move the fixpoint conversion function s31_32_to_q2_12() to drm core
  as a shared helper.

Signed-off-by: james qian wang (Arm Technology China) 
Reviewed-by: Mihail Atanassov 
---
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.c | 14 ++
 .../gpu/drm/arm/display/komeda/komeda_color_mgmt.h |  1 +
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
index c180ce70c26c..d8e449e6ebda 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.c
@@ -117,3 +117,17 @@ void drm_lut_to_fgamma_coeffs(struct drm_property_blob 
*lut_blob, u32 *coeffs)
 {
drm_lut_to_coeffs(lut_blob, coeffs, sector_tbl, ARRAY_SIZE(sector_tbl));
 }
+
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs)
+{
+   struct drm_color_ctm *ctm;
+   u32 i;
+
+   if (!ctm_blob)
+   return;
+
+   ctm = ctm_blob->data;
+
+   for (i = 0; i < KOMEDA_N_CTM_COEFFS; i++)
+   coeffs[i] = drm_color_ctm_s31_32_to_qm_n(ctm->matrix[i], 3, 12);
+}
diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h 
b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
index 08ab69281648..2f4668466112 100644
--- a/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
+++ b/drivers/gpu/drm/arm/display/komeda/komeda_color_mgmt.h
@@ -18,6 +18,7 @@
 #define KOMEDA_N_CTM_COEFFS9
 
 void drm_lut_to_fgamma_coeffs(struct drm_property_blob *lut_blob, u32 *coeffs);
+void drm_ctm_to_coeffs(struct drm_property_blob *ctm_blob, u32 *coeffs);
 
 const s32 *komeda_select_yuv2rgb_coeffs(u32 color_encoding, u32 color_range);
 
-- 
2.20.1

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

  1   2   3   4   5   >