On Mon, Nov 13, 2017 at 12:32:28PM +0200, Laurent Pinchart wrote:
> When the DU sources its frames from a VSP, it performs no memory access
> and thus has no requirements on imported dma-buf memory types. In
> particular the DU could import a physically non-contiguous buffer that
> would later be mapped contiguously through the VSP IOMMU.
> 
> This use case isn't supported at the moment as the GEM CMA helpers will
> reject any non-contiguous buffer, and the DU isn't connected to an IOMMU
> that can make the buffer contiguous for DMA. Fix this by implementing a
> custom .gem_prime_import_sg_table() operation that accepts all imported
> dma-buf regardless of the number of scatterlist entries.

This patch raises the question of why use CMA at all if you can accept
any kind of buffers.

> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
> ---
>  drivers/gpu/drm/rcar-du/rcar_du_drv.c |  2 +-
>  drivers/gpu/drm/rcar-du/rcar_du_kms.c | 39 
> +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/rcar-du/rcar_du_kms.h |  7 +++++++
>  3 files changed, 47 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> index 48c166f925a3..d999231f98c7 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
> @@ -289,7 +289,7 @@ static struct drm_driver rcar_du_driver = {
>       .gem_prime_import       = drm_gem_prime_import,
>       .gem_prime_export       = drm_gem_prime_export,
>       .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
> -     .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
> +     .gem_prime_import_sg_table = rcar_du_gem_prime_import_sg_table,
>       .gem_prime_vmap         = drm_gem_cma_prime_vmap,
>       .gem_prime_vunmap       = drm_gem_cma_prime_vunmap,
>       .gem_prime_mmap         = drm_gem_cma_prime_mmap,
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c 
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> index 566d1a948c8f..2dd0c2ba047d 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
> @@ -20,6 +20,7 @@
>  #include <drm/drm_gem_cma_helper.h>
>  #include <drm/drm_gem_framebuffer_helper.h>
>  
> +#include <linux/dma-buf.h>
>  #include <linux/of_graph.h>
>  #include <linux/wait.h>
>  
> @@ -148,6 +149,44 @@ const struct rcar_du_format_info 
> *rcar_du_format_info(u32 fourcc)
>   * Frame buffer
>   */
>  
> +struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device 
> *dev,
> +                             struct dma_buf_attachment *attach,
> +                             struct sg_table *sgt)
> +{
> +     struct rcar_du_device *rcdu = dev->dev_private;
> +     struct drm_gem_cma_object *cma_obj;
> +     struct drm_gem_object *gem_obj;
> +     int ret;
> +
> +     if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE))
> +             return drm_gem_cma_prime_import_sg_table(dev, attach, sgt);
> +
> +     /* Create a CMA GEM buffer. */
> +     cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
> +     if (!cma_obj)
> +             return ERR_PTR(-ENOMEM);
> +     gem_obj = &cma_obj->base;
> +
> +     ret = drm_gem_object_init(dev, gem_obj, attach->dmabuf->size);
> +     if (ret)
> +             goto error;
> +
> +     ret = drm_gem_create_mmap_offset(gem_obj);
> +     if (ret) {
> +             drm_gem_object_release(gem_obj);
> +             goto error;
> +     }
> +
> +     cma_obj->paddr = 0;

This is going to break drm_gem_cma_describe() if you are using it plus
the rcar_du_plane_setup_scanout() unless I'm missing something besides
familiarity with the RCAR driver code :)

This function looks very similar to what I tried to do for mali-dp to
allow the import of contiguous DMA buffers that have more than 1 sgt
entries. In the end I gave up as I kept finding issues and went for the
drm_gem_cma_prime_import_sg_table() changes. Maybe you need to do a
similar change in the function to bypass some requirements if the driver
signals that it can accept relaxed requirements?

Best regards,
Liviu

> +     cma_obj->sgt = sgt;
> +
> +     return gem_obj;
> +
> +error:
> +     kfree(cma_obj);
> +     return ERR_PTR(ret);
> +}
> +
>  int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
>                       struct drm_mode_create_dumb *args)
>  {
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h 
> b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
> index 07951d5fe38b..10b2bb0f0df9 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h
> @@ -16,10 +16,13 @@
>  
>  #include <linux/types.h>
>  
> +struct dma_buf_attachment;
>  struct drm_file;
>  struct drm_device;
> +struct drm_gem_object;
>  struct drm_mode_create_dumb;
>  struct rcar_du_device;
> +struct sg_table;
>  
>  struct rcar_du_format_info {
>       u32 fourcc;
> @@ -36,4 +39,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu);
>  int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
>                       struct drm_mode_create_dumb *args);
>  
> +struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device 
> *dev,
> +                             struct dma_buf_attachment *attach,
> +                             struct sg_table *sgt);
> +
>  #endif /* __RCAR_DU_KMS_H__ */
> -- 
> Regards,
> 
> Laurent Pinchart
> 

-- 
====================
| 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

Reply via email to