aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_fbdev.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 8f007aaeffc..d85d02b4963 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -28,6 +28,10 @@
#define to_exynos_fbdev(x) container_of(x, struct exynos_drm_fbdev,\
drm_fb_helper)
+#define IOCTL_GET_FB_DMA_BUF _IOWR('m',0xF9, __u32 )
+#include <linux/dma-buf.h>
+#define NUM_BUFFERS 3
+
struct exynos_drm_fbdev {
struct drm_fb_helper drm_fb_helper;
struct exynos_drm_gem_obj *exynos_gem_obj;
@@ -62,6 +66,50 @@ static int exynos_drm_fb_mmap(struct fb_info *info,
return 0;
}
+static u32 exynos_fb_get_dma_buf( struct fb_info *info)
+{
+ int fd = -1;
+ struct drm_fb_helper *helper = info->par;
+ struct drm_device *dev = helper->dev;
+ struct exynos_drm_fbdev *exynos_fbd = to_exynos_fbdev(helper);
+ struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj;
+
+ if( dev->driver->gem_prime_export )
+ {
+ struct dma_buf *buf = NULL;
+ buf = dev->driver->gem_prime_export( dev, &exynos_gem_obj->base, O_RDWR);
+ if(buf)
+ fd = dma_buf_fd(buf, O_RDWR);
+ }
+
+ return fd;
+}
+
+static int fb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+
+ switch (cmd) {
+ case IOCTL_GET_FB_DMA_BUF:
+ {
+ u32 __user *out_ptr = (u32 __user *)arg;
+ u32 buf_fd = exynos_fb_get_dma_buf(info);
+ if(buf_fd == -1)
+ {
+ ret = -ENOMEM;
+ break;
+ }
+ ret = put_user(buf_fd, out_ptr);
+ break;
+ }
+ default:
+ ret = -ENOTTY;
+ }
+
+ return ret;
+}
+
static struct fb_ops exynos_drm_fb_ops = {
.owner = THIS_MODULE,
.fb_mmap = exynos_drm_fb_mmap,
@@ -73,6 +121,7 @@ static struct fb_ops exynos_drm_fb_ops = {
.fb_blank = drm_fb_helper_blank,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_setcmap = drm_fb_helper_setcmap,
+ .fb_ioctl = fb_ioctl,
};
static int exynos_drm_fbdev_update(struct drm_fb_helper *helper,
@@ -155,7 +204,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
sizes->surface_bpp);
mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
+ mode_cmd.height = sizes->surface_height * NUM_BUFFERS;
mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3);
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);