diff mbox

sh: Add wait for vsync ioctl

Message ID AB12B32E73474741A2C5361C433A44DE017832D3@rte-ben-exch.RTE.ADWIN.RENESAS.COM (mailing list archive)
State Superseded
Headers show

Commit Message

Phil Edworthy Feb. 10, 2010, 3 p.m. UTC
None
diff mbox

Patch

--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -19,6 +19,7 @@ 
 #include <linux/dma-mapping.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
+#include <linux/ioctl.h>
 #include <video/sh_mobile_lcdc.h>
 #include <asm/atomic.h>
 
@@ -40,6 +41,10 @@ 
 #define _LDDWAR 0x900
 #define _LDDRAR 0x904
 
+#ifndef FBIO_WAITFORVSYNC
+#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
+#endif
+
 /* shared registers and their order for context save/restore */
 static int lcdc_shared_regs[] = {
 	_LDDCKR,
@@ -106,6 +111,7 @@ 
 #define LDRCNTR_SRC	0x00010000
 #define LDRCNTR_MRS	0x00000002
 #define LDRCNTR_MRC	0x00000001
+#define LDSR_MRS    0x00000100
 
 struct sh_mobile_lcdc_priv;
 struct sh_mobile_lcdc_chan {
@@ -124,6 +130,8 @@ 
 	unsigned long pan_offset;
 	unsigned long new_pan_offset;
 	wait_queue_head_t frame_end_wait;
+	unsigned long seen_vsync;
+	wait_queue_head_t wait_vsync;
 };
 
 struct sh_mobile_lcdc_priv {
@@ -367,17 +375,22 @@ 
 
 		/* VSYNC End */
 		if (ldintr & LDINTR_VES) {
-			unsigned long ldrcntr = lcdc_read(priv, _LDRCNTR);
-			/* Set the source address for the next refresh */
-			lcdc_write_chan_mirror(ch, LDSA1R, ch->dma_handle +
-					       ch->new_pan_offset);
-			if (lcdc_chan_is_sublcd(ch))
-				lcdc_write(ch->lcdc, _LDRCNTR,
-					   ldrcntr ^ LDRCNTR_SRS);
-			else
-				lcdc_write(ch->lcdc, _LDRCNTR,
-					   ldrcntr ^ LDRCNTR_MRS);
-			ch->pan_offset = ch->new_pan_offset;
+			if (ch->pan_offset != ch->new_pan_offset) {
+				unsigned long ldrcntr = lcdc_read(priv,
_LDRCNTR);
+				/* Set the source address for the next
refresh */
+				lcdc_write_chan_mirror(ch, LDSA1R,
ch->dma_handle +
+
ch->new_pan_offset);
+				if (lcdc_chan_is_sublcd(ch))
+					lcdc_write(ch->lcdc, _LDRCNTR,
+						   ldrcntr ^ LDRCNTR_SRS);
+				else
+					lcdc_write(ch->lcdc, _LDRCNTR,
+						   ldrcntr ^ LDRCNTR_MRS);
+				ch->pan_offset = ch->new_pan_offset;
+			}
+
+			ch->seen_vsync = 1;