drm/rockchip: gem: Add GEM create ioctl support

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 <mark.yao@rock-chips.com>
Signed-off-by: Sandy Huang <hjc@rock-chips.com>
This commit is contained in:
Sandy Huang
2019-06-12 10:24:36 +08:00
parent 116c907ea3
commit a430ff906a
3 changed files with 100 additions and 0 deletions

View File

@@ -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,
@@ -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,

View File

@@ -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)
{

View File

@@ -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);