Index: include/video/davincifb.h =================================================================== --- include/video/davincifb.h (revision 765) +++ include/video/davincifb.h (working copy) @@ -40,6 +40,21 @@ u_int32_t zoom_v; } zoom_params_t; + +typedef struct fb_set_start { + int offset; /* offset from smem_start */ + unsigned long physical; /* absolute physical address when offset < 0 */ + + u_int64_t sync; /* input: target sync counter for change or 0 for no sync at all, + output: sync counter of actual change or 0 if still pending */ +} fb_set_start_t; + + +#ifdef _IOC_TYPECHECK +#undef _IOC_TYPECHECK +#define _IOC_TYPECHECK(x) (sizeof(x)) +#endif + #define RAM_CLUT_SIZE 256*3 #define FBIO_ENABLE_DISABLE_WIN \ _IOW('F', 0x30, unsigned char) @@ -83,6 +98,8 @@ _IOW('F', 0x49, u_int32_t) #define FBIO_SET_CURSOR \ _IOW('F', 0x50, struct fb_cursor) +#define FBIO_SET_START \ + _IOW('F', 0x66, struct fb_set_start) /* * Defines and Constants Index: drivers/video/davincifb.c =================================================================== --- drivers/video/davincifb.c (revision 765) +++ drivers/video/davincifb.c (working copy) @@ -1095,6 +1095,58 @@ return 0; } +static int +davincifb_set_start( struct fb_set_start *set, struct fb_info *info ) +{ + struct vpbe_dm_win_info *win = (struct vpbe_dm_win_info *) info->par; + unsigned long start = 0; + + /* Physical mode (absolute address)? */ + if (set->offset < 0) { + start = set->physical; + + /* FIXME: address checks */ + } + else { + /* Offset mode (from frame buffer device base). */ + if (set->offset + info->var.yres * info->fix.line_length >= win->fb_size) + return -EFAULT; + + start = win->fb_base_phys + set->offset; + } + + /* Set on explicit sync count? */ + if (set->sync > 1) { + if (set->sync <= dm->vsync_cnt) { + set_sdram_params( info->fix.id, start, info->fix.line_length ); + win->sdram_address = start; + + set->sync = dm->vsync_cnt; + } + else { + /* FIXME: No queue yet. */ + win->sdram_address = start; + + set->sync = 0; + } + } + /* Set on next sync? */ + else if (set->sync) { + win->sdram_address = start; + + set->sync = 0; + } + /* Set now! */ + else { + set_sdram_params( info->fix.id, start, info->fix.line_length ); + win->sdram_address = start; + + set->sync = dm->vsync_cnt; + } + + return 0; +} + /* * davincifb_ioctl - handler for private ioctls. */ @@ -1105,6 +1157,7 @@ struct vpbe_dm_win_info *w = (struct vpbe_dm_win_info *)info->par; void __user *argp = (void __user *)arg; struct fb_fillrect rect; + struct fb_set_start set_start; zoom_params_t zoom; int retval = 0; long std = 0; @@ -1414,6 +1467,16 @@ return -EINVAL; break; + case FBIO_SET_START: + if (copy_from_user(&set_start, argp, sizeof(set_start))) + return -EFAULT; + retval = davincifb_set_start( &set_start, &w->info ); + if (retval) + return retval; + if (copy_to_user(argp, &set_start, sizeof(set_start))) + return -EFAULT; + break; + default: retval = -EINVAL; break;