Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-25 Thread Daniel Vetter
On Wed, Sep 25, 2019 at 11:35 AM Ayan Halder  wrote:
>
> On Mon, Sep 23, 2019 at 02:20:13PM +0200, Andrzej Pietrasiewicz wrote:
> > From: Ezequiel Garcia 
> >
> > AFBC is a proprietary lossless image compression protocol and format.
> > It helps reduce memory bandwidth of the graphics pipeline operations.
> > This, in turn, improves power efficiency.
> >
> > Signed-off-by: Ezequiel Garcia 
> > [locking improvements]
> > Signed-off-by: Tomeu Vizoso 
> > [squashing the above, commit message and Rockchip AFBC modifier]
> > Signed-off-by: Andrzej Pietrasiewicz 
> > ---
> >  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
> >  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
> >  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
> >  include/uapi/drm/drm_fourcc.h   |  3 +
> >  5 files changed, 151 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > index 64ca87cf6d50..5178939a9c29 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> > @@ -24,6 +24,27 @@ static const struct drm_framebuffer_funcs 
> > rockchip_drm_fb_funcs = {
> >   .dirty = drm_atomic_helper_dirtyfb,
> >  };
> >
> > +static int
> > +rockchip_verify_afbc_mod(struct drm_device *dev,
> > +  const struct drm_mode_fb_cmd2 *mode_cmd)
> > +{
> > + if (mode_cmd->modifier[0] &
> > + ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_ROCKCHIP)) {
> > + DRM_DEV_ERROR(dev->dev,
> > +   "Unsupported format modifier 0x%llx\n",
> > +   mode_cmd->modifier[0]);
> > + return -EINVAL;
> > + }
> > +
> > + if (mode_cmd->width > 2560) {
> > + DRM_DEV_ERROR(dev->dev,
> > +   "Unsupported width %d\n", mode_cmd->width);
> > + return -EINVAL;
> > + }
> > +
> I think you are missing one additional check here.
> framebuffer width and height should be aligned to 16 pixels as you are
> using AFBC_FORMAT_MOD_BLOCK_SIZE_16x16.
> Please have a look at malidp_verify_afbc_framebuffer_caps()

Maybe time to extract that into a helper, so that there's only one
copy of the code that validates a buffer with afbc modifier set?
-Daniel

>
> > + return 0;
> > +}
> > +
> >  static struct drm_framebuffer *
> >  rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 
> > *mode_cmd,
> > struct drm_gem_object **obj, unsigned int num_planes)
> > @@ -32,6 +53,12 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
> > drm_mode_fb_cmd2 *mode_cm
> >   int ret;
> >   int i;
> >
> > + if (mode_cmd->modifier[0]) {
> > + ret = rockchip_verify_afbc_mod(dev, mode_cmd);
> > + if (ret)
> > + return ERR_PTR(ret);
> > + }
> > +
> >   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
> >   if (!fb)
> >   return ERR_PTR(-ENOMEM);
> > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > index 21b68eea46cc..50bf214d21da 100644
> > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> > @@ -46,6 +46,13 @@
> >   vop_reg_set(vop, >phy->scl->ext->name, \
> >   win->base, ~0, v, #name)
> >
> > +#define VOP_AFBC_SET(x, name, v) \
> > + do { \
> > + if (vop->data->afbc) \
> > + vop_reg_set(vop, >data->afbc->name, \
> > + 0, ~0, v, #name); \
> > + } while (0)
> > +
> >  #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
> >   do { \
> >   if (win_yuv2yuv && win_yuv2yuv->name.mask) \
> > @@ -123,6 +130,8 @@ struct vop {
> >   struct drm_device *drm_dev;
> >   bool is_enabled;
> >
> > + struct vop_win *afbc_win;
> > +
> >   struct completion dsp_hold_completion;
> >
> >   /* protected by dev->event_lock */
> > @@ -245,6 +254,30 @@ static bool has_rb_swapped(uint32_t format)
> >   }
> >  }
> >
> > +#define AFBC_FMT_RGB5650x0
> > +#define AFBC_FMT_U8U8U8U8  0x5
> > +#define AFBC_FMT_U8U8U80x4
> > +
> > +static int vop_convert_afbc_format(uint32_t format)
> > +{
> > + switch (format) {
> > + case DRM_FORMAT_XRGB:
> > + case DRM_FORMAT_ARGB:
> > + case DRM_FORMAT_XBGR:
> > + case DRM_FORMAT_ABGR:
> > + return AFBC_FMT_U8U8U8U8;
> > + case DRM_FORMAT_RGB888:
> > + case DRM_FORMAT_BGR888:
> > + return AFBC_FMT_U8U8U8;
> > + case DRM_FORMAT_RGB565:
> > + case DRM_FORMAT_BGR565:
> > + return AFBC_FMT_RGB565;
> > + default:
> > + DRM_ERROR("unsupported afbc format[%08x]\n", format);
> > + return -EINVAL;
> > 

Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-25 Thread Andrzej Pietrasiewicz

Hi Brian,

W dniu 25.09.2019 o 11:39, Brian Starkey pisze:

Hi Andrzej,

Thanks for the patch, it's nice to see another AFBC implementation
coming in.



I did a false start, though. But the work is in progress. Thanks for the review, 
anyway.



For future versions, could you please Cc ayan.hal...@arm.com? It would
have been nice to have someone @arm.com on patches which use/impact
Arm modifiers. Sadly I don't know how to make get_maintainer.pl help


Of course.

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

Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-25 Thread Brian Starkey
Hi Andrzej,

Thanks for the patch, it's nice to see another AFBC implementation
coming in.

For future versions, could you please Cc ayan.hal...@arm.com? It would
have been nice to have someone @arm.com on patches which use/impact
Arm modifiers. Sadly I don't know how to make get_maintainer.pl help
with that.

Some more comments below.

On Mon, Sep 23, 2019 at 02:20:13PM +0200, Andrzej Pietrasiewicz wrote:
> From: Ezequiel Garcia 
> 
> AFBC is a proprietary lossless image compression protocol and format.
> It helps reduce memory bandwidth of the graphics pipeline operations.
> This, in turn, improves power efficiency.
> 
> Signed-off-by: Ezequiel Garcia 
> [locking improvements]
> Signed-off-by: Tomeu Vizoso 
> [squashing the above, commit message and Rockchip AFBC modifier]
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
>  include/uapi/drm/drm_fourcc.h   |  3 +
>  5 files changed, 151 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 64ca87cf6d50..5178939a9c29 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -24,6 +24,27 @@ static const struct drm_framebuffer_funcs 
> rockchip_drm_fb_funcs = {
>   .dirty = drm_atomic_helper_dirtyfb,
>  };
>  
> +static int
> +rockchip_verify_afbc_mod(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> + if (mode_cmd->modifier[0] &
> + ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_ROCKCHIP)) {
> + DRM_DEV_ERROR(dev->dev,
> +   "Unsupported format modifier 0x%llx\n",
> +   mode_cmd->modifier[0]);
> + return -EINVAL;
> + }
> +
> + if (mode_cmd->width > 2560) {
> + DRM_DEV_ERROR(dev->dev,
> +   "Unsupported width %d\n", mode_cmd->width);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
>  static struct drm_framebuffer *
>  rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 
> *mode_cmd,
> struct drm_gem_object **obj, unsigned int num_planes)
> @@ -32,6 +53,12 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
> drm_mode_fb_cmd2 *mode_cm
>   int ret;
>   int i;
>  
> + if (mode_cmd->modifier[0]) {
> + ret = rockchip_verify_afbc_mod(dev, mode_cmd);
> + if (ret)
> + return ERR_PTR(ret);
> + }
> +
>   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
>   if (!fb)
>   return ERR_PTR(-ENOMEM);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 21b68eea46cc..50bf214d21da 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -46,6 +46,13 @@
>   vop_reg_set(vop, >phy->scl->ext->name, \
>   win->base, ~0, v, #name)
>  
> +#define VOP_AFBC_SET(x, name, v) \
> + do { \
> + if (vop->data->afbc) \
> + vop_reg_set(vop, >data->afbc->name, \
> + 0, ~0, v, #name); \
> + } while (0)
> +
>  #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
>   do { \
>   if (win_yuv2yuv && win_yuv2yuv->name.mask) \
> @@ -123,6 +130,8 @@ struct vop {
>   struct drm_device *drm_dev;
>   bool is_enabled;
>  
> + struct vop_win *afbc_win;
> +
>   struct completion dsp_hold_completion;
>  
>   /* protected by dev->event_lock */
> @@ -245,6 +254,30 @@ static bool has_rb_swapped(uint32_t format)
>   }
>  }
>  
> +#define AFBC_FMT_RGB5650x0
> +#define AFBC_FMT_U8U8U8U8  0x5
> +#define AFBC_FMT_U8U8U80x4
> +
> +static int vop_convert_afbc_format(uint32_t format)
> +{

It would be great if you are able to follow the guidance Arm published
here: https://www.kernel.org/doc/html/latest/gpu/afbc.html, which will
help ensure interoperability and compatibility between different
devices/drivers. Hopefully it doesn't limit some use-cases for you -
if it does, let's discuss them.

Specifically, please take a look at the format list there. Some of
your formats below are not on the preferred interop list:

> + switch (format) {
> + case DRM_FORMAT_XRGB:

XRGB: Not preferred, as encoding the X channel is a waste of bits

> + case DRM_FORMAT_ARGB:

ARGB: Not preferred as the channel order prevents YTR

> + case DRM_FORMAT_XBGR:

XBGR: Not preferred, as encoding the X channel is a waste of bits

> + case DRM_FORMAT_ABGR:
> + return AFBC_FMT_U8U8U8U8;
> + 

Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-25 Thread Ayan Halder
On Mon, Sep 23, 2019 at 02:20:13PM +0200, Andrzej Pietrasiewicz wrote:
> From: Ezequiel Garcia 
> 
> AFBC is a proprietary lossless image compression protocol and format.
> It helps reduce memory bandwidth of the graphics pipeline operations.
> This, in turn, improves power efficiency.
> 
> Signed-off-by: Ezequiel Garcia 
> [locking improvements]
> Signed-off-by: Tomeu Vizoso 
> [squashing the above, commit message and Rockchip AFBC modifier]
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
>  include/uapi/drm/drm_fourcc.h   |  3 +
>  5 files changed, 151 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> index 64ca87cf6d50..5178939a9c29 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
> @@ -24,6 +24,27 @@ static const struct drm_framebuffer_funcs 
> rockchip_drm_fb_funcs = {
>   .dirty = drm_atomic_helper_dirtyfb,
>  };
>  
> +static int
> +rockchip_verify_afbc_mod(struct drm_device *dev,
> +  const struct drm_mode_fb_cmd2 *mode_cmd)
> +{
> + if (mode_cmd->modifier[0] &
> + ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_ROCKCHIP)) {
> + DRM_DEV_ERROR(dev->dev,
> +   "Unsupported format modifier 0x%llx\n",
> +   mode_cmd->modifier[0]);
> + return -EINVAL;
> + }
> +
> + if (mode_cmd->width > 2560) {
> + DRM_DEV_ERROR(dev->dev,
> +   "Unsupported width %d\n", mode_cmd->width);
> + return -EINVAL;
> + }
> +
I think you are missing one additional check here.
framebuffer width and height should be aligned to 16 pixels as you are
using AFBC_FORMAT_MOD_BLOCK_SIZE_16x16.
Please have a look at malidp_verify_afbc_framebuffer_caps()

> + return 0;
> +}
> +
>  static struct drm_framebuffer *
>  rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 
> *mode_cmd,
> struct drm_gem_object **obj, unsigned int num_planes)
> @@ -32,6 +53,12 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
> drm_mode_fb_cmd2 *mode_cm
>   int ret;
>   int i;
>  
> + if (mode_cmd->modifier[0]) {
> + ret = rockchip_verify_afbc_mod(dev, mode_cmd);
> + if (ret)
> + return ERR_PTR(ret);
> + }
> +
>   fb = kzalloc(sizeof(*fb), GFP_KERNEL);
>   if (!fb)
>   return ERR_PTR(-ENOMEM);
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
> b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> index 21b68eea46cc..50bf214d21da 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
> @@ -46,6 +46,13 @@
>   vop_reg_set(vop, >phy->scl->ext->name, \
>   win->base, ~0, v, #name)
>  
> +#define VOP_AFBC_SET(x, name, v) \
> + do { \
> + if (vop->data->afbc) \
> + vop_reg_set(vop, >data->afbc->name, \
> + 0, ~0, v, #name); \
> + } while (0)
> +
>  #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
>   do { \
>   if (win_yuv2yuv && win_yuv2yuv->name.mask) \
> @@ -123,6 +130,8 @@ struct vop {
>   struct drm_device *drm_dev;
>   bool is_enabled;
>  
> + struct vop_win *afbc_win;
> +
>   struct completion dsp_hold_completion;
>  
>   /* protected by dev->event_lock */
> @@ -245,6 +254,30 @@ static bool has_rb_swapped(uint32_t format)
>   }
>  }
>  
> +#define AFBC_FMT_RGB5650x0
> +#define AFBC_FMT_U8U8U8U8  0x5
> +#define AFBC_FMT_U8U8U80x4
> +
> +static int vop_convert_afbc_format(uint32_t format)
> +{
> + switch (format) {
> + case DRM_FORMAT_XRGB:
> + case DRM_FORMAT_ARGB:
> + case DRM_FORMAT_XBGR:
> + case DRM_FORMAT_ABGR:
> + return AFBC_FMT_U8U8U8U8;
> + case DRM_FORMAT_RGB888:
> + case DRM_FORMAT_BGR888:
> + return AFBC_FMT_U8U8U8;
> + case DRM_FORMAT_RGB565:
> + case DRM_FORMAT_BGR565:
> + return AFBC_FMT_RGB565;
> + default:
> + DRM_ERROR("unsupported afbc format[%08x]\n", format);
> + return -EINVAL;
> + }
> +}
> +
>  static enum vop_data_format vop_convert_format(uint32_t format)
>  {
>   switch (format) {
> @@ -587,10 +620,16 @@ static int vop_enable(struct drm_crtc *crtc)
>  
>   vop_win_disable(vop, win);
>   }
> - spin_unlock(>reg_lock);
> +
> + if (vop->data->afbc) {
> + VOP_AFBC_SET(vop, enable, 0);
> + vop->afbc_win = NULL;
> + }
>  
>   vop_cfg_done(vop);
>  

Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-25 Thread Ayan Halder
On Mon, Sep 23, 2019 at 05:34:14PM +0200, Andrzej Pietrasiewicz wrote:
> Dear All,
> 
> As a result of my mistake I've sent this patch with an incorrect SOB chain.
> Please kindly disregard this patch.
> 
> @Neil: thank you for your time you spent reviewing it and answering and I'm
> sorry it's to no effect.
> @Ezequiel, @Tomeu: I apologize to you. My mistake.
> 
> Regards,
> 
> Andrzej Pietrasiewicz
> 
> 
> W dniu 23.09.2019 o 15:53, Neil Armstrong pisze:
> >On 23/09/2019 14:20, Andrzej Pietrasiewicz wrote:
> >>From: Ezequiel Garcia 
> >>
> >>AFBC is a proprietary lossless image compression protocol and format.
> >>It helps reduce memory bandwidth of the graphics pipeline operations.
> >>This, in turn, improves power efficiency.
> >>
> >>Signed-off-by: Ezequiel Garcia 
> >>[locking improvements]
> >>Signed-off-by: Tomeu Vizoso 
> >>[squashing the above, commit message and Rockchip AFBC modifier]
> >>Signed-off-by: Andrzej Pietrasiewicz 
> >>---
> >>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
> >>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
> >>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
> >>  include/uapi/drm/drm_fourcc.h   |  3 +
> >>  5 files changed, 151 insertions(+), 3 deletions(-)
> >>
> >
> >[...]
> >
> >>diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> >>index 3feeaa3f987a..ba6caf06c824 100644
> >>--- a/include/uapi/drm/drm_fourcc.h
> >>+++ b/include/uapi/drm/drm_fourcc.h
> >>@@ -742,6 +742,9 @@ extern "C" {
> >>   */
> >>  #define AFBC_FORMAT_MOD_BCH (1ULL << 11)
> >>+#define AFBC_FORMAT_MOD_ROCKCHIP \
> >>+   (AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE)
> >
> >This define looks useless, what's Rockchip specific here ?
> >
Please reuse the existing AFBC modifiers.

Have a look at malidp_format_modifiers[] in which we have defined
the modifiers(for our driver) we are using.

In your case, it will be
DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16|AFBC_FORMAT_MOD_SPARSE)

> >Neil
> >
> >>+
> >>  /*
> >>   * Allwinner tiled modifier
> >>   *
> >>
> >
> 
> ___
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-23 Thread Andrzej Pietrasiewicz

Dear All,

As a result of my mistake I've sent this patch with an incorrect SOB chain. 
Please kindly disregard this patch.


@Neil: thank you for your time you spent reviewing it and answering and I'm 
sorry it's to no effect.

@Ezequiel, @Tomeu: I apologize to you. My mistake.

Regards,

Andrzej Pietrasiewicz


W dniu 23.09.2019 o 15:53, Neil Armstrong pisze:

On 23/09/2019 14:20, Andrzej Pietrasiewicz wrote:

From: Ezequiel Garcia 

AFBC is a proprietary lossless image compression protocol and format.
It helps reduce memory bandwidth of the graphics pipeline operations.
This, in turn, improves power efficiency.

Signed-off-by: Ezequiel Garcia 
[locking improvements]
Signed-off-by: Tomeu Vizoso 
[squashing the above, commit message and Rockchip AFBC modifier]
Signed-off-by: Andrzej Pietrasiewicz 
---
  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
  include/uapi/drm/drm_fourcc.h   |  3 +
  5 files changed, 151 insertions(+), 3 deletions(-)



[...]


diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 3feeaa3f987a..ba6caf06c824 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -742,6 +742,9 @@ extern "C" {
   */
  #define AFBC_FORMAT_MOD_BCH (1ULL << 11)
  
+#define AFBC_FORMAT_MOD_ROCKCHIP \

+   (AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE)


This define looks useless, what's Rockchip specific here ?

Neil


+
  /*
   * Allwinner tiled modifier
   *







Re: [PATCH] drm/rockchip: Add AFBC support

2019-09-23 Thread Neil Armstrong
On 23/09/2019 14:20, Andrzej Pietrasiewicz wrote:
> From: Ezequiel Garcia 
> 
> AFBC is a proprietary lossless image compression protocol and format.
> It helps reduce memory bandwidth of the graphics pipeline operations.
> This, in turn, improves power efficiency.
> 
> Signed-off-by: Ezequiel Garcia 
> [locking improvements]
> Signed-off-by: Tomeu Vizoso 
> [squashing the above, commit message and Rockchip AFBC modifier]
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
>  drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
>  drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
>  include/uapi/drm/drm_fourcc.h   |  3 +
>  5 files changed, 151 insertions(+), 3 deletions(-)
> 

[...]

> diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
> index 3feeaa3f987a..ba6caf06c824 100644
> --- a/include/uapi/drm/drm_fourcc.h
> +++ b/include/uapi/drm/drm_fourcc.h
> @@ -742,6 +742,9 @@ extern "C" {
>   */
>  #define AFBC_FORMAT_MOD_BCH (1ULL << 11)
>  
> +#define AFBC_FORMAT_MOD_ROCKCHIP \
> + (AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 | AFBC_FORMAT_MOD_SPARSE)

This define looks useless, what's Rockchip specific here ?

Neil

> +
>  /*
>   * Allwinner tiled modifier
>   *
> 

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

[PATCH] drm/rockchip: Add AFBC support

2019-09-23 Thread Andrzej Pietrasiewicz
From: Ezequiel Garcia 

AFBC is a proprietary lossless image compression protocol and format.
It helps reduce memory bandwidth of the graphics pipeline operations.
This, in turn, improves power efficiency.

Signed-off-by: Ezequiel Garcia 
[locking improvements]
Signed-off-by: Tomeu Vizoso 
[squashing the above, commit message and Rockchip AFBC modifier]
Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/rockchip/rockchip_drm_fb.c  | 27 ++
 drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 94 -
 drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 12 +++
 drivers/gpu/drm/rockchip/rockchip_vop_reg.c | 18 
 include/uapi/drm/drm_fourcc.h   |  3 +
 5 files changed, 151 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
index 64ca87cf6d50..5178939a9c29 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c
@@ -24,6 +24,27 @@ static const struct drm_framebuffer_funcs 
rockchip_drm_fb_funcs = {
.dirty = drm_atomic_helper_dirtyfb,
 };
 
+static int
+rockchip_verify_afbc_mod(struct drm_device *dev,
+const struct drm_mode_fb_cmd2 *mode_cmd)
+{
+   if (mode_cmd->modifier[0] &
+   ~DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_ROCKCHIP)) {
+   DRM_DEV_ERROR(dev->dev,
+ "Unsupported format modifier 0x%llx\n",
+ mode_cmd->modifier[0]);
+   return -EINVAL;
+   }
+
+   if (mode_cmd->width > 2560) {
+   DRM_DEV_ERROR(dev->dev,
+ "Unsupported width %d\n", mode_cmd->width);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
 static struct drm_framebuffer *
 rockchip_fb_alloc(struct drm_device *dev, const struct drm_mode_fb_cmd2 
*mode_cmd,
  struct drm_gem_object **obj, unsigned int num_planes)
@@ -32,6 +53,12 @@ rockchip_fb_alloc(struct drm_device *dev, const struct 
drm_mode_fb_cmd2 *mode_cm
int ret;
int i;
 
+   if (mode_cmd->modifier[0]) {
+   ret = rockchip_verify_afbc_mod(dev, mode_cmd);
+   if (ret)
+   return ERR_PTR(ret);
+   }
+
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c 
b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 21b68eea46cc..50bf214d21da 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -46,6 +46,13 @@
vop_reg_set(vop, >phy->scl->ext->name, \
win->base, ~0, v, #name)
 
+#define VOP_AFBC_SET(x, name, v) \
+   do { \
+   if (vop->data->afbc) \
+   vop_reg_set(vop, >data->afbc->name, \
+   0, ~0, v, #name); \
+   } while (0)
+
 #define VOP_WIN_YUV2YUV_SET(vop, win_yuv2yuv, name, v) \
do { \
if (win_yuv2yuv && win_yuv2yuv->name.mask) \
@@ -123,6 +130,8 @@ struct vop {
struct drm_device *drm_dev;
bool is_enabled;
 
+   struct vop_win *afbc_win;
+
struct completion dsp_hold_completion;
 
/* protected by dev->event_lock */
@@ -245,6 +254,30 @@ static bool has_rb_swapped(uint32_t format)
}
 }
 
+#define AFBC_FMT_RGB5650x0
+#define AFBC_FMT_U8U8U8U8  0x5
+#define AFBC_FMT_U8U8U80x4
+
+static int vop_convert_afbc_format(uint32_t format)
+{
+   switch (format) {
+   case DRM_FORMAT_XRGB:
+   case DRM_FORMAT_ARGB:
+   case DRM_FORMAT_XBGR:
+   case DRM_FORMAT_ABGR:
+   return AFBC_FMT_U8U8U8U8;
+   case DRM_FORMAT_RGB888:
+   case DRM_FORMAT_BGR888:
+   return AFBC_FMT_U8U8U8;
+   case DRM_FORMAT_RGB565:
+   case DRM_FORMAT_BGR565:
+   return AFBC_FMT_RGB565;
+   default:
+   DRM_ERROR("unsupported afbc format[%08x]\n", format);
+   return -EINVAL;
+   }
+}
+
 static enum vop_data_format vop_convert_format(uint32_t format)
 {
switch (format) {
@@ -587,10 +620,16 @@ static int vop_enable(struct drm_crtc *crtc)
 
vop_win_disable(vop, win);
}
-   spin_unlock(>reg_lock);
+
+   if (vop->data->afbc) {
+   VOP_AFBC_SET(vop, enable, 0);
+   vop->afbc_win = NULL;
+   }
 
vop_cfg_done(vop);
 
+   spin_unlock(>reg_lock);
+
/*
 * At here, vop clock & iommu is enable, R/W vop regs would be safe.
 */
@@ -719,6 +758,32 @@ static int vop_plane_atomic_check(struct drm_plane *plane,
return -EINVAL;
}
 
+   if (fb->modifier & DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_ROCKCHIP)) {
+   struct vop *vop = to_vop(crtc);
+
+   if (!vop->data->afbc) {
+