drm/panfrost: Restructure the GEM object creation
Setting the GPU VA when creating the GEM object doesn't allow for any conditional adjustments to the mapping. In preparation to support adjusting the mapping and per FD address spaces, restructure the GEM object creation to map and unmap the GEM object in the GEM object .open() and .close() hooks. While panfrost_gem_free_object() and panfrost_gem_prime_import_sg_table() are not really needed after this commit, keep them as we'll need them in subsequent commits. Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com> Cc: Boris Brezillon <boris.brezillon@collabora.com> Cc: Robin Murphy <robin.murphy@arm.com> Reviewed-by: Steven Price <steven.price@arm.com> Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Signed-off-by: Rob Herring <robh@kernel.org> Link: https://patchwork.freedesktop.org/patch/msgid/20190808222200.13176-4-robh@kernel.org
This commit is contained in:
parent
3bf5189d93
commit
a5efb4c9a5
|
@ -78,7 +78,6 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct
|
||||||
static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
|
static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file)
|
struct drm_file *file)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct drm_gem_shmem_object *shmem;
|
struct drm_gem_shmem_object *shmem;
|
||||||
struct drm_panfrost_create_bo *args = data;
|
struct drm_panfrost_create_bo *args = data;
|
||||||
|
|
||||||
|
@ -90,17 +89,9 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
|
||||||
if (IS_ERR(shmem))
|
if (IS_ERR(shmem))
|
||||||
return PTR_ERR(shmem);
|
return PTR_ERR(shmem);
|
||||||
|
|
||||||
ret = panfrost_mmu_map(to_panfrost_bo(&shmem->base));
|
|
||||||
if (ret)
|
|
||||||
goto err_free;
|
|
||||||
|
|
||||||
args->offset = to_panfrost_bo(&shmem->base)->node.start << PAGE_SHIFT;
|
args->offset = to_panfrost_bo(&shmem->base)->node.start << PAGE_SHIFT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_free:
|
|
||||||
drm_gem_handle_delete(file, args->handle);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -19,13 +19,6 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
|
||||||
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
||||||
struct panfrost_device *pfdev = obj->dev->dev_private;
|
struct panfrost_device *pfdev = obj->dev->dev_private;
|
||||||
|
|
||||||
if (bo->is_mapped)
|
|
||||||
panfrost_mmu_unmap(bo);
|
|
||||||
|
|
||||||
spin_lock(&pfdev->mm_lock);
|
|
||||||
drm_mm_remove_node(&bo->node);
|
|
||||||
spin_unlock(&pfdev->mm_lock);
|
|
||||||
|
|
||||||
mutex_lock(&pfdev->shrinker_lock);
|
mutex_lock(&pfdev->shrinker_lock);
|
||||||
if (!list_empty(&bo->base.madv_list))
|
if (!list_empty(&bo->base.madv_list))
|
||||||
list_del(&bo->base.madv_list);
|
list_del(&bo->base.madv_list);
|
||||||
|
@ -34,8 +27,47 @@ static void panfrost_gem_free_object(struct drm_gem_object *obj)
|
||||||
drm_gem_shmem_free_object(obj);
|
drm_gem_shmem_free_object(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
size_t size = obj->size;
|
||||||
|
u64 align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0;
|
||||||
|
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
||||||
|
struct panfrost_device *pfdev = obj->dev->dev_private;
|
||||||
|
|
||||||
|
spin_lock(&pfdev->mm_lock);
|
||||||
|
ret = drm_mm_insert_node_generic(&pfdev->mm, &bo->node,
|
||||||
|
size >> PAGE_SHIFT, align, 0, 0);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = panfrost_mmu_map(bo);
|
||||||
|
if (ret)
|
||||||
|
drm_mm_remove_node(&bo->node);
|
||||||
|
|
||||||
|
out:
|
||||||
|
spin_unlock(&pfdev->mm_lock);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void panfrost_gem_close(struct drm_gem_object *obj, struct drm_file *file_priv)
|
||||||
|
{
|
||||||
|
struct panfrost_gem_object *bo = to_panfrost_bo(obj);
|
||||||
|
struct panfrost_device *pfdev = obj->dev->dev_private;
|
||||||
|
|
||||||
|
if (bo->is_mapped)
|
||||||
|
panfrost_mmu_unmap(bo);
|
||||||
|
|
||||||
|
spin_lock(&pfdev->mm_lock);
|
||||||
|
if (drm_mm_node_allocated(&bo->node))
|
||||||
|
drm_mm_remove_node(&bo->node);
|
||||||
|
spin_unlock(&pfdev->mm_lock);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct drm_gem_object_funcs panfrost_gem_funcs = {
|
static const struct drm_gem_object_funcs panfrost_gem_funcs = {
|
||||||
.free = panfrost_gem_free_object,
|
.free = panfrost_gem_free_object,
|
||||||
|
.open = panfrost_gem_open,
|
||||||
|
.close = panfrost_gem_close,
|
||||||
.print_info = drm_gem_shmem_print_info,
|
.print_info = drm_gem_shmem_print_info,
|
||||||
.pin = drm_gem_shmem_pin,
|
.pin = drm_gem_shmem_pin,
|
||||||
.unpin = drm_gem_shmem_unpin,
|
.unpin = drm_gem_shmem_unpin,
|
||||||
|
@ -55,10 +87,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = {
|
||||||
*/
|
*/
|
||||||
struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size)
|
struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
struct panfrost_device *pfdev = dev->dev_private;
|
|
||||||
struct panfrost_gem_object *obj;
|
struct panfrost_gem_object *obj;
|
||||||
u64 align;
|
|
||||||
|
|
||||||
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
|
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
|
@ -66,21 +95,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t
|
||||||
|
|
||||||
obj->base.base.funcs = &panfrost_gem_funcs;
|
obj->base.base.funcs = &panfrost_gem_funcs;
|
||||||
|
|
||||||
size = roundup(size, PAGE_SIZE);
|
|
||||||
align = size >= SZ_2M ? SZ_2M >> PAGE_SHIFT : 0;
|
|
||||||
|
|
||||||
spin_lock(&pfdev->mm_lock);
|
|
||||||
ret = drm_mm_insert_node_generic(&pfdev->mm, &obj->node,
|
|
||||||
size >> PAGE_SHIFT, align, 0, 0);
|
|
||||||
spin_unlock(&pfdev->mm_lock);
|
|
||||||
if (ret)
|
|
||||||
goto free_obj;
|
|
||||||
|
|
||||||
return &obj->base.base;
|
return &obj->base.base;
|
||||||
|
|
||||||
free_obj:
|
|
||||||
kfree(obj);
|
|
||||||
return ERR_PTR(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct drm_gem_object *
|
struct drm_gem_object *
|
||||||
|
@ -89,15 +104,10 @@ panfrost_gem_prime_import_sg_table(struct drm_device *dev,
|
||||||
struct sg_table *sgt)
|
struct sg_table *sgt)
|
||||||
{
|
{
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
struct panfrost_gem_object *pobj;
|
|
||||||
|
|
||||||
obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt);
|
obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt);
|
||||||
if (IS_ERR(obj))
|
if (IS_ERR(obj))
|
||||||
return ERR_CAST(obj);
|
return ERR_CAST(obj);
|
||||||
|
|
||||||
pobj = to_panfrost_bo(obj);
|
|
||||||
|
|
||||||
panfrost_mmu_map(pobj);
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue