> Here's two patches

No, _here's_ two patches.  Grr.

Mark
diff -u -p -r1.4 uc_overlay.c
--- uc_overlay.c        27 Oct 2005 15:56:28 -0000      1.4
+++ uc_overlay.c        4 Nov 2005 17:38:31 -0000
@@ -23,6 +23,22 @@
 
 #include <misc/conf.h>
 
+struct fb_flip {
+    __u32 device;
+    __u32 field;
+    __u32 count;
+    __u32 offset[6];
+};
+
+#define VIAFB_FLIP_GRAPHICS 0
+#define VIAFB_FLIP_V1 1
+#define VIAFB_FLIP_V3 2
+#define VIAFB_FLIP_SPIC 3
+
+#ifndef FBIO_FLIPONVSYNC
+#define FBIO_FLIPONVSYNC    _IOWR('F', 0x21, struct fb_flip)
+#endif
+
 // Forward declaration
 static DFBResult
 uc_ovl_remove(CoreLayer *layer,
@@ -116,6 +132,8 @@ uc_ovl_set_region( CoreLayer            
 {
     UcDriverData*  ucdrv = (UcDriverData*) driver_data;
     UcOverlayData* ucovl = (UcOverlayData*) layer_data;
+    FBDev *dfb_fbdev = dfb_system_data();
+    int field_option;
 
     /* remember configuration */
     ucovl->config = *config;
@@ -144,6 +162,9 @@ uc_ovl_set_region( CoreLayer            
     ucovl->deinterlace = config->options & DLOP_DEINTERLACING;
     ucovl->surface     = surface;
 
+    field_option = 3;  // wait for any pending flip to complete
+    ioctl(dfb_fbdev->fd, FBIO_WAITFORVSYNC, &field_option);
+    
     return uc_ovl_update(ucdrv, ucovl, UC_OVL_CHANGE, surface);
 }
 
@@ -254,6 +275,7 @@ uc_ovl_flip_region( CoreLayer           
 
     ucovl->field = 0;
 
+#if 0
     if (ucovl->config.options & DLOP_FIELD_PARITY)
     {
         int field_option;
@@ -272,6 +294,33 @@ uc_ovl_flip_region( CoreLayer           
     ret = uc_ovl_update(ucdrv, ucovl, UC_OVL_FLIP, surface);
     if (ret)
         return ret;
+#else
+    if (ucovl->config.options & DLOP_FIELD_PARITY)
+    {
+        struct fb_flip flip;
+        int field_option;
+        
+        field_option = 3;      // wait for last pending flip to complete
+        ioctl(dfb_fbdev->fd, FBIO_WAITFORVSYNC, &field_option);
+        
+        flip.device = VIAFB_FLIP_V1;
+        flip.field = ucovl->config.parity;
+        flip.count = 0;        // until we implement this
+        
+        uc_ovl_map_buffer(surface->format, surface->front_buffer->video.offset,
+            ucovl->v1.ox, ucovl->v1.oy, surface->width, surface->height,
+            surface->front_buffer->video.pitch, 0,
+            &flip.offset[0], &flip.offset[1], &flip.offset[2]);
+        
+        ioctl(dfb_fbdev->fd, FBIO_FLIPONVSYNC, &flip);
+    }
+    else
+    {
+        ret = uc_ovl_update(ucdrv, ucovl, UC_OVL_FLIP, surface);
+        if (ret)
+            return ret;
+    }
+#endif
 
     if (flags & DSFLIP_WAIT)
         dfb_layer_wait_vsync(layer);
diff -u -p -r1.3 via_fbobj.c
--- linux/drivers/video/cle266/via_fbobj.c      4 Nov 2005 12:39:38 -0000       
1.3
+++ linux/drivers/video/cle266/via_fbobj.c      4 Nov 2005 17:40:14 -0000
@@ -48,6 +48,9 @@
 #ifndef FBIO_WAITFORVSYNC
 #define FBIO_WAITFORVSYNC   _IOW('F', 0x20, u_int32_t)
 #endif
+#ifndef FBIO_FLIPONVSYNC
+#define FBIO_FLIPONVSYNC    _IOWR('F', 0x21, struct fb_flip)
+#endif
 
 static struct fb_fix_screeninfo viafb_fix __initdata = {
     .id =       "UNICHROME", 
@@ -74,6 +77,12 @@ static struct via_par* current_par;
 #define t_inb(reg)          inb(reg)
 #endif
 
+#define V1_STARTADDR_0                  0x254
+#define V1_STARTADDR_CR0                0x2F0
+#define V1_STARTADDR_CB0                0x28C
+#define V_COMPOSE_MODE                  0x298
+#define V1_COMMAND_FIRE                 0x80000000
+
 #define VERSION     "1.0"
 
 int VIACheckTVExist(struct fb_info *info);
@@ -1262,6 +1271,10 @@ static int viafb_wait_for_sync(struct fb
     {
         ret = wait_event_interruptible_timeout(p->wq, (cnt != p->irq_cnt) && 
((p->irq_cnt & 1)==1), HZ/10);
     }
+    else if (field_option == 3) // wait for any pending flip to complete
+    {
+        ret = wait_event_interruptible_timeout(p->wq, p->flip_pending == 0, 
HZ/10);
+    }
 
     if (ret < 0) {
         return ret;
@@ -1273,6 +1286,21 @@ static int viafb_wait_for_sync(struct fb
     return 0;
 }
 
+static int viafb_flip_on_sync(struct fb_info *info, struct fb_flip *flip)
+{
+    struct via_par * p = (struct via_par *)info->par;
+    
+    if (flip->device == VIAFB_FLIP_V1)
+    {
+        p->flip = *flip;
+        flip->field = p->irq_cnt % 2;
+        flip->count = p->irq_cnt / 2;
+        p->flip_pending = 1;
+        return 0;
+    }
+    return -EINVAL;
+}
+
 static int viafb_ioctl(struct inode *inode, struct file *file, unsigned int 
cmd,
     unsigned long arg, struct fb_info *info)
 {
@@ -1286,6 +1314,23 @@ static int viafb_ioctl(struct inode *ino
             
             return viafb_wait_for_sync(info, field_option);
         }
+        case FBIO_FLIPONVSYNC:
+        {
+            struct fb_flip flip;
+            int err;
+
+            if (copy_from_user(&flip, (void __user *)arg, sizeof(flip)))
+                return -EFAULT;
+
+            err = viafb_flip_on_sync(info, &flip);
+            if (err)
+                return err;
+
+            if (copy_to_user((void __user *)arg, &flip, sizeof(flip)))
+                return -EFAULT;
+
+            return 0;
+        }
     }
 
     return -ENOTTY;
@@ -1303,6 +1348,14 @@ static irqreturn_t via_vga_irqhandler(in
         VIASETREG(p->io_base_virt, VIA_REG_INTERRUPT, status | 
VIA_IRQ_VBI_PENDING);
 
         p->irq_cnt++;
+        if (p->flip_pending && ((p->irq_cnt & 1) == p->flip.field))
+        {
+            VIASETREG(p->io_base_virt, V1_STARTADDR_0, p->flip.offset[0]);
+            VIASETREG(p->io_base_virt, V1_STARTADDR_CB0, p->flip.offset[1]);
+            VIASETREG(p->io_base_virt, V1_STARTADDR_CR0, p->flip.offset[2]);
+            VIASETREG(p->io_base_virt, V_COMPOSE_MODE, 
VIAGETREG(p->io_base_virt, V_COMPOSE_MODE)|V1_COMMAND_FIRE);
+            p->flip_pending = 0;
+        }
         wake_up_interruptible(&p->wq);
         handled = 1;
     }
@@ -1532,6 +1585,8 @@ static int __devinit via_pci_probe(struc
     current_par->TVoverscan = TVoverscan;
     current_par->TVEncoder = TVEncoder;
     
+    current_par->flip_pending = 0;
+    
     if (TVon) {
         VIACheckTVExist(info);
         if (default_xres==640 && default_yres==480)
diff -u -p -r1.2 via_fbobj.h
--- linux/drivers/video/cle266/via_fbobj.h      4 Nov 2005 12:39:38 -0000       
1.2
+++ linux/drivers/video/cle266/via_fbobj.h      4 Nov 2005 17:40:14 -0000
@@ -33,6 +33,18 @@
 
 #define CLE266          0x3122
 
+struct fb_flip {
+    u32 device;
+    u32 field;
+    u32 count;
+    u32 offset[6];
+};
+
+#define VIAFB_FLIP_GRAPHICS 0
+#define VIAFB_FLIP_V1 1
+#define VIAFB_FLIP_V3 2
+#define VIAFB_FLIP_SPIC 3
+
 /* 
  * This structure defines the hardware state of the graphics card. Normally
  * you place this in a header file in linux/include/video. This file usually
@@ -69,6 +81,9 @@ struct via_par {
     wait_queue_head_t wq;
     
     int vclk;       // in MHz
+    
+    struct fb_flip flip;
+    int flip_pending;
 };
 
 #define VIASETREG(mmio, addr, data)   *(volatile u32 *)((mmio) +(addr)) = 
(data)
_______________________________________________
directfb-users mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-users

Reply via email to