All of lore.kernel.org
 help / color / mirror / Atom feed
From: "james qian wang (Arm Technology China)" <james.qian.wang@arm.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: nd <nd@arm.com>, Ayan Halder <Ayan.Halder@arm.com>,
	"kernel@collabora.com" <kernel@collabora.com>,
	David Airlie <airlied@linux.ie>,
	Liviu Dudau <Liviu.Dudau@arm.com>,
	Andrzej Pietrasiewicz <andrzej.p@collabora.com>,
	"dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	Mihail Atanassov <Mihail.Atanassov@arm.com>,
	Sean Paul <sean@poorly.run>
Subject: Re: [PATCHv3/RFC 1/4] drm/arm: Factor out generic afbc helpers
Date: Thu, 28 Nov 2019 10:47:58 +0000	[thread overview]
Message-ID: <20191128104751.GA3121@jamwan02-TSP300> (raw)
In-Reply-To: <20191125085506.GA29965@phenom.ffwll.local>

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 <andrzej.p@collabora.com>
> > ---
> >  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 000000000000..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 <andrzej.p@collabora.com>
> > + *
> > + */
> > +#include <linux/module.h>
> > +
> > +#include <drm/drm_afbc.h>
> > +#include <drm/drm_device.h>
> > +#include <drm/drm_fourcc.h>
> > +#include <drm/drm_gem.h>
> > +#include <drm/drm_mode.h>
> > +#include <drm/drm_print.h>
> > +
> > +/**
> > + * 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],
> > +				 &afbc->tile_w, &afbc->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 <linux/export.h>
> >  #include <linux/kernel.h>
> >  
> > +#include <drm/drm_afbc.h>
> >  #include <drm/drm_device.h>
> >  #include <drm/drm_fourcc.h>
> >  
> > @@ -322,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..303eea624a02 100644
> > --- a/drivers/gpu/drm/drm_framebuffer.c
> > +++ b/drivers/gpu/drm/drm_framebuffer.c
> > @@ -23,6 +23,7 @@
> >  #include <linux/export.h>
> >  #include <linux/uaccess.h>
> >  
> > +#include <drm/drm_afbc.h>
> >  #include <drm/drm_atomic.h>
> >  #include <drm/drm_atomic_uapi.h>
> >  #include <drm/drm_auth.h>
> > @@ -31,6 +32,7 @@
> >  #include <drm/drm_file.h>
> >  #include <drm/drm_fourcc.h>
> >  #include <drm/drm_framebuffer.h>
> > +#include <drm/drm_gem.h>
> >  #include <drm/drm_print.h>
> >  #include <drm/drm_util.h>
> >  
> > @@ -168,7 +170,69 @@ static int fb_plane_height(int height,
> >  	return DIV_ROUND_UP(height, format->vsub);
> >  }
> >  
> > +static int afbc_check(struct drm_file *file_priv,
> > +		      const struct drm_mode_fb_cmd2 *r, int i,
> > +		      const struct drm_format_info *info)
> > +{
> > +	struct drm_gem_object *obj;
> > +	int bpp = info->cpp[0] * 8;
> > +	int tiles;
> > +	u32 w, h, height, tile_sz, afbc_size;
> > +	int result = 0;
> > +
> > +	if (i) {
> > +		DRM_DEBUG_KMS("AFBC supported only for plane 0\n");
> > +
> > +		return 1;
> > +	}
> > +
> > +	/* get tile w/h */
> > +	if (!drm_afbc_get_superblk_wh(r->modifier[0], &w, &h))
> > +		return 1;
> > +
> > +	/* pitch must be divisible by tile width */
> > +	if (r->pitches[0] % w) {
> > +		DRM_DEBUG_KMS("Invalid pitch for plane %d\n", i);
> > +
> > +		return 1;
> > +	}
> > +
> > +	obj = drm_gem_object_lookup(file_priv, r->handles[0]);
> 
> I think this is a bit ugly ... I'd split this into a new
> framebuffer_check_post() function which is called after fb_create, at that
> point you do have the objects already looked up.
> 
> Also I suggested that this could be done as a helper implementation for
> fb_create, wrapping it around the default gem implementation. That way you
> could keep all the afbc stuff in helpers entirely (but drivers could screw
> things up, so there's a tradeoff).
> 
> What's definitely not ok is calling drm_gem_object_lookup unconditionally
> from core code here. For consistency I think the helper approach would be
> good, since currently the size related checks are done in
> drm_gem_fb_create() - i.e. in the helpers, not in core. Otoh having checks
> split like this is also ugly, so maybe we should have a
> framebuffer_check_post for everyone, and move all the size checks into
> core (not just for afbc).
> -Daniel
> 
> > +	if (!obj) {
> > +		DRM_DEBUG_KMS("Failed to lookup GEM object\n");
> > +
> > +		return 1;
> > +	}
> > +
> > +	/* estimate height based on tile size and height from userspace */
> > +	height = DIV_ROUND_UP(r->height, h) * h;
> > +
> > +	tiles = (r->pitches[0] / w) * (height / h);
> > +	afbc_size = ALIGN(tiles * AFBC_HEADER_SIZE, AFBC_SUPERBLK_ALIGNMENT);
> > +
> > +	tile_sz = (bpp * w * h) / BITS_PER_BYTE;
> > +	afbc_size += tiles * ALIGN(tile_sz, AFBC_SUPERBLK_ALIGNMENT);
> > +
> > +	result = obj->size < afbc_size;
> > +
> > +	drm_gem_object_put_unlocked(obj);
> > +
> > +	return result;
> > +}
> > +
> > +static int modifier_check(struct drm_file *file_priv,
> > +			  const struct drm_mode_fb_cmd2 *r, int i,
> > +			  const struct drm_format_info *info)
> > +{
> > +	/* non-afbc format */
> > +	if (!drm_is_afbc(r->modifier[i]))
> > +		return 0;
> > +
> > +	return afbc_check(file_priv, r, i, info);
> > +}
> > +
> >  static int framebuffer_check(struct drm_device *dev,
> > +			     struct drm_file *file_priv,
> >  			     const struct drm_mode_fb_cmd2 *r)
> >  {
> >  	const struct drm_format_info *info;
> > @@ -204,6 +268,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;
> > @@ -253,6 +320,8 @@ static int framebuffer_check(struct drm_device *dev,
> >  			break;
> >  
> >  		default:
> > +			if (modifier_check(file_priv, r, i, info))
> > +				return -EINVAL;
> >  			break;
> >  		}
> >  	}
> > @@ -317,7 +386,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
> >  		return ERR_PTR(-EINVAL);
> >  	}
> >  
> > -	ret = framebuffer_check(dev, r);
> > +	ret = framebuffer_check(dev, file_priv, r);
> >  	if (ret)
> >  		return ERR_PTR(ret);
> >  
> > diff --git a/include/drm/drm_afbc.h b/include/drm/drm_afbc.h
> > new file mode 100644
> > index 000000000000..fb4d4549f77e
> > --- /dev/null
> > +++ b/include/drm/drm_afbc.h
> > @@ -0,0 +1,35 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +/*
> > + * (C) 2019 Collabora Ltd.
> > + *
> > + * author: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
> > + *
> > + */
> > +#ifndef __DRM_AFBC_H__
> > +#define __DRM_AFBC_H__
> > +
> > +#include <linux/types.h>
> > +
> > +struct drm_device;
> > +struct drm_mode_fb_cmd2;
> > +struct drm_gem_object;
> > +
> > +struct drm_afbc {
> > +	u32 tile_w;
> > +	u32 tile_h;
> > +	u32 width;
> > +	u32 height;
> > +	u32 offset;
> > +};
> > +

Can we put a afbc ptr into drm_framebuffer, as the afbc extension if
the fb is afbc.
Since mostly this drm_afbc is enough for afbc support, but no need to
expose check func to driver, since per design the afbc modifier bits represent
all the requrement, the check is like a sanity check between the modifier and
fb info.

And we can also extend such afbc_info to all modifier which need an
extra check or extra info. like.

struct drm_framebuffer {
    ...
    union {    
        struct drm_afbc *afbc_info;
        void *mod_info; //extra modifier extension.  
    }
    ...
}

and such modifier info can be returned modifier_check()

drm_gem_fb_create_with_funcs()
{
    void *mod_info;

    if (!modifier)
        none_modifier_size_check();
    else if (afbc)
        mod_info = drm_afbc_size_check();
    else if (mode_config->fb_modifier_check())
        // for vendor specific modifier check
        mod_info = mode_config->fb_modifier_check();

    fb = drm_gem_fb_alloc();

    fb->mod_info = mod_info;
}

And in specific driver, you can directly convert the fb->mod_info to
your own modifier info. like current modifier is afbc, then

   struct drm_afbc *afbc_info = fb->mod_info;

Thanks
James
> > +#define AFBC_HEADER_SIZE		16
> > +#define AFBC_SUPERBLK_ALIGNMENT		128
> > +
> > +bool drm_afbc_get_superblk_wh(u64 modifier, u32 *w, u32 *h);
> > +
> > +void drm_afbc_get_parameters(const struct drm_mode_fb_cmd2 *mode_cmd,
> > +			     struct drm_afbc *afbc);
> > +
> > +bool drm_is_afbc(u64 modifier);
> > +
> > +#endif /* __DRM_AFBC_H__ */
> > -- 
> > 2.17.1
> > 
> 
> -- 
> 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

  parent reply	other threads:[~2019-11-28 10:48 UTC|newest]

