drm/exynos: gem: Simplify access to exynos GEM objects

Replace all calls to exynos_drm_gem_get_{dma_addr,size}, by a simpler
function exynos_drm_gem_get(). This lets the caller to get access to
exynos_drm_gem object and extract any information about GEM object
without searching object tree for getting each parameter.

Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
Marek Szyprowski 2018-07-09 15:44:31 +02:00 committed by Inki Dae
parent eb4d9796fa
commit 3aa2a5c140
3 changed files with 35 additions and 96 deletions

View file

@ -191,7 +191,7 @@ struct g2d_buf_desc {
struct g2d_buf_info { struct g2d_buf_info {
unsigned int map_nr; unsigned int map_nr;
enum g2d_reg_type reg_types[MAX_REG_TYPE_NR]; enum g2d_reg_type reg_types[MAX_REG_TYPE_NR];
unsigned long handles[MAX_REG_TYPE_NR]; void *obj[MAX_REG_TYPE_NR];
unsigned int types[MAX_REG_TYPE_NR]; unsigned int types[MAX_REG_TYPE_NR];
struct g2d_buf_desc descs[MAX_REG_TYPE_NR]; struct g2d_buf_desc descs[MAX_REG_TYPE_NR];
}; };
@ -374,11 +374,10 @@ static void g2d_add_cmdlist_to_inuse(struct drm_exynos_file_private *file_priv,
} }
static void g2d_userptr_put_dma_addr(struct g2d_data *g2d, static void g2d_userptr_put_dma_addr(struct g2d_data *g2d,
unsigned long obj, void *obj,
bool force) bool force)
{ {
struct g2d_cmdlist_userptr *g2d_userptr = struct g2d_cmdlist_userptr *g2d_userptr = obj;
(struct g2d_cmdlist_userptr *)obj;
struct page **pages; struct page **pages;
if (!obj) if (!obj)
@ -421,7 +420,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
unsigned long userptr, unsigned long userptr,
unsigned long size, unsigned long size,
struct drm_file *filp, struct drm_file *filp,
unsigned long *obj) void **obj)
{ {
struct drm_exynos_file_private *file_priv = filp->driver_priv; struct drm_exynos_file_private *file_priv = filp->driver_priv;
struct g2d_cmdlist_userptr *g2d_userptr; struct g2d_cmdlist_userptr *g2d_userptr;
@ -444,7 +443,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
*/ */
if (g2d_userptr->size == size) { if (g2d_userptr->size == size) {
atomic_inc(&g2d_userptr->refcount); atomic_inc(&g2d_userptr->refcount);
*obj = (unsigned long)g2d_userptr; *obj = g2d_userptr;
return &g2d_userptr->dma_addr; return &g2d_userptr->dma_addr;
} }
@ -528,7 +527,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d,
g2d_userptr->in_pool = true; g2d_userptr->in_pool = true;
} }
*obj = (unsigned long)g2d_userptr; *obj = g2d_userptr;
return &g2d_userptr->dma_addr; return &g2d_userptr->dma_addr;
@ -557,9 +556,7 @@ static void g2d_userptr_free_all(struct g2d_data *g2d, struct drm_file *filp)
list_for_each_entry_safe(g2d_userptr, n, &file_priv->userptr_list, list) list_for_each_entry_safe(g2d_userptr, n, &file_priv->userptr_list, list)
if (g2d_userptr->in_pool) if (g2d_userptr->in_pool)
g2d_userptr_put_dma_addr(g2d, g2d_userptr_put_dma_addr(g2d, g2d_userptr, true);
(unsigned long)g2d_userptr,
true);
g2d->current_pool = 0; g2d->current_pool = 0;
} }
@ -714,26 +711,23 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
buf_desc = &buf_info->descs[reg_type]; buf_desc = &buf_info->descs[reg_type];
if (buf_info->types[reg_type] == BUF_TYPE_GEM) { if (buf_info->types[reg_type] == BUF_TYPE_GEM) {
unsigned long size; struct exynos_drm_gem *exynos_gem;
size = exynos_drm_gem_get_size(drm_dev, handle, file); exynos_gem = exynos_drm_gem_get(file, handle);
if (!size) { if (!exynos_gem) {
ret = -EFAULT; ret = -EFAULT;
goto err; goto err;
} }
if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, if (!g2d_check_buf_desc_is_valid(buf_desc,
size)) { reg_type, exynos_gem->size)) {
exynos_drm_gem_put(exynos_gem);
ret = -EFAULT; ret = -EFAULT;
goto err; goto err;
} }
addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, addr = &exynos_gem->dma_addr;
file); buf_info->obj[reg_type] = exynos_gem;
if (IS_ERR(addr)) {
ret = -EFAULT;
goto err;
}
} else { } else {
struct drm_exynos_g2d_userptr g2d_userptr; struct drm_exynos_g2d_userptr g2d_userptr;
@ -753,7 +747,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
g2d_userptr.userptr, g2d_userptr.userptr,
g2d_userptr.size, g2d_userptr.size,
file, file,
&handle); &buf_info->obj[reg_type]);
if (IS_ERR(addr)) { if (IS_ERR(addr)) {
ret = -EFAULT; ret = -EFAULT;
goto err; goto err;
@ -762,7 +756,6 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d,
cmdlist->data[reg_pos + 1] = *addr; cmdlist->data[reg_pos + 1] = *addr;
buf_info->reg_types[i] = reg_type; buf_info->reg_types[i] = reg_type;
buf_info->handles[reg_type] = handle;
} }
return 0; return 0;
@ -782,20 +775,20 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d,
for (i = 0; i < buf_info->map_nr; i++) { for (i = 0; i < buf_info->map_nr; i++) {
struct g2d_buf_desc *buf_desc; struct g2d_buf_desc *buf_desc;
enum g2d_reg_type reg_type; enum g2d_reg_type reg_type;
unsigned long handle; void *obj;
reg_type = buf_info->reg_types[i]; reg_type = buf_info->reg_types[i];
buf_desc = &buf_info->descs[reg_type]; buf_desc = &buf_info->descs[reg_type];
handle = buf_info->handles[reg_type]; obj = buf_info->obj[reg_type];
if (buf_info->types[reg_type] == BUF_TYPE_GEM) if (buf_info->types[reg_type] == BUF_TYPE_GEM)
exynos_drm_gem_put_dma_addr(g2d->drm_dev, handle, filp); exynos_drm_gem_put(obj);
else else
g2d_userptr_put_dma_addr(g2d, handle, false); g2d_userptr_put_dma_addr(g2d, obj, false);
buf_info->reg_types[i] = REG_TYPE_NONE; buf_info->reg_types[i] = REG_TYPE_NONE;
buf_info->handles[reg_type] = 0; buf_info->obj[reg_type] = NULL;
buf_info->types[reg_type] = 0; buf_info->types[reg_type] = 0;
memset(buf_desc, 0x00, sizeof(*buf_desc)); memset(buf_desc, 0x00, sizeof(*buf_desc));
} }

View file

@ -171,26 +171,6 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem *exynos_gem)
kfree(exynos_gem); kfree(exynos_gem);
} }
unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *file_priv)
{
struct exynos_drm_gem *exynos_gem;
struct drm_gem_object *obj;
obj = drm_gem_object_lookup(file_priv, gem_handle);
if (!obj) {
DRM_ERROR("failed to lookup gem object.\n");
return 0;
}
exynos_gem = to_exynos_gem(obj);
drm_gem_object_put_unlocked(obj);
return exynos_gem->size;
}
static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev,
unsigned long size) unsigned long size)
{ {
@ -299,43 +279,15 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
&args->offset); &args->offset);
} }
dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, struct exynos_drm_gem *exynos_drm_gem_get(struct drm_file *filp,
unsigned int gem_handle, unsigned int gem_handle)
struct drm_file *filp)
{
struct exynos_drm_gem *exynos_gem;
struct drm_gem_object *obj;
obj = drm_gem_object_lookup(filp, gem_handle);
if (!obj) {
DRM_ERROR("failed to lookup gem object.\n");
return ERR_PTR(-EINVAL);
}
exynos_gem = to_exynos_gem(obj);
return &exynos_gem->dma_addr;
}
void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *filp)
{ {
struct drm_gem_object *obj; struct drm_gem_object *obj;
obj = drm_gem_object_lookup(filp, gem_handle); obj = drm_gem_object_lookup(filp, gem_handle);
if (!obj) { if (!obj)
DRM_ERROR("failed to lookup gem object.\n"); return NULL;
return; return to_exynos_gem(obj);
}
drm_gem_object_put_unlocked(obj);
/*
* decrease obj->refcount one more time because we has already
* increased it at exynos_drm_gem_get_dma_addr().
*/
drm_gem_object_put_unlocked(obj);
} }
static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem, static int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem *exynos_gem,

View file

@ -77,32 +77,26 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
/* /*
* get dma address from gem handle and this function could be used for * get exynos drm object from gem handle, this function could be used for
* other drivers such as 2d/3d acceleration drivers. * other drivers such as 2d/3d acceleration drivers.
* with this function call, gem object reference count would be increased. * with this function call, gem object reference count would be increased.
*/ */
dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, struct exynos_drm_gem *exynos_drm_gem_get(struct drm_file *filp,
unsigned int gem_handle, unsigned int gem_handle);
struct drm_file *filp);
/* /*
* put dma address from gem handle and this function could be used for * put exynos drm object acquired from exynos_drm_gem_get(),
* other drivers such as 2d/3d acceleration drivers. * gem object reference count would be decreased.
* with this function call, gem object reference count would be decreased.
*/ */
void exynos_drm_gem_put_dma_addr(struct drm_device *dev, static inline void exynos_drm_gem_put(struct exynos_drm_gem *exynos_gem)
unsigned int gem_handle, {
struct drm_file *filp); drm_gem_object_put_unlocked(&exynos_gem->base);
}
/* get buffer information to memory region allocated by gem. */ /* get buffer information to memory region allocated by gem. */
int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
/* get buffer size to gem handle. */
unsigned long exynos_drm_gem_get_size(struct drm_device *dev,
unsigned int gem_handle,
struct drm_file *file_priv);
/* free gem object. */ /* free gem object. */
void exynos_drm_gem_free_object(struct drm_gem_object *obj); void exynos_drm_gem_free_object(struct drm_gem_object *obj);