mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 03:10:12 +00:00
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:
parent
eb4d9796fa
commit
3aa2a5c140
3 changed files with 35 additions and 96 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue