Index: linux/drivers/video/w100fb.h
===================================================================
--- linux.orig/drivers/video/w100fb.h	2005-03-18 17:40:30.000000000 +0000
+++ linux/drivers/video/w100fb.h	2005-03-19 18:14:25.000000000 +0000
@@ -392,6 +392,22 @@
 	struct crtc_total_t f;
 } __attribute__((packed));
 
+struct crtc_ss_t {
+	unsigned long ss_start    : 10;
+	unsigned long             : 6;
+	unsigned long ss_end      : 10;
+	unsigned long             : 2;
+	unsigned long ss_align    : 1;
+	unsigned long ss_pol      : 1;
+	unsigned long ss_run_mode : 1;
+	unsigned long ss_en       : 1;
+} __attribute__((packed));
+
+union crtc_ss_u {
+	unsigned long val : 32;
+	struct crtc_ss_t f;
+} __attribute__((packed));
+
 struct active_h_disp_t {
 	unsigned long active_h_start  : 10;
 	unsigned long                 : 6;
@@ -672,6 +688,13 @@
 	struct pclk_cntl_t f;
 } __attribute__((packed));
 
+
+#define TESTCLK_SRC_PLL   0x01
+#define TESTCLK_SRC_SCLK  0x02
+#define TESTCLK_SRC_PCLK  0x03
+/* 4 and 5 seem to by XTAL/M */
+#define TESTCLK_SRC_XTAL  0x06
+
 struct clk_test_cntl_t {
 	unsigned long testclk_sel      : 4;
 	unsigned long                  : 3;
Index: linux/drivers/video/w100fb.c
===================================================================
--- linux.orig/drivers/video/w100fb.c	2005-03-18 17:40:30.000000000 +0000
+++ linux/drivers/video/w100fb.c	2005-03-19 23:27:28.000000000 +0000
@@ -25,6 +25,7 @@
 #include <linux/mm.h>
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/vmalloc.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <video/w100fb.h>
@@ -43,6 +44,7 @@
 static void w100_set_dispregs(struct w100fb_par*);
 static void w100_update_enable(void);
 static void w100_update_disable(void);
+static void calc_hsync(struct w100fb_par *par);
 struct w100_pll_info *w100_get_xtal_table(unsigned int freq);
 
 /* Pseudo palette size */
@@ -53,8 +55,6 @@
 
 #define BITS_PER_PIXEL    16
 
-static struct w100fb_par *current_par;
-
 /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */
 static void *remapped_base;
 static void *remapped_regs;
@@ -93,6 +93,8 @@
 	w100_update_disable();
 	w100_set_dispregs(par);
 	w100_update_enable();
+	
+	calc_hsync(par);
 
 	return count;
 }
@@ -101,8 +103,7 @@
 
 static ssize_t w100fb_reg_read(struct device *dev, const char *buf, size_t count)
 {
-	unsigned long param;
-	unsigned long regs;
+	unsigned long regs, param;
 	regs = simple_strtoul(buf, NULL, 16);
 	param = readl(remapped_regs + regs);
 	printk("Read Register 0x%08lX: 0x%08lX\n", regs, param);
@@ -113,8 +114,7 @@
 
 static ssize_t w100fb_reg_write(struct device *dev, const char *buf, size_t count)
 {
-	unsigned long regs;
-	unsigned long param;
+	unsigned long regs, param;
 	sscanf(buf, "%lx %lx", &regs, &param);
 
 	if (regs <= 0x2000) {
@@ -128,60 +128,55 @@
 static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write);
 	
 
-static ssize_t fastsysclk_show(struct device *dev, char *buf)
+static ssize_t fastpllclk_show(struct device *dev, char *buf)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct w100fb_par *par=info->par;
 
-	return sprintf(buf, "%d\n",par->fastsysclk_mode);
+	return sprintf(buf, "%d\n",par->fastpll_mode);
 }
 
-static ssize_t fastsysclk_store(struct device *dev, const char *buf, size_t count)
+static ssize_t fastpllclk_store(struct device *dev, const char *buf, size_t count)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct w100fb_par *par=info->par;
 
 	if (simple_strtoul(buf, NULL, 10) > 0) {
-		par->fastsysclk_mode=1;
+		par->fastpll_mode=1;
 		printk("w100fb: Using fast system clock (if possible)\n");
 	} else {
-		par->fastsysclk_mode=0;
+		par->fastpll_mode=0;
 		printk("w100fb: Using normal system clock\n");		
 	}
 
 	w100_init_clocks(par);
+	calc_hsync(par);
 
 	return count;
 }
 
-static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store);
+static DEVICE_ATTR(fastpllclk, 0644, fastpllclk_show, fastpllclk_store);
 
 /*
- * The touchscreen on this device needs certain information
- * from the video driver to function correctly. We export it here.
+ * Some touchscreens need hsync information from the video driver to 
+ * function correctly. We export it here.
  */
-int w100fb_get_xres(void) {
-	return current_par->xres;
-}
-
-int w100fb_get_blanking(void) {
-	return current_par->blanked;
-}
+unsigned long w100fb_get_hsynclen(struct device *dev)
+{
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
 
-int w100fb_get_fastsysclk(void) {
-	return (current_par->fastsysclk_mode ? 100 : 75);
+	/* If display is blanked/suspended, hsync isn't active */
+	if (par->blanked)
+		return 0;
+	else
+		return par->hsync_len;
 }
-EXPORT_SYMBOL(w100fb_get_xres);
-EXPORT_SYMBOL(w100fb_get_blanking);
-EXPORT_SYMBOL(w100fb_get_fastsysclk);
-
+EXPORT_SYMBOL(w100fb_get_hsynclen);
 
 static void w100fb_clear_screen(struct w100fb_par *par)
 {
-	unsigned int i;
-
-	for (i = 0; i < (par->xres * par->yres); i++)
-		writew(0x0000, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE) + (2*i));	
+	memset(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), 0, (par->xres * par->yres * BITS_PER_PIXEL/8));
 }
 
 
@@ -232,14 +227,14 @@
 	case FB_BLANK_HSYNC_SUSPEND:  /* VESA blank (hsync off) */
  	case FB_BLANK_POWERDOWN:      /* Poweroff */
   		if (par->blanked == 0) {
-			if(par->mach_info->tg) par->mach_info->tg->suspend(par);
+			if(par->mach->tg) par->mach->tg->suspend(par);
 			par->blanked = 1;
   		}
   		break;
 
  	case FB_BLANK_UNBLANK: /* Unblanking */
   		if (par->blanked != 0) {
-			if(par->mach_info->tg) par->mach_info->tg->resume(par);
+			if(par->mach->tg) par->mach->tg->resume(par);
 			par->blanked = 0;
   		}
   		break;
@@ -264,7 +259,9 @@
 	w100_set_dispregs(par);
 	w100_update_enable();
 
-	if (!par->blanked && par->mach_info->tg) par->mach_info->tg->change(par);
+	calc_hsync(par);
+
+	if (!par->blanked && par->mach->tg) par->mach->tg->change(par);
 }
 
 
@@ -275,11 +272,11 @@
 static struct w100_mode *w100fb_get_mode(struct w100fb_par *par, unsigned int *x, unsigned int *y, int saveval)
 {
 	struct w100_mode *mode = NULL;
-	struct w100_mode *modelist = par->mach_info->modelist;
+	struct w100_mode *modelist = par->mach->modelist;
 	unsigned int best_x = 0xffffffff, best_y = 0xffffffff;
 	unsigned int i;
 
-	for (i = 0 ; i < par->mach_info->num_modes ; i++) {
+	for (i = 0 ; i < par->mach->num_modes ; i++) {
 		if (modelist[i].xres >= *x && modelist[i].yres >= *y &&
 				modelist[i].xres < best_x && modelist[i].yres < best_y) {
 			best_x = modelist[i].xres;
@@ -314,10 +311,10 @@
 	if(!w100fb_get_mode(par, &var->xres, &var->yres, 1))
 		return -EINVAL;
 
-	if (par->mach_info->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach_info->mem->size+1)))
+	if (par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach->mem->size+1)))
 		return -EINVAL;
 	
-	if (!par->mach_info->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)))
+	if (!par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)))
 		return -EINVAL;
 
 	var->xres_virtual = max(var->xres_virtual, var->xres);
@@ -369,7 +366,7 @@
 
 		if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) {
 			par->extmem_active = 1;
-			info->fix.smem_len = par->mach_info->mem->size+1;
+			info->fix.smem_len = par->mach->mem->size+1;
 		} else {
 			par->extmem_active = 0;
 			info->fix.smem_len = MEM_INT_SIZE+1;
@@ -396,66 +393,43 @@
 	.fb_cursor    = soft_cursor,
 };
 
-/* Need to split up the buffers to stay within the limits of kmalloc */
-#define W100_BUF_NUM	6
-static uint32_t *gSaveImagePtr[W100_BUF_NUM] = { NULL };
-
-static void w100fb_clear_buffer(void)
-{
-	int i;
-	for (i = 0; i < W100_BUF_NUM; i++) {
-		if (gSaveImagePtr[i] != NULL) {
-			kfree(gSaveImagePtr[i]);
-			gSaveImagePtr[i] = NULL;
-		}
-	}
-}
+static uint32_t *saved_intmem;
+static uint32_t *saved_extmem;
 
-static void w100fb_save_buffer(struct w100fb_par *par)
+static void w100fb_save_vidmem(struct w100fb_par *par)
 {
-	int i, j, bufsize;
+	int memsize;
 	
-/*	Should probably save all of extmem and intmem here...
-	unsigned int memsize;
-
-	if (par->extmem_active)
-		memsize=par->mach_info->mem->size/2;
-	else
-		memsize=MEM_INT_SIZE/2;
-		
-	for (i = 0; i < memsize; i++)
-		writew(0xffff, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE) + (2*i));
-*/
-
-	bufsize=(par->xres * par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
-	for (i = 0; i < W100_BUF_NUM; i++) {
-		if (gSaveImagePtr[i] == NULL)
-			gSaveImagePtr[i] = kmalloc(bufsize, GFP_KERNEL);
-		if (gSaveImagePtr[i] == NULL) {
-			w100fb_clear_buffer();
-			printk(KERN_WARNING "can't alloc pre-off image buffer %d\n", i);
-			break;
-		}
-		for (j = 0; j < bufsize/4; j++)
-			*(gSaveImagePtr[i] + j) = readl(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE)+ (bufsize*i) + j*4);
-	}
+	if (par->extmem_active) {
+		memsize=par->mach->mem->size;
+		saved_extmem = vmalloc(memsize);
+		if (saved_extmem) 
+			memcpy(saved_extmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize);
+	}
+	memsize=MEM_INT_SIZE;
+	saved_intmem = vmalloc(memsize);
+	if (saved_intmem && par->extmem_active) 
+		memcpy(saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), memsize);
+	else if (saved_intmem) 
+		memcpy(saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize);
 }
-
-static void w100fb_restore_buffer(struct w100fb_par *par)
+		
+static void w100fb_restore_vidmem(struct w100fb_par *par)
 {
-	int i, j, bufsize;
-
-	bufsize=(par->xres * par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM;
-	for (i = 0; i < W100_BUF_NUM; i++) {
-		if (gSaveImagePtr[i] == NULL) {
-			printk(KERN_WARNING "can't find pre-off image buffer %d\n", i);
-			w100fb_clear_buffer();
-			break;
-		}
-		for (j = 0; j < (bufsize/4); j++)
-			writel(*(gSaveImagePtr[i] + j),remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE) + (bufsize*i) + (j*4));
-		kfree(gSaveImagePtr[i]);
-		gSaveImagePtr[i] = NULL;
+	int memsize;
+		
+	if (par->extmem_active && saved_extmem) {
+		memsize=par->mach->mem->size;
+		memcpy(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), saved_extmem, memsize);
+		vfree(saved_extmem);
+	}
+	if (saved_intmem) {
+		memsize=MEM_INT_SIZE;
+		if (par->extmem_active) 
+			memcpy(remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), saved_intmem, memsize);
+		else
+			memcpy(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), saved_intmem, memsize);
+		vfree(saved_intmem);
 	}
 }
 
@@ -467,8 +441,8 @@
 		struct fb_info *info = dev_get_drvdata(dev);
 		struct w100fb_par *par=info->par;
 
-		w100fb_save_buffer(par);
-		if(par->mach_info->tg) par->mach_info->tg->suspend(par);
+		w100fb_save_vidmem(par);
+		if(par->mach->tg) par->mach->tg->suspend(par);
 		w100_suspend(W100_SUSPEND_ALL);
 		par->blanked = 1;
 	}
@@ -483,8 +457,8 @@
 
 		w100_hw_init(par);
 		w100fb_activate_var(par);
-		w100fb_restore_buffer(par);
-		if(par->mach_info->tg) par->mach_info->tg->resume(par);
+		w100fb_restore_vidmem(par);
+		if(par->mach->tg) par->mach->tg->resume(par);
 		par->blanked = 0;
 	}
 	return 0;
@@ -497,7 +471,7 @@
 
 int __init w100fb_probe(struct device *dev)
 {
-	int err;
+	int err = -EIO;
 	struct w100fb_mach_info *inf;
 	struct fb_info *info = NULL;
 	struct w100fb_par *par;
@@ -510,19 +484,16 @@
 	/* Remap the areas we're going to use */
 	remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);
 	if (remapped_base == NULL) {
-		err = -EIO;
 		goto out;
 	}
 
 	remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);
 	if (remapped_regs == NULL) {
-		err = -EIO;
 		goto out;
 	}
 
 	remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE);
 	if (remapped_fbuf == NULL) {
-		err = -EIO;
 		goto out;
 	}
 
@@ -534,17 +505,16 @@
 
 	info->device=dev;
 	par = info->par;
-	current_par=info->par;
 	dev_set_drvdata(dev, info);
 
 	inf = dev->platform_data;
-	par->mach_info = inf;
-	par->fastsysclk_mode = 0;
+	par->mach = inf;
+	par->fastpll_mode = 0;
 	par->blanked = 0;
 	
 	par->pll_table=w100_get_xtal_table(inf->xtal_freq);
 	if (!par->pll_table) {
-		printk(KERN_ERR "Not matching Xtal definition found\n");
+		printk(KERN_ERR "No matching Xtal definition found\n");
 		err = -EINVAL;
 		goto out;
 	}
@@ -607,7 +577,7 @@
 		goto out;
 	}
 
-	device_create_file(dev, &dev_attr_fastsysclk);
+	device_create_file(dev, &dev_attr_fastpllclk);
 	device_create_file(dev, &dev_attr_reg_read);
 	device_create_file(dev, &dev_attr_reg_write);
 	device_create_file(dev, &dev_attr_flip);
@@ -632,14 +602,15 @@
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 
-	device_remove_file(dev, &dev_attr_fastsysclk);
+	device_remove_file(dev, &dev_attr_fastpllclk);
 	device_remove_file(dev, &dev_attr_reg_read);
 	device_remove_file(dev, &dev_attr_reg_write);
 	device_remove_file(dev, &dev_attr_flip);
 
 	unregister_framebuffer(info);
 
-	w100fb_clear_buffer();
+	vfree(saved_intmem);
+	vfree(saved_extmem);
 	kfree(info->pseudo_palette);
 
 	iounmap(remapped_base);
@@ -688,7 +659,7 @@
 
 unsigned long w100fb_gpio_read(int port)
 {
-	int value;
+	unsigned long value;
 	
 	if (port==W100_GPIO_PORT_A)
 		value = readl(remapped_regs + mmGPIO_DATA);
@@ -723,7 +694,7 @@
 	union cif_write_dbg_u cif_write_dbg;
 	union wrap_start_dir_u wrap_start_dir;
 	union cif_io_u cif_io;
-	struct w100_gpio_regs *gpio = par->mach_info->gpio;
+	struct w100_gpio_regs *gpio = par->mach->gpio;
 
 	w100_soft_reset();
 
@@ -812,36 +783,43 @@
 	union pll_cntl_u pll_cntl;
 	union sclk_cntl_u sclk_cntl;
 	union pclk_cntl_u pclk_cntl;
-	union clk_test_cntl_u clk_test_cntl;
 	union pwrmgt_cntl_u pwrmgt_cntl;
-	uint8_t auto_mode;  /* system clock auto changing? */
+	int auto_mode;  /* system clock auto changing? */
 };
 
 
 static struct power_state w100_pwr_state;
 
-/* 12.5MHz Crystal PLL Table */ 
+/* The PLL Fout is determined by (XtalFreq/(M+1)) * ((N_int+1) + (N_fac/8)) */
+
+/* 12.5MHz Crystal PLL Table */
 static struct w100_pll_info xtal_12500000[] = {
 	/*freq     M   N_int    N_fac  tfgoal  lock_time */
-	{ 50,      0,   1,       0,     0xE0,        56},  /*  50.00 MHz */
-	{ 75,      0,   5,       0,     0xDE,        37},  /*  75.00 MHz */
-	{100,      0,   7,       0,     0xE0,        28},  /* 100.00 MHz */
-	{125,      0,   9,       0,     0xE0,        22},  /* 125.00 MHz */
-	{150,      0,   11,      0,     0xE0,        17},  /* 150.00 MHz */
+	{ 50,      0,   1,       0,     0xe0,        56},  /*  50.00 MHz */
+	{ 75,      0,   5,       0,     0xde,        37},  /*  75.00 MHz */
+	{100,      0,   7,       0,     0xe0,        28},  /* 100.00 MHz */
+	{125,      0,   9,       0,     0xe0,        22},  /* 125.00 MHz */
+	{150,      0,   11,      0,     0xe0,        17},  /* 150.00 MHz */
 	{  0,      0,   0,       0,        0,         0},  /* Terminator */
 };
 
-/* 14.318MHz Crystal PLL Table */ 
+/* 14.318MHz Crystal PLL Table */
 static struct w100_pll_info xtal_14318000[] = {
 	/*freq     M   N_int    N_fac  tfgoal  lock_time */
-	{ 40,      4,   13,      0,     0xe0,        80},
-	{  0,      0,   0,       0,        0,         0},
+	{ 40,      4,   13,      0,     0xe0,        80}, /* tfgoal guessed	*/
+	{ 50,      1,   6,       0,     0xe0,	     64}, /*  50.05 MHz */
+	{ 57,      2,   11,      0,     0xe0,        53}, /* tfgoal guessed	*/
+	{ 75,      0,   4,       3,     0xe0,	     43}, /*  75.08 MHz */
+	{100,      0,   6,       0,     0xe0,        32}, /* 100.10 MHz */
+	{  0,      0,   0,       0,        0,         0},    
 };
 
-/* 16MHz Crystal PLL Table */ 
+/* 16MHz Crystal PLL Table */
 static struct w100_pll_info xtal_16000000[] = {
 	/*freq     M   N_int    N_fac  tfgoal  lock_time */
-	{ 95,      1,   10,      7,     0xe0,        38},
+	{ 72,      1,   8,       0,     0xe0,        48}, /* tfgoal guessed	*/
+	{ 95,      1,   10,      7,     0xe0,        38}, /* tfgoal guessed	*/
+	{ 96,      1,   11,      0,     0xe0,        36}, /* tfgoal guessed	*/
 	{  0,      0,   0,       0,        0,         0},
 };
 
@@ -869,51 +847,67 @@
 }
 
 
-static unsigned int w100_pll_get_testcount(unsigned int testclk_sel)
+static unsigned int w100_get_testcount(unsigned int testclk_sel)
 {
+	union clk_test_cntl_u clk_test_cntl;
+	
 	udelay(5);
 
-	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
-	w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel;
-	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1;  /*reset test count */
-	writel((uint32_t) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
-	w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0;
-	writel((uint32_t) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
-
-	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1;
-	writel((uint32_t) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+	/* Select the test clock source and reset */
+	clk_test_cntl.f.start_check_freq = 0x0;
+	clk_test_cntl.f.testclk_sel = testclk_sel;
+	clk_test_cntl.f.tstcount_rst = 0x1; /* set reset */
+	writel((uint32_t) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	clk_test_cntl.f.tstcount_rst = 0x0; /* clear reset */
+	writel((uint32_t) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+
+	/* Run clock test */
+	clk_test_cntl.f.start_check_freq = 0x1;
+	writel((uint32_t) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
 
+	/* Give the test time to complete */
 	udelay(20);
 
-	w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
-	w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0;
-	writel((uint32_t) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
+	/* Return the result */
+	clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL);
+	clk_test_cntl.f.start_check_freq = 0x0;
+	writel((uint32_t) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL);
 
-	return w100_pwr_state.clk_test_cntl.f.test_count;
+	return clk_test_cntl.f.test_count;
 }
 
 
 static int w100_pll_adjust(struct w100_pll_info *pll)
 {
-	uint8_t tf80;
-	uint8_t tf20;
+	unsigned int tf80;
+	unsigned int tf20;
+	
+	/* Initial Settings */
+	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0;     /* power down */
+	w100_pwr_state.pll_cntl.f.pll_reset = 0x0;    /* not reset */
+	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1;   /* Hi-Z */
+	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;      /* VCO gain = 0 */
+	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;    /* VCO frequency range control = off */
+	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;  /* current offset inside VCO = 0 */
+	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
 
 	/* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V
 	 * therefore, commented out the following lines
 	 * tf80 meant tf100
-	 * set VCO input = 0.8 * VDD
 	 */
 	do {
+		/* set VCO input = 0.8 * VDD */
 		w100_pwr_state.pll_cntl.f.pll_dactal = 0xd;
 		writel((uint32_t) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
 
-		tf80 = w100_pll_get_testcount(0x1);  /* PLLCLK */
+		tf80 = w100_get_testcount(TESTCLK_SRC_PLL);
 		if (tf80 >= (pll->tfgoal)) {
 			/* set VCO input = 0.2 * VDD */
 			w100_pwr_state.pll_cntl.f.pll_dactal = 0x7;
 			writel((uint32_t) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
 
-			tf20 = w100_pll_get_testcount(0x1);  /* PLLCLK */
+			tf20 = w100_get_testcount(TESTCLK_SRC_PLL);
 			if (tf20 <= (pll->tfgoal))
 				return 1;  /* Success */
 
@@ -924,20 +918,16 @@
 				w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1;
 				w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;
 				w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
-				writel((uint32_t) (w100_pwr_state.pll_cntl.val),
-					remapped_regs + mmPLL_CNTL);
 				continue;
 			}
 		}
 		if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) {
 			w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1;
-			writel((uint32_t) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
 		} else if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) {
 			w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;
 			w100_pwr_state.pll_cntl.f.pll_pvg += 0x1;
-			writel((uint32_t) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
 		} else {
-			return 0;  /* error */
+			return 0;  /* Error */
 		}
 	} while(1);
 }
@@ -950,16 +940,6 @@
 {
 	int status;
 
-	/* initial setting */
-	w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0;     /* power down */
-	w100_pwr_state.pll_cntl.f.pll_reset = 0x0;    /* not reset */
-	w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1;   /* Hi-Z */
-	w100_pwr_state.pll_cntl.f.pll_pvg = 0x0;      /* VCO gain = 0 */
-	w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0;    /* VCO frequency range control = off */
-	w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0;  /* current offset inside VCO = 0 */
-	w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0;
-	writel((uint32_t) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL);
-
 	status = w100_pll_adjust(pll);
 
 	/* PLL Reset And Lock */
@@ -997,7 +977,7 @@
 	}
 
 	/* Set system clock source to XTAL whilst adjusting the PLL! */
-	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;  /* crystal clock */
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL;
 	writel((uint32_t) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
 
 	w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = pll->M;
@@ -1021,7 +1001,7 @@
 }
 
 /* freq = target frequency of the PLL */
-static int w100_set_fastsysclk(struct w100fb_par *par, uint16_t freq)
+static int w100_set_pll_freq(struct w100fb_par *par, unsigned int freq)
 {
 	struct w100_pll_info *pll = par->pll_table;
 
@@ -1046,7 +1026,7 @@
 	w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0;
 	writel((uint32_t) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL);
 
-	w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0;        /* Crystal Clk */
+	w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL;
 	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0;  /* Pfast = 1 */
 	w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3;
 	w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0;  /* Pslow = 1 */
@@ -1066,7 +1046,7 @@
 	w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0;
 	writel((uint32_t) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL);
 
-	w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0;     /* Crystal Clk */
+	w100_pwr_state.pclk_cntl.f.pclk_src_sel = CLK_SRC_XTAL;
 	w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1;    /* P = 2 */
 	w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0;  /* Dynamic */
 	writel((uint32_t) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL);
@@ -1120,8 +1100,8 @@
 {
 	struct w100_mode *mode = par->mode;
 
-	if(mode->pixclk_src == CLK_SRC_PLL || mode->sysclk_src == CLK_SRC_PLL)
-		w100_set_fastsysclk(par, par->fastsysclk_mode ? mode->fast_pll_freq : mode->pll_freq);
+	if (mode->pixclk_src == CLK_SRC_PLL || mode->sysclk_src == CLK_SRC_PLL)
+		w100_set_pll_freq(par, (par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq);
 
 	w100_pwr_state.sclk_cntl.f.sclk_src_sel = mode->sysclk_src;
 	w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = mode->sysclk_divider;
@@ -1133,7 +1113,7 @@
 {
 	uint32_t temp32;
 	struct w100_mode *mode = par->mode;
-	struct w100_gen_regs *regs = par->mach_info->regs;
+	struct w100_gen_regs *regs = par->mach->regs;
 	union active_h_disp_u active_h_disp;
 	union active_v_disp_u active_v_disp;
 	union graphic_h_disp_u graphic_h_disp;
@@ -1193,7 +1173,7 @@
 {
 	union mc_ext_mem_location_u extmem_location;
 	union mc_fb_location_u intmem_location;
-	struct w100_mem_info *mem = par->mach_info->mem;
+	struct w100_mem_info *mem = par->mach->mem;
 
 	if (!par->extmem_active) {
 		w100_suspend(W100_SUSPEND_EXTMEM);
@@ -1216,7 +1196,7 @@
 
 		/* Map External Memory at FB Base */
 		extmem_location.f.mc_ext_mem_start = W100_FB_BASE >> 8;
-		extmem_location.f.mc_ext_mem_top = (W100_FB_BASE+par->mach_info->mem->size) >> 8;
+		extmem_location.f.mc_ext_mem_top = (W100_FB_BASE+par->mach->mem->size) >> 8;
 		writel((uint32_t) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION);
 			
 		writel(0x00007800, remapped_regs + mmMC_BIST_CTRL);
@@ -1301,6 +1281,27 @@
 }
 
 
+/* 
+ * Work out how long the sync pulse lasts 
+ * Value is 1/(time in seconds)
+ */
+static void calc_hsync(struct w100fb_par *par)
+{
+	unsigned long hsync;
+	struct w100_mode *mode = par->mode;
+	union crtc_ss_u crtc_ss;
+	
+	if (mode->pixclk_src == CLK_SRC_XTAL)
+		hsync=par->mach->xtal_freq;
+	else
+		hsync=((par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq)*100000;
+	
+	hsync /= (w100_pwr_state.pclk_cntl.f.pclk_post_div + 1);
+
+	crtc_ss.val = readl(remapped_regs + mmCRTC_SS);
+	par->hsync_len = hsync / (crtc_ss.f.ss_end-crtc_ss.f.ss_start);
+}
+
 static void w100_suspend(uint32_t mode)
 {
 	uint32_t val;
Index: linux/include/video/w100fb.h
===================================================================
--- linux.orig/include/video/w100fb.h	2005-03-18 17:40:30.000000000 +0000
+++ linux/include/video/w100fb.h	2005-03-19 23:11:30.000000000 +0000
@@ -18,19 +18,6 @@
 unsigned long w100fb_gpio_read(int port);
 void w100fb_gpio_write(int port, unsigned long value);
 
-/* General frame buffer data structures */
-struct w100fb_par {
-	unsigned int xres;
-	unsigned int yres;
-	unsigned int fastsysclk_mode;
-	unsigned int flip;
-	unsigned int blanked;
-	unsigned int extmem_active;
-	struct w100_mode *mode;
-	struct w100_pll_info *pll_table;
-	struct w100fb_mach_info *mach_info;
-};
-
 /* LCD Specific Routines and Config */
 struct w100_tg_info {
 	void (*change)(struct w100fb_par*);
@@ -127,3 +114,16 @@
 	unsigned int xtal_freq;
 };
 
+/* General frame buffer data structure */
+struct w100fb_par {
+	unsigned int xres;
+	unsigned int yres;
+	unsigned int extmem_active;
+	unsigned int flip;
+	unsigned int blanked;
+	unsigned int fastpll_mode;
+	unsigned long hsync_len;
+	struct w100_mode *mode;
+	struct w100_pll_info *pll_table;
+	struct w100fb_mach_info *mach;
+};
\ No newline at end of file
Index: linux/drivers/input/touchscreen/corgi_ts.c
===================================================================
--- linux.orig/drivers/input/touchscreen/corgi_ts.c	2005-03-18 17:40:26.000000000 +0000
+++ linux/drivers/input/touchscreen/corgi_ts.c	2005-03-19 23:03:22.000000000 +0000
@@ -56,9 +56,6 @@
 #define CCNT_ON()	{int pmnc = 1; asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(pmnc));}
 #define CCNT_OFF()	{int pmnc = 0; asm volatile ("mcr p14, 0, %0, C0, C0, 0" : : "r"(pmnc));}
 
-#define WAIT_HS_400_VGA		7013U	// 17.615us
-#define WAIT_HS_400_QVGA	16622U	// 41.750us
-
 
 /* ADS7846 Touch Screen Controller bit definitions */
 #define ADSCTRL_PD0		(1u << 0)	/* PD0 */
@@ -69,40 +66,22 @@
 #define ADSCTRL_STS		(1u << 7)	/* Start Bit */
 
 /* External Functions */
-extern int w100fb_get_xres(void);
-extern int w100fb_get_blanking(void);
-extern int w100fb_get_fastsysclk(void);
+extern unsigned long w100fb_get_hsynclen(struct device *dev);
 extern unsigned int get_clk_frequency_khz(int info);
 
 static unsigned long calc_waittime(void) 
 {
-	int w100fb_xres = w100fb_get_xres();
-	unsigned int waittime=0;
-
-	if (w100fb_xres == 480 || w100fb_xres == 640) {
-		waittime = WAIT_HS_400_VGA*get_clk_frequency_khz(0)/398131U;
-	
-		if (w100fb_get_fastsysclk() == 100) 
-			waittime=waittime*75/100;
-
-		if (w100fb_xres == 640)
-			waittime=waittime*3;
+	unsigned long hsync_len = w100fb_get_hsynclen(&corgifb_device.dev);
 
-		return waittime;
-	}
-		
-	return WAIT_HS_400_QVGA*get_clk_frequency_khz(0)/398131U;
+	return get_clk_frequency_khz(0)*1000/hsync_len;
 }
 
 static int sync_receive_data_send_cmd(int doRecive,int doSend,unsigned int address, unsigned long wait_time)
 {
 	int pos = 0;
 	unsigned long timer1=0,timer2;
-	int dosleep;
-
-	dosleep = !w100fb_get_blanking();
 
-	if (dosleep && doSend) {
+	if (wait_time && doSend) {
 		CCNT_ON();
 		/* polling HSync */
 		SyncHS();
@@ -119,7 +98,7 @@
 		corgi_ssp_ads7846_put(cmd);
 		corgi_ssp_ads7846_get();
 
-		if (dosleep) {
+		if (wait_time) {
 			/* Wait after HSync */
 			CCNT(timer2);
 			if ((timer2-timer1) > wait_time) {
@@ -134,7 +113,7 @@
 				CCNT(timer2);
 		}
 		corgi_ssp_ads7846_put(cmd);
-		if (dosleep)
+		if (wait_time)
 			CCNT_OFF();
 	}
 	return pos;

