Skip to content

Commit

Permalink
drm/rockchip: gem: Add GEM create ioctl support
Browse files Browse the repository at this point in the history
Rockchip Socs have GPU, we need allocate GPU accelerated buffers.
So add special ioctls GEM_CREATE/GEM_MAP_OFFSET to support
accelerated buffers.

Change-Id: Ia4b13798aac97d16214da7a75a2479e6e334313a
Signed-off-by: Mark Yao <[email protected]>
Signed-off-by: Sandy Huang <[email protected]>
  • Loading branch information
sandy-huang committed Jul 20, 2021
1 parent 116c907 commit a430ff9
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 0 deletions.
12 changes: 12 additions & 0 deletions drivers/gpu/drm/rockchip/rockchip_drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,16 @@ static void rockchip_drm_unbind(struct device *dev)
drm_dev_put(drm_dev);
}

static const struct drm_ioctl_desc rockchip_ioctls[] = {
DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_CREATE, rockchip_gem_create_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_MAP_OFFSET,
rockchip_gem_map_offset_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(ROCKCHIP_GEM_GET_PHYS, rockchip_gem_get_phys_ioctl,
DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW),
};

static const struct file_operations rockchip_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
Expand Down Expand Up @@ -651,6 +661,8 @@ static struct drm_driver rockchip_drm_driver = {
#ifdef CONFIG_DEBUG_FS
.debugfs_init = rockchip_drm_debugfs_init,
#endif
.ioctls = rockchip_ioctls,
.num_ioctls = ARRAY_SIZE(rockchip_ioctls),
.fops = &rockchip_drm_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
Expand Down
74 changes: 74 additions & 0 deletions drivers/gpu/drm/rockchip/rockchip_drm_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,80 @@ void rockchip_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
/* Nothing to do if allocated by DMA mapping API. */
}

static int rockchip_gem_dumb_map_offset(struct drm_file *file_priv,
struct drm_device *dev, uint32_t handle,
uint64_t *offset)
{
struct drm_gem_object *obj;
int ret;

obj = drm_gem_object_lookup(file_priv, handle);
if (!obj) {
DRM_ERROR("failed to lookup gem object.\n");
return -EINVAL;
}

ret = drm_gem_create_mmap_offset(obj);
if (ret)
goto out;

*offset = drm_vma_node_offset_addr(&obj->vma_node);
DRM_DEBUG_KMS("offset = 0x%llx\n", *offset);

out:
drm_gem_object_put_locked(obj);

return 0;
}

int rockchip_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_rockchip_gem_create *args = data;
struct rockchip_gem_object *rk_obj;

rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
&args->handle);
return PTR_ERR_OR_ZERO(rk_obj);
}

int rockchip_gem_map_offset_ioctl(struct drm_device *drm, void *data,
struct drm_file *file_priv)
{
struct drm_rockchip_gem_map_off *args = data;

return rockchip_gem_dumb_map_offset(file_priv, drm, args->handle,
&args->offset);
}

int rockchip_gem_get_phys_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_rockchip_gem_phys *args = data;
struct rockchip_gem_object *rk_obj;
struct drm_gem_object *obj;
int ret = 0;

obj = drm_gem_object_lookup(file_priv, args->handle);
if (!obj) {
DRM_ERROR("failed to lookup gem object.\n");
return -EINVAL;
}
rk_obj = to_rockchip_obj(obj);

if (!(rk_obj->flags & ROCKCHIP_BO_CONTIG)) {
DRM_ERROR("Can't get phys address from non-continue buf.\n");
ret = -EINVAL;
goto out;
}

args->phy_addr = page_to_phys(rk_obj->pages[0]);

out:
drm_gem_object_put_locked(obj);
return ret;
}

int rockchip_gem_prime_begin_cpu_access(struct drm_gem_object *obj,
enum dma_data_direction dir)
{
Expand Down
14 changes: 14 additions & 0 deletions drivers/gpu/drm/rockchip/rockchip_drm_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,20 @@ void rockchip_gem_free_object(struct drm_gem_object *obj);
int rockchip_gem_dumb_create(struct drm_file *file_priv,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
/*
* request gem object creation and buffer allocation as the size
* that it is calculated with framebuffer information such as width,
* height and bpp.
*/
int rockchip_gem_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

/* get buffer offset to map to user space. */
int rockchip_gem_map_offset_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

int rockchip_gem_get_phys_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);

int rockchip_gem_prime_begin_cpu_access(struct drm_gem_object *obj,
enum dma_data_direction dir);
Expand Down

0 comments on commit a430ff9

Please sign in to comment.