Thread overview: 63+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-11 11:18 [PATCH 0/2] AFBC for Rockchip Andrzej Pietrasiewicz
2019-10-11 11:18 ` Andrzej Pietrasiewicz
2019-10-11 11:18 ` [PATCH 1/2] drm/arm: Factor out generic afbc helpers Andrzej Pietrasiewicz
2019-10-11 11:18   ` Andrzej Pietrasiewicz
2019-10-21 13:50   ` Ayan Halder
2019-10-21 13:50     ` Ayan Halder
2019-10-21 13:50     ` Ayan Halder
2019-10-21 14:41     ` Mihail Atanassov
2019-10-21 14:41       ` Mihail Atanassov
2019-10-21 14:41       ` Mihail Atanassov
2019-11-04 22:12       ` [PATCHv2 0/4] AFBC support for Rockchip Andrzej Pietrasiewicz
2019-11-04 22:12         ` [PATCHv2 1/4] drm/arm: Factor out generic afbc helpers Andrzej Pietrasiewicz
2019-11-05  9:22           ` Daniel Vetter
2019-11-06 12:45             ` Andrzej Pietrasiewicz
2019-11-07  8:27               ` Daniel Vetter
2019-11-05 23:26           ` Daniel Stone
2019-11-05 23:26             ` Daniel Stone
2019-11-06 10:28             ` Liviu Dudau
2019-11-07 17:20             ` Brian Starkey
2019-11-07 17:20               ` Brian Starkey
2019-11-07 17:32               ` Daniel Vetter
2019-11-07 17:32                 ` Daniel Vetter
2019-11-07 17:49                 ` Brian Starkey
2019-11-07 17:49                   ` Brian Starkey
2019-11-07 19:28                   ` Daniel Vetter
2019-11-07 19:28                     ` Daniel Vetter
2019-11-08  9:46                     ` Brian Starkey
2019-11-08  9:46                       ` Brian Starkey
2019-11-04 22:12         ` [PATCHv2 2/4] drm/malidp: use " Andrzej Pietrasiewicz
2019-11-06 11:09           ` Liviu Dudau
2019-11-04 22:12         ` [PATCHv2 3/4] drm/komeda: " Andrzej Pietrasiewicz
2019-11-08 16:09           ` Ayan Halder
2019-11-08 16:09             ` Ayan Halder
2019-11-13  2:01             ` james qian wang (Arm Technology China)
2019-11-13 11:39               ` Daniel Vetter
2019-11-14  1:52                 ` james qian wang (Arm Technology China)
2019-11-14 10:12                   ` Daniel Vetter
2019-11-18  7:09                     ` james qian wang (Arm Technology China)
2019-11-18  9:51                       ` Daniel Vetter
     [not found]                         ` <20191118095136.GC23790-dv86pmgwkMBes7Z6vYuT8azUEOm+Xw19@public.gmane.org>
2019-11-19  8:34                           ` james qian wang (Arm Technology China)
2019-11-19  8:34                             ` james qian wang (Arm Technology China)
2019-11-21 17:22                             ` [PATCHv3/RFC 0/4] AFBC rework and support for Rockchip Andrzej Pietrasiewicz
2019-11-21 17:22                               ` [PATCHv3/RFC 1/4] drm/arm: Factor out generic afbc helpers Andrzej Pietrasiewicz
2019-11-23  7:13                                 ` Ezequiel Garcia
2019-11-23  7:13                                   ` Ezequiel Garcia
2019-11-24 10:11                                 ` kbuild test robot
2019-11-25  8:55                                 ` Daniel Vetter
2019-11-26 20:27                                   ` Andrzej Pietrasiewicz
2019-11-27  9:51                                     ` Daniel Vetter
2019-11-28 10:47                                   ` james qian wang (Arm Technology China) [this message]
2019-11-21 17:22                               ` [PATCHv3/RFC 2/4] drm/malidp: use " Andrzej Pietrasiewicz
2019-11-21 17:22                               ` [PATCHv3/RFC 3/4] drm/komeda: Use afbc helper Andrzej Pietrasiewicz
2019-11-21 17:22                               ` [PATCHv3/RFC 4/4] drm/rockchip: Add support for afbc Andrzej Pietrasiewicz
2019-11-23  7:21                                 ` Ezequiel Garcia
2019-11-23  7:21                                   ` Ezequiel Garcia
2019-11-04 22:12         ` [PATCHv2 " Andrzej Pietrasiewicz
2019-11-05 23:34           ` Daniel Stone
2019-11-05 23:34             ` Daniel Stone
2019-10-11 11:18 ` [PATCH 2/2] " Andrzej Pietrasiewicz
2019-10-11 11:18   ` Andrzej Pietrasiewicz
2019-10-11 11:59   ` Daniel Stone
2019-10-11 11:59     ` Daniel Stone
2019-10-11 11:59     ` Daniel Stone

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191128104751.GA3121@jamwan02-TSP300 \
    --to=james.qian.wang@arm.com \
    --cc=Ayan.Halder@arm.com \
    --cc=Liviu.Dudau@arm.com \
    --cc=Mihail.Atanassov@arm.com \
    --cc=airlied@linux.ie \
    --cc=andrzej.p@collabora.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kernel@collabora.com \
    --cc=nd@arm.com \
    --cc=sean@poorly.run \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.