Message ID | 1354819712-7019-1-git-send-email-aplattner@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Hi, CCing media guys. I agree with you but we should consider one issue released to v4l2. As you may know, V4L2-based driver uses vb2 as buffer manager and the vb2 includes dmabuf feature>(import and export) And v4l2 uses streaming concept>(qbuf and dqbuf) With dmabuf and iommu, generally qbuf imports a fd into its own buffer and maps it with its own iommu table calling dma_buf_map_attachment(). And dqbuf calls dma_buf_unmap_attachment() to unmap that buffer from its own iommu table. But now vb2's unmap_dma_buf callback is nothing to do. I think that the reason is the below issue, If qbuf maps buffer with iomm table and dqbuf unmaps it from iommu table then it has performance deterioration because qbuf and dqbuf are called repeatedly. And this means map/unmap are repeated also. So I think media guys moved dma_unmap_sg call from its own unmap_dma_buf callback to detach callback instead. For this, you can refer to vb2_dc_dmabuf_ops_unmap and vb2_dc_dmabuf_ops_detach function. So I added the below patch to avoid that performance deterioration and am testing it now.(this patch is derived from videobuf2-dma-contig.c) http://git.kernel.org/?p=linux/kernel/git/daeinki/drm-exynos.git;a=commit;h=576b1c3de8b90cf1570b8418b60afd1edaae4e30 Thus, I'm not sure that your common set could cover all the cases including other frameworks. Please give me any opinions. Thanks, Inki Dae 2012/12/7 Aaron Plattner <aplattner@nvidia.com> > Simplify the Exynos prime implementation by using the default behavior > provided > by drm_gem_prime_import and drm_gem_prime_export. > > Signed-off-by: Aaron Plattner <aplattner@nvidia.com> > --- > v2: fix dumb mistakes now that I have a toolchain that can compile-test > this > > drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 156 > ++--------------------------- > drivers/gpu/drm/exynos/exynos_drm_dmabuf.h | 13 ++- > drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 + > 3 files changed, 20 insertions(+), 151 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c > b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c > index 539da9f..71b40f4 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c > @@ -28,8 +28,6 @@ > #include "exynos_drm_drv.h" > #include "exynos_drm_gem.h" > > -#include <linux/dma-buf.h> > - > static struct sg_table *exynos_get_sgt(struct drm_device *drm_dev, > struct exynos_drm_gem_buf *buf) > { > @@ -56,15 +54,12 @@ out: > return NULL; > } > > -static struct sg_table * > - exynos_gem_map_dma_buf(struct dma_buf_attachment *attach, > - enum dma_data_direction dir) > +struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj) > { > - struct exynos_drm_gem_obj *gem_obj = attach->dmabuf->priv; > + struct exynos_drm_gem_obj *gem_obj = to_exynos_gem_obj(obj); > struct drm_device *dev = gem_obj->base.dev; > struct exynos_drm_gem_buf *buf; > struct sg_table *sgt = NULL; > - int nents; > > DRM_DEBUG_PRIME("%s\n", __FILE__); > > @@ -74,120 +69,20 @@ static struct sg_table * > return sgt; > } > > - mutex_lock(&dev->struct_mutex); > - > sgt = exynos_get_sgt(dev, buf); > if (!sgt) > - goto err_unlock; > - > - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir); > - if (!nents) { > - DRM_ERROR("failed to map sgl with iommu.\n"); > - sgt = NULL; > - goto err_unlock; > - } > + goto err; > > DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); > > -err_unlock: > - mutex_unlock(&dev->struct_mutex); > +err: > return sgt; > } > > -static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach, > - struct sg_table *sgt, > - enum dma_data_direction > dir) > -{ > - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); > - > - sg_free_table(sgt); > - kfree(sgt); > - sgt = NULL; > -} > - > -static void exynos_dmabuf_release(struct dma_buf *dmabuf) > +struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev, > + size_t size, > + struct sg_table *sgt) > { > - struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv; > - > - DRM_DEBUG_PRIME("%s\n", __FILE__); > - > - /* > - * exynos_dmabuf_release() call means that file object's > - * f_count is 0 and it calls drm_gem_object_handle_unreference() > - * to drop the references that these values had been increased > - * at drm_prime_handle_to_fd() > - */ > - if (exynos_gem_obj->base.export_dma_buf == dmabuf) { > - exynos_gem_obj->base.export_dma_buf = NULL; > - > - /* > - * drop this gem object refcount to release allocated > buffer > - * and resources. > - */ > - drm_gem_object_unreference_unlocked(&exynos_gem_obj->base); > - } > -} > - > -static void *exynos_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, > - unsigned long page_num) > -{ > - /* TODO */ > - > - return NULL; > -} > - > -static void exynos_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, > - unsigned long page_num, > - void *addr) > -{ > - /* TODO */ > -} > - > -static void *exynos_gem_dmabuf_kmap(struct dma_buf *dma_buf, > - unsigned long page_num) > -{ > - /* TODO */ > - > - return NULL; > -} > - > -static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, > - unsigned long page_num, void *addr) > -{ > - /* TODO */ > -} > - > -static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, > - struct vm_area_struct *vma) > -{ > - return -ENOTTY; > -} > - > -static struct dma_buf_ops exynos_dmabuf_ops = { > - .map_dma_buf = exynos_gem_map_dma_buf, > - .unmap_dma_buf = exynos_gem_unmap_dma_buf, > - .kmap = exynos_gem_dmabuf_kmap, > - .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, > - .kunmap = exynos_gem_dmabuf_kunmap, > - .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, > - .mmap = exynos_gem_dmabuf_mmap, > - .release = exynos_dmabuf_release, > -}; > - > -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, > - struct drm_gem_object *obj, int flags) > -{ > - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); > - > - return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops, > - exynos_gem_obj->base.size, 0600); > -} > - > -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device > *drm_dev, > - struct dma_buf *dma_buf) > -{ > - struct dma_buf_attachment *attach; > - struct sg_table *sgt; > struct scatterlist *sgl; > struct exynos_drm_gem_obj *exynos_gem_obj; > struct exynos_drm_gem_buf *buffer; > @@ -195,39 +90,13 @@ struct drm_gem_object > *exynos_dmabuf_prime_import(struct drm_device *drm_dev, > > DRM_DEBUG_PRIME("%s\n", __FILE__); > > - /* is this one of own objects? */ > - if (dma_buf->ops == &exynos_dmabuf_ops) { > - struct drm_gem_object *obj; > - > - exynos_gem_obj = dma_buf->priv; > - obj = &exynos_gem_obj->base; > - > - /* is it from our device? */ > - if (obj->dev == drm_dev) { > - drm_gem_object_reference(obj); > - return obj; > - } > - } > - > - attach = dma_buf_attach(dma_buf, drm_dev->dev); > - if (IS_ERR(attach)) > - return ERR_PTR(-EINVAL); > - > - > - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); > - if (IS_ERR_OR_NULL(sgt)) { > - ret = PTR_ERR(sgt); > - goto err_buf_detach; > - } > - > buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); > if (!buffer) { > DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); > - ret = -ENOMEM; > - goto err_unmap_attach; > + return ERR_PTR(-ENOMEM); > } > > - exynos_gem_obj = exynos_drm_gem_init(drm_dev, dma_buf->size); > + exynos_gem_obj = exynos_drm_gem_init(dev, size); > if (!exynos_gem_obj) { > ret = -ENOMEM; > goto err_free_buffer; > @@ -235,7 +104,7 @@ struct drm_gem_object > *exynos_dmabuf_prime_import(struct drm_device *drm_dev, > > sgl = sgt->sgl; > > - buffer->size = dma_buf->size; > + buffer->size = size; > buffer->dma_addr = sg_dma_address(sgl); > > if (sgt->nents == 1) { > @@ -253,7 +122,6 @@ struct drm_gem_object > *exynos_dmabuf_prime_import(struct drm_device *drm_dev, > > exynos_gem_obj->buffer = buffer; > buffer->sgt = sgt; > - exynos_gem_obj->base.import_attach = attach; > > DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", > buffer->dma_addr, > > buffer->size); > @@ -263,10 +131,6 @@ struct drm_gem_object > *exynos_dmabuf_prime_import(struct drm_device *drm_dev, > err_free_buffer: > kfree(buffer); > buffer = NULL; > -err_unmap_attach: > - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); > -err_buf_detach: > - dma_buf_detach(dma_buf, attach); > return ERR_PTR(ret); > } > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h > b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h > index 662a8f9..f198183 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h > +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h > @@ -27,13 +27,16 @@ > #define _EXYNOS_DRM_DMABUF_H_ > > #ifdef CONFIG_DRM_EXYNOS_DMABUF > -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, > - struct drm_gem_object *obj, int flags); > - > -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device > *drm_dev, > - struct dma_buf *dma_buf); > +#define exynos_dmabuf_prime_export drm_gem_prime_export > +#define exynos_dmabuf_prime_import drm_gem_prime_import > +struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj); > +struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev, > + size_t size, > + struct sg_table *sg); > #else > #define exynos_dmabuf_prime_export NULL > #define exynos_dmabuf_prime_import NULL > +#define exynos_gem_prime_get_pages NULL > +#define exynos_gem_prime_import_sg NULL > #endif > #endif > diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c > b/drivers/gpu/drm/exynos/exynos_drm_drv.c > index 2b287d2..2a04e97 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c > @@ -283,6 +283,8 @@ static struct drm_driver exynos_drm_driver = { > .prime_fd_to_handle = drm_gem_prime_fd_to_handle, > .gem_prime_export = exynos_dmabuf_prime_export, > .gem_prime_import = exynos_dmabuf_prime_import, > + .gem_prime_get_pages = exynos_gem_prime_get_pages, > + .gem_prime_import_sg = exynos_gem_prime_import_sg, > .ioctls = exynos_ioctls, > .fops = &exynos_drm_driver_fops, > .name = DRIVER_NAME, > -- > 1.8.0.1 > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/dri-devel >
On Fri, Dec 7, 2012 at 7:36 AM, Inki Dae <inki.dae@samsung.com> wrote: > Thus, I'm not sure that your common set could cover all the cases including > other frameworks. Please give me any opinions. I don't think that's required - as long as it is fairly useable by many drivers a helper library is good enough. And since it's no midlayer there's no requirement to use it, you're always free to do your own special sauce in your driver. But I think the current rfc could be made a bit more flexible so that more drivers could use at least parts of it, see my other mail. -Daniel
On 12/06/2012 10:36 PM, Inki Dae wrote: > > Hi, > > CCing media guys. > > I agree with you but we should consider one issue released to v4l2. > > As you may know, V4L2-based driver uses vb2 as buffer manager and the > vb2 includes dmabuf feature>(import and export) And v4l2 uses streaming > concept>(qbuf and dqbuf) > With dmabuf and iommu, generally qbuf imports a fd into its own buffer > and maps it with its own iommu table calling dma_buf_map_attachment(). > And dqbuf calls dma_buf_unmap_attachment() to unmap that buffer from its > own iommu table. > But now vb2's unmap_dma_buf callback is nothing to do. I think that the > reason is the below issue, > > If qbuf maps buffer with iomm table and dqbuf unmaps it from iommu table > then it has performance deterioration because qbuf and dqbuf are called > repeatedly. > And this means map/unmap are repeated also. So I think media guys moved > dma_unmap_sg call from its own unmap_dma_buf callback to detach callback > instead. > For this, you can refer to vb2_dc_dmabuf_ops_unmap and > vb2_dc_dmabuf_ops_detach function. > > So I added the below patch to avoid that performance deterioration and > am testing it now.(this patch is derived from videobuf2-dma-contig.c) > http://git.kernel.org/?p=linux/kernel/git/daeinki/drm-exynos.git;a=commit;h=576b1c3de8b90cf1570b8418b60afd1edaae4e30 > > Thus, I'm not sure that your common set could cover all the cases > including other frameworks. Please give me any opinions. It seems like this adjustment would make perfect sense to add to the helper layer I suggested. E.g., instead of having an exynos_attach structure that caches the sgt, there'd be a struct drm_gem_prime_attach that would do the same thing, and save the sgt it gets from driver->gem_prime_get_sg. Then it would benefit nouveau and radeon, too. Alternatively, patch #4 could be dropped and Exynos can continue to reimplement all of this core functionality, since the helpers are optional, but I don't see anything about this change that should make it Exynos-specific, unless I'm missing something. -- Aaron
2012/12/8 Aaron Plattner <aplattner@nvidia.com> > On 12/06/2012 10:36 PM, Inki Dae wrote: > >> >> Hi, >> >> CCing media guys. >> >> I agree with you but we should consider one issue released to v4l2. >> >> As you may know, V4L2-based driver uses vb2 as buffer manager and the >> vb2 includes dmabuf feature>(import and export) And v4l2 uses streaming >> concept>(qbuf and dqbuf) >> With dmabuf and iommu, generally qbuf imports a fd into its own buffer >> and maps it with its own iommu table calling dma_buf_map_attachment(). >> And dqbuf calls dma_buf_unmap_attachment() to unmap that buffer from its >> own iommu table. >> But now vb2's unmap_dma_buf callback is nothing to do. I think that the >> reason is the below issue, >> >> If qbuf maps buffer with iomm table and dqbuf unmaps it from iommu table >> then it has performance deterioration because qbuf and dqbuf are called >> repeatedly. >> And this means map/unmap are repeated also. So I think media guys moved >> dma_unmap_sg call from its own unmap_dma_buf callback to detach callback >> instead. >> For this, you can refer to vb2_dc_dmabuf_ops_unmap and >> vb2_dc_dmabuf_ops_detach function. >> >> So I added the below patch to avoid that performance deterioration and >> am testing it now.(this patch is derived from videobuf2-dma-contig.c) >> http://git.kernel.org/?p=**linux/kernel/git/daeinki/drm-** >> exynos.git;a=commit;h=**576b1c3de8b90cf1570b8418b60afd**1edaae4e30<http://git.kernel.org/?p=linux/kernel/git/daeinki/drm-exynos.git;a=commit;h=576b1c3de8b90cf1570b8418b60afd1edaae4e30> >> >> Thus, I'm not sure that your common set could cover all the cases >> including other frameworks. Please give me any opinions. >> > > It seems like this adjustment would make perfect sense to add to the > helper layer I suggested. E.g., instead of having an exynos_attach > structure that caches the sgt, there'd be a struct drm_gem_prime_attach > that would do the same thing, and save the sgt it gets from > driver->gem_prime_get_sg. Then it would benefit nouveau and radeon, too. > If this change is applied to common helper and also that could be accepted by other maintainers then I think it's better to use this common helper instead of specific one. > > Alternatively, patch #4 could be dropped and Exynos can continue to > reimplement all of this core functionality, since the helpers are optional, > but I don't see anything about this change that should make it > Exynos-specific, I agree with you. I also think this change isn't specific to Exynos. But you need to check if this is a reasonable change for other drivers also. Thanks, Inki Dae > unless I'm missing something. > > -- > Aaron > > ______________________________**_________________ > dri-devel mailing list > dri-devel@lists.freedesktop.**org <dri-devel@lists.freedesktop.org> > http://lists.freedesktop.org/**mailman/listinfo/dri-devel<http://lists.freedesktop.org/mailman/listinfo/dri-devel> >
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 539da9f..71b40f4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c @@ -28,8 +28,6 @@ #include "exynos_drm_drv.h" #include "exynos_drm_gem.h" -#include <linux/dma-buf.h> - static struct sg_table *exynos_get_sgt(struct drm_device *drm_dev, struct exynos_drm_gem_buf *buf) { @@ -56,15 +54,12 @@ out: return NULL; } -static struct sg_table * - exynos_gem_map_dma_buf(struct dma_buf_attachment *attach, - enum dma_data_direction dir) +struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj) { - struct exynos_drm_gem_obj *gem_obj = attach->dmabuf->priv; + struct exynos_drm_gem_obj *gem_obj = to_exynos_gem_obj(obj); struct drm_device *dev = gem_obj->base.dev; struct exynos_drm_gem_buf *buf; struct sg_table *sgt = NULL; - int nents; DRM_DEBUG_PRIME("%s\n", __FILE__); @@ -74,120 +69,20 @@ static struct sg_table * return sgt; } - mutex_lock(&dev->struct_mutex); - sgt = exynos_get_sgt(dev, buf); if (!sgt) - goto err_unlock; - - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir); - if (!nents) { - DRM_ERROR("failed to map sgl with iommu.\n"); - sgt = NULL; - goto err_unlock; - } + goto err; DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); -err_unlock: - mutex_unlock(&dev->struct_mutex); +err: return sgt; } -static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *sgt, - enum dma_data_direction dir) -{ - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir); - - sg_free_table(sgt); - kfree(sgt); - sgt = NULL; -} - -static void exynos_dmabuf_release(struct dma_buf *dmabuf) +struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev, + size_t size, + struct sg_table *sgt) { - struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv; - - DRM_DEBUG_PRIME("%s\n", __FILE__); - - /* - * exynos_dmabuf_release() call means that file object's - * f_count is 0 and it calls drm_gem_object_handle_unreference() - * to drop the references that these values had been increased - * at drm_prime_handle_to_fd() - */ - if (exynos_gem_obj->base.export_dma_buf == dmabuf) { - exynos_gem_obj->base.export_dma_buf = NULL; - - /* - * drop this gem object refcount to release allocated buffer - * and resources. - */ - drm_gem_object_unreference_unlocked(&exynos_gem_obj->base); - } -} - -static void *exynos_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num) -{ - /* TODO */ - - return NULL; -} - -static void exynos_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf, - unsigned long page_num, - void *addr) -{ - /* TODO */ -} - -static void *exynos_gem_dmabuf_kmap(struct dma_buf *dma_buf, - unsigned long page_num) -{ - /* TODO */ - - return NULL; -} - -static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, - unsigned long page_num, void *addr) -{ - /* TODO */ -} - -static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, - struct vm_area_struct *vma) -{ - return -ENOTTY; -} - -static struct dma_buf_ops exynos_dmabuf_ops = { - .map_dma_buf = exynos_gem_map_dma_buf, - .unmap_dma_buf = exynos_gem_unmap_dma_buf, - .kmap = exynos_gem_dmabuf_kmap, - .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, - .kunmap = exynos_gem_dmabuf_kunmap, - .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, - .mmap = exynos_gem_dmabuf_mmap, - .release = exynos_dmabuf_release, -}; - -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, - struct drm_gem_object *obj, int flags) -{ - struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); - - return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops, - exynos_gem_obj->base.size, 0600); -} - -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, - struct dma_buf *dma_buf) -{ - struct dma_buf_attachment *attach; - struct sg_table *sgt; struct scatterlist *sgl; struct exynos_drm_gem_obj *exynos_gem_obj; struct exynos_drm_gem_buf *buffer; @@ -195,39 +90,13 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, DRM_DEBUG_PRIME("%s\n", __FILE__); - /* is this one of own objects? */ - if (dma_buf->ops == &exynos_dmabuf_ops) { - struct drm_gem_object *obj; - - exynos_gem_obj = dma_buf->priv; - obj = &exynos_gem_obj->base; - - /* is it from our device? */ - if (obj->dev == drm_dev) { - drm_gem_object_reference(obj); - return obj; - } - } - - attach = dma_buf_attach(dma_buf, drm_dev->dev); - if (IS_ERR(attach)) - return ERR_PTR(-EINVAL); - - - sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); - if (IS_ERR_OR_NULL(sgt)) { - ret = PTR_ERR(sgt); - goto err_buf_detach; - } - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); if (!buffer) { DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n"); - ret = -ENOMEM; - goto err_unmap_attach; + return ERR_PTR(-ENOMEM); } - exynos_gem_obj = exynos_drm_gem_init(drm_dev, dma_buf->size); + exynos_gem_obj = exynos_drm_gem_init(dev, size); if (!exynos_gem_obj) { ret = -ENOMEM; goto err_free_buffer; @@ -235,7 +104,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, sgl = sgt->sgl; - buffer->size = dma_buf->size; + buffer->size = size; buffer->dma_addr = sg_dma_address(sgl); if (sgt->nents == 1) { @@ -253,7 +122,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, exynos_gem_obj->buffer = buffer; buffer->sgt = sgt; - exynos_gem_obj->base.import_attach = attach; DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", buffer->dma_addr, buffer->size); @@ -263,10 +131,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, err_free_buffer: kfree(buffer); buffer = NULL; -err_unmap_attach: - dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); -err_buf_detach: - dma_buf_detach(dma_buf, attach); return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h index 662a8f9..f198183 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h @@ -27,13 +27,16 @@ #define _EXYNOS_DRM_DMABUF_H_ #ifdef CONFIG_DRM_EXYNOS_DMABUF -struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev, - struct drm_gem_object *obj, int flags); - -struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, - struct dma_buf *dma_buf); +#define exynos_dmabuf_prime_export drm_gem_prime_export +#define exynos_dmabuf_prime_import drm_gem_prime_import +struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj); +struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev, + size_t size, + struct sg_table *sg); #else #define exynos_dmabuf_prime_export NULL #define exynos_dmabuf_prime_import NULL +#define exynos_gem_prime_get_pages NULL +#define exynos_gem_prime_import_sg NULL #endif #endif diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 2b287d2..2a04e97 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -283,6 +283,8 @@ static struct drm_driver exynos_drm_driver = { .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = exynos_dmabuf_prime_export, .gem_prime_import = exynos_dmabuf_prime_import, + .gem_prime_get_pages = exynos_gem_prime_get_pages, + .gem_prime_import_sg = exynos_gem_prime_import_sg, .ioctls = exynos_ioctls, .fops = &exynos_drm_driver_fops, .name = DRIVER_NAME,
Simplify the Exynos prime implementation by using the default behavior provided by drm_gem_prime_import and drm_gem_prime_export. Signed-off-by: Aaron Plattner <aplattner@nvidia.com> --- v2: fix dumb mistakes now that I have a toolchain that can compile-test this drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 156 ++--------------------------- drivers/gpu/drm/exynos/exynos_drm_dmabuf.h | 13 ++- drivers/gpu/drm/exynos/exynos_drm_drv.c | 2 + 3 files changed, 20 insertions(+), 151 deletions(-)