diff options
Diffstat (limited to 'drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c')
-rw-r--r-- | drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c | 104 |
1 files changed, 94 insertions, 10 deletions
diff --git a/drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c b/drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c index b5867b4..522442d 100644 --- a/drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c +++ b/drivers/video/samsung_extdisp/s3cfb_extdsp_ops.c @@ -505,6 +505,7 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) struct s3cfb_extdsp_user_window user_window; int vsync; int lock; + struct s3cfb_extdsp_buf_list buf_list; } p; switch (cmd) { @@ -522,10 +523,61 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) win->lock_buf_offset = fix->smem_start + ((var->xres_virtual * var->yoffset + var->xoffset) * (var->bits_per_pixel / 8)); + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].phys_addr == + (unsigned int)win->lock_buf_offset) + fbdev->buf_list[i].buf_status = + BUF_LOCKED; + } } else { /* Unlocked */ + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].phys_addr == + (unsigned int)win->lock_buf_offset) + fbdev->buf_list[i].buf_status = + BUF_FREE; + } win->lock_buf_offset = 0; } break; + case S3CFB_EXTDSP_LOCK_AND_GET_BUF: + if (copy_from_user(&p.buf_list, + (struct s3cfb_extdsp_buf_list __user *)arg, + sizeof(p.buf_list))) + return -EFAULT; + + if (p.buf_list.buf_status == BUF_LOCKED) { /* Locked */ + memset(&p.buf_list, 0, sizeof(p.buf_list)); + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].buf_status == + BUF_ACTIVE) { + fbdev->buf_list[i].buf_status = + BUF_LOCKED; + + p.buf_list.phys_addr = + fbdev->buf_list[i].phys_addr; + p.buf_list.time_marker = + fbdev->buf_list[i].time_marker; + p.buf_list.buf_status = + fbdev->buf_list[i].buf_status; + break; + } + } + } else if (p.buf_list.buf_status == BUF_FREE) { /* Unlocked */ + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].phys_addr == + p.buf_list.phys_addr) { + fbdev->buf_list[i].buf_status = + BUF_FREE; + break; + } + } + } + if (copy_to_user((void *)arg, &(p.buf_list), + sizeof(unsigned int))) { + dev_err(fbdev->dev, "copy_to_user error\n"); + return -EFAULT; + } + break; case S3CFB_EXTDSP_GET_LOCKED_BUFFER: if (copy_to_user((void *)arg, &(win->lock_buf_offset), @@ -535,6 +587,22 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) } break; + case S3CFB_EXTDSP_GET_FREE_BUFFER: + win->free_buf_offset = 0; + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].buf_status == BUF_FREE) { + win->free_buf_offset = + fbdev->buf_list[i].phys_addr; + break; + } + } + if (copy_to_user((void *)arg, &(win->free_buf_offset), + sizeof(unsigned int))) { + dev_err(fbdev->dev, "copy_to_user error\n"); + return -EFAULT; + } + break; + case S3CFB_EXTDSP_GET_NEXT_INDEX: cur_nrbuffer = var->yoffset / (var->yres_virtual / CONFIG_FB_S5P_EXTDSP_NR_BUFFERS); @@ -606,20 +674,20 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) } do_gettimeofday(&time_stamp.time_marker); for(i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { - if (fbdev->time_stamp[i].phys_addr == time_stamp.phys_addr) { - fbdev->time_stamp[i].time_marker = time_stamp.time_marker; + if (fbdev->buf_list[i].phys_addr == time_stamp.phys_addr) { + fbdev->buf_list[i].time_marker = time_stamp.time_marker; break; } - if (!fbdev->time_stamp[i].phys_addr) { - fbdev->time_stamp[i].phys_addr = time_stamp.phys_addr; - fbdev->time_stamp[i].time_marker = time_stamp.time_marker; + if (!fbdev->buf_list[i].phys_addr) { + fbdev->buf_list[i].phys_addr = time_stamp.phys_addr; + fbdev->buf_list[i].time_marker = time_stamp.time_marker; break; } if (i == (CONFIG_FB_S5P_EXTDSP_NR_BUFFERS -1)) { - fbdev->time_stamp[0].phys_addr = time_stamp.phys_addr; - fbdev->time_stamp[0].time_marker = time_stamp.time_marker; + fbdev->buf_list[0].phys_addr = time_stamp.phys_addr; + fbdev->buf_list[0].time_marker = time_stamp.time_marker; for(i = 1; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) - fbdev->time_stamp[i].phys_addr = 0; + fbdev->buf_list[i].phys_addr = 0; break; } } @@ -633,8 +701,8 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) return -EFAULT; } for(i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { - if (fbdev->time_stamp[i].phys_addr == time_stamp.phys_addr) { - time_stamp.time_marker = fbdev->time_stamp[i].time_marker; + if (fbdev->buf_list[i].phys_addr == time_stamp.phys_addr) { + time_stamp.time_marker = fbdev->buf_list[i].time_marker; break; } } @@ -646,6 +714,15 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) } break; + case S3CFB_EXTDSP_GET_LOCKED_NUMBER: + fbdev->lock_cnt = 0; + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].buf_status == BUF_LOCKED) + fbdev->lock_cnt++; + } + ret = memcpy(argp, &fbdev->lock_cnt, sizeof(fbdev->lock_cnt)) ? 0 : -EFAULT; + break; + case FBIOGET_FSCREENINFO: ret = memcpy(argp, &fb->fix, sizeof(fb->fix)) ? 0 : -EFAULT; break; @@ -700,6 +777,13 @@ int s3cfb_extdsp_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg) case S3CFB_EXTDSP_SET_WIN_ADDR: fix->smem_start = (unsigned long)argp; + for (i = 0; i < CONFIG_FB_S5P_EXTDSP_NR_BUFFERS; i++) { + if (fbdev->buf_list[i].phys_addr == + (unsigned int)fix->smem_start) + fbdev->buf_list[i].buf_status = BUF_ACTIVE; + else if (fbdev->buf_list[i].buf_status != BUF_LOCKED) + fbdev->buf_list[i].buf_status = BUF_FREE; + } break; case S3CFB_EXTDSP_GET_TZ_MODE: |