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

2020-02-20 Thread Boris Brezillon
On Tue, 17 Dec 2019 15:49:48 +0100
Andrzej Pietrasiewicz  wrote:

> +/**
> + * 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)

Maybe we should rename that one drm_gem_fb_linear_size_check().

> +{
> + 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);
> +
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


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)
Hi Andrzej:
On Tue, Dec 17, 2019 at 03:49:48PM +0100, Andrzej Pietrasiewicz wrote:
> Prepare tools for drivers which need to allocate a struct drm_framebuffer
> (or a container of struct drm_framebuffer) explicitly, before calling
> helpers. In such a case we need new helpers which omit allocating the
> struct drm_framebuffer and this patch provides them. Consequently, they
> are used also inside the helpers themselves.
> 
> The interested drivers will likely need to be able to perform object
> lookups and size checks in separate invocations and this patch provides
> that as well. Helpers themselves are updated, too.
> 
> Signed-off-by: Andrzej Pietrasiewicz 
> ---
>  drivers/gpu/drm/drm_gem_framebuffer_helper.c | 216 ++-
>  include/drm/drm_gem_framebuffer_helper.h |  17 ++
>  2 files changed, 181 insertions(+), 52 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
> b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> index b9bcd310ca2d..b3494f6b66bb 100644
> --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
> @@ -54,6 +54,69 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
> drm_framebuffer *fb,
>  }
>  EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
>  
> +/**
> + * drm_gem_fb_init_with_funcs() - Initialize an already allocated framebuffer
> + * @fb: Framebuffer
> + * @dev: DRM device
> + * @mode_cmd: Metadata from the userspace framebuffer creation request
> + * @obj: GEM objects to be assigned to the framebuffer
> + * @num_planes: number of planes
> + * @funcs: vtable to be used for the framebuffer object
> + *
> + * This variant of the function allows passing a custom vtable.
> + *
> + * Returns:
> + * 0 on success or a negative error code
> + */
> +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 ret, i;
> +
> + drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
> +
> + for (i = 0; i < num_planes; i++)
> + fb->obj[i] = obj[i];
> +
> + ret = drm_framebuffer_init(dev, fb, funcs);
> + if (ret)
> + DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n", 
> ret);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_fb_init_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_init() - Initialize an already allocated framebuffer
> + * @fb: Framebuffer
> + * @dev: DRM device
> + * @mode_cmd: Metadata from the userspace framebuffer creation request
> + * @obj: GEM objects to be assigned to the framebuffer
> + * @num_planes: number of planes
> + *
> + * This variant of the function uses a default vtable.
> + *
> + * Returns:
> + * 0 on success or a negative error code
> + */
> +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)
> +{
> + return drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
> _gem_fb_funcs);
> +}
> +EXPORT_SYMBOL_GPL(drm_gem_fb_init);
> +
>  static struct drm_framebuffer *
>  drm_gem_fb_alloc(struct drm_device *dev,
>const struct drm_mode_fb_cmd2 *mode_cmd,
> @@ -61,21 +124,14 @@ drm_gem_fb_alloc(struct drm_device *dev,
>const struct drm_framebuffer_funcs *funcs)
>  {
>   struct drm_framebuffer *fb;
> - int ret, i;
> + int ret;
>  
>   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++)
> - fb->obj[i] = obj[i];
> -
> - ret = drm_framebuffer_init(dev, fb, funcs);
> + ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
> funcs);
>   if (ret) {
> - DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",
> -   ret);
>   kfree(fb);
>   return ERR_PTR(ret);
>   }
> @@ -144,59 +200,29 @@ 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)
>  {
> - 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);
> -
> -  

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

2019-12-17 Thread Andrzej Pietrasiewicz
Prepare tools for drivers which need to allocate a struct drm_framebuffer
(or a container of struct drm_framebuffer) explicitly, before calling
helpers. In such a case we need new helpers which omit allocating the
struct drm_framebuffer and this patch provides them. Consequently, they
are used also inside the helpers themselves.

The interested drivers will likely need to be able to perform object
lookups and size checks in separate invocations and this patch provides
that as well. Helpers themselves are updated, too.

Signed-off-by: Andrzej Pietrasiewicz 
---
 drivers/gpu/drm/drm_gem_framebuffer_helper.c | 216 ++-
 include/drm/drm_gem_framebuffer_helper.h |  17 ++
 2 files changed, 181 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c 
b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
index b9bcd310ca2d..b3494f6b66bb 100644
--- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c
+++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c
@@ -54,6 +54,69 @@ struct drm_gem_object *drm_gem_fb_get_obj(struct 
drm_framebuffer *fb,
 }
 EXPORT_SYMBOL_GPL(drm_gem_fb_get_obj);
 
+/**
+ * drm_gem_fb_init_with_funcs() - Initialize an already allocated framebuffer
+ * @fb: Framebuffer
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @obj: GEM objects to be assigned to the framebuffer
+ * @num_planes: number of planes
+ * @funcs: vtable to be used for the framebuffer object
+ *
+ * This variant of the function allows passing a custom vtable.
+ *
+ * Returns:
+ * 0 on success or a negative error code
+ */
+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 ret, i;
+
+   drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);
+
+   for (i = 0; i < num_planes; i++)
+   fb->obj[i] = obj[i];
+
+   ret = drm_framebuffer_init(dev, fb, funcs);
+   if (ret)
+   DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n", 
ret);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_init_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_init() - Initialize an already allocated framebuffer
+ * @fb: Framebuffer
+ * @dev: DRM device
+ * @mode_cmd: Metadata from the userspace framebuffer creation request
+ * @obj: GEM objects to be assigned to the framebuffer
+ * @num_planes: number of planes
+ *
+ * This variant of the function uses a default vtable.
+ *
+ * Returns:
+ * 0 on success or a negative error code
+ */
+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)
+{
+   return drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
_gem_fb_funcs);
+}
+EXPORT_SYMBOL_GPL(drm_gem_fb_init);
+
 static struct drm_framebuffer *
 drm_gem_fb_alloc(struct drm_device *dev,
 const struct drm_mode_fb_cmd2 *mode_cmd,
@@ -61,21 +124,14 @@ drm_gem_fb_alloc(struct drm_device *dev,
 const struct drm_framebuffer_funcs *funcs)
 {
struct drm_framebuffer *fb;
-   int ret, i;
+   int ret;
 
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++)
-   fb->obj[i] = obj[i];
-
-   ret = drm_framebuffer_init(dev, fb, funcs);
+   ret = drm_gem_fb_init_with_funcs(fb, dev, mode_cmd, obj, num_planes, 
funcs);
if (ret) {
-   DRM_DEV_ERROR(dev->dev, "Failed to init framebuffer: %d\n",
- ret);
kfree(fb);
return ERR_PTR(ret);
}
@@ -144,59 +200,29 @@ 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)
 {
-   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);
-
-   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;
+   int