Linux Framebuffer Layer development
 help / color / mirror / Atom feed
From: Mark Pustjens <pustjens@dds.nl>
To: linux-fbdev-devel@lists.sourceforge.net
Subject: Re: [PATCH] savagefb: vsync for twisterP
Date: Wed, 20 Dec 2006 10:59:32 +0100 (CET)	[thread overview]
Message-ID: <Pine.LNX.4.64.0612201059100.2728@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.64.0612201036130.2728@localhost.localdomain>

[-- Attachment #1: Type: TEXT/PLAIN, Size: 570 bytes --]

Ofcourse, I have to actually *add* the patch :)

On Wed, 20 Dec 2006, Mark Pustjens wrote:

> Hi,
>
> This patch add support to the savagefb driver for
> waiting for vsync for the TwisterP chipset.
>
> The patch adds an ioctl FBIO_WAITFORVSYNC just like the
> matroxfb driver.
>
> It probably needs some work.
>
> Merry Greetings,
>
> Mark Pustjens
>
>

-- 
Racism was not a problem on the Discworld, because -- what with trolls and
dwarfs and so on -- speciesism was more interesting. Black and white lived
in perfect harmony and ganged up on green.
   (Witches Abroad)

[-- Attachment #2: Type: TEXT/PLAIN, Size: 7398 bytes --]

diff -Naur linux-2.6.19.1-org/drivers/video/savage/savagefb_driver.c linux-2.6.19.1-new/drivers/video/savage/savagefb_driver.c
--- linux-2.6.19.1-org/drivers/video/savage/savagefb_driver.c	2006-12-11 20:32:53.000000000 +0100
+++ linux-2.6.19.1-new/drivers/video/savage/savagefb_driver.c	2006-12-19 10:17:06.000000000 +0100
@@ -4,6 +4,9 @@
  * Copyright (c) 2001-2002  Denis Oliver Kropp <dok@directfb.org>
  *                          Sven Neumann <neo@directfb.org>
  *
+ * Copyright (c) 2006 TPO Displays Corp
+ *		       adapted by Mark Pustjens <pustjens@dds.nl> to
+ *		       include vsync interrupt support.
  *
  * Card specific code is based on XFree86's savage driver.
  * Framebuffer framework code is based on code of cyber2000fb and tdfxfb.
@@ -526,6 +529,121 @@
 }
 #endif
 
+static irqreturn_t savagefb_irq(int irq, void *dev_id, struct pt_regs *fp)
+{
+	struct savagefb_par *par = dev_id;
+        u_int32_t status;
+        int handled = 0;
+	unsigned char b;
+
+	vga_out8(0x3d4, 0x11, par);
+	if ((((b = vga_in8(0x3d5, par)) & 0x30) == 0x10) && (vga_in8(0x3da, par) & 0x08)) {
+		par->vsync.cnt++;
+		wake_up_interruptible(&par->vsync.wait);
+		vga_out8(0x3d5, (b & 0xef) | 0x20, par);
+		handled = 1;
+	}
+
+        return IRQ_RETVAL(handled);
+}
+
+int savagefb_enable_irq(struct fb_info *info, int reenable) {
+	struct savagefb_par *par = (struct savagefb_par *)info->par;
+
+        if (info->fix.accel != FB_ACCEL_S3TWISTER_P)
+                return -EINVAL;
+
+        if (!test_and_set_bit(0, &par->irq_flags)) {
+                if (request_irq(par->pcidev->irq, savagefb_irq,
+                                SA_SHIRQ, "savagefb", par)) {
+                        clear_bit(0, &par->irq_flags);
+                        return -EINVAL;
+                }
+		vga_out8(0x3d4, 0x11, par);
+		vga_out8(0x3d5, (vga_in8(0x3d5, par) | 0x10) & 0xdf, par);
+        } else if (reenable) {
+		unsigned char b;
+		vga_out8(0x3d4, 0x11, par);
+		b = vga_in8(0x3d5, par);
+                if ((b & 0x20) == 0x20) {
+                        printk(KERN_DEBUG "savagefb: someone disabled vertical retrace interrupt [0x%02X]\n", b);
+                } else if ((b & 0x10) == 0x00) {
+                        printk(KERN_DEBUG "savagefb: interrupt enabled but interrupt cleared [0x%02X]\n", b);
+		}
+		vga_out8(0x3d5, (b | 0x10) & 0xdf, par);
+        }
+        return 0;
+}
+
+static void savagefb_disable_irq(struct fb_info *info) {
+	struct savagefb_par *par = (struct savagefb_par *)info->par;
+
+        if (test_and_clear_bit(0, &par->irq_flags)) {
+		/* disabling the interrupt in hardware was done in the interrupt handler */
+		vga_out8(0x3d4, 0x17, par);
+		while ((vga_in8(0x3da, par) & 0x08) == 0x00);
+
+	//	VerticalRetraceWait(par); /* wait until it is save to call free_irq */
+                free_irq(par->pcidev->irq, par);
+        }
+}
+
+int savagefb_wait_for_vsync(struct fb_info *info, u32 crtc) {
+	struct savagefb_par *par = (struct savagefb_par *)info->par;
+	struct savagefb_vsync *vs;
+	unsigned int cnt;
+	int ret;
+
+	switch (crtc) {
+        	case 0: 
+                	vs = &par->vsync;
+	                break;
+        	default:
+                	return -ENODEV;
+        }
+	
+	ret = savagefb_enable_irq(info, 0);
+        if (ret) {
+                return ret;
+        }
+
+	cnt = vs->cnt;
+	ret = wait_event_interruptible_timeout(vs->wait, cnt != vs->cnt, HZ*10);
+	savagefb_disable_irq(info);
+	if (ret < 0) {
+                return ret;
+        }
+        if (ret == 0) {
+                savagefb_enable_irq(info, 1);
+		printk (KERN_ERR "savagefb timeout while waiting for vsync\n");
+                return -ETIMEDOUT;
+        }
+        return 0;
+}
+
+static int savagefb_ioctl(struct inode *inode, struct file *file,
+                          unsigned int cmd, unsigned long arg,
+                          struct fb_info *info)
+{
+        void __user *argp = (void __user *)arg;
+	struct savagefb_par *par = (struct savagefb_par *)info->par;
+
+        DBG(__FUNCTION__)
+
+        switch (cmd) {
+                case FBIO_WAITFORVSYNC:
+			{
+				u_int32_t crt;
+
+	                        if (get_user(crt, (__u32 __user *) arg))
+        	                        return -EFAULT;
+
+				return savagefb_wait_for_vsync(info, crt);
+                        }
+	}
+	return -ENOTTY;
+}
+
 /* --------------------------------------------------------------------- */
 
 static void savage_get_default_par(struct savagefb_par *par, struct savage_reg *reg)
@@ -1458,6 +1576,10 @@
 	vga_out8(0x3d4, 0x3a, par);
 	vga_out8(0x3d5, cr3a, par);
 
+	/* enable the possibility of irqs */
+	vga_out8 (0x3d4, 0x32, par);
+	vga_out8 (0x3d5, vga_in8(0x3d5, par) | 0x10, par);
+
 	SavageSetup2DEngine(par);
 	vgaHWProtect(par, 0);
 }
@@ -1616,6 +1738,7 @@
 	.fb_setcolreg   = savagefb_setcolreg,
 	.fb_pan_display = savagefb_pan_display,
 	.fb_blank       = savagefb_blank,
+	.fb_ioctl       = savagefb_ioctl,
 	.fb_save_state  = savagefb_save_state,
 	.fb_restore_state = savagefb_restore_state,
 #if defined(CONFIG_FB_SAVAGE_ACCEL)
@@ -2169,6 +2292,9 @@
 		goto failed_enable;
 	}
 
+	init_waitqueue_head(&par->vsync.wait);
+	par->irq_flags = 0;
+
 	err = -ENOMEM;
 
 	if ((err = savage_init_fb_info(info, dev, id)))
diff -Naur linux-2.6.19.1-org/drivers/video/savage/savagefb.h linux-2.6.19.1-new/drivers/video/savage/savagefb.h
--- linux-2.6.19.1-org/drivers/video/savage/savagefb.h	2006-12-11 20:32:53.000000000 +0100
+++ linux-2.6.19.1-new/drivers/video/savage/savagefb.h	2006-12-19 09:39:06.000000000 +0100
@@ -50,7 +50,16 @@
 #define PCI_CHIP_SUPSAV_IXCSDR		0x8c2e
 #define PCI_CHIP_SUPSAV_IXCDDR		0x8c2f
 
-
+#define S3_TWISTERP_INT_VSYNC	0x00000001
+#define S3_TWISTERP_INT_GEBSY	0x00000002 // 2D graphics engine busy
+#define S3_TWISTERP_INT_BFF	0x00000004 // bfifo full
+#define S3_TWISTERP_INT_BFE	0x00000008 // bfifo empty
+#define S3_TWISTERP_INT_CFF	0x00000010 // cfifo full
+#define S3_TWISTERP_INT_CFE	0x00000020 // cfifo empty
+#define S3_TWISTERP_INT_BCI	0x00000040
+#define S3_TWISTERP_INT_CBUT	0x00010000 // command overflow upper treshold
+#define S3_TWISTERP_INT_CBLT	0x00020000 // command overflow lower treshold
+#define S3_TWISTERP_INT_MASK	0x0003007F
 
 #define S3_SAVAGE3D_SERIES(chip)  ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
 
@@ -60,6 +69,9 @@
 
 #define S3_SAVAGE_SERIES(chip)    ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
 
+ /* ioctls */
+#define FBIO_WAITFORVSYNC     _IOW('F', 0x20, u_int32_t)
+
 /* Chip tags.  These are used to group the adapters into
  * related families.
  */
@@ -183,10 +195,17 @@
 	u32   reg;
 };
 
++ struct savagefb_vsync {
++         wait_queue_head_t       wait;
++         unsigned int            cnt;
++ };
++ 
+
 struct savagefb_par {
 	struct pci_dev *pcidev;
 	savage_chipset  chip;
 	struct savagefb_i2c_chan chan;
+	struct savagefb_vsync vsync;
 	struct savage_reg state;
 	struct savage_reg save;
 	unsigned char   *edid;
@@ -223,6 +242,8 @@
 	u32           cob_size;
 	int           cob_index;
 
+	unsigned long irq_flags;
+
 	void (*SavageWaitIdle) (struct savagefb_par *par);
 	void (*SavageWaitFifo) (struct savagefb_par *par, int space);
 

[-- Attachment #3: Type: text/plain, Size: 347 bytes --]

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV

[-- Attachment #4: Type: text/plain, Size: 182 bytes --]

_______________________________________________
Linux-fbdev-devel mailing list
Linux-fbdev-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel

  reply	other threads:[~2006-12-20  9:59 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-20  9:38 [PATCH] savagefb: vsync for twisterP Mark Pustjens
2006-12-20  9:59 ` Mark Pustjens [this message]
2006-12-20 16:37   ` Randy Dunlap
2007-01-09 11:12     ` Mark Pustjens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.LNX.4.64.0612201059100.2728@localhost.localdomain \
    --to=pustjens@dds.nl \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox