This adds necessary two ioctls for cpu access of gem object from user. It needs to be synced properly in order for the cpu and device if the buffer of gem object is cachable. - DRM_IOCTL_EXYNOS_GEM_CPU_PREP Should be used explicitly before it will be cpu access of gem object from user. - DRM_IOCTL_EXYNOS_GEM_CPU_FINI Should be used explicitly after it is finished cpu access of gem object from user. Signed-off-by: Joonyoung Shim <jy0922.shim@xxxxxxxxxxx> --- This is based on patch of Daniel dropping DRM_UNLOCKED flag on each drivers[1] and patch that is droped DRM_UNLOCKED flag from my posted patch[2]. [1] http://lists.freedesktop.org/archives/intel-gfx/2015-September/075368.html [2] http://www.spinics.net/lists/dri-devel/msg91465.html drivers/gpu/drm/exynos/exynos_drm_drv.c | 4 +++ drivers/gpu/drm/exynos/exynos_drm_gem.c | 48 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_gem.h | 14 ++++++++++ include/uapi/drm/exynos_drm.h | 18 ++++++++++++- 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 74bf3afed519..f15945c1c01d 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -408,6 +408,10 @@ static const struct drm_ioctl_desc exynos_ioctls[] = { DRM_AUTH | DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP, exynos_drm_gem_map_ioctl, DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_PREP, exynos_drm_gem_cpu_prep_ioctl, + DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CPU_FINI, exynos_drm_gem_cpu_fini_ioctl, + DRM_AUTH | DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, exynos_drm_gem_get_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, vidi_connection_ioctl, diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 01c5e0854016..4907ad3994db 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -321,6 +321,54 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data, &args->offset); } +int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_exynos_gem_cpu_access *args = data; + struct drm_gem_object *obj; + struct exynos_drm_gem *exynos_gem; + + obj = drm_gem_object_lookup(dev, file, args->handle); + if (!obj) { + DRM_ERROR("Failed to lookup gem object\n"); + return -EINVAL; + } + + exynos_gem = to_exynos_gem(obj); + + if (exynos_gem->flags & EXYNOS_BO_CACHABLE) + dma_sync_sg_for_cpu(dev->dev, exynos_gem->sgt->sgl, + exynos_gem->sgt->nents, DMA_FROM_DEVICE); + + drm_gem_object_unreference_unlocked(obj); + + return 0; +} + +int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_exynos_gem_cpu_access *args = data; + struct drm_gem_object *obj; + struct exynos_drm_gem *exynos_gem; + + obj = drm_gem_object_lookup(dev, file, args->handle); + if (!obj) { + DRM_ERROR("Failed to lookup gem object\n"); + return -EINVAL; + } + + exynos_gem = to_exynos_gem(obj); + + if (exynos_gem->flags & EXYNOS_BO_CACHABLE) + dma_sync_sg_for_device(dev->dev, exynos_gem->sgt->sgl, + exynos_gem->sgt->nents, DMA_TO_DEVICE); + + drm_gem_object_unreference_unlocked(obj); + + return 0; +} + dma_addr_t *exynos_drm_gem_get_dma_addr(struct drm_device *dev, unsigned int gem_handle, struct drm_file *filp) diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index e9eb5631f322..d5aac38f455a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -74,6 +74,20 @@ int exynos_drm_gem_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); /* + * Should be used explicitly before it will be cpu access of gem object + * from user. + */ +int exynos_drm_gem_cpu_prep_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +/* + * Should be used explicitly after it is finished cpu access of gem + * object from user. + */ +int exynos_drm_gem_cpu_fini_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); + +/* * get dma address from gem handle and this function could be used for * other drivers such as 2d/3d acceleration drivers. * with this function call, gem object reference count would be increased. diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h index 1d7c80734e43..b16a9a9ea34e 100644 --- a/include/uapi/drm/exynos_drm.h +++ b/include/uapi/drm/exynos_drm.h @@ -46,6 +46,16 @@ struct drm_exynos_gem_map { }; /** + * A structure for cpu access of gem object from user. + * + * @handle: handle of gem object. + */ +struct drm_exynos_gem_cpu_access { + __u32 handle; + __u32 reserved; +}; + +/** * A structure to gem information. * * @handle: a handle to gem object created. @@ -301,8 +311,10 @@ struct drm_exynos_ipp_cmd_ctrl { #define DRM_EXYNOS_GEM_CREATE 0x00 #define DRM_EXYNOS_GEM_MAP 0x01 -/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ +#define DRM_EXYNOS_GEM_CPU_PREP 0x02 +#define DRM_EXYNOS_GEM_CPU_FINI 0x03 #define DRM_EXYNOS_GEM_GET 0x04 +/* Reserved 0x05 ~ 0x06 for exynos specific gem ioctl */ #define DRM_EXYNOS_VIDI_CONNECTION 0x07 /* G2D */ @@ -320,6 +332,10 @@ struct drm_exynos_ipp_cmd_ctrl { DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create) #define DRM_IOCTL_EXYNOS_GEM_MAP DRM_IOWR(DRM_COMMAND_BASE + \ DRM_EXYNOS_GEM_MAP, struct drm_exynos_gem_map) +#define DRM_IOCTL_EXYNOS_GEM_CPU_PREP DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_CPU_PREP, struct drm_exynos_gem_cpu_access) +#define DRM_IOCTL_EXYNOS_GEM_CPU_FINI DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_EXYNOS_GEM_CPU_FINI, struct drm_exynos_gem_cpu_access) #define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \ DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info) -- 1.9.1 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel