> 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