drm/rocckhip: implement rockchip_drm_gem_prime_import

1. when import dma-buf we should compare dma_buf->ops with
rockchip_drm_gem_prime_dmabuf_ops;
2. drm_gem_prime_import_dev add some special change for ion alloc
buffer, we must remove them from drm_prime.c for gki.

so we implement rockchip_drm_gem_prime_import to instead of
drm_gem_prime_import.

Change-Id: Iab3260b5c3efb5634d411eb1e8620fb575aa063c
Signed-off-by: Sandy Huang <hjc@rock-chips.com>
This commit is contained in:
Sandy Huang
2020-07-23 16:15:08 +08:00
committed by Tao Huang
parent cc1f5b2bce
commit 1484f3cf59

View File

@@ -136,6 +136,13 @@ int rockchip_drm_get_sub_dev_type(void)
}
EXPORT_SYMBOL(rockchip_drm_get_sub_dev_type);
#ifdef CONFIG_ARCH_ROCKCHIP
struct drm_prime_callback_data {
struct drm_gem_object *obj;
struct sg_table *sgt;
};
#endif
#ifndef MODULE
static struct drm_crtc *find_crtc_by_node(struct drm_device *drm_dev, struct device_node *node)
{
@@ -1685,6 +1692,118 @@ static const struct dma_buf_ops rockchip_drm_gem_prime_dmabuf_ops = {
.end_cpu_access = rockchip_drm_gem_dmabuf_end_cpu_access,
};
#ifdef CONFIG_ARCH_ROCKCHIP
static void drm_gem_prime_dmabuf_release_callback(void *data)
{
struct drm_prime_callback_data *cb_data = data;
if (cb_data && cb_data->obj && cb_data->obj->import_attach) {
struct dma_buf_attachment *attach = cb_data->obj->import_attach;
struct sg_table *sgt = cb_data->sgt;
if (sgt)
dma_buf_unmap_attachment(attach, sgt,
DMA_BIDIRECTIONAL);
dma_buf_detach(attach->dmabuf, attach);
drm_gem_object_put_unlocked(cb_data->obj);
kfree(cb_data);
}
}
#endif
static struct drm_gem_object *rockchip_drm_gem_prime_import_dev(struct drm_device *dev,
struct dma_buf *dma_buf,
struct device *attach_dev)
{
struct dma_buf_attachment *attach;
struct sg_table *sgt;
struct drm_gem_object *obj;
#ifdef CONFIG_ARCH_ROCKCHIP
struct drm_prime_callback_data *cb_data = NULL;
#endif
int ret;
if (dma_buf->ops == &rockchip_drm_gem_prime_dmabuf_ops) {
obj = dma_buf->priv;
if (obj->dev == dev) {
/*
* Importing dmabuf exported from out own gem increases
* refcount on gem itself instead of f_count of dmabuf.
*/
drm_gem_object_get(obj);
return obj;
}
}
#ifdef CONFIG_ARCH_ROCKCHIP
cb_data = dma_buf_get_release_callback_data(dma_buf,
drm_gem_prime_dmabuf_release_callback);
if (cb_data && cb_data->obj && cb_data->obj->dev == dev) {
drm_gem_object_get(cb_data->obj);
return cb_data->obj;
}
#endif
if (!dev->driver->gem_prime_import_sg_table)
return ERR_PTR(-EINVAL);
attach = dma_buf_attach(dma_buf, attach_dev);
if (IS_ERR(attach))
return ERR_CAST(attach);
get_dma_buf(dma_buf);
#ifdef CONFIG_ARCH_ROCKCHIP
cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL);
if (!cb_data) {
ret = -ENOMEM;
goto fail_detach;
}
#endif
sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
if (IS_ERR(sgt)) {
ret = PTR_ERR(sgt);
goto fail_detach;
}
obj = dev->driver->gem_prime_import_sg_table(dev, attach, sgt);
if (IS_ERR(obj)) {
ret = PTR_ERR(obj);
goto fail_unmap;
}
obj->import_attach = attach;
#ifdef CONFIG_ARCH_ROCKCHIP
cb_data->obj = obj;
cb_data->sgt = sgt;
dma_buf_set_release_callback(dma_buf,
drm_gem_prime_dmabuf_release_callback, cb_data);
dma_buf_put(dma_buf);
drm_gem_object_get(obj);
#endif
return obj;
fail_unmap:
dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
fail_detach:
#ifdef CONFIG_ARCH_ROCKCHIP
kfree(cb_data);
#endif
dma_buf_detach(dma_buf, attach);
dma_buf_put(dma_buf);
return ERR_PTR(ret);
}
static struct drm_gem_object *rockchip_drm_gem_prime_import(struct drm_device *dev,
struct dma_buf *dma_buf)
{
return rockchip_drm_gem_prime_import_dev(dev, dma_buf, dev->dev);
}
static struct dma_buf *rockchip_drm_gem_prime_export(struct drm_device *dev,
struct drm_gem_object *obj,
int flags)
@@ -1718,7 +1837,7 @@ static struct drm_driver rockchip_drm_driver = {
.dumb_destroy = drm_gem_dumb_destroy,
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = drm_gem_prime_import,
.gem_prime_import = rockchip_drm_gem_prime_import,
.gem_prime_export = rockchip_drm_gem_prime_export,
.gem_prime_get_sg_table = rockchip_gem_prime_get_sg_table,
.gem_prime_import_sg_table = rockchip_gem_prime_import_sg_table,