diff -urN -X /home/jsimmons/dontdiff linus-2.6/Documentation/fb/neofb.txt fbdev-2.6/Documentation/fb/neofb.txt
--- linus-2.6/Documentation/fb/neofb.txt	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/Documentation/fb/neofb.txt	Thu Oct 16 14:07:38 2003
@@ -0,0 +1,27 @@
+the neofb framebuffer driver supports the following Neomagic chipsets:
+
+NM2070 MagicGraph 128
+NM2090 MagicGraph 128V
+NM2093 MagicGraph 128ZV
+NM2097 MagicGraph 128ZV+
+NM2160 MagicGraph 128XD
+NM2200 MagicGraph 256AV
+NM2230 MagicGraph 256AV+
+NM2360 MagicGraph 256ZX
+NM2380 MagicGraph 256XL+
+
+with the following options:
+
+disabled	Disable this driver's initialization.
+internal	Enable output on internal LCD Display.
+external	Enable output on external CRT.
+nostretch	Disable stretching of modes smaller than LCD.
+nopciburst	Disable PCI burst mode.
+libretto	Force Libretto 100/110 800x480 LCD.
+picturebook	Force Picturebook 1024x480 LCD.
+
+at the boot prompt:
+	video=neofb:picturebook
+
+as a module:
+	modprobe neofb picturebook=1
diff -urN -X /home/jsimmons/dontdiff linus-2.6/MAINTAINERS fbdev-2.6/MAINTAINERS
--- linus-2.6/MAINTAINERS	Thu Oct 16 14:07:44 2003
+++ fbdev-2.6/MAINTAINERS	Thu Oct 16 14:06:50 2003
@@ -722,6 +722,11 @@
 W:	http://sourceforge.net/projects/emu10k1/
 S:	Maintained
 
+EPSON 1355 FRAMEBUFFER DRIVER
+P:	Christopher Hoover
+M:	ch@murgatroid.com, ch@hpl.hp.com
+S:	Maintained
+
 ETHEREXPRESS-16 NETWORK DRIVER
 P:	Philip Blundell
 M:	Philip.Blundell@pobox.com
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Kconfig fbdev-2.6/drivers/video/Kconfig
--- linus-2.6/drivers/video/Kconfig	Thu Oct 16 14:13:27 2003
+++ fbdev-2.6/drivers/video/Kconfig	Thu Oct 16 14:13:29 2003
@@ -55,7 +55,7 @@
 
 config FB_PM2
 	tristate "Permedia2 support"
-	depends on FB && (AMIGA || PCI) && BROKEN
+	depends on FB && (AMIGA || PCI)
 	help
 	  This is the frame buffer device driver for the Permedia2 AGP frame
 	  buffer card from ASK, aka `Graphic Blaster Exxtreme'.  There is a
@@ -68,16 +68,9 @@
 	help
 	  Support the Permedia2 FIFOI disconnect feature (see CONFIG_FB_PM2).
 
-config FB_PM2_PCI
-	bool "generic Permedia2 PCI board support"
-	depends on FB_PM2 && PCI
-	help
-	  Say Y to enable support for Permedia2 AGP frame buffer card from
-	  3Dlabs (aka `Graphic Blaster Exxtreme') on the PCI bus.
-
 config FB_PM2_CVPPC
 	bool "Phase5 CVisionPPC/BVisionPPC support"
-	depends on FB_PM2 && AMIGA
+	depends on FB_PM2 && AMIGA && BROKEN
 	help
 	  Say Y to enable support for the Amiga Phase 5 CVisionPPC BVisionPPC
 	  framebuffer cards.  Phase 5 is no longer with us, alas.
@@ -266,6 +259,10 @@
 	  This is the frame buffer device driver for the Chips & Technologies
 	  65550 graphics chip in PowerBooks.
 
+config FB_ASILIANT
+	bool "Chips 69000 display support"
+	depends on FB && PCI
+
 config FB_IMSTT
 	bool "IMS Twin Turbo display support"
 	depends on FB && PCI
@@ -414,35 +411,15 @@
 	  messages. Most people will want to say N here. If unsure, you will
 	  also want to say N.
 
-config FB_E1355
+config FB_EPSON1355
 	bool "Epson 1355 framebuffer support"
-	depends on FB && SUPERH
+	depends on FB && (SUPERH || ARCH_CEIVA)
 	help
 	  Build in support for the SED1355 Epson Research Embedded RAMDAC
 	  LCD/CRT Controller (since redesignated as the S1D13505) as a
 	  framebuffer.  Product specs at
 	  <http://www.erd.epson.com/vdc/html/products.htm>.
 
-config E1355_REG_BASE
-	hex "Register Base Address"
-	depends on FB_E1355
-	default "a8000000"
-	help
-	  Epson SED1355/S1D13505 LCD/CRT controller register base address.
-	  See the manuals at
-	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
-	  discussion.
-
-config E1355_FB_BASE
-	hex "Framebuffer Base Address"
-	depends on FB_E1355
-	default "a8200000"
-	help
-	  Epson SED1355/S1D13505 LCD/CRT controller memory base address.  See
-	  the manuals at
-	  <http://www.erd.epson.com/vdc/html/contents/S1D13505.htm> for
-	  discussion.
-
 config FB_RIVA
 	tristate "nVidia Riva support"
 	depends on FB && PCI
@@ -685,6 +662,19 @@
 	  framebuffer device.  The ATI product support page for these boards
 	  is at <http://support.ati.com/products/pc/mach64/>.
 
+config FB_ATY_GENERIC_LCD
+	bool "Mach64 generic LCD support (EXPERIMENTAL)"
+	depends on FB_ATY_CT
+	help
+	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
+	  Rage XC, or Rage XL chipset.
+
+config FB_ATY_XL_INIT
+	bool "Rage XL No-BIOS Init support"
+	depends on FB_ATY_CT
+	help
+	  Say Y here to support booting a Rage XL without BIOS support.
+
 config FB_ATY_GX
 	bool "Mach64 GX support" if PCI
 	depends on FB_ATY
@@ -696,33 +686,41 @@
 	  is at
 	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
 
-config FB_ATY_XL_INIT
-	bool "  Rage XL No-BIOS Init support" if FB_ATY_CT
-	depends on FB_ATY
-	help
-	  Say Y here to support booting a Rage XL without BIOS support.
-
 config FB_SIS
-	tristate "SIS acceleration"
+	tristate "SiS acceleration"
 	depends on FB && PCI
 	help
-	  This is the frame buffer device driver for the SiS 630 and 640 Super
-	  Socket 7 UMA cards.  Specs available at <http://www.sis.com.tw/>.
+	  This is the frame buffer device driver for the SiS 300, 315 and Xabre
+	  series VGA controller.
+
+	  Specs available at <http://www.sis.com.tw/>.
+
+	  See <http://www.winischhofer.net/linuxsisvga.shtml> for
+	  documentation and updates.
+
+	  The driver is also available as a module ( = code which can be
+	  inserted and removed from the running kernel whenever you want). The
+	  module will be called sisfb. If you want to compile it as a
+	  module, say M here and read Documentation/modules.txt.
 
 config FB_SIS_300
-	bool "SIS 630/540/730 support"
+	bool "SIS 300 series support"
 	depends on FB_SIS
 	help
-	  This is the frame buffer device driver for the SiS 630 and related
-	  Super Socket 7 UMA cards.  Specs available at
-	  <http://www.sis.com.tw/>.
+	  This is the frame buffer device driver for the SiS 300 series VGA
+	  controllers. This includes the 300, 540, 630, 730.
+	  Documentation and updates available at
+	  http://www.winischhofer.net/linuxsisvga.shtml
 
 config FB_SIS_315
-	bool "SIS 315H/315 support"
+	bool "SIS 315/Xabre support"
 	depends on FB_SIS
 	help
-	  This is the frame buffer device driver for the SiS 315 graphics
-	  card.  Specs available at <http://www.sis.com.tw/>.
+	  This is the frame buffer device driver for the SiS 315 and Xabre
+	  series VGA controllers. This includes the 315, 315H, 315PRO, 650,
+	  651, M650, 652, M652, 740, 330 (Xabre), 660, M660, 760, M760.
+	  Documentation and updates available at
+	  http://www.winischhofer.net/linuxsisvga.shtml
 
 config FB_NEOMAGIC
 	tristate "NeoMagic display support"
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/Makefile fbdev-2.6/drivers/video/Makefile
--- linus-2.6/drivers/video/Makefile	Thu Oct 16 14:13:28 2003
+++ fbdev-2.6/drivers/video/Makefile	Wed Oct 15 16:50:03 2003
@@ -15,14 +15,13 @@
 
 obj-$(CONFIG_FB_ACORN)            += acornfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p.o
-obj-$(CONFIG_FB_PM2)              += pm2fb.o
+obj-$(CONFIG_FB_PM2)              += pm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PM3)		  += pm3fb.o
 obj-$(CONFIG_FB_APOLLO)           += dnfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_Q40)              += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_ATARI)            += atafb.o
 obj-$(CONFIG_FB_68328)            += 68328fb.o
-obj-$(CONFIG_FB_RADEON)		  += radeonfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o vgastate.o
 obj-$(CONFIG_FB_IGA)              += igafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_CONTROL)          += controlfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
@@ -33,7 +32,7 @@
 obj-$(CONFIG_FB_CYBER)            += cyberfb.o
 obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_3DFX)             += tdfxfb.o cfbimgblt.o
+obj-$(CONFIG_FB_3DFX)             += tdfxfb.o
 obj-$(CONFIG_FB_MAC)              += macfb.o macmodes.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HP300)            += hpfb.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_OF)               += offb.o cfbfillrect.o cfbimgblt.o cfbcopyarea.o
@@ -60,6 +59,7 @@
 obj-$(CONFIG_FB_SIS)		  += sis/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_ATY)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_ATY128)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
+obj-$(CONFIG_FB_RADEON)		  += aty/ cfbcopyarea.o cfbfillrect.o cfbimgblt.o
 obj-$(CONFIG_FB_I810)             += i810/ cfbfillrect.o cfbcopyarea.o \
 	                             cfbimgblt.o vgastate.o
 
@@ -68,9 +68,10 @@
 obj-$(CONFIG_FB_SA1100)           += sa1100fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o 
 obj-$(CONFIG_FB_HIT)              += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
-obj-$(CONFIG_FB_E1355)            += epson1355fb.o
-obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_EPSON1355)        += epson1355fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_PVR2)             += pvr2fb.o cfbcillrect.o cfbcopyarea.o cfbimgblt.o
 obj-$(CONFIG_FB_VOODOO1)          += sstfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
+obj-$(CONFIG_FB_ASILIANT)         += asiliantfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
 
 obj-$(CONFIG_FB_FFB)               += ffb.o sbuslib.o cfbimgblt.o cfbcopyarea.o
 obj-$(CONFIG_FB_CG6)               += cg6.o sbuslib.o cfbimgblt.o cfbcopyarea.o
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/acornfb.c fbdev-2.6/drivers/video/acornfb.c
--- linus-2.6/drivers/video/acornfb.c	Thu Oct 16 14:13:29 2003
+++ fbdev-2.6/drivers/video/acornfb.c	Thu Oct 16 14:13:30 2003
@@ -1287,7 +1287,6 @@
 		}
 	}
 
-	fb_info.currcon	       = -1;
 	fb_info.screen_base    = (char *)SCREEN_BASE;
 	fb_info.fix.smem_start = SCREEN_START;
 	current_par.using_vram = 0;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/asiliantfb.c fbdev-2.6/drivers/video/asiliantfb.c
--- linus-2.6/drivers/video/asiliantfb.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/asiliantfb.c	Thu Oct 16 14:13:30 2003
@@ -0,0 +1,619 @@
+/*
+ * drivers/video/asiliantfb.c
+ *  frame buffer driver for Asiliant 69000 chip
+ *  Copyright (C) 2001-2003 Saito.K & Jeanne
+ *
+ *  from driver/video/chipsfb.c and,
+ *
+ *  drivers/video/asiliantfb.c -- frame buffer device for
+ *  Asiliant 69030 chip (formerly Intel, formerly Chips & Technologies)
+ *  Author: apc@agelectronics.co.uk
+ *  Copyright (C) 2000 AG Electronics
+ *  Note: the data sheets don't seem to be available from Asiliant.
+ *  They are available by searching developer.intel.com, but are not otherwise
+ *  linked to.
+ *
+ *  This driver should be portable with minimal effort to the 69000 display
+ *  chip, and to the twin-display mode of the 69030.
+ *  Contains code from Thomas Hhenleitner <th@visuelle-maschinen.de> (thanks)
+ *
+ *  Derived from the CT65550 driver chipsfb.c:
+ *  Copyright (C) 1998 Paul Mackerras
+ *  ...which was derived from the Powermac "chips" driver:
+ *  Copyright (C) 1997 Fabio Riccardi.
+ *  And from the frame buffer device for Open Firmware-initialized devices:
+ *  Copyright (C) 1997 Geert Uytterhoeven.
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+static struct fb_info asiliantfb_info;
+
+/* Built in clock of the 69030 */
+const unsigned Fref = 14318180;
+
+static u32 pseudo_palette[17];
+
+#define mmio_base (p->screen_base + 0x400000)
+
+#define mm_write_ind(num, val, ap, dp)	do { \
+	writeb((num), mmio_base + (ap)); writeb((val), mmio_base + (dp)); \
+} while (0)
+
+static void mm_write_xr(struct fb_info *p, u8 reg, u8 data)
+{
+	mm_write_ind(reg, data, 0x7ac, 0x7ad);
+}
+#define write_xr(num, val)	mm_write_xr(p, num, val)
+
+static void mm_write_fr(struct fb_info *p, u8 reg, u8 data)
+{
+	mm_write_ind(reg, data, 0x7a0, 0x7a1);
+}
+#define write_fr(num, val)	mm_write_fr(p, num, val)
+
+static void mm_write_cr(struct fb_info *p, u8 reg, u8 data)
+{
+	mm_write_ind(reg, data, 0x7a8, 0x7a9);
+}
+#define write_cr(num, val)	mm_write_cr(p, num, val)
+
+static void mm_write_gr(struct fb_info *p, u8 reg, u8 data)
+{
+	mm_write_ind(reg, data, 0x79c, 0x79d);
+}
+#define write_gr(num, val)	mm_write_gr(p, num, val)
+
+static void mm_write_sr(struct fb_info *p, u8 reg, u8 data)
+{
+	mm_write_ind(reg, data, 0x788, 0x789);
+}
+#define write_sr(num, val)	mm_write_sr(p, num, val)
+
+static void mm_write_ar(struct fb_info *p, u8 reg, u8 data)
+{
+	readb(mmio_base + 0x7b4);
+	mm_write_ind(reg, data, 0x780, 0x780);
+}
+#define write_ar(num, val)	mm_write_ar(p, num, val)
+
+/*
+ * Exported functions
+ */
+int asiliantfb_init(void);
+
+static int asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
+static int asiliantfb_check_var(struct fb_var_screeninfo *var,
+				struct fb_info *info);
+static int asiliantfb_set_par(struct fb_info *info);
+static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+				u_int transp, struct fb_info *info);
+
+static struct fb_ops asiliantfb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= asiliantfb_check_var,
+	.fb_set_par	= asiliantfb_set_par,
+	.fb_setcolreg	= asiliantfb_setcolreg,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+};
+
+/* Calculate the ratios for the dot clocks without using a single long long
+ * value */
+static void asiliant_calc_dclk2(u32 *ppixclock, u8 *dclk2_m, u8 *dclk2_n, u8 *dclk2_div)
+{
+	unsigned pixclock = *ppixclock;
+	unsigned Ftarget = 1000000 * (1000000 / pixclock);
+	unsigned n;
+	unsigned best_error = 0xffffffff;
+	unsigned best_m = 0xffffffff,
+	         best_n = 0xffffffff;
+	unsigned ratio;
+	unsigned remainder;
+	unsigned char divisor = 0;
+
+	/* Calculate the frequency required. This is hard enough. */
+	ratio = 1000000 / pixclock;
+	remainder = 1000000 % pixclock;
+	Ftarget = 1000000 * ratio + (1000000 * remainder) / pixclock;
+
+	while (Ftarget < 100000000) {
+		divisor += 0x10;
+		Ftarget <<= 1;
+	}
+
+	ratio = Ftarget / Fref;
+	remainder = Ftarget % Fref;
+
+	/* This expresses the constraint that 150kHz <= Fref/n <= 5Mhz,
+	 * together with 3 <= n <= 257. */
+	for (n = 3; n <= 257; n++) {
+		unsigned m = n * ratio + (n * remainder) / Fref;
+
+		/* 3 <= m <= 257 */
+		if (m >= 3 && m <= 257) {
+			unsigned new_error = ((Ftarget * n) - (Fref * m)) >= 0 ?
+					       ((Ftarget * n) - (Fref * m)) : ((Fref * m) - (Ftarget * n));
+			if (new_error < best_error) {
+				best_n = n;
+				best_m = m;
+				best_error = new_error;
+			}
+		}
+		/* But if VLD = 4, then 4m <= 1028 */
+		else if (m <= 1028) {
+			/* remember there are still only 8-bits of precision in m, so
+			 * avoid over-optimistic error calculations */
+			unsigned new_error = ((Ftarget * n) - (Fref * (m & ~3))) >= 0 ?
+					       ((Ftarget * n) - (Fref * (m & ~3))) : ((Fref * (m & ~3)) - (Ftarget * n));
+			if (new_error < best_error) {
+				best_n = n;
+				best_m = m;
+				best_error = new_error;
+			}
+		}
+	}
+	if (best_m > 257)
+		best_m >>= 2;	/* divide m by 4, and leave VCO loop divide at 4 */
+	else
+		divisor |= 4;	/* or set VCO loop divide to 1 */
+	*dclk2_m = best_m - 2;
+	*dclk2_n = best_n - 2;
+	*dclk2_div = divisor;
+	*ppixclock = pixclock;
+	return;
+}
+
+static void asiliant_set_timing(struct fb_info *p)
+{
+	unsigned hd = p->var.xres / 8;
+	unsigned hs = (p->var.xres + p->var.right_margin) / 8;
+       	unsigned he = (p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
+	unsigned ht = (p->var.left_margin + p->var.xres + p->var.right_margin + p->var.hsync_len) / 8;
+	unsigned vd = p->var.yres;
+	unsigned vs = p->var.yres + p->var.lower_margin;
+	unsigned ve = p->var.yres + p->var.lower_margin + p->var.vsync_len;
+	unsigned vt = p->var.upper_margin + p->var.yres + p->var.lower_margin + p->var.vsync_len;
+	unsigned wd = (p->var.xres_virtual * ((p->var.bits_per_pixel+7)/8)) / 8;
+
+	if ((p->var.xres == 640) && (p->var.yres == 480) && (p->var.pixclock == 39722)) {
+	  write_fr(0x01, 0x02);  /* LCD */
+	} else {
+	  write_fr(0x01, 0x01);  /* CRT */
+	}
+
+	write_cr(0x11, (ve - 1) & 0x0f);
+	write_cr(0x00, (ht - 5) & 0xff);
+	write_cr(0x01, hd - 1);
+	write_cr(0x02, hd);
+	write_cr(0x03, ((ht - 1) & 0x1f) | 0x80);
+	write_cr(0x04, hs);
+	write_cr(0x05, (((ht - 1) & 0x20) <<2) | (he & 0x1f));
+	write_cr(0x3c, (ht - 1) & 0xc0);
+	write_cr(0x06, (vt - 2) & 0xff);
+	write_cr(0x30, (vt - 2) >> 8);
+	write_cr(0x07, 0x00);
+	write_cr(0x08, 0x00);
+	write_cr(0x09, 0x00);
+	write_cr(0x10, (vs - 1) & 0xff);
+	write_cr(0x32, ((vs - 1) >> 8) & 0xf);
+	write_cr(0x11, ((ve - 1) & 0x0f) | 0x80);
+	write_cr(0x12, (vd - 1) & 0xff);
+	write_cr(0x31, ((vd - 1) & 0xf00) >> 8);
+	write_cr(0x13, wd & 0xff);
+	write_cr(0x41, (wd & 0xf00) >> 8);
+	write_cr(0x15, (vs - 1) & 0xff);
+	write_cr(0x33, ((vs - 1) >> 8) & 0xf);
+	write_cr(0x38, ((ht - 5) & 0x100) >> 8);
+	write_cr(0x16, (vt - 1) & 0xff);
+	write_cr(0x18, 0x00);
+
+	if (p->var.xres == 640) {
+	  writeb(0xc7, mmio_base + 0x784);	/* set misc output reg */
+	} else {
+	  writeb(0x07, mmio_base + 0x784);	/* set misc output reg */
+	}
+}
+
+static int asiliantfb_check_var(struct fb_var_screeninfo *var,
+			     struct fb_info *p)
+{
+	unsigned long Ftarget, ratio, remainder;
+
+	ratio = 1000000 / var->pixclock;
+	remainder = 1000000 % var->pixclock;
+	Ftarget = 1000000 * ratio + (1000000 * remainder) / var->pixclock;
+
+	/* First check the constraint that the maximum post-VCO divisor is 32,
+	 * and the maximum Fvco is 220MHz */
+	if (Ftarget > 220000000 || Ftarget < 3125000) {
+		printk(KERN_ERR "asiliantfb dotclock must be between 3.125 and 220MHz\n");
+		return -ENXIO;
+	}
+	var->xres_virtual = var->xres;
+	var->yres_virtual = var->yres;
+
+	if (var->bits_per_pixel == 24) {
+		var->red.offset = 16;
+		var->green.offset = 8;
+		var->blue.offset = 0;
+		var->red.length = var->blue.length = var->green.length = 8;
+	} else if (var->bits_per_pixel == 16) {
+		switch (var->red.offset) {
+			case 11:
+				var->green.length = 6;
+				break;
+			case 10:
+				var->green.length = 5;
+				break;
+			default:
+				return -EINVAL;
+		}
+		var->green.offset = 5;
+		var->blue.offset = 0;
+		var->red.length = var->blue.length = 5;
+	} else if (var->bits_per_pixel == 8) {
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = 8;
+	}
+	return 0;
+}
+
+static int asiliantfb_set_par(struct fb_info *p)
+{
+	u8 dclk2_m;		/* Holds m-2 value for register */
+	u8 dclk2_n;		/* Holds n-2 value for register */
+	u8 dclk2_div;		/* Holds divisor bitmask */
+
+	/* Set pixclock */
+	asiliant_calc_dclk2(&p->var.pixclock, &dclk2_m, &dclk2_n, &dclk2_div);
+
+	/* Set color depth */
+	if (p->var.bits_per_pixel == 24) {
+		write_xr(0x81, 0x16);	/* 24 bit packed color mode */
+		write_xr(0x82, 0x00);	/* Disable palettes */
+		write_xr(0x20, 0x20);	/* 24 bit blitter mode */
+	} else if (p->var.bits_per_pixel == 16) {
+		if (p->var.red.offset == 11)
+			write_xr(0x81, 0x15);	/* 16 bit color mode */
+		else
+			write_xr(0x81, 0x14);	/* 15 bit color mode */
+		write_xr(0x82, 0x00);	/* Disable palettes */
+		write_xr(0x20, 0x10);	/* 16 bit blitter mode */
+	} else if (p->var.bits_per_pixel == 8) {
+		write_xr(0x0a, 0x02);	/* Linear */
+		write_xr(0x81, 0x12);	/* 8 bit color mode */
+		write_xr(0x82, 0x00);	/* Graphics gamma enable */
+		write_xr(0x20, 0x00);	/* 8 bit blitter mode */
+	}
+	p->fix.line_length = p->var.xres * (p->var.bits_per_pixel >> 3);
+	p->fix.visual = (p->var.bits_per_pixel == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	write_xr(0xc4, dclk2_m);
+	write_xr(0xc5, dclk2_n);
+	write_xr(0xc7, dclk2_div);
+	/* Set up the CR registers */
+	asiliant_set_timing(p);
+	return 0;
+}
+
+static int asiliantfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+			     u_int transp, struct fb_info *p)
+{
+	if (regno > 255)
+		return 1;
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+
+        /* Set hardware palete */
+	writeb(regno, mmio_base + 0x790);
+	udelay(1);
+	writeb(red, mmio_base + 0x791);
+	writeb(green, mmio_base + 0x791);
+	writeb(blue, mmio_base + 0x791);
+
+	switch(p->var.bits_per_pixel) {
+	case 15:
+		if (regno < 16) {
+			((u32 *)(p->pseudo_palette))[regno] =
+				((red & 0xf8) << 7) |
+				((green & 0xf8) << 2) |
+				((blue & 0xf8) >> 3);
+		}
+		break;
+	case 16:
+		if (regno < 16) {
+			((u32 *)(p->pseudo_palette))[regno] =
+				((red & 0xf8) << 8) |
+				((green & 0xfc) << 3) |
+				((blue & 0xf8) >> 3);
+		}
+		break;
+	case 24:
+		if (regno < 24) {
+			((u32 *)(p->pseudo_palette))[regno] =
+				(red << 16)  |
+				(green << 8) |
+				(blue);
+		}
+		break;
+	}
+	return 0;
+}
+
+struct chips_init_reg {
+	unsigned char addr;
+	unsigned char data;
+};
+
+#define N_ELTS(x)	(sizeof(x) / sizeof(x[0]))
+
+static struct chips_init_reg chips_init_sr[] =
+{
+	{0x00, 0x03},		/* Reset register */
+	{0x01, 0x01},		/* Clocking mode */
+	{0x02, 0x0f},		/* Plane mask */
+	{0x04, 0x0e}		/* Memory mode */
+};
+
+static struct chips_init_reg chips_init_gr[] =
+{
+        {0x03, 0x00},		/* Data rotate */
+	{0x05, 0x00},		/* Graphics mode */
+	{0x06, 0x01},		/* Miscellaneous */
+	{0x08, 0x00}		/* Bit mask */
+};
+
+static struct chips_init_reg chips_init_ar[] =
+{
+	{0x10, 0x01},		/* Mode control */
+	{0x11, 0x00},		/* Overscan */
+	{0x12, 0x0f},		/* Memory plane enable */
+	{0x13, 0x00}		/* Horizontal pixel panning */
+};
+
+static struct chips_init_reg chips_init_cr[] =
+{
+	{0x0c, 0x00},		/* Start address high */
+	{0x0d, 0x00},		/* Start address low */
+	{0x40, 0x00},		/* Extended Start Address */
+	{0x41, 0x00},		/* Extended Start Address */
+	{0x14, 0x00},		/* Underline location */
+	{0x17, 0xe3},		/* CRT mode control */
+	{0x70, 0x00}		/* Interlace control */
+};
+
+
+static struct chips_init_reg chips_init_fr[] =
+{
+	{0x01, 0x02},
+	{0x03, 0x08},
+	{0x08, 0xcc},
+	{0x0a, 0x08},
+	{0x18, 0x00},
+	{0x1e, 0x80},
+	{0x40, 0x83},
+	{0x41, 0x00},
+	{0x48, 0x13},
+	{0x4d, 0x60},
+	{0x4e, 0x0f},
+
+	{0x0b, 0x01},
+
+	{0x21, 0x51},
+	{0x22, 0x1d},
+	{0x23, 0x5f},
+	{0x20, 0x4f},
+	{0x34, 0x00},
+	{0x24, 0x51},
+	{0x25, 0x00},
+	{0x27, 0x0b},
+	{0x26, 0x00},
+	{0x37, 0x80},
+	{0x33, 0x0b},
+	{0x35, 0x11},
+	{0x36, 0x02},
+	{0x31, 0xea},
+	{0x32, 0x0c},
+	{0x30, 0xdf},
+	{0x10, 0x0c},
+	{0x11, 0xe0},
+	{0x12, 0x50},
+	{0x13, 0x00},
+	{0x16, 0x03},
+	{0x17, 0xbd},
+	{0x1a, 0x00},
+};
+
+
+static struct chips_init_reg chips_init_xr[] =
+{
+	{0xce, 0x00},		/* set default memory clock */
+	{0xcc, 200 },	        /* MCLK ratio M */
+	{0xcd, 18  },	        /* MCLK ratio N */
+	{0xce, 0x90},		/* MCLK divisor = 2 */
+
+	{0xc4, 209 },
+	{0xc5, 118 },
+	{0xc7, 32  },
+	{0xcf, 0x06},
+	{0x09, 0x01},		/* IO Control - CRT controller extensions */
+	{0x0a, 0x02},		/* Frame buffer mapping */
+	{0x0b, 0x01},		/* PCI burst write */
+	{0x40, 0x03},		/* Memory access control */
+	{0x80, 0x82},		/* Pixel pipeline configuration 0 */
+	{0x81, 0x12},		/* Pixel pipeline configuration 1 */
+	{0x82, 0x08},		/* Pixel pipeline configuration 2 */
+
+	{0xd0, 0x0f},
+	{0xd1, 0x01},
+};
+
+static void __init chips_hw_init(struct fb_info *p)
+{
+	int i;
+
+	for (i = 0; i < N_ELTS(chips_init_xr); ++i)
+		write_xr(chips_init_xr[i].addr, chips_init_xr[i].data);
+	write_xr(0x81, 0x12);
+	write_xr(0x82, 0x08);
+	write_xr(0x20, 0x00);
+	for (i = 0; i < N_ELTS(chips_init_sr); ++i)
+		write_sr(chips_init_sr[i].addr, chips_init_sr[i].data);
+	for (i = 0; i < N_ELTS(chips_init_gr); ++i)
+		write_gr(chips_init_gr[i].addr, chips_init_gr[i].data);
+	for (i = 0; i < N_ELTS(chips_init_ar); ++i)
+		write_ar(chips_init_ar[i].addr, chips_init_ar[i].data);
+	/* Enable video output in attribute index register */
+	writeb(0x20, mmio_base + 0x780);
+	for (i = 0; i < N_ELTS(chips_init_cr); ++i)
+		write_cr(chips_init_cr[i].addr, chips_init_cr[i].data);
+	for (i = 0; i < N_ELTS(chips_init_fr); ++i)
+		write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
+}
+
+static struct fb_fix_screeninfo asiliantfb_fix __initdata = {
+	.id =		"Asiliant 69000",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_PSEUDOCOLOR,
+	.accel =	FB_ACCEL_NONE,
+	.line_length =	640,
+	.smem_len =	0x200000,	/* 2MB */
+};
+
+static struct fb_var_screeninfo asiliantfb_var __initdata = {
+	.xres 		= 640,
+	.yres 		= 480,
+	.xres_virtual 	= 640,
+	.yres_virtual 	= 480,
+	.bits_per_pixel = 8,
+	.red 		= { .length = 8 },
+	.green 		= { .length = 8 },
+	.blue 		= { .length = 8 },
+	.height 	= -1,
+	.width 		= -1,
+	.vmode 		= FB_VMODE_NONINTERLACED,
+	.pixclock 	= 39722,
+	.left_margin 	= 48,
+	.right_margin 	= 16,
+	.upper_margin 	= 33,
+	.lower_margin 	= 10,
+	.hsync_len 	= 96,
+	.vsync_len 	= 2,
+};
+
+static void __init init_asiliant(struct fb_info *p, unsigned long addr)
+{
+	p->fix			= asiliantfb_fix;
+	p->fix.smem_start	= addr;
+	p->var			= asiliantfb_var;
+	p->fbops		= &asiliantfb_ops;
+	p->pseudo_palette	= pseudo_palette;
+	p->flags		= FBINFO_FLAG_DEFAULT;
+
+	fb_alloc_cmap(&p->cmap, 256, 0);
+
+	if (register_framebuffer(p) < 0) {
+		printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
+		return;
+	}
+
+	printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
+		p->node, p->fix.smem_len / 1024);
+
+	writeb(0xff, mmio_base + 0x78c);
+	chips_hw_init(p);
+}
+
+static int __devinit
+asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
+{
+	struct fb_info *p = &asiliantfb_info;
+	unsigned long addr, size;
+
+	if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
+		return -ENODEV;
+	addr = pci_resource_start(dp, 0);
+	size = pci_resource_len(dp, 0);
+	if (addr == 0)
+		return -ENODEV;
+	if (p->screen_base != 0)
+		return -EBUSY;
+	if (!request_mem_region(addr, size, "asiliantfb"))
+		return -EBUSY;
+
+	p->screen_base = ioremap(addr, 0x800000);
+	if (p->screen_base == NULL) {
+		release_mem_region(addr, size);
+		return -ENOMEM;
+	}
+
+	pci_write_config_dword(dp, 4, 0x02800083);
+	writeb(3, addr + 0x400784);
+
+	init_asiliant(p, addr);
+
+	/* Clear the entire framebuffer */
+	memset(p->screen_base, 0, 0x200000);
+
+	pci_set_drvdata(dp, p);
+	return 0;
+}
+
+static void __devexit asiliantfb_remove(struct pci_dev *dp)
+{
+	struct fb_info *p = pci_get_drvdata(dp);
+
+	if (p != &asiliantfb_info || p->screen_base == NULL)
+		return;
+	unregister_framebuffer(p);
+	iounmap(p->screen_base);
+	p->screen_base = NULL;
+	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
+}
+
+static struct pci_device_id asiliantfb_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000, PCI_ANY_ID, PCI_ANY_ID },
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, asiliantfb_pci_tbl);
+
+static struct pci_driver asiliantfb_driver = {
+	.name =		"asiliantfb",
+	.id_table =	asiliantfb_pci_tbl,
+	.probe =	asiliantfb_pci_init,
+	.remove =	__devexit_p(asiliantfb_remove),
+};
+
+int __init asiliantfb_init(void)
+{
+	return pci_module_init(&asiliantfb_driver);
+}
+
+static void __exit asiliantfb_exit(void)
+{
+	pci_unregister_driver(&asiliantfb_driver);
+}
+
+MODULE_LICENSE("GPL");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/Makefile fbdev-2.6/drivers/video/aty/Makefile
--- linus-2.6/drivers/video/aty/Makefile	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/aty/Makefile	Wed Oct 15 17:31:13 2003
@@ -1,7 +1,11 @@
 obj-$(CONFIG_FB_ATY) += atyfb.o
 obj-$(CONFIG_FB_ATY128) += aty128fb.o
+obj-$(CONFIG_FB_RADEON) += radeonfb.o
 
 atyfb-y				:= atyfb_base.o mach64_accel.o
 atyfb-$(CONFIG_FB_ATY_GX)	+= mach64_gx.o
 atyfb-$(CONFIG_FB_ATY_CT)	+= mach64_ct.o mach64_cursor.o
-atyfb-objs			:= $(atyfb-y)
+
+radeonfb-y                    	:= radeon_base.o radeon_pm.o radeon_monitor.o
+radeonfb-$(CONFIG_FB_RADEON_I2C)      += radeon_i2c.o
+radeonfb-objs                 	:= $(radeonfb-y)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/aty128fb.c fbdev-2.6/drivers/video/aty/aty128fb.c
--- linus-2.6/drivers/video/aty/aty128fb.c	Thu Oct 16 14:13:34 2003
+++ fbdev-2.6/drivers/video/aty/aty128fb.c	Thu Oct 16 14:13:34 2003
@@ -24,6 +24,10 @@
  *		  Paul Mundt 
  *		  	- PCI hotplug
  *
+ *		  Jon Smirl <jonsmirl@yahoo.com>
+ * 			- PCI ID update
+ * 			- replace ROM BIOS search
+ *
  *  Based off of Geert's atyfb.c and vfb.c.
  *
  *  TODO:
@@ -43,6 +47,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/string.h>
@@ -136,8 +141,25 @@
 /* Chip generations */
 enum {
 	rage_128,
+	rage_128_pci,
 	rage_128_pro,
-	rage_M3
+	rage_128_pro_pci,
+	rage_M3,
+	rage_M3_pci,
+	rage_M4,
+	rage_128_ultra,
+};
+
+/* Must match above enum */
+static const char *r128_family[] __devinitdata = {
+	"AGP",
+	"PCI",
+	"PRO AGP",
+	"PRO PCI",
+	"M3 AGP",
+	"M3 PCI",
+	"M4 AGP",
+	"Ultra AGP",
 };
 
 /*
@@ -149,32 +171,100 @@
 
 /* supported Rage128 chipsets */
 static struct pci_device_id aty128_pci_tbl[] = {
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RI,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_Rage128_PD,
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_MF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_ML,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M4 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PA,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PB,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PC,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PD,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PE,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PF,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PG,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PH,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PI,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PJ,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PM,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PN,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PO,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
 	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PP,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PQ,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PS,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U3,
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PT,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_U1,
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PU,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LE,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
-	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_LF,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_M3 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PV,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PW,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_PX,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pro },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RG,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_RL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_pci },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SG,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SH,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SK,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SM,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_SN,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128 },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TF,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TL,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TR,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TS,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TT,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RAGE128_TU,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, rage_128_ultra },
 	{ 0, }
 };
 
@@ -250,14 +340,7 @@
 	.accel		= FB_ACCEL_ATI_RAGE128,
 };
 
-#ifdef MODULE
 static char *mode __initdata = NULL;
-#ifdef CONFIG_MTRR
-static int  nomtrr __initdata = 0;
-#endif /* CONFIG_MTRR */
-#endif /* MODULE */
-
-static char *mode_option __initdata = NULL;
 
 #ifdef CONFIG_PPC_PMAC
 static int default_vmode __initdata = VMODE_1024_768_60;
@@ -349,7 +432,6 @@
      *  Interface used by the world
      */
 int aty128fb_init(void);
-int aty128fb_setup(char *options);
 
 static int aty128fb_check_var(struct fb_var_screeninfo *var,
 			      struct fb_info *info);
@@ -374,7 +456,7 @@
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
 static void __init aty128_get_pllinfo(struct aty128fb_par *par,
 				      void *bios);
-static void __init *aty128_map_ROM(struct pci_dev *pdev);
+static void __init *aty128_map_ROM(struct pci_dev *pdev, const struct aty128fb_par *par);
 static void __init aty128_unmap_ROM(struct pci_dev *dev, void * rom);
 #endif
 static void aty128_timings(struct aty128fb_par *par);
@@ -1410,61 +1492,6 @@
 	return 0;
 }
 
-int __init
-aty128fb_setup(char *options)
-{
-	char *this_opt;
-
-	if (!options || !*options)
-		return 0;
-
-	while ((this_opt = strsep(&options, ",")) != NULL) {
-#ifdef CONFIG_PMAC_PBOOK
-		if (!strncmp(this_opt, "lcd:", 4)) {
-			default_lcd_on = simple_strtoul(this_opt+4, NULL, 0);
-			continue;
-		} else if (!strncmp(this_opt, "crt:", 4)) {
-			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);
-			continue;
-		}
-#endif
-#ifdef CONFIG_MTRR
-		if(!strncmp(this_opt, "nomtrr", 6)) {
-			mtrr = 0;
-			continue;
-		}
-#endif
-#ifdef CONFIG_PPC_PMAC
-		/* vmode and cmode deprecated */
-		if (!strncmp(this_opt, "vmode:", 6)) {
-			unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
-			if (vmode > 0 && vmode <= VMODE_MAX)
-				default_vmode = vmode;
-			continue;
-		} else if (!strncmp(this_opt, "cmode:", 6)) {
-			unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
-			switch (cmode) {
-			case 0:
-			case 8:
-				default_cmode = CMODE_8;
-				break;
-			case 15:
-			case 16:
-				default_cmode = CMODE_16;
-				break;
-			case 24:
-			case 32:
-				default_cmode = CMODE_32;
-				break;
-			}
-			continue;
-		}
-#endif /* CONFIG_PPC_PMAC */
-		mode_option = this_opt;
-	}
-	return 0;
-}
-
 
 /*
  *  Initialisation
@@ -1476,7 +1503,7 @@
 	struct fb_info *info = pci_get_drvdata(pdev);
 	struct aty128fb_par *par = info->par;
 	struct fb_var_screeninfo var;
-	char video_card[25];
+	char video_card[DEVICE_NAME_SIZE];
 	u8 chip_rev;
 	u32 dac;
 
@@ -1486,43 +1513,13 @@
 	/* Get the chip revision */
 	chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
 
-	switch (pdev->device) {
-		case PCI_DEVICE_ID_ATI_RAGE128_RE:
-			strcpy(video_card, "Rage128 RE (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RF:
-			strcpy(video_card, "Rage128 RF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RK:
-			strcpy(video_card, "Rage128 RK (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_RL:
-			strcpy(video_card, "Rage128 RL (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_Rage128_PD:
-			strcpy(video_card, "Rage128 Pro PD (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_PF:
-			strcpy(video_card, "Rage128 Pro PF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_PR:
-			strcpy(video_card, "Rage128 Pro PR (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_U3:
-			strcpy(video_card, "Rage128 Pro TR (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_U1:
-			strcpy(video_card, "Rage128 Pro TF (AGP)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_LE:
-			strcpy(video_card, "Rage Mobility M3 (PCI)");
-			break;
-		case PCI_DEVICE_ID_ATI_RAGE128_LF:
-			strcpy(video_card, "Rage Mobility M3 (AGP)");
-			break;
-		default:
-			return -ENODEV;
-	}
+	strcpy(video_card, "Rage128 XX ");
+	video_card[8] = ent->device >> 8;
+	video_card[9] = ent->device & 0xFF;
+
+	/* range check to make sure */
+	if (ent->driver_data < (sizeof(r128_family)/sizeof(char *)))
+	    strncat(video_card, r128_family[ent->driver_data], sizeof(video_card));
 
 	printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
 
@@ -1536,17 +1533,17 @@
 	/* fill in info */
 	info->fbops = &aty128fb_ops;
 	info->flags = FBINFO_FLAG_DEFAULT;
-
+
 #ifdef CONFIG_PMAC_PBOOK
 	par->lcd_on = default_lcd_on;
 	par->crt_on = default_crt_on;
 #endif
-
+
 	var = default_var;
 #ifdef CONFIG_PPC_PMAC
 	if (_machine == _MACH_Pmac) {
-		if (mode_option) {
-			if (!mac_find_mode(&var, info, mode_option, 8))
+		if (mode) {
+			if (!mac_find_mode(&var, info, mode, 8))
 				var = default_var;
 		} else {
 			if (default_vmode <= 0 || default_vmode > VMODE_MAX)
@@ -1575,8 +1572,12 @@
 			if (machine_is_compatible("PowerBook3,2"))
 				default_vmode = VMODE_1152_768_60;
 	
-			if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
-				default_cmode = CMODE_8;
+			if (default_cmode > 16)
+			    default_cmode = CMODE_32;
+			else if (default_cmode > 8)
+			    default_cmode = CMODE_16;
+			else
+			    default_cmode = CMODE_8;
 
 			if (mac_vmode_to_var(default_vmode, default_cmode, &var))
 				var = default_var;
@@ -1584,9 +1585,10 @@
 	} else
 #endif /* CONFIG_PPC_PMAC */
 	{
-		if (fb_find_mode(&var, info, mode_option, NULL, 0,
-				 &defaultmode, 8) == 0)
-			var = default_var;
+		if (mode)
+			if (fb_find_mode(&var, info, mode, NULL,
+					 0, &defaultmode, 8) == 0)
+				var = default_var;
 	}
 
 	var.accel_flags &= ~FB_ACCELF_TEXT;
@@ -1614,7 +1616,7 @@
 	var.activate = FB_ACTIVATE_NOW;
 
 	aty128_init_engine(par);
-
+
 	if (register_framebuffer(info) < 0)
 		return 0;
 
@@ -1647,7 +1649,7 @@
 	unsigned long fb_addr, reg_addr;
 	struct aty128fb_par *par;
 	struct fb_info *info;
-	int err, size;
+	int err;
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
 	void *bios = NULL;
 #endif
@@ -1675,17 +1677,13 @@
 	}
 
 	/* We have the resources. Now virtualize them */
-	size = sizeof(struct fb_info) + sizeof(struct aty128fb_par);
-	if (!(info = kmalloc(size, GFP_ATOMIC))) {
+	if (!(info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev))) {
 		printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
 		goto err_free_mmio;
 	}
-	memset(info, 0, size);
+	par = info->par;
 
-	par = (struct aty128fb_par *)(info + 1);
 	info->pseudo_palette = par->pseudo_palette;
-
-	info->par = par;
 	info->fix = aty128fb_fix;
 
 	/* Virtualize mmio region */
@@ -1716,7 +1714,7 @@
 	}
 
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
-	if (!(bios = aty128_map_ROM(pdev)))
+	if (!(bios = aty128_map_ROM(pdev, par)))
 		printk(KERN_INFO "aty128fb: BIOS not located, guessing timings.\n");
 	else {
 		printk(KERN_INFO "aty128fb: Rage128 BIOS located at %lx\n",
@@ -1776,47 +1774,61 @@
 
 	release_mem_region(pci_resource_start(pdev, 0),
 			   pci_resource_len(pdev, 0));
-	release_mem_region(pci_resource_start(pdev, 1),
-			   pci_resource_len(pdev, 1));
 	release_mem_region(pci_resource_start(pdev, 2),
 			   pci_resource_len(pdev, 2));
 #ifdef CONFIG_PMAC_PBOOK
 	if (info == aty128_fb)
 		aty128_fb = NULL;
 #endif
-	kfree(info);
+	framebuffer_release(info);
 }
 #endif /* CONFIG_PCI */
 
 /* PPC and Sparc cannot read video ROM */
 #if !defined(CONFIG_PPC) && !defined(__sparc__)
-static void * __init aty128_map_ROM(struct pci_dev *dev)
+static void * __init aty128_map_ROM(struct pci_dev *dev, const struct aty128fb_par *par)
 {
+	struct resource *r;
+	void *rom;
+
 	// If this is a primary card, there is a shadow copy of the
 	// ROM somewhere in the first meg. We will just ignore the copy
 	// and use the ROM directly.
 	
+    	/* Fix from ATI for problem with Rage128 hardware not leaving ROM enabled */
+    	unsigned int temp;
+	temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
+	temp &= 0x00ffffffu;
+	temp |= 0x04 << 24;
+	aty_st_le32(RAGE128_MPP_TB_CONFIG, temp);
+	temp = aty_ld_le32(RAGE128_MPP_TB_CONFIG);
+
 	// no need to search for the ROM, just ask the card where it is.
-	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
-	unsigned char *addr;
-	
+	r = &dev->resource[PCI_ROM_RESOURCE];
+
 	// assign the ROM an address if it doesn't have one
-	if (r->start == 0)
+	if (r->parent == NULL)
 		pci_assign_resource(dev, PCI_ROM_RESOURCE);
 	
 	// enable if needed
-	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE))
+	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
 		pci_write_config_dword(dev, dev->rom_base_reg, r->start | PCI_ROM_ADDRESS_ENABLE);
+		r->flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
 	
-	addr = ioremap(r->start, r->end - r->start + 1);
+	rom = ioremap(r->start, r->end - r->start + 1);
+	if (!rom) {
+		printk(KERN_ERR "aty128fb: ROM failed to map\n");
+		return NULL;
+	}
 	
 	// Very simple test to make sure it appeared
-	if (addr && (*addr != 0x55)) {
-		printk("aty128fb: Invalid ROM signature %x\n", *addr);
-		iounmap(addr);
+	if (readb(rom) != 0x55) {
+		printk(KERN_ERR "aty128fb: Invalid ROM signature %x should be 0x55\n", readb(rom));
+		aty128_unmap_ROM(dev, rom);
 		return NULL;
 	}
-	return (void *)addr;
+	return rom;
 }
 
 static void __init aty128_unmap_ROM(struct pci_dev *dev, void * rom)
@@ -1826,10 +1838,12 @@
 	
 	iounmap(rom);
 	
-	r->flags &= !PCI_ROM_ADDRESS_ENABLE;
+	r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
 	r->end -= r->start;
 	r->start = 0;
+	/* This will disable and set address to unassigned */
 	pci_write_config_dword(dev, dev->rom_base_reg, 0);
+	release_resource(r);
 }
 
 static void __init
@@ -2331,6 +2345,7 @@
 	return pci_module_init(&aty128fb_driver);
 }
 
+#ifdef MODULE
 static void __exit aty128fb_exit(void)
 {
 #ifdef CONFIG_PMAC_PBOOK
@@ -2338,14 +2353,32 @@
 #endif
 	pci_unregister_driver(&aty128fb_driver);
 }
+#endif
+
+#ifdef MODULE
+module_init(aty128fb_init);
+module_exit(aty128fb_exit);
+#endif
 
 MODULE_AUTHOR("(c)1999-2003 Brad Douglas <brad@neruo.com>");
 MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
 MODULE_LICENSE("GPL");
-MODULE_PARM(mode, "s");
+module_param(mode, charp, 0);
 MODULE_PARM_DESC(mode, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
 #ifdef CONFIG_MTRR
-MODULE_PARM(nomtrr, "i");
-MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
+module_param_named(nomtrr, mtrr, invbool, 0);
+MODULE_PARM_DESC(mtrr, "bool: Disable MTRR support (0 or 1=disabled) (default=0)");
+#endif
+#ifdef CONFIG_PPC_PMAC
+module_param_named(vmode, default_vmode, int, 0);
+MODULE_PARM_DESC(default_vmode, "Deprecated: video mode int");
+module_param_named(cmode, default_cmode, int, 0);
+MODULE_PARM_DESC(default_cmode, "Deprecated: color mode int");
+#endif
+#ifdef CONFIG_PMAC_PBOOK
+module_param_named(lcd, default_lcd_on, bool, 0);
+MODULE_PARM_DESC(default_lcd_on, "bool: Default LCD on");
+module_param_named(crt, default_crt_on, bool, 0);
+MODULE_PARM_DESC(default_crt_on, "bool: Default CRT on");
 #endif
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/atyfb.h fbdev-2.6/drivers/video/aty/atyfb.h
--- linus-2.6/drivers/video/aty/atyfb.h	Thu Oct 16 14:13:34 2003
+++ fbdev-2.6/drivers/video/aty/atyfb.h	Thu Oct 16 14:13:34 2003
@@ -55,18 +55,10 @@
     /*
      *  The hardware parameters for each card
      */
-
-struct aty_cursor {
-	u8 bits[8][64];
-	u8 mask[8][64];
-	u8 *ram;
-};
-
 struct atyfb_par {
 	struct aty_cmap_regs *aty_cmap_regs;
 	const struct aty_dac_ops *dac_ops;
 	const struct aty_pll_ops *pll_ops;
-	struct aty_cursor *cursor;
 	unsigned long ati_regbase;
 	unsigned long clk_wr_offset;
 	struct crtc crtc;
@@ -237,10 +229,10 @@
      *  Hardware cursor support
      */
 
-extern struct aty_cursor *aty_init_cursor(struct fb_info *info);
+extern int aty_init_cursor(struct fb_info *info);
 extern int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor);
 extern void aty_set_cursor_color(struct fb_info *info);
-extern void aty_set_cursor_shape(struct fb_info *info);
+extern void aty_set_cursor_shape(struct fb_info *info, u8 *src, u8 *dst, unsigned int width);
 
     /*
      *  Hardware acceleration
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/atyfb_base.c fbdev-2.6/drivers/video/aty/atyfb_base.c
--- linus-2.6/drivers/video/aty/atyfb_base.c	Thu Oct 16 14:13:35 2003
+++ fbdev-2.6/drivers/video/aty/atyfb_base.c	Thu Oct 16 14:13:35 2003
@@ -202,7 +202,7 @@
 	.fb_fillrect	= atyfb_fillrect,
 	.fb_copyarea	= atyfb_copyarea,
 	.fb_imageblit	= atyfb_imageblit,
-	.fb_cursor	= soft_cursor,
+	.fb_cursor	= atyfb_cursor,
 #ifdef __sparc__
 	.fb_mmap	= atyfb_mmap,
 #endif
@@ -1889,7 +1889,7 @@
 
 #ifdef CONFIG_FB_ATY_CT
 	if (curblink && M64_HAS(INTEGRATED))
-		par->cursor = aty_init_cursor(info);
+		aty_init_cursor(info);
 #endif				/* CONFIG_FB_ATY_CT */
 	info->var = var;
 
@@ -2470,22 +2470,6 @@
 }
 #endif				/* CONFIG_ATARI */
 
-/*
-#ifdef CONFIG_FB_ATY_CT
-   * Erase HW Cursor *
-    if (par->cursor && (info->currcon >= 0))
-	atyfb_cursor(&fb_display[par->currcon], CM_ERASE,
-		     par->cursor->pos.x, par->cursor->pos.y);
-#endif * CONFIG_FB_ATY_CT *
-
-#ifdef CONFIG_FB_ATY_CT
-    * Install hw cursor *
-    if (par->cursor) {
-	aty_set_cursor_color(info);
-	aty_set_cursor_shape(info);
-    }
-#endif * CONFIG_FB_ATY_CT */
-
     /*
      *  Blank the display.
      */
@@ -2595,13 +2579,9 @@
 		iounmap((void *) par->ati_regbase);
 	if (info->screen_base)
 		iounmap((void *) info->screen_base);
-#ifdef __BIG_ENDIAN
-	if (par->cursor && par->cursor->ram)
-		iounmap(par->cursor->ram);
-#endif
 #endif
-	if (par->cursor)
-		kfree(par->cursor);
+	if (info->sprite.addr)
+		iounmap(info->sprite.addr);
 #ifdef __sparc__
 	if (par->mmap_map)
 		kfree(par->mmap_map);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/mach64_cursor.c fbdev-2.6/drivers/video/aty/mach64_cursor.c
--- linus-2.6/drivers/video/aty/mach64_cursor.c	Thu Oct 16 14:13:35 2003
+++ fbdev-2.6/drivers/video/aty/mach64_cursor.c	Thu Oct 16 14:13:35 2003
@@ -1,12 +1,11 @@
-
 /*
  *  ATI Mach64 CT/VT/GT/LT Cursor Support
  */
 
 #include <linux/slab.h>
-#include <linux/console.h>
 #include <linux/fb.h>
 #include <linux/init.h>
+#include <linux/string.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -22,104 +21,70 @@
     /*
      *  Hardware Cursor support.
      */
-
-static const u8 cursor_pixel_map[2] = { 0, 15 };
-static const u8 cursor_color_map[2] = { 0, 0xff };
-
 static const u8 cursor_bits_lookup[16] = {
-	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
-	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
+	0x55, 0x15, 0x45, 0x05, 0x51, 0x11, 0x41, 0x01,
+	0x54, 0x14, 0x44, 0x04, 0x50, 0x10, 0x40, 0x00
 };
 
 static const u8 cursor_mask_lookup[16] = {
 	0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
 	0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
-};
-
-void aty_set_cursor_color(struct fb_info *info)
-{
-	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	struct aty_cursor *c = par->cursor;
-	const u8 *pixel = cursor_pixel_map;	/* ++Geert: Why?? */
-	const u8 *red = cursor_color_map;
-	const u8 *green = cursor_color_map;
-	const u8 *blue = cursor_color_map;
-	u32 fg_color, bg_color;
-
-	if (!c)
-		return;
-
-#ifdef __sparc__
-	if (par->mmaped)
-		return;
-#endif
-	fg_color = (u32) red[0] << 24;
-	fg_color |= (u32) green[0] << 16;
-	fg_color |= (u32) blue[0] << 8;
-	fg_color |= (u32) pixel[0];
-
-	bg_color = (u32) red[1] << 24;
-	bg_color |= (u32) green[1] << 16;
-	bg_color |= (u32) blue[1] << 8;
-	bg_color |= (u32) pixel[1];
-
-	wait_for_fifo(2, par);
-	aty_st_le32(CUR_CLR0, fg_color, par);
-	aty_st_le32(CUR_CLR1, bg_color, par);
-}
+};
 
-void aty_set_cursor_shape(struct fb_info *info)
+void aty_set_cursor_shape(struct fb_info *info, u8 *src, u8 *dst, unsigned int width)
 {
-	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	struct fb_cursor *cursor = &info->cursor;
-	struct aty_cursor *c = par->cursor;
-	u8 *ram, m, b;
-	int x, y;
+	int i, j, offset = info->sprite.scan_align - width;
+	u8 *mask = info->cursor.mask, m, b;
 
-	if (!c)
-		return;
-#ifdef __sparc__
-	if (par->mmaped)
-		return;
-#endif
-
-	ram = c->ram;
-	for (y = 0; y < cursor->image.height; y++) {
-		for (x = 0; x < cursor->image.width >> 2; x++) {
-			m = c->mask[x][y];
-			b = c->bits[x][y];
-			fb_writeb(cursor_mask_lookup[m >> 4] |
-				  cursor_bits_lookup[(b & m) >> 4], ram++);
-			fb_writeb(cursor_mask_lookup[m & 0x0f] |
-				  cursor_bits_lookup[(b & m) & 0x0f],
-				  ram++);
-		}
-		for (; x < 8; x++) {
-			fb_writeb(0xaa, ram++);
-			fb_writeb(0xaa, ram++);
+	// Clear cursor image with 1010101010...
+	fb_memset(dst, 0xaa, 1024);
+
+	for (i = 0; i < info->cursor.image.height; i++) {
+		for (j = 0; j < width; j++) {
+			b = *src++;
+			m = *mask++;
+			// Upper 4 bits of mask data
+			fb_writeb(cursor_mask_lookup[m >> 4 ] |
+				  cursor_bits_lookup[(b & m) >> 4], dst++);
+			// Lower 4 bits of mask
+			fb_writeb(cursor_mask_lookup[m & 0x0f ] |
+				  cursor_bits_lookup[(b & m) & 0x0f], dst++);
 		}
+		dst += offset*2;
 	}
-	fb_memset(ram, 0xaa, (64 - cursor->image.height) * 16);
 }
 
-static void aty_set_cursor(struct fb_info *info)
+int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	struct fb_cursor *cursor = &info->cursor;
-	struct aty_cursor *c = par->cursor;
 	u16 xoff, yoff;
 	int x, y;
-
-	if (!c)
-		return;
-
+
 #ifdef __sparc__
 	if (par->mmaped)
-		return;
+		return -EPERM;
 #endif
 
-	if (cursor->enable) {
-		x = cursor->image.dx - cursor->hot.x - info->var.xoffset;
+	/* Hide cursor */
+	wait_for_fifo(1, par);
+	aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par);
+
+	/* Set size */
+	if (cursor->set & FB_CUR_SETSIZE) {
+		info->cursor.image.height = cursor->image.height;
+		info->cursor.image.width = cursor->image.width;
+	}
+
+	/* Set hot spot */
+	if  (cursor->set & FB_CUR_SETHOT)
+		info->cursor.hot = cursor->hot;
+
+	/* set position */
+	if (cursor->set & FB_CUR_SETPOS) {
+		info->cursor.image.dx = cursor->image.dx;
+		info->cursor.image.dy = cursor->image.dy;
+
+		x = info->cursor.image.dx - info->cursor.hot.x - info->var.xoffset;
 		if (x < 0) {
 			xoff = -x;
 			x = 0;
@@ -127,7 +92,7 @@
 			xoff = 0;
 		}
 
-		y = cursor->image.dy - cursor->hot.y - info->var.yoffset;
+		y = info->cursor.image.dy - info->cursor.hot.y - info->var.yoffset;
 		if (y < 0) {
 			yoff = -y;
 			y = 0;
@@ -135,107 +100,78 @@
 			yoff = 0;
 		}
 
+		/*
+		 * In doublescan mode, the cursor location also needs to be
+		 * doubled.
+		 */
+                if (par->crtc.gen_cntl & CRTC_DBL_SCAN_EN)
+			y<<=1;
 		wait_for_fifo(4, par);
-		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1),
-			    par);
+		aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
 		aty_st_le32(CUR_HORZ_VERT_OFF,
-			    ((u32) (64 - cursor->image.height + yoff) << 16) | xoff,
+			    ((u32) (64 - info->cursor.image.height + yoff) << 16) | xoff,
 			    par);
 		aty_st_le32(CUR_HORZ_VERT_POSN, ((u32) y << 16) | x, par);
+	}
+
+	/* Set color map */
+	if (cursor->set & FB_CUR_SETCMAP) {
+		u32 fg_idx, bg_idx, fg, bg;
+
+		info->cursor.image.fg_color = cursor->image.fg_color;
+		info->cursor.image.bg_color = cursor->image.bg_color;
+		fg_idx = info->cursor.image.fg_color;
+		bg_idx = info->cursor.image.bg_color;
+
+		fg = (info->cmap.red[fg_idx] << 24) |
+		     (info->cmap.green[fg_idx] << 16) |
+		     (info->cmap.blue[fg_idx] << 8) | 15;
+
+		bg = (info->cmap.red[bg_idx] << 24) |
+		     (info->cmap.green[bg_idx] << 16) |
+		     (info->cmap.blue[bg_idx] << 8) | 15;
+
+		wait_for_fifo(2, par);
+		aty_st_le32(CUR_CLR0, fg, par);
+		aty_st_le32(CUR_CLR1, bg, par);
+	}
+
+	if (cursor->set & FB_CUR_SETSHAPE)
+		load_cursor_image(info);
+
+	if (info->cursor.enable) {
+		wait_for_fifo(1, par);
 		aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
 			    | HWCURSOR_ENABLE, par);
-	} else {
-		wait_for_fifo(1, par);
-		aty_st_le32(GEN_TEST_CNTL,
-			    aty_ld_le32(GEN_TEST_CNTL,
-					par) & ~HWCURSOR_ENABLE, par);
-	}
-	if (par->blitter_may_be_busy)
-		wait_for_idle(par);
-}
-
-int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
-{
-	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	struct aty_cursor *c = par->cursor;
-
-	if (!c)
-		return -1;
-
-#ifdef __sparc__
-	if (par->mmaped)
-		return 0;
-#endif
-
-	aty_set_cursor(info);
-	cursor->image.dx = info->cursor.image.dx;
-	cursor->image.dy = info->cursor.image.dy;
-
-	aty_set_cursor(info);
+	}
 	return 0;
 }
 
-struct aty_cursor *__init aty_init_cursor(struct fb_info *info)
+int __init aty_init_cursor(struct fb_info *info)
 {
-	struct aty_cursor *cursor;
 	unsigned long addr;
 
-	cursor = kmalloc(sizeof(struct aty_cursor), GFP_ATOMIC);
-	if (!cursor)
-		return 0;
-	memset(cursor, 0, sizeof(*cursor));
-
 	info->fix.smem_len -= PAGE_SIZE;
 
 #ifdef __sparc__
 	addr = (unsigned long) info->screen_base - 0x800000 + info->fix.smem_len;
-	cursor->ram = (u8 *) addr;
+	info->sprite.addr = (u8 *) addr;
 #else
 #ifdef __BIG_ENDIAN
 	addr = info->fix.smem_start - 0x800000 + info->fix.smem_len;
-	cursor->ram = (u8 *) ioremap(addr, 1024);
+	info->sprite.addr = (u8 *) ioremap(addr, 1024);
 #else
 	addr = (unsigned long) info->screen_base + info->fix.smem_len;
-	cursor->ram = (u8 *) addr;
+	info->sprite.addr = (u8 *) addr;
 #endif
 #endif
-	if (!cursor->ram) {
-		kfree(cursor);
-		return NULL;
-	}
-	return cursor;
+	if (!info->sprite.addr)
+		return -ENXIO;
+	info->sprite.size = PAGE_SIZE;
+	info->sprite.scan_align = 8;	// Scratch pad 8 bytes wide
+	info->sprite.buf_align = 8; 	// *64;	// and 64 lines tall.
+	info->sprite.flags = FB_PIXMAP_IO;
+	info->sprite.outbuf = aty_set_cursor_shape;
+	return 0;
 }
 
-int atyfb_set_font(struct fb_info *info, int width, int height)
-{
-	struct atyfb_par *par = (struct atyfb_par *) info->par;
-	struct fb_cursor *cursor = &info->cursor;
-	struct aty_cursor *c = par->cursor;
-	int i, j;
-
-	if (c) {
-		if (!width || !height) {
-			width = 8;
-			height = 16;
-		}
-
-		cursor->hot.x = 0;
-		cursor->hot.y = 0;
-		cursor->image.width = width;
-		cursor->image.height = height;
-
-		memset(c->bits, 0xff, sizeof(c->bits));
-		memset(c->mask, 0, sizeof(c->mask));
-
-		for (i = 0, j = width; j >= 0; j -= 8, i++) {
-			c->mask[i][height - 2] =
-			    (j >= 8) ? 0xff : (0xff << (8 - j));
-			c->mask[i][height - 1] =
-			    (j >= 8) ? 0xff : (0xff << (8 - j));
-		}
-
-		aty_set_cursor_color(info);
-		aty_set_cursor_shape(info);
-	}
-	return 1;
-}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/radeon_base.c fbdev-2.6/drivers/video/aty/radeon_base.c
--- linus-2.6/drivers/video/aty/radeon_base.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/aty/radeon_base.c	Thu Oct 16 12:08:22 2003
@@ -0,0 +1,2228 @@
+/*
+ *	drivers/video/radeonfb.c
+ *	framebuffer driver for ATI Radeon chipset video boards
+ *
+ *	Copyright 2003	Ben. Herrenschmidt <benh@kernel.crashing.org>
+ *	Copyright 2000	Ani Joshi <ajoshi@kernel.crashing.org>
+ *
+ *	i2c bits from Luca Tettamanti <kronos@kronoz.cjb.net>
+ *
+ *	Special thanks to ATI DevRel team for their hardware donations.
+ *
+ *	...Insert GPL boilerplate here...
+ *
+ *	TODO: - Bring a couple of cleanups from 2.4 to the mode setting code,
+ *	      - Split CRT vs. FP register calc/setting
+ *	      - Add CRTC2 support for mirror at least, dual head then
+ *	      - Add back some accel
+ *
+ */
+
+
+#define RADEON_VERSION	"0.2.0"
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#if CONFIG_PPC_OF
+
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include "../macmodes.h"
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include <asm/backlight.h>
+#endif
+
+#ifdef CONFIG_BOOTX_TEXT
+#include <asm/btext.h>
+#endif
+
+#endif /* CONFIG_PPC_OF */
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif
+
+#include <video/radeon.h>
+#include <linux/radeonfb.h>
+
+#include "../edid.h" // MOVE THAT TO include/video
+#include "radeonfb.h"
+
+/* Must match above enum */
+static const char *radeon_family[] __devinitdata = {
+	"R100",
+	"VE RV100",
+	"8500 R200",
+	"7500 RV200",
+	"9000 RV250",
+	"9200 RV280",
+	"9700 R300",
+	"9700 RS300",
+	"9800 R350",
+	"Mobility M6",
+	"Mobility M7",
+	"Mobility M9",
+};
+
+
+
+static struct pci_device_id radeonfb_pci_table[] = {
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_A6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_A7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_AG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ad, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_B7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_BB, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_D7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV250},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ie, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV250},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_If, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV250},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ig, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV250},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_In, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV250_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M7},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M7},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M6},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_LZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M6},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ld, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M9},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Le, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M9},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M9},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Lg, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M9},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ln, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_M9_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_ND, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_NH, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R350},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Nd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ne, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Nf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ng, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R300_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Nh, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R350_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QH, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QI, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QJ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QK, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QM, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QW, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QX, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV200},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QY, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_QZ, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV100},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Qh, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Qi, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Qj, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Qk, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Ql, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_R200_SEC},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_X7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RS300},
+	{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RADEON_Y_, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RADEON_RV280},
+	{ 0, }
+};
+MODULE_DEVICE_TABLE(pci, radeonfb_pci_table);
+
+
+typedef struct {
+	u16 reg;
+	u32 val;
+} reg_val;
+
+
+/* these common regs are cleared before mode setting so they do not
+ * interfere with anything
+ */
+reg_val common_regs[] = {
+	{ OVR_CLR, 0 },
+	{ OVR_WID_LEFT_RIGHT, 0 },
+	{ OVR_WID_TOP_BOTTOM, 0 },
+	{ OV0_SCALE_CNTL, 0 },
+	{ SUBPIC_CNTL, 0 },
+	{ VIPH_CONTROL, 0 },
+	{ I2C_CNTL_1, 0 },
+	{ GEN_INT_CNTL, 0 },
+	{ CAP0_TRIG_CNTL, 0 },
+};
+
+reg_val common_regs_m6[] = {
+	{ OVR_CLR,      0 },
+	{ OVR_WID_LEFT_RIGHT,   0 },
+	{ OVR_WID_TOP_BOTTOM,   0 },
+	{ OV0_SCALE_CNTL,   0 },
+	{ SUBPIC_CNTL,      0 },
+	{ GEN_INT_CNTL,     0 },
+	{ CAP0_TRIG_CNTL,   0 }
+};
+
+/*
+ * globals
+ */
+
+static char *mode_option __initdata;
+static char *monitor_layout __initdata;
+static int noaccel = 0;
+static int nomodeset = 0;
+static int ignore_edid = 0;
+static int mirror = 0;
+static int panel_yres __initdata = 0;
+static int force_dfp __initdata = 0;
+static struct radeonfb_info *board_list = NULL;
+#ifdef CONFIG_MTRR
+static int nomtrr __initdata = 0;
+#endif
+
+/*
+ * prototypes
+ */
+
+
+#ifdef CONFIG_PPC_OF
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+static int radeon_set_backlight_enable(int on, int level, void *data);
+static int radeon_set_backlight_level(int level, void *data);
+static struct backlight_controller radeon_backlight_controller = {
+	radeon_set_backlight_enable,
+	radeon_set_backlight_level
+};
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+#endif /* CONFIG_PPC_OF */
+
+/* Wrapper for external files */
+int radeon_accel_disabled(void)
+{
+	return noaccel;
+}
+
+void _radeon_engine_reset(struct radeonfb_info *rinfo)
+{
+	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+	u32 host_path_cntl;
+
+	radeon_engine_flush (rinfo);
+
+    	/* Some ASICs have bugs with dynamic-on feature, which are
+     	 * ASIC-version dependent, so we force all blocks on for now
+     	 * -- from XFree86
+     	 * We don't do that on macs, things just work here with dynamic
+     	 * clocking... --BenH
+	 */
+#ifdef CONFIG_ALL_PPC
+	if (_machine != _MACH_Pmac && rinfo->hasCRTC2)
+#else
+	if (rinfo->has_CRTC2)
+#endif
+	{
+		u32 tmp;
+
+		tmp = INPLL(SCLK_CNTL);
+		OUTPLL(SCLK_CNTL, ((tmp & ~DYN_STOP_LAT_MASK) |
+				   CP_MAX_DYN_STOP_LAT |
+				   SCLK_FORCEON_MASK));
+
+		if (rinfo->arch == RADEON_RV200)
+		{
+			tmp = INPLL(SCLK_MORE_CNTL);
+			OUTPLL(SCLK_MORE_CNTL, tmp | SCLK_MORE_FORCEON);
+		}
+	}
+
+	clock_cntl_index = INREG(CLOCK_CNTL_INDEX);
+	mclk_cntl = INPLL(MCLK_CNTL);
+
+	OUTPLL(MCLK_CNTL, (mclk_cntl |
+			   FORCEON_MCLKA |
+			   FORCEON_MCLKB |
+			   FORCEON_YCLKA |
+			   FORCEON_YCLKB |
+			   FORCEON_MC |
+			   FORCEON_AIC));
+
+	host_path_cntl = INREG(HOST_PATH_CNTL);
+	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
+
+	if (rinfo->arch == RADEON_R300) {
+		u32 tmp;
+
+		OUTREG(RBBM_SOFT_RESET, (rbbm_soft_reset |
+					 SOFT_RESET_CP |
+					 SOFT_RESET_HI |
+					 SOFT_RESET_E2));
+		INREG(RBBM_SOFT_RESET);
+		OUTREG(RBBM_SOFT_RESET, 0);
+		tmp = INREG(RB2D_DSTCACHE_MODE);
+		OUTREG(RB2D_DSTCACHE_MODE, tmp | (1 << 17)); /* FIXME */
+	} else {
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
+					SOFT_RESET_CP |
+					SOFT_RESET_HI |
+					SOFT_RESET_SE |
+					SOFT_RESET_RE |
+					SOFT_RESET_PP |
+					SOFT_RESET_E2 |
+					SOFT_RESET_RB);
+		INREG(RBBM_SOFT_RESET);
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
+					~(SOFT_RESET_CP |
+					  SOFT_RESET_HI |
+					  SOFT_RESET_SE |
+					  SOFT_RESET_RE |
+					  SOFT_RESET_PP |
+					  SOFT_RESET_E2 |
+					  SOFT_RESET_RB));
+		INREG(RBBM_SOFT_RESET);
+	}
+
+	OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
+	INREG(HOST_PATH_CNTL);
+	OUTREG(HOST_PATH_CNTL, host_path_cntl);
+
+	if (rinfo->arch != RADEON_R300)
+		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+
+	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+	OUTPLL(MCLK_CNTL, mclk_cntl);
+}
+
+static void __devexit radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+{
+	// leave it disabled and unassigned
+	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
+
+	if (!rinfo->bios_seg)
+		return;
+	iounmap(rinfo->bios_seg);
+
+	if (r->parent) {
+		release_resource(r);
+		r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+		r->end -= r->start;
+		r->start = 0;
+	}
+	/* This will disable and set address to unassigned */
+	pci_write_config_dword(dev, dev->rom_base_reg, 0);
+}
+
+static void * __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev)
+{
+        struct resource *r;
+	void *rom;
+
+	/* If this is a primary card, there is a shadow copy of the
+	 * ROM somewhere in the first meg. We will just ignore the copy
+	 * and use the ROM directly.
+	 */
+
+    	/* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */
+    	unsigned int temp;
+	temp = INREG(MPP_TB_CONFIG);
+	temp &= 0x00ffffffu;
+	temp |= 0x04 << 24;
+	OUTREG(MPP_TB_CONFIG, temp);
+	temp = INREG(MPP_TB_CONFIG);
+
+	/* no need to search for the ROM, just ask the card where it is. */
+	r = &dev->resource[PCI_ROM_RESOURCE];
+
+	/* assign the ROM an address if it doesn't have one */
+	if (r->parent == NULL)
+		pci_assign_resource(dev, PCI_ROM_RESOURCE);
+
+	/* enable if needed */
+	if (!(r->flags & PCI_ROM_ADDRESS_ENABLE)) {
+		pci_write_config_dword(dev, dev->rom_base_reg, r->start | PCI_ROM_ADDRESS_ENABLE);
+		r->flags |= PCI_ROM_ADDRESS_ENABLE;
+	}
+
+	rom = ioremap(r->start, r->end - r->start + 1);
+	if (!rom) {
+		printk(KERN_ERR "radeonfb: ROM failed to map\n");
+		return NULL;
+	}
+
+	rinfo->bios_seg = rom;
+
+	/* Very simple test to make sure it appeared */
+	if (BIOS_IN16(0) != 0xaa55) {
+		printk(KERN_ERR "radeonfb: Invalid ROM signature %x should be 0xaa55\n", BIOS_IN16(0));
+		rinfo->bios_seg = NULL;
+		radeon_unmap_ROM(rinfo, dev);
+		return NULL;
+	}
+	/* Locate the flat panel infos */
+	rinfo->fp_bios_start = BIOS_IN16(0x48);
+
+	return rom;
+}
+
+#ifdef CONFIG_PPC_OF
+static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo)
+{
+	struct device_node *dp;
+	unsigned int *xtal;
+
+	dp = pci_device_to_OF_node(rinfo->pdev);
+
+	xtal = (unsigned int *) get_property(dp, "ATY,RefCLK", 0);
+	if (!xtal || !*xtal)
+		return 0;
+
+	rinfo->pll.ref_clk = *xtal / 10;
+
+       	return 1;
+}
+#endif /* CONFIG_PPC_OF */
+
+static void __devinit radeon_get_pllinfo(struct radeonfb_info *rinfo, char *bios_seg)
+{
+        void *bios_header;
+        void *header_ptr;
+        u16 bios_header_offset, pll_info_offset;
+        PLL_BLOCK pll;
+
+	if (bios_seg) {
+		// XXX FIXME: Use BIOS_INx accessors
+
+	        bios_header = bios_seg + 0x48L;
+       		header_ptr  = bios_header;
+
+        	bios_header_offset = readw(header_ptr);
+	        bios_header = bios_seg + bios_header_offset;
+        	bios_header += 0x30;
+
+        	header_ptr = bios_header;
+        	pll_info_offset = readw(header_ptr);
+        	header_ptr = bios_seg + pll_info_offset;
+
+        	memcpy_fromio(&pll, header_ptr, 50);
+
+        	rinfo->pll.xclk = (u32)pll.XCLK;
+        	rinfo->pll.ref_clk = (u32)pll.PCLK_ref_freq;
+        	rinfo->pll.ref_div = (u32)pll.PCLK_ref_divider;
+        	rinfo->pll.ppll_min = pll.PCLK_min_freq;
+        	rinfo->pll.ppll_max = pll.PCLK_max_freq;
+
+		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from BIOS\n",
+			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+	} else {
+#ifdef CONFIG_PPC_OF
+		if (radeon_read_xtal_OF(rinfo)) {
+			unsigned int tmp, Nx, M, ref_div, xclk;
+
+			tmp = INPLL(M_SPLL_REF_FB_DIV);
+			ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
+
+			Nx = (tmp & 0xff00) >> 8;
+			M = (tmp & 0xff);
+			xclk = ((((2 * Nx * rinfo->pll.ref_clk) + (M)) /
+				(2 * M)));
+
+			rinfo->pll.xclk = xclk;
+			rinfo->pll.ref_div = ref_div;
+			rinfo->pll.ppll_min = 12000;
+			rinfo->pll.ppll_max = 35000;
+
+			printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d from OF\n",
+				rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+
+			return;
+		}
+#endif /* CONFIG_PPC_OF */
+		/* no BIOS or BIOS not found, use defaults */
+		switch (rinfo->chipset) {
+			case PCI_DEVICE_ID_ATI_RADEON_QW:
+			case PCI_DEVICE_ID_ATI_RADEON_QX:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 23000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case PCI_DEVICE_ID_ATI_RADEON_QL:
+			case PCI_DEVICE_ID_ATI_RADEON_QN:
+			case PCI_DEVICE_ID_ATI_RADEON_QO:
+			case PCI_DEVICE_ID_ATI_RADEON_Ql:
+			case PCI_DEVICE_ID_ATI_RADEON_BB:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 27500;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case PCI_DEVICE_ID_ATI_RADEON_Id:
+			case PCI_DEVICE_ID_ATI_RADEON_Ie:
+			case PCI_DEVICE_ID_ATI_RADEON_If:
+			case PCI_DEVICE_ID_ATI_RADEON_Ig:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 25000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case PCI_DEVICE_ID_ATI_RADEON_ND:
+			case PCI_DEVICE_ID_ATI_RADEON_NE:
+			case PCI_DEVICE_ID_ATI_RADEON_NF:
+			case PCI_DEVICE_ID_ATI_RADEON_NG:
+				rinfo->pll.ppll_max = 40000;
+				rinfo->pll.ppll_min = 20000;
+				rinfo->pll.xclk = 27000;
+				rinfo->pll.ref_div = 12;
+				rinfo->pll.ref_clk = 2700;
+				break;
+			case PCI_DEVICE_ID_ATI_RADEON_QD:
+			case PCI_DEVICE_ID_ATI_RADEON_QE:
+			case PCI_DEVICE_ID_ATI_RADEON_QF:
+			case PCI_DEVICE_ID_ATI_RADEON_QG:
+			default:
+				rinfo->pll.ppll_max = 35000;
+				rinfo->pll.ppll_min = 12000;
+				rinfo->pll.xclk = 16600;
+				rinfo->pll.ref_div = 67;
+				rinfo->pll.ref_clk = 2700;
+				break;
+		}
+
+		printk("radeonfb: ref_clk=%d, ref_div=%d, xclk=%d defaults\n",
+			rinfo->pll.ref_clk, rinfo->pll.ref_div, rinfo->pll.xclk);
+	}
+}
+
+
+#if 0
+static int __devinit radeon_get_dfpinfo (struct radeonfb_info *rinfo)
+{
+	unsigned int tmp;
+	unsigned short a, b;
+
+	if (radeon_get_dfpinfo_BIOS(rinfo))
+		radeon_update_default_var(rinfo);
+
+	if (radeon_dfp_parse_EDID(rinfo))
+		radeon_update_default_var(rinfo);
+
+	if (!rinfo->got_dfpinfo) {
+		/*
+		 * it seems all else has failed now and we
+		 * resort to probing registers for our DFP info
+	         */
+		if (panel_yres) {
+			rinfo->panel_yres = panel_yres;
+		} else {
+			tmp = INREG(FP_VERT_STRETCH);
+			tmp &= 0x00fff000;
+			rinfo->panel_yres = (unsigned short)(tmp >> 0x0c) + 1;
+		}
+
+		switch (rinfo->panel_yres) {
+			case 480:
+				rinfo->panel_xres = 640;
+				break;
+			case 600:
+				rinfo->panel_xres = 800;
+				break;
+			case 768:
+#if defined(__powerpc__)
+				if (rinfo->dviDisp_type == MT_LCD)
+					rinfo->panel_xres = 1152;
+				else
+#endif
+				rinfo->panel_xres = 1024;
+				break;
+			case 1024:
+				rinfo->panel_xres = 1280;
+				break;
+			case 1050:
+				rinfo->panel_xres = 1400;
+				break;
+			case 1200:
+				rinfo->panel_xres = 1600;
+				break;
+			default:
+				printk(KERN_ERR "radeonfb: Failed to detect DFP panel size\n");
+				return 0;
+		}
+
+		printk("radeonfb: detected DFP panel size from registers: %dx%d\n",
+			rinfo->panel_xres, rinfo->panel_yres);
+
+		tmp = INREG(FP_CRTC_H_TOTAL_DISP);
+		a = (tmp & FP_CRTC_H_TOTAL_MASK) + 4;
+		b = (tmp & 0x01ff0000) >> FP_CRTC_H_DISP_SHIFT;
+		rinfo->hblank = (a - b + 1) * 8;
+
+		tmp = INREG(FP_H_SYNC_STRT_WID);
+		rinfo->hOver_plus = (unsigned short) ((tmp & FP_H_SYNC_STRT_CHAR_MASK) >>
+					FP_H_SYNC_STRT_CHAR_SHIFT) - b - 1;
+		rinfo->hOver_plus *= 8;
+		rinfo->hSync_width = (unsigned short) ((tmp & FP_H_SYNC_WID_MASK) >>
+					FP_H_SYNC_WID_SHIFT);
+		rinfo->hSync_width *= 8;
+		tmp = INREG(FP_CRTC_V_TOTAL_DISP);
+		a = (tmp & FP_CRTC_V_TOTAL_MASK) + 1;
+		b = (tmp & FP_CRTC_V_DISP_MASK) >> FP_CRTC_V_DISP_SHIFT;
+		rinfo->vblank = a - b /* + 24 */ ;
+
+		tmp = INREG(FP_V_SYNC_STRT_WID);
+		rinfo->vOver_plus = (unsigned short) (tmp & FP_V_SYNC_STRT_MASK)
+					- b + 1;
+		rinfo->vSync_width = (unsigned short) ((tmp & FP_V_SYNC_WID_MASK) >>
+					FP_V_SYNC_WID_SHIFT);
+
+		return 1;
+	}
+
+	return 1;
+}
+#endif
+
+
+static void radeon_engine_init (struct radeonfb_info *rinfo)
+{
+	unsigned long temp;
+
+	/* disable 3D engine */
+	OUTREG(RB3D_CNTL, 0);
+
+	radeon_engine_reset ();
+
+	radeon_fifo_wait (1);
+	if (rinfo->arch != RADEON_R300)
+		OUTREG(RB2D_DSTCACHE_MODE, 0);
+
+	radeon_fifo_wait (3);
+	/* We re-read MC_FB_LOCATION from card as it can have been
+	 * modified by XFree drivers (ouch !)
+	 */
+	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+
+	OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) |
+				     (rinfo->fb_local_base >> 10));
+	OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+	OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10));
+
+	radeon_fifo_wait (1);
+#if defined(__BIG_ENDIAN)
+	OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN);
+#else
+	OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN);
+#endif
+	radeon_fifo_wait (1);
+	OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX |
+					 DEFAULT_SC_BOTTOM_MAX));
+
+	temp = radeon_get_dstbpp(rinfo->depth);
+	rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS);
+
+	radeon_fifo_wait (1);
+	OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl |
+				    GMC_BRUSH_SOLID_COLOR |
+				    GMC_SRC_DATATYPE_COLOR));
+
+	radeon_fifo_wait (7);
+
+	/* clear line drawing regs */
+	OUTREG(DST_LINE_START, 0);
+	OUTREG(DST_LINE_END, 0);
+
+	/* set brush color regs */
+	OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff);
+	OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000);
+
+	/* set source color regs */
+	OUTREG(DP_SRC_FRGD_CLR, 0xffffffff);
+	OUTREG(DP_SRC_BKGD_CLR, 0x00000000);
+
+	/* default write mask */
+	OUTREG(DP_WRITE_MSK, 0xffffffff);
+
+	radeon_engine_idle ();
+}
+
+
+static int radeon_do_maximize(struct radeonfb_info *rinfo,
+                                struct fb_var_screeninfo *var,
+                                struct fb_var_screeninfo *v,
+                                int nom, int den)
+{
+        static struct {
+                int xres, yres;
+        } modes[] = {
+                {1600, 1280},
+                {1280, 1024},
+                {1024, 768},
+                {800, 600},
+                {640, 480},
+                {-1, -1}
+        };
+        int i;
+
+        /* use highest possible virtual resolution */
+        if (v->xres_virtual == -1 && v->yres_virtual == -1) {
+                printk("radeonfb: using max available virtual resolution\n");
+                for (i=0; modes[i].xres != -1; i++) {
+                        if (modes[i].xres * nom / den * modes[i].yres <
+                            rinfo->video_ram / 2)
+                                break;
+                }
+                if (modes[i].xres == -1) {
+                        printk("radeonfb: could not find virtual resolution that fits into video memory!\n");
+                        return -EINVAL;
+                }
+                v->xres_virtual = modes[i].xres;
+                v->yres_virtual = modes[i].yres;
+
+                printk("radeonfb: virtual resolution set to max of %dx%d\n",
+                        v->xres_virtual, v->yres_virtual);
+        } else if (v->xres_virtual == -1) {
+                v->xres_virtual = (rinfo->video_ram * den /
+                                (nom * v->yres_virtual * 2)) & ~15;
+        } else if (v->yres_virtual == -1) {
+                v->xres_virtual = (v->xres_virtual + 15) & ~15;
+                v->yres_virtual = rinfo->video_ram * den /
+                        (nom * v->xres_virtual *2);
+        } else {
+                if (v->xres_virtual * nom / den * v->yres_virtual >
+                        rinfo->video_ram) {
+                        return -EINVAL;
+                }
+        }
+
+        if (v->xres_virtual * nom / den >= 8192) {
+                v->xres_virtual = 8192 * den / nom - 16;
+        }
+
+        if (v->xres_virtual < v->xres)
+                return -EINVAL;
+
+        if (v->yres_virtual < v->yres)
+                return -EINVAL;
+
+        return 0;
+}
+
+
+static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = info->par;
+        struct fb_var_screeninfo v;
+        int nom, den;
+
+        memcpy (&v, var, sizeof (v));
+
+        switch (v.bits_per_pixel) {
+		case 0 ... 8:
+			v.bits_per_pixel = 8;
+			break;
+		case 9 ... 16:
+			v.bits_per_pixel = 16;
+			break;
+		case 17 ... 24:
+#if 0 /* Doesn't seem to work */
+			v.bits_per_pixel = 24;
+			break;
+#endif
+			return -EINVAL;
+		case 25 ... 32:
+			v.bits_per_pixel = 32;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	switch (var_to_depth(&v)) {
+                case 8:
+                        nom = den = 1;
+                        v.red.offset = v.green.offset = v.blue.offset = 0;
+                        v.red.length = v.green.length = v.blue.length = 8;
+                        v.transp.offset = v.transp.length = 0;
+                        break;
+		case 15:
+			nom = 2;
+			den = 1;
+			v.red.offset = 10;
+			v.green.offset = 5;
+			v.red.offset = 0;
+			v.red.length = v.green.length = v.blue.length = 5;
+			v.transp.offset = v.transp.length = 0;
+			break;
+                case 16:
+                        nom = 2;
+                        den = 1;
+                        v.red.offset = 11;
+                        v.green.offset = 5;
+                        v.blue.offset = 0;
+                        v.red.length = 5;
+                        v.green.length = 6;
+                        v.blue.length = 5;
+                        v.transp.offset = v.transp.length = 0;
+                        break;
+                case 24:
+                        nom = 4;
+                        den = 1;
+                        v.red.offset = 16;
+                        v.green.offset = 8;
+                        v.blue.offset = 0;
+                        v.red.length = v.blue.length = v.green.length = 8;
+                        v.transp.offset = v.transp.length = 0;
+                        break;
+                case 32:
+                        nom = 4;
+                        den = 1;
+                        v.red.offset = 16;
+                        v.green.offset = 8;
+                        v.blue.offset = 0;
+                        v.red.length = v.blue.length = v.green.length = 8;
+                        v.transp.offset = 24;
+                        v.transp.length = 8;
+                        break;
+                default:
+                        printk ("radeonfb: mode %dx%dx%d rejected, color depth invalid\n",
+                                var->xres, var->yres, var->bits_per_pixel);
+                        return -EINVAL;
+        }
+
+        if (radeon_do_maximize(rinfo, var, &v, nom, den) < 0)
+                return -EINVAL;
+
+        if (v.xoffset < 0)
+                v.xoffset = 0;
+        if (v.yoffset < 0)
+                v.yoffset = 0;
+
+        if (v.xoffset > v.xres_virtual - v.xres)
+                v.xoffset = v.xres_virtual - v.xres - 1;
+
+        if (v.yoffset > v.yres_virtual - v.yres)
+                v.yoffset = v.yres_virtual - v.yres - 1;
+
+        v.red.msb_right = v.green.msb_right = v.blue.msb_right =
+                          v.transp.offset = v.transp.length =
+                          v.transp.msb_right = 0;
+
+	if (noaccel)
+		v.accel_flags = 0;
+
+        memcpy(var, &v, sizeof(v));
+
+        return 0;
+}
+
+
+static int radeonfb_pan_display (struct fb_var_screeninfo *var,
+                                 struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = info->par;
+
+        if ((var->xoffset + var->xres > var->xres_virtual)
+	    || (var->yoffset + var->yres > var->yres_virtual))
+               return -EINVAL;
+
+        if (rinfo->asleep)
+        	return 0;
+
+        OUTREG(CRTC_OFFSET, ((var->yoffset * var->xres_virtual + var->xoffset)
+			     * var->bits_per_pixel / 8) & ~7);
+        return 0;
+}
+
+
+static int radeonfb_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
+                           unsigned long arg, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = info->par;
+	unsigned int tmp;
+	u32 value = 0;
+	int rc;
+
+	switch (cmd) {
+		/*
+		 * TODO:  set mirror accordingly for non-Mobility chipsets with 2 CRTC's
+		 */
+		case FBIO_RADEON_SET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_R100:
+				case RADEON_RV100:
+				case RADEON_R200:
+				case RADEON_RV200:
+				case RADEON_RV250:
+				case RADEON_R300:
+					return -EINVAL;
+				default:
+					/* RADEON M6, RADEON_M7, RADEON_M9 */
+					break;
+			}
+
+			rc = get_user(value, (__u32*)arg);
+
+			if (rc)
+				return rc;
+
+			if (value & 0x01) {
+				tmp = INREG(LVDS_GEN_CNTL);
+
+				tmp |= (LVDS_ON | LVDS_BLON);
+			} else {
+				tmp = INREG(LVDS_GEN_CNTL);
+
+				tmp &= ~(LVDS_ON | LVDS_BLON);
+			}
+
+			OUTREG(LVDS_GEN_CNTL, tmp);
+
+			if (value & 0x02) {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp |= CRTC_CRT_ON;
+
+				mirror = 1;
+			} else {
+				tmp = INREG(CRTC_EXT_CNTL);
+				tmp &= ~CRTC_CRT_ON;
+
+				mirror = 0;
+			}
+
+			OUTREG(CRTC_EXT_CNTL, tmp);
+
+			break;
+		case FBIO_RADEON_GET_MIRROR:
+			switch (rinfo->arch) {
+				case RADEON_R100:
+				case RADEON_RV100:
+				case RADEON_R200:
+				case RADEON_RV200:
+				case RADEON_RV250:
+				case RADEON_R300:
+					return -EINVAL;
+				default:
+					/* RADEON M6, RADEON_M7, RADEON_M9 */
+					break;
+			}
+
+			tmp = INREG(LVDS_GEN_CNTL);
+			if ((LVDS_ON | LVDS_BLON) & tmp)
+				value |= 0x01;
+
+			tmp = INREG(CRTC_EXT_CNTL);
+			if (CRTC_CRT_ON & tmp)
+				value |= 0x02;
+
+			return put_user(value, (__u32*)arg);
+		default:
+			return -EINVAL;
+	}
+
+	return -EINVAL;
+}
+
+
+int radeonfb_blank (int blank, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = info->par;
+        u32 val = INREG(CRTC_EXT_CNTL);
+	u32 val2 = INREG(LVDS_GEN_CNTL);
+
+	if (rinfo->asleep)
+		return 0;
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (rinfo->mon1_type == MT_LCD && _machine == _MACH_Pmac) {
+		set_backlight_enable(!blank);
+		return 0;
+	}
+#endif
+
+        /* reset it */
+        val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
+                 CRTC_VSYNC_DIS);
+	val2 &= ~(LVDS_DISPLAY_DIS);
+
+        switch (blank) {
+                case VESA_NO_BLANKING:
+                        break;
+                case VESA_VSYNC_SUSPEND:
+                        val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
+                        break;
+                case VESA_HSYNC_SUSPEND:
+                        val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
+                        break;
+                case VESA_POWERDOWN:
+                        val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
+                                CRTC_HSYNC_DIS);
+			val2 |= (LVDS_DISPLAY_DIS);
+                        break;
+        }
+
+	switch (rinfo->mon1_type) {
+		case MT_LCD:
+			OUTREG(LVDS_GEN_CNTL, val2);
+			break;
+		case MT_CRT:
+		default:
+		        OUTREG(CRTC_EXT_CNTL, val);
+			break;
+	}
+
+	return 0;
+}
+
+
+static int radeonfb_setcolreg (unsigned regno, unsigned red, unsigned green,
+                             unsigned blue, unsigned transp, struct fb_info *info)
+{
+        struct radeonfb_info *rinfo = info->par;
+	u32 pindex;
+	unsigned int i;
+
+	if (regno > 255)
+		return 1;
+
+	red >>= 8;
+	green >>= 8;
+	blue >>= 8;
+	rinfo->palette[regno].red = red;
+	rinfo->palette[regno].green = green;
+	rinfo->palette[regno].blue = blue;
+
+        /* default */
+        pindex = regno;
+
+        if (!rinfo->asleep) {
+        	u32 dac_cntl2, vclk_cntl;
+
+		vclk_cntl = INPLL(VCLK_ECP_CNTL);
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
+
+		/* Make sure we are on first palette */
+		if (rinfo->has_CRTC2) {
+			dac_cntl2 = INREG(DAC_CNTL2);
+			dac_cntl2 &= ~DAC2_PALETTE_ACCESS_CNTL;
+			OUTREG(DAC_CNTL2, dac_cntl2);
+		}
+
+		if (rinfo->bpp == 16) {
+			pindex = regno * 8;
+
+			if (rinfo->depth == 16 && regno > 63)
+				return 1;
+			if (rinfo->depth == 15 && regno > 31)
+				return 1;
+
+			/* For 565, the green component is mixed one order below */
+			if (rinfo->depth == 16) {
+		                OUTREG(PALETTE_INDEX, pindex>>1);
+	       	         	OUTREG(PALETTE_DATA, (rinfo->palette[regno>>1].red << 16) |
+	                        	(green << 8) | (rinfo->palette[regno>>1].blue));
+	                	green = rinfo->palette[regno<<1].green;
+	        	}
+		}
+
+		if (rinfo->depth != 16 || regno < 32) {
+			OUTREG(PALETTE_INDEX, pindex);
+			OUTREG(PALETTE_DATA, (red << 16) | (green << 8) | blue);
+		}
+
+		OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
+	}
+ 	if (regno < 16) {
+        	switch (rinfo->depth) {
+		case 15:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 10) | (regno << 5) | regno;
+			break;
+		case 16:
+			((u16 *) (info->pseudo_palette))[regno] =
+			    (regno << 11) | (regno << 6) | regno;
+			break;
+		case 24:
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (regno << 16) | (regno << 8) | regno;
+			break;
+		case 32:
+			i = (regno << 8) | regno;
+			((u32 *) (info->pseudo_palette))[regno] =
+			    (i << 16) | i;
+			break;
+		}
+        }
+	return 0;
+}
+
+
+static void radeon_save_state (struct radeonfb_info *rinfo, struct radeon_regs *save)
+{
+	/* CRTC regs */
+	save->crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
+	save->crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+	save->crtc_more_cntl = INREG(CRTC_MORE_CNTL);
+	save->dac_cntl = INREG(DAC_CNTL);
+        save->crtc_h_total_disp = INREG(CRTC_H_TOTAL_DISP);
+        save->crtc_h_sync_strt_wid = INREG(CRTC_H_SYNC_STRT_WID);
+        save->crtc_v_total_disp = INREG(CRTC_V_TOTAL_DISP);
+        save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
+	save->crtc_pitch = INREG(CRTC_PITCH);
+	save->surface_cntl = INREG(SURFACE_CNTL);
+
+	/* FP regs */
+	save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
+	save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
+	save->fp_gen_cntl = INREG(FP_GEN_CNTL);
+	save->fp_h_sync_strt_wid = INREG(FP_H_SYNC_STRT_WID);
+	save->fp_horz_stretch = INREG(FP_HORZ_STRETCH);
+	save->fp_v_sync_strt_wid = INREG(FP_V_SYNC_STRT_WID);
+	save->fp_vert_stretch = INREG(FP_VERT_STRETCH);
+	save->lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	save->lvds_pll_cntl = INREG(LVDS_PLL_CNTL);
+	save->tmds_crc = INREG(TMDS_CRC);	save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
+	save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
+}
+
+
+static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
+{
+	/* Workaround from XFree */
+	if (rinfo->arch < RADEON_R300) {
+	        /* A temporal workaround for the occational blanking on certain laptop panels.
+	           This appears to related to the PLL divider registers (fail to lock?).
+		   It occurs even when all dividers are the same with their old settings.
+	           In this case we really don't need to fiddle with PLL registers.
+	           By doing this we can avoid the blanking problem with some panels.
+	        */
+		if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) &&
+		    (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) &
+		    		(PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK))))
+            		return;
+	}
+
+	while ((INREG(CLOCK_CNTL_INDEX) & PPLL_DIV_SEL_MASK) !=
+	       PPLL_DIV_SEL_MASK) {
+		OUTREGP(CLOCK_CNTL_INDEX, PPLL_DIV_SEL_MASK, 0xffff);
+	}
+
+	OUTPLLP(PPLL_CNTL, PPLL_RESET, 0xffff);
+
+	while ((INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK) !=
+	       (mode->ppll_ref_div & PPLL_REF_DIV_MASK)) {
+		OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK);
+	}
+
+	while ((INPLL(PPLL_DIV_3) & PPLL_FB3_DIV_MASK) !=
+	       (mode->ppll_div_3 & PPLL_FB3_DIV_MASK)) {
+		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK);
+	}
+
+	while ((INPLL(PPLL_DIV_3) & PPLL_POST3_DIV_MASK) !=
+	       (mode->ppll_div_3 & PPLL_POST3_DIV_MASK)) {
+		OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK);
+	}
+
+	OUTPLL(HTOTAL_CNTL, 0);
+
+	OUTPLLP(PPLL_CNTL, 0, ~PPLL_RESET);
+}
+
+
+static void radeon_write_mode (struct radeonfb_info *rinfo,
+                               struct radeon_regs *mode)
+{
+	int i;
+	int primary_mon = PRIMARY_MONITOR(rinfo);
+
+	if (nomodeset)
+		return;
+
+	radeonfb_blank(VESA_POWERDOWN, rinfo->info);
+
+	if (rinfo->arch == RADEON_M6) {
+		for (i=0; i<8; i++)
+			OUTREG(common_regs_m6[i].reg, common_regs_m6[i].val);
+	} else {
+		for (i=0; i<9; i++)
+			OUTREG(common_regs[i].reg, common_regs[i].val);
+	}
+
+	OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl);
+	OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl,
+		CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS);
+	OUTREG(CRTC_MORE_CNTL, mode->crtc_more_cntl);
+	OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING);
+	OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp);
+	OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid);
+	OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp);
+	OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid);
+	OUTREG(CRTC_OFFSET, 0);
+	OUTREG(CRTC_OFFSET_CNTL, 0);
+	OUTREG(CRTC_PITCH, mode->crtc_pitch);
+	OUTREG(SURFACE_CNTL, mode->surface_cntl);
+
+	radeon_write_pll_regs(rinfo, mode);
+
+#if 0
+	/* Those don't seem to actually exist in radeon's, despite some drivers still
+	 * apparently trying to fill them, including some ATI sample codes ...
+	 * Can someone confirm what's up ? --BenH.
+	 */
+	OUTREG(DDA_CONFIG, mode->dda_config);
+	OUTREG(DDA_ON_OFF, mode->dda_on_off);
+#endif
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+		OUTREG(FP_CRTC_H_TOTAL_DISP, mode->fp_crtc_h_total_disp);
+		OUTREG(FP_CRTC_V_TOTAL_DISP, mode->fp_crtc_v_total_disp);
+		OUTREG(FP_H_SYNC_STRT_WID, mode->fp_h_sync_strt_wid);
+		OUTREG(FP_V_SYNC_STRT_WID, mode->fp_v_sync_strt_wid);
+		OUTREG(FP_HORZ_STRETCH, mode->fp_horz_stretch);
+		OUTREG(FP_VERT_STRETCH, mode->fp_vert_stretch);
+		OUTREG(FP_GEN_CNTL, mode->fp_gen_cntl);
+		OUTREG(TMDS_CRC, mode->tmds_crc);
+		OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
+
+		if (primary_mon == MT_LCD) {
+			unsigned int tmp = INREG(LVDS_GEN_CNTL);
+
+			mode->lvds_gen_cntl &= ~LVDS_STATE_MASK;
+			mode->lvds_gen_cntl |= (rinfo->init_state.lvds_gen_cntl & LVDS_STATE_MASK);
+
+			if ((tmp & (LVDS_ON | LVDS_BLON)) ==
+			    (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON))) {
+				OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+			} else {
+				if (mode->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				} else {
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl |
+					       LVDS_BLON);
+					udelay(1000);
+					OUTREG(LVDS_GEN_CNTL, mode->lvds_gen_cntl);
+				}
+			}
+		}
+	}
+
+	radeonfb_blank(VESA_NO_BLANKING, rinfo->info);
+
+	OUTPLL(VCLK_ECP_CNTL, mode->vclk_ecp_cntl);
+
+	return;
+}
+
+
+static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, unsigned long freq)
+{
+	const struct {
+		int divider;
+		int bitvalue;
+	} *post_div,
+	  post_divs[] = {
+		{ 1,  0 },
+		{ 2,  1 },
+		{ 4,  2 },
+		{ 8,  3 },
+		{ 3,  4 },
+		{ 16, 5 },
+		{ 6,  6 },
+		{ 12, 7 },
+		{ 0,  0 },
+	};
+
+	if (freq > rinfo->pll.ppll_max)
+		freq = rinfo->pll.ppll_max;
+	if (freq*12 < rinfo->pll.ppll_min)
+		freq = rinfo->pll.ppll_min / 12;
+
+
+	for (post_div = &post_divs[0]; post_div->divider; ++post_div) {
+		rinfo->pll_output_freq = post_div->divider * freq;
+		if (rinfo->pll_output_freq >= rinfo->pll.ppll_min  &&
+		    rinfo->pll_output_freq <= rinfo->pll.ppll_max)
+			break;
+	}
+
+	/* Why do we have those in rinfo at this point ? --BenH */
+	rinfo->post_div = post_div->divider;
+	rinfo->fb_div = round_div(rinfo->pll.ref_div*rinfo->pll_output_freq,
+				  rinfo->pll.ref_clk);
+	regs->ppll_ref_div = rinfo->pll.ref_div;
+	regs->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
+
+#ifdef CONFIG_ALL_PPC
+	/* Gross hack for iBook with M7 until I find out a proper fix */
+	if (machine_is_compatible("PowerBook4,3") && rinfo->arch == RADEON_M7)
+		regs->ppll_div_3 = 0x000600ad;
+#endif /* CONFIG_ALL_PPC */
+
+	RTRACE("post div = 0x%x\n", rinfo->post_div);
+	RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
+	RTRACE("ppll_div_3 = 0x%x\n", regs->ppll_div_3);
+}
+
+
+int radeonfb_set_par (struct fb_info *info)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)info->par;
+	struct fb_var_screeninfo *mode = &info->var;
+	struct radeon_regs newmode;
+	int hTotal, vTotal, hSyncStart, hSyncEnd,
+	    hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync;
+	u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
+	u8 hsync_fudge_fp[] = {2, 2, 0, 0, 5, 5};
+	u32 sync, h_sync_pol, v_sync_pol, dotClock, pixClock;
+	int freq;
+        int format = 0;
+	int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
+	int primary_mon = PRIMARY_MONITOR(rinfo);
+	int depth = var_to_depth(mode);
+        int accel = (mode->accel_flags & FB_ACCELF_TEXT) != 0;
+
+	rinfo->xres = mode->xres;
+	rinfo->yres = mode->yres;
+	rinfo->xres_virtual = mode->xres_virtual;
+	rinfo->yres_virtual = mode->yres_virtual;
+	rinfo->pixclock = mode->pixclock;
+
+	hSyncStart = mode->xres + mode->right_margin;
+	hSyncEnd = hSyncStart + mode->hsync_len;
+	hTotal = hSyncEnd + mode->left_margin;
+
+	vSyncStart = mode->yres + mode->lower_margin;
+	vSyncEnd = vSyncStart + mode->vsync_len;
+	vTotal = vSyncEnd + mode->upper_margin;
+	pixClock = mode->pixclock;
+
+	sync = mode->sync;
+	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+		if (rinfo->panel_info.xres < mode->xres)
+			rinfo->xres = mode->xres = rinfo->panel_info.xres;
+		if (rinfo->panel_info.yres < mode->yres)
+			rinfo->yres = mode->yres = rinfo->panel_info.yres;
+
+		hTotal = mode->xres + rinfo->panel_info.hblank;
+		hSyncStart = mode->xres + rinfo->panel_info.hOver_plus;
+		hSyncEnd = hSyncStart + rinfo->panel_info.hSync_width;
+
+		vTotal = mode->yres + rinfo->panel_info.vblank;
+		vSyncStart = mode->yres + rinfo->panel_info.vOver_plus;
+		vSyncEnd = vSyncStart + rinfo->panel_info.vSync_width;
+
+		h_sync_pol = !rinfo->panel_info.hAct_high;
+		v_sync_pol = !rinfo->panel_info.vAct_high;
+
+		pixClock = 100000000 / rinfo->panel_info.clock;
+	}
+	dotClock = 1000000000 / pixClock;
+	freq = dotClock / 10; /* x100 */
+
+	RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
+		hSyncStart, hSyncEnd, hTotal);
+	RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
+		vSyncStart, vSyncEnd, vTotal);
+
+	hsync_wid = (hSyncEnd - hSyncStart) / 8;
+	vsync_wid = vSyncEnd - vSyncStart;
+	if (hsync_wid == 0)
+		hsync_wid = 1;
+	else if (hsync_wid > 0x3f)	/* max */
+		hsync_wid = 0x3f;
+
+	if (vsync_wid == 0)
+		vsync_wid = 1;
+	else if (vsync_wid > 0x1f)	/* max */
+		vsync_wid = 0x1f;
+
+	hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+	vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+	cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
+
+	format = radeon_get_dstbpp(depth);
+	bytpp = mode->bits_per_pixel >> 3;
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
+		hsync_fudge = hsync_fudge_fp[format-1];
+	else
+		hsync_fudge = hsync_adj_tab[format-1];
+
+	hsync_start = hSyncStart - 8 + hsync_fudge;
+
+	newmode.crtc_gen_cntl = CRTC_EXT_DISP_EN | CRTC_EN |
+				(format << 8);
+
+	/* Clear auto-center etc... */
+	newmode.crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
+	newmode.crtc_more_cntl &= 0xfffffff0;
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
+		if (mirror)
+			newmode.crtc_ext_cntl |= CRTC_CRT_ON;
+
+		newmode.crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
+					   CRTC_INTERLACE_EN);
+	} else {
+		newmode.crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN |
+					CRTC_CRT_ON;
+	}
+
+	newmode.dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN |
+			   DAC_8BIT_EN;
+
+	newmode.crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
+				     (((mode->xres / 8) - 1) << 16));
+
+	newmode.crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
+					(hsync_wid << 16) | (h_sync_pol << 23));
+
+	newmode.crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
+				    ((mode->yres - 1) << 16);
+
+	newmode.crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) |
+					 (vsync_wid << 16) | (v_sync_pol  << 23));
+
+	if (accel) {
+		/* We first calculate the engine pitch */
+		rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
+ 				& ~(0x3f)) >> 6;
+
+		/* Then, re-multiply it to get the CRTC pitch */
+		newmode.crtc_pitch = (rinfo->pitch << 3) / ((mode->bits_per_pixel + 1) / 8);
+	} else
+		newmode.crtc_pitch = (mode->xres_virtual >> 3);
+
+	newmode.crtc_pitch |= (newmode.crtc_pitch << 16);
+
+	/*
+	 * It looks like recent chips have a problem with SURFACE_CNTL,
+	 * setting SURF_TRANSLATION_DIS completely disables the
+	 * swapper as well, so we leave it unset now.
+	 */
+	newmode.surface_cntl = 0;
+
+#if defined(__BIG_ENDIAN)
+
+	/* Setup swapping on both apertures, though we currently
+	 * only use aperture 0, enabling swapper on aperture 1
+	 * won't harm
+	 */
+	switch (mode->bits_per_pixel) {
+		case 16:
+			newmode.surface_cntl |= NONSURF_AP0_SWP_16BPP;
+			newmode.surface_cntl |= NONSURF_AP1_SWP_16BPP;
+			break;
+		case 24:
+		case 32:
+			newmode.surface_cntl |= NONSURF_AP0_SWP_32BPP;
+			newmode.surface_cntl |= NONSURF_AP1_SWP_32BPP;
+			break;
+	}
+#endif
+
+	RTRACE("h_total_disp = 0x%x\t   hsync_strt_wid = 0x%x\n",
+		newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid);
+	RTRACE("v_total_disp = 0x%x\t   vsync_strt_wid = 0x%x\n",
+		newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid);
+
+	newmode.xres = mode->xres;
+	newmode.yres = mode->yres;
+
+	rinfo->bpp = mode->bits_per_pixel;
+	rinfo->depth = depth;
+
+	RTRACE("pixclock = %lu\n", (unsigned long)pixClock);
+	RTRACE("freq = %lu\n", (unsigned long)freq);
+	radeon_calc_pll_regs(rinfo, &newmode, freq);
+
+	newmode.vclk_ecp_cntl = rinfo->init_state.vclk_ecp_cntl;
+
+	if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) {
+		unsigned int hRatio, vRatio;
+
+		if (mode->xres > rinfo->panel_info.xres)
+			mode->xres = rinfo->panel_info.xres;
+		if (mode->yres > rinfo->panel_info.yres)
+			mode->yres = rinfo->panel_info.yres;
+
+		newmode.fp_horz_stretch = (((rinfo->panel_info.xres / 8) - 1)
+					   << HORZ_PANEL_SHIFT);
+		newmode.fp_vert_stretch = ((rinfo->panel_info.yres - 1)
+					   << VERT_PANEL_SHIFT);
+
+		if (mode->xres != rinfo->panel_info.xres) {
+			hRatio = round_div(mode->xres * HORZ_STRETCH_RATIO_MAX,
+					   rinfo->panel_info.xres);
+			newmode.fp_horz_stretch = (((((unsigned long)hRatio) & HORZ_STRETCH_RATIO_MASK)) |
+						   (newmode.fp_horz_stretch &
+						    (HORZ_PANEL_SIZE | HORZ_FP_LOOP_STRETCH |
+						     HORZ_AUTO_RATIO_INC)));
+			newmode.fp_horz_stretch |= (HORZ_STRETCH_BLEND |
+						    HORZ_STRETCH_ENABLE);
+		}
+		newmode.fp_horz_stretch &= ~HORZ_AUTO_RATIO;
+
+		if (mode->yres != rinfo->panel_info.yres) {
+			vRatio = round_div(mode->yres * VERT_STRETCH_RATIO_MAX,
+					   rinfo->panel_info.yres);
+			newmode.fp_vert_stretch = (((((unsigned long)vRatio) & VERT_STRETCH_RATIO_MASK)) |
+						   (newmode.fp_vert_stretch &
+						   (VERT_PANEL_SIZE | VERT_STRETCH_RESERVED)));
+			newmode.fp_vert_stretch |= (VERT_STRETCH_BLEND |
+						    VERT_STRETCH_ENABLE);
+		}
+		newmode.fp_vert_stretch &= ~VERT_AUTO_RATIO_EN;
+
+		newmode.fp_gen_cntl = (rinfo->init_state.fp_gen_cntl & (u32)
+				       ~(FP_SEL_CRTC2 |
+					 FP_RMX_HVSYNC_CONTROL_EN |
+					 FP_DFP_SYNC_SEL |
+					 FP_CRT_SYNC_SEL |
+					 FP_CRTC_LOCK_8DOT |
+					 FP_USE_SHADOW_EN |
+					 FP_CRTC_USE_SHADOW_VEND |
+					 FP_CRT_SYNC_ALT));
+
+		newmode.fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR |
+					FP_CRTC_DONT_SHADOW_HEND);
+
+		newmode.lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
+		newmode.lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
+		newmode.tmds_crc = rinfo->init_state.tmds_crc;
+		newmode.tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
+
+		if (primary_mon == MT_LCD) {
+			newmode.lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
+			newmode.fp_gen_cntl &= ~(FP_FPON | FP_TMDS_EN);
+		} else {
+			/* DFP */
+			newmode.fp_gen_cntl |= (FP_FPON | FP_TMDS_EN);
+			newmode.tmds_transmitter_cntl = (TMDS_RAN_PAT_RST | TMDS_ICHCSEL) &
+							 ~(TMDS_PLLRST);
+			/* TMDS_PLL_EN bit is reversed on RV (and mobility) chips */
+			if (rinfo->arch == RADEON_R100 ||
+			    rinfo->arch == RADEON_R200 ||
+			    rinfo->arch == RADEON_R300 ||
+			    rinfo->arch == RADEON_R350)
+				newmode.tmds_transmitter_cntl &= ~TMDS_PLL_EN;
+			else
+				newmode.tmds_transmitter_cntl |= TMDS_PLL_EN;
+			newmode.crtc_ext_cntl &= ~CRTC_CRT_ON;
+		}
+
+		newmode.fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) |
+				(((mode->xres / 8) - 1) << 16));
+		newmode.fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) |
+				((mode->yres - 1) << 16);
+		newmode.fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) |
+				(hsync_wid << 16) | (h_sync_pol << 23));
+		newmode.fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) |
+				(vsync_wid << 16) | (v_sync_pol  << 23));
+	}
+
+	/* do it! */
+	if (!rinfo->asleep) {
+		radeon_write_mode (rinfo, &newmode);
+		/* (re)initialize the engine */
+		if (accel)
+			radeon_engine_init (rinfo);
+
+	}
+	/* Update fix */
+	if (accel)
+        	info->fix.line_length = rinfo->pitch*64;
+        else
+		info->fix.line_length = mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8);
+        info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+
+#ifdef CONFIG_BOOTX_TEXT
+	/* Update debug text engine */
+	btext_update_display(rinfo->fb_base_phys, mode->xres, mode->yres,
+			     rinfo->depth, info->fix.line_length);
+#endif
+
+	return 0;
+}
+
+
+
+static struct fb_ops radeonfb_ops = {
+	.owner			= THIS_MODULE,
+	.fb_check_var		= radeonfb_check_var,
+	.fb_set_par		= radeonfb_set_par,
+	.fb_setcolreg		= radeonfb_setcolreg,
+	.fb_pan_display 	= radeonfb_pan_display,
+	.fb_blank		= radeonfb_blank,
+	.fb_ioctl		= radeonfb_ioctl,
+#if 0
+	.fb_fillrect	= radeonfb_fillrect,
+	.fb_copyarea	= radeonfb_copyarea,
+	.fb_imageblit	= radeonfb_imageblit,
+	.fb_rasterimg	= radeonfb_rasterimg,
+#else
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+#endif
+	.fb_cursor	= soft_cursor,
+};
+
+
+static int __devinit radeon_set_fbinfo (struct radeonfb_info *rinfo)
+{
+	struct fb_info *info;
+
+	info = rinfo->info;
+
+	info->pseudo_palette = rinfo->pseudo_palette;
+        info->flags = FBINFO_FLAG_DEFAULT;
+        info->fbops = &radeonfb_ops;
+        info->display_fg = NULL;
+        info->screen_base = (char *)rinfo->fb_base;
+
+	/* Fill fix common fields */
+	strlcpy(info->fix.id, rinfo->name, sizeof(info->fix.id));
+        info->fix.smem_start = rinfo->fb_base_phys;
+        info->fix.smem_len = rinfo->video_ram;
+        info->fix.type = FB_TYPE_PACKED_PIXELS;
+        info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+        info->fix.xpanstep = 8;
+        info->fix.ypanstep = 1;
+        info->fix.ywrapstep = 0;
+        info->fix.type_aux = 0;
+        info->fix.mmio_start = rinfo->mmio_base_phys;
+        info->fix.mmio_len = RADEON_REGSIZE;
+	if (noaccel)
+	        info->fix.accel = FB_ACCEL_NONE;
+	else
+		info->fix.accel = FB_ACCEL_ATI_RADEON;
+
+	fb_alloc_cmap(&info->cmap, 256, 0);
+
+	if (noaccel)
+		info->var.accel_flags &= ~FB_ACCELF_TEXT;
+	else
+		info->var.accel_flags |= FB_ACCELF_TEXT;
+
+        return 0;
+}
+
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+
+/* TODO: Dbl check these tables, we don't go up to full ON backlight
+ * in these, possibly because we noticed MacOS doesn't, but I'd prefer
+ * having some more official numbers from ATI
+ */
+static int backlight_conv_m6[] = {
+	0xff, 0xc0, 0xb5, 0xaa, 0x9f, 0x94, 0x89, 0x7e,
+	0x73, 0x68, 0x5d, 0x52, 0x47, 0x3c, 0x31, 0x24
+};
+static int backlight_conv_m7[] = {
+	0x00, 0x3f, 0x4a, 0x55, 0x60, 0x6b, 0x76, 0x81,
+	0x8c, 0x97, 0xa2, 0xad, 0xb8, 0xc3, 0xce, 0xd9
+};
+
+#define BACKLIGHT_LVDS_OFF
+#undef BACKLIGHT_DAC_OFF
+
+/* We turn off the LCD completely instead of just dimming the backlight.
+ * This provides some greater power saving and the display is useless
+ * without backlight anyway.
+ */
+static int radeon_set_backlight_enable(int on, int level, void *data)
+{
+	struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
+	unsigned int lvds_gen_cntl = INREG(LVDS_GEN_CNTL);
+	int* conv_table;
+
+	/* Pardon me for that hack... maybe some day we can figure
+	 * out in what direction backlight should work on a given
+	 * panel ?
+	 */
+	if ((rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
+		&& !machine_is_compatible("PowerBook4,3"))
+		conv_table = backlight_conv_m7;
+	else
+		conv_table = backlight_conv_m6;
+
+	lvds_gen_cntl |= (LVDS_BL_MOD_EN | LVDS_BLON);
+	if (on && (level > BACKLIGHT_OFF)) {
+		lvds_gen_cntl |= LVDS_DIGON;
+		if (!lvds_gen_cntl & LVDS_ON) {
+			lvds_gen_cntl &= ~LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+			(void)INREG(LVDS_GEN_CNTL);
+			mdelay(10);
+			lvds_gen_cntl |= LVDS_BLON;
+			OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		}
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[level] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= (LVDS_ON | LVDS_EN);
+		lvds_gen_cntl &= ~LVDS_DISPLAY_DIS;
+	} else {
+		lvds_gen_cntl &= ~LVDS_BL_MOD_LEVEL_MASK;
+		lvds_gen_cntl |= (conv_table[0] <<
+				  LVDS_BL_MOD_LEVEL_SHIFT);
+		lvds_gen_cntl |= LVDS_DISPLAY_DIS;
+		OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+		udelay(10);
+		lvds_gen_cntl &= ~(LVDS_ON | LVDS_EN | LVDS_BLON | LVDS_DIGON);
+	}
+
+	OUTREG(LVDS_GEN_CNTL, lvds_gen_cntl);
+	rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
+	rinfo->init_state.lvds_gen_cntl |= (lvds_gen_cntl & LVDS_STATE_MASK);
+
+	return 0;
+}
+
+
+static int radeon_set_backlight_level(int level, void *data)
+{
+	return radeon_set_backlight_enable(1, level, data);
+}
+#endif /* CONFIG_PMAC_BACKLIGHT */
+
+
+/*
+ * This reconfigure the card's internal memory map. In theory, we'd like
+ * to setup the card's memory at the same address as it's PCI bus address,
+ * and the AGP aperture right after that so that system RAM on 32 bits
+ * machines at least, is directly accessible. However, doing so would
+ * conflict with the current XFree drivers...
+ * Ultimately, I hope XFree, GATOS and ATI binary drivers will all agree
+ * on the proper way to set this up and duplicate this here. In the meantime,
+ * I put the card's memory at 0 in card space and AGP at some random high
+ * local (0xe0000000 for now) that will be changed by XFree/DRI anyway
+ */
+#ifdef CONFIG_PPC_OF
+#undef SET_MC_FB_FROM_APERTURE
+static void fixup_memory_mappings(struct radeonfb_info *rinfo)
+{
+	u32 save_crtc_gen_cntl, save_crtc2_gen_cntl;
+	u32 save_crtc_ext_cntl;
+	u32 aper_base, aper_size;
+	u32 agp_base;
+
+	/* First, we disable display to avoid interfering */
+	if (rinfo->has_CRTC2) {
+		save_crtc2_gen_cntl = INREG(CRTC2_GEN_CNTL);
+		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl | CRTC2_DISP_REQ_EN_B);
+	}
+	save_crtc_gen_cntl = INREG(CRTC_GEN_CNTL);
+	save_crtc_ext_cntl = INREG(CRTC_EXT_CNTL);
+
+	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl | CRTC_DISPLAY_DIS);
+	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl | CRTC_DISP_REQ_EN_B);
+	mdelay(100);
+
+	aper_base = INREG(CONFIG_APER_0_BASE);
+	aper_size = INREG(CONFIG_APER_SIZE);
+
+#ifdef SET_MC_FB_FROM_APERTURE
+	/* Set framebuffer to be at the same address as set in PCI BAR */
+	OUTREG(MC_FB_LOCATION,
+		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16));
+	rinfo->fb_local_base = aper_base;
+#else
+	OUTREG(MC_FB_LOCATION, 0x7fff0000);
+	rinfo->fb_local_base = 0;
+#endif
+	agp_base = aper_base + aper_size;
+	if (agp_base & 0xf0000000)
+		agp_base = (aper_base | 0x0fffffff) + 1;
+
+	/* Set AGP to be just after the framebuffer on a 256Mb boundary. This
+	 * assumes the FB isn't mapped to 0xf0000000 or above, but this is
+	 * always the case on PPCs afaik.
+	 */
+#ifdef SET_MC_FB_FROM_APERTURE
+	OUTREG(MC_AGP_LOCATION, 0xffff0000 | (agp_base >> 16));
+#else
+	OUTREG(MC_AGP_LOCATION, 0xffffe000);
+#endif
+
+	/* Fixup the display base addresses & engine offsets while we
+	 * are at it as well
+	 */
+#ifdef SET_MC_FB_FROM_APERTURE
+	OUTREG(DISPLAY_BASE_ADDR, aper_base);
+	if (rinfo->has_CRTC2)
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, aper_base);
+#else
+	OUTREG(DISPLAY_BASE_ADDR, 0);
+	if (rinfo->has_CRTC2)
+		OUTREG(CRTC2_DISPLAY_BASE_ADDR, 0);
+#endif
+	mdelay(100);
+
+	/* Restore display settings */
+	OUTREG(CRTC_GEN_CNTL, save_crtc_gen_cntl);
+	OUTREG(CRTC_EXT_CNTL, save_crtc_ext_cntl);
+	if (rinfo->has_CRTC2)
+		OUTREG(CRTC2_GEN_CNTL, save_crtc2_gen_cntl);
+
+	RTRACE("aper_base: %08x MC_FB_LOC to: %08x, MC_AGP_LOC to: %08x\n",
+		aper_base,
+		((aper_base + aper_size - 1) & 0xffff0000) | (aper_base >> 16),
+		0xffff0000 | (agp_base >> 16));
+}
+#endif /* CONFIG_PPC_OF */
+
+
+/*
+ * Sysfs
+ */
+
+static ssize_t radeon_show_one_edid(char *buf, loff_t off, size_t count, const u8 *edid)
+{
+	if (off > EDID_LENGTH)
+		return 0;
+
+	if (off + count > EDID_LENGTH)
+		count = EDID_LENGTH - off;
+
+	memcpy(buf, edid + off, count);
+
+	return count;
+}
+
+
+static ssize_t radeon_show_edid1(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+	return radeon_show_one_edid(buf, off, count, rinfo->mon1_EDID);
+}
+
+
+static ssize_t radeon_show_edid2(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct pci_dev *pdev = to_pci_dev(dev);
+	struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+	return radeon_show_one_edid(buf, off, count, rinfo->mon2_EDID);
+}
+
+static struct bin_attribute edid1_attr = {
+	.attr   = {
+		.name	= "edid1",
+		.owner	= THIS_MODULE,
+		.mode	= 0444,
+	},
+	.size	= EDID_LENGTH,
+	.read	= radeon_show_edid1,
+};
+
+static struct bin_attribute edid2_attr = {
+	.attr   = {
+		.name	= "edid2",
+		.owner	= THIS_MODULE,
+		.mode	= 0444,
+	},
+	.size	= EDID_LENGTH,
+	.read	= radeon_show_edid2,
+};
+
+
+static int radeonfb_pci_register (struct pci_dev *pdev,
+				  const struct pci_device_id *ent)
+{
+	struct radeonfb_info *rinfo;
+        struct fb_info *info;
+	u32 tmp;
+
+	RTRACE("radeonfb_pci_register BEGIN\n");
+
+	/*
+	 * The driver acknowledges owning secondary devices but they are handled
+	 * by primary
+	 */
+	switch (ent->driver_data) {
+	case RADEON_R200_SEC:
+	case RADEON_RV250_SEC:
+	case RADEON_R300_SEC:
+	case RADEON_R350_SEC:
+	case RADEON_M9_SEC:
+		return 0;
+	default:
+		break;
+	}
+
+	/* Enable device in PCI config */
+	if (pci_enable_device(pdev) != 0) {
+		printk(KERN_ERR "radeonfb: Cannot enable PCI device\n");
+		return -ENODEV;
+	}
+
+        info = framebuffer_alloc(sizeof(struct radeonfb_info), &pdev->dev);
+        if (!info) {
+                printk ("radeonfb: could not allocate memory\n");
+                return -ENODEV;
+        }
+        rinfo = info->par;
+        rinfo->info = info;
+	rinfo->pdev = pdev;
+
+	strcpy(rinfo->name, "ATI Radeon XX ");
+	rinfo->name[11] = ent->device >> 8;
+	rinfo->name[12] = ent->device & 0xFF;
+	rinfo->arch = ent->driver_data;
+
+	/* range check to make sure */
+	if (ent->driver_data < (sizeof(radeon_family)/sizeof(char *)))
+	    strncat(rinfo->name, radeon_family[ent->driver_data], sizeof(rinfo->name));
+
+	/* Set base addrs */
+	rinfo->fb_base_phys = pci_resource_start (pdev, 0);
+	rinfo->mmio_base_phys = pci_resource_start (pdev, 2);
+
+	/* request the mem regions */
+	if (!request_mem_region (rinfo->fb_base_phys,
+				 pci_resource_len(pdev, 0), "radeonfb")) {
+		printk (KERN_ERR "radeonfb: cannot reserve FB region\n");
+		goto free_rinfo;
+	}
+
+	if (!request_mem_region (rinfo->mmio_base_phys,
+				 pci_resource_len(pdev, 2), "radeonfb")) {
+		printk (KERN_ERR "radeonfb: cannot reserve MMIO region\n");
+		goto release_fb;
+	}
+
+	/* map the regions */
+	rinfo->mmio_base = (unsigned long) ioremap (rinfo->mmio_base_phys, RADEON_REGSIZE);
+	if (!rinfo->mmio_base) {
+		printk (KERN_ERR "radeonfb: cannot map MMIO\n");
+		goto release_mmio;
+	}
+
+	rinfo->chipset = pdev->device;
+
+	/* fill some arch-specific flags, could be done via a separate
+	 * table though
+	 */
+	switch (rinfo->arch) {
+	case RADEON_R100:
+	       	rinfo->has_CRTC2 = 0;
+		break;
+	case RADEON_M6:
+	case RADEON_M7:
+	case RADEON_M9:
+		rinfo->is_mobility = 1;
+		/* fall through */
+	default:
+	       	/* all the rest have it */
+	       	rinfo->has_CRTC2 = 1;
+	       	break;
+	}
+
+	/* On PPC, the firmware sets up a memory mapping that tends
+	 * to cause lockups when enabling the engine. We reconfigure
+	 * the card internal memory mappings properly
+	 */
+#ifdef CONFIG_PPC_OF
+	fixup_memory_mappings(rinfo);
+#else
+	rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16;
+#endif /* CONFIG_PPC_OF */
+
+	/* framebuffer size */
+	tmp = INREG(CONFIG_MEMSIZE);
+
+	/* mem size is bits [28:0], mask off the rest */
+	rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK;
+
+	/* ram type */
+	tmp = INREG(MEM_SDRAM_MODE_REG);
+	switch ((MEM_CFG_TYPE & tmp) >> 30) {
+       	case 0:
+       		/* SDR SGRAM (2:1) */
+       		strcpy(rinfo->ram_type, "SDR SGRAM");
+       		rinfo->ram.ml = 4;
+       		rinfo->ram.mb = 4;
+       		rinfo->ram.trcd = 1;
+       		rinfo->ram.trp = 2;
+       		rinfo->ram.twr = 1;
+       		rinfo->ram.cl = 2;
+       		rinfo->ram.loop_latency = 16;
+       		rinfo->ram.rloop = 16;
+       		break;
+       	case 1:
+       		/* DDR SGRAM */
+       		strcpy(rinfo->ram_type, "DDR SGRAM");
+       		rinfo->ram.ml = 4;
+       		rinfo->ram.mb = 4;
+       		rinfo->ram.trcd = 3;
+       		rinfo->ram.trp = 3;
+       		rinfo->ram.twr = 2;
+       		rinfo->ram.cl = 3;
+       		rinfo->ram.tr2w = 1;
+       		rinfo->ram.loop_latency = 16;
+       		rinfo->ram.rloop = 16;
+		break;
+       	default:
+       		/* 64-bit SDR SGRAM */
+       		strcpy(rinfo->ram_type, "SDR SGRAM 64");
+       		rinfo->ram.ml = 4;
+       		rinfo->ram.mb = 8;
+       		rinfo->ram.trcd = 3;
+       		rinfo->ram.trp = 3;
+       		rinfo->ram.twr = 1;
+       		rinfo->ram.cl = 3;
+       		rinfo->ram.tr2w = 1;
+       		rinfo->ram.loop_latency = 17;
+       		rinfo->ram.rloop = 17;
+		break;
+	}
+
+	/*
+	 * Hack to get around some busted production M6's
+	 * reporting no ram
+	 */
+	if (rinfo->video_ram == 0) {
+		switch (pdev->device) {
+	       	case PCI_DEVICE_ID_ATI_RADEON_LY:
+	       	case PCI_DEVICE_ID_ATI_RADEON_LZ:
+	       		rinfo->video_ram = 8192 * 1024;
+	       		break;
+	       	default:
+	       		break;
+		}
+	}
+
+	RTRACE("radeonfb: probed %s %ldk videoram\n", (rinfo->ram_type), (rinfo->video_ram/1024));
+
+	rinfo->fb_base = (unsigned long) ioremap (rinfo->fb_base_phys, rinfo->video_ram);
+	if (!rinfo->fb_base) {
+		printk (KERN_ERR "radeonfb: cannot map FB\n");
+		goto unmap_rom;
+	}
+
+	/*
+	 * Map the BIOS ROM if any and retreive PLL parameters from
+	 * either BIOS or Open Firmware
+	 */
+	rinfo->bios_seg = radeon_map_ROM(rinfo, pdev);
+	radeon_get_pllinfo(rinfo, rinfo->bios_seg);
+
+#ifdef CONFIG_FB_RADEON_I2C
+	/* Register I2C bus */
+	radeon_create_i2c_busses(rinfo);
+#endif
+
+	/* set all the vital stuff */
+	radeon_set_fbinfo (rinfo);
+
+	/* Probe screen types */
+	radeon_probe_screens(rinfo, monitor_layout, ignore_edid);
+
+	/* Build mode list, check out panel native model */
+	radeon_check_modes(rinfo, mode_option);
+
+	/* Register some sysfs stuff (should be done better) */
+	if (rinfo->mon1_EDID)
+		sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid1_attr);
+	if (rinfo->mon2_EDID)
+		sysfs_create_bin_file(&rinfo->pdev->dev.kobj, &edid2_attr);
+
+	/* save current mode regs before we switch into the new one
+	 * so we can restore this upon __exit
+	 */
+	radeon_save_state (rinfo, &rinfo->init_state);
+
+	pci_set_drvdata(pdev, rinfo);
+	rinfo->next = board_list;
+	board_list = rinfo;
+
+	/* Enable PM on mobility chips */
+	if (rinfo->is_mobility)
+		radeon_pm_enable_dynamic_mode(rinfo);
+
+        if (register_framebuffer (rinfo->info) < 0) {
+		printk (KERN_ERR "radeonfb: could not register framebuffer\n");
+		goto unmap_fb;
+	}
+
+#ifdef CONFIG_MTRR
+	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys,
+						 rinfo->video_ram,
+						 MTRR_TYPE_WRCOMB, 1);
+#endif
+
+#ifdef CONFIG_PMAC_BACKLIGHT
+	if (rinfo->mon1_type == MT_LCD)
+		register_backlight_controller(&radeon_backlight_controller,
+					      rinfo, "ati");
+#endif
+
+	printk ("radeonfb: %s %s %ld MB\n", rinfo->name, rinfo->ram_type,
+		(rinfo->video_ram/(1024*1024)));
+
+	if (rinfo->bios_seg)
+		radeon_unmap_ROM(rinfo, pdev);
+	RTRACE("radeonfb_pci_register END\n");
+
+	return 0;
+unmap_fb:
+	iounmap ((void*)rinfo->fb_base);
+unmap_rom:
+	if (rinfo->mon1_EDID)
+	    kfree(rinfo->mon1_EDID);
+	if (rinfo->mon2_EDID)
+	    kfree(rinfo->mon2_EDID);
+	if (rinfo->mon1_modedb)
+		fb_destroy_modedb(rinfo->mon1_modedb);
+#ifdef CONFIG_FB_RADEON_I2C
+	radeon_delete_i2c_busses(rinfo);
+#endif
+	if (rinfo->bios_seg)
+		radeon_unmap_ROM(rinfo, pdev);
+	iounmap ((void*)rinfo->mmio_base);
+release_mmio:
+	release_mem_region (rinfo->mmio_base_phys,
+			    pci_resource_len(pdev, 2));
+release_fb:
+	release_mem_region (rinfo->fb_base_phys,
+			    pci_resource_len(pdev, 0));
+free_rinfo:
+	kfree (info);
+	return -ENODEV;
+}
+
+
+
+static void __devexit radeonfb_pci_unregister (struct pci_dev *pdev)
+{
+        struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+        if (!rinfo)
+                return;
+
+	/* restore original state
+	 *
+	 * Doesn't quite work yet, possibly because of the PPC hacking
+	 * I do on startup, disable for now. --BenH
+	 */
+        radeon_write_mode (rinfo, &rinfo->init_state);
+
+#ifdef CONFIG_MTRR
+	if (rinfo->mtrr_hdl >= 0)
+		mtrr_del(rinfo->mtrr_hdl, 0, 0);
+#endif
+
+        unregister_framebuffer (rinfo->info);
+
+        iounmap ((void*)rinfo->mmio_base);
+        iounmap ((void*)rinfo->fb_base);
+
+	release_mem_region (rinfo->mmio_base_phys,
+			    pci_resource_len(pdev, 2));
+	release_mem_region (rinfo->fb_base_phys,
+			    pci_resource_len(pdev, 0));
+
+	if (rinfo->mon1_EDID)
+		kfree(rinfo->mon1_EDID);
+	if (rinfo->mon2_EDID)
+		kfree(rinfo->mon2_EDID);
+	if (rinfo->mon1_modedb)
+		fb_destroy_modedb(rinfo->mon1_modedb);
+#ifdef CONFIG_FB_RADEON_I2C
+	radeon_delete_i2c_busses(rinfo);
+#endif
+        framebuffer_release(rinfo->info);
+}
+
+
+static struct pci_driver radeonfb_driver = {
+	.name		= "radeonfb",
+	.id_table	= radeonfb_pci_table,
+	.probe		= radeonfb_pci_register,
+	.remove		= __devexit_p(radeonfb_pci_unregister),
+#ifdef CONFIG_PM
+	.suspend       	= radeonfb_pci_suspend,
+	.resume		= radeonfb_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+
+int __init radeonfb_init (void)
+{
+	return pci_module_init (&radeonfb_driver);
+}
+
+
+void __exit radeonfb_exit (void)
+{
+	pci_unregister_driver (&radeonfb_driver);
+}
+
+#ifdef MODULE
+module_init(radeonfb_init);
+module_exit(radeonfb_exit);
+#endif
+
+MODULE_AUTHOR("Ani Joshi");
+MODULE_DESCRIPTION("framebuffer driver for ATI Radeon chipset");
+MODULE_LICENSE("GPL");
+module_param(noaccel, bool, 0);
+MODULE_PARM_DESC(noaccel, "bool: disable acceleration");
+module_param(nomodeset, bool, 0);
+MODULE_PARM_DESC(nomodeset, "bool: disable actual setting of video mode");
+module_param(mirror, bool, 0);
+MODULE_PARM_DESC(mirror, "bool: mirror the display to both monitors");
+module_param(force_dfp, bool, 0);
+MODULE_PARM_DESC(force_dfp, "bool: force display to dfp");
+module_param(ignore_edid, bool, 0);
+MODULE_PARM_DESC(ignore_edid, "bool: Ignore EDID data when doing DDC probe");
+module_param(monitor_layout, charp, 0);
+MODULE_PARM_DESC(monitor_layout, "Specify monitor mapping (like XFree86)");
+#ifdef CONFIG_MTRR
+module_param(nomtrr, bool, 0);
+MODULE_PARM_DESC(nomtrr, "bool: disable use of MTRR registers");
+#endif
+module_param(panel_yres, int, 0);
+MODULE_PARM_DESC(force_dfp, "int: set panel yres");
+module_param(mode_option, charp, 0);
+MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" ");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/radeon_i2c.c fbdev-2.6/drivers/video/aty/radeon_i2c.c
--- linus-2.6/drivers/video/aty/radeon_i2c.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/aty/radeon_i2c.c	Wed Oct 15 17:30:55 2003
@@ -0,0 +1,245 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+
+#include <video/radeon.h>
+#include "radeonfb.h"
+#include "../edid.h"
+
+#define RADEON_DDC 	0x50
+
+static void radeon_gpio_setscl(void* data, int state)
+{
+	struct radeon_i2c_chan 	*chan = data;
+	struct radeonfb_info	*rinfo = chan->rinfo;
+	u32			val;
+
+	val = INREG(chan->ddc_reg) & ~(VGA_DDC_CLK_OUT_EN);
+	if (!state)
+		val |= VGA_DDC_CLK_OUT_EN;
+
+	OUTREG(chan->ddc_reg, val);
+}
+
+static void radeon_gpio_setsda(void* data, int state)
+{
+	struct radeon_i2c_chan 	*chan = data;
+	struct radeonfb_info	*rinfo = chan->rinfo;
+	u32			val;
+
+	val = INREG(chan->ddc_reg) & ~(VGA_DDC_DATA_OUT_EN);
+	if (!state)
+		val |= VGA_DDC_DATA_OUT_EN;
+
+	OUTREG(chan->ddc_reg, val);
+}
+
+static int radeon_gpio_getscl(void* data)
+{
+	struct radeon_i2c_chan 	*chan = data;
+	struct radeonfb_info	*rinfo = chan->rinfo;
+	u32			val;
+
+	val = INREG(chan->ddc_reg);
+
+	return (val & VGA_DDC_CLK_INPUT) ? 1 : 0;
+}
+
+static int radeon_gpio_getsda(void* data)
+{
+	struct radeon_i2c_chan 	*chan = data;
+	struct radeonfb_info	*rinfo = chan->rinfo;
+	u32			val;
+
+	val = INREG(chan->ddc_reg);
+
+	return (val & VGA_DDC_DATA_INPUT) ? 1 : 0;
+}
+
+static int radeon_setup_i2c_bus(struct radeon_i2c_chan *chan, const char *name)
+{
+	int rc;
+
+	strcpy(chan->adapter.name, name);
+	chan->adapter.owner		= THIS_MODULE;
+	chan->adapter.id		= I2C_ALGO_ATI;
+	chan->adapter.algo_data		= &chan->algo;
+	chan->adapter.dev.parent	= &chan->rinfo->pdev->dev;
+	chan->algo.setsda		= radeon_gpio_setsda;
+	chan->algo.setscl		= radeon_gpio_setscl;
+	chan->algo.getsda		= radeon_gpio_getsda;
+	chan->algo.getscl		= radeon_gpio_getscl;
+	chan->algo.udelay		= 40;
+	chan->algo.timeout		= 20;
+	chan->algo.data 		= chan;
+
+	i2c_set_adapdata(&chan->adapter, chan);
+
+	/* Raise SCL and SDA */
+	radeon_gpio_setsda(chan, 1);
+	radeon_gpio_setscl(chan, 1);
+	udelay(20);
+
+	rc = i2c_bit_add_bus(&chan->adapter);
+	if (rc == 0)
+		dev_dbg(&chan->rinfo->pdev->dev, "I2C bus %s registered.\n", name);
+	else
+		dev_warn(&chan->rinfo->pdev->dev, "Failed to register I2C bus %s.\n", name);
+	return rc;
+}
+
+void radeon_create_i2c_busses(struct radeonfb_info *rinfo)
+{
+	rinfo->i2c[0].rinfo	= rinfo;
+	rinfo->i2c[0].ddc_reg	= GPIO_MONID;
+	radeon_setup_i2c_bus(&rinfo->i2c[0], "monid");
+
+	rinfo->i2c[1].rinfo	= rinfo;
+	rinfo->i2c[1].ddc_reg	= GPIO_DVI_DDC;
+	radeon_setup_i2c_bus(&rinfo->i2c[1], "dvi");
+
+	rinfo->i2c[2].rinfo	= rinfo;
+	rinfo->i2c[2].ddc_reg	= GPIO_VGA_DDC;
+	radeon_setup_i2c_bus(&rinfo->i2c[2], "vga");
+
+	rinfo->i2c[3].rinfo	= rinfo;
+	rinfo->i2c[3].ddc_reg	= GPIO_CRT2_DDC;
+	radeon_setup_i2c_bus(&rinfo->i2c[3], "crt2");
+}
+
+void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
+{
+	if (rinfo->i2c[0].rinfo)
+		i2c_bit_del_bus(&rinfo->i2c[0].adapter);
+	rinfo->i2c[0].rinfo = NULL;
+
+	if (rinfo->i2c[1].rinfo)
+		i2c_bit_del_bus(&rinfo->i2c[1].adapter);
+	rinfo->i2c[1].rinfo = NULL;
+
+	if (rinfo->i2c[2].rinfo)
+		i2c_bit_del_bus(&rinfo->i2c[2].adapter);
+	rinfo->i2c[2].rinfo = NULL;
+
+	if (rinfo->i2c[3].rinfo)
+		i2c_bit_del_bus(&rinfo->i2c[3].adapter);
+	rinfo->i2c[3].rinfo = NULL;
+}
+
+
+static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan)
+{
+	u8 start = 0x0;
+	struct i2c_msg msgs[] = {
+		{
+			.addr	= RADEON_DDC,
+			.len	= 1,
+			.buf	= &start,
+		}, {
+			.addr	= RADEON_DDC,
+			.flags	= I2C_M_RD,
+			.len	= EDID_LENGTH,
+		},
+	};
+	u8 *buf;
+
+	buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
+	if (!buf) {
+		dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
+		return NULL;
+	}
+	msgs[1].buf = buf;
+
+	if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
+		return buf;
+	dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
+	kfree(buf);
+	return NULL;
+}
+
+
+int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
+{
+	u32 reg = rinfo->i2c[conn-1].ddc_reg;
+	u8 *edid = NULL;
+	int i, j;
+
+	OUTREG(reg, INREG(reg) &
+			~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
+
+	OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
+	for (i = 0; i < 3; i++) {
+		/* For some old monitors we need the
+		 * following process to initialize/stop DDC
+		 */
+		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
+		wait_ms(13);
+
+		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
+		for (j = 0; j < 5; j++) {
+			wait_ms(10);
+			if (INREG(reg) & VGA_DDC_CLK_INPUT)
+				break;
+		}
+		if (j == 5)
+			continue;
+
+		OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
+		wait_ms(15);
+		OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
+		wait_ms(15);
+		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
+		wait_ms(15);
+
+		/* Do the real work */
+		edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
+
+		OUTREG(reg, INREG(reg) |
+				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
+		wait_ms(15);
+
+		OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
+		for (j = 0; j < 10; j++) {
+			wait_ms(10);
+			if (INREG(reg) & VGA_DDC_CLK_INPUT)
+				break;
+		}
+
+		OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
+		wait_ms(15);
+		OUTREG(reg, INREG(reg) |
+				(VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
+		if (edid)
+			break;
+	}
+	if (out_edid)
+		*out_edid = edid;
+	if (!edid) {
+		RTRACE("radeonfb: I2C (port %d) ... not found\n", conn);
+		return MT_NONE;
+	}
+	if (edid[0x14] & 0x80) {
+		if (rinfo->is_mobility && conn == ddc_dvi &&
+		    (INREG(LVDS_GEN_CNTL) & LVDS_ON)) {
+			RTRACE("radeonfb: I2C (port %d) ... found LVDS panel\n", conn);
+			return MT_LCD;
+		} else {
+			RTRACE("radeonfb: I2C (port %d) ... found TMDS panel\n", conn);
+			return MT_DFP;
+		}
+	}
+       	RTRACE("radeonfb: I2C (port %d) ... found CRT display\n", conn);
+	return MT_CRT;
+}
+
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/radeon_monitor.c fbdev-2.6/drivers/video/aty/radeon_monitor.c
--- linus-2.6/drivers/video/aty/radeon_monitor.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/aty/radeon_monitor.c	Wed Oct 15 16:46:15 2003
@@ -0,0 +1,677 @@
+#include "radeonfb.h"
+#include "../edid.h"
+
+#ifdef CONFIG_PPC_OF
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#endif /* CONFIG_PPC_OF */
+
+static struct fb_var_screeninfo radeonfb_default_var = {
+        640, 480, 640, 480, 0, 0, 8, 0,
+        {0, 6, 0}, {0, 6, 0}, {0, 6, 0}, {0, 0, 0},
+        0, 0, -1, -1, 0, 39721, 40, 24, 32, 11, 96, 2,
+        0, FB_VMODE_NONINTERLACED
+};
+
+static char *radeon_get_mon_name(int type)
+{
+	char *pret = NULL;
+
+	switch (type) {
+		case MT_NONE:
+			pret = "no";
+			break;
+		case MT_CRT:
+			pret = "CRT";
+			break;
+		case MT_DFP:
+			pret = "DFP";
+			break;
+		case MT_LCD:
+			pret = "LCD";
+			break;
+		case MT_CTV:
+			pret = "CTV";
+			break;
+		case MT_STV:
+			pret = "STV";
+			break;
+	}
+
+	return pret;
+}
+
+
+#ifdef CONFIG_PPC_OF
+/*
+ * Try to find monitor informations & EDID data out of the Open Firmware
+ * device-tree. This also contains some "hacks" to work around a few machine
+ * models with broken OF probing by hard-coding known EDIDs for some Mac
+ * laptops internal LVDS panel.
+ */
+static int __devinit radeon_parse_montype_prop(struct device_node *dp, u8 **out_EDID)
+{
+        static char *propnames[] = { "DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID2",  NULL };
+	u8 *pedid = NULL;
+	u8 *pmt = NULL;
+        int i, mt;
+
+	pmt = (u8 *)get_property(dp, "display-type", NULL);
+	if (!pmt)
+		return MT_NONE;
+	if (!strcmp(pmt, "LCD") || !strcmp(pmt, "DFP"))
+		mt = MT_DFP;
+	else if (!strcmp(pmt, "CRT"))
+		mt = MT_CRT;
+	else if (strcmp(pmt, "NONE")) {
+		printk(KERN_WARNING "radeonfb: Unknown OF display-type: %s\n", pmt);
+		return MT_NONE;
+	}
+	for (i = 0; propnames[i] != NULL; ++i) {
+		pedid = (u8 *)get_property(dp, propnames[i], NULL);
+		if (pedid != NULL) {
+			u8 *tmp = (u8 *)kmalloc(EDID_LENGTH, GFP_KERNEL);
+			if (tmp)
+				return mt;
+			memcpy(tmp, pedid, EDID_LENGTH);
+			*out_EDID = tmp;
+			break;
+		}
+	}
+	return mt;
+}
+
+static int __devinit radeon_probe_OF_head(struct radeonfb_info *rinfo, int head_no, u8 **out_EDID)
+{
+        struct device_node *dp;
+
+        dp = pci_device_to_OF_node(rinfo->pdev);
+        while (dp == NULL)
+		return MT_NONE;
+
+	if (rinfo->has_CRTC2) {
+		char *pname;
+		int len, second = 0;
+
+		dp = dp->child;
+		do {
+			if (!dp)
+				return MT_NONE;
+			pname = (char *)get_property(dp, "name", NULL);
+			if (!pname)
+				return MT_NONE;
+			len = strlen(pname);
+			if (pname[len-1] == 'A' && head_no == 0) {
+				int mt = radeon_parse_montype_prop(dp, out_EDID);
+				/* Maybe check for LVDS_GEN_CNTL here ? I need to check out
+				 * what OF does when booting with lid closed
+				 */
+				if (mt == MT_DFP && rinfo->is_mobility)
+					mt = MT_LCD;
+			} else if (pname[len-1] == 'B' && head_no == 1)
+				return radeon_parse_montype_prop(dp, out_EDID);
+			second = 1;
+			dp = dp->sibling;
+		} while(!second);
+	} else {
+		if (head_no > 0)
+			return MT_NONE;
+		return radeon_parse_montype_prop(dp, out_EDID);
+	}
+        return MT_NONE;
+}
+#endif /* CONFIG_PPC_OF */
+
+
+static int __devinit radeon_get_panel_info_BIOS(struct radeonfb_info *rinfo)
+{
+	unsigned long tmp, tmp0;
+	char stmp[30];
+	int i;
+
+	if (!rinfo->bios_seg)
+		return 0;
+
+	if (!(tmp = BIOS_IN16(rinfo->fp_bios_start + 0x40))) {
+		printk(KERN_ERR "radeonfb: Failed to detect DFP panel info using BIOS\n");
+		return 0;
+	}
+
+	for(i=0; i<24; i++)
+		stmp[i] = BIOS_IN8(tmp+i+1);
+	stmp[24] = 0;
+	printk("radeonfb: panel ID string: %s\n", stmp);
+	rinfo->panel_info.xres = BIOS_IN16(tmp + 25);
+	rinfo->panel_info.yres = BIOS_IN16(tmp + 27);
+	printk("radeonfb: detected LVDS panel size from BIOS: %dx%d\n",
+		rinfo->panel_info.xres, rinfo->panel_info.yres);
+
+	rinfo->panel_info.pwr_delay = BIOS_IN16(tmp + 44);
+	if (rinfo->panel_info.pwr_delay > 2000 || rinfo->panel_info.pwr_delay < 0)
+		rinfo->panel_info.pwr_delay = 2000;
+
+	/*
+	 * Some panels only work properly with some divider combinations
+	 */
+	rinfo->panel_info.ref_divider = BIOS_IN16(tmp + 46);
+	rinfo->panel_info.post_divider = BIOS_IN8(tmp + 48);
+	rinfo->panel_info.fbk_divider = BIOS_IN16(tmp + 49);
+	if (rinfo->panel_info.ref_divider != 0 &&
+	    rinfo->panel_info.fbk_divider > 3) {
+		rinfo->panel_info.use_bios_dividers = 1;
+		printk(KERN_INFO "radeondb: BIOS provided dividers will be used\n");
+	}
+	for(i=0; i<20; i++) {
+		tmp0 = BIOS_IN16(tmp+64+i*2);
+		if (tmp0 == 0)
+			break;
+		if ((BIOS_IN16(tmp0) == rinfo->panel_info.xres) &&
+		    (BIOS_IN16(tmp0+2) == rinfo->panel_info.yres)) {
+			rinfo->panel_info.hblank = (BIOS_IN16(tmp0+17) - BIOS_IN16(tmp0+19)) * 8;
+			rinfo->panel_info.hOver_plus = ((BIOS_IN16(tmp0+21) -
+							 BIOS_IN16(tmp0+19) -1) * 8) & 0x7fff;
+			rinfo->panel_info.hSync_width = BIOS_IN8(tmp0+23) * 8;
+			rinfo->panel_info.vblank = BIOS_IN16(tmp0+24) - BIOS_IN16(tmp0+26);
+			rinfo->panel_info.vOver_plus = (BIOS_IN16(tmp0+28) & 0x7ff) - BIOS_IN16(tmp0+26);
+			rinfo->panel_info.vSync_width = (BIOS_IN16(tmp0+28) & 0xf800) >> 11;
+			rinfo->panel_info.clock = BIOS_IN16(tmp0+9);
+			/* Assume high active syncs for now until ATI tells me more... maybe we
+			 * can probe register values here ?
+			 */
+			rinfo->panel_info.hAct_high = 1;
+			rinfo->panel_info.vAct_high = 1;
+			/* Mark panel infos valid */
+			rinfo->panel_info.valid = 1;
+
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * Probe physical connection of a CRT. This code comes from XFree
+ * as well and currently is only implemented for the CRT DAC, the
+ * code for the TVDAC is commented out in XFree as "non working"
+ */
+static int __devinit radeon_crt_is_connected(struct radeonfb_info *rinfo, int is_crt_dac)
+{
+    int	          connected = 0;
+
+    /* the monitor either wasn't connected or it is a non-DDC CRT.
+     * try to probe it
+     */
+    if(is_crt_dac) {
+	unsigned long ulOrigVCLK_ECP_CNTL;
+	unsigned long ulOrigDAC_CNTL;
+	unsigned long ulOrigDAC_EXT_CNTL;
+	unsigned long ulOrigCRTC_EXT_CNTL;
+	unsigned long ulData;
+	unsigned long ulMask;
+
+	ulOrigVCLK_ECP_CNTL = INPLL(VCLK_ECP_CNTL);
+
+	ulData              = ulOrigVCLK_ECP_CNTL;
+	ulData             &= ~(PIXCLK_ALWAYS_ONb
+				| PIXCLK_DAC_ALWAYS_ONb);
+	ulMask              = ~(PIXCLK_ALWAYS_ONb
+				| PIXCLK_DAC_ALWAYS_ONb);
+	OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
+
+	ulOrigCRTC_EXT_CNTL = INREG(CRTC_EXT_CNTL);
+	ulData              = ulOrigCRTC_EXT_CNTL;
+	ulData             |= CRTC_CRT_ON;
+	OUTREG(CRTC_EXT_CNTL, ulData);
+
+	ulOrigDAC_EXT_CNTL = INREG(DAC_EXT_CNTL);
+	ulData             = ulOrigDAC_EXT_CNTL;
+	ulData            &= ~DAC_FORCE_DATA_MASK;
+	ulData            |=  (DAC_FORCE_BLANK_OFF_EN
+			       |DAC_FORCE_DATA_EN
+			       |DAC_FORCE_DATA_SEL_MASK);
+	if ((rinfo->arch == RADEON_RV250) ||
+	    (rinfo->arch == RADEON_RV280))
+	    ulData |= (0x01b6 << DAC_FORCE_DATA_SHIFT);
+	else
+	    ulData |= (0x01ac << DAC_FORCE_DATA_SHIFT);
+
+	OUTREG(DAC_EXT_CNTL, ulData);
+
+	ulOrigDAC_CNTL     = INREG(DAC_CNTL);
+	ulData             = ulOrigDAC_CNTL;
+	ulData            |= DAC_CMP_EN;
+	ulData            &= ~(DAC_RANGE_CNTL_MASK
+			       | DAC_PDWN);
+	ulData            |= 0x2;
+	OUTREG(DAC_CNTL, ulData);
+
+	mdelay(1);
+
+	ulData     = INREG(DAC_CNTL);
+	connected =  (DAC_CMP_OUTPUT & ulData) ? 1 : 0;
+
+	ulData    = ulOrigVCLK_ECP_CNTL;
+	ulMask    = 0xFFFFFFFFL;
+	OUTPLLP(VCLK_ECP_CNTL, ulData, ulMask);
+
+	OUTREG(DAC_CNTL,      ulOrigDAC_CNTL     );
+	OUTREG(DAC_EXT_CNTL,  ulOrigDAC_EXT_CNTL );
+	OUTREG(CRTC_EXT_CNTL, ulOrigCRTC_EXT_CNTL);
+    }
+
+    return connected ? MT_CRT : MT_NONE;
+}
+
+/*
+ * Parse the "monitor_layout" string if any. This code is mostly
+ * copied from XFree's radeon driver
+ */
+static int __devinit radeon_parse_monitor_layout(struct radeonfb_info *rinfo, const char *monitor_layout)
+{
+	char s1[5], s2[5];
+	int i = 0, second = 0;
+	const char *s;
+
+	if (!monitor_layout)
+		return 0;
+
+	s = monitor_layout;
+	do {
+		switch(*s) {
+		case ',':
+			s1[i] = '\0';
+			i = 0;
+			second = 1;
+			break;
+		case ' ':
+		case '\0':
+			break;
+		default:
+			if (i > 4)
+				break;
+			if (second)
+				s2[i] = *s;
+			else
+				s1[i] = *s;
+			i++;
+		}
+	} while (*s++);
+	if (second)
+		s2[i] = 0;
+	else {
+		s1[i] = 0;
+		s2[0] = 0;
+	}
+	if (strcmp(s1, "CRT") == 0)
+		rinfo->mon1_type = MT_CRT;
+	else if (strcmp(s1, "TMDS") == 0)
+		rinfo->mon1_type = MT_DFP;
+	else if (strcmp(s1, "LVDS") == 0)
+		rinfo->mon1_type = MT_LCD;
+
+	if (strcmp(s2, "CRT") == 0)
+		rinfo->mon2_type = MT_CRT;
+	else if (strcmp(s2, "TMDS") == 0)
+		rinfo->mon2_type = MT_DFP;
+	else if (strcmp(s2, "LVDS") == 0)
+		rinfo->mon2_type = MT_LCD;
+
+	return 1;
+}
+
+/*
+ * Probe display on both primary and secondary card's connector (if any)
+ * by various available techniques (i2c, OF device tree, BIOS, ...) and
+ * try to retreive EDID. The algorithm here comes from XFree's radeon
+ * driver
+ */
+void __devinit radeon_probe_screens(struct radeonfb_info *rinfo,
+				    const char *monitor_layout, int ignore_edid)
+{
+	int ddc_crt2_used = 0;
+	int tmp, i;
+
+	if (radeon_parse_monitor_layout(rinfo, monitor_layout)) {
+
+		/*
+		 * If user specified a monitor_layout option, use it instead
+		 * of auto-detecting. Maybe we should only use this argument
+		 * on the first radeon card probed or provide a way to specify
+		 * a layout for each card ?
+		 */
+
+		RTRACE("Using specified monitor layout: %s", monitor_layout);
+#ifdef CONFIG_FB_RADEON_I2C
+		if (!ignore_edid) {
+			if (rinfo->mon1_type != MT_NONE)
+				if (!radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID)) {
+					radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
+					ddc_crt2_used = 1;
+				}
+			if (rinfo->mon2_type != MT_NONE)
+				if (!radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID) &&
+				    !ddc_crt2_used)
+					radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
+		}
+#endif /* CONFIG_FB_RADEON_I2C */
+		if (rinfo->mon1_type == MT_NONE) {
+			if (rinfo->mon2_type != MT_NONE) {
+				rinfo->mon1_type = rinfo->mon2_type;
+				rinfo->mon1_EDID = rinfo->mon2_EDID;
+			} else {
+				rinfo->mon1_type = MT_CRT;
+				printk(KERN_INFO "radeonfb: No valid monitor, assuming CRT on first port\n");
+			}
+			rinfo->mon2_type = MT_NONE;
+			rinfo->mon2_EDID = NULL;
+		}
+	} else {
+
+		/*
+		 * Auto-detecting display type (well... trying to ...)
+		 */
+
+		RTRACE("Starting monitor auto detection...\n");
+
+		/*
+		 * Old single head cards
+		 */
+		if (!rinfo->has_CRTC2) {
+#ifdef CONFIG_FB_RADEON_I2C
+			rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID);
+			if (rinfo->mon1_type == MT_NONE)
+				rinfo->mon1_type =
+					radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon1_EDID);
+			if (rinfo->mon1_type == MT_NONE)
+				rinfo->mon1_type =
+					radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
+#endif /* CONFIG_FB_RADEON_I2C */
+#ifdef CONFIG_PPC_OF
+			if (rinfo->mon1_type == MT_NONE)
+				rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, &rinfo->mon1_EDID);
+#endif /* CONFIG_PPC_OF */
+			if (rinfo->mon1_type == MT_NONE)
+				rinfo->mon1_type = MT_CRT;
+			goto bail;
+		}
+
+		/*
+		 * Check for cards with reversed DACs or TMDS controllers using BIOS
+		 */
+		if (rinfo->bios_seg &&
+		    (tmp = BIOS_IN16(rinfo->fp_bios_start + 0x50))) {
+			for (i = 1; i < 4; i++) {
+				unsigned int tmp0;
+
+				if (!BIOS_IN8(tmp + i*2) && i > 1)
+					break;
+				tmp0 = BIOS_IN16(tmp + i*2);
+				if ((!(tmp0 & 0x01)) && (((tmp0 >> 8) & 0x0f) == ddc_dvi)) {
+					rinfo->reversed_DAC = 1;
+					printk(KERN_INFO "radeonfb: Reversed DACs detected\n");
+				}
+				if ((((tmp0 >> 8) & 0x0f) == ddc_dvi) && ((tmp0 >> 4) & 0x01)) {
+					rinfo->reversed_TMDS = 1;
+					printk(KERN_INFO "radeonfb: Reversed TMDS detected\n");
+				}
+			}
+		}
+
+		/*
+		 * Probe primary head (DVI or laptop internal panel)
+		 */
+#ifdef CONFIG_FB_RADEON_I2C
+		rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_dvi, &rinfo->mon1_EDID);
+		if (rinfo->mon1_type == MT_NONE) {
+			rinfo->mon1_type = radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon1_EDID);
+			if (rinfo->mon1_type != MT_NONE)
+				ddc_crt2_used = 1;
+		}
+#endif /* CONFIG_FB_RADEON_I2C */
+#ifdef CONFIG_PPC_OF
+		if (rinfo->mon1_type == MT_NONE)
+			rinfo->mon1_type = radeon_probe_OF_head(rinfo, 0, &rinfo->mon1_EDID);
+#endif /* CONFIG_PPC_OF */
+		if (rinfo->mon1_type == MT_NONE && rinfo->is_mobility &&
+		    ((rinfo->bios_seg && (INREG(BIOS_4_SCRATCH) & 4))
+		     || (INREG(LVDS_GEN_CNTL) & LVDS_ON))) {
+			rinfo->mon1_type = MT_LCD;
+			printk("Non-DDC laptop panel detected\n");
+		}
+		if (rinfo->mon1_type == MT_NONE)
+			rinfo->mon1_type = radeon_crt_is_connected(rinfo, rinfo->reversed_DAC);
+
+		/*
+		 * Probe secondary head (mostly VGA, can be DVI)
+		 */
+#ifdef CONFIG_FB_RADEON_I2C
+		rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_vga, &rinfo->mon2_EDID);
+		if (rinfo->mon2_type == MT_NONE && !ddc_crt2_used)
+			rinfo->mon2_type = radeon_probe_i2c_connector(rinfo, ddc_crt2, &rinfo->mon2_EDID);
+#endif /* CONFIG_FB_RADEON_I2C */
+#ifdef CONFIG_PPC_OF
+		if (rinfo->mon2_type == MT_NONE)
+			rinfo->mon2_type = radeon_probe_OF_head(rinfo, 1, &rinfo->mon2_EDID);
+#endif /* CONFIG_PPC_OF */
+		if (rinfo->mon2_type == MT_NONE)
+			rinfo->mon2_type = radeon_crt_is_connected(rinfo, !rinfo->reversed_DAC);
+
+		/*
+		 * If we only detected port 2, we swap them, if none detected,
+		 * assume CRT (maybe fallback to old BIOS_SCRATCH stuff ? or look
+		 * at FP registers ?)
+		 */
+		if (rinfo->mon1_type == MT_NONE) {
+			if (rinfo->mon2_type != MT_NONE) {
+				rinfo->mon1_type = rinfo->mon2_type;
+				rinfo->mon1_EDID = rinfo->mon2_EDID;
+			} else
+				rinfo->mon1_type = MT_CRT;
+			rinfo->mon2_type = MT_NONE;
+			rinfo->mon2_EDID = NULL;
+		}
+
+		/*
+		 * Deal with reversed TMDS
+		 */
+		if (rinfo->reversed_TMDS) {
+			/* Always keep internal TMDS as primary head */
+			if (rinfo->mon1_type == MT_DFP || rinfo->mon2_type == MT_DFP) {
+				int tmp_type = rinfo->mon1_type;
+				u8 *tmp_EDID = rinfo->mon1_EDID;
+				rinfo->mon1_type = rinfo->mon2_type;
+				rinfo->mon1_EDID = rinfo->mon2_EDID;
+				rinfo->mon2_type = tmp_type;
+				rinfo->mon2_EDID = tmp_EDID;
+				if (rinfo->mon1_type == MT_CRT || rinfo->mon2_type == MT_CRT)
+					rinfo->reversed_DAC ^= 1;
+			}
+		}
+	}
+	if (ignore_edid) {
+		if (rinfo->mon1_EDID)
+			kfree(rinfo->mon1_EDID);
+		rinfo->mon1_EDID = NULL;
+		if (rinfo->mon2_EDID)
+			kfree(rinfo->mon2_EDID);
+		rinfo->mon2_EDID = NULL;
+	}
+
+ bail:
+	printk(KERN_INFO "radeonfb: Monitor 1 type %s found\n",
+	       radeon_get_mon_name(rinfo->mon1_type));
+	if (rinfo->mon1_EDID) {
+		printk(KERN_INFO "radeonfb: EDID probed\n");
+		show_edid(rinfo->mon1_EDID);
+	}
+	if (!rinfo->has_CRTC2)
+		return;
+	printk(KERN_INFO "radeonfb: Monitor 2 type %s found\n",
+	       radeon_get_mon_name(rinfo->mon2_type));
+	if (rinfo->mon2_EDID) {
+		printk(KERN_INFO "radeonfb: EDID probed\n");
+		show_edid(rinfo->mon2_EDID);
+	}
+}
+
+
+static void radeon_var_to_panel_info(struct radeonfb_info *rinfo, struct fb_var_screeninfo *var)
+{
+	rinfo->panel_info.xres = var->xres;
+	rinfo->panel_info.yres = var->yres;
+	rinfo->panel_info.clock = 100000000 / var->pixclock;
+	rinfo->panel_info.hOver_plus = var->right_margin;
+	rinfo->panel_info.hSync_width = var->hsync_len;
+       	rinfo->panel_info.hblank = var->left_margin +
+		(var->right_margin + var->hsync_len);
+	rinfo->panel_info.vOver_plus = var->lower_margin;
+	rinfo->panel_info.vSync_width = var->vsync_len;
+       	rinfo->panel_info.vblank = var->upper_margin +
+		(var->lower_margin + var->vsync_len);
+	rinfo->panel_info.hAct_high =
+		(var->sync & FB_SYNC_HOR_HIGH_ACT) != 0;
+	rinfo->panel_info.vAct_high =
+		(var->sync & FB_SYNC_VERT_HIGH_ACT) != 0;
+	rinfo->panel_info.valid = 1;
+}
+
+static void radeon_var_to_videomode(struct fb_videomode *mode,
+				    const struct fb_var_screeninfo *var)
+{
+    mode->xres = var->xres;
+    mode->yres = var->yres;
+    mode->pixclock = var->pixclock;
+    mode->left_margin = var->left_margin;
+    mode->right_margin = var->right_margin;
+    mode->upper_margin = var->upper_margin;
+    mode->lower_margin = var->lower_margin;
+    mode->hsync_len = var->hsync_len;
+    mode->vsync_len = var->vsync_len;
+    mode->sync = var->sync;
+    mode->vmode = var->vmode;
+}
+
+/*
+ * Build the modedb for head 1 (head 2 will come later), check panel infos
+ * from either BIOS or EDID, and pick up the default mode
+ */
+void __devinit radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option)
+{
+	int has_default_mode = 0;
+
+	/*
+	 * Fill default var first
+	 */
+	rinfo->info->var = radeonfb_default_var;
+
+	/*
+	 * First check out what BIOS has to say
+	 */
+	if (rinfo->mon1_type == MT_LCD)
+		radeon_get_panel_info_BIOS(rinfo);
+
+	/*
+	 * Parse EDID detailed timings and deduce panel infos if any. Right now
+	 * we only deal with first entry returned by parse_EDID, we may do better
+	 * some day...
+	 */
+	if (!rinfo->panel_info.use_bios_dividers && rinfo->mon1_type != MT_CRT
+	    && rinfo->mon1_EDID) {
+		struct fb_var_screeninfo var;
+		if (parse_edid(rinfo->mon1_EDID, &var) == 0) {
+			if (var.xres >= rinfo->panel_info.xres &&
+			    var.yres >= rinfo->panel_info.yres)
+				radeon_var_to_panel_info(rinfo, &var);
+		}
+	}
+
+	/*
+	 * If we have some valid panel infos, we setup the default mode based on
+	 * those
+	 */
+	if (rinfo->mon1_type != MT_CRT && rinfo->panel_info.valid) {
+		struct fb_var_screeninfo *var = &rinfo->info->var;
+
+		var->xres = rinfo->panel_info.xres;
+		var->yres = rinfo->panel_info.yres;
+		var->xres_virtual = rinfo->panel_info.xres;
+		var->yres_virtual = rinfo->panel_info.yres;
+		var->xoffset = var->yoffset = 0;
+		var->bits_per_pixel = 8;
+		var->pixclock = 100000000 / rinfo->panel_info.clock;
+		var->left_margin = (rinfo->panel_info.hblank - rinfo->panel_info.hOver_plus
+				    - rinfo->panel_info.hSync_width);
+		var->right_margin = rinfo->panel_info.hOver_plus;
+		var->upper_margin = (rinfo->panel_info.vblank - rinfo->panel_info.vOver_plus
+				     - rinfo->panel_info.vSync_width);
+		var->lower_margin = rinfo->panel_info.vOver_plus;
+		var->hsync_len = rinfo->panel_info.hSync_width;
+		var->vsync_len = rinfo->panel_info.vSync_width;
+		var->sync = 0;
+		if (rinfo->panel_info.hAct_high)
+			var->sync |= FB_SYNC_HOR_HIGH_ACT;
+		if (rinfo->panel_info.vAct_high)
+			var->sync |= FB_SYNC_VERT_HIGH_ACT;
+		var->vmode = 0;
+		has_default_mode = 1;
+	}
+
+	/*
+	 * Now build modedb from EDID
+	 */
+	if (rinfo->mon1_EDID)
+		rinfo->mon1_modedb = fb_create_modedb(rinfo->mon1_EDID, &rinfo->mon1_dbsize);
+
+	/*
+	 * Finally, if we don't have panel infos we need to figure some (or
+	 * we try to read it from card), we try to pick a default mode
+	 * and create some panel infos. Whatever...
+	 */
+	if (rinfo->mon1_type != MT_CRT && !rinfo->panel_info.valid) {
+		struct fb_videomode	*modedb;
+		int			dbsize;
+		char			modename[32];
+
+		if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
+			u32 tmp = INREG(FP_HORZ_STRETCH) & HORZ_PANEL_SIZE;
+			rinfo->panel_info.xres = ((tmp >> HORZ_PANEL_SHIFT) + 1) * 8;
+			tmp = INREG(FP_VERT_STRETCH) & VERT_PANEL_SIZE;
+			rinfo->panel_info.yres = (tmp >> VERT_PANEL_SHIFT) + 1;
+		}
+		if (rinfo->panel_info.xres == 0 || rinfo->panel_info.yres == 0) {
+			printk(KERN_WARNING "radeonfb: Can't find panel size, going back to CRT\n");
+			rinfo->mon1_type = MT_CRT;
+			goto pickup_default;
+		}
+		printk(KERN_WARNING "radeonfb: Asssuming panel size %dx%d\n",
+		       rinfo->panel_info.xres, rinfo->panel_info.yres);
+		modedb = rinfo->mon1_modedb;
+		dbsize = rinfo->mon1_dbsize;
+		snprintf(modename, 31, "%dx%d", rinfo->panel_info.xres, rinfo->panel_info.yres);
+		if (fb_find_mode(&rinfo->info->var, rinfo->info, modename,
+				 modedb, dbsize, NULL, 8) == 0) {
+			printk(KERN_WARNING "radeonfb: Can't find mode for panel size, going back to CRT\n");
+			rinfo->mon1_type = MT_CRT;
+			goto pickup_default;
+		}
+		has_default_mode = 1;
+		radeon_var_to_panel_info(rinfo, &rinfo->info->var);
+	}
+
+ pickup_default:
+	/*
+	 * Pick up a random default mode
+	 */
+	if (!has_default_mode || mode_option) {
+		struct fb_videomode default_mode;
+		if (has_default_mode)
+			radeon_var_to_videomode(&default_mode, &rinfo->info->var);
+		else
+			radeon_var_to_videomode(&default_mode, &radeonfb_default_var);
+		if (fb_find_mode(&rinfo->info->var, rinfo->info, mode_option,
+			     rinfo->mon1_modedb, rinfo->mon1_dbsize, &default_mode, 8) == 0)
+			rinfo->info->var = radeonfb_default_var;
+	}
+
+}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/radeon_pm.c fbdev-2.6/drivers/video/aty/radeon_pm.c
--- linus-2.6/drivers/video/aty/radeon_pm.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/aty/radeon_pm.c	Wed Oct 15 16:46:10 2003
@@ -0,0 +1,910 @@
+#include "radeonfb.h"
+
+#include <linux/console.h>
+
+/*
+ * Radeon M6, M7 and M9 Power Management code. This code currently
+ * only supports the mobile chips in D2 mode, that is typically what
+ * is used on Apple laptops, it's based from some informations provided
+ * by ATI along with hours of tracing of MacOS drivers.
+ *
+ * New version of this code almost totally rewritten by ATI, many thanks
+ * for their support.
+ */
+
+void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo)
+{
+
+	u32 sclk_cntl;
+	u32 mclk_cntl;
+	u32 sclk_more_cntl;
+
+	u32 vclk_ecp_cntl;
+	u32 pixclks_cntl;
+
+	/* Mobility chips only */
+	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
+		return;
+
+	/* Force Core Clocks */
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
+	sclk_cntl |= 	SCLK_CNTL_M6__FORCE_CP|
+			SCLK_CNTL_M6__FORCE_HDP|
+			SCLK_CNTL_M6__FORCE_DISP1|
+			SCLK_CNTL_M6__FORCE_DISP2|
+			SCLK_CNTL_M6__FORCE_TOP|
+			SCLK_CNTL_M6__FORCE_E2|
+			SCLK_CNTL_M6__FORCE_SE|
+			SCLK_CNTL_M6__FORCE_IDCT|
+			SCLK_CNTL_M6__FORCE_VIP|
+			SCLK_CNTL_M6__FORCE_RE|
+			SCLK_CNTL_M6__FORCE_PB|
+			SCLK_CNTL_M6__FORCE_TAM|
+			SCLK_CNTL_M6__FORCE_TDM|
+			SCLK_CNTL_M6__FORCE_RB|
+			SCLK_CNTL_M6__FORCE_TV_SCLK|
+			SCLK_CNTL_M6__FORCE_SUBPIC|
+			SCLK_CNTL_M6__FORCE_OV0;
+    	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+
+
+
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS|
+				SCLK_MORE_CNTL__FORCE_MC_GUI|
+				SCLK_MORE_CNTL__FORCE_MC_HOST;
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
+
+	/* Force Display clocks	*/
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+	vclk_ecp_cntl &= ~(	VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+			 	VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
+			 	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
+				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
+
+ 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+
+	/* Force Memory Clocks */
+	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |
+			MCLK_CNTL_M6__FORCE_MCLKB |
+			MCLK_CNTL_M6__FORCE_YCLKA |
+			MCLK_CNTL_M6__FORCE_YCLKB );
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+}
+
+void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo)
+{
+	u32 clk_pwrmgt_cntl;
+	u32 sclk_cntl;
+	u32 sclk_more_cntl;
+	u32 clk_pin_cntl;
+	u32 pixclks_cntl;
+	u32 vclk_ecp_cntl;
+	u32 mclk_cntl;
+	u32 mclk_misc;
+
+	/* Mobility chips only */
+	if ((rinfo->arch != RADEON_M6) && (rinfo->arch != RADEON_M7) && (rinfo->arch != RADEON_M9))
+		return;
+
+	/* Set Latencies */
+	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
+
+	clk_pwrmgt_cntl &= ~(	 CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK|
+				 CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK|
+				 CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK);
+	/* Mode 1 */
+	clk_pwrmgt_cntl = 	CLK_PWRMGT_CNTL_M6__MC_CH_MODE|
+				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE |
+				(1<<CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT) |
+				(0<<CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT)|
+				(0<<CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT);
+
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+
+
+	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
+	clk_pin_cntl |= CLK_PIN_CNTL__SCLK_DYN_START_CNTL;
+
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+
+	/* Enable Dyanmic mode for SCLK */
+
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
+	sclk_cntl &= SCLK_CNTL_M6__SCLK_SRC_SEL_MASK;
+	sclk_cntl |= SCLK_CNTL_M6__FORCE_VIP;
+
+	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+
+
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl &= ~(SCLK_MORE_CNTL__FORCE_DISPREGS);
+
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
+
+
+	/* Enable Dynamic mode for PIXCLK & PIX2CLK */
+
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+
+	pixclks_cntl|=  PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb |
+			PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+			PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb;
+
+	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+
+
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+
+	vclk_ecp_cntl|=  VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |
+			 VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb;
+
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+
+
+	/* Enable Dynamic mode for MCLK	*/
+
+	mclk_cntl  = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl |= 	MCLK_CNTL_M6__FORCE_MCLKA|
+			MCLK_CNTL_M6__FORCE_MCLKB|
+			MCLK_CNTL_M6__FORCE_YCLKA|
+			MCLK_CNTL_M6__FORCE_YCLKB;
+
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+
+	mclk_misc = INPLL(pllMCLK_MISC);
+	mclk_misc |= 	MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT|
+			MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT|
+			MCLK_MISC__MC_MCLK_DYN_ENABLE|
+			MCLK_MISC__IO_MCLK_DYN_ENABLE;
+
+	OUTPLL(pllMCLK_MISC, mclk_misc);
+}
+
+#ifdef CONFIG_PM
+
+static void OUTMC( struct radeonfb_info *rinfo, u8 indx, u32 value)
+{
+	OUTREG( MC_IND_INDEX, indx | MC_IND_INDEX__MC_IND_WR_EN);
+	OUTREG( MC_IND_DATA, value);
+}
+
+static u32 INMC(struct radeonfb_info *rinfo, u8 indx)
+{
+	OUTREG( MC_IND_INDEX, indx);
+	return INREG( MC_IND_DATA);
+}
+
+static void radeon_pm_save_regs(struct radeonfb_info *rinfo)
+{
+	rinfo->save_regs[0] = INPLL(PLL_PWRMGT_CNTL);
+	rinfo->save_regs[1] = INPLL(CLK_PWRMGT_CNTL);
+	rinfo->save_regs[2] = INPLL(MCLK_CNTL);
+	rinfo->save_regs[3] = INPLL(SCLK_CNTL);
+	rinfo->save_regs[4] = INPLL(CLK_PIN_CNTL);
+	rinfo->save_regs[5] = INPLL(VCLK_ECP_CNTL);
+	rinfo->save_regs[6] = INPLL(PIXCLKS_CNTL);
+	rinfo->save_regs[7] = INPLL(MCLK_MISC);
+	rinfo->save_regs[8] = INPLL(P2PLL_CNTL);
+
+	rinfo->save_regs[9] = INREG(DISP_MISC_CNTL);
+	rinfo->save_regs[10] = INREG(DISP_PWR_MAN);
+	rinfo->save_regs[11] = INREG(LVDS_GEN_CNTL);
+	rinfo->save_regs[12] = INREG(LVDS_PLL_CNTL);
+	rinfo->save_regs[13] = INREG(TV_DAC_CNTL);
+	rinfo->save_regs[14] = INREG(BUS_CNTL1);
+	rinfo->save_regs[15] = INREG(CRTC_OFFSET_CNTL);
+	rinfo->save_regs[16] = INREG(AGP_CNTL);
+	rinfo->save_regs[17] = (INREG(CRTC_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[18] = (INREG(CRTC2_GEN_CNTL) & 0xfdffffff) | 0x04000000;
+	rinfo->save_regs[19] = INREG(GPIOPAD_A);
+	rinfo->save_regs[20] = INREG(GPIOPAD_EN);
+	rinfo->save_regs[21] = INREG(GPIOPAD_MASK);
+	rinfo->save_regs[22] = INREG(ZV_LCDPAD_A);
+	rinfo->save_regs[23] = INREG(ZV_LCDPAD_EN);
+	rinfo->save_regs[24] = INREG(ZV_LCDPAD_MASK);
+	rinfo->save_regs[25] = INREG(GPIO_VGA_DDC);
+	rinfo->save_regs[26] = INREG(GPIO_DVI_DDC);
+	rinfo->save_regs[27] = INREG(GPIO_MONID);
+	rinfo->save_regs[28] = INREG(GPIO_CRT2_DDC);
+
+	rinfo->save_regs[29] = INREG(SURFACE_CNTL);
+	rinfo->save_regs[30] = INREG(MC_FB_LOCATION);
+	rinfo->save_regs[31] = INREG(DISPLAY_BASE_ADDR);
+	rinfo->save_regs[32] = INREG(MC_AGP_LOCATION);
+	rinfo->save_regs[33] = INREG(CRTC2_DISPLAY_BASE_ADDR);
+}
+
+static void radeon_pm_restore_regs(struct radeonfb_info *rinfo)
+{
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8] & 0xFFFFFFFE); /* First */
+
+	OUTPLL(PLL_PWRMGT_CNTL, rinfo->save_regs[0]);
+	OUTPLL(CLK_PWRMGT_CNTL, rinfo->save_regs[1]);
+	OUTPLL(MCLK_CNTL, rinfo->save_regs[2]);
+	OUTPLL(SCLK_CNTL, rinfo->save_regs[3]);
+	OUTPLL(CLK_PIN_CNTL, rinfo->save_regs[4]);
+	OUTPLL(VCLK_ECP_CNTL, rinfo->save_regs[5]);
+	OUTPLL(PIXCLKS_CNTL, rinfo->save_regs[6]);
+	OUTPLL(MCLK_MISC, rinfo->save_regs[7]);
+
+	OUTREG(SURFACE_CNTL, rinfo->save_regs[29]);
+	OUTREG(MC_FB_LOCATION, rinfo->save_regs[30]);
+	OUTREG(DISPLAY_BASE_ADDR, rinfo->save_regs[31]);
+	OUTREG(MC_AGP_LOCATION, rinfo->save_regs[32]);
+	OUTREG(CRTC2_DISPLAY_BASE_ADDR, rinfo->save_regs[33]);
+
+	OUTREG(DISP_MISC_CNTL, rinfo->save_regs[9]);
+	OUTREG(DISP_PWR_MAN, rinfo->save_regs[10]);
+	OUTREG(LVDS_GEN_CNTL, rinfo->save_regs[11]);
+	OUTREG(LVDS_PLL_CNTL,rinfo->save_regs[12]);
+	OUTREG(TV_DAC_CNTL, rinfo->save_regs[13]);
+	OUTREG(BUS_CNTL1, rinfo->save_regs[14]);
+	OUTREG(CRTC_OFFSET_CNTL, rinfo->save_regs[15]);
+	OUTREG(AGP_CNTL, rinfo->save_regs[16]);
+	OUTREG(CRTC_GEN_CNTL, rinfo->save_regs[17]);
+	OUTREG(CRTC2_GEN_CNTL, rinfo->save_regs[18]);
+
+	// wait VBL before that one  ?
+	OUTPLL(P2PLL_CNTL, rinfo->save_regs[8]);
+
+	OUTREG(GPIOPAD_A, rinfo->save_regs[19]);
+	OUTREG(GPIOPAD_EN, rinfo->save_regs[20]);
+	OUTREG(GPIOPAD_MASK, rinfo->save_regs[21]);
+	OUTREG(ZV_LCDPAD_A, rinfo->save_regs[22]);
+	OUTREG(ZV_LCDPAD_EN, rinfo->save_regs[23]);
+	OUTREG(ZV_LCDPAD_MASK, rinfo->save_regs[24]);
+	OUTREG(GPIO_VGA_DDC, rinfo->save_regs[25]);
+	OUTREG(GPIO_DVI_DDC, rinfo->save_regs[26]);
+	OUTREG(GPIO_MONID, rinfo->save_regs[27]);
+	OUTREG(GPIO_CRT2_DDC, rinfo->save_regs[28]);
+}
+
+static void radeon_pm_disable_iopad(struct radeonfb_info *rinfo)
+{
+	OUTREG(GPIOPAD_MASK, 0x0001ffff);
+	OUTREG(GPIOPAD_EN, 0x00000400);
+	OUTREG(GPIOPAD_A, 0x00000000);
+        OUTREG(ZV_LCDPAD_MASK, 0x00000000);
+        OUTREG(ZV_LCDPAD_EN, 0x00000000);
+      	OUTREG(ZV_LCDPAD_A, 0x00000000);
+	OUTREG(GPIO_VGA_DDC, 0x00030000);
+	OUTREG(GPIO_DVI_DDC, 0x00000000);
+	OUTREG(GPIO_MONID, 0x00030000);
+	OUTREG(GPIO_CRT2_DDC, 0x00000000);
+}
+
+static void radeon_pm_program_v2clk(struct radeonfb_info *rinfo)
+{
+	/* Set v2clk to 65MHz */
+  	OUTPLL(pllPIXCLKS_CNTL,
+  		INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK);
+
+  	OUTPLL(pllP2PLL_REF_DIV, 0x0000000c);
+	OUTPLL(pllP2PLL_CNTL, 0x0000bf00);
+	OUTPLL(pllP2PLL_DIV_0, 0x00020074 | P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W);
+
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_SLEEP);
+	mdelay(1);
+
+	OUTPLL(pllP2PLL_CNTL, INPLL(pllP2PLL_CNTL) & ~P2PLL_CNTL__P2PLL_RESET);
+	mdelay( 1);
+
+  	OUTPLL(pllPIXCLKS_CNTL,
+  		(INPLL(pllPIXCLKS_CNTL) & ~PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK)
+  		| (0x03 << PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT));
+	mdelay( 1);
+}
+
+static void radeon_pm_low_current(struct radeonfb_info *rinfo)
+{
+	u32 reg;
+
+	reg  = INREG(BUS_CNTL1);
+	reg &= ~BUS_CNTL1_MOBILE_PLATFORM_SEL_MASK;
+	reg |= BUS_CNTL1_AGPCLK_VALID | (1<<BUS_CNTL1_MOBILE_PLATFORM_SEL_SHIFT);
+	OUTREG(BUS_CNTL1, reg);
+
+	reg  = INPLL(PLL_PWRMGT_CNTL);
+	reg |= PLL_PWRMGT_CNTL_SPLL_TURNOFF | PLL_PWRMGT_CNTL_PPLL_TURNOFF |
+		PLL_PWRMGT_CNTL_P2PLL_TURNOFF | PLL_PWRMGT_CNTL_TVPLL_TURNOFF;
+	reg &= ~PLL_PWRMGT_CNTL_SU_MCLK_USE_BCLK;
+	reg &= ~PLL_PWRMGT_CNTL_MOBILE_SU;
+	OUTPLL(PLL_PWRMGT_CNTL, reg);
+
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~(TV_DAC_CNTL_BGADJ_MASK |TV_DAC_CNTL_DACADJ_MASK);
+	reg |=TV_DAC_CNTL_BGSLEEP | TV_DAC_CNTL_RDACPD | TV_DAC_CNTL_GDACPD |
+		TV_DAC_CNTL_BDACPD |
+		(8<<TV_DAC_CNTL_BGADJ__SHIFT) | (8<<TV_DAC_CNTL_DACADJ__SHIFT);
+	OUTREG(TV_DAC_CNTL, reg);
+
+	reg  = INREG(TMDS_TRANSMITTER_CNTL);
+	reg &= ~(TMDS_PLL_EN | TMDS_PLLRST);
+	OUTREG(TMDS_TRANSMITTER_CNTL, reg);
+
+	reg = INREG(DAC_CNTL);
+	reg &= ~DAC_CMP_EN;
+	OUTREG(DAC_CNTL, reg);
+
+	reg = INREG(DAC_CNTL2);
+	reg &= ~DAC2_CMP_EN;
+	OUTREG(DAC_CNTL2, reg);
+
+	reg  = INREG(TV_DAC_CNTL);
+	reg &= ~TV_DAC_CNTL_DETECT;
+	OUTREG(TV_DAC_CNTL, reg);
+}
+
+static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo)
+{
+
+	u32 sclk_cntl, mclk_cntl, sclk_more_cntl;
+
+	u32 pll_pwrmgt_cntl;
+	u32 clk_pwrmgt_cntl;
+	u32 clk_pin_cntl;
+	u32 vclk_ecp_cntl;
+	u32 pixclks_cntl;
+	u32 disp_mis_cntl;
+	u32 disp_pwr_man;
+
+
+	/* Force Core Clocks */
+	sclk_cntl = INPLL( pllSCLK_CNTL_M6);
+	sclk_cntl |= 	SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT|
+			SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT|
+
+			SCLK_CNTL_M6__FORCE_DISP2|
+			SCLK_CNTL_M6__FORCE_CP|
+			SCLK_CNTL_M6__FORCE_HDP|
+			SCLK_CNTL_M6__FORCE_DISP1|
+			SCLK_CNTL_M6__FORCE_TOP|
+			SCLK_CNTL_M6__FORCE_E2|
+			SCLK_CNTL_M6__FORCE_SE|
+			SCLK_CNTL_M6__FORCE_IDCT|
+			SCLK_CNTL_M6__FORCE_VIP|
+
+			SCLK_CNTL_M6__FORCE_RE|
+			SCLK_CNTL_M6__FORCE_PB|
+			SCLK_CNTL_M6__FORCE_TAM|
+			SCLK_CNTL_M6__FORCE_TDM|
+			SCLK_CNTL_M6__FORCE_RB|
+			SCLK_CNTL_M6__FORCE_TV_SCLK|
+			SCLK_CNTL_M6__FORCE_SUBPIC|
+			SCLK_CNTL_M6__FORCE_OV0;
+
+	OUTPLL( pllSCLK_CNTL_M6, sclk_cntl);
+
+	sclk_more_cntl = INPLL(pllSCLK_MORE_CNTL);
+	sclk_more_cntl |= 	SCLK_MORE_CNTL__FORCE_DISPREGS |
+				SCLK_MORE_CNTL__FORCE_MC_GUI |
+				SCLK_MORE_CNTL__FORCE_MC_HOST;
+
+	OUTPLL(pllSCLK_MORE_CNTL, sclk_more_cntl);
+
+
+	mclk_cntl = INPLL( pllMCLK_CNTL_M6);
+	mclk_cntl &= ~(	MCLK_CNTL_M6__FORCE_MCLKA |
+			MCLK_CNTL_M6__FORCE_MCLKB |
+			MCLK_CNTL_M6__FORCE_YCLKA |
+			MCLK_CNTL_M6__FORCE_YCLKB |
+			MCLK_CNTL_M6__FORCE_MC
+		      );
+    	OUTPLL( pllMCLK_CNTL_M6, mclk_cntl);
+
+	/* Force Display clocks	*/
+	vclk_ecp_cntl = INPLL( pllVCLK_ECP_CNTL);
+	vclk_ecp_cntl &= ~(VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb |VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb);
+	vclk_ecp_cntl |= VCLK_ECP_CNTL__ECP_FORCE_ON;
+	OUTPLL( pllVCLK_ECP_CNTL, vclk_ecp_cntl);
+
+
+	pixclks_cntl = INPLL( pllPIXCLKS_CNTL);
+	pixclks_cntl &= ~(	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb |
+				PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb |
+				PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb|
+				PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb);
+
+ 	OUTPLL( pllPIXCLKS_CNTL, pixclks_cntl);
+
+
+
+	/* Enable System power management */
+	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL);
+
+	pll_pwrmgt_cntl |= 	PLL_PWRMGT_CNTL__SPLL_TURNOFF |
+				PLL_PWRMGT_CNTL__MPLL_TURNOFF|
+				PLL_PWRMGT_CNTL__PPLL_TURNOFF|
+				PLL_PWRMGT_CNTL__P2PLL_TURNOFF|
+				PLL_PWRMGT_CNTL__TVPLL_TURNOFF;
+
+	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
+
+	clk_pwrmgt_cntl	 = INPLL( pllCLK_PWRMGT_CNTL_M6);
+
+	clk_pwrmgt_cntl &= ~(	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF|
+				CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF|
+				CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN|
+				CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE|
+				CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK|
+				CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK
+			);
+
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN | CLK_PWRMGT_CNTL_M6__DISP_PM;
+
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+
+	clk_pin_cntl = INPLL( pllCLK_PIN_CNTL);
+
+	clk_pin_cntl &= ~CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND;
+	OUTPLL( pllMCLK_MISC, INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND);
+
+	/* AGP PLL control */
+	OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) |  BUS_CNTL1__AGPCLK_VALID);
+
+	OUTREG(BUS_CNTL1,
+		(INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK)
+		| (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT));	// 440BX
+	OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN));
+
+	clk_pin_cntl &= ~CLK_PIN_CNTL__CG_CLK_TO_OUTPIN;
+	clk_pin_cntl |= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+
+	/* Solano2M */
+	OUTREG(AGP_CNTL,
+		(INREG(AGP_CNTL) & ~(AGP_CNTL__MAX_IDLE_CLK_MASK))
+		| (0x20<<AGP_CNTL__MAX_IDLE_CLK__SHIFT));
+
+	/* ACPI mode */
+	OUTPLL( pllPLL_PWRMGT_CNTL, INPLL( pllPLL_PWRMGT_CNTL) & ~PLL_PWRMGT_CNTL__PM_MODE_SEL);
+
+
+	disp_mis_cntl = INREG(DISP_MISC_CNTL);
+
+	disp_mis_cntl &= ~(	DISP_MISC_CNTL__SOFT_RESET_GRPH_PP |
+				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP |
+				DISP_MISC_CNTL__SOFT_RESET_OV0_PP |
+				DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP|
+				DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK|
+				DISP_MISC_CNTL__SOFT_RESET_LVDS|
+				DISP_MISC_CNTL__SOFT_RESET_TMDS|
+				DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS|
+				DISP_MISC_CNTL__SOFT_RESET_TV);
+
+	OUTREG(DISP_MISC_CNTL, disp_mis_cntl);
+
+	disp_pwr_man = INREG(DISP_PWR_MAN);
+
+	disp_pwr_man &= ~(	DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN	|
+						DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN |
+						DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK|
+						DISP_PWR_MAN__DISP_D3_RST|
+						DISP_PWR_MAN__DISP_D3_REG_RST
+					);
+
+	disp_pwr_man |= DISP_PWR_MAN__DISP_D3_GRPH_RST|
+					DISP_PWR_MAN__DISP_D3_SUBPIC_RST|
+					DISP_PWR_MAN__DISP_D3_OV0_RST|
+					DISP_PWR_MAN__DISP_D1D2_GRPH_RST|
+					DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST|
+					DISP_PWR_MAN__DISP_D1D2_OV0_RST|
+					DISP_PWR_MAN__DIG_TMDS_ENABLE_RST|
+					DISP_PWR_MAN__TV_ENABLE_RST|
+//					DISP_PWR_MAN__AUTO_PWRUP_EN|
+					0;
+
+	OUTREG(DISP_PWR_MAN, disp_pwr_man);
+
+	clk_pwrmgt_cntl = INPLL( pllCLK_PWRMGT_CNTL_M6);
+	pll_pwrmgt_cntl = INPLL( pllPLL_PWRMGT_CNTL) ;
+	clk_pin_cntl 	= INPLL( pllCLK_PIN_CNTL);
+	disp_pwr_man	= INREG(DISP_PWR_MAN);
+
+
+	/* D2 */
+	clk_pwrmgt_cntl |= CLK_PWRMGT_CNTL_M6__DISP_PM;
+	pll_pwrmgt_cntl |= PLL_PWRMGT_CNTL__MOBILE_SU | PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK;
+	clk_pin_cntl	|= CLK_PIN_CNTL__XTALIN_ALWAYS_ONb;
+	disp_pwr_man 	&= ~(DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK | DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK);
+
+
+	OUTPLL( pllCLK_PWRMGT_CNTL_M6, clk_pwrmgt_cntl);
+	OUTPLL( pllPLL_PWRMGT_CNTL, pll_pwrmgt_cntl);
+	OUTPLL( pllCLK_PIN_CNTL, clk_pin_cntl);
+	OUTREG(DISP_PWR_MAN, disp_pwr_man);
+
+	/* disable display request & disable display */
+	OUTREG( CRTC_GEN_CNTL, (INREG( CRTC_GEN_CNTL) & ~CRTC_GEN_CNTL__CRTC_EN) | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B);
+	OUTREG( CRTC2_GEN_CNTL, (INREG( CRTC2_GEN_CNTL) & ~CRTC2_GEN_CNTL__CRTC2_EN) | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B);
+
+	mdelay(17);
+
+}
+
+static void radeon_pm_yclk_mclk_sync(struct radeonfb_info *rinfo)
+{
+	u32 mc_chp_io_cntl_a1, mc_chp_io_cntl_b1;
+
+	mc_chp_io_cntl_a1 = INMC( rinfo, ixMC_CHP_IO_CNTL_A1) & ~MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK;
+	mc_chp_io_cntl_b1 = INMC( rinfo, ixMC_CHP_IO_CNTL_B1) & ~MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK;
+
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1 | (1<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT));
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1 | (1<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT));
+
+	/* Wassup ? This doesn't seem to be defined, let's hope we are ok this way --BenH */
+#ifdef MCLK_YCLK_SYNC_ENABLE
+	mc_chp_io_cntl_a1 |= (2<<MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT);
+	mc_chp_io_cntl_b1 |= (2<<MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT);
+#endif
+
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_A1, mc_chp_io_cntl_a1);
+	OUTMC( rinfo, ixMC_CHP_IO_CNTL_B1, mc_chp_io_cntl_b1);
+
+	mdelay( 1);
+}
+
+static void radeon_pm_program_mode_reg(struct radeonfb_info *rinfo, u16 value, u8 delay_required)
+{
+	u32 mem_sdram_mode;
+
+	mem_sdram_mode  = INREG( MEM_SDRAM_MODE_REG);
+
+	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK;
+	mem_sdram_mode |= (value<<MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT) | MEM_SDRAM_MODE_REG__MEM_CFG_TYPE;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+
+	mem_sdram_mode |=  MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+
+	mem_sdram_mode &= ~MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET;
+	OUTREG( MEM_SDRAM_MODE_REG, mem_sdram_mode);
+
+	if (delay_required == 1)
+		while( (INREG( MC_STATUS) & (MC_STATUS__MEM_PWRUP_COMPL_A | MC_STATUS__MEM_PWRUP_COMPL_B) ) == 0 )
+			{ };
+}
+
+
+static void radeon_pm_enable_dll(struct radeonfb_info *rinfo)
+{
+#define DLL_RESET_DELAY 	5
+#define DLL_SLEEP_DELAY		1
+
+	u32 DLL_CKO_Value = INPLL(pllMDLL_CKO)   | MDLL_CKO__MCKOA_SLEEP |  MDLL_CKO__MCKOA_RESET;
+	u32 DLL_CKA_Value = INPLL(pllMDLL_RDCKA) | MDLL_RDCKA__MRDCKA0_SLEEP | MDLL_RDCKA__MRDCKA1_SLEEP | MDLL_RDCKA__MRDCKA0_RESET | MDLL_RDCKA__MRDCKA1_RESET;
+	u32 DLL_CKB_Value = INPLL(pllMDLL_RDCKB) | MDLL_RDCKB__MRDCKB0_SLEEP | MDLL_RDCKB__MRDCKB1_SLEEP | MDLL_RDCKB__MRDCKB0_RESET | MDLL_RDCKB__MRDCKB1_RESET;
+
+	/* Setting up the DLL range for write */
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
+	OUTPLL(pllMDLL_RDCKB,	DLL_CKB_Value);
+
+	mdelay( DLL_RESET_DELAY);
+
+	/* Channel A */
+
+	/* Power Up */
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_SLEEP );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOA_RESET );
+	OUTPLL(pllMDLL_CKO,	DLL_CKO_Value);
+	mdelay( DLL_RESET_DELAY);
+
+	/* Power Up */
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_SLEEP );
+	OUTPLL(pllMDLL_RDCKA,  	DLL_CKA_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA0_RESET );
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_RESET_DELAY);
+
+	/* Power Up */
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_SLEEP);
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKA_Value &= ~(MDLL_RDCKA__MRDCKA1_RESET);
+	OUTPLL(pllMDLL_RDCKA,	DLL_CKA_Value);
+	mdelay( DLL_RESET_DELAY);
+
+
+	/* Channel B */
+
+	/* Power Up */
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_SLEEP );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKO_Value &= ~(MDLL_CKO__MCKOB_RESET );
+	OUTPLL(pllMDLL_CKO,   	DLL_CKO_Value);
+	mdelay( DLL_RESET_DELAY);
+
+	/* Power Up */
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_SLEEP);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB0_RESET);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_RESET_DELAY);
+
+	/* Power Up */
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_SLEEP);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_SLEEP_DELAY);
+
+	DLL_CKB_Value &= ~(MDLL_RDCKB__MRDCKB1_RESET);
+	OUTPLL(pllMDLL_RDCKB,   DLL_CKB_Value);
+	mdelay( DLL_RESET_DELAY);
+
+#undef DLL_RESET_DELAY
+#undef DLL_SLEEP_DELAY
+}
+
+static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)
+{
+	u32 crtcGenCntl, crtcGenCntl2, memRefreshCntl, crtc_more_cntl, fp_gen_cntl, fp2_gen_cntl;
+
+	crtcGenCntl  = INREG( CRTC_GEN_CNTL);
+	crtcGenCntl2 = INREG( CRTC2_GEN_CNTL);
+
+	memRefreshCntl 	= INREG( MEM_REFRESH_CNTL);
+	crtc_more_cntl 	= INREG( CRTC_MORE_CNTL);
+	fp_gen_cntl 	= INREG( FP_GEN_CNTL);
+	fp2_gen_cntl 	= INREG( FP2_GEN_CNTL);
+
+
+	OUTREG( CRTC_MORE_CNTL, 	0);
+	OUTREG( FP_GEN_CNTL, 	0);
+	OUTREG( FP2_GEN_CNTL, 	0);
+
+	OUTREG( CRTC_GEN_CNTL,  (crtcGenCntl | CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B) );
+	OUTREG( CRTC2_GEN_CNTL, (crtcGenCntl2 | CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B) );
+
+	/* Disable refresh */
+	OUTREG( MEM_REFRESH_CNTL, memRefreshCntl | MEM_REFRESH_CNTL__MEM_REFRESH_DIS);
+
+	/* Reset memory */
+	OUTREG( MEM_SDRAM_MODE_REG,
+		INREG( MEM_SDRAM_MODE_REG) & ~MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init  Not Complete
+
+	/* DLL */
+	radeon_pm_enable_dll(rinfo);
+
+	// MLCK /YCLK sync
+	radeon_pm_yclk_mclk_sync(rinfo);
+
+	if ((rinfo->arch == RADEON_M6) || (rinfo->arch == RADEON_M7) || (rinfo->arch == RADEON_M9)) {
+		radeon_pm_program_mode_reg(rinfo, 0x2000, 1);
+		radeon_pm_program_mode_reg(rinfo, 0x2001, 1);
+		radeon_pm_program_mode_reg(rinfo, 0x2002, 1);
+		radeon_pm_program_mode_reg(rinfo, 0x0132, 1);
+		radeon_pm_program_mode_reg(rinfo, 0x0032, 1);
+	}
+
+	OUTREG( MEM_SDRAM_MODE_REG,
+		INREG( MEM_SDRAM_MODE_REG) |  MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE); // Init Complete
+
+	OUTREG( MEM_REFRESH_CNTL, 	memRefreshCntl);
+
+	OUTREG( CRTC_GEN_CNTL, 		crtcGenCntl);
+	OUTREG( CRTC2_GEN_CNTL, 	crtcGenCntl2);
+	OUTREG( FP_GEN_CNTL, 		fp_gen_cntl);
+	OUTREG( FP2_GEN_CNTL, 		fp2_gen_cntl);
+
+	OUTREG( CRTC_MORE_CNTL, 	crtc_more_cntl);
+
+	mdelay( 15);
+}
+
+static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
+{
+	u16 pwr_cmd;
+
+	if (!rinfo->pm_reg)
+		return;
+
+	/* Set the chip into appropriate suspend mode (we use D2,
+	 * D3 would require a compete re-initialization of the chip,
+	 * including PCI config registers, clocks, AGP conf, ...)
+	 */
+	if (suspend) {
+		/* Disable dynamic power management of clocks for the
+		 * duration of the suspend/resume process
+		 */
+		radeon_pm_disable_dynamic_mode(rinfo);
+		/* Save some registers */
+		radeon_pm_save_regs(rinfo);
+
+		/* Prepare mobility chips for suspend
+		 */
+		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9) {
+			/* Program V2CLK */
+			radeon_pm_program_v2clk(rinfo);
+
+			/* Disable IO PADs */
+			radeon_pm_disable_iopad(rinfo);
+
+			/* Set low current */
+			radeon_pm_low_current(rinfo);
+
+			/* Prepare chip for power management */
+			radeon_pm_setup_for_suspend(rinfo);
+
+			/* Reset the MDLL */
+			OUTPLL( pllMDLL_CKO, INPLL( pllMDLL_CKO) | MDLL_CKO__MCKOA_RESET | MDLL_CKO__MCKOB_RESET);
+		}
+
+		/* Switch PCI power managment to D2. */
+		for (;;) {
+			pci_read_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				&pwr_cmd);
+			if (pwr_cmd & 2)
+				break;
+			pci_write_config_word(
+				rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL,
+				(pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2);
+			mdelay(500);
+		}
+	} else {
+		/* Switch back PCI powermanagment to D0 */
+		mdelay(200);
+		pci_write_config_word(rinfo->pdev, rinfo->pm_reg+PCI_PM_CTRL, 0);
+		mdelay(500);
+
+		/* Reset the SDRAM controller */
+		if (rinfo->arch == RADEON_M6 || rinfo->arch == RADEON_M7 || rinfo->arch == RADEON_M9)
+			radeon_pm_full_reset_sdram(rinfo);
+
+		/* Restore some registers */
+		radeon_pm_restore_regs(rinfo);
+		radeon_pm_enable_dynamic_mode(rinfo);
+	}
+}
+
+int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+	/* We don't do anything but D2, for now we return 0, but
+	 * we may want to change that. How do we know if the BIOS
+	 * can properly take care of D3 ? Also, with swsusp, we
+	 * know we'll be rebooted, ...
+	 */
+#ifdef CONFIG_PPC_PMAC
+	/* HACK ALERT ! Once I find a proper way to say to each driver
+	 * individually what will happen with it's PCI slot, I'll change
+	 * that. On laptops, the AGP slot is just unclocked, so D2 is
+	 * expected, while on desktops, the card is powered off
+	 */
+	if (state >= 3)
+		state = 2;
+#endif /* CONFIG_PPC_PMAC */
+
+	if (state != 2 || state == pdev->dev.power_state)
+		return 0;
+
+	printk(KERN_DEBUG "radeonfb: suspending...\n");
+
+	acquire_console_sem();
+
+#if 0 /* Re-enable when core support merged by James */
+	fb_set_suspend(rinfo->info, 1);
+
+	/* Setup dummy fb raster ops */
+	rinfo->info.fbops->fb_fillrect 	= fb_dummy_fillrect;
+	rinfo->info.fbops->fb_copyarea 	= fb_dummy_copyarea;
+	rinfo->info.fbops->fb_imageblit	= fb_dummy_imageblit;
+	rinfo->info.fbops->fb_cursor   	= fb_dummy_cursor;
+#endif
+	if (!radeon_accel_disabled()) {
+		/* Make sure engine is reset */
+		radeon_engine_idle();
+		radeon_engine_reset();
+		radeon_engine_idle();
+	}
+
+	/* Blank display and LCD */
+	radeonfb_blank(VESA_POWERDOWN+1, rinfo->info);
+
+	/* Sleep */
+	rinfo->asleep = 1;
+	rinfo->lock_blank = 1;
+
+	/* We need a way to make sure the fbdev layer will _not_ touch the
+	 * framebuffer before we put the chip to suspend state. On 2.4, I
+	 * used dummy fb ops, 2.5 need proper support for this at the
+	 * fbdev level
+	 */
+	if (state == 2)
+		radeon_set_suspend(rinfo, 1);
+
+	release_console_sem();
+
+	pdev->dev.power_state = state;
+
+	return 0;
+}
+
+int radeonfb_pci_resume(struct pci_dev *pdev)
+{
+	struct radeonfb_info *rinfo = pci_get_drvdata(pdev);
+
+	if (pdev->dev.power_state == 0)
+		return 0;
+
+	acquire_console_sem();
+
+	/* Wakeup chip */
+	if (pdev->dev.power_state == 2)
+		radeon_set_suspend(rinfo, 0);
+	rinfo->asleep = 0;
+
+	/* Restore display & engine */
+	radeonfb_set_par(rinfo->info);
+	fb_pan_display(rinfo->info, &rinfo->info->var);
+	fb_set_cmap(&rinfo->info->cmap, 1, rinfo->info);
+
+	/* Restore fb raster ops */
+	rinfo->info->fbops->fb_fillrect  = cfb_fillrect;
+	rinfo->info->fbops->fb_copyarea  = cfb_copyarea;
+	rinfo->info->fbops->fb_imageblit = cfb_imageblit;
+	rinfo->info->fbops->fb_cursor    = soft_cursor;
+
+#if 0 /* Re-enable when core support merged by James */
+	/* Refresh */
+	fb_set_suspend(rinfo->info, 0);
+#endif
+	/* Unblank */
+	rinfo->lock_blank = 0;
+	radeonfb_blank(0, rinfo->info);
+
+	release_console_sem();
+
+	pdev->dev.power_state = 0;
+
+	printk(KERN_DEBUG "radeonfb: resumed !\n");
+
+	return 0;
+}
+
+#endif /* CONFIG_PM */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/aty/radeonfb.h fbdev-2.6/drivers/video/aty/radeonfb.h
--- linus-2.6/drivers/video/aty/radeonfb.h	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/aty/radeonfb.h	Wed Oct 15 17:00:43 2003
@@ -0,0 +1,420 @@
+#ifndef __RADEONFB_H__
+#define __RADEONFB_H__
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/fb.h>
+
+
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+
+#include <video/radeon.h>
+
+
+enum radeon_arch {
+	RADEON_R100,
+	RADEON_RV100,
+	RADEON_R200,
+	RADEON_RV200,
+	RADEON_RV250,
+	RADEON_RV280,
+	RADEON_R300,
+	RADEON_RS300,
+	RADEON_R350,
+	RADEON_M6,
+	RADEON_M7,
+	RADEON_M9,
+	RADEON_R200_SEC,
+	RADEON_RV250_SEC,
+	RADEON_R300_SEC,
+	RADEON_R350_SEC,
+	RADEON_M9_SEC,
+};
+
+enum radeon_montype
+{
+	MT_NONE = 0,
+	MT_CRT,		/* CRT */
+	MT_LCD,		/* LCD */
+	MT_DFP,		/* DVI */
+	MT_CTV,		/* composite TV */
+	MT_STV		/* S-Video out */
+};
+
+
+typedef struct {
+        u8 clock_chip_type;
+        u8 struct_size;
+        u8 accelerator_entry;
+        u8 VGA_entry;
+        u16 VGA_table_offset;
+        u16 POST_table_offset;
+        u16 XCLK;
+        u16 MCLK;
+        u8 num_PLL_blocks;
+        u8 size_PLL_blocks;
+        u16 PCLK_ref_freq;
+        u16 PCLK_ref_divider;
+        u32 PCLK_min_freq;
+        u32 PCLK_max_freq;
+        u16 MCLK_ref_freq;
+        u16 MCLK_ref_divider;
+        u32 MCLK_min_freq;
+        u32 MCLK_max_freq;
+        u16 XCLK_ref_freq;
+        u16 XCLK_ref_divider;
+        u32 XCLK_min_freq;
+        u32 XCLK_max_freq;
+} __attribute__ ((packed)) PLL_BLOCK;
+
+
+struct pll_info {
+	int ppll_max;
+	int ppll_min;
+	int xclk;
+	int ref_div;
+	int ref_clk;
+};
+
+
+struct ram_info {
+	int ml;
+	int mb;
+	int trcd;
+	int trp;
+	int twr;
+	int cl;
+	int tr2w;
+	int loop_latency;
+	int rloop;
+};
+
+
+struct radeon_regs {
+	/* CRTC regs */
+	u32 crtc_h_total_disp;
+	u32 crtc_h_sync_strt_wid;
+	u32 crtc_v_total_disp;
+	u32 crtc_v_sync_strt_wid;
+	u32 crtc_pitch;
+	u32 crtc_gen_cntl;
+	u32 crtc_ext_cntl;
+	u32 crtc_more_cntl;
+	u32 dac_cntl;
+
+	u32 flags;
+	u32 pix_clock;
+	int xres, yres;
+
+	/* PLL regs */
+	u32 ppll_div_3;
+	u32 ppll_ref_div;
+	u32 vclk_ecp_cntl;
+
+	/* Flat panel regs */
+	u32 fp_crtc_h_total_disp;
+	u32 fp_crtc_v_total_disp;
+	u32 fp_gen_cntl;
+	u32 fp_h_sync_strt_wid;
+	u32 fp_horz_stretch;
+	u32 fp_panel_cntl;
+	u32 fp_v_sync_strt_wid;
+	u32 fp_vert_stretch;
+	u32 lvds_gen_cntl;
+	u32 lvds_pll_cntl;
+	u32 tmds_crc;
+	u32 tmds_transmitter_cntl;
+
+	/* Aperture access control */
+	u32 surface_cntl;
+};
+
+struct panel_info {
+	int xres, yres;
+	int valid;
+	int clock;
+	int hOver_plus, hSync_width, hblank;
+	int vOver_plus, vSync_width, vblank;
+	int hAct_high, vAct_high, interlaced;
+	int pwr_delay;
+	int use_bios_dividers;
+	int ref_divider;
+	int post_divider;
+	int fbk_divider;
+};
+
+struct radeonfb_info;
+
+enum ddc_type {
+	ddc_none,
+	ddc_monid,
+	ddc_dvi,
+	ddc_vga,
+	ddc_crt2,
+};
+
+#ifdef CONFIG_FB_RADEON_I2C
+struct radeon_i2c_chan {
+	struct radeonfb_info		*rinfo;
+	u32		 		ddc_reg;
+	struct i2c_adapter		adapter;
+	struct i2c_algo_bit_data	algo;
+};
+#endif
+
+struct radeonfb_info {
+	struct fb_info 		*info;
+
+	struct radeon_regs 	state;
+	struct radeon_regs	init_state;
+
+	char			name[DEVICE_NAME_SIZE];
+	char			ram_type[12];
+
+	unsigned long		mmio_base_phys;
+	unsigned long		fb_base_phys;
+
+	unsigned long		mmio_base;
+	unsigned long		fb_base;
+
+	unsigned long 		fb_local_base;
+
+	struct pci_dev		*pdev;
+
+	u8			*bios_seg;
+	int			fp_bios_start;
+
+	u32			pseudo_palette[17];
+	struct { u8 red, green, blue, pad; }
+				palette[256];
+
+	int			chipset;
+	u8			arch;
+	u8			rev;
+	unsigned long		video_ram;
+
+	int			pitch, bpp, depth;
+	int			xres, yres, pixclock;
+	int			xres_virtual, yres_virtual;
+	u32			accel_flags;
+
+	// KILL THOSE
+	int use_default_var;
+	int got_dfpinfo;
+
+	int			has_CRTC2 : 1;
+	int			is_mobility : 1;
+	int			reversed_DAC : 1;
+	int			reversed_TMDS : 1;
+	struct panel_info	panel_info;
+	int			mon1_type;
+	u8			*mon1_EDID;
+	struct fb_videomode	*mon1_modedb;
+	int			mon1_dbsize;
+	int			mon2_type;
+	u8		        *mon2_EDID;
+
+	u32			dp_gui_master_cntl;
+
+	struct pll_info		pll;
+	int			pll_output_freq, post_div, fb_div;
+
+	struct ram_info		ram;
+
+	int			mtrr_hdl;
+
+	int			pm_reg;
+	u32			save_regs[64];
+	int			asleep;
+	int			lock_blank;
+
+#ifdef CONFIG_FB_RADEON_I2C
+	struct radeon_i2c_chan 	i2c[4];
+#endif
+
+	struct radeonfb_info *next;
+};
+
+
+#define PRIMARY_MONITOR(rinfo)	(rinfo->mon1_type)
+
+
+/*
+ * Debugging stuffs
+ */
+#define DEBUG		1
+
+#if DEBUG
+#define RTRACE		printk
+#else
+#define RTRACE		if(0) printk
+#endif
+
+
+/*
+ * IO macros
+ */
+
+#define INREG8(addr)		readb((rinfo->mmio_base)+addr)
+#define OUTREG8(addr,val)	writeb(val, (rinfo->mmio_base)+addr)
+#define INREG(addr)		readl((rinfo->mmio_base)+addr)
+#define OUTREG(addr,val)	writel(val, (rinfo->mmio_base)+addr)
+
+#define OUTPLL(addr,val)	\
+	do {	\
+		OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000003f) | 0x00000080); \
+		OUTREG(CLOCK_CNTL_DATA, val); \
+	} while(0)
+
+#define OUTPLLP(addr,val,mask)  					\
+	do {								\
+		unsigned int _tmp = INPLL(addr);			\
+		_tmp &= (mask);						\
+		_tmp |= (val);						\
+		OUTPLL(addr, _tmp);					\
+	} while (0)
+
+#define OUTREGP(addr,val,mask)  					\
+	do {								\
+		unsigned int _tmp = INREG(addr);			\
+		_tmp &= (mask);						\
+		_tmp |= (val);						\
+		OUTREG(addr, _tmp);					\
+	} while (0)
+
+
+static __inline__ u32 _INPLL(struct radeonfb_info *rinfo, u32 addr)
+{
+	OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f);
+	return (INREG(CLOCK_CNTL_DATA));
+}
+
+#define INPLL(addr)		_INPLL(rinfo, addr)
+
+#define BIOS_IN8(v)  	(readb(rinfo->bios_seg + (v)))
+#define BIOS_IN16(v) 	(readb(rinfo->bios_seg + (v)) | \
+			  (readb(rinfo->bios_seg + (v) + 1) << 8))
+#define BIOS_IN32(v) 	(readb(rinfo->bios_seg + (v)) | \
+			  (readb(rinfo->bios_seg + (v) + 1) << 8) | \
+			  (readb(rinfo->bios_seg + (v) + 2) << 16) | \
+			  (readb(rinfo->bios_seg + (v) + 3) << 24))
+
+/*
+ * Inline utilities
+ */
+
+static inline void wait_ms(unsigned long ms)
+{
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout((ms * HZ + 999) / 1000);
+}
+
+
+
+static inline int round_div(int num, int den)
+{
+        return (num + (den / 2)) / den;
+}
+
+static inline int var_to_depth(const struct fb_var_screeninfo *var)
+{
+	if (var->bits_per_pixel != 16)
+		return var->bits_per_pixel;
+	return (var->green.length == 6) ? 16 : 15;
+}
+
+static inline u32 radeon_get_dstbpp(u16 depth)
+{
+	switch (depth) {
+       	case 8:
+       		return DST_8BPP;
+       	case 15:
+       		return DST_15BPP;
+       	case 16:
+       		return DST_16BPP;
+       	case 32:
+       		return DST_32BPP;
+       	default:
+       		return 0;
+	}
+}
+
+/*
+ * 2D Engine helper routines
+ */
+static inline void radeon_engine_flush (struct radeonfb_info *rinfo)
+{
+	int i;
+
+	/* initiate flush */
+	OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL,
+	        ~RB2D_DC_FLUSH_ALL);
+
+	for (i=0; i < 2000000; i++) {
+		if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY))
+			break;
+	}
+}
+
+
+static inline void _radeon_fifo_wait (struct radeonfb_info *rinfo, int entries)
+{
+	int i;
+
+	for (i=0; i<2000000; i++)
+		if ((INREG(RBBM_STATUS) & 0x7f) >= entries)
+			return;
+}
+
+
+static inline void _radeon_engine_idle (struct radeonfb_info *rinfo)
+{
+	int i;
+
+	/* ensure FIFO is empty before waiting for idle */
+	_radeon_fifo_wait (rinfo, 64);
+
+	for (i=0; i<2000000; i++) {
+		if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) {
+			radeon_engine_flush (rinfo);
+			return;
+		}
+	}
+}
+
+#define radeon_engine_idle()		_radeon_engine_idle(rinfo)
+#define radeon_fifo_wait(entries)	_radeon_fifo_wait(rinfo,entries)
+
+
+/* I2C Functions */
+extern void radeon_create_i2c_busses(struct radeonfb_info *rinfo);
+extern void radeon_delete_i2c_busses(struct radeonfb_info *rinfo);
+extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid);
+
+/* PM Functions */
+extern void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo);
+extern void radeon_pm_enable_dynamic_mode(struct radeonfb_info *rinfo);
+extern int radeonfb_pci_suspend(struct pci_dev *pdev, u32 state);
+extern int radeonfb_pci_resume(struct pci_dev *pdev);
+
+/* Monitor probe functions */
+extern void radeon_probe_screens(struct radeonfb_info *rinfo,
+				 const char *monitor_layout, int ignore_edid);
+extern void radeon_check_modes(struct radeonfb_info *rinfo, const char *mode_option);
+
+/* Other functions */
+#define radeon_engine_reset()		_radeon_engine_reset(rinfo)
+extern void _radeon_engine_reset(struct radeonfb_info *rinfo);
+extern int radeonfb_blank(int blank, struct fb_info *info);
+extern int radeonfb_set_par(struct fb_info *info);
+extern int radeon_accel_disabled(void);
+
+#endif /* __RADEONFB_H__ */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/bw2.c fbdev-2.6/drivers/video/bw2.c
--- linus-2.6/drivers/video/bw2.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/bw2.c	Thu Oct 16 14:13:30 2003
@@ -119,6 +119,7 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -284,95 +285,90 @@
 	}
 }
 
-struct all_info {
-	struct fb_info info;
-	struct bw2_par par;
-	struct list_head list;
-};
 static LIST_HEAD(bw2_list);
 
 static void bw2_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct bw2_par *par;
+	struct fb_info *info;
 	struct resource *resp;
 #ifdef CONFIG_SUN4
 	struct resource res;
 #endif
 	int linebytes;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct bw2_par), NULL);
+	if (!info) {
 		printk(KERN_ERR "bw2: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
 #ifdef CONFIG_SUN4
 	if (!sdev) {
-		all->par.physbase = sun4_bwtwo_physaddr;
+		par->physbase = sun4_bwtwo_physaddr;
 		res.start = sun4_bwtwo_physaddr;
 		res.end = res.start + BWTWO_REGISTER_OFFSET + sizeof(struct bw2_regs) - 1;
 		res.flags = IORESOURCE_IO;
 		resp = &res;
-		all->info.var.xres = all->info.var.xres_virtual = 1152;
-		all->info.var.yres = all->info.var.yres_virtual = 900;
-		all->info.bits_per_pixel = 1;
+		info->var.xres = info->var.xres_virtual = 1152;
+		info->info.var.yres = info->var.yres_virtual = 900;
+		info->info.bits_per_pixel = 1;
 		linebytes = 1152 / 8;
 	} else
 #else
 	{
 		if (!sdev)
 			BUG();
-		all->par.physbase = sdev->reg_addrs[0].phys_addr;
+		par->physbase = sdev->reg_addrs[0].phys_addr;
 		resp = &sdev->resource[0];
-		sbusfb_fill_var(&all->info.var, (sdev ? sdev->prom_node : 0), 1);
+		sbusfb_fill_var(&info->var, (sdev ? sdev->prom_node : 0), 1);
 		linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-					       all->info.var.xres);
+					       info->var.xres);
 	}
 #endif
 
-	all->par.regs = (struct bw2_regs *)
+	par->regs = (struct bw2_regs *)
 		sbus_ioremap(resp, BWTWO_REGISTER_OFFSET,
 			     sizeof(struct bw2_regs), "bw2 regs");
 
 	if (sdev && !prom_getbool(sdev->prom_node, "width"))
-		bw2_do_default_mode(&all->par, &all->info, &linebytes);
+		bw2_do_default_mode(par, info, &linebytes);
 
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &bw2_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &bw2_ops;
 #if defined(CONFIG_SPARC32)
 	if (sdev)
-		all->info.screen_base = (char *)
+		info->screen_base = (char *)
 			prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
-			sbus_ioremap(resp, 0, all->par.fbsize, "bw2 ram");
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+	if (!info->screen_base)
+		info->screen_base = (char *)
+			sbus_ioremap(resp, 0, par->fbsize, "bw2 ram");
 
-	bw2_blank(0, &all->info);
+	bw2_blank(0, info);
 
-	bw2_init_fix(&all->info, linebytes);
+	bw2_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "bw2: Could not register framebuffer.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &bw2_list);
+	list_add(&par->list, &bw2_list);
 
 	printk("bw2: bwtwo at %lx:%lx\n",
 	       (long) (sdev ? sdev->reg_addrs[0].which_io : 0),
-	       (long) all->par.physbase);
+	       (long) par->physbase);
 }
 
 int __init bw2_init(void)
@@ -396,10 +392,10 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &bw2_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct bw2_par *par = list_entry(pos, typeof(*par), list);
 
-		unregister_framebuffer(&all->info);
-		kfree(all);
+		unregister_framebuffer(par->info);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cg14.c fbdev-2.6/drivers/video/cg14.c
--- linus-2.6/drivers/video/cg14.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/cg14.c	Thu Oct 16 14:13:30 2003
@@ -204,6 +204,7 @@
 	int			mode;
 	int			ramsize;
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -386,16 +387,12 @@
 	{ 0,			0,			0		    }
 };
 
-struct all_info {
-	struct fb_info info;
-	struct cg14_par par;
-	struct list_head list;
-};
 static LIST_HEAD(cg14_list);
 
 static void cg14_init_one(struct sbus_dev *sdev, int node, int parent_node)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct cg14_par *par;
 	unsigned long phys, rphys;
 	u32 bases[6];
 	int is_8mb, linebytes, i;
@@ -413,70 +410,71 @@
 		}
 	}
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct cg14_par), NULL);
+	if (!info) {
 		printk(KERN_ERR "cg14: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
+	spin_lock_init(&par->lock);
 
-	sbusfb_fill_var(&all->info.var, node, 8);
+	sbusfb_fill_var(&info->var, node, 8);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
-	all->par.sdev = sdev;
+	par->sdev = sdev;
 	if (sdev) {
 		rphys = sdev->reg_addrs[0].phys_addr;
-		all->par.physbase = phys = sdev->reg_addrs[1].phys_addr;
-		all->par.iospace = sdev->reg_addrs[0].which_io;
+		par->physbase = phys = sdev->reg_addrs[1].phys_addr;
+		par->iospace = sdev->reg_addrs[0].which_io;
 
-		all->par.regs = (struct cg14_regs *)
+		par->regs = (struct cg14_regs *)
 			sbus_ioremap(&sdev->resource[0], 0,
 				     sizeof(struct cg14_regs),
 				     "cg14 regs");
-		all->par.clut = (struct cg14_clut *)
+		par->clut = (struct cg14_clut *)
 			sbus_ioremap(&sdev->resource[0], CG14_CLUT1,
 				     sizeof(struct cg14_clut),
 				     "cg14 clut");
-		all->par.cursor = (struct cg14_cursor *)
+		par->cursor = (struct cg14_cursor *)
 			sbus_ioremap(&sdev->resource[0], CG14_CURSORREGS,
 				     sizeof(struct cg14_cursor),
 				     "cg14 cursor");
-		all->info.screen_base = (char *)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[1], 0,
-				     all->par.fbsize, "cg14 ram");
+				     par->fbsize, "cg14 ram");
 	} else {
 		rphys = __get_phys(bases[0]);
-		all->par.physbase = phys = __get_phys(bases[1]);
-		all->par.iospace = __get_iospace(bases[0]);
-		all->par.regs = (struct cg14_regs *)(unsigned long)bases[0];
-		all->par.clut = (struct cg14_clut *)((unsigned long)bases[0] +
+		par->physbase = phys = __get_phys(bases[1]);
+		par->iospace = __get_iospace(bases[0]);
+		par->regs = (struct cg14_regs *)(unsigned long)bases[0];
+		par->clut = (struct cg14_clut *)((unsigned long)bases[0] +
 						     CG14_CLUT1);
-		all->par.cursor =
+		par->cursor =
 			(struct cg14_cursor *)((unsigned long)bases[0] +
 					       CG14_CURSORREGS);
 
-		all->info.screen_base = (char *)(unsigned long)bases[1];
+		info->screen_base = (char *)(unsigned long)bases[1];
 	}
 
 	prom_getproperty(node, "reg", (char *) &bases[0], sizeof(bases));
 	is_8mb = (bases[5] == 0x800000);
 
-	if (sizeof(all->par.mmap_map) != sizeof(__cg14_mmap_map)) {
+	if (sizeof(par->mmap_map) != sizeof(__cg14_mmap_map)) {
 		extern void __cg14_mmap_sized_wrongly(void);
 
 		__cg14_mmap_sized_wrongly();
 	}
 		
-	memcpy(&all->par.mmap_map, &__cg14_mmap_map, sizeof(all->par.mmap_map));
+	memcpy(&par->mmap_map, &__cg14_mmap_map, sizeof(par->mmap_map));
 	for (i = 0; i < CG14_MMAP_ENTRIES; i++) {
-		struct sbus_mmap_map *map = &all->par.mmap_map[i];
+		struct sbus_mmap_map *map = &par->mmap_map[i];
 
 		if (!map->size)
 			break;
@@ -488,35 +486,33 @@
 			map->size *= 2;
 	}
 
-	all->par.mode = MDI_8_PIX;
-	all->par.ramsize = (is_8mb ? 0x800000 : 0x400000);
+	par->mode = MDI_8_PIX;
+	par->ramsize = (is_8mb ? 0x800000 : 0x400000);
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &cg14_ops;
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &cg14_ops;
 
-	__cg14_reset(&all->par);
+	__cg14_reset(par);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "cg14: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	cg14_init_fix(&all->info, linebytes);
+	cg14_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "cg14: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &cg14_list);
+	list_add(&par->list, &cg14_list);
 
 	printk("cg14: cgfourteen at %lx:%lx\n",
-	       all->par.physbase, all->par.iospace);
+	       par->physbase, par->iospace);
 
 }
 
@@ -552,11 +548,13 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &cg14_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct cg14_par *par = list_entry(pos, typeof(*par), list);
+
+		unregister_framebuffer(par->info);
+
+		fb_dealloc_cmap(&par->info->cmap);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cg3.c fbdev-2.6/drivers/video/cg3.c
--- linus-2.6/drivers/video/cg3.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/cg3.c	Thu Oct 16 14:13:30 2003
@@ -122,6 +122,7 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -354,80 +355,75 @@
 	}
 }
 
-struct all_info {
-	struct fb_info info;
-	struct cg3_par par;
-	struct list_head list;
-};
 static LIST_HEAD(cg3_list);
 
 static void cg3_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct cg3_par *par;
 	int linebytes;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct cg3_par), NULL);
+	if (!info) {
 		printk(KERN_ERR "cg3: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
-	all->par.physbase = sdev->reg_addrs[0].phys_addr;
+	par->physbase = sdev->reg_addrs[0].phys_addr;
 
-	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	sbusfb_fill_var(&info->var, sdev->prom_node, 8);
 	if (!strcmp(sdev->prom_name, "cgRDI"))
-		all->par.flags |= CG3_FLAG_RDI;
-	if (all->par.flags & CG3_FLAG_RDI)
-		cg3_rdi_maybe_fixup_var(&all->info.var, sdev);
+		par->flags |= CG3_FLAG_RDI;
+	if (par->flags & CG3_FLAG_RDI)
+		cg3_rdi_maybe_fixup_var(&info->var, sdev);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
-	all->par.regs = (struct cg3_regs *)
+	par->regs = (struct cg3_regs *)
 		sbus_ioremap(&sdev->resource[0], CG3_REGS_OFFSET,
 			     sizeof(struct cg3_regs), "cg3 regs");
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &cg3_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &cg3_ops;
 #ifdef CONFIG_SPARC32
-	all->info.screen_base = (char *)
+	info->screen_base = (char *)
 		prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
+	if (!info->screen_base)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[0], CG3_RAM_OFFSET,
-				     all->par.fbsize, "cg3 ram");
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+				     par->fbsize, "cg3 ram");
 
-	cg3_blank(0, &all->info);
+	cg3_blank(0, info);
 
 	if (!prom_getbool(sdev->prom_node, "width"))
-		cg3_do_default_mode(&all->par);
+		cg3_do_default_mode(par);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "cg3: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	cg3_init_fix(&all->info, linebytes);
+	cg3_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "cg3: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &cg3_list);
+	list_add(&par->list, &cg3_list);
 
 	printk("cg3: %s at %lx:%lx\n",
 	       sdev->prom_name,
@@ -454,11 +450,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &cg3_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct cg3_par *par = list_entry(pos, typeof(*par), list);
+
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cg6.c fbdev-2.6/drivers/video/cg6.c
--- linus-2.6/drivers/video/cg6.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/cg6.c	Thu Oct 16 14:13:30 2003
@@ -263,6 +263,7 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -630,94 +631,89 @@
 	sbus_writel(tmp, &par->bt->control);
 }
 
-struct all_info {
-	struct fb_info info;
-	struct cg6_par par;
-	struct list_head list;
-};
 static LIST_HEAD(cg6_list);
 
 static void cg6_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct cg6_par *par;
 	int linebytes;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct cg6_par), NULL);
+	if (!info) {
 		printk(KERN_ERR "cg6: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
-	all->par.physbase = sdev->reg_addrs[0].phys_addr;
+	par->physbase = sdev->reg_addrs[0].phys_addr;
 
-	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	sbusfb_fill_var(&info->var, sdev->prom_node, 8);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 	if (prom_getbool(sdev->prom_node, "dblbuf"))
-		all->par.fbsize *= 4;
+		par->fbsize *= 4;
 
-	all->par.fbc = (struct cg6_fbc *)
+	par->fbc = (struct cg6_fbc *)
 		sbus_ioremap(&sdev->resource[0], CG6_FBC_OFFSET,
 			     4096, "cgsix fbc");
-	all->par.tec = (struct cg6_tec *)
+	par->tec = (struct cg6_tec *)
 		sbus_ioremap(&sdev->resource[0], CG6_TEC_OFFSET,
 			     sizeof(struct cg6_tec), "cgsix tec");
-	all->par.thc = (struct cg6_thc *)
+	par->thc = (struct cg6_thc *)
 		sbus_ioremap(&sdev->resource[0], CG6_THC_OFFSET,
 			     sizeof(struct cg6_thc), "cgsix thc");
-	all->par.bt = (struct bt_regs *)
+	par->bt = (struct bt_regs *)
 		sbus_ioremap(&sdev->resource[0], CG6_BROOKTREE_OFFSET,
 			     sizeof(struct bt_regs), "cgsix dac");
-	all->par.fhc = (u32 *)
+	par->fhc = (u32 *)
 		sbus_ioremap(&sdev->resource[0], CG6_FHC_OFFSET,
 			     sizeof(u32), "cgsix fhc");
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &cg6_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &cg6_ops;
 #ifdef CONFIG_SPARC32
-	all->info.screen_base = (char *)
+	info->screen_base = (char *)
 		prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
+	if (!info->screen_base)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[0], CG6_RAM_OFFSET,
-				     all->par.fbsize, "cgsix ram");
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+				     par->fbsize, "cgsix ram");
 
-	all->info.var.accel_flags = FB_ACCELF_TEXT;
+	info->var.accel_flags = FB_ACCELF_TEXT;
 
-	cg6_bt_init(&all->par);
-	cg6_chip_init(&all->info);
-	cg6_blank(0, &all->info);
+	cg6_bt_init(par);
+	cg6_chip_init(info);
+	cg6_blank(0, info);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "cg6: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	cg6_init_fix(&all->info, linebytes);
+	cg6_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "cg6: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &cg6_list);
+	list_add(&par->list, &cg6_list);
 
 	printk("cg6: CGsix [%s] at %lx:%lx\n",
-	       all->info.fix.id,
+	       info->fix.id,
 	       (long) sdev->reg_addrs[0].which_io,
 	       (long) sdev->reg_addrs[0].phys_addr);
 }
@@ -741,11 +737,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &cg6_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct cg6_par *par = list_entry(pos, typeof(*par), list);
+
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/chipsfb.c fbdev-2.6/drivers/video/chipsfb.c
--- linus-2.6/drivers/video/chipsfb.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/chipsfb.c	Thu Oct 16 14:13:30 2003
@@ -85,7 +85,7 @@
 /*
  * Exported functions
  */
-int chips_init(void);
+int chipsfb_init(void);
 
 static int chipsfb_pci_init(struct pci_dev *dp, const struct pci_device_id *);
 static int chipsfb_check_var(struct fb_var_screeninfo *var,
@@ -460,7 +460,7 @@
 	.remove =	__devexit_p(chipsfb_remove),
 };
 
-int __init chips_init(void)
+int __init chipsfb_init(void)
 {
 	return pci_module_init(&chipsfb_driver);
 }
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cirrusfb.c fbdev-2.6/drivers/video/cirrusfb.c
--- linus-2.6/drivers/video/cirrusfb.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/cirrusfb.c	Thu Oct 16 14:13:30 2003
@@ -2787,6 +2787,7 @@
 	fb_info->gen.info.switch_con = &fbgen_switch;
 	fb_info->gen.info.updatevar = &fbgen_update_var;
 	fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
+	fb_info->gen.info.dev = fb_info->pdev;
 
 	for (j = 0; j < 256; j++) {
 		if (j < 16) {
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/clients.c fbdev-2.6/drivers/video/clients.c
--- linus-2.6/drivers/video/clients.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/clients.c	Wed Oct 15 19:43:29 2003
@@ -0,0 +1,96 @@
+static DECLARE_MUTEX(fb_clients_lock);
+static LIST_HEAD(fb_clients);
+
+/*
+ * Graphics Client management
+ */
+int register_fb_client(struct fb_client_ops *ops, void *data)
+{
+	fb_client *client;
+
+	client = kmalloc(sizeof(*client), GFP_KERNEL);
+	if (!client)
+		return -ENOMEM;
+	memset(client, 0, sizeof(*client));
+	client->ops = ops;
+	client->data = data;
+
+	down(&fb_clients_lock);
+	list_add(&client->link, &fb_clients);
+	up(&fb_clients_lock);
+
+	return 0;
+}
+
+int unregister_fb_client(struct fb_client_ops *ops)
+{
+	struct fb_client *client = NULL;
+	struct list_head *pos;
+
+	down(&fb_clients_lock);
+	list_for_each(pos, &fb_clients) {
+		client = list_entry(pos, struct fb_client, link);
+		if (client->ops == ops) {
+			list_del(&client->link);
+			kfree(client);
+			break;
+		}
+	}
+	up(&fb_clients_lock);
+	return 0;
+}
+
+int fb_client_set_state(struct fb_info *info, u32 state)
+{
+	struct fb_client *client = NULL;
+	struct list_head *pos;
+
+	down(&fb_clients_lock);
+	list_for_each(pos, &fb_clients) {
+		client = list_entry(pos, struct fb_client, link);
+		if (try_module_get(client->ops->owner)) {
+			if (client->ops->state_manager)
+				client->ops->state_manager(client->data, info, state);
+			module_put(client->ops->owner);
+		}
+	}
+	up(&fb_clients_lock);
+	return 0;
+}
+
+static int fbdev_dummy(void)
+{
+	return 0;
+}
+
+#define FBDEV_EMPTY (void *)fbdev_dummy
+
+const struct fb_ops dummy_fbdev = {
+	.fb_open	= FBDEV_EMPTY,
+	.fb_release	= FBDEV_EMPTY,
+	.fb_read	= FBDEV_EMPTY,
+	.fb_write	= FBDEV_EMPTY,
+	.fb_check_var	= FBDEV_EMPTY,
+	.fb_set_par	= FBDEV_EMPTY,
+	.fb_setcolreg	= FBDEV_EMPTY,
+	.fb_blank	= FBDEV_EMPTY,
+	.fb_pan_display	= FBDEV_EMPTY,
+	.fb_fillrect	= FBDEV_EMPTY,
+	.fb_copyarea	= FBDEV_EMPTY,
+	.fb_imageblit	= FBDEV_EMPTY,
+	.fb_cursor	= FBDEV_EMPTY,
+	.fb_rotate	= FBDEV_EMPTY,
+	.fb_sync	= FBDEV_EMPTY,
+	.fb_ioctl	= FBDEV_EMPTY,
+	.fb_mmap	= FBDEV_EMPTY,
+};
+
+     /*
+      *  Visible symbols for modules
+      */
+EXPORT_SYMBOL(unregister_fb_client);
+EXPORT_SYMBOL(register_fb_client);
+EXPORT_SYMBOL(fb_client_set_state);
+EXPORT_SYMBOL(dummy_fbdev);
+
+MODULE_LICENSE("GPL");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/Makefile fbdev-2.6/drivers/video/console/Makefile
--- linus-2.6/drivers/video/console/Makefile	Thu Oct 16 14:13:35 2003
+++ fbdev-2.6/drivers/video/console/Makefile	Thu Oct 16 14:13:35 2003
@@ -3,18 +3,16 @@
 # Rewritten to use lists instead of if-statements.
 
 # Font handling
-font-objs := fonts.o
+font-y := fonts.o
 
-font-objs-$(CONFIG_FONT_SUN8x16)   += font_sun8x16.o
-font-objs-$(CONFIG_FONT_SUN12x22)  += font_sun12x22.o
-font-objs-$(CONFIG_FONT_8x8)       += font_8x8.o
-font-objs-$(CONFIG_FONT_8x16)      += font_8x16.o
-font-objs-$(CONFIG_FONT_6x11)      += font_6x11.o
-font-objs-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
-font-objs-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
-font-objs-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
-
-font-objs += $(font-objs-y)
+font-$(CONFIG_FONT_SUN8x16)   += font_sun8x16.o
+font-$(CONFIG_FONT_SUN12x22)  += font_sun12x22.o
+font-$(CONFIG_FONT_8x8)       += font_8x8.o
+font-$(CONFIG_FONT_8x16)      += font_8x16.o
+font-$(CONFIG_FONT_6x11)      += font_6x11.o
+font-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
+font-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
+font-$(CONFIG_FONT_MINI_4x6)  += font_mini_4x6.o
 
 # Each configuration option enables a list of files.
 
@@ -30,9 +28,12 @@
 
 # Files generated that shall be removed upon make clean
 clean-files := promcon_tbl.c
-
-$(obj)/promcon_tbl.c: $(src)/prom.uni
-	$(objtree)/scripts/conmakehash $< | \
+
+quiet_cmd_promtbl = GEN	$@
+	cmd_promtbl = scripts/conmakehash $< | \
 	sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
 	    -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > $@
+
+$(obj)/promcon_tbl.c: $(src)/prom.uni
+	$(call cmd,promtbl)
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.c fbdev-2.6/drivers/video/console/fbcon.c
--- linus-2.6/drivers/video/console/fbcon.c	Thu Oct 16 14:13:35 2003
+++ fbdev-2.6/drivers/video/console/fbcon.c	Thu Oct 16 14:13:35 2003
@@ -195,8 +195,7 @@
 {
 	struct fb_info *info = (struct fb_info *) private;
 
-	/* Test to see if the cursor is erased but still on */
-	if (!info || (info->cursor.rop == ROP_COPY))
+	if (!info)
 		return;
 	info->cursor.enable ^= 1;
 	info->fbops->fb_cursor(info, &info->cursor);
@@ -226,8 +225,7 @@
 	struct fb_info *info = (struct fb_info *) dev_addr;
 	
 	schedule_work(&info->queue);	
-	cursor_timer.expires = jiffies + HZ / 5;
-	add_timer(&cursor_timer);
+	mod_timer(&cursor_timer, jiffies + HZ/5);
 }
 
 int __init fb_console_setup(char *this_opt)
@@ -308,97 +306,6 @@
 }
 
 /*
- * drawing helpers
- */
-static void putcs_unaligned(struct vc_data *vc, struct fb_info *info,
-			    struct fb_image *image, int count,
-			    const unsigned short *s)
-{
-	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-	unsigned int width = (vc->vc_font.width + 7) >> 3;
-	unsigned int cellsize = vc->vc_font.height * width;
-	unsigned int maxcnt = info->pixmap.size/cellsize;
-	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
-	unsigned int shift_high = 8, size, pitch, cnt, k;
-	unsigned int buf_align = info->pixmap.buf_align - 1;
-	unsigned int scan_align = info->pixmap.scan_align - 1;
-	unsigned int idx = vc->vc_font.width >> 3;
-	u8 mask, *src, *dst, *dst0;
-
-	while (count) {
-		if (count > maxcnt)
-			cnt = k = maxcnt;
-		else
-			cnt = k = count;
-
-		image->width = vc->vc_font.width * cnt;
-		pitch = ((image->width + 7) >> 3) + scan_align;
-		pitch &= ~scan_align;
-		size = pitch * vc->vc_font.height + buf_align;
-		size &= ~buf_align;
-		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
-		image->data = dst0;
-		while (k--) {
-			src = vc->vc_font.data + (scr_readw(s++) & charmask)*
-			cellsize;
-			dst = dst0;
-			mask = (u8) (0xfff << shift_high);
-			move_buf_unaligned(info, dst, src, pitch, image->height,
-					mask, shift_high, shift_low, mod, idx);
-			shift_low += mod;
-			dst0 += (shift_low >= 8) ? width : width - 1;
-			shift_low &= 7;
-			shift_high = 8 - shift_low;
-		}
-		info->fbops->fb_imageblit(info, image);
-		image->dx += cnt * vc->vc_font.width;
-		count -= cnt;
-		atomic_dec(&info->pixmap.count);
-		smp_mb__after_atomic_dec();
-	}
-}
-
-static void putcs_aligned(struct vc_data *vc, struct fb_info *info,
-			  struct fb_image *image, int count,
-			  const unsigned short *s)
-{
-	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-	unsigned int width = vc->vc_font.width >> 3;
-	unsigned int cellsize = vc->vc_font.height * width;
-	unsigned int maxcnt = info->pixmap.size/cellsize;
-	unsigned int scan_align = info->pixmap.scan_align - 1;
-	unsigned int buf_align = info->pixmap.buf_align - 1;
-	unsigned int pitch, cnt, size, k;
-	u8 *src, *dst, *dst0;
-
-	while (count) {
-		if (count > maxcnt)
-			cnt = k = maxcnt;
-		else
-			cnt = k = count;
-		
-		pitch = width * cnt + scan_align;
-		pitch &= ~scan_align;
-		size = pitch * vc->vc_font.height + buf_align;
-		size &= ~buf_align;
-		image->width = vc->vc_font.width * cnt;
-		dst0 = info->pixmap.addr + fb_get_buffer_offset(info, size);
-		image->data = dst0;
-		while (k--) {
-			src = vc->vc_font.data + (scr_readw(s++)&charmask)*cellsize;
-			dst = dst0;
-			move_buf_aligned(info, dst, src, pitch, width, image->height);
-			dst0 += width;
-		}
-		info->fbops->fb_imageblit(info, image);
-		image->dx += cnt * vc->vc_font.width;
-		count -= cnt;
-		atomic_dec(&info->pixmap.count);
-		smp_mb__after_atomic_dec();
-	}
-}
-
-/*
  * Accelerated handlers.
  */
 void accel_bmove(struct vc_data *vc, struct fb_info *info, int sy, 
@@ -432,51 +339,24 @@
 	info->fbops->fb_fillrect(info, &region);
 }	
 
-static void accel_putc(struct vc_data *vc, struct fb_info *info,
-                      int c, int ypos, int xpos)
+void accel_putcs(struct vc_data *vc, struct fb_info *info,
+			const unsigned short *s, int count, int yy, int xx)
 {
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	unsigned int width = (vc->vc_font.width + 7) >> 3;
+	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int maxcnt = info->pixmap.size/cellsize;
 	unsigned int scan_align = info->pixmap.scan_align - 1;
 	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
+	unsigned int shift_high = 8, pitch, cnt, size, k;
 	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
 	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
-	unsigned int size, pitch;
-	struct fb_image image;
-	u8 *src, *dst;
-
-	image.dx = xpos * vc->vc_font.width;
-	image.dy = ypos * vc->vc_font.height;
-	image.width = vc->vc_font.width;
-	image.height = vc->vc_font.height;
-	image.fg_color = attr_fgcol(fgshift, c);
-	image.bg_color = attr_bgcol(bgshift, c);
-	image.depth = 1;
-
-	pitch = width + scan_align;
-	pitch &= ~scan_align;
-	size = pitch * vc->vc_font.height;
-	size += buf_align;
-	size &= ~buf_align;
-	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
-	image.data = dst;
-	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
-
-	move_buf_aligned(info, dst, src, pitch, width, image.height);
-
-	info->fbops->fb_imageblit(info, &image);
-	atomic_dec(&info->pixmap.count);
-	smp_mb__after_atomic_dec();
-}
-
-void accel_putcs(struct vc_data *vc, struct fb_info *info,
-			const unsigned short *s, int count, int yy, int xx)
-{
-	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+	unsigned int idx = vc->vc_font.width >> 3;
 	struct fb_image image;
 	u16 c = scr_readw(s);
-
+	u8 *src, *dst, *dst0;
+
 	image.fg_color = attr_fgcol(fgshift, c);
 	image.bg_color = attr_bgcol(bgshift, c);
 	image.dx = xx * vc->vc_font.width;
@@ -484,10 +364,43 @@
 	image.height = vc->vc_font.height;
 	image.depth = 1;
 
-	if (!(vc->vc_font.width & 7))
-               putcs_aligned(vc, info, &image, count, s);
-        else
-               putcs_unaligned(vc, info, &image, count, s);
+	while (count) {
+		if (count > maxcnt)
+			cnt = k = maxcnt;
+		else
+			cnt = k = count;
+
+		image.width = vc->vc_font.width * cnt;
+		pitch = ((image.width + 7) >> 3) + scan_align;
+		pitch &= ~scan_align;
+		size = pitch * image.height + buf_align;
+		size &= ~buf_align;
+		dst0 = fb_get_buffer_offset(info, &info->pixmap, size);
+		image.data = dst0;
+		while (k--) {
+			src = vc->vc_font.data + (scr_readw(s++) & charmask)*cellsize;
+			dst = dst0;
+
+			if (mod) {
+				move_buf_unaligned(info, &info->pixmap, dst, pitch,
+						   src, idx, image.height, shift_high,
+						   shift_low, mod);
+				shift_low += mod;
+				dst0 += (shift_low >= 8) ? width : width - 1;
+				shift_low &= 7;
+				shift_high = 8 - shift_low;
+			} else {
+				move_buf_aligned(info, &info->pixmap, dst, pitch,
+						 src, idx, image.height);
+				dst0 += width;
+			}
+		}
+		info->fbops->fb_imageblit(info, &image);
+		image.dx += cnt * vc->vc_font.width;
+		count -= cnt;
+		atomic_dec(&info->pixmap.count);
+		smp_mb__after_atomic_dec();
+	}
 }
 
 void accel_clear_margins(struct vc_data *vc, struct fb_info *info,
@@ -672,11 +585,11 @@
 #endif
 	/* Initialize the work queue. If the driver provides its
 	 * own work queue this means it will use something besides 
-	 * default timer to flash the cursor. */
+	 * default timer to flash the cursor. */
 	if (!info->queue.func) {
 		INIT_WORK(&info->queue, fb_flashcursor, info);
 		
-		cursor_timer.expires = jiffies + HZ / 50;
+		cursor_timer.expires = jiffies + HZ / 5;
 		cursor_timer.data = (unsigned long ) info;
 		add_timer(&cursor_timer);
 	}
@@ -728,15 +641,13 @@
 static void fbcon_set_display(struct vc_data *vc, int init, int logo)
 {
 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	int nr_rows, nr_cols, old_rows, old_cols, i, charcnt = 256;
 	struct display *p = &fb_display[vc->vc_num];
-	int nr_rows, nr_cols;
-	int old_rows, old_cols;
 	unsigned short *save = NULL, *r, *q;
-	int i, charcnt = 256;
 	struct font_desc *font;
 
 	if (vc->vc_num != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
-	    info->fix.type == FB_TYPE_TEXT)
+	    (info->fix.type == FB_TYPE_TEXT))
 		logo = 0;
 
 	info->var.xoffset = info->var.yoffset = p->yscroll = 0;	/* reset wrap/pan */
@@ -960,19 +871,50 @@
 		accel_clear(vc, info, real_y(p, sy), sx, height, width);
 }
 
-
 static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
 {
 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
+	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+	unsigned int scan_align = info->pixmap.scan_align - 1;
+	unsigned int buf_align = info->pixmap.buf_align - 1;
+	unsigned int width = (vc->vc_font.width + 7) >> 3;
+	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
 	struct display *p = &fb_display[vc->vc_num];
-
+	unsigned int size, pitch;
+	struct fb_image image;
+	u8 *src, *dst;
+
 	if (!info->fbops->fb_blank && console_blanked)
 		return;
 
 	if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT)
 		return;
 
-	accel_putc(vc, info, c, real_y(p, ypos), xpos);
+	image.dx = xpos * vc->vc_font.width;
+	image.dy = real_y(p, ypos) * vc->vc_font.height;
+	image.width = vc->vc_font.width;
+	image.height = vc->vc_font.height;
+	image.fg_color = attr_fgcol(fgshift, c);
+	image.bg_color = attr_bgcol(bgshift, c);
+	image.depth = 1;
+
+	src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * width;
+
+	pitch = width + scan_align;
+	pitch &= ~scan_align;
+	size = pitch * vc->vc_font.height;
+	size += buf_align;
+	size &= ~buf_align;
+
+	dst = fb_get_buffer_offset(info, &info->pixmap, size);
+	image.data = dst;
+
+	move_buf_aligned(info, &info->pixmap, dst, pitch, src, width, image.height);
+
+	info->fbops->fb_imageblit(info, &image);
+	atomic_dec(&info->pixmap.count);
+	smp_mb__after_atomic_dec();
 }
 
 static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
@@ -993,13 +935,8 @@
 static void fbcon_cursor(struct vc_data *vc, int mode)
 {
 	struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
-	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
-	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
-	int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
 	struct display *p = &fb_display[vc->vc_num];
-	int w = (vc->vc_font.width + 7) >> 3, c;
 	int y = real_y(p, vc->vc_y);
-	struct fb_cursor cursor;
 	
 	if (mode & CM_SOFTBACK) {
 		mode &= ~CM_SOFTBACK;
@@ -1012,28 +949,32 @@
 	} else if (softback_lines)
 		fbcon_set_origin(vc);
 
- 	c = scr_readw((u16 *) vc->vc_pos);
+	del_timer(&cursor_timer);
+	if (info->cursor.enable) {
+		info->cursor.enable = 0;
+		info->fbops->fb_cursor(info, &info->cursor);
+	}
 
-	cursor.image.data = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
-	cursor.set = FB_CUR_SETCUR;
-	cursor.image.depth = 1;
-	
-	switch (mode) {
-	case CM_ERASE:
-		if (info->cursor.rop == ROP_XOR) {
-			info->cursor.enable = 0;
-			info->cursor.rop = ROP_COPY;
-			info->fbops->fb_cursor(info, &cursor);
-		}	
-		break;
-	case CM_MOVE:
-	case CM_DRAW:
-		info->cursor.enable = 1;
+	if (mode != CM_ERASE) {
+		unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+		int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+		int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+		int s_pitch = (vc->vc_font.width + 7) >> 3;
+		int size = s_pitch * vc->vc_font.height;
+		struct fb_cursor cursor;
+		int cur_height, c;
+		u8 *dst;
 		
-		if (info->cursor.image.fg_color != attr_fgcol(fgshift, c) ||
-	    	    info->cursor.image.bg_color != attr_bgcol(bgshift, c)) {
-			cursor.image.fg_color = attr_fgcol(fgshift, c);
-			cursor.image.bg_color = attr_bgcol(bgshift, c);
+		memset(&cursor, 0, sizeof(struct fb_cursor));
+		cursor.enable = 1;
+
+ 		c = scr_readw((u16 *) vc->vc_pos);
+
+		if (info->cursor.image.bg_color != attr_fgcol(fgshift, c) ||
+	    	    info->cursor.image.fg_color != attr_bgcol(bgshift, c)) {
+			cursor.image.bg_color = attr_fgcol(fgshift, c);
+			cursor.image.fg_color = attr_bgcol(bgshift, c);
+			cursor.image.depth = 1;
 			cursor.set |= FB_CUR_SETCMAP;
 		}
 		
@@ -1055,22 +996,20 @@
 			cursor.hot.x = cursor.hot.y = 0;
 			cursor.set |= FB_CUR_SETHOT;
 		}
+
+		if ((cursor.set & FB_CUR_SETSIZE)) {
+			dst = kmalloc(size, GFP_ATOMIC);
 
-		if ((cursor.set & FB_CUR_SETSIZE) || ((vc->vc_cursor_type & 0x0f) != p->cursor_shape)) {
-			char *mask = kmalloc(w*vc->vc_font.height, GFP_ATOMIC);
-			int cur_height, size, i = 0;
+			if (!dst)
+				return;
+			memset(dst, 0, size);
 
-			if (!mask)	return;	
-		
 			if (info->cursor.mask)
 				kfree(info->cursor.mask);
-			info->cursor.mask = mask;
-	
-			p->cursor_shape = vc->vc_cursor_type & 0x0f;
-			cursor.set |= FB_CUR_SETSHAPE;
-
+			info->cursor.mask = dst;
+
 			switch (vc->vc_cursor_type & 0x0f) {
-			case CUR_NONE:
+			case CUR_NONE:
 				cur_height = 0;
 				break;
 			case CUR_UNDERLINE:
@@ -1085,22 +1024,23 @@
 			case CUR_TWO_THIRDS:
 				cur_height = (vc->vc_font.height << 1)/3;
 				break;
-			case CUR_BLOCK:
+			case CUR_BLOCK:
 			default:
 				cur_height = vc->vc_font.height;
 				break;
 			}
-			size = (vc->vc_font.height - cur_height) * w;
-			while (size--)
-				mask[i++] = 0;
-			size = cur_height * w;
-			while (size--)
-				mask[i++] = 0xff;
+			dst += (vc->vc_font.height - cur_height) * s_pitch;
+			memset(dst, 0xff, cur_height * s_pitch);
 		}
-        	info->cursor.rop = ROP_XOR;
+
+		info->cursor.image.data = vc->vc_font.data + ((c & charmask) * size);
+		cursor.set |= FB_CUR_SETSHAPE;
 		info->fbops->fb_cursor(info, &cursor);
+		info->cursor.enable = 1;
+		atomic_dec(&info->sprite.count);
+		smp_mb__after_atomic_dec();
+		mod_timer(&cursor_timer, jiffies + HZ/5);
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
-		break;
 	}
 }
 
@@ -1826,9 +1766,11 @@
 	vc->vc_font.height = h;
 	if (vc->vc_hi_font_mask && cnt == 256) {
 		vc->vc_hi_font_mask = 0;
-		if (vc->vc_can_do_color)
+		if (vc->vc_can_do_color) {
 			vc->vc_complement_mask >>= 1;
-
+			vc->vc_s_complement_mask >>= 1;
+		}
+
 		/* ++Edmund: reorder the attribute bits */
 		if (vc->vc_can_do_color) {
 			unsigned short *cp =
@@ -1847,9 +1789,11 @@
 		}
 	} else if (!vc->vc_hi_font_mask && cnt == 512) {
 		vc->vc_hi_font_mask = 0x100;
-		if (vc->vc_can_do_color)
+		if (vc->vc_can_do_color) {
 			vc->vc_complement_mask <<= 1;
-
+			vc->vc_s_complement_mask <<= 1;
+		}
+
 		/* ++Edmund: reorder the attribute bits */
 		{
 			unsigned short *cp =
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/console/fbcon.h fbdev-2.6/drivers/video/console/fbcon.h
--- linus-2.6/drivers/video/console/fbcon.h	Thu Oct 16 14:13:35 2003
+++ fbdev-2.6/drivers/video/console/fbcon.h	Thu Oct 16 14:13:35 2003
@@ -33,7 +33,6 @@
     u_short scrollmode;             /* Scroll Method */
     short yscroll;                  /* Hardware scrolling */
     int vrows;                      /* number of virtual rows */
-    int cursor_shape;
 };
 
 /* drivers/video/console/fbcon.c */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/controlfb.c fbdev-2.6/drivers/video/controlfb.c
--- linus-2.6/drivers/video/controlfb.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/controlfb.c	Thu Oct 16 14:13:30 2003
@@ -136,8 +136,8 @@
 /*
  * inititialization
  */
-int control_init(void);
-void control_setup(char *);
+int controlfb_init(void);
+void controlfb_setup(char *);
 
 /******************** Prototypes for internal functions **********************/
 
@@ -553,7 +553,7 @@
 /*
  * Called from fbmem.c for probing & initializing
  */
-int __init control_init(void)
+int __init controlfb_init(void)
 {
 	struct device_node *dp;
 
@@ -1057,7 +1057,7 @@
 /*
  * Parse user speficied options (`video=controlfb:')
  */
-void __init control_setup(char *options)
+void __init controlfb_setup(char *options)
 {
 	char *this_opt;
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cyber2000fb.c fbdev-2.6/drivers/video/cyber2000fb.c
--- linus-2.6/drivers/video/cyber2000fb.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/cyber2000fb.c	Thu Oct 16 14:13:30 2003
@@ -62,7 +62,7 @@
 #include "cyber2000fb.h"
 
 struct cfb_info {
-	struct fb_info		fb;
+	struct fb_info		*fb;
 	struct display_switch	*dispsw;
 	struct display		*display;
 	struct pci_dev		*dev;
@@ -148,10 +148,10 @@
 static void
 cyber2000fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 	unsigned long dst, col;
 
-	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
+	if (!(info->var.accel_flags & FB_ACCELF_TEXT)) {
 		cfb_fillrect(info, rect);
 		return;
 	}
@@ -161,12 +161,12 @@
 	cyber2000fb_writew(rect->height - 1, CO_REG_PIXHEIGHT, cfb);
 
 	col = rect->color;
-	if (cfb->fb.var.bits_per_pixel > 8)
-		col = ((u32 *)cfb->fb.pseudo_palette)[col];
+	if (info->var.bits_per_pixel > 8)
+		col = ((u32 *)info->pseudo_palette)[col];
 	cyber2000fb_writel(col, CO_REG_FGCOLOUR, cfb);
 
-	dst = rect->dx + rect->dy * cfb->fb.var.xres_virtual;
-	if (cfb->fb.var.bits_per_pixel == 24) {
+	dst = rect->dx + rect->dy * info->var.xres_virtual;
+	if (info->var.bits_per_pixel == 24) {
 		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 		dst *= 3;
 	}
@@ -180,11 +180,11 @@
 static void
 cyber2000fb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 	unsigned int cmd = CO_CMD_L_PATTERN_FGCOL;
 	unsigned long src, dst;
 
-	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT)) {
+	if (!(info->var.accel_flags & FB_ACCELF_TEXT)) {
 		cfb_copyarea(info, region);
 		return;
 	}
@@ -193,8 +193,8 @@
 	cyber2000fb_writew(region->width - 1, CO_REG_PIXWIDTH, cfb);
 	cyber2000fb_writew(region->height - 1, CO_REG_PIXHEIGHT, cfb);
 
-	src = region->sx + region->sy * cfb->fb.var.xres_virtual;
-	dst = region->dx + region->dy * cfb->fb.var.xres_virtual;
+	src = region->sx + region->sy * info->var.xres_virtual;
+	dst = region->dx + region->dy * info->var.xres_virtual;
 
 	if (region->sx < region->dx) {
 		src += region->width - 1;
@@ -203,12 +203,12 @@
 	}
 
 	if (region->sy < region->dy) {
-		src += (region->height - 1) * cfb->fb.var.xres_virtual;
-		dst += (region->height - 1) * cfb->fb.var.xres_virtual;
+		src += (region->height - 1) * info->var.xres_virtual;
+		dst += (region->height - 1) * info->var.xres_virtual;
 		cmd |= CO_CMD_L_INC_UP;
 	}
 
-	if (cfb->fb.var.bits_per_pixel == 24) {
+	if (info->var.bits_per_pixel == 24) {
 		cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
 		src *= 3;
 		dst *= 3;
@@ -234,10 +234,10 @@
 
 static int cyber2000fb_sync(struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 	int count = 100000;
 
-	if (!(cfb->fb.var.accel_flags & FB_ACCELF_TEXT))
+	if (!(info->var.accel_flags & FB_ACCELF_TEXT))
 		return 0;
 
 	while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
@@ -269,12 +269,12 @@
 cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
 		      u_int transp, struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
-	struct fb_var_screeninfo *var = &cfb->fb.var;
+	struct cfb_info *cfb = info->par;
+	struct fb_var_screeninfo *var = &info->var;
 	u32 pseudo_val;
 	int ret = 1;
 
-	switch (cfb->fb.fix.visual) {
+	switch (info->fix.visual) {
 	default:
 		return 1;
 
@@ -400,7 +400,7 @@
 	 * Now set our pseudo palette for the CFB16/24/32 drivers.
 	 */
 	if (regno < 16)
-		((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
+		((u32 *)info->pseudo_palette)[regno] = pseudo_val;
 
 	return ret;
 }
@@ -744,7 +744,7 @@
 static int
 cyber2000fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 	struct par_info hw;
 	unsigned int mem;
 	int err;
@@ -831,8 +831,8 @@
 	}
 
 	mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
-	if (mem > cfb->fb.fix.smem_len)
-		var->yres_virtual = cfb->fb.fix.smem_len * 8 /
+	if (mem > info->fix.smem_len)
+		var->yres_virtual = info->fix.smem_len * 8 /
 			(var->bits_per_pixel * var->xres_virtual);
 
 	if (var->yres > var->yres_virtual)
@@ -853,8 +853,8 @@
 
 static int cyber2000fb_set_par(struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
-	struct fb_var_screeninfo *var = &cfb->fb.var;
+	struct cfb_info *cfb = info->par;
+	struct fb_var_screeninfo *var = &info->var;
 	struct par_info hw;
 	unsigned int mem;
 
@@ -924,7 +924,7 @@
 		hw.fetch <<= 1;
 	hw.fetch += 1;
 
-	cfb->fb.fix.line_length	= var->xres_virtual * var->bits_per_pixel / 8;
+	info->fix.line_length	= var->xres_virtual * var->bits_per_pixel / 8;
 
 	/*
 	 * Same here - if the size of the video mode exceeds the
@@ -933,8 +933,8 @@
 	 * In theory, since NetWinders contain just one VGA card,
 	 * we should never end up hitting this problem.
 	 */
-	mem = cfb->fb.fix.line_length * var->yres_virtual;
-	BUG_ON(mem > cfb->fb.fix.smem_len);
+	mem = info->fix.line_length * var->yres_virtual;
+	BUG_ON(mem > info->fix.smem_len);
 
 	/*
 	 * 8bpp displays are always pseudo colour.  16bpp and above
@@ -943,11 +943,11 @@
 	 * palettes, true colour does not.)
 	 */
 	if (var->bits_per_pixel == 8)
-		cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
+		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
 	else if (hw.ramdac & RAMDAC_BYPASS)
-		cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
+		info->fix.visual = FB_VISUAL_TRUECOLOR;
 	else
-		cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
+		info->fix.visual = FB_VISUAL_DIRECTCOLOR;
 
 	cyber2000fb_set_timing(cfb, &hw);
 	cyber2000fb_update_start(cfb, var);
@@ -962,18 +962,18 @@
 static int
 cyber2000fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 
 	if (cyber2000fb_update_start(cfb, var))
 		return -EINVAL;
 
-	cfb->fb.var.xoffset = var->xoffset;
-	cfb->fb.var.yoffset = var->yoffset;
+	info->var.xoffset = var->xoffset;
+	info->var.yoffset = var->yoffset;
 
 	if (var->vmode & FB_VMODE_YWRAP) {
-		cfb->fb.var.vmode |= FB_VMODE_YWRAP;
+		info->var.vmode |= FB_VMODE_YWRAP;
 	} else {
-		cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
+		info->var.vmode &= ~FB_VMODE_YWRAP;
 	}
 
 	return 0;
@@ -998,7 +998,7 @@
  */
 static int cyber2000fb_blank(int blank, struct fb_info *info)
 {
-	struct cfb_info *cfb = (struct cfb_info *)info;
+	struct cfb_info *cfb = info->par;
 	unsigned int sync = 0;
 	int i;
 
@@ -1111,7 +1111,7 @@
 
 void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
 {
-	memcpy(var, &cfb->fb.var, sizeof(struct fb_var_screeninfo));
+	memcpy(var, &cfb->fb->var, sizeof(struct fb_var_screeninfo));
 }
 
 /*
@@ -1122,13 +1122,13 @@
 	if (int_cfb_info != NULL) {
 		info->dev	      = int_cfb_info->dev;
 		info->regs	      = int_cfb_info->regs;
-		info->fb	      = int_cfb_info->fb.screen_base;
-		info->fb_size	      = int_cfb_info->fb.fix.smem_len;
+		info->fb	      = int_cfb_info->fb->screen_base;
+		info->fb_size	      = int_cfb_info->fb->fix.smem_len;
 		info->enable_extregs  = cyber2000fb_enable_extregs;
 		info->disable_extregs = cyber2000fb_disable_extregs;
 		info->info            = int_cfb_info;
 
-		strlcpy(info->dev_name, int_cfb_info->fb.fix.id, sizeof(info->dev_name));
+		strlcpy(info->dev_name, int_cfb_info->fb->fix.id, sizeof(info->dev_name));
 	}
 
 	return int_cfb_info != NULL;
@@ -1220,18 +1220,18 @@
 }
 
 static struct cfb_info * __devinit
-cyberpro_alloc_fb_info(unsigned int id, char *name)
+cyberpro_alloc_fb_info(unsigned int id, char *name, struct device *dev)
 {
 	struct cfb_info *cfb;
+	struct fb_info *fb_info;
 
-	cfb = kmalloc(sizeof(struct cfb_info) +
-		       sizeof(u32) * 16, GFP_KERNEL);
+	fb_info = framebuffer_alloc(sizeof(struct cfb_info) + 32 * 16, dev);
 
-	if (!cfb)
+	if (!fb_info)
 		return NULL;
 
-	memset(cfb, 0, sizeof(struct cfb_info));
-
+	cfb			= fb_info->par;
+	cfb->fb			= fb_info;
 	cfb->id			= id;
 
 	if (id == ID_CYBERPRO_5000)
@@ -1248,43 +1248,43 @@
 	else
 		cfb->divisors[3] = 6;
 
-	strcpy(cfb->fb.fix.id, name);
+	strcpy(fb_info->fix.id, name);
 
-	cfb->fb.fix.type	= FB_TYPE_PACKED_PIXELS;
-	cfb->fb.fix.type_aux	= 0;
-	cfb->fb.fix.xpanstep	= 0;
-	cfb->fb.fix.ypanstep	= 1;
-	cfb->fb.fix.ywrapstep	= 0;
+	fb_info->fix.type	= FB_TYPE_PACKED_PIXELS;
+	fb_info->fix.type_aux	= 0;
+	fb_info->fix.xpanstep	= 0;
+	fb_info->fix.ypanstep	= 1;
+	fb_info->fix.ywrapstep	= 0;
 
 	switch (id) {
 	case ID_IGA_1682:
-		cfb->fb.fix.accel = 0;
+		fb_info->fix.accel = 0;
 		break;
 
 	case ID_CYBERPRO_2000:
-		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;
+		fb_info->fix.accel = FB_ACCEL_IGS_CYBER2000;
 		break;
 
 	case ID_CYBERPRO_2010:
-		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;
+		fb_info->fix.accel = FB_ACCEL_IGS_CYBER2010;
 		break;
 
 	case ID_CYBERPRO_5000:
-		cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;
+		fb_info->fix.accel = FB_ACCEL_IGS_CYBER5000;
 		break;
 	}
 
-	cfb->fb.var.nonstd	= 0;
-	cfb->fb.var.activate	= FB_ACTIVATE_NOW;
-	cfb->fb.var.height	= -1;
-	cfb->fb.var.width	= -1;
-	cfb->fb.var.accel_flags	= FB_ACCELF_TEXT;
-
-	cfb->fb.fbops		= &cyber2000fb_ops;
-	cfb->fb.flags		= FBINFO_FLAG_DEFAULT;
-	cfb->fb.pseudo_palette	= (void *)(cfb + 1);
+	fb_info->var.nonstd	= 0;
+	fb_info->var.activate	= FB_ACTIVATE_NOW;
+	fb_info->var.height	= -1;
+	fb_info->var.width	= -1;
+	fb_info->var.accel_flags	= FB_ACCELF_TEXT;
+
+	fb_info->fbops		= &cyber2000fb_ops;
+	fb_info->flags		= FBINFO_FLAG_DEFAULT;
+	fb_info->pseudo_palette	= (void *)(cfb + 1);
 
-	fb_alloc_cmap(&cfb->fb.cmap, NR_PALETTE, 0);
+	fb_alloc_cmap(&fb_info->cmap, NR_PALETTE, 0);
 
 	return cfb;
 }
@@ -1296,9 +1296,9 @@
 		/*
 		 * Free the colourmap
 		 */
-		fb_alloc_cmap(&cfb->fb.cmap, 0, 0);
+		fb_alloc_cmap(&cfb->fb->cmap, 0, 0);
 
-		kfree(cfb);
+		kfree(cfb->fb);
 	}
 }
 
@@ -1339,6 +1339,7 @@
  */
 static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
 {
+	struct fb_info *fb_info = cfb->fb;
 	u_long smem_size;
 	u_int h_sync, v_sync;
 	int err;
@@ -1363,22 +1364,22 @@
 	default:		smem_size = 0x00100000; break;
 	}
 
-	cfb->fb.fix.smem_len   = smem_size;
-	cfb->fb.fix.mmio_len   = MMIO_SIZE;
-	cfb->fb.screen_base    = cfb->region;
+	fb_info->fix.smem_len   = smem_size;
+	fb_info->fix.mmio_len   = MMIO_SIZE;
+	fb_info->screen_base    = cfb->region;
 
 	err = -EINVAL;
-	if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
+	if (!fb_find_mode(&fb_info->var, fb_info, NULL, NULL, 0,
 	    		  &cyber2000fb_default_mode, 8)) {
-		printk("%s: no valid mode found\n", cfb->fb.fix.id);
+		printk("%s: no valid mode found\n", fb_info->fix.id);
 		goto failed;
 	}
 
-	cfb->fb.var.yres_virtual = cfb->fb.fix.smem_len * 8 /
-			(cfb->fb.var.bits_per_pixel * cfb->fb.var.xres_virtual);
+	fb_info->var.yres_virtual = fb_info->fix.smem_len * 8 /
+			(fb_info->var.bits_per_pixel * fb_info->var.xres_virtual);
 
-	if (cfb->fb.var.yres_virtual < cfb->fb.var.yres)
-		cfb->fb.var.yres_virtual = cfb->fb.var.yres;
+	if (fb_info->var.yres_virtual < fb_info->var.yres)
+		fb_info->var.yres_virtual = fb_info->var.yres;
 
 //	fb_set_var(&cfb->fb.var, -1, &cfb->fb);
 
@@ -1388,18 +1389,18 @@
 	 * the precision and fit the results into 32-bit registers.
 	 *  (1953125000 * 512 = 1e12)
 	 */
-	h_sync = 1953125000 / cfb->fb.var.pixclock;
-	h_sync = h_sync * 512 / (cfb->fb.var.xres + cfb->fb.var.left_margin +
-		 cfb->fb.var.right_margin + cfb->fb.var.hsync_len);
-	v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
-		 cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
+	h_sync = 1953125000 / fb_info->var.pixclock;
+	h_sync = h_sync * 512 / (fb_info->var.xres + fb_info->var.left_margin +
+		 fb_info->var.right_margin + fb_info->var.hsync_len);
+	v_sync = h_sync / (cfb->fb->var.yres + fb_info->var.upper_margin +
+		 fb_info->var.lower_margin + fb_info->var.vsync_len);
 
 	printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
-		cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
-		cfb->fb.var.xres, cfb->fb.var.yres,
+		fb_info->fix.id, fb_info->fix.smem_len >> 10,
+		fb_info->var.xres, fb_info->var.yres,
 		h_sync / 1000, h_sync % 1000, v_sync);
 
-	err = register_framebuffer(&cfb->fb);
+	err = register_framebuffer(fb_info);
 
 failed:
 	return err;
@@ -1419,7 +1420,7 @@
 	 * Restore the old video mode and the palette.
 	 * We also need to tell fbcon to redraw the console.
 	 */
-	cyber2000fb_set_par(&cfb->fb);
+	cyber2000fb_set_par(cfb->fb);
 }
 
 #ifdef CONFIG_ARCH_SHARK
@@ -1434,7 +1435,7 @@
 
 	if (!request_mem_region(FB_START,FB_SIZE,"CyberPro2010")) return err;
 
-	cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010");
+	cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010", NULL);
 	if (!cfb)
 		goto failed_release;
 
@@ -1444,8 +1445,8 @@
 		goto failed_ioremap;
 
 	cfb->regs = cfb->region + MMIO_OFFSET;
-	cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET;
-	cfb->fb.fix.smem_start = FB_START;
+	cfb->fb->fix.mmio_start = FB_START + MMIO_OFFSET;
+	cfb->fb->fix.smem_start = FB_START;
 
 	/*
 	 * Bring up the hardware.  This is expected to enable access
@@ -1540,7 +1541,7 @@
 	 */
 	val = cyber2000_grphr(EXT_BUS_CTL, cfb);
 	if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
-		printk(KERN_INFO "%s: enabling PCI bursts\n", cfb->fb.fix.id);
+		printk(KERN_INFO "%s: enabling PCI bursts\n", cfb->fb->fix.id);
 
 		val |= EXT_BUS_CTL_PCIBURST_WRITE;
 
@@ -1571,7 +1572,7 @@
 		return err;
 
 	err = -ENOMEM;
-	cfb = cyberpro_alloc_fb_info(id->driver_data, name);
+	cfb = cyberpro_alloc_fb_info(id->driver_data, name, &dev->dev);
 	if (!cfb)
 		goto failed_release;
 
@@ -1582,8 +1583,8 @@
 		goto failed_ioremap;
 
 	cfb->regs = cfb->region + MMIO_OFFSET;
-	cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
-	cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
+	cfb->fb->fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
+	cfb->fb->fix.smem_start = pci_resource_start(dev, 0);
 
 	/*
 	 * Bring up the hardware.  This is expected to enable access
@@ -1644,12 +1645,11 @@
 		 * we will be leaving hooks that could cause
 		 * oopsen laying around.
 		 */
-		if (unregister_framebuffer(&cfb->fb))
+		if (unregister_framebuffer(cfb->fb))
 			printk(KERN_WARNING "%s: danger Will Robinson, "
 				"danger danger!  Oopsen imminent!\n",
-				cfb->fb.fix.id);
+				cfb->fb->fix.id);
 		iounmap(cfb->region);
-		cyberpro_free_fb_info(cfb);
 
 		/*
 		 * Ensure that the driver data is no longer
@@ -1660,6 +1660,8 @@
 			int_cfb_info = NULL;
 
 		pci_release_regions(dev);
+
+		framebuffer_release(cfb->fb);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/epson1355fb.c fbdev-2.6/drivers/video/epson1355fb.c
--- linus-2.6/drivers/video/epson1355fb.c	Thu Oct 16 14:13:30 2003
+++ fbdev-2.6/drivers/video/epson1355fb.c	Thu Oct 16 14:13:30 2003
@@ -1,541 +1,714 @@
 /*
- * linux/drivers/video/epson1355fb.c
- *	-- Support for the Epson SED1355 LCD/CRT controller
+ * linux/drivers/video/epson1355fb.c -- Epson S1D13505 frame buffer for 2.5.
  *
- * Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ * Epson Research S1D13505 Embedded RAMDAC LCD/CRT Controller
+ *   (previously known as SED1355)
  *
- * based on linux/drivers/video/skeletonfb.c, which was
+ * Cf. http://www.erd.epson.com/vdc/html/S1D13505.html
+ *
+ *
+ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ *
+ * Adapted from:
+ *
+ *  linux/drivers/video/skeletonfb.c
+ *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
  *  Created 28 Dec 1997 by Geert Uytterhoeven
  *
+ *  linux/drivers/video/epson1355fb.c (2.4 driver)
+ *  Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>
+ *
  * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
- */
-/* TODO (roughly in order of priority):
- * 16 bpp support
- * crt support
- * hw cursor support
- * SwivelView
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *
+ * Noteworthy Issues
+ * -----------------
+ *
+ * This driver is complicated by the fact that this is a 16-bit chip
+ * and, on at least one platform (ceiva), we can only do 16-bit reads
+ * and writes to the framebuffer.  We hide this from user space
+ * except in the case of mmap().
+ *
+ *
+ * To Do
+ * -----
+ *
+ * - Test 8-bit pseudocolor mode
+ * - Allow setting bpp, virtual resolution
+ * - Implement horizontal panning
+ * - (maybe) Implement hardware cursor
  */
 
-#include <asm/io.h>
-#include <linux/config.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
 #include <linux/module.h>
-#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
 #include <linux/string.h>
+#include <linux/mm.h>
 #include <linux/tty.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-mfb.h>
-#include <video/fbcon.h>
-
-/* Register defines.  The docs don't seem to provide nice mnemonic names
- * so I made them up myself ... */
-
-#define E1355_PANEL	0x02
-#define E1355_DISPLAY	0x0D
-#define E1355_MISC	0x1B
-#define E1355_GPIO	0x20
-#define E1355_LUT_INDEX 0x24
-#define E1355_LUT_DATA	0x26
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include <video/epson1355.h>
+
+static struct fb_info info;
+
+static struct epson1355fb_par {
+	unsigned long reg_addr;
+} par;
+
+static u32 pseudo_palette[16];
+
+/* ------------------------------------------------------------------------- */
 
 #ifdef CONFIG_SUPERH
-#define E1355_REG_BASE	CONFIG_E1355_REG_BASE
-#define E1355_FB_BASE	CONFIG_E1355_FB_BASE
 
-static inline u8 e1355_read_reg(int index)
+static inline u8 epson1355_read_reg(int index)
 {
-	return ctrl_inb(E1355_REG_BASE + index);
+	return ctrl_inb(par.reg_addr + index);
 }
 
-static inline void e1355_write_reg(u8 data, int index)
+static inline void epson1355_write_reg(u8 data, int index)
 {
-	ctrl_outb(data, E1355_REG_BASE + index);
+	ctrl_outb(data, par.reg_addr + index);
 }
 
-static inline u16 e1355_read_reg16(int index)
+#elif defined(CONFIG_ARM)
+
+# ifdef CONFIG_ARCH_CEIVA
+#  include <asm/arch/hardware.h>
+#  define EPSON1355FB_BASE_PHYS	(CEIVA_PHYS_SED1355)
+# endif
+
+static inline u8 epson1355_read_reg(int index)
 {
-	return e1355_read_reg(index) + (e1355_read_reg(index+1) << 8);
+	return __raw_readb(par.reg_addr + index);
 }
 
-static inline void e1355_write_reg16(u16 data, int index)
+static inline void epson1355_write_reg(u8 data, int index)
 {
-	e1355_write_reg((data&0xff), index);
-	e1355_write_reg(((data>>8)&0xff), index + 1);
+	__raw_writeb(data, par.reg_addr + index);
 }
+
 #else
-#error unknown architecture
+# error "no architecture-specific epson1355_{read,write}_reg"
 #endif
 
-struct e1355fb_info {
-	struct fb_info_gen gen;
-};
-
-static int current_par_valid = 0;
-static struct display disp;
+#ifndef EPSON1355FB_BASE_PHYS
+# error  "EPSON1355FB_BASE_PHYS is not defined"
+#endif
 
-static struct fb_var_screeninfo default_var;
+#define EPSON1355FB_REGS_OFS	(0)
+#define EPSON1355FB_REGS_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_REGS_OFS)
+#define EPSON1355FB_REGS_LEN	(64)
 
-int e1355fb_init(void);
-int e1355fb_setup(char*);
-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *par,
-			    struct fb_info_gen *info);
-/* ------------------- chipset specific functions -------------------------- */
+#define EPSON1355FB_FB_OFS	(0x00200000)
+#define EPSON1355FB_FB_PHYS	(EPSON1355FB_BASE_PHYS + EPSON1355FB_FB_OFS)
+#define EPSON1355FB_FB_LEN	(2 * 1024 * 1024)
 
+/* ------------------------------------------------------------------------- */
 
-static void disable_hw_cursor(void)
+static inline u16 epson1355_read_reg16(int index)
 {
-	u8 curs;
+	u8 lo = epson1355_read_reg(index);
+	u8 hi = epson1355_read_reg(index + 1);
 
-	curs = e1355_read_reg(0x27);
-	curs &= ~0xc0;
-	e1355_write_reg(curs, 0x27);
+	return (hi << 8) | lo;
 }
 
-static void e1355_detect(void)
+static inline void epson1355_write_reg16(u16 data, int index)
 {
-	u8 rev;
+	u8 lo = data & 0xff;
+	u8 hi = (data >> 8) & 0xff;
 
-	e1355_write_reg(0x00, E1355_MISC);
+	epson1355_write_reg(lo, index);
+	epson1355_write_reg(hi, index + 1);
+}
 
-	rev = e1355_read_reg(0x00);
+static inline u32 epson1355_read_reg20(int index)
+{
+	u8 b0 = epson1355_read_reg(index);
+	u8 b1 = epson1355_read_reg(index + 1);
+	u8 b2 = epson1355_read_reg(index + 2);
 
-	if ((rev & 0xfc) != 0x0c) {
-		printk(KERN_WARNING "Epson 1355 not detected\n");
-	}
+	return (b2 & 0x0f) << 16 | (b1 << 8) | b0;
+}
 
-	/* XXX */
-	disable_hw_cursor();
+static inline void epson1355_write_reg20(u32 data, int index)
+{
+	u8 b0 = data & 0xff;
+	u8 b1 = (data >> 8) & 0xff;
+	u8 b2 = (data >> 16) & 0x0f;
 
-	e1355_encode_var(&default_var, NULL, NULL);
+	epson1355_write_reg(b0, index);
+	epson1355_write_reg(b1, index + 1);
+	epson1355_write_reg(b2, index + 2);
 }
 
-struct e1355_par {
-	u32 xres;
-	u32 yres;
+/* ------------------------------------------------------------------------- */
 
-	int bpp;
-	int mem_bpp;
+static void set_lut(u8 index, u8 r, u8 g, u8 b)
+{
+	epson1355_write_reg(index, REG_LUT_ADDR);
+	epson1355_write_reg(r, REG_LUT_DATA);
+	epson1355_write_reg(g, REG_LUT_DATA);
+	epson1355_write_reg(b, REG_LUT_DATA);
+}
 
-	u32 panel_xres;
-	u32 panel_yres;
-	
-	int panel_width;
-	int panel_ymul;
-};
 
-static int e1355_encode_fix(struct fb_fix_screeninfo *fix,
-			    const void *raw_par,
-			    struct fb_info_gen *info)
-{
-	const struct e1355_par *par = raw_par;
-	
-	memset(fix, 0, sizeof *fix);
-	
-	fix->type= FB_TYPE_PACKED_PIXELS;
+/**
+ *  	epson1355fb_setcolreg - sets a color register.
+ *      @regno: Which register in the CLUT we are programming
+ *      @red: The red value which can be up to 16 bits wide
+ *	@green: The green value which can be up to 16 bits wide
+ *	@blue:  The blue value which can be up to 16 bits wide.
+ *	@transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+static int epson1355fb_setcolreg(unsigned regno, unsigned r, unsigned g,
+				 unsigned b, unsigned transp,
+				 struct fb_info *info)
+{
+	if (info->var.grayscale)
+		r = g = b = (19595 * r + 38470 * g + 7471 * b) >> 16;
+
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+		if (regno >= 16)
+			return -EINVAL;
 
-	if (!par)
-		BUG();
+		((u32 *) info->pseudo_palette)[regno] =
+		    (r & 0xf800) | (g & 0xfc00) >> 5 | (b & 0xf800) >> 11;
 
-	if (par->bpp == 1) {
-		fix->visual = FB_VISUAL_MONO10;
-	} else if (par->bpp <= 8) {
-		fix->visual = FB_VISUAL_PSEUDOCOLOR;
-	} else {
-		fix->visual = FB_VISUAL_TRUECOLOR;
-	}
+		break;
+	case FB_VISUAL_PSEUDOCOLOR:
+		if (regno >= 256)
+			return -EINVAL;
 
-	return 0;
-}
+		set_lut(regno, r >> 8, g >> 8, b >> 8);
 
-static int e1355_set_bpp(struct e1355_par *par, int bpp)
-{
-	int code;
-	u8 disp;
-	u16 bytes_per_line;
-
-	switch(bpp) {
-	case 1:
-		code = 0; break;
-	case 2:
-		code = 1; break;
-	case 4:
-		code = 2; break;
-	case 8:
-		code = 3; break;
-	case 16:
-		code = 5; break;
+		break;
 	default:
-		return -EINVAL; break;
+		return -ENOSYS;
 	}
-
-	disp = e1355_read_reg(E1355_DISPLAY);
-	disp &= ~0x1c;
-	disp |= code << 2;
-	e1355_write_reg(disp, E1355_DISPLAY);
-	
-	bytes_per_line = (par->xres * bpp) >> 3;
-	
-	e1355_write_reg16(bytes_per_line, 0x16);
-
-	par->bpp = bpp;
-
 	return 0;
 }
-		
-static int e1355_decode_var(const struct fb_var_screeninfo *var,
-			    void *raw_par,
-			    struct fb_info_gen *info)
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ *      epson1355fb_pan_display - Pans the display.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Pan (or wrap, depending on the `vmode' field) the display using the
+ *  	`xoffset' and `yoffset' fields of the `var' structure.
+ *  	If the values don't fit, return -EINVAL.
+ *
+ *      Returns negative errno on error, or zero on success.
+ */
+static int epson1355fb_pan_display(struct fb_var_screeninfo *var,
+				   struct fb_info *info)
 {
-	struct e1355_par *par = raw_par;
-	int ret;
+	u32 start;
 
-	if (!par)
-		BUG();
+	if (var->xoffset != 0)	/* not yet ... */
+		return -EINVAL;
 
-	/*
-	 * Don't allow setting any of these yet: xres and yres don't
-	 * make sense for LCD panels; xres_virtual and yres_virtual
-	 * should be supported fine by our hardware though.
-	 */
-	if (var->xres != par->xres ||
-	    var->yres != par->yres ||
-	    var->xres != var->xres_virtual ||
-	    var->yres != var->yres_virtual ||
-	    var->xoffset != 0 ||
-	    var->yoffset != 0)
+	if (var->yoffset + info->var.yres > info->var.yres_virtual)
 		return -EINVAL;
 
-	if(var->bits_per_pixel != par->bpp) {
-		ret = e1355_set_bpp(par, var->bits_per_pixel);
+	start = (info->fix.line_length >> 1) * var->yoffset;
 
-		if (ret)
-			goto out_err;
-	}
-		
-	return 0;
+	epson1355_write_reg20(start, REG_SCRN1_DISP_START_ADDR0);
 
- out_err:
-	return ret;
+	return 0;
 }
 
-static void dump_panel_data(void)
+/* ------------------------------------------------------------------------- */
+
+static void lcd_enable(int enable)
 {
-	u8 panel = e1355_read_reg(E1355_PANEL);
-	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+	u8 mode = epson1355_read_reg(REG_DISPLAY_MODE);
 
-	printk("%s %s %s panel, width %d bits\n",
-	       panel & 2 ? "dual" : "single",
-	       panel & 4 ? "color" : "mono",
-	       panel & 1 ? "TFT" : "passive",
-	       width[panel&1][(panel>>4)&3]);
+	if (enable)
+		mode |= 1;
+	else
+		mode &= ~1;
 
-	printk("resolution %d x %d\n",
-	       (e1355_read_reg(0x04) + 1) * 8,
-	       ((e1355_read_reg16(0x08) + 1) * (1 + ((panel & 3) == 2))));
+	epson1355_write_reg(mode, REG_DISPLAY_MODE);
 }
 
-static int e1355_bpp_to_var(int bpp, struct fb_var_screeninfo *var)
+#if defined(CONFIG_ARCH_CEIVA)
+static void backlight_enable(int enable)
 {
-	switch(bpp) {
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-		var->bits_per_pixel = bpp;
-		var->red.offset = var->green.offset = var->blue.offset = 0;
-		var->red.length = var->green.length = var->blue.length = bpp;
+	/* ### this should be protected by a spinlock ... */
+	u8 pddr = clps_readb(PDDR);
+	if (enable)
+		pddr |= (1 << 5);
+	else
+		pddr &= ~(1 << 5);
+	clps_writeb(pddr, PDDR);
+}
+#else
+static void backlight_enable(int enable)
+{
+}
+#endif
+
+
+/**
+ *      epson1355fb_blank - blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
+ *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a
+ *      video mode which doesn't support it. Implements VESA suspend
+ *      and powerdown modes on hardware that supports disabling hsync/vsync:
+ *      blank_mode == 2: suspend vsync
+ *      blank_mode == 3: suspend hsync
+ *      blank_mode == 4: powerdown
+ *
+ *      Returns negative errno on error, or zero on success.
+ *
+ */
+static int epson1355fb_blank(int blank_mode, struct fb_info *info)
+{
+	switch (blank_mode) {
+	case VESA_NO_BLANKING:
+		lcd_enable(1);
+		backlight_enable(1);
 		break;
-	case 16:
-		var->bits_per_pixel = 16;
-		var->red.offset = 11;
-		var->red.length = 5;
-		var->green.offset = 5;
-		var->green.length = 6;
-		var->blue.offset = 0;
-		var->blue.length = 5;
+	case VESA_VSYNC_SUSPEND:
+	case VESA_HSYNC_SUSPEND:
+		backlight_enable(0);
 		break;
+	case VESA_POWERDOWN:
+		backlight_enable(0);
+		lcd_enable(0);
+		break;
+	default:
+		return -EINVAL;
 	}
-
 	return 0;
 }
 
-static int e1355_encode_var(struct fb_var_screeninfo *var, const void *raw_par,
-			    struct fb_info_gen *info)
+/* ------------------------------------------------------------------------- */
+
+/*
+ * We can't use the cfb generic routines, as we have to limit
+ * ourselves to 16-bit or 8-bit loads and stores to this 16-bit
+ * chip.
+ */
+
+static inline void epson1355fb_fb_writel(unsigned long v, unsigned long *a)
 {
-	u8 panel, display;
-	u32 xres, xres_virtual, yres;
-	static int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
-	static int bpp_tab[8] = { 1, 2, 4, 8, 15, 16 };
-	int bpp, hw_bpp;
-	int is_color, is_dual, is_tft;
-	int lcd_enabled, crt_enabled;
+	u16 *p = (u16 *) a;
+	u16 l = v & 0xffff;
+	u16 h = v >> 16;
 
-	panel = e1355_read_reg(E1355_PANEL);
-	display = e1355_read_reg(E1355_DISPLAY);
+	fb_writew(l, p);
+	fb_writew(h, p + 1);
+}
 
-	is_color = (panel & 0x04) != 0;
-	is_dual  = (panel & 0x02) != 0;
-	is_tft   = (panel & 0x01) != 0;
+static inline unsigned long epson1355fb_fb_readl(const unsigned long *a)
+{
+	const u16 *p = (u16 *) a;
+	u16 l = fb_readw(p);
+	u16 h = fb_readw(p + 1);
 
-	bpp = bpp_tab[(display>>2)&7]; 
-	e1355_bpp_to_var(bpp, var);
+	return (h << 16) | l;
+}
 
-	crt_enabled = (display & 0x02) != 0;
-	lcd_enabled = (display & 0x02) != 0;
+#define FB_READL epson1355fb_fb_readl
+#define FB_WRITEL epson1355fb_fb_writel
 
-	hw_bpp = width[is_tft][(panel>>4)&3];
+/* ------------------------------------------------------------------------- */
 
-	xres = e1355_read_reg(0x04) + 1;
-	yres = e1355_read_reg16(0x08) + 1;
-	
-	xres *= 8;
-	/* talk about weird hardware .. */
-	yres *= (is_dual && !crt_enabled) ? 2 : 1;
-
-	xres_virtual = e1355_read_reg16(0x16);
-	/* it's in 2-byte words initially */
-	xres_virtual *= 16;
-	xres_virtual /= var->bits_per_pixel;
+static inline unsigned long copy_from_user16(void *to, const void *from,
+					     unsigned long n)
+{
+	u16 *dst = (u16 *) to;
+	u16 *src = (u16 *) from;
 
-	var->xres = xres;
-	var->yres = yres;
-	var->xres_virtual = xres_virtual;
-	var->yres_virtual = yres;
+	if (!access_ok(VERIFY_READ, from, n))
+		return n;
 
-	var->xoffset = var->yoffset = 0;
+	while (n > 1) {
+		u16 v;
+		if (__get_user(v, src))
+			return n;
 
-	var->grayscale = !is_color;
-	
-	return 0;
-}
+		fb_writew(v, dst);
 
-#define is_dual(panel) (((panel)&3)==2)
+		src++, dst++;
+		n -= 2;
+	}
 
-static void get_panel_data(struct e1355_par *par)
-{
-	u8 panel;
-	int width[2][4] = { { 4, 8, 16, -1 }, { 9, 12, 16, -1 } };
+	if (n) {
+		u8 v;
 
-	panel = e1355_read_reg(E1355_PANEL);
+		if (__get_user(v, ((u8 *) src)))
+			return n;
 
-	par->panel_width = width[panel&1][(panel>>4)&3];
-	par->panel_xres = (e1355_read_reg(0x04) + 1) * 8;
-	par->panel_ymul = is_dual(panel) ? 2 : 1;
-	par->panel_yres = ((e1355_read_reg16(0x08) + 1)
-			   * par->panel_ymul);
+		fb_writeb(v, dst);
+	}
+	return 0;
 }
 
-static void e1355_get_par(void *raw_par, struct fb_info_gen *info)
+static inline unsigned long copy_to_user16(void *to, const void *from,
+					   unsigned long n)
 {
-	struct e1355_par *par = raw_par;
+	u16 *dst = (u16 *) to;
+	u16 *src = (u16 *) from;
 
-	get_panel_data(par);
-}
+	if (!access_ok(VERIFY_WRITE, to, n))
+		return n;
 
-static void e1355_set_par(const void *par, struct fb_info_gen *info)
-{
-}
+	while (n > 1) {
+		u16 v = fb_readw(src);
 
-static int e1355_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-			   unsigned *blue, unsigned *transp,
-			   struct fb_info *info)
-{
-	u8 r, g, b;
+		if (__put_user(v, dst))
+			return n;
 
-	e1355_write_reg(regno, E1355_LUT_INDEX);
-	r = e1355_read_reg(E1355_LUT_DATA);
-	g = e1355_read_reg(E1355_LUT_DATA);
-	b = e1355_read_reg(E1355_LUT_DATA);
+		src++, dst++;
+		n -= 2;
+	}
 
-	*red = r << 8;
-	*green = g << 8;
-	*blue = b << 8;
+	if (n) {
+		u8 v = fb_readb(src);
 
+		if (__put_user(v, ((u8 *) dst)))
+			return n;
+	}
 	return 0;
 }
 
-static int e1355fb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			     unsigned blue, unsigned transp,
-			     struct fb_info *info)
-{
-	u8 r = (red >> 8) & 0xf0;
-	u8 g = (green>>8) & 0xf0;
-	u8 b = (blue>> 8) & 0xf0;
-
-	e1355_write_reg(regno, E1355_LUT_INDEX);
-	e1355_write_reg(r, E1355_LUT_DATA);
-	e1355_write_reg(g, E1355_LUT_DATA);
-	e1355_write_reg(b, E1355_LUT_DATA);
-	
-	return 0;
-}
 
-static int e1355_pan_display(const struct fb_var_screeninfo *var,
-			     struct fb_info_gen *info)
+static ssize_t
+epson1355fb_read(struct file *file, char *buf, size_t count, loff_t * ppos)
 {
-	BUG();
-	
-	return -EINVAL;
+	unsigned long p = *ppos;
+
+	/* from fbmem.c except for our own copy_*_user */
+	if (p >= info.fix.smem_len)
+		return 0;
+	if (count >= info.fix.smem_len)
+		count = info.fix.smem_len;
+	if (count + p > info.fix.smem_len)
+		count = info.fix.smem_len - p;
+
+	if (count) {
+		char *base_addr;
+
+		base_addr = info.screen_base;
+		count -= copy_to_user16(buf, base_addr + p, count);
+		if (!count)
+			return -EFAULT;
+		*ppos += count;
+	}
+	return count;
 }
 
-/*
- * The AERO_HACKS parts disable/enable the backlight on the Compaq Aero 8000.
- * I'm not sure they aren't dangerous to the hardware, so be warned.
- */
-#undef AERO_HACKS
+static ssize_t
+epson1355fb_write(struct file *file, const char *buf,
+		  size_t count, loff_t * ppos)
+{
+	unsigned long p = *ppos;
+	int err;
+
+	/* from fbmem.c except for our own copy_*_user */
+	if (p > info.fix.smem_len)
+		return -ENOSPC;
+	if (count >= info.fix.smem_len)
+		count = info.fix.smem_len;
+	err = 0;
+	if (count + p > info.fix.smem_len) {
+		count = info.fix.smem_len - p;
+		err = -ENOSPC;
+	}
 
-static int e1355_blank(int blank_mode, struct fb_info_gen *info)
-{
-	u8 disp;
+	if (count) {
+		char *base_addr;
 
-	switch (blank_mode) {
-	case VESA_NO_BLANKING:
-		disp = e1355_read_reg(E1355_DISPLAY);
-		disp |= 1;
-		e1355_write_reg(disp, E1355_DISPLAY);
- 		
-#ifdef AERO_HACKS
-		e1355_write_reg(0x6, 0x20);
-#endif
-		break;
+		base_addr = info.screen_base;
+		count -= copy_from_user16(base_addr + p, buf, count);
+		*ppos += count;
+		err = -EFAULT;
+	}
+	if (count)
+		return count;
+	return err;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static struct fb_ops epson1355fb_fbops = {
+	.owner 		= THIS_MODULE,
+	.fb_setcolreg 	= epson1355fb_setcolreg,
+	.fb_pan_display = epson1355fb_pan_display,
+	.fb_blank 	= epson1355fb_blank,
+	.fb_fillrect 	= cfb_fillrect,
+	.fb_copyarea 	= cfb_copyarea,
+	.fb_imageblit 	= cfb_imageblit,
+	.fb_read 	= epson1355fb_read,
+	.fb_write 	= epson1355fb_write,
+	.fb_cursor 	= soft_cursor,
+};
 
-	case VESA_VSYNC_SUSPEND:
-	case VESA_HSYNC_SUSPEND:
-	case VESA_POWERDOWN:
-		disp = e1355_read_reg(E1355_DISPLAY);
-		disp &= ~1;
-		e1355_write_reg(disp, E1355_DISPLAY);
+/* ------------------------------------------------------------------------- */
 
-#ifdef AERO_HACKS
-		e1355_write_reg(0x0, 0x20);
-#endif
-		break;
+static __init unsigned int get_fb_size(struct fb_info *info)
+{
+	unsigned int size = 2 * 1024 * 1024;
+	char *p = info->screen_base;
 
-	default:
-		return -EINVAL;
-	}
+	/* the 512k framebuffer is aliased at start + 0x80000 * n */
+	fb_writeb(1, p);
+	fb_writeb(0, p + 0x80000);
+	if (!fb_readb(p))
+		size = 512 * 1024;
 
-	return 0;
+	fb_writeb(0, p);
+
+	return size;
 }
 
-static struct display_switch e1355_dispsw;
+static int epson1355_width_tab[2][4] __initdata =
+    { {4, 8, 16, -1}, {9, 12, 16, -1} };
+static int epson1355_bpp_tab[8] __initdata = { 1, 2, 4, 8, 15, 16 };
 
-static void e1355_set_disp(const void *unused, struct display *disp,
-			   struct fb_info_gen *info)
+static void __init fetch_hw_state(struct fb_info *info)
 {
-	struct display_switch *d;
+	struct fb_var_screeninfo *var = &info->var;
+	struct fb_fix_screeninfo *fix = &info->fix;
+	u8 panel, display;
+	u16 offset;
+	u32 xres, yres;
+	u32 xres_virtual, yres_virtual;
+	int bpp, lcd_bpp;
+	int is_color, is_dual, is_tft;
+	int lcd_enabled, crt_enabled;
+
+	fix->type = FB_TYPE_PACKED_PIXELS;
+
+	display = epson1355_read_reg(REG_DISPLAY_MODE);
+	bpp = epson1355_bpp_tab[(display >> 2) & 7];
 
-	disp->dispsw = &e1355_dispsw;
-	
-	switch(disp->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
-	case 1:
-		d = &fbcon_mfb; break;
-#endif	       
-#ifdef FBCON_HAS_CFB8
+	switch (bpp) {
 	case 8:
-		d = &fbcon_cfb8; break;
-#endif
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+		var->bits_per_pixel = 8;
+		var->red.offset = var->green.offset = var->blue.offset = 0;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		/* 5-6-5 RGB */
+		fix->visual = FB_VISUAL_TRUECOLOR;
+		var->bits_per_pixel = 16;
+		var->red.offset = 11;
+		var->red.length = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset = 0;
+		var->blue.length = 5;
+		break;
 	default:
-		BUG(); break;
+		BUG();
 	}
 
-	memcpy(&e1355_dispsw, d, sizeof *d);
+	if (fix->visual == FB_VISUAL_TRUECOLOR) {
+		info->pseudo_palette = &pseudo_palette;
+		fb_alloc_cmap(&(info->cmap), 16, 0);
+	} else
+		fb_alloc_cmap(&(info->cmap), 1 << bpp, 0);
+
+	panel = epson1355_read_reg(REG_PANEL_TYPE);
+	is_color = (panel & 0x04) != 0;
+	is_dual = (panel & 0x02) != 0;
+	is_tft = (panel & 0x01) != 0;
+	crt_enabled = (display & 0x02) != 0;
+	lcd_enabled = (display & 0x01) != 0;
+	lcd_bpp = epson1355_width_tab[is_tft][(panel >> 4) & 3];
+
+	xres = (epson1355_read_reg(REG_HORZ_DISP_WIDTH) + 1) * 8;
+	yres = (epson1355_read_reg16(REG_VERT_DISP_HEIGHT0) + 1) *
+	    ((is_dual && !crt_enabled) ? 2 : 1);
+	offset = epson1355_read_reg16(REG_MEM_ADDR_OFFSET0) & 0x7ff;
+	xres_virtual = offset * 16 / bpp;
+	yres_virtual = fix->smem_len / (offset * 2);
+
+	var->xres = xres;
+	var->yres = yres;
+	var->xres_virtual = xres_virtual;
+	var->yres_virtual = yres_virtual;
+	var->xoffset = var->yoffset = 0;
+
+	fix->line_length = offset * 2;
+
+	fix->xpanstep = 0;	/* no pan yet */
+	fix->ypanstep = 1;
+	fix->ywrapstep = 0;
+	fix->accel = FB_ACCEL_NONE;
+
+	var->grayscale = !is_color;
 
-	/* reading is terribly slow for us */
-#if 0 /* XXX: need to work out why this doesn't work */
-	e1355_dispsw.bmove = fbcon_redraw_bmove;
+#ifdef DEBUG
+	printk(KERN_INFO
+	       "epson1355fb: xres=%d, yres=%d, "
+	       "is_color=%d, is_dual=%d, is_tft=%d\n",
+	       xres, yres, is_color, is_dual, is_tft);
+	printk(KERN_INFO
+	       "epson1355fb: bpp=%d, lcd_bpp=%d, "
+	       "crt_enabled=%d, lcd_enabled=%d\n",
+	       bpp, lcd_bpp, crt_enabled, lcd_enabled);
 #endif
 }
 
-/* ------------ Interfaces to hardware functions ------------ */
 
+static void clearfb16(struct fb_info *info)
+{
+	u16 *dst = (u16 *) info->screen_base;
+	unsigned long n = info->fix.smem_len;
 
-struct fbgen_hwswitch e1355_switch = {
-	.detect =	e1355_detect,
-	.encode_fix =	e1355_encode_fix,
-	.decode_var =	e1355_decode_var,
-	.encode_var =	e1355_encode_var,
-	.get_par =	e1355_get_par,
-	.set_par =	e1355_set_par,
-	.getcolreg =	e1355_getcolreg,
-	.pan_display =	e1355_pan_display,
-	.blank =	e1355_blank,
-	.set_disp =	e1355_set_disp,
-};
+	while (n > 1) {
+		fb_writew(0, dst);
+		dst++, n -= 2;
+	}
 
+	if (n)
+		fb_writeb(0, dst);
+}
 
-/* ------------ Hardware Independent Functions ------------ */
+static void epson1355fb_deinit(void);
 
+int __init epson1355fb_init(void)
+{
+	u8 revision;
+	int rc = 0;
 
-static struct fb_ops e1355fb_ops = {
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	fbgen_get_fix,
-	.fb_get_var =	fbgen_get_var,
-	.fb_set_var =	fbgen_set_var,
-	.fb_get_cmap =	fbgen_get_cmap,
-	.fb_set_cmap =	gen_set_cmap,
-	.fb_setcolreg =	e1355fb_setcolreg,
-	.fb_pan_display =fbgen_pan_display,
-	.fb_blank =	fbgen_blank,
-};
+	if (!request_mem_region
+	    (EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN,
+	     "S1D13505 registers")) {
+		printk(KERN_ERR "epson1355fb: unable to reserve "
+		       "registers at 0x%0x\n", EPSON1355FB_REGS_PHYS);
+		rc = -EBUSY;
+		goto bail;
+	}
 
-static struct e1355fb_info fb_info;
+	if (!request_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN,
+				"S1D13505 framebuffer")) {
+		printk(KERN_ERR "epson1355fb: unable to reserve "
+		       "framebuffer at 0x%0x\n", EPSON1355FB_FB_PHYS);
+		rc = -EBUSY;
+		goto bail;
+	}
+
+	par.reg_addr = (unsigned long)
+	    ioremap(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
+	if (!par.reg_addr) {
+		printk(KERN_ERR "epson1355fb: unable to map registers\n");
+		rc = -ENOMEM;
+		goto bail;
+	}
+
+	info.screen_base =
+	    ioremap(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
+	if (!info.screen_base) {
+		printk(KERN_ERR
+		       "epson1355fb: unable to map framebuffer\n");
+		rc = -ENOMEM;
+		goto bail;
+	}
+
+	revision = epson1355_read_reg(REG_REVISION_CODE);
+	if ((revision >> 2) != 3) {
+		printk(KERN_INFO "epson1355fb: epson1355 not found\n");
+		rc = -ENODEV;
+		goto bail;
+	}
+
+	info.fix.mmio_start = EPSON1355FB_REGS_PHYS;
+	info.fix.mmio_len = EPSON1355FB_REGS_LEN;
+	info.fix.smem_start = EPSON1355FB_FB_PHYS;
+	info.fix.smem_len = get_fb_size(&info);
+
+	printk(KERN_INFO
+	       "epson1355fb: regs mapped at 0x%lx, fb %d KiB mapped at 0x%p\n",
+	       par.reg_addr, info.fix.smem_len / 1024, info.screen_base);
+
+	strcpy(info.fix.id, "S1D13505");
+	info.par = &par;
+	info.node = NODEV;
+	info.fbops = &epson1355fb_fbops;
+	info.flags = FBINFO_FLAG_DEFAULT;
+
+	/* we expect the boot loader to have initialized the chip
+	   with appropriate parameters from which we can determinte
+	   the flavor of lcd panel attached */
+	fetch_hw_state(&info);
+
+	/* turn this puppy on ... */
+	clearfb16(&info);
+	backlight_enable(1);
+	lcd_enable(1);
+
+	if (register_framebuffer(&info) < 0) {
+		rc = -EINVAL;
+		goto bail;
+	}
+
+	printk(KERN_INFO "fb%d: %s frame buffer device\n",
+	       minor(info.node), info.fix.id);
 
-int __init e1355fb_setup(char *str)
-{
 	return 0;
+
+      bail:
+	epson1355fb_deinit();
+	return rc;
 }
 
-int __init e1355fb_init(void)
+static void epson1355fb_deinit(void)
 {
-	fb_info.gen.fbhw = &e1355_switch;
-	fb_info.gen.fbhw->detect();
-	strcpy(fb_info.gen.info.modename, "SED1355");
-	fb_info.gen.info.changevar = NULL;
-	fb_info.gen.info.fbops = &e1355fb_ops;
-	fb_info.gen.info.screen_base = (void *)E1355_FB_BASE;
-	fb_info.gen.currcon = -1;
-	fb_info.gen.info.disp = &disp;
-	fb_info.gen.parsize = sizeof(struct e1355_par);
-	fb_info.gen.info.switch_con = &fbgen_switch;
-	fb_info.gen.info.updatevar = &fbgen_update_var;
-	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-	/* This should give a reasonable default video mode */
-	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
-	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
-	fbgen_set_disp(-1, &fb_info.gen);
-	if (disp.var.bits_per_pixel > 1) 
-		do_install_cmap(0, &fb_info.gen);
-	if (register_framebuffer(&fb_info.gen.info) < 0)
-		return -EINVAL;
-	printk(KERN_INFO "fb%d: %s frame buffer device\n", fb_info.gen.info.node,
-	       fb_info.gen.info.modename);
+	fb_dealloc_cmap(&info.cmap);
 
-	return 0;
+	if (info.screen_base)
+		iounmap(info.screen_base);
+	if (par.reg_addr)
+		iounmap((void *) par.reg_addr);
+
+	release_mem_region(EPSON1355FB_FB_PHYS, EPSON1355FB_FB_LEN);
+	release_mem_region(EPSON1355FB_REGS_PHYS, EPSON1355FB_REGS_LEN);
 }
 
+static void __exit epson1355fb_cleanup(void)
+{
+	backlight_enable(0);
+	lcd_enable(0);
 
-    /*
-     *  Cleanup
-     */
-
-void e1355fb_cleanup(struct fb_info *info)
-{
-	/*
-	 *  If your driver supports multiple boards, you should unregister and
-	 *  clean up all instances.
-	 */
-	
-	unregister_framebuffer(info);
-	/* ... */
+	unregister_framebuffer(&info);
+	epson1355fb_deinit();
 }
 
+/* ------------------------------------------------------------------------- */
+
+#ifdef MODULE
+module_init(epson1355fb_init);
+#endif
+module_exit(epson1355fb_cleanup);
+
+MODULE_AUTHOR("Christopher Hoover <ch@hpl.hp.com>");
+MODULE_DESCRIPTION("Framebuffer driver for Epson S1D13505");
 MODULE_LICENSE("GPL");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c
--- linus-2.6/drivers/video/fbmem.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/fbmem.c	Thu Oct 16 14:13:31 2003
@@ -25,12 +25,12 @@
 #include <linux/mman.h>
 #include <linux/tty.h>
 #include <linux/init.h>
-#include <linux/linux_logo.h>
 #include <linux/proc_fs.h>
 #ifdef CONFIG_KMOD
 #include <linux/kmod.h>
 #endif
 #include <linux/devfs_fs_kernel.h>
+#include <linux/device.h>
 
 #if defined(__mc68000__) || defined(CONFIG_APUS)
 #include <asm/setup.h>
@@ -79,7 +79,6 @@
 extern int atyfb_init(void);
 extern int atyfb_setup(char*);
 extern int aty128fb_init(void);
-extern int aty128fb_setup(char*);
 extern int neofb_init(void);
 extern int neofb_setup(char*);
 extern int igafb_init(void);
@@ -102,13 +101,13 @@
 extern int matroxfb_init(void);
 extern int matroxfb_setup(char*);
 extern int hpfb_init(void);
-extern int control_init(void);
-extern int control_setup(char*);
-extern int platinum_init(void);
-extern int platinum_setup(char*);
+extern int controlfb_init(void);
+extern int controlfb_setup(char*);
+extern int platinumfb_init(void);
+extern int platinumfb_setup(char*);
 extern int valkyriefb_init(void);
 extern int valkyriefb_setup(char*);
-extern int chips_init(void);
+extern int chipsfb_init(void);
 extern int g364fb_init(void);
 extern int sa1100fb_init(void);
 extern int fm2fb_init(void);
@@ -134,15 +133,14 @@
 extern int tx3912fb_init(void);
 extern int tx3912fb_setup(char*);
 extern int radeonfb_init(void);
-extern int radeonfb_setup(char*);
-extern int e1355fb_init(void);
-extern int e1355fb_setup(char*);
+extern int epson1355fb_init(void);
 extern int pvr2fb_init(void);
 extern int pvr2fb_setup(char*);
 extern int sstfb_init(void);
 extern int sstfb_setup(char*);
 extern int i810fb_init(void);
 extern int i810fb_setup(char*);
+extern int asiliantfb_init(void);
 extern int ffb_init(void);
 extern int ffb_setup(char*);
 extern int cg6_init(void);
@@ -203,7 +201,7 @@
 	{ "matroxfb", matroxfb_init, matroxfb_setup },
 #endif
 #ifdef CONFIG_FB_ATY128
-	{ "aty128fb", aty128fb_init, aty128fb_setup },
+	{ "aty128fb", aty128fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_NEOMAGIC
 	{ "neofb", neofb_init, neofb_setup },
@@ -218,19 +216,19 @@
 	{ "tdfxfb", tdfxfb_init, tdfxfb_setup },
 #endif
 #ifdef CONFIG_FB_RADEON
-	{ "radeonfb", radeonfb_init, radeonfb_setup },
+	{ "radeonfb", radeonfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_CONTROL
-	{ "controlfb", control_init, control_setup },
+	{ "controlfb", controlfb_init, controlfb_setup },
 #endif
 #ifdef CONFIG_FB_PLATINUM
-	{ "platinumfb", platinum_init, platinum_setup },
+	{ "platinumfb", platinumfb_init, platinumfb_setup },
 #endif
 #ifdef CONFIG_FB_VALKYRIE
 	{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
 #endif
 #ifdef CONFIG_FB_CT65550
-	{ "chipsfb", chips_init, NULL },
+	{ "chipsfb", chipsfb_init, NULL },
 #endif
 #ifdef CONFIG_FB_IMSTT
 	{ "imsttfb", imsttfb_init, imsttfb_setup },
@@ -342,8 +340,8 @@
 #ifdef CONFIG_FB_TX3912
 	{ "tx3912fb", tx3912fb_init, tx3912fb_setup },
 #endif
-#ifdef CONFIG_FB_E1355
-	{ "e1355fb", e1355fb_init, e1355fb_setup },
+#ifdef CONFIG_FB_EPSON1355
+	{ "s1d1355fb", epson1355fb_init, NULL },
 #endif
 #ifdef CONFIG_FB_PVR2
 	{ "pvr2fb", pvr2fb_init, pvr2fb_setup },
@@ -360,6 +358,10 @@
 #ifdef CONFIG_FB_VOODOO1
 	{ "sstfb", sstfb_init, sstfb_setup },
 #endif
+#ifdef CONFIG_FB_ASILIANT
+	{ "asiliantfb", asiliantfb_init, NULL },
+#endif
+
 	/*
 	 * Generic drivers that don't use resource management (yet)
 	 */
@@ -383,7 +385,7 @@
 };
 
 #define NUM_FB_DRIVERS	(sizeof(fb_drivers)/sizeof(*fb_drivers))
-#define FBPIXMAPSIZE	8192
+#define FBPIXMAPSIZE	16384
 
 extern const char *global_mode_option;
 
@@ -404,47 +406,49 @@
 	return *src;
 }
 
-void sys_outbuf(u8 *src, u8 *dst, unsigned int size)
+void sys_outbuf(struct fb_info *info, u8 *dst, u8 *src, unsigned int size)
 {
 	memcpy(dst, src, size);
 }	
 
-void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
-			u32 s_pitch, u32 height)
+void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+			u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+			u32 height)
 {
 	int i;
 
 	for (i = height; i--; ) {
-		info->pixmap.outbuf(src, dst, s_pitch);
+		buf->outbuf(info, dst, src, s_pitch);
 		src += s_pitch;
 		dst += d_pitch;
 	}
 }
 
-void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch, 
-			u32 height, u32 mask, u32 shift_high, u32 shift_low,
-			u32 mod, u32 idx)
+void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
+			u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+			u32 height, u32 shift_high, u32 shift_low,
+			u32 mod)
 {
+	u8 mask = (u8) (0xfff << shift_high), tmp;
 	int i, j;
-	u8 tmp;
 
 	for (i = height; i--; ) {
 		for (j = 0; j < idx; j++) {
-			tmp = info->pixmap.inbuf(dst+j);
+			tmp = buf->inbuf(dst+j);
 			tmp &= mask;
 			tmp |= *src >> shift_low;
-			info->pixmap.outbuf(&tmp, dst+j, 1);
+			buf->outbuf(info, dst+j, &tmp, 1);
 			tmp = *src << shift_high;
-			info->pixmap.outbuf(&tmp, dst+j+1, 1);
+			buf->outbuf(info, dst+j+1, &tmp, 1);
 			src++;
 		}
-		tmp = info->pixmap.inbuf(dst+idx);
+		tmp = buf->inbuf(dst+idx);
 		tmp &= mask;
 		tmp |= *src >> shift_low;
-		info->pixmap.outbuf(&tmp, dst+idx, 1);
+		buf->outbuf(info, dst+idx, &tmp, 1);
 		if (shift_high < mod) {
 			tmp = *src << shift_high;
-			info->pixmap.outbuf(&tmp, dst+idx+1, 1);
+			buf->outbuf(info, dst+idx+1, &tmp, 1);
 		}	
 		src++;
 		dst += d_pitch;
@@ -455,26 +459,29 @@
  * we need to lock this section since fb_cursor
  * may use fb_imageblit()
  */
-u32 fb_get_buffer_offset(struct fb_info *info, u32 size)
+char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size)
 {
-	u32 align = info->pixmap.buf_align - 1;
+	u32 align = buf->buf_align - 1;
 	u32 offset, count = 1000;
+	char *addr = buf->addr;
 
-	spin_lock(&info->pixmap.lock);
-	offset = info->pixmap.offset + align;
-	offset &= ~align;
-	if (offset + size > info->pixmap.size) {
-		while (atomic_read(&info->pixmap.count) && count--);
-		if (info->fbops->fb_sync && 
-		    info->pixmap.flags & FB_PIXMAP_SYNC)
-			info->fbops->fb_sync(info);
-		offset = 0;
+	spin_lock(&buf->lock);
+	if (!(buf->flags & FB_PIXMAP_IO)) {
+		offset = buf->offset + align;
+		offset &= ~align;
+		if (offset + size > buf->size) {
+			while (atomic_read(&buf->count) && count--);
+			if (info->fbops->fb_sync && (buf->flags & FB_PIXMAP_SYNC))
+				info->fbops->fb_sync(info);
+			offset = 0;
+		}
+		buf->offset = offset + size;
+		addr += offset;
 	}
-	info->pixmap.offset = offset + size;
-	atomic_inc(&info->pixmap.count);	
+	atomic_inc(&buf->count);
 	smp_mb__after_atomic_inc();
-	spin_unlock(&info->pixmap.lock);
-	return offset;
+	spin_unlock(&buf->lock);
+	return addr;
 }
 
 #ifdef CONFIG_LOGO
@@ -656,7 +663,7 @@
 	}
 
 	/* Return if no suitable logo was found */
-	fb_logo.logo = fb_find_logo(info->var.bits_per_pixel);
+	fb_logo.logo = find_logo(info->var.bits_per_pixel);
 	
 	if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) {
 		fb_logo.logo = NULL;
@@ -726,8 +733,6 @@
 	     x <= info->var.xres-fb_logo.logo->width; x += (fb_logo.logo->width + 8)) {
 		image.dx = x;
 		info->fbops->fb_imageblit(info, &image);
-		//atomic_dec(&info->pixmap.count);
-		//smp_mb__after_atomic_dec();
 	}
 	
 	if (palette != NULL)
@@ -843,6 +848,15 @@
 }
 #endif /* CONFIG_KMOD */
 
+void
+load_cursor_image(struct fb_info *info)
+{
+	unsigned int width = (info->cursor.image.width + 7) >> 3;
+	u8 *data = (u8 *) info->cursor.image.data;
+
+	info->sprite.outbuf(info, data, info->sprite.addr, width);
+}
+
 int
 fb_cursor(struct fb_info *info, struct fb_cursor *sprite)
 {
@@ -1199,6 +1213,93 @@
 #endif
 };
 
+#define to_fb_info(d) container_of(d, struct fb_info, class_dev)
+
+static void release_fb_info(struct class_device *class_dev)
+{
+	struct fb_info *fb_info = to_fb_info(class_dev);
+
+	/* This doesn't harm */
+	fb_dealloc_cmap(&fb_info->cmap);
+
+	kfree(fb_info);
+}
+
+static struct class fb_class = {
+	.name		= "graphics",
+	.release	= &release_fb_info,
+};
+
+static ssize_t show_dev(struct class_device *class_dev, char *buf)
+{
+	struct fb_info *fb_info = to_fb_info(class_dev);
+	return sprintf(buf, "%u:%u\n", FB_MAJOR, fb_info->node);
+}
+static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL);
+
+static int fb_add_class_device(struct fb_info *fb_info)
+{
+	int retval;
+
+	fb_info->class_dev.class = &fb_class;
+	snprintf(fb_info->class_dev.class_id, BUS_ID_SIZE, "fb%d", fb_info->node);
+	retval = class_device_register(&fb_info->class_dev);
+	if (retval)
+		return retval;
+	return class_device_create_file(&fb_info->class_dev, &class_device_attr_dev);
+}
+
+/**
+ * framebuffer_alloc - creates a new frame buffer info structure
+ *
+ * @size: size of driver private data, can be zero
+ * @dev: pointer to the device for this fb, can be NULL
+ *
+ * Creates a new frame buffer info structure. Also reserves @size bytes
+ * for driver private data (fb_info->par). fb_info->par (if any) will be
+ * aligned to sizeof(long).
+ *
+ * Returns the new structure, or NULL if an error occurred.
+ *
+ */
+struct fb_info *framebuffer_alloc(size_t size, struct device *dev) {
+#define BYTES_PER_LONG (BITS_PER_LONG/8)
+#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
+	struct fb_info *fb_info;
+	char *p;
+	int fb_info_size = sizeof(struct fb_info);
+
+	if (size)
+		fb_info_size += PADDING;
+
+	p = kmalloc(fb_info_size + size, GFP_KERNEL);
+	if (!p)
+		return NULL;
+	memset(p, 0, fb_info_size + size);
+	fb_info = (struct fb_info *)p;
+	fb_info->class_dev.dev = dev;
+
+	if (size)
+		fb_info->par = p + fb_info_size;
+
+	return fb_info;
+#undef PADDING
+#undef BYTES_PER_LONG
+}
+
+/**
+ * framebuffer_release - marks the structure available for freeing
+ *
+ * @fb_info: frame buffer info structure
+ *
+ * Drop the reference count of the class_device embedded in the
+ * framebuffer info structure.
+ *
+ */
+void framebuffer_release(struct fb_info *fb_info) {
+	class_device_put(&fb_info->class_dev);
+}
+
 /**
  *	register_framebuffer - registers a frame buffer device
  *	@fb_info: frame buffer info structure
@@ -1222,6 +1323,9 @@
 			break;
 	fb_info->node = i;
 	
+	if (fb_add_class_device(fb_info))
+		return -EINVAL;
+
 	if (fb_info->pixmap.addr == NULL) {
 		fb_info->pixmap.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
 		if (fb_info->pixmap.addr) {
@@ -1238,10 +1342,27 @@
 		fb_info->pixmap.inbuf = sys_inbuf;
 	spin_lock_init(&fb_info->pixmap.lock);
 
+	if (fb_info->sprite.addr == NULL) {
+		fb_info->sprite.addr = kmalloc(FBPIXMAPSIZE, GFP_KERNEL);
+		if (fb_info->sprite.addr) {
+			fb_info->sprite.size = FBPIXMAPSIZE;
+			fb_info->sprite.buf_align = sizeof(unsigned long);
+			fb_info->sprite.scan_align = sizeof(unsigned long);
+			fb_info->sprite.flags = FB_PIXMAP_IO;
+		}
+	}
+	fb_info->sprite.offset = 0;
+	if (fb_info->sprite.outbuf == NULL)
+		fb_info->sprite.outbuf = sys_outbuf;
+	if (fb_info->sprite.inbuf == NULL)
+		fb_info->sprite.inbuf = sys_inbuf;
+	spin_lock_init(&fb_info->sprite.lock);
+
 	registered_fb[i] = fb_info;
 
 	devfs_mk_cdev(MKDEV(FB_MAJOR, i),
 			S_IFCHR | S_IRUGO | S_IWUGO, "fb/%d", i);
+
 	return 0;
 }
 
@@ -1270,6 +1391,7 @@
 		kfree(fb_info->pixmap.addr);
 	registered_fb[i]=NULL;
 	num_registered_fb--;
+	class_device_del(&fb_info->class_dev);
 	return 0;
 }
 
@@ -1294,6 +1416,8 @@
 	if (register_chrdev(FB_MAJOR,"fb",&fb_fops))
 		printk("unable to get major %d for fb devs\n", FB_MAJOR);
 
+	class_register(&fb_class);
+
 #ifdef CONFIG_FB_OF
 	if (ofonly) {
 		offb_init();
@@ -1377,6 +1501,8 @@
 
 EXPORT_SYMBOL(register_framebuffer);
 EXPORT_SYMBOL(unregister_framebuffer);
+EXPORT_SYMBOL(framebuffer_alloc);
+EXPORT_SYMBOL(framebuffer_release);
 EXPORT_SYMBOL(num_registered_fb);
 EXPORT_SYMBOL(registered_fb);
 EXPORT_SYMBOL(fb_prepare_logo);
@@ -1387,5 +1513,6 @@
 EXPORT_SYMBOL(fb_get_buffer_offset);
 EXPORT_SYMBOL(move_buf_unaligned);
 EXPORT_SYMBOL(move_buf_aligned);
+EXPORT_SYMBOL(load_cursor_image);
 
 MODULE_LICENSE("GPL");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmon.c fbdev-2.6/drivers/video/fbmon.c
--- linus-2.6/drivers/video/fbmon.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/fbmon.c	Thu Oct 16 14:13:31 2003
@@ -566,17 +566,19 @@
 	}
 	refresh = (block[1] & 0x3f) + 60;
 
+	/* First find standard mode from the table of VESA modes */
 	for (i = 0; i < VESA_MODEDB_SIZE; i++) {
 		if (vesa_modes[i].xres == xres && 
 		    vesa_modes[i].yres == yres &&
 		    vesa_modes[i].refresh == refresh) {
 			*mode = vesa_modes[i];
-			break;
-		} else {
-			calc_mode_timings(xres, yres, refresh, mode);
-			break;
+			return 1;
 		}
 	}
+
+	/* If mode is not found in table, calculate it using GTF */
+	calc_mode_timings(xres, yres, refresh, mode);
+
 	return 1;
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/ffb.c fbdev-2.6/drivers/video/ffb.c
--- linus-2.6/drivers/video/ffb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/ffb.c	Thu Oct 16 14:13:31 2003
@@ -359,6 +359,7 @@
 	int			prom_parent_node;
 	int			dac_rev;
 	int			board_type;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -868,12 +869,6 @@
 	return 1;
 }
 
-struct all_info {
-	struct fb_info info;
-	struct ffb_par par;
-	u32 pseudo_palette[256];
-	struct list_head list;
-};
 static LIST_HEAD(ffb_list);
 
 static void ffb_init_one(int node, int parent)
@@ -881,7 +876,8 @@
 	struct linux_prom64_registers regs[2*PROMREG_MAX];
 	struct ffb_fbc *fbc;
 	struct ffb_dac *dac;
-	struct all_info *all;
+	struct fb_info *info;
+	struct ffb_par *par;
 
 	if (prom_getproperty(node, "reg", (void *) regs, sizeof(regs)) <= 0) {
 		printk("ffb: Cannot get reg device node property.\n");
@@ -893,87 +889,86 @@
 		return;
 	}
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct ffb_par) + 32 * 256, NULL);
+	if (!info) {
 		printk(KERN_ERR "ffb: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
-
-	INIT_LIST_HEAD(&all->list);	
-
-	spin_lock_init(&all->par.lock);
-	all->par.fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
-	all->par.dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
-	all->par.rop_cache = FFB_ROP_NEW;
-	all->par.physbase = regs[0].phys_addr;
-	all->par.prom_node = node;
-	all->par.prom_parent_node = parent;
-
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &ffb_ops;
-	all->info.screen_base = (char *) all->par.physbase + FFB_DFB24_POFF;
-	all->info.currcon = -1;
-	all->info.par = &all->par;
-	all->info.pseudo_palette = all->pseudo_palette;
-
-	sbusfb_fill_var(&all->info.var, all->par.prom_node, 32);
-	all->par.fbsize = PAGE_ALIGN(all->info.var.xres *
-				     all->info.var.yres *
+	par = info->par;
+	par->info = info;
+
+	INIT_LIST_HEAD(&par->list);
+
+	spin_lock_init(&par->lock);
+	par->fbc = (struct ffb_fbc *)(regs[0].phys_addr + FFB_FBC_REGS_POFF);
+	par->dac = (struct ffb_dac *)(regs[0].phys_addr + FFB_DAC_POFF);
+	par->rop_cache = FFB_ROP_NEW;
+	par->physbase = regs[0].phys_addr;
+	par->prom_node = node;
+	par->prom_parent_node = parent;
+
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &ffb_ops;
+	info->screen_base = (char *) par->physbase + FFB_DFB24_POFF;
+	info->pseudo_palette = (void *)(par + 1);
+
+	sbusfb_fill_var(&info->var, par->prom_node, 32);
+	par->fbsize = PAGE_ALIGN(info->var.xres *
+				     info->var.yres *
 				     4);
-	ffb_fixup_var_rgb(&all->info.var);
+	ffb_fixup_var_rgb(&info->var);
 
-	all->info.var.accel_flags = FB_ACCELF_TEXT;
+	info->var.accel_flags = FB_ACCELF_TEXT;
 
-	prom_getstring(node, "name", all->par.name, sizeof(all->par.name));
-	if (!strcmp(all->par.name, "SUNW,afb"))
-		all->par.flags |= FFB_FLAG_AFB;
+	prom_getstring(node, "name", par->name, sizeof(par->name));
+	if (!strcmp(par->name, "SUNW,afb"))
+		par->flags |= FFB_FLAG_AFB;
 
-	all->par.board_type = prom_getintdefault(node, "board_type", 0);
+	par->board_type = prom_getintdefault(node, "board_type", 0);
 
-	fbc = all->par.fbc;
+	fbc = par->fbc;
 	if((upa_readl(&fbc->ucsr) & FFB_UCSR_ALL_ERRORS) != 0)
 		upa_writel(FFB_UCSR_ALL_ERRORS, &fbc->ucsr);
 
-	ffb_switch_from_graph(&all->par);
+	ffb_switch_from_graph(par);
 
-	dac = all->par.dac;
+	dac = par->dac;
 	upa_writel(0x8000, &dac->type);
-	all->par.dac_rev = upa_readl(&dac->value) >> 0x1c;
+	par->dac_rev = upa_readl(&dac->value) >> 0x1c;
 
 	/* Elite3D has different DAC revision numbering, and no DAC revisions
 	 * have the reversed meaning of cursor enable.
 	 */
-	if (all->par.flags & FFB_FLAG_AFB)
-		all->par.dac_rev = 10;
+	if (par->flags & FFB_FLAG_AFB)
+		par->dac_rev = 10;
 
 	/* Unblank it just to be sure.  When there are multiple
 	 * FFB/AFB cards in the system, or it is not the OBP
 	 * chosen console, it will have video outputs off in
 	 * the DAC.
 	 */
-	ffb_blank(0, &all->info);
+	ffb_blank(0, info);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "ffb: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	ffb_init_fix(&all->info);
+	ffb_init_fix(info);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "ffb: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &ffb_list);
+	list_add(&par->list, &ffb_list);
 
 	printk("ffb: %s at %016lx type %d DAC %d\n",
-	       ((all->par.flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
-	       regs[0].phys_addr, all->par.board_type, all->par.dac_rev);
+	       ((par->flags & FFB_FLAG_AFB) ? "AFB" : "FFB"),
+	       regs[0].phys_addr, par->board_type, par->dac_rev);
 }
 
 static void ffb_scan_siblings(int root)
@@ -1008,11 +1003,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &ffb_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct ffb_par *par = list_entry(pos, typeof(*par), list);
+
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/g364fb.c fbdev-2.6/drivers/video/g364fb.c
--- linus-2.6/drivers/video/g364fb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/g364fb.c	Thu Oct 16 14:13:31 2003
@@ -127,20 +127,55 @@
 
 int g364fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
+
+	/* Turn the cursor off before we start changing it. */
+	*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
+
+	if (cursor->set & FB_CUR_SETHOT)
+		info->cursor.hot = cursor->hot;
 	
-	switch (cursor->enable) {
-	case CM_ERASE:
-		*(unsigned int *) CTLA_REG |= CURS_TOGGLE;
-		break;
+	if (cursor->set & FB_CUR_SETPOS) {
+		unsigned int tmp;
+
+		info->cursor.image.dx = cursor->image.dx;
+		info->cursor.image.dy = cursor->image.dy;
+
+		tmp = cursor->image.dy - info->var.yoffset;
+		tmp |= (cursor->image.dx - info->var.xoffset) << 12;
+
+		*(unsigned int *) CURS_POS_REG = tmp;
+	}
 
-	case CM_MOVE:
-	case CM_DRAW:
+	if (cursor->set & FB_CUR_SETSIZE) {
+		info->cursor.image.height = cursor->image.height;
+		info->cursor.image.width = cursor->image.width;
+
+	 	/* set the whole cursor to transparent */
+		for (i = 0; i < 512; i++)
+			*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
+	}
+
+	if (cursor->set & FB_CUR_SETCMAP) {
+		volatile unsigned int *curs_pal_ptr =
+	    			(volatile unsigned int *) CURS_PAL_REG;
+
+		/* setup cursor */
+		curs_pal_ptr[0] |= 0x00ffffff;
+		curs_pal_ptr[2] |= 0x00ffffff;
+		curs_pal_ptr[4] |= 0x00ffffff;
+	}
+
+	if (cursor->set & FB_CUR_SETSHAPE) {
+		/*
+	 	 * switch the last two lines to cursor palette 3
+	 	 * we assume here, that FONTSIZE_X is 8
+	 	 */
+		*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
+		*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
+	}
+
+	if (info->cursor.enable)
 		*(unsigned int *) CTLA_REG &= ~CURS_TOGGLE;
-		*(unsigned int *) CURS_POS_REG =
-		    ((x * fontwidth(p)) << 12) | ((y * fontheight(p)) -
-						  info->var.yoffset);
-		break;
-	}
 	return 0;
 }
 
@@ -196,10 +231,6 @@
  */
 int __init g364fb_init(void)
 {
-	volatile unsigned int *pal_ptr =
-	    (volatile unsigned int *) CLR_PAL_REG;
-	volatile unsigned int *curs_pal_ptr =
-	    (volatile unsigned int *) CURS_PAL_REG;
 	int mem, i, j;
 
 	/* TBD: G364 detection */
@@ -212,23 +243,6 @@
 	    (*((volatile unsigned int *) VDISPLAY_REG) & 0x00ffffff) / 2;
 	*(volatile unsigned int *) CTLA_REG |= ENABLE_VTG;
 
-	/* setup cursor */
-	curs_pal_ptr[0] |= 0x00ffffff;
-	curs_pal_ptr[2] |= 0x00ffffff;
-	curs_pal_ptr[4] |= 0x00ffffff;
-
-	/*
-	 * first set the whole cursor to transparent
-	 */
-	for (i = 0; i < 512; i++)
-		*(unsigned short *) (CURS_PAT_REG + i * 8) = 0;
-
-	/*
-	 * switch the last two lines to cursor palette 3
-	 * we assume here, that FONTSIZE_X is 8
-	 */
-	*(unsigned short *) (CURS_PAT_REG + 14 * 64) = 0xffff;
-	*(unsigned short *) (CURS_PAT_REG + 15 * 64) = 0xffff;
 	fb_var.xres_virtual = fbvar.xres;
 	fb_fix.line_length = (xres / 8) * fb_var.bits_per_pixel;
 	fb_fix.smem_start = 0x40000000;	/* physical address */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/Makefile fbdev-2.6/drivers/video/i810/Makefile
--- linus-2.6/drivers/video/i810/Makefile	Thu Oct 16 14:13:37 2003
+++ fbdev-2.6/drivers/video/i810/Makefile	Thu Oct 16 14:13:37 2003
@@ -1,15 +1,8 @@
 #
 # Makefile for the Intel 810/815 framebuffer driver
 #
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
 
 obj-$(CONFIG_FB_I810)		+= i810fb.o
-
 
 i810fb-objs                     := i810_main.o i810_accel.o
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/i810/i810_main.c fbdev-2.6/drivers/video/i810/i810_main.c
--- linus-2.6/drivers/video/i810/i810_main.c	Thu Oct 16 14:13:37 2003
+++ fbdev-2.6/drivers/video/i810/i810_main.c	Thu Oct 16 14:13:37 2003
@@ -1838,20 +1838,12 @@
 	struct i810fb_par *par = NULL;
 	int err, vfreq, hfreq, pixclock;
 
-	if (!(info = kmalloc(sizeof(struct fb_info), GFP_KERNEL))) {
-		i810fb_release_resource(info, par);
+	info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev);
+	if (!info)
 		return -ENOMEM;
-	}
-	memset(info, 0, sizeof(struct fb_info));
-
-	if(!(par = kmalloc(sizeof(struct i810fb_par), GFP_KERNEL))) {
-		i810fb_release_resource(info, par);
-		return -ENOMEM;
-	}
-	memset(par, 0, sizeof(struct i810fb_par));
 
+	par = info->par;
 	par->dev = dev;
-	info->par = par;
 
 	if (!(info->pixmap.addr = kmalloc(64*1024, GFP_KERNEL))) {
 		i810fb_release_resource(info, par);
@@ -1954,8 +1946,6 @@
 
 		if (par->res_flags & PCI_DEVICE_ENABLED)
 			pci_disable_device(par->dev); 
-
-		kfree(par);
 	}
 	if (info) 
 		kfree(info);
@@ -1967,7 +1957,8 @@
 	struct i810fb_par *par = (struct i810fb_par *) info->par;
 
 	unregister_framebuffer(info);  
-	i810fb_release_resource(info, par);
+	i810fb_release_resource(NULL, par);
+	framebuffer_release(info);
 	pci_set_drvdata(dev, NULL);
 	printk("cleanup_module:  unloaded i810 framebuffer device\n");
 }                                                	
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/igafb.c fbdev-2.6/drivers/video/igafb.c
--- linus-2.6/drivers/video/igafb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/igafb.c	Thu Oct 16 14:13:31 2003
@@ -332,7 +332,7 @@
 #endif
 };
 
-static int __init iga_init(struct fb_info *info, struct iga_par *par)
+static int __init iga_init(struct fb_info *info, struct iga_par *par, struct pci_dev *dev)
 {
         char vramsz = iga_inb(par, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL) 
 		                                         & MEM_SIZE_ALIAS;
@@ -358,6 +358,7 @@
 
 	info->fbops = &igafb_ops;
 	info->flags = FBINFO_FLAG_DEFAULT;
+	info->dev = &dev->dev;
 
 	fb_alloc_cmap(info->cmap, video_cmap_len, 0);
 
@@ -529,7 +530,7 @@
 	info->fix = igafb_fix;
 	info->pseudo_palette = (void *)(par + 1);
 
-	if (!iga_init(info, par)) {
+	if (!iga_init(info, par, pdev)) {
 		iounmap((void *)par->io_base);
 		iounmap(info->screen_base);
 		if (par->mmap_map)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/imsttfb.c fbdev-2.6/drivers/video/imsttfb.c
--- linus-2.6/drivers/video/imsttfb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/imsttfb.c	Thu Oct 16 14:13:31 2003
@@ -1348,7 +1348,7 @@
 };
 
 static void __init 
-init_imstt(struct fb_info *info)
+init_imstt(struct fb_info *info, struct pci_dev *pdev)
 {
 	struct imstt_par *par = (struct imstt_par *) info->par;
 	__u32 i, tmp, *ip, *end;
@@ -1442,6 +1442,7 @@
 
 	info->fbops = &imsttfb_ops;
 	info->flags = FBINFO_FLAG_DEFAULT;
+	info->class_dev.dev = &pdev->dev;
 
 	fb_alloc_cmap(&info->cmap, 0, 0);
 
@@ -1509,6 +1510,8 @@
 		default:
 			printk(KERN_INFO "imsttfb: Device 0x%x unknown, "
 					 "contact maintainer.\n", pdev->device);
+			release_mem_region(addr, size);
+			kfree(info);
 			return -ENODEV;
 	}
 
@@ -1520,7 +1523,7 @@
 	par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000);
 	info->par = par;
 	info->pseudo_palette = (void *) (par + 1);
-	init_imstt(info);
+	init_imstt(info, pdev);
 
 	pci_set_drvdata(pdev, info);
 	return 0;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/leo.c fbdev-2.6/drivers/video/leo.c
--- linus-2.6/drivers/video/leo.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/leo.c	Thu Oct 16 14:13:31 2003
@@ -195,6 +195,7 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -487,81 +488,81 @@
 
 static void leo_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct leo_par *par;
 	int linebytes;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(struct leo_par), NULL);
+	if (!info) {
 		printk(KERN_ERR "leo: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
-	all->par.physbase = sdev->reg_addrs[0].phys_addr;
+	par->physbase = sdev->reg_addrs[0].phys_addr;
 
-	sbusfb_fill_var(&all->info.var, sdev->prom_node, 32);
-	leo_fixup_var_rgb(&all->info.var);
+	sbusfb_fill_var(&info->var, sdev->prom_node, 32);
+	leo_fixup_var_rgb(&info->var);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
 #ifdef CONFIG_SPARC32
-	all->info.screen_base = (char *)
+	info->screen_base = (char *)
 		prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
+	if (!info->screen_base)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[0], LEO_OFF_SS0,
 				     0x800000, "leo ram");
 
-	all->par.lc_ss0_usr = (struct leo_lc_ss0_usr *)
+	par->lc_ss0_usr = (struct leo_lc_ss0_usr *)
 		sbus_ioremap(&sdev->resource[0], LEO_OFF_LC_SS0_USR,
 			     0x1000, "leolc ss0usr");
-	all->par.ld_ss0 = (struct leo_ld_ss0 *)
+	par->ld_ss0 = (struct leo_ld_ss0 *)
 		sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS0,
 			     0x1000, "leold ss0");
-	all->par.ld_ss1 = (struct leo_ld_ss1 *)
+	par->ld_ss1 = (struct leo_ld_ss1 *)
 		sbus_ioremap(&sdev->resource[0], LEO_OFF_LD_SS1,
 			     0x1000, "leold ss1");
-	all->par.lx_krn = (struct leo_lx_krn *)
+	par->lx_krn = (struct leo_lx_krn *)
 		sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_KRN,
 			     0x1000, "leolx krn");
-	all->par.cursor = (struct leo_cursor *)
+	par->cursor = (struct leo_cursor *)
 		sbus_ioremap(&sdev->resource[0], LEO_OFF_LX_CURSOR,
 			     sizeof(struct leo_cursor), "leolx cursor");
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &leo_ops;
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &leo_ops;
 
-	leo_init_wids(&all->info);
-	leo_init_hw(&all->info);
+	leo_init_wids(info);
+	leo_init_hw(info);
 
-	leo_blank(0, &all->info);
+	leo_blank(0, info);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "leo: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	leo_init_fix(&all->info);
+	leo_init_fix(info);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "leo: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &leo_list);
+	list_add(&par->list, &leo_list);
 
 	printk("leo: %s at %lx:%lx\n",
 	       sdev->prom_name,
@@ -587,11 +588,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &leo_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct leo_par *par = list_entry(pos, typeof(*par), list);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
+
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/logo/Kconfig fbdev-2.6/drivers/video/logo/Kconfig
--- linus-2.6/drivers/video/logo/Kconfig	Thu Oct 16 14:13:37 2003
+++ fbdev-2.6/drivers/video/logo/Kconfig	Thu Oct 16 14:13:37 2003
@@ -25,7 +25,7 @@
 
 config LOGO_DEC_CLUT224
 	bool "224-color Digital Equipment Corporation Linux logo"
-	depends on LOGO && DECSTATION
+	depends on LOGO && (DECSTATION || ALPHA)
 	default y
 
 config LOGO_MAC_CLUT224
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/logo/Makefile fbdev-2.6/drivers/video/logo/Makefile
--- linus-2.6/drivers/video/logo/Makefile	Thu Oct 16 14:13:37 2003
+++ fbdev-2.6/drivers/video/logo/Makefile	Thu Oct 16 14:13:37 2003
@@ -13,30 +13,36 @@
 obj-$(CONFIG_LOGO_SUPERH_VGA16)		+= logo_superh_vga16.o
 obj-$(CONFIG_LOGO_SUPERH_CLUT224)	+= logo_superh_clut224.o
 
-# Dependencies on generated files need to be listed explicitly
-
-$(obj)/%_mono.o: $(src)/%_mono.c
-
-$(obj)/%_vga16.o: $(src)/%_vga16.c
-
-$(obj)/%_clut224.o: $(src)/%_clut224.c
-
-$(obj)/%_gray256.o: $(src)/%_gray256.c
-
-# How to generate them
+# mono logo's
+$(obj)/logo_linux_mono.o:	$(obj)/logo_linux_mono.c
+$(obj)/logo_superh_mono.o:	$(obj)/logo_superh_mono.c
+
+# vga16 logo's
+$(obj)/logo_linux_vga16.o:	$(obj)/logo_linux_vga16.c
+$(obj)/logo_superh_vga16.o:	$(obj)/logo_superh_vga16.c
+
+# clut224 logo's
+$(obj)/logo_linux_clut224.o:	$(obj)/logo_linux_clut224.c
+$(obj)/logo_dec_clut224.o:	$(obj)/logo_dec_clut224.c
+$(obj)/logo_mac_clut224.o:	$(obj)/logo_mac_clut224.c
+$(obj)/logo_sgi_clut224.o:	$(obj)/logo_sgi_clut224.c
+$(obj)/logo_sun_clut224.o:	$(obj)/logo_sun_clut224.c
+$(obj)/logo_superh_clut224.o:	$(obj)/logo_superh_clut224.c
+
+# Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..."
+quiet_cmd_logo = LOGO    $@
+	cmd_logo = scripts/pnmtologo \
+			-t $(patsubst $*_%,%,$(notdir $(basename $<))) \
+			-n $(notdir $(basename $<)) -o $@ $<
 
 $(obj)/%_mono.c:	$(src)/%_mono.pbm
-		$(objtree)/scripts/pnmtologo -t mono -n $*_mono -o $@ $<
+	$(call cmd,logo)
 
 $(obj)/%_vga16.c:	$(src)/%_vga16.ppm
-		$(objtree)/scripts/pnmtologo -t vga16 -n $*_vga16 -o $@ $<
+	$(call cmd,logo)
 
 $(obj)/%_clut224.c:	$(src)/%_clut224.ppm
-		$(objtree)/scripts/pnmtologo -t clut224 -n $*_clut224 -o $@ $<
-
-$(obj)/%_gray256.c:	$(src)/%_gray256.pgm
-		$(objtree)/scripts/pnmtologo -t gray256 -n $*_gray256 -o $@ $<
-
+	$(call cmd,logo)
 
 # Files generated that shall be removed upon make clean
-clean-files := *_mono.c *_vga16.c *_clut224.c *_gray256.c
+clean-files := *_mono.c *_vga16.c *_clut224.c
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/logo/logo.c fbdev-2.6/drivers/video/logo/logo.c
--- linus-2.6/drivers/video/logo/logo.c	Thu Oct 16 14:13:37 2003
+++ fbdev-2.6/drivers/video/logo/logo.c	Thu Oct 16 14:13:37 2003
@@ -32,8 +32,7 @@
 extern const struct linux_logo logo_superh_vga16;
 extern const struct linux_logo logo_superh_clut224;
 
-
-const struct linux_logo *fb_find_logo(int depth)
+const struct linux_logo *find_logo(int depth)
 {
 	const struct linux_logo *logo = 0;
 
@@ -65,9 +64,14 @@
 		logo = &logo_linux_clut224;
 #endif
 #ifdef CONFIG_LOGO_DEC_CLUT224
+# if defined(CONFIG_MIPS) || defined(CONFIG_MIPS64)
 		/* DEC Linux logo on MIPS/MIPS64 */
 		if (mips_machgroup == MACH_GROUP_DEC)
 			logo = &logo_dec_clut224;
+# else
+		/* Assume DEC Linux logo on ALPHA */
+		logo = &logo_dec_clut224;
+# endif
 #endif
 #ifdef CONFIG_LOGO_MAC_CLUT224
 		/* Macintosh Linux logo on m68k */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/logo/logo_linux_clut224.c fbdev-2.6/drivers/video/logo/logo_linux_clut224.c
--- linus-2.6/drivers/video/logo/logo_linux_clut224.c	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/drivers/video/logo/logo_linux_clut224.c	Wed Oct 15 22:54:37 2003
@@ -0,0 +1,606 @@
+/*
+ *  DO NOT EDIT THIS FILE!
+ *
+ *  It was automatically generated from drivers/video/logo/logo_linux_clut224.ppm
+ *
+ *  Linux logo logo_linux_clut224
+ */
+
+#include <linux/linux_logo.h>
+
+static unsigned char logo_linux_clut224_data[] __initdata = {
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+	0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d, 0x2d, 0x2e, 0x2c, 0x2b,
+	0x2a, 0x25, 0x28, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x24, 0x2a, 0x2c, 0x2f,
+	0x2c, 0x30, 0x30, 0x24, 0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
+	0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x29, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x22, 0x25, 0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c, 0x30, 0x28, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
+	0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x21, 0x31, 0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34, 0x25, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
+	0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x29, 0x20, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x22, 0x26, 0x2c, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22, 0x36, 0x35, 0x31, 0x27,
+	0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x26,
+	0x38, 0x38, 0x35, 0x25, 0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
+	0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+	0x26, 0x2d, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x2d,
+	0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36, 0x36, 0x21, 0x22, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+	0x32, 0x2f, 0x36, 0x36, 0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36, 0x36, 0x36, 0x36, 0x22,
+	0x2f, 0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
+	0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36, 0x23, 0x2f, 0x3b, 0x3c,
+	0x3d, 0x30, 0x25, 0x21, 0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23, 0x3e, 0x3f, 0x40, 0x3a,
+	0x22, 0x36, 0x36, 0x21, 0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
+	0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x20,
+	0x29, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+	0x32, 0x2f, 0x36, 0x2b, 0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
+	0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x31, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
+	0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32, 0x4f, 0x50, 0x21, 0x31,
+	0x51, 0x52, 0x53, 0x36, 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a, 0x4d, 0x21, 0x31, 0x54,
+	0x55, 0x28, 0x30, 0x2b, 0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x20,
+	0x29, 0x20, 0x29, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+	0x2a, 0x38, 0x23, 0x37, 0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
+	0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21, 0x36, 0x36, 0x36, 0x36,
+	0x2e, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
+	0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x36,
+	0x31, 0x47, 0x3b, 0x36, 0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22, 0x40, 0x62, 0x63, 0x5d,
+	0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+	0x27, 0x2f, 0x23, 0x36, 0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
+	0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x33, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
+	0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78, 0x70, 0x71, 0x71, 0x71,
+	0x72, 0x5f, 0x5e, 0x21, 0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79, 0x63, 0x7a, 0x7b, 0x5c,
+	0x66, 0x69, 0x6e, 0x7c, 0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+	0x26, 0x2d, 0x32, 0x24, 0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
+	0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36, 0x21, 0x2b, 0x23, 0x36,
+	0x36, 0x39, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
+	0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89, 0x8a, 0x63, 0x85, 0x8b,
+	0x8c, 0x8d, 0x41, 0x36, 0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
+	0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21, 0x55, 0x8e, 0x8f, 0x8a,
+	0x7d, 0x5e, 0x90, 0x7e, 0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
+	0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31, 0x26, 0x22, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+	0x33, 0x37, 0x25, 0x22, 0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
+	0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c, 0x36, 0x36, 0x33, 0x39,
+	0x21, 0x36, 0x22, 0x51, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
+	0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97, 0x8e, 0x42, 0x50, 0x43,
+	0x47, 0x48, 0x48, 0x98, 0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
+	0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32, 0x4c, 0x4b, 0x50, 0x50,
+	0x50, 0x42, 0x42, 0x50, 0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
+	0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23, 0x2f, 0x2b, 0x24, 0x21,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x32, 0x51,
+	0x32, 0x28, 0x21, 0x98, 0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
+	0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x93, 0x23, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
+	0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b, 0x47, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+	0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48, 0x47,
+	0x46, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x28, 0x51, 0x39,
+	0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x35, 0x51, 0x28, 0x36,
+	0x36, 0x9d, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x28, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x21, 0x24, 0x33, 0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
+	0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48, 0x48, 0x48, 0x48, 0x9b,
+	0x99, 0x99, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
+	0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x30, 0x34, 0x2a, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c, 0x36, 0x36, 0x36, 0x21,
+	0x31, 0x4e, 0x9a, 0x4c, 0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
+	0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93, 0x3f, 0x93, 0x98, 0x28,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
+	0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x23, 0x2a, 0x34, 0x28, 0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
+	0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+	0x52, 0x46, 0x43, 0x93, 0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32, 0x28, 0x21, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
+	0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x9b,
+	0x99, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
+	0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30, 0x26, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x39, 0x2c, 0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36, 0x25, 0x25, 0x36, 0x4d,
+	0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x44, 0x93,
+	0x43, 0x23, 0x36, 0x36, 0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
+	0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
+	0x2a, 0x51, 0x24, 0x36, 0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
+	0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d, 0x35, 0x24, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
+	0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30, 0x35, 0x25, 0x30, 0x36,
+	0x36, 0x36, 0x36, 0x32, 0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a, 0x36, 0x24, 0x4f, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x47, 0x32, 0x30, 0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
+	0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x2a,
+	0x51, 0x28, 0x28, 0x25, 0x36, 0x3a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x9b, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
+	0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36, 0x2e, 0x35, 0x24, 0x21,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
+	0x23, 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x99,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36, 0x36, 0x36, 0x36, 0x32,
+	0x36, 0x36, 0x36, 0x36, 0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36, 0x2e, 0x9b, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x99, 0x99, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x98, 0x36, 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
+	0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x2c, 0x34,
+	0x36, 0x24, 0x28, 0x36, 0x54, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+	0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32, 0x23,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
+	0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x99,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21, 0x36, 0x36, 0x21, 0x26,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+	0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25, 0x52, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x52, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x4f, 0x21, 0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x30, 0x2d, 0x21, 0x36,
+	0x36, 0x32, 0x23, 0x2a, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x4f, 0x99, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x22,
+	0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x2c, 0x39, 0x24,
+	0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x21, 0x28, 0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
+	0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x47,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23, 0x36, 0x36, 0x26, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+	0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31, 0x9b, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x46, 0x22, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x35, 0x39, 0x36, 0x36,
+	0x36, 0x36, 0x26, 0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
+	0x24, 0x27, 0x9f, 0x24, 0x25, 0x28, 0x21, 0x36, 0x36, 0x34, 0x2b, 0x28,
+	0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x21, 0x25, 0x39, 0x4d, 0xa0, 0x84, 0x81, 0x57, 0x21, 0x39,
+	0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x47,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28, 0x23, 0x36, 0x36, 0x36,
+	0x21, 0x28, 0x2c, 0x30, 0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
+	0x2d, 0xa1, 0x7a, 0xa2, 0xa3, 0xa3, 0x7f, 0x22, 0x51, 0x52, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0xa4,
+	0xa5, 0xa5, 0xa6, 0x61, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
+	0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31, 0x4d, 0x91, 0x5b, 0xa2,
+	0xa3, 0xa3, 0xa3, 0x5a, 0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25, 0x83, 0xaa, 0x2c, 0x25,
+	0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x30, 0x35,
+	0x2d, 0x2f, 0x37, 0x4a, 0x60, 0x85, 0xab, 0xac, 0xa3, 0xa3, 0xa3, 0x82,
+	0x86, 0x36, 0x32, 0x3f, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x99,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0xad, 0xa2, 0xa8, 0xae, 0xaf, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x21, 0x57, 0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
+	0x8b, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x5d, 0xb1, 0x36, 0x24,
+	0x53, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x99, 0xad,
+	0x64, 0x5c, 0x8b, 0xb1, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
+	0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+	0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b, 0x7b, 0xa2, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
+	0x9f, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b, 0x64, 0x64, 0xb5, 0x35,
+	0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x31, 0xb6, 0x5b,
+	0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x4b, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63, 0xb9, 0xba, 0x86, 0xba,
+	0xbb, 0x90, 0x5b, 0x64, 0xa2, 0xa2, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x83, 0xaf,
+	0x36, 0x36, 0x36, 0x30, 0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x9a, 0x3f, 0xbd,
+	0x5b, 0x7b, 0xbe, 0x85, 0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa2, 0xa3,
+	0xa3, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
+	0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
+	0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
+	0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xc1,
+	0x37, 0x35, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0xbf, 0x7a,
+	0x7b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36, 0x24, 0x52, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b, 0x76, 0x5b, 0x5b, 0x76,
+	0x7b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
+	0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa8,
+	0x89, 0x9f, 0x36, 0x36, 0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x2f, 0x8f,
+	0x7a, 0x7b, 0xa2, 0xac, 0xa2, 0x64, 0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x5d, 0xc3, 0x2c, 0x26, 0x22, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+	0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x57, 0x27, 0x4d,
+	0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x99, 0x34, 0x9f, 0xb9, 0x7a, 0x7b, 0xa2, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa2, 0xc2, 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0xc2, 0x85,
+	0x7b, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5f, 0x92, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
+	0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0xa2, 0xc0,
+	0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x23, 0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0x66, 0x89, 0x45, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25, 0x36, 0x36, 0x61, 0xb9,
+	0x6d, 0x64, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0xbe, 0xc3, 0x32, 0x28, 0x21, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+	0x33, 0xc4, 0x63, 0xbe, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x72, 0x81, 0xc5,
+	0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
+	0x3f, 0x2c, 0x36, 0x36, 0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2,
+	0xab, 0x8b, 0xb0, 0x2c, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x35, 0x96, 0x75, 0xab,
+	0xa2, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0x81, 0xb9, 0x73, 0x3b, 0x44, 0x9b,
+	0x48, 0x48, 0x48, 0x9b, 0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
+	0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x21, 0x24, 0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa2, 0xa2,
+	0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
+	0xa3, 0x7b, 0x7a, 0xc7, 0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
+	0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0xc8, 0xbb,
+	0x8b, 0x7b, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x64, 0x64,
+	0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28, 0x21, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
+	0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b, 0x76, 0x7b, 0x64, 0x64,
+	0xa2, 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x76, 0x85, 0xb9,
+	0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa2, 0xa3,
+	0xa3, 0xa3, 0xac, 0xa2, 0x64, 0x76, 0xbe, 0x8b, 0xb6, 0xb5, 0x2f, 0x35,
+	0x30, 0x24, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x27, 0x31, 0xcb, 0xc9,
+	0xbb, 0x74, 0x63, 0x90, 0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa2,
+	0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc, 0x79, 0x9f, 0x36, 0x36,
+	0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+	0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64, 0xac, 0xa2, 0x64, 0x7b,
+	0xbe, 0x75, 0x63, 0x96, 0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x21, 0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
+	0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d, 0x5b, 0x7b, 0x7b, 0xab,
+	0x6d, 0x90, 0xb9, 0xcd, 0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
+	0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36, 0x36, 0x21, 0xb4, 0x80,
+	0xc7, 0x7e, 0x6d, 0x76, 0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
+	0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f, 0x41, 0xce, 0xcf, 0x6c,
+	0x80, 0xcc, 0xb9, 0x74, 0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
+	0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
+	0x2d, 0x34, 0x2f, 0x38, 0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
+	0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a, 0x24, 0x22, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22,
+	0x23, 0x24, 0x26, 0x30, 0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
+	0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3, 0x41, 0x34, 0x35, 0x32,
+	0x30, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
+	0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7, 0xc7, 0xbb, 0xcc, 0x6c,
+	0x41, 0x39, 0x27, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
+	0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41, 0xd6, 0xb7, 0x79, 0x79,
+	0x79, 0xca, 0xd7, 0x51, 0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
+	0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23, 0x24, 0x2a, 0x31, 0xd8,
+	0xc8, 0x79, 0xd1, 0x80, 0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x22, 0x23,
+	0x28, 0x25, 0x30, 0x2b, 0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
+	0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
+	0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
+	0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35, 0x2b, 0x2a, 0x26, 0x28,
+	0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x23, 0x28,
+	0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
+	0x23, 0x28, 0x24, 0x24, 0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+	0x20, 0x20, 0x20, 0x20
+};
+
+static unsigned char logo_linux_clut224_clut[] __initdata = {
+	0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x0a, 0x0a, 0x0a, 0x0e, 0x0e, 0x0e,
+	0x16, 0x16, 0x16, 0x1a, 0x1a, 0x1a, 0x1e, 0x1e, 0x1e, 0x22, 0x22, 0x22,
+	0x12, 0x12, 0x12, 0x00, 0x00, 0x01, 0x2a, 0x2a, 0x2a, 0x36, 0x36, 0x36,
+	0x42, 0x42, 0x42, 0x4e, 0x4e, 0x4e, 0x4a, 0x4a, 0x4a, 0x56, 0x56, 0x56,
+	0x26, 0x26, 0x26, 0x46, 0x46, 0x46, 0x2e, 0x2e, 0x2e, 0x32, 0x32, 0x32,
+	0x52, 0x52, 0x52, 0x3a, 0x3a, 0x3a, 0x02, 0x02, 0x06, 0x65, 0x65, 0x65,
+	0x5e, 0x5e, 0x5e, 0x3e, 0x3e, 0x3e, 0x74, 0x74, 0x74, 0x8a, 0x8a, 0x8a,
+	0xa2, 0xa2, 0xa2, 0x9a, 0x9a, 0x9a, 0x86, 0x86, 0x86, 0xc6, 0xc6, 0xc6,
+	0xc3, 0xc3, 0xc3, 0x65, 0x62, 0x59, 0xbb, 0xbb, 0xbb, 0xd2, 0xd2, 0xd2,
+	0xda, 0xda, 0xda, 0xd6, 0xd6, 0xd6, 0xe2, 0xe2, 0xe2, 0xf6, 0xf6, 0xf6,
+	0xfd, 0xfd, 0xfd, 0xae, 0xae, 0xae, 0x7b, 0x7b, 0x7b, 0xdd, 0xdd, 0xdd,
+	0xea, 0xea, 0xea, 0x6a, 0x6a, 0x6a, 0xaa, 0xaa, 0xaa, 0xe7, 0xe7, 0xe7,
+	0xbe, 0xbe, 0xbe, 0x5a, 0x5a, 0x5a, 0xee, 0xee, 0xee, 0x9e, 0x9e, 0x9e,
+	0x95, 0x95, 0x95, 0x80, 0x80, 0x80, 0x76, 0x62, 0x2e, 0x79, 0x5c, 0x08,
+	0x62, 0x4e, 0x0a, 0x36, 0x26, 0x06, 0x9a, 0x72, 0x0a, 0xe2, 0xaa, 0x0b,
+	0xec, 0xba, 0x0b, 0xe1, 0xaf, 0x0f, 0xb8, 0x90, 0x0c, 0xd7, 0xae, 0x0f,
+	0xaf, 0x92, 0x3d, 0x25, 0x1a, 0x09, 0xbc, 0xa4, 0x73, 0xc0, 0x85, 0x09,
+	0xef, 0xb6, 0x0d, 0xea, 0xbe, 0x0a, 0xe8, 0xc3, 0x10, 0xe8, 0xc8, 0x1e,
+	0xf5, 0xcf, 0x2d, 0xf1, 0xd0, 0x13, 0xda, 0xc2, 0x86, 0xd3, 0xce, 0xba,
+	0x79, 0x57, 0x19, 0xdb, 0xa2, 0x0a, 0xf4, 0xd6, 0x36, 0xf6, 0xda, 0x3c,
+	0xf6, 0xda, 0x26, 0xf6, 0xd7, 0x14, 0xe2, 0xb8, 0x0d, 0x3d, 0x2a, 0x06,
+	0xb4, 0x7b, 0x07, 0xce, 0x91, 0x0a, 0xe6, 0xae, 0x0b, 0xee, 0xca, 0x0f,
+	0xf6, 0xda, 0x4a, 0x68, 0x45, 0x06, 0xd8, 0x9e, 0x0a, 0xec, 0xb2, 0x0c,
+	0xf5, 0xd7, 0x2b, 0xc6, 0x9b, 0x0a, 0xc8, 0x90, 0x0b, 0x9c, 0x76, 0x0a,
+	0x89, 0x5c, 0x06, 0xd2, 0xa2, 0x0a, 0xee, 0xbe, 0x0a, 0xcb, 0xa6, 0x11,
+	0xb9, 0x85, 0x0b, 0xd2, 0x96, 0x0a, 0x66, 0x4e, 0x0a, 0x5e, 0x46, 0x1e,
+	0x8b, 0x66, 0x0f, 0xbe, 0x92, 0x0d, 0xa8, 0x7a, 0x0a, 0xd5, 0x9a, 0x0b,
+	0xca, 0x96, 0x22, 0xb6, 0x9d, 0x6a, 0xae, 0x9a, 0x72, 0x9c, 0x6b, 0x0b,
+	0xc5, 0x8a, 0x0b, 0xbe, 0x8e, 0x22, 0xbe, 0xb2, 0x90, 0xca, 0xca, 0xca,
+	0x90, 0x90, 0x90, 0xb2, 0xa6, 0x92, 0x9a, 0x79, 0x3c, 0xa8, 0x7c, 0x2c,
+	0xb6, 0xb6, 0xb6, 0xf2, 0xf2, 0xf2, 0xce, 0xce, 0xce, 0xfa, 0xfa, 0xfa,
+	0xb2, 0xb2, 0xb2, 0x6e, 0x6e, 0x6e, 0xa6, 0xa6, 0xa6, 0x12, 0x0e, 0x06,
+	0x4a, 0x36, 0x0e, 0x8e, 0x86, 0x6a, 0xf2, 0xba, 0x0e, 0xf6, 0xbe, 0x0e,
+	0xf6, 0xe6, 0xbe, 0xee, 0xcc, 0x5b, 0xb5, 0x8e, 0x2c, 0xe4, 0xb8, 0x3e,
+	0xf1, 0xc4, 0x0e, 0x26, 0x1e, 0x0a, 0x9a, 0x8e, 0x5a, 0xea, 0xae, 0x0d,
+	0xf6, 0xba, 0x0e, 0xe0, 0xb2, 0x3e, 0xd2, 0xa6, 0x0a, 0x16, 0x12, 0x06,
+	0x9a, 0x7a, 0x2e, 0x2e, 0x20, 0x06, 0x70, 0x64, 0x4e, 0xd6, 0xaa, 0x36,
+	0x46, 0x2f, 0x06, 0x7c, 0x70, 0x58, 0xb4, 0x85, 0x24, 0x62, 0x46, 0x06,
+	0xd6, 0xa6, 0x3a, 0xa3, 0x6e, 0x08, 0x74, 0x51, 0x08, 0xa7, 0x72, 0x07,
+	0xa2, 0x92, 0x5e, 0xca, 0xa2, 0x45, 0xe0, 0xa6, 0x0a, 0xae, 0x87, 0x32,
+	0xbe, 0x96, 0x2e, 0xce, 0xa2, 0x2a, 0xa3, 0x85, 0x43, 0x8e, 0x7a, 0x48,
+	0x6d, 0x6a, 0x5f, 0x8e, 0x6e, 0x2e, 0x32, 0x22, 0x06, 0xaf, 0x76, 0x06,
+	0x50, 0x36, 0x07, 0x9e, 0x76, 0x24, 0x5b, 0x3c, 0x06, 0x8a, 0x6e, 0x32,
+	0x98, 0x63, 0x06, 0x82, 0x53, 0x06, 0x7a, 0x66, 0x46, 0x82, 0x62, 0x2e,
+	0x56, 0x42, 0x22, 0x7c, 0x50, 0x06, 0x8a, 0x56, 0x06, 0x56, 0x42, 0x1e,
+	0x5e, 0x56, 0x4c, 0x86, 0x56, 0x06, 0x6a, 0x56, 0x3a, 0x52, 0x3e, 0x22,
+	0x59, 0x51, 0x42, 0x64, 0x52, 0x34, 0x5e, 0x56, 0x42
+};
+
+struct linux_logo logo_linux_clut224 __initdata = {
+    .type	= LINUX_LOGO_CLUT224,
+    .width	= 80,
+    .height	= 80,
+    .clutsize	= 187,
+    .clut	= logo_linux_clut224_clut,
+    .data	= logo_linux_clut224_data
+};
+
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/matrox/matroxfb_base.c fbdev-2.6/drivers/video/matrox/matroxfb_base.c
--- linus-2.6/drivers/video/matrox/matroxfb_base.c	Thu Oct 16 14:13:40 2003
+++ fbdev-2.6/drivers/video/matrox/matroxfb_base.c	Thu Oct 16 14:13:40 2003
@@ -1678,7 +1678,6 @@
 	}
 	ACCESS_FBINFO(devflags.ydstorg) = 0;
 
-	ACCESS_FBINFO(fbcon.currcon) = -1;
 	ACCESS_FBINFO(video.base) = video_base_phys;
 	ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
 	if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
@@ -1829,13 +1828,6 @@
 	}
 	printk("fb%d: %s frame buffer device\n",
 	       ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id));
-	if (ACCESS_FBINFO(fbcon.currcon) < 0) {
-		/* there is no console on this fb... but we have to initialize hardware
-		 * until someone tells me what is proper thing to do */
-		printk(KERN_INFO "fb%d: initializing hardware\n",
-			ACCESS_FBINFO(fbcon.node));
-		fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined);
-	}
 	return 0;
 failVideoIO:;
 	matroxfb_g450_shutdown(PMINFO2);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/matrox/matroxfb_crtc2.c fbdev-2.6/drivers/video/matrox/matroxfb_crtc2.c
--- linus-2.6/drivers/video/matrox/matroxfb_crtc2.c	Thu Oct 16 14:13:40 2003
+++ fbdev-2.6/drivers/video/matrox/matroxfb_crtc2.c	Thu Oct 16 14:13:40 2003
@@ -605,6 +605,7 @@
 	m2info->fbcon.flags = FBINFO_FLAG_DEFAULT;
 	m2info->fbcon.currcon = -1;
 	m2info->fbcon.pseudo_palette = m2info->cmap;
+	m2info->fbcon.class_dev.dev = &m2info->primary_dev->pcidev->dev;
 	fb_alloc_cmap(&m2info->fbcon.cmap, 256, 1);
 
 	if (mem < 64)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/modedb.c fbdev-2.6/drivers/video/modedb.c
--- linus-2.6/drivers/video/modedb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/modedb.c	Thu Oct 16 14:13:31 2003
@@ -130,11 +130,11 @@
 	0, FB_VMODE_NONINTERLACED   	
     }, {
 	/* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
-	"LCD_XGA_75", 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
+	NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3,
 	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
     }, {
 	/* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
-	"LCD_XGA_60", 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
+	NULL, 60, 1400, 1050, 9259, 128, 40, 12, 0, 112, 3,
 	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
     }, {
 	/* 1024x768 @ 85 Hz, 70.24 kHz hsync */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/neofb.c fbdev-2.6/drivers/video/neofb.c
--- linus-2.6/drivers/video/neofb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/neofb.c	Thu Oct 16 14:13:31 2003
@@ -81,9 +81,10 @@
 #include <asm/mtrr.h>
 #endif
 
+#include <video/vga.h>
 #include <video/neomagic.h>
 
-#define NEOFB_VERSION "0.4.1"
+#define NEOFB_VERSION "0.4.2"
 
 /* --------------------------------------------------------------------- */
 
@@ -152,6 +153,16 @@
 };
 #endif
 
+static inline u32 read_le32(int regindex, const struct neofb_par *par)
+{
+	return readl(par->neo2200 + par->cursorOff + regindex);
+}
+
+static inline void write_le32(int regindex, u32 val, const struct neofb_par *par)
+{
+	writel(val, par->neo2200 + par->cursorOff + regindex);
+}
+
 static int neoFindMode(int xres, int yres, int depth)
 {
 	int xres_s;
@@ -363,44 +374,61 @@
 	par->Attribute[18] = 0x0F;
 	par->Attribute[19] = 0x00;
 	par->Attribute[20] = 0x00;
-
 	return 0;
 }
 
-static void vgaHWLock(void)
+static void vgaHWLock(struct vgastate *state)
 {
 	/* Protect CRTC[0-7] */
-	VGAwCR(0x11, VGArCR(0x11) | 0x80);
+	vga_wcrt(state->vgabase, 0x11, vga_rcrt(state->vgabase, 0x11) | 0x80);
 }
 
 static void vgaHWUnlock(void)
 {
 	/* Unprotect CRTC[0-7] */
-	VGAwCR(0x11, VGArCR(0x11) & ~0x80);
+	vga_wcrt(NULL, 0x11, vga_rcrt(NULL, 0x11) & ~0x80);
 }
 
-static void neoLock(void)
+static void neoLock(struct vgastate *state)
 {
-	VGAwGR(0x09, 0x00);
-	vgaHWLock();
+	vga_wgfx(state->vgabase, 0x09, 0x00);
+	vgaHWLock(state);
 }
 
 static void neoUnlock(void)
 {
 	vgaHWUnlock();
-	VGAwGR(0x09, 0x26);
+	vga_wgfx(NULL, 0x09, 0x26);
 }
 
 /*
- * vgaHWSeqReset
- *      perform a sequencer reset.
+ * VGA Palette management
  */
-void vgaHWSeqReset(int start)
+static int paletteEnabled = 0;
+
+inline void VGAenablePalette(void)
 {
-	if (start)
-		VGAwSEQ(0x00, 0x01);	/* Synchronous Reset */
+	vga_r(NULL, VGA_IS1_RC);
+	vga_w(NULL, VGA_ATT_W, 0x00);
+	paletteEnabled = 1;
+}
+
+inline void VGAdisablePalette(void)
+{
+	vga_r(NULL, VGA_IS1_RC);
+	vga_w(NULL, VGA_ATT_W, 0x20);
+	paletteEnabled = 0;
+}
+
+inline void VGAwATTR(u8 index, u8 value)
+{
+	if (paletteEnabled)
+		index &= ~0x20;
 	else
-		VGAwSEQ(0x00, 0x03);	/* End Reset */
+		index |= 0x20;
+
+	vga_r(NULL, VGA_IS1_RC);
+	vga_wattr(NULL, index, value);
 }
 
 void vgaHWProtect(int on)
@@ -411,21 +439,18 @@
 		/*
 		 * Turn off screen and disable sequencer.
 		 */
-		tmp = VGArSEQ(0x01);
-
-		vgaHWSeqReset(1);	/* start synchronous reset */
-		VGAwSEQ(0x01, tmp | 0x20);	/* disable the display */
+		tmp = vga_rseq(NULL, 0x01);
+		vga_wseq(NULL, 0x00, 0x01);		/* Synchronous Reset */
+		vga_wseq(NULL, 0x01, tmp | 0x20);	/* disable the display */
 
 		VGAenablePalette();
 	} else {
 		/*
 		 * Reenable sequencer, then turn on screen.
 		 */
-
-		tmp = VGArSEQ(0x01);
-
-		VGAwSEQ(0x01, tmp & ~0x20);	/* reenable display */
-		vgaHWSeqReset(0);	/* clear synchronousreset */
+		tmp = vga_rseq(NULL, 0x01);
+		vga_wseq(NULL, 0x01, tmp & ~0x20);	/* reenable display */
+		vga_wseq(NULL, 0x00, 0x03);		/* clear synchronousreset */
 
 		VGAdisablePalette();
 	}
@@ -436,19 +461,19 @@
 {
 	int i;
 
-	VGAwMISC(par->MiscOutReg);
+	vga_w(NULL, VGA_MIS_W, par->MiscOutReg);
 
 	for (i = 1; i < 5; i++)
-		VGAwSEQ(i, par->Sequencer[i]);
+		vga_wseq(NULL, i, par->Sequencer[i]);
 
 	/* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 or CRTC[17] */
-	VGAwCR(17, par->CRTC[17] & ~0x80);
+	vga_wcrt(NULL, 17, par->CRTC[17] & ~0x80);
 
 	for (i = 0; i < 25; i++)
-		VGAwCR(i, par->CRTC[i]);
+		vga_wcrt(NULL, i, par->CRTC[i]);
 
 	for (i = 0; i < 9; i++)
-		VGAwGR(i, par->Graphics[i]);
+		vga_wgfx(NULL, i, par->Graphics[i]);
 
 	VGAenablePalette();
 
@@ -535,6 +560,36 @@
 /* --------------------------------------------------------------------- */
 
 static int
+neofb_open(struct fb_info *info, int user)
+{
+	struct neofb_par *par = (struct neofb_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (cnt) {
+		memset(&par->state, 0, sizeof(struct vgastate));
+		par->state.flags = VGA_SAVE_MODE | VGA_SAVE_FONTS;
+		save_vga(&par->state);
+	}
+	atomic_inc(&par->ref_count);
+	return 0;
+}
+
+static int
+neofb_release(struct fb_info *info, int user)
+{
+	struct neofb_par *par = (struct neofb_par *) info->par;
+	int cnt = atomic_read(&par->ref_count);
+
+	if (!cnt)
+		return -EINVAL;
+	if (cnt == 1) {
+		restore_vga(&par->state);
+	}
+	atomic_dec(&par->ref_count);
+	return 0;
+}
+
+static int
 neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
@@ -981,13 +1036,13 @@
 	}
 
 	/* alread unlocked above */
-	/* BOGUS  VGAwGR (0x09, 0x26); */
+	/* BOGUS  vga_wgfx(NULL, 0x09, 0x26); */
 
 	/* don't know what this is, but it's 0 from bootup anyway */
-	VGAwGR(0x15, 0x00);
+	vga_wgfx(NULL, 0x15, 0x00);
 
 	/* was set to 0x01 by my bios in text and vesa modes */
-	VGAwGR(0x0A, par->GeneralLockReg);
+	vga_wgfx(NULL, 0x0A, par->GeneralLockReg);
 
 	/*
 	 * The color mode needs to be set before calling vgaHWRestore
@@ -996,7 +1051,7 @@
 	 * NOTE: Make sure we don't change bits make sure we don't change
 	 * any reserved bits.
 	 */
-	temp = VGArGR(0x90);
+	temp = vga_rgfx(NULL, 0x90);
 	switch (info->fix.accel) {
 	case FB_ACCEL_NEOMAGIC_NM2070:
 		temp &= 0xF0;	/* Save bits 7:4 */
@@ -1015,7 +1070,7 @@
 		break;
 	}
 
-	VGAwGR(0x90, temp);
+	vga_wgfx(NULL, 0x90, temp);
 
 	/*
 	 * In some rare cases a lockup might occur if we don't delay
@@ -1027,9 +1082,9 @@
 	 * Disable horizontal and vertical graphics and text expansions so
 	 * that vgaHWRestore works properly.
 	 */
-	temp = VGArGR(0x25);
+	temp = vga_rgfx(NULL, 0x25);
 	temp &= 0x39;
-	VGAwGR(0x25, temp);
+	vga_wgfx(NULL, 0x25, temp);
 
 	/*
 	 * Sleep for 200ms to make sure that the two operations above have
@@ -1041,19 +1096,18 @@
 	 * This function handles restoring the generic VGA registers.  */
 	vgaHWRestore(info, par);
 
-
-	VGAwGR(0x0E, par->ExtCRTDispAddr);
-	VGAwGR(0x0F, par->ExtCRTOffset);
-	temp = VGArGR(0x10);
+	vga_wgfx(NULL, 0x0E, par->ExtCRTDispAddr);
+	vga_wgfx(NULL, 0x0F, par->ExtCRTOffset);
+	temp = vga_rgfx(NULL, 0x10);
 	temp &= 0x0F;		/* Save bits 3:0 */
 	temp |= (par->SysIfaceCntl1 & ~0x0F);	/* VESA Bios sets bit 1! */
-	VGAwGR(0x10, temp);
+	vga_wgfx(NULL, 0x10, temp);
 
-	VGAwGR(0x11, par->SysIfaceCntl2);
-	VGAwGR(0x15, 0 /*par->SingleAddrPage */ );
-	VGAwGR(0x16, 0 /*par->DualAddrPage */ );
+	vga_wgfx(NULL, 0x11, par->SysIfaceCntl2);
+	vga_wgfx(NULL, 0x15, 0 /*par->SingleAddrPage */ );
+	vga_wgfx(NULL, 0x16, 0 /*par->DualAddrPage */ );
 
-	temp = VGArGR(0x20);
+	temp = vga_rgfx(NULL, 0x20);
 	switch (info->fix.accel) {
 	case FB_ACCEL_NEOMAGIC_NM2070:
 		temp &= 0xFC;	/* Save bits 7:2 */
@@ -1074,79 +1128,78 @@
 		temp |= (par->PanelDispCntlReg1 & ~0x98);
 		break;
 	}
-	VGAwGR(0x20, temp);
+	vga_wgfx(NULL, 0x20, temp);
 
-	temp = VGArGR(0x25);
+	temp = vga_rgfx(NULL, 0x25);
 	temp &= 0x38;		/* Save bits 5:3 */
 	temp |= (par->PanelDispCntlReg2 & ~0x38);
-	VGAwGR(0x25, temp);
+	vga_wgfx(NULL, 0x25, temp);
 
 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
-		temp = VGArGR(0x30);
+		temp = vga_rgfx(NULL, 0x30);
 		temp &= 0xEF;	/* Save bits 7:5 and bits 3:0 */
 		temp |= (par->PanelDispCntlReg3 & ~0xEF);
-		VGAwGR(0x30, temp);
+		vga_wgfx(NULL, 0x30, temp);
 	}
 
-	VGAwGR(0x28, par->PanelVertCenterReg1);
-	VGAwGR(0x29, par->PanelVertCenterReg2);
-	VGAwGR(0x2a, par->PanelVertCenterReg3);
+	vga_wgfx(NULL, 0x28, par->PanelVertCenterReg1);
+	vga_wgfx(NULL, 0x29, par->PanelVertCenterReg2);
+	vga_wgfx(NULL, 0x2a, par->PanelVertCenterReg3);
 
 	if (info->fix.accel != FB_ACCEL_NEOMAGIC_NM2070) {
-		VGAwGR(0x32, par->PanelVertCenterReg4);
-		VGAwGR(0x33, par->PanelHorizCenterReg1);
-		VGAwGR(0x34, par->PanelHorizCenterReg2);
-		VGAwGR(0x35, par->PanelHorizCenterReg3);
+		vga_wgfx(NULL, 0x32, par->PanelVertCenterReg4);
+		vga_wgfx(NULL, 0x33, par->PanelHorizCenterReg1);
+		vga_wgfx(NULL, 0x34, par->PanelHorizCenterReg2);
+		vga_wgfx(NULL, 0x35, par->PanelHorizCenterReg3);
 	}
 
 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2160)
-		VGAwGR(0x36, par->PanelHorizCenterReg4);
+		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
 
 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
-		VGAwGR(0x36, par->PanelHorizCenterReg4);
-		VGAwGR(0x37, par->PanelVertCenterReg5);
-		VGAwGR(0x38, par->PanelHorizCenterReg5);
+		vga_wgfx(NULL, 0x36, par->PanelHorizCenterReg4);
+		vga_wgfx(NULL, 0x37, par->PanelVertCenterReg5);
+		vga_wgfx(NULL, 0x38, par->PanelHorizCenterReg5);
 
 		clock_hi = 1;
 	}
 
 	/* Program VCLK3 if needed. */
-	if (par->ProgramVCLK && ((VGArGR(0x9B) != par->VCLK3NumeratorLow)
-				 || (VGArGR(0x9F) != par->VCLK3Denominator)
-				 || (clock_hi && ((VGArGR(0x8F) & ~0x0f)
-						  != (par->
-						      VCLK3NumeratorHigh &
+	if (par->ProgramVCLK && ((vga_rgfx(NULL, 0x9B) != par->VCLK3NumeratorLow)
+				 || (vga_rgfx(NULL, 0x9F) != par->VCLK3Denominator)
+				 || (clock_hi && ((vga_rgfx(NULL, 0x8F) & ~0x0f)
+						  != (par->VCLK3NumeratorHigh &
 						      ~0x0F))))) {
-		VGAwGR(0x9B, par->VCLK3NumeratorLow);
+		vga_wgfx(NULL, 0x9B, par->VCLK3NumeratorLow);
 		if (clock_hi) {
-			temp = VGArGR(0x8F);
+			temp = vga_rgfx(NULL, 0x8F);
 			temp &= 0x0F;	/* Save bits 3:0 */
 			temp |= (par->VCLK3NumeratorHigh & ~0x0F);
-			VGAwGR(0x8F, temp);
+			vga_wgfx(NULL, 0x8F, temp);
 		}
-		VGAwGR(0x9F, par->VCLK3Denominator);
+		vga_wgfx(NULL, 0x9F, par->VCLK3Denominator);
 	}
 
 	if (par->biosMode)
-		VGAwCR(0x23, par->biosMode);
+		vga_wcrt(NULL, 0x23, par->biosMode);
 
-	VGAwGR(0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
+	vga_wgfx(NULL, 0x93, 0xc0);	/* Gives 5x faster framebuffer writes !!! */
 
 	/* Program vertical extension register */
 	if (info->fix.accel == FB_ACCEL_NEOMAGIC_NM2200 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2230 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2360 ||
 	    info->fix.accel == FB_ACCEL_NEOMAGIC_NM2380) {
-		VGAwCR(0x70, par->VerticalExt);
+		vga_wcrt(NULL, 0x70, par->VerticalExt);
 	}
 
 	vgaHWProtect(0);	/* Turn on screen */
 
 	/* Calling this also locks offset registers required in update_start */
-	neoLock();
+	neoLock(&par->state);
 
 	info->fix.line_length =
 	    info->var.xres_virtual * (info->var.bits_per_pixel >> 3);
@@ -1167,6 +1220,8 @@
 static void neofb_update_start(struct fb_info *info,
 			       struct fb_var_screeninfo *var)
 {
+	struct neofb_par *par = (struct neofb_par *) info->par;
+	struct vgastate *state = &par->state;
 	int oldExtCRTDispAddr;
 	int Base;
 
@@ -1180,18 +1235,18 @@
 	/*
 	 * These are the generic starting address registers.
 	 */
-	VGAwCR(0x0C, (Base & 0x00FF00) >> 8);
-	VGAwCR(0x0D, (Base & 0x00FF));
+	vga_wcrt(state->vgabase, 0x0C, (Base & 0x00FF00) >> 8);
+	vga_wcrt(state->vgabase, 0x0D, (Base & 0x00FF));
 
 	/*
 	 * Make sure we don't clobber some other bits that might already
 	 * have been set. NOTE: NM2200 has a writable bit 3, but it shouldn't
 	 * be needed.
 	 */
-	oldExtCRTDispAddr = VGArGR(0x0E);
-	VGAwGR(0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
+	oldExtCRTDispAddr = vga_rgfx(NULL, 0x0E);
+	vga_wgfx(state->vgabase, 0x0E, (((Base >> 16) & 0x0f) | (oldExtCRTDispAddr & 0xf0)));
 
-	neoLock();
+	neoLock(state);
 }
 
 /*
@@ -1353,7 +1408,7 @@
 	}
 
 	par->neo2200->dstStart =
-	    dst * ((info->var.bits_per_pixel + 7) / 8);
+	    dst * ((info->var.bits_per_pixel + 7) >> 3);
 	par->neo2200->xyExt =
 	    (rect->height << 16) | (rect->width & 0xffff);
 }
@@ -1361,26 +1416,22 @@
 static void
 neo2200_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-	struct neofb_par *par = (struct neofb_par *) info->par;
 	u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
+	struct neofb_par *par = (struct neofb_par *) info->par;
 	u_long src, dst, bltCntl;
-
+
 	bltCntl = NEO_BC3_FIFO_EN | NEO_BC3_SKIP_MAPPING | 0x0C0000;
 
-	if (sy < dy) {
+	if ((dy > sy) || ((dy == sy) && (dx > sx))) {
+		/* Start with the lower right corner */
 		sy += (area->height - 1);
 		dy += (area->height - 1);
-
-		bltCntl |= NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
-	}
-
-	if (area->sx < area->dx) {
 		sx += (area->width - 1);
-		dx += (area->width - 1);
-
-		bltCntl |= NEO_BC0_X_DEC;
-	}
-
+		dx += (area->width - 1);
+
+		bltCntl |= NEO_BC0_X_DEC | NEO_BC0_DST_Y_DEC | NEO_BC0_SRC_Y_DEC;
+	}
+
 	src = sx * (info->var.bits_per_pixel >> 3) + sy*info->fix.line_length;
 	dst = dx * (info->var.bits_per_pixel >> 3) + dy*info->fix.line_length;
 
@@ -1496,8 +1547,60 @@
 	return 0;		
 }
 
+static int
+neofb_cursor(struct fb_info *info, struct fb_cursor *cursor)
+{
+	struct neofb_par *par = (struct neofb_par *) info->par;
+
+	/* Disable cursor */
+	write_le32(NEOREG_CURSCNTL, ~NEO_CURS_ENABLE, par);
+
+	if (cursor->set & FB_CUR_SETPOS) {
+		u32 x = cursor->image.dx;
+		u32 y = cursor->image.dy;
+
+		info->cursor.image.dx = x;
+		info->cursor.image.dy = y;
+		write_le32(NEOREG_CURSX, x, par);
+		write_le32(NEOREG_CURSY, y, par);
+	}
+
+	if (cursor->set & FB_CUR_SETSIZE) {
+	}
+
+	if (cursor->set & FB_CUR_SETCMAP) {
+		if (cursor->image.depth == 1) {
+			u32 fg = cursor->image.fg_color;
+			u32 bg = cursor->image.bg_color;
+
+			info->cursor.image.fg_color = fg;
+			info->cursor.image.bg_color = bg;
+
+			fg = ((fg & 0xff0000) >> 16) | ((fg & 0xff) << 16) | (fg & 0xff00);
+			bg = ((bg & 0xff0000) >> 16) | ((bg & 0xff) << 16) | (bg & 0xff00);
+			write_le32(NEOREG_CURSFGCOLOR, fg, par);
+			write_le32(NEOREG_CURSBGCOLOR, bg, par);
+		}
+	}
+
+	if (cursor->set & FB_CUR_SETSHAPE) {
+		unsigned long dest = (unsigned long) par->cursorPad;
+		int i, j;
+
+		//memset_io(par->cursorPad, 0xff, 1);
+		//write_le32(NEOREG_CURSMEMPOS, ((0x000f & (dest >> 10)) << 8) |
+		//		((0x0ff0 & (dest >> 10)) >> 4), par);
+	}
+
+	if (info->cursor.enable)
+		write_le32(NEOREG_CURSCNTL, NEO_CURS_ENABLE, par);
+	return 0;
+}
+
 static struct fb_ops neofb_ops = {
 	.owner		= THIS_MODULE,
+	.fb_open	= neofb_open,
+	.fb_release	= neofb_release,
 	.fb_check_var	= neofb_check_var,
 	.fb_set_par	= neofb_set_par,
 	.fb_setcolreg	= neofb_setcolreg,
@@ -1507,7 +1610,7 @@
 	.fb_fillrect	= neofb_fillrect,
 	.fb_copyarea	= neofb_copyarea,
 	.fb_imageblit	= neofb_imageblit,
-	.fb_cursor	= soft_cursor,
+	.fb_cursor	= neofb_cursor,
 };
 
 /* --------------------------------------------------------------------- */
@@ -1650,7 +1753,8 @@
 				   struct pci_dev *dev, int video_len)
 {
 	struct neofb_par *par = (struct neofb_par *) info->par;
-
+	unsigned long addr;
+
 	DBG("neo_map_video");
 
 	info->fix.smem_start = pci_resource_start(dev, 0);
@@ -1681,6 +1785,10 @@
 
 	/* Clear framebuffer, it's all white in memory after boot */
 	memset(info->screen_base, 0, info->fix.smem_len);
+
+	/* Allocate Cursor drawing pad. */
+	addr = info->fix.smem_start + info->fix.smem_len;
+	par->cursorPad = (u8 *) ioremap(addr, info->sprite.size);
 	return 0;
 }
 
@@ -1725,16 +1833,16 @@
 	printk(KERN_DEBUG "--- Neo extended register dump ---\n");
 	for (w = 0; w < 0x85; w++)
 		printk(KERN_DEBUG "CR %p: %p\n", (void *) w,
-		       (void *) VGArCR(w));
+		       (void *) vga_rcrt(NULL, w);
 	for (w = 0; w < 0xC7; w++)
 		printk(KERN_DEBUG "GR %p: %p\n", (void *) w,
-		       (void *) VGArGR(w));
+		       (void *) vga_rgfx(NULL, w));
 #endif
 
 	/* Determine the panel type */
-	VGAwGR(0x09, 0x26);
-	type = VGArGR(0x21);
-	display = VGArGR(0x20);
+	vga_wgfx(NULL, 0x09, 0x26);
+	type = vga_rgfx(NULL, 0x21);
+	display = vga_rgfx(NULL, 0x20);
 	if (!par->internal_display && !par->external_display) {
 		par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
 		par->external_display = display & 1;
@@ -1744,8 +1852,8 @@
 	}
 
 	/* Determine panel width -- used in NeoValidMode. */
-	w = VGArGR(0x20);
-	VGAwGR(0x09, 0x00);
+	w = vga_rgfx(NULL, 0x20);
+	vga_wgfx(NULL, 0x09, 0x00);
 	switch ((w & 0x18) >> 3) {
 	case 0x00:
 		par->NeoPanelWidth = 640;
@@ -1870,10 +1978,20 @@
 		par->neo2200 = (Neo2200 *) par->mmio_vbase;
 		break;
 	}
-
+	info->sprite.size = CursorMem;
+	info->sprite.addr = kmalloc(CursorMem, GFP_KERNEL);
+	info->sprite.scan_align = 1;
+	info->sprite.buf_align = 1;
+	info->sprite.flags = FB_PIXMAP_IO;
 	par->maxClock = maxClock;
-
-	return videoRam * 1024;
+	par->cursorOff = CursorOff;
+	/*
+	 * We decrease the size of the framebuffer by a page
+	 * instead of the size of the cursor pad to avoid
+	 * userland being able to page fault the cursor
+	 * region and start drawing in it.
+	 */
+	return ((videoRam * 1024) - PAGE_SIZE);
 }
 
 
@@ -1883,15 +2001,12 @@
 	struct fb_info *info;
 	struct neofb_par *par;
 
-	info = kmalloc(sizeof(struct fb_info) + sizeof(struct neofb_par) + 
-		       sizeof(u32) * 17, GFP_KERNEL);
+	info = framebuffer_alloc(sizeof(struct neofb_par) + sizeof(u32) * 17, &dev->dev);
 
 	if (!info)
 		return NULL;
 
-	memset(info, 0, sizeof(struct fb_info) + sizeof(struct neofb_par) + sizeof(u32) * 17);
-
-	par = (struct neofb_par *) (info + 1);
+	par = info->par;
 
 	info->fix.accel = id->driver_data;
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/p9100.c fbdev-2.6/drivers/video/p9100.c
--- linus-2.6/drivers/video/p9100.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/p9100.c	Thu Oct 16 14:13:31 2003
@@ -138,6 +138,7 @@
 	unsigned long		fbsize;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -269,65 +270,65 @@
 
 static void p9100_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct p9100_par *par;
 	int linebytes;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(*par), NULL);
+	if (!info) {
 		printk(KERN_ERR "p9100: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
 	/* This is the framebuffer and the only resource apps can mmap.  */
-	all->par.physbase = sdev->reg_addrs[2].phys_addr;
+	par->physbase = sdev->reg_addrs[2].phys_addr;
 
 	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
-	all->par.regs = (struct p9100_regs *)
+	par->regs = (struct p9100_regs *)
 		sbus_ioremap(&sdev->resource[0], 0,
 			     sizeof(struct p9100_regs), "p9100 regs");
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &p9100_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &p9100_ops;
 #ifdef CONFIG_SPARC32
-	all->info.screen_base = (char *)
+	info->screen_base = (char *)
 		prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
+	if (!info->screen_base)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[2], 0,
-				     all->par.fbsize, "p9100 ram");
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+				     par->fbsize, "p9100 ram");
 
-	p9100_blank(0, &all->info);
+	p9100_blank(0, info);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "p9100: Could not allocate color map.\n");
 		kfree(all);
 		return;
 	}
 
-	p9100_init_fix(&all->info, linebytes);
+	p9100_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "p9100: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &p9100_list);
+	list_add(&par->list, &p9100_list);
 
 	printk("p9100: %s at %lx:%lx\n",
 	       sdev->prom_name,
@@ -353,11 +354,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &p9100_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct p9100_par *par = list_entry(pos, typeof(*par), list);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
+
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/pm2fb.c fbdev-2.6/drivers/video/pm2fb.c
--- linus-2.6/drivers/video/pm2fb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/pm2fb.c	Thu Oct 16 14:13:31 2003
@@ -1,25 +1,30 @@
 /*
  * Permedia2 framebuffer driver.
+ *
+ * 2.5/2.6 driver:
+ * Copyright (c) 2003 Jim Hague (jim.hague@acm.org)
+ *
+ * based on 2.4 driver:
  * Copyright (c) 1998-2000 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
  * Copyright (c) 1999 Jakub Jelinek (jakub@redhat.com)
- * Based on linux/drivers/video/skeletonfb.c by Geert Uytterhoeven.
- * --------------------------------------------------------------------------
- * $Id: pm2fb.c,v 1.213 2000/09/19 01:03:19 illo Exp $
- * --------------------------------------------------------------------------
- * History:
- *  1999/05/09 added Jim Hague's 'var' kernel option (thanks Jim!)
- *  2002/04/23 Jim Hague <jim.hague@acm.org>
- *	* Integrated Illo's last changes, No changelist available.
- *	  Major items: acceleration support, hardware cursor code
- *	  (not yet enabled).
- *	* Fixed -vsync, added lowhsync/lowvsync overrides for use with
- *	  XFree GLINT driver.
- * --------------------------------------------------------------------------
- * TODO multiple boards support
- * --------------------------------------------------------------------------
+ *
+ * and additional input from James Simmon's port of Hannu Mallat's tdfx
+ * driver.
+ *
+ * $Id$
+ *
+ * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86.
+ * I have no access to other pm2fb implementations, and cannot test
+ * on them. Therefore for now I am omitting Sparc and CVision code.
+ *
+ * Multiple boards support has been on the TODO list for ages.
+ * Don't expect this to change.
+ *
  * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive
- * for more details.
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ *
+ *
  */
 
 #include <linux/config.h>
@@ -30,43 +35,24 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/slab.h>
-#include <linux/vmalloc.h>
 #include <linux/delay.h>
-#include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
-#include <linux/console.h>
 #include <linux/init.h>
 #include <linux/pci.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <video/fbcon.h>
-#include <video/fbcon-cfb8.h>
-#include <video/fbcon-cfb16.h>
-#include <video/fbcon-cfb24.h>
-#include <video/fbcon-cfb32.h>
+
 #include <video/pm2fb.h>
-#include "cvisionppc.h"
-#ifdef __sparc__
-#include <asm/pbm.h>
-#include <asm/fbio.h>
-#endif
+#include <video/cvisionppc.h>
 
 #if !defined(__LITTLE_ENDIAN) && !defined(__BIG_ENDIAN)
 #error	"The endianness of the target host has not been defined."
 #endif
 
-#if defined(__BIG_ENDIAN) && !defined(__sparc__) && (!defined(CONFIG_PPC) || defined(CONFIG_FB_PM2_CVPPC))
+#if defined(__BIG_ENDIAN) && !defined(__sparc__)
 #define PM2FB_BE_APERTURE
 #endif
 
-/* Need to debug this some more */
-#undef PM2FB_HW_CURSOR
-
-#if defined(CONFIG_FB_PM2_PCI) && !defined(CONFIG_PCI)
-#undef CONFIG_FB_PM2_PCI
-#warning "support for Permedia2 PCI boards with no generic PCI support!"
+#if !defined(CONFIG_PCI)
+#error "Only generic PCI cards supported."
 #endif
 
 #undef PM2FB_MASTER_DEBUG
@@ -74,22 +60,9 @@
 #define DPRINTK(a,b...)	printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
 #else
 #define DPRINTK(a,b...)
-#endif 
-
-#define PICOS2KHZ(a) (1000000000UL/(a))
-#define KHZ2PICOS(a) (1000000000UL/(a))
-
-/*
- * The _DEFINITIVE_ memory mapping/unmapping functions.
- * This is due to the fact that they're changing soooo often...
- */
-#define MMAP(a,b)	ioremap((unsigned long )(a), b)
-#define UNMAP(a,b)	iounmap(a)
+#endif
 
-/*
- * The _DEFINITIVE_ memory i/o barrier functions.
- * This is due to the fact that they're changing soooo often...
- */
+/* Memory barriers. */
 #ifdef __mc68000__
 #define DEFW()
 #define DEFR()
@@ -100,356 +73,105 @@
 #define DEFRW()		mb()
 #endif
 
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-#define VIDEO_MASK	0x00011e7f	/* r/w values for VIDEO_CONTROL */
-
-#define PM2FF_ACCEL		(1L<<0)
-
-struct pm2fb_par {
-	u32 pixclock;		/* pixclock in KHz */
-	u32 width;		/* width of virtual screen */
-	u32 height;		/* height of virtual screen */
-	u32 hsstart;		/* horiz. sync start */
-	u32 hsend;		/* horiz. sync end */
-	u32 hbend;		/* horiz. blank end (also gate end) */
-	u32 htotal;		/* total width (w/ sync & blank) */
-	u32 vsstart;		/* vert. sync start */
-	u32 vsend;		/* vert. sync end */
-	u32 vbend;		/* vert. blank end */
-	u32 vtotal;		/* total height (w/ sync & blank) */
-	u32 stride;		/* screen stride */
-	u32 base;		/* screen base (xoffset+yoffset) */
-	u32 depth;		/* screen depth (8, 16, 24 or 32) */
-	u32 video;		/* video control (hsync,vsync) */
-	u32 flags;		/* internal flags (PM2FF_xxxx) */
-};
-
-#define OPTF_OLD_MEM		(1L<<0)
-#define OPTF_YPAN		(1L<<1)
-#define OPTF_VIRTUAL		(1L<<2)
-#define OPTF_USER		(1L<<3)
-#define OPTF_USER_VAR		(1L<<4)
-#define	OPTF_LOW_HSYNC		(1L<<5)
-#define	OPTF_LOW_VSYNC		(1L<<6)
-
-static struct {
-	char font[40];
-	u32 flags;
-	struct pm2fb_par user_mode;
-} pm2fb_options =
-#ifdef __sparc__
-	/* For some reason Raptor is not happy with the low-end mode */
-	{"\0", 0L, {31499,640,480,4,20,50,209,0,3,20,499,80,0,8,121}};
-#else
-	{"\0", 0L, {25174,640,480,4,28,40,199,9,11,45,524,80,0,8,121}};
-#endif
-
-static char curblink __initdata = 1;
-
-static struct fb_var_screeninfo user_var __initdata={0,};
-
-#define DEFAULT_USER_MODE	0
-
-static const struct {
-	char name[16];
-	struct pm2fb_par par;
-} user_mode[] __initdata = {
-	{"640x480-60",
-		{25174,640,480,4,28,40,199,9,11,45,524,80,0,8,121,PM2FF_ACCEL}},
-	{"640x480-72",
-		{31199,640,480,6,16,48,207,8,10,39,518,80,0,8,121,PM2FF_ACCEL}},
-	{"640x480-75",
-		{31499,640,480,4,20,50,209,0,3,20,499,80,0,8,121,PM2FF_ACCEL}},
-	{"640x480-90",
-		{39909,640,480,8,18,48,207,24,38,53,532,80,0,8,121,PM2FF_ACCEL}},
-	{"640x480-100",
-		{44899,640,480,8,40,52,211,21,33,51,530,80,0,8,121,PM2FF_ACCEL}},
-	{"800x600-56",
-		{35999,800,600,6,24,56,255,0,2,25,624,100,0,8,41,PM2FF_ACCEL}},
-	{"800x600-60",
-		{40000,800,600,10,42,64,263,0,4,28,627,100,0,8,41,PM2FF_ACCEL}},
-	{"800x600-70",
-		{44899,800,600,6,42,52,251,8,20,36,635,100,0,8,105,PM2FF_ACCEL}},
-	{"800x600-72",
-		{50000,800,600,14,44,60,259,36,42,66,665,100,0,8,41,PM2FF_ACCEL}},
-	{"800x600-75",
-		{49497,800,600,4,24,64,263,0,3,25,624,100,0,8,41,PM2FF_ACCEL}},
-	{"800x600-90",
-		{56637,800,600,2,18,48,247,7,18,35,634,100,0,8,41,PM2FF_ACCEL}},
-	{"800x600-100",
-		{67499,800,600,0,16,70,269,6,10,25,624,100,0,8,41,PM2FF_ACCEL}},
-	{"1024x768-60",
-		{64998,1024,768,6,40,80,335,2,8,38,805,128,0,8,121,PM2FF_ACCEL}},
-	{"1024x768-70",
-		{74996,1024,768,6,40,76,331,2,8,38,805,128,0,8,121,PM2FF_ACCEL}},
-	{"1024x768-72",
-		{74996,1024,768,6,40,66,321,2,8,38,805,128,0,8,121,PM2FF_ACCEL}},
-	{"1024x768-75",
-		{78932,1024,768,4,28,72,327,0,3,32,799,128,0,8,41,PM2FF_ACCEL}},
-	{"1024x768-90",
-		{100000,1024,768,0,24,72,327,20,35,77,844,128,0,8,121,PM2FF_ACCEL}},
-	{"1024x768-100",
-		{109998,1024,768,0,22,92,347,0,7,24,791,128,0,8,121,PM2FF_ACCEL}},
-	{"1024x768-illo",
-		{120336,1024,768,12,48,120,375,3,7,32,799,128,0,8,41,PM2FF_ACCEL}},
-	{"1152x864-60",
-		{80000,1152,864,16,44,76,363,5,10,52,915,144,0,8,41,PM2FF_ACCEL}},
-	{"1152x864-70",
-		{100000,1152,864,10,48,90,377,12,23,81,944,144,0,8,41,PM2FF_ACCEL}},
-	{"1152x864-75",
-		{109998,1152,864,6,42,78,365,44,52,138,1001,144,0,8,41,PM2FF_ACCEL}},
-	{"1152x864-80",
-		{109998,1152,864,4,32,72,359,29,36,94,957,144,0,8,41,PM2FF_ACCEL}},
-        {"1152x900-66-sun",
-                {92940,1152,900,16,80,176,751,1,5,37,936,288,0,16,121,PM2FF_ACCEL}},
-	{"1280x1024-60",
-		{107991,1280,1024,12,40,102,421,0,3,42,1065,160,0,8,41,PM2FF_ACCEL}},
-	{"1280x1024-70",
-		{125992,1280,1024,20,48,102,421,0,5,42,1065,160,0,8,41,PM2FF_ACCEL}},
-	{"1280x1024-74",
-		{134989,1280,1024,8,44,108,427,0,29,40,1063,160,0,8,41,PM2FF_ACCEL}},
-	{"1280x1024-75",
-		{134989,1280,1024,4,40,102,421,0,3,42,1065,160,0,8,41,PM2FF_ACCEL}},
-	{"1600x1200-60",
-		{155981,1600,1200,8,48,112,511,9,17,70,1269,200,0,8,121,PM2FF_ACCEL}},
-	{"1600x1200-66",
-		{171998,1600,1200,10,44,120,519,2,5,53,1252,200,0,8,121,PM2FF_ACCEL}},
-	{"1600x1200-76",
-		{197980,1600,1200,10,44,120,519,2,7,50,1249,200,0,8,121,PM2FF_ACCEL}},
-	{"\0", },
-};
-
-#ifdef CONFIG_FB_PM2_PCI
-struct pm2pci_par {
-	u32 mem_config;
-	u32 mem_control;
-	u32 boot_address;
-	struct pci_dev* dev;
-};
-#endif
-
-#define DEFAULT_CURSOR_BLINK_RATE       (20)
-#define CURSOR_DRAW_DELAY               (2)
-
-struct pm2_cursor {
-    int	enable;
-    int on;
-    int vbl_cnt;
-    int blink_rate;
-    struct {
-        u16 x, y;
-    } pos, hot, size;
-    u8 color[6];
-    u8 bits[8][64];
-    u8 mask[8][64];
-    struct timer_list *timer;
-};
-
-static const char permedia2_name[16]="Permedia2";
-
-static struct pm2fb_info {
-	struct fb_info_gen gen;
-	int board;			/* Permedia2 board index (see
-					   board_table[] below) */
-	pm2type_t type;			/* Permedia2 board type */
-	struct {
-		unsigned long  fb_base;	/* physical framebuffer memory base */
-		u32 fb_size;		/* framebuffer memory size */
-		unsigned long  rg_base;	/* physical register memory base */
-		unsigned long  p_fb;	/* physical address of frame buffer */
-		unsigned char* v_fb;	/* virtual address of frame buffer */
-		unsigned long  p_regs;	/* physical address of registers
-					   region, must be rg_base or
-					   rg_base+PM2_REGS_SIZE depending on
-					   the host endianness */
-		unsigned char* v_regs;	/* virtual address of p_regs */
-	} regions;
-	union {				/* here, the per-board par structs */
-#ifdef CONFIG_FB_PM2_CVPPC
-		struct cvppc_par cvppc;	/* CVisionPPC data */
-#endif
-#ifdef CONFIG_FB_PM2_PCI
-		struct pm2pci_par pci;	/* Permedia2 PCI boards data */
-#endif
-	} board_par;
-	struct pm2fb_par current_par;	/* displayed screen */
-	int current_par_valid;
-	int is_blank;
-	u32 memclock;			/* memclock (set by the per-board
-					   		init routine) */
-	struct display disp;
-	struct {
-		u8 transp;
-		u8 red;
-		u8 green;
-		u8 blue;
-	} palette[256];
-	union {
-#ifdef FBCON_HAS_CFB16
-		u16 cmap16[16];
-#endif
-#ifdef FBCON_HAS_CFB24
-		u32 cmap24[16];
-#endif
-#ifdef FBCON_HAS_CFB32
-		u32 cmap32[16];
-#endif
-	} cmap;
-	struct pm2_cursor *cursor;
-} fb_info;
-
-#ifdef CONFIG_FB_PM2_CVPPC
-static int cvppc_detect(struct pm2fb_info*);
-static void cvppc_init(struct pm2fb_info*);
-#endif
-
-#ifdef CONFIG_FB_PM2_PCI
-static int pm2pci_detect(struct pm2fb_info*);
-static void pm2pci_init(struct pm2fb_info*);
-#endif
+/*
+ * Driver data
+ */
+static char *mode __initdata = NULL;
 
-#ifdef PM2FB_HW_CURSOR
-static void pm2fb_cursor(struct display *p, int mode, int x, int y);
-static int pm2fb_set_font(struct display *d, int width, int height);
-static struct pm2_cursor *pm2_init_cursor(struct pm2fb_info *fb);
-static void pm2v_set_cursor_color(struct pm2fb_info *fb, u8 *red, u8 *green, u8 *blue);
-static void pm2v_set_cursor_shape(struct pm2fb_info *fb);
-static u8 cursor_color_map[2] = { 0, 0xff };
-#else
-#define pm2fb_cursor NULL
-#define pm2fb_set_font NULL
-#endif
+/*
+ * The XFree GLINT driver will (I think to implement hardware cursor
+ * support on TVP4010 and similar where there is no RAMDAC - see
+ * comment in set_video) always request +ve sync regardless of what
+ * the mode requires. This screws me because I have a Sun
+ * fixed-frequency monitor which absolutely has to have -ve sync. So
+ * these flags allow the user to specify that requests for +ve sync
+ * should be silently turned in -ve sync.
+ */
+static int lowhsync __initdata = 0;
+static int lowvsync __initdata = 0;
 
 /*
- * Table of the supported Permedia2 based boards.
- * Three hooks are defined for each board:
- * detect(): should return 1 if the related board has been detected, 0
- *           otherwise. It should also fill the fields 'regions.fb_base',
- *           'regions.fb_size', 'regions.rg_base' and 'memclock' in the
- *           passed pm2fb_info structure.
- * init(): called immediately after the reset of the Permedia2 chip.
- *         It should reset the memory controller if needed (the MClk
- *         is set shortly afterwards by the caller).
- * cleanup(): called after the driver has been unregistered.
- *
- * the init and cleanup pointers can be NULL.
+ * The hardware state of the graphics card that isn't part of the
+ * screeninfo.
  */
-static const struct {
-	int (*detect)(struct pm2fb_info*);
-	void (*init)(struct pm2fb_info*);
-	void (*cleanup)(struct pm2fb_info*);
-	char name[32];
-} board_table[] = {
-#ifdef CONFIG_FB_PM2_PCI
-	{ pm2pci_detect, pm2pci_init, NULL, "Permedia2 PCI board" },
-#endif
-#ifdef CONFIG_FB_PM2_CVPPC
-	{ cvppc_detect, cvppc_init, NULL, "CVisionPPC/BVisionPPC" },
-#endif
-	{ NULL, }
+struct pm2fb_par
+{
+	pm2type_t	type;		/* Board type */
+	u32		fb_size;	/* framebuffer memory size */
+	unsigned char*	v_fb;		/* virtual address of frame buffer */
+	unsigned char*	v_regs;		/* virtual address of p_regs */
+	u32 	   	memclock;	/* memclock */
+	u32		video;		/* video flags before blanking */
 };
 
 /*
- * partial products for the supported horizontal resolutions.
+ * Here we define the default structs fb_fix_screeninfo and fb_var_screeninfo
+ * if we don't use modedb.
  */
-#define PACKPP(p0,p1,p2)	(((p2)<<6)|((p1)<<3)|(p0))
-static const struct {
-	u16 width;
-	u16 pp;
-} pp_table[] = {
-	{ 32,	PACKPP(1, 0, 0) }, { 64,	PACKPP(1, 1, 0) },
-	{ 96,	PACKPP(1, 1, 1) }, { 128,	PACKPP(2, 1, 1) },
-	{ 160,	PACKPP(2, 2, 1) }, { 192,	PACKPP(2, 2, 2) },
-	{ 224,	PACKPP(3, 2, 1) }, { 256,	PACKPP(3, 2, 2) },
-	{ 288,	PACKPP(3, 3, 1) }, { 320,	PACKPP(3, 3, 2) },
-	{ 384,	PACKPP(3, 3, 3) }, { 416,	PACKPP(4, 3, 1) },
-	{ 448,	PACKPP(4, 3, 2) }, { 512,	PACKPP(4, 3, 3) },
-	{ 544,	PACKPP(4, 4, 1) }, { 576,	PACKPP(4, 4, 2) },
-	{ 640,	PACKPP(4, 4, 3) }, { 768,	PACKPP(4, 4, 4) },
-	{ 800,	PACKPP(5, 4, 1) }, { 832,	PACKPP(5, 4, 2) },
-	{ 896,	PACKPP(5, 4, 3) }, { 1024,	PACKPP(5, 4, 4) },
-	{ 1056,	PACKPP(5, 5, 1) }, { 1088,	PACKPP(5, 5, 2) },
-	{ 1152,	PACKPP(5, 5, 3) }, { 1280,	PACKPP(5, 5, 4) },
-	{ 1536,	PACKPP(5, 5, 5) }, { 1568,	PACKPP(6, 5, 1) },
-	{ 1600,	PACKPP(6, 5, 2) }, { 1664,	PACKPP(6, 5, 3) },
-	{ 1792,	PACKPP(6, 5, 4) }, { 2048,	PACKPP(6, 5, 5) },
-	{ 0,	0 } };
-
-static void pm2fb_detect(void);
-static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,
-				const void* par, struct fb_info_gen* info);
-static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
-					void* par, struct fb_info_gen* info);
-static int pm2fb_encode_var(struct fb_var_screeninfo* var,
-				const void* par, struct fb_info_gen* info);
-static void pm2fb_get_par(void* par, struct fb_info_gen* info);
-static void pm2fb_set_par(const void* par, struct fb_info_gen* info);
-static int pm2fb_getcolreg(unsigned regno,
-			unsigned* red, unsigned* green, unsigned* blue,
-				unsigned* transp, struct fb_info* info);
-static int pm2fb_blank(int blank_mode, struct fb_info_gen* info);
-static int pm2fb_pan_display(const struct fb_var_screeninfo* var,
-					struct fb_info_gen* info);
-static void pm2fb_set_disp(const void* par, struct display* disp,
-						struct fb_info_gen* info);
-
-static struct fbgen_hwswitch pm2fb_hwswitch={
-	pm2fb_detect, pm2fb_encode_fix, pm2fb_decode_var,
-	pm2fb_encode_var, pm2fb_get_par, pm2fb_set_par,
-	pm2fb_getcolreg, pm2fb_pan_display,
-	pm2fb_blank, pm2fb_set_disp
+static struct fb_fix_screeninfo pm2fb_fix __initdata = {
+	.id =		"",
+	.type =		FB_TYPE_PACKED_PIXELS,
+	.visual =	FB_VISUAL_PSEUDOCOLOR,
+	.xpanstep =	1,
+	.ypanstep =	1,
+	.ywrapstep =	0,
+	.accel =	FB_ACCEL_NONE,
 };
 
-
-static int pm2fb_setcolreg(unsigned regno,
-			unsigned red, unsigned green, unsigned blue,
-				unsigned transp, struct fb_info* info);
-
-static struct fb_ops pm2fb_ops={
-	.owner =	THIS_MODULE,
-	.fb_get_fix =	fbgen_get_fix,
-	.fb_get_var =	fbgen_get_var,
-	.fb_set_var =	fbgen_set_var,
-	.fb_get_cmap =	fbgen_get_cmap,
-	.fb_set_cmap =	fbgen_set_cmap,
-	.fb_pan_display =fbgen_pan_display,
-	.fb_setcolreg =	pm2fb_setcolreg,
-	.fb_blank =	fbgen_blank,
+/*
+ * Default video mode. In case the modedb doesn't work, or we're
+ * a module (in which case modedb doesn't really work).
+ */
+static struct fb_var_screeninfo pm2fb_var __initdata = {
+	/* "640x480, 8 bpp @ 60 Hz */
+	.xres =		640,
+	.yres =		480,
+	.xres_virtual =	640,
+	.yres_virtual =	480,
+	.bits_per_pixel =8,
+	.red =		{0, 8, 0},
+	.blue =		{0, 8, 0},
+	.green =	{0, 8, 0},
+	.activate =	FB_ACTIVATE_NOW,
+	.height =	-1,
+	.width =	-1,
+	.accel_flags =	0,
+	.pixclock =	39721,
+	.left_margin =	40,
+	.right_margin =	24,
+	.upper_margin =	32,
+	.lower_margin =	11,
+	.hsync_len =	96,
+	.vsync_len =	2,
+	.vmode =	FB_VMODE_NONINTERLACED
 };
 
-/***************************************************************************
- * Begin of Permedia2 specific functions
- ***************************************************************************/
-
-inline static u32 RD32(unsigned char* base, s32 off) {
+/*
+ * Utility functions
+ */
 
-	return fb_readl(base+off);
+inline static u32 RD32(unsigned char* base, s32 off)
+{
+	return fb_readl(base + off);
 }
 
-inline static void WR32(unsigned char* base, s32 off, u32 v) {
-
-	fb_writel(v, base+off);
+inline static void WR32(unsigned char* base, s32 off, u32 v)
+{
+	fb_writel(v, base + off);
 }
 
-inline static u32 pm2_RD(struct pm2fb_info* p, s32 off) {
-
-	return RD32(p->regions.v_regs, off);
+inline static u32 pm2_RD(struct pm2fb_par* p, s32 off)
+{
+	return RD32(p->v_regs, off);
 }
 
-inline static void pm2_WR(struct pm2fb_info* p, s32 off, u32 v) {
-
-	WR32(p->regions.v_regs, off, v);
+inline static void pm2_WR(struct pm2fb_par* p, s32 off, u32 v)
+{
+	WR32(p->v_regs, off, v);
 }
 
-inline static u32 pm2_RDAC_RD(struct pm2fb_info* p, s32 idx) {
-
+inline static u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx)
+{
 	int index = PM2R_RD_INDEXED_DATA;
 	switch (p->type) {
 	case PM2_TYPE_PERMEDIA2:
@@ -464,9 +186,8 @@
 	return pm2_RD(p, index);
 }
 
-inline static void pm2_RDAC_WR(struct pm2fb_info* p, s32 idx,
-						u32 v) {
-
+inline static void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+{
 	int index = PM2R_RD_INDEXED_DATA;
 	switch (p->type) {
 	case PM2_TYPE_PERMEDIA2:
@@ -481,16 +202,15 @@
 	pm2_WR(p, index, v);
 }
 
-inline static u32 pm2v_RDAC_RD(struct pm2fb_info* p, s32 idx) {
-
+inline static u32 pm2v_RDAC_RD(struct pm2fb_par* p, s32 idx)
+{
 	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
 	DEFRW();
 	return pm2_RD(p, PM2VR_RD_INDEXED_DATA);
 }
 
-inline static void pm2v_RDAC_WR(struct pm2fb_info* p, s32 idx,
-						u32 v) {
-
+inline static void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
+{
 	pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
 	DEFRW();
 	pm2_WR(p, PM2VR_RD_INDEXED_DATA, v);
@@ -499,79 +219,88 @@
 #ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
 #define WAIT_FIFO(p,a)
 #else
-inline static void WAIT_FIFO(struct pm2fb_info* p, u32 a) {
-
-	while(pm2_RD(p, PM2R_IN_FIFO_SPACE)<a);
+inline static void WAIT_FIFO(struct pm2fb_par* p, u32 a)
+{
+	while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a );
 	DEFRW();
 }
 #endif
 
-static u32 partprod(u32 xres) {
+/*
+ * partial products for the supported horizontal resolutions.
+ */
+#define PACKPP(p0,p1,p2)	(((p2) << 6) | ((p1) << 3) | (p0))
+static const struct {
+	u16 width;
+	u16 pp;
+} pp_table[] = {
+	{ 32,	PACKPP(1, 0, 0) }, { 64,	PACKPP(1, 1, 0) },
+	{ 96,	PACKPP(1, 1, 1) }, { 128,	PACKPP(2, 1, 1) },
+	{ 160,	PACKPP(2, 2, 1) }, { 192,	PACKPP(2, 2, 2) },
+	{ 224,	PACKPP(3, 2, 1) }, { 256,	PACKPP(3, 2, 2) },
+	{ 288,	PACKPP(3, 3, 1) }, { 320,	PACKPP(3, 3, 2) },
+	{ 384,	PACKPP(3, 3, 3) }, { 416,	PACKPP(4, 3, 1) },
+	{ 448,	PACKPP(4, 3, 2) }, { 512,	PACKPP(4, 3, 3) },
+	{ 544,	PACKPP(4, 4, 1) }, { 576,	PACKPP(4, 4, 2) },
+	{ 640,	PACKPP(4, 4, 3) }, { 768,	PACKPP(4, 4, 4) },
+	{ 800,	PACKPP(5, 4, 1) }, { 832,	PACKPP(5, 4, 2) },
+	{ 896,	PACKPP(5, 4, 3) }, { 1024,	PACKPP(5, 4, 4) },
+	{ 1056,	PACKPP(5, 5, 1) }, { 1088,	PACKPP(5, 5, 2) },
+	{ 1152,	PACKPP(5, 5, 3) }, { 1280,	PACKPP(5, 5, 4) },
+	{ 1536,	PACKPP(5, 5, 5) }, { 1568,	PACKPP(6, 5, 1) },
+	{ 1600,	PACKPP(6, 5, 2) }, { 1664,	PACKPP(6, 5, 3) },
+	{ 1792,	PACKPP(6, 5, 4) }, { 2048,	PACKPP(6, 5, 5) },
+	{ 0,	0 } };
+
+static u32 partprod(u32 xres)
+{
 	int i;
 
-	for (i=0; pp_table[i].width && pp_table[i].width!=xres; i++);
-	if (!pp_table[i].width)
+	for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++)
+		;
+	if ( pp_table[i].width == 0 )
 		DPRINTK("invalid width %u\n", xres);
 	return pp_table[i].pp;
 }
 
-static u32 to3264(u32 timing, int bpp, int is64) {
-
-	switch (bpp) {
-		case 8:
-			timing=timing>>(2+is64);
-			break;
-		case 16:
-			timing=timing>>(1+is64);
-			break;
-		case 24:
-			timing=(timing*3)>>(2+is64);
-			break;
-		case 32:
-			if (is64)
-				timing=timing>>1;
-			break;
-	}
-	return timing;
-}
-
-static u32 from3264(u32 timing, int bpp, int is64) {
-
+static u32 to3264(u32 timing, int bpp, int is64)
+{
 	switch (bpp) {
-		case 8:
-			timing=timing<<(2+is64);
-			break;
-		case 16:
-			timing=timing<<(1+is64);
-			break;
-		case 24:
-			timing=(timing<<(2+is64))/3;
-			break;
-		case 32:
-			if (is64)
-				timing=timing<<1;
-			break;
+	case 8:
+		timing >>= 2 + is64;
+		break;
+	case 16:
+		timing >>= 1 + is64;
+		break;
+	case 24:
+		timing = (timing * 3) >> (2 + is64);
+		break;
+	case 32:
+		if (is64)
+			timing >>= 1;
+		break;
 	}
 	return timing;
 }
 
 static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
-		    unsigned char* pp) {
+		    unsigned char* pp)
+{
 	unsigned char m;
 	unsigned char n;
 	unsigned char p;
 	u32 f;
 	s32 curr;
-	s32 delta=100000;
+	s32 delta = 100000;
 
-	*mm=*nn=*pp=0;
-	for (n=2; n<15; n++) {
-		for (m=2; m; m++) {
-			f=PM2_REFERENCE_CLOCK*m/n;
-			if (f>=150000 && f<=300000) {
-				for (p=0; p<5; p++, f>>=1) {
-					curr=clk>f?clk-f:f-clk;
-					if (curr<delta) {
+	*mm = *nn = *pp = 0;
+	for (n = 2; n < 15; n++) {
+		for (m = 2; m; m++) {
+			f = PM2_REFERENCE_CLOCK * m / n;
+			if (f >= 150000 && f <= 300000) {
+				for ( p = 0; p < 5; p++, f >>= 1) {
+					curr = ( clk > f ) ? clk - f : f - clk;
+					if ( curr < delta ) {
 						delta=curr;
 						*mm=m;
 						*nn=n;
@@ -584,20 +313,21 @@
 }
 
 static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
-		unsigned char* pp) {
+		     unsigned char* pp)
+{
 	unsigned char m;
 	unsigned char n;
 	unsigned char p;
 	u32 f;
-	s32 delta=1000;
+	s32 delta = 1000;
 
-	*mm=*nn=*pp=0;
-	for (n=1; n; n++) {
-		for (m=1; m; m++) {
-			for (p=0; p<2; p++) {
-				f=PM2_REFERENCE_CLOCK*n/(m * (1<<(p+1)));
-				if (clk>f-delta && clk<f+delta) {
-					delta=clk>f?clk-f:f-clk;
+	*mm = *nn = *pp = 0;
+	for (n = 1; n; n++) {
+		for ( m = 1; m; m++) {
+			for ( p = 0; p < 2; p++) {
+				f = PM2_REFERENCE_CLOCK * n / (m * (1 << (p + 1)));
+				if ( clk > f - delta && clk < f + delta ) {
+					delta = ( clk > f ) ? clk - f : f - clk;
 					*mm=m;
 					*nn=n;
 					*pp=p;
@@ -607,72 +337,7 @@
 	}
 }
 
-static void wait_pm2(struct pm2fb_info* i) {
-
-	WAIT_FIFO(i, 1);
-	pm2_WR(i, PM2R_SYNC, 0);
-	DEFRW();
-	do {
-		while (pm2_RD(i, PM2R_OUT_FIFO_WORDS)==0);
-		DEFR();
-	} while (pm2_RD(i, PM2R_OUT_FIFO)!=PM2TAG(PM2R_SYNC));
-}
-
-static void pm2_set_memclock(struct pm2fb_info* info, u32 clk) {
-	int i;
-	unsigned char m, n, p;
-
-	pm2_mnp(clk, &m, &n, &p);
-	WAIT_FIFO(info, 10);
-	pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 6);
-	DEFW();
-	pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_1, m);
-	pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_2, n);
-	DEFW();
-	pm2_RDAC_WR(info, PM2I_RD_MEMORY_CLOCK_3, 8|p);
-	DEFW();
-	pm2_RDAC_RD(info, PM2I_RD_MEMORY_CLOCK_STATUS);
-	DEFR();
-	for (i=256; i &&
-		!(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED); i--);
-}
-
-static void pm2_set_pixclock(struct pm2fb_info* info, u32 clk) {
-	int i;
-	unsigned char m, n, p;
-
-	switch (info->type) {
-	case PM2_TYPE_PERMEDIA2:
-		pm2_mnp(clk, &m, &n, &p);
-		WAIT_FIFO(info, 8);
-		pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 0);
-		DEFW();
-		pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A1, m);
-		pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A2, n);
-		DEFW();
-		pm2_RDAC_WR(info, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
-		DEFW();
-		pm2_RDAC_RD(info, PM2I_RD_PIXEL_CLOCK_STATUS);
-		DEFR();
-		for (i=256;
-		     i && !(pm2_RD(info, PM2R_RD_INDEXED_DATA)&PM2F_PLL_LOCKED);
-		     i--)
-		    ;
-		break;
-	case PM2_TYPE_PERMEDIA2V:
-		pm2v_mnp(clk/2, &m, &n, &p);
-		WAIT_FIFO(info, 8);
-		pm2_WR(info, PM2VR_RD_INDEX_HIGH,
-		       PM2VI_RD_CLK0_PRESCALE >> 8);
-		pm2v_RDAC_WR(info, PM2VI_RD_CLK0_PRESCALE, m);
-		pm2v_RDAC_WR(info, PM2VI_RD_CLK0_FEEDBACK, n);
-		pm2v_RDAC_WR(info, PM2VI_RD_CLK0_POSTSCALE, p);
-		pm2_WR(info, PM2VR_RD_INDEX_HIGH, 0);
-		break;
-	}
-}
-
-static void clear_palette(struct pm2fb_info* p) {
+static void clear_palette(struct pm2fb_par* p) {
 	int i=256;
 
 	WAIT_FIFO(p, 1);
@@ -686,300 +351,38 @@
 	}
 }
 
-static void set_color(struct pm2fb_info* p, unsigned char regno,
-			unsigned char r, unsigned char g, unsigned char b) {
-
-	WAIT_FIFO(p, 4);
-	pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, regno);
-	DEFW();
-	pm2_WR(p, PM2R_RD_PALETTE_DATA, r);
-	DEFW();
-	pm2_WR(p, PM2R_RD_PALETTE_DATA, g);
-	DEFW();
-	pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
-}
-
-static void set_aperture(struct pm2fb_info* i, struct pm2fb_par* p) {
-
-	WAIT_FIFO(i, 4);
-#ifdef __LITTLE_ENDIAN
-	pm2_WR(i, PM2R_APERTURE_ONE, 0);
-	pm2_WR(i, PM2R_APERTURE_TWO, 0);
-#else
-	switch (p->depth) {
-		case 8:
-		case 24:
-			pm2_WR(i, PM2R_APERTURE_ONE, 0);
-			pm2_WR(i, PM2R_APERTURE_TWO, 1);
-			break;
-		case 16:
-			pm2_WR(i, PM2R_APERTURE_ONE, 2);
-			pm2_WR(i, PM2R_APERTURE_TWO, 1);
-			break;
-		case 32:
-			pm2_WR(i, PM2R_APERTURE_ONE, 1);
-			pm2_WR(i, PM2R_APERTURE_TWO, 1);
-			break;
-	}
+#if 0
+/*
+ * FIXME:
+ * The 2.4 driver calls this at init time, where it also sets the
+ * initial mode. I don't think the driver should touch the chip
+ * until the console sets a video mode. So I was calling this
+ * at the start of setting a mode. However, certainly on 1280x1024
+ * depth 16 this causes the display to smear slightly.
+ * I don't know why. Guesses to jim.hague@acm.org.
+ */
+static void reset_card(struct pm2fb_par* p)
+{
+	if (p->type == PM2_TYPE_PERMEDIA2V)
+		pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
+	pm2_WR(p, PM2R_RESET_STATUS, 0);
+	DEFRW();
+	while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET)
+		;
+	DEFRW();
+#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
+	DPRINTK("FIFO disconnect enabled\n");
+	pm2_WR(p, PM2R_FIFO_DISCON, 1);
+	DEFRW();
 #endif
 }
+#endif
 
-static void set_video(struct pm2fb_info* i, u32 video) {
-	u32 tmp;
-	u32 vsync;
-
-	vsync=video;
-	
-	/*
-	 * The hardware cursor needs +vsync to recognise vert retrace.
-	 * We may not be using the hardware cursor, but the X Glint
-	 * driver may well. So always set +hsync/+vsync and then set
-	 * the RAMDAC to invert the sync if necessary.
-	 */
-	vsync&=~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK);
-	vsync|=PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH;
-
-	WAIT_FIFO(i, 5);
-	pm2_WR(i, PM2R_VIDEO_CONTROL, vsync);
-
-	switch (i->type) {
-		case PM2_TYPE_PERMEDIA2:
-			tmp = PM2F_RD_PALETTE_WIDTH_8;
-			if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
-				tmp |= 4; /* invert hsync */
-			if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
-				tmp |= 8; /* invert vsync */
-			pm2_RDAC_WR(i, PM2I_RD_MISC_CONTROL, tmp);
-			break;
-		case PM2_TYPE_PERMEDIA2V:
-			tmp = 0;
-			if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
-				tmp |= 1; /* invert hsync */
-			if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
-				tmp |= 4; /* invert vsync */
-			pm2v_RDAC_WR(i, PM2VI_RD_SYNC_CONTROL, tmp);
-			pm2v_RDAC_WR(i, PM2VI_RD_MISC_CONTROL, 1);
-			break;
-	}
-}
-
-static void get_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
-	u32 clrmode;
-	u32 readpx;
-	u32 misc;
-
-	memset(p, 0, sizeof(struct pm2fb_par));
-	p->base=pm2_RD(i, PM2R_SCREEN_BASE);
-	p->video=pm2_RD(i, PM2R_VIDEO_CONTROL) & VIDEO_MASK;
-	switch (i->type) {
-		case PM2_TYPE_PERMEDIA2:
-			misc=pm2_RDAC_RD(i, PM2I_RD_MISC_CONTROL);
-			if ( misc & 4 )
-				/* Hsync is actually low */
-				p->video |= PM2F_HSYNC_ACT_LOW;
-			if ( misc & 8 )
-				/* Vsync is actually low */
-				p->video |= PM2F_VSYNC_ACT_LOW;
-			break;
-		case PM2_TYPE_PERMEDIA2V:
-			misc=pm2_RDAC_RD(i, PM2VI_RD_SYNC_CONTROL);
-			if ( misc & 1 )
-				/* Hsync is actually low */
-				p->video |= PM2F_HSYNC_ACT_LOW;
-			if ( misc & 4 )
-				/* Vsync is actually low */
-				p->video |= PM2F_VSYNC_ACT_LOW;
-			break;
-	}
-	p->width=pm2_RD(i, PM2R_SCREEN_SIZE) & 0xffff;
-	p->height=pm2_RD(i, PM2R_SCREEN_SIZE) >> 16;
-	p->htotal=pm2_RD(i, PM2R_H_TOTAL);
-	p->hsstart=pm2_RD(i, PM2R_HS_START);
-	p->hsend=pm2_RD(i, PM2R_HS_END);
-	p->hbend=pm2_RD(i, PM2R_HB_END);
-	p->vtotal=pm2_RD(i, PM2R_V_TOTAL);
-	p->vsstart=pm2_RD(i, PM2R_VS_START);
-	p->vsend=pm2_RD(i, PM2R_VS_END);
-	p->vbend=pm2_RD(i, PM2R_VB_END);
-	p->stride=pm2_RD(i, PM2R_SCREEN_STRIDE);
-	clrmode=pm2_RDAC_RD(i, PM2I_RD_COLOR_MODE);
-	readpx=pm2_RD(i, PM2R_FB_READ_PIXEL);
-	if (clrmode & PM2F_RD_GUI_ACTIVE) {
-		clrmode &= ~(PM2F_RD_COLOR_MODE_RGB|PM2F_RD_GUI_ACTIVE);
-		if (clrmode==0 && readpx==0)
-			p->depth=8;
-		else if (clrmode==(PM2F_RD_TRUECOLOR|0x06) && readpx==1)
-			p->depth=16;
-		else if (clrmode==(PM2F_RD_TRUECOLOR|0x08) && readpx==2)
-			p->depth=32;
-		else if (clrmode==(PM2F_RD_TRUECOLOR|0x09) && readpx==4)
-			p->depth=24;
-	}
-	/*
-	 * Somehow I have to manage this unretrievable fields.
-	 * To say the truth, 'flags' field ought to be somewhere else.
-	 */
-	if (i->current_par_valid) {
-		p->pixclock=i->current_par.pixclock;
-		p->flags=i->current_par.flags;
-	}
-}
-	
-static void set_screen(struct pm2fb_info* i, struct pm2fb_par* p) {
-	u32 clrmode=PM2F_RD_COLOR_MODE_RGB;
-	u32 txtmap=0;
-	u32 pixsize=0;
-	u32 clrformat=0;
-	u32 xres;
-
-	if (i->type == PM2_TYPE_PERMEDIA2V) {
-		WAIT_FIFO(i, 1);
-		pm2_WR(i, PM2VR_RD_INDEX_HIGH, 0);
-	}
-	xres=(p->width+31)&~31;
-	set_aperture(i, p);
-	DEFRW();
-	WAIT_FIFO(i, 19);
-	pm2_RDAC_WR(i, PM2I_RD_COLOR_KEY_CONTROL, p->depth==8?0:
-						PM2F_COLOR_KEY_TEST_OFF);
-	switch (p->depth) {
-		case 8:
-			pm2_WR(i, PM2R_FB_READ_PIXEL, 0);
-			clrformat=0x0e;
-			break;
-		case 16:
-			pm2_WR(i, PM2R_FB_READ_PIXEL, 1);
-			clrmode|=PM2F_RD_TRUECOLOR|0x06;
-			txtmap=PM2F_TEXTEL_SIZE_16;
-			pixsize=1;
-			clrformat=0x70;
-			break;
-		case 32:
-			pm2_WR(i, PM2R_FB_READ_PIXEL, 2);
-			clrmode|=PM2F_RD_TRUECOLOR|0x08;
-			txtmap=PM2F_TEXTEL_SIZE_32;
-			pixsize=2;
-			clrformat=0x20;
-			break;
-		case 24:
-			pm2_WR(i, PM2R_FB_READ_PIXEL, 4);
-			clrmode|=PM2F_RD_TRUECOLOR|0x09;
-#ifndef PM2FB_BE_APERTURE
-			clrmode&=~PM2F_RD_COLOR_MODE_RGB;
-#endif
-			txtmap=PM2F_TEXTEL_SIZE_24;
-			pixsize=4;
-			clrformat=0x20;
-			break;
-	}
-	pm2_WR(i, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
-	pm2_WR(i, PM2R_FB_READ_MODE, partprod(xres));
-	pm2_WR(i, PM2R_LB_READ_MODE, partprod(xres));
-	pm2_WR(i, PM2R_TEXTURE_MAP_FORMAT, txtmap|partprod(xres));
-	pm2_WR(i, PM2R_H_TOTAL, p->htotal);
-	pm2_WR(i, PM2R_HS_START, p->hsstart);
-	pm2_WR(i, PM2R_HS_END, p->hsend);
-	pm2_WR(i, PM2R_HG_END, p->hbend);
-	pm2_WR(i, PM2R_HB_END, p->hbend);
-	pm2_WR(i, PM2R_V_TOTAL, p->vtotal);
-	pm2_WR(i, PM2R_VS_START, p->vsstart);
-	pm2_WR(i, PM2R_VS_END, p->vsend);
-	pm2_WR(i, PM2R_VB_END, p->vbend);
-	pm2_WR(i, PM2R_SCREEN_STRIDE, p->stride);
-	DEFW();
-	pm2_WR(i, PM2R_WINDOW_ORIGIN, 0);
-	pm2_WR(i, PM2R_SCREEN_SIZE, (p->height<<16)|p->width);
-	pm2_WR(i, PM2R_SCISSOR_MODE, PM2F_SCREEN_SCISSOR_ENABLE);
-	DEFW();
-	pm2_WR(i, PM2R_SCREEN_BASE, p->base);
-	DEFW();
-	set_video(i, p->video);
-	WAIT_FIFO(i, 4);
-	switch (i->type) {
-		case PM2_TYPE_PERMEDIA2:
-			pm2_RDAC_WR(i, PM2I_RD_COLOR_MODE, PM2F_RD_COLOR_MODE_RGB|
-					PM2F_RD_GUI_ACTIVE|clrmode);
-			break;
-		case PM2_TYPE_PERMEDIA2V:
-			pm2v_RDAC_WR(i, PM2VI_RD_PIXEL_SIZE, pixsize);
-			pm2v_RDAC_WR(i, PM2VI_RD_COLOR_FORMAT, clrformat);
-			break;
-	}
-	pm2_set_pixclock(i, p->pixclock);
-}
-
-static int screen_is_valid(struct pm2fb_info* i) {
-	struct pm2fb_par actual;
-
-	get_screen(i, &actual);
-	return i->current_par_valid &&
-		!memcmp(&actual, &i->current_par, sizeof(struct pm2fb_par));
-}
-
-/*
- * copy with packed pixels (8/16bpp only).
- */
-static void pm2fb_pp_copy(struct pm2fb_info* i, s32 xsrc, s32 ysrc,
-					s32 x, s32 y, s32 w, s32 h) {
-	s32 scale=i->current_par.depth==8?2:1;
-	s32 offset;
-
-	if (!w || !h)
-		return;
-	WAIT_FIFO(i, 6);
-	pm2_WR(i, PM2R_CONFIG,	PM2F_CONFIG_FB_WRITE_ENABLE|
-				PM2F_CONFIG_FB_PACKED_DATA|
-				PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
-	pm2_WR(i, PM2R_FB_SOURCE_DELTA,	((ysrc-y)&0xfff)<<16|
-						((xsrc-x)&0xfff));
-	offset=(x&0x3)-(xsrc&0x3);
-	pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|(x>>scale));
-	pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|((w+7)>>scale));
-	pm2_WR(i, PM2R_PACKED_DATA_LIMITS, (offset<<29)|(x<<16)|(x+w));
-	DEFW();
-	pm2_WR(i, PM2R_RENDER,	PM2F_RENDER_RECTANGLE|
-				(x<xsrc?PM2F_INCREASE_X:0)|
-				(y<ysrc?PM2F_INCREASE_Y:0));
-	wait_pm2(i);
-}
-
-/*
- * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
- */
-static void pm2fb_block_op(struct pm2fb_info* i, int copy,
-					s32 xsrc, s32 ysrc,
-					s32 x, s32 y, s32 w, s32 h,
-					u32 color) {
-
-	if (!w || !h)
-		return;
-	WAIT_FIFO(i, 5);
-	pm2_WR(i, PM2R_CONFIG,	PM2F_CONFIG_FB_WRITE_ENABLE|
-				(copy?PM2F_CONFIG_FB_READ_SOURCE_ENABLE:0));
-	if (copy)
-		pm2_WR(i, PM2R_FB_SOURCE_DELTA,	((ysrc-y)&0xfff)<<16|
-							((xsrc-x)&0xfff));
-	else
-		pm2_WR(i, PM2R_FB_BLOCK_COLOR, color);
-	pm2_WR(i, PM2R_RECTANGLE_ORIGIN, (y<<16)|x);
-	pm2_WR(i, PM2R_RECTANGLE_SIZE, (h<<16)|w);
-	DEFW();
-	pm2_WR(i, PM2R_RENDER,	PM2F_RENDER_RECTANGLE|
-				(x<xsrc?PM2F_INCREASE_X:0)|
-				(y<ysrc?PM2F_INCREASE_Y:0)|
-				(copy?0:PM2F_RENDER_FASTFILL));
-	wait_pm2(i);
-}
-
-/***************************************************************************
- * Begin of generic initialization functions
- ***************************************************************************/
-
-static void reset_units(struct pm2fb_info* p) {
-
+static void reset_config(struct pm2fb_par* p)
+{
 	WAIT_FIFO(p, 52);
 	pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG)&
-					~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED));
+	       ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED));
 	pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
 	pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
 	pm2_WR(p, PM2R_FIFO_CONTROL, 0);
@@ -1031,1396 +434,845 @@
 	pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
 }
 
-static void pm2fb_reset(struct pm2fb_info* p) {
-
-	if (p->type == PM2_TYPE_PERMEDIA2V)
-		pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
-	pm2_WR(p, PM2R_RESET_STATUS, 0);
-	DEFRW();
-	while (pm2_RD(p, PM2R_RESET_STATUS)&PM2F_BEING_RESET);
-	DEFRW();
-#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
-	DPRINTK("FIFO disconnect enabled\n");
-	pm2_WR(p, PM2R_FIFO_DISCON, 1);
-	DEFRW();
-#endif
-	if (board_table[p->board].init)
-		board_table[p->board].init(p);
-	reset_units(p);
-	clear_palette(p);
-	if (p->memclock)
-		pm2_set_memclock(p, p->memclock);
-}
-
-static int __init pm2fb_conf(struct pm2fb_info* p) {
-
-	for (p->board=0; board_table[p->board].detect &&
-			!(board_table[p->board].detect(p)); p->board++);
-	if (!board_table[p->board].detect) {
-		DPRINTK("no board found.\n");
-		return 0;
-	}
-	DPRINTK("found board: %s\n", board_table[p->board].name);
-
-	p->regions.p_fb=p->regions.fb_base;
-	if (!request_mem_region((unsigned long )p->regions.p_fb,
-					p->regions.fb_size, "pm2fb")) {
-		printk (KERN_ERR "pm2fb: cannot reserve fb memory, abort.\n");
-		return 0;
-	}
-	p->regions.v_fb=MMAP(p->regions.p_fb, p->regions.fb_size);
-
-#ifndef PM2FB_BE_APERTURE
-	p->regions.p_regs=p->regions.rg_base;
+static void set_aperture(struct pm2fb_par* p)
+{
+	WAIT_FIFO(p, 4);
+#ifdef __LITTLE_ENDIAN
+	pm2_WR(p, PM2R_APERTURE_ONE, 0);
+	pm2_WR(p, PM2R_APERTURE_TWO, 0);
 #else
-	p->regions.p_regs=p->regions.rg_base+PM2_REGS_SIZE;
-#endif
-	if (!request_mem_region((unsigned long )p->regions.p_regs,
-						PM2_REGS_SIZE, "pm2fb")) {
-		printk (KERN_ERR "pm2fb: cannot reserve mmio memory, abort.\n");
-		UNMAP(p->regions.v_fb, p->regions.fb_size);
-		return 0;
+	switch (p->depth) {
+	case 8:
+	case 24:
+		pm2_WR(p, PM2R_APERTURE_ONE, 0);
+		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+		break;
+	case 16:
+		pm2_WR(p, PM2R_APERTURE_ONE, 2);
+		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+		break;
+	case 32:
+		pm2_WR(p, PM2R_APERTURE_ONE, 1);
+		pm2_WR(p, PM2R_APERTURE_TWO, 1);
+		break;
 	}
-	p->regions.v_regs=MMAP(p->regions.p_regs, PM2_REGS_SIZE);
-
-#ifdef PM2FB_HW_CURSOR
-	p->cursor = pm2_init_cursor(p);
 #endif
-	return 1;
 }
 
-/***************************************************************************
- * Begin of per-board initialization functions
- ***************************************************************************/
-
-/*
- * Phase5 CvisionPPC/BVisionPPC
- */
-#ifdef CONFIG_FB_PM2_CVPPC
-static int cvppc_PCI_init(struct cvppc_par* p) {
-	extern u32 powerup_PCI_present;
-
-	if (!powerup_PCI_present) {
-		DPRINTK("no PCI bridge detected\n");
-		return 0;
-	}
-	if (!(p->pci_config=MMAP(CVPPC_PCI_CONFIG, 256))) {
-		DPRINTK("unable to map PCI config region\n");
-		return 0;
-	}
-	if (RD32(p->pci_config, PCI_VENDOR_ID)!=
-			((PCI_DEVICE_ID_TI_TVP4020<<16)|PCI_VENDOR_ID_TI)) {
-		DPRINTK("bad vendorID/deviceID\n");
-		return 0;
-	}
-	if (!(p->pci_bridge=MMAP(CSPPC_PCI_BRIDGE, 256))) {
-		DPRINTK("unable to map PCI bridge\n");
-		return 0;
-	}
-	WR32(p->pci_bridge, CSPPC_BRIDGE_ENDIAN, CSPPCF_BRIDGE_BIG_ENDIAN);
+static void set_color(struct pm2fb_par* p, unsigned char regno,
+		      unsigned char r, unsigned char g, unsigned char b)
+{
+	WAIT_FIFO(p, 4);
+	pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, regno);
 	DEFW();
-	if (pm2fb_options.flags & OPTF_OLD_MEM)
-		WR32(p->pci_config, PCI_CACHE_LINE_SIZE, 0xff00);
-	WR32(p->pci_config, PCI_BASE_ADDRESS_0, CVPPC_REGS_REGION);
-	WR32(p->pci_config, PCI_BASE_ADDRESS_1, CVPPC_FB_APERTURE_ONE);
-	WR32(p->pci_config, PCI_BASE_ADDRESS_2, CVPPC_FB_APERTURE_TWO);
-	WR32(p->pci_config, PCI_ROM_ADDRESS, CVPPC_ROM_ADDRESS);
+	pm2_WR(p, PM2R_RD_PALETTE_DATA, r);
 	DEFW();
-	WR32(p->pci_config, PCI_COMMAND, 0xef000000 |
-						PCI_COMMAND_IO |
-						PCI_COMMAND_MEMORY |
-						PCI_COMMAND_MASTER);
-	return 1;
-}
-
-static int __init cvppc_detect(struct pm2fb_info* p) {
-
-	if (!cvppc_PCI_init(&p->board_par.cvppc))
-		return 0;
-	p->type=PM2_TYPE_PERMEDIA2;
-	p->regions.fb_base=CVPPC_FB_APERTURE_ONE;
-	p->regions.fb_size=CVPPC_FB_SIZE;
-	p->regions.rg_base=CVPPC_REGS_REGION;
-	p->memclock=CVPPC_MEMCLOCK;
-	return 1;
-}
-
-static void cvppc_init(struct pm2fb_info* p) {
-
-	WAIT_FIFO(p, 3);
-	pm2_WR(p, PM2R_MEM_CONTROL, 0);
-	pm2_WR(p, PM2R_BOOT_ADDRESS, 0x30);
+	pm2_WR(p, PM2R_RD_PALETTE_DATA, g);
 	DEFW();
-	if (pm2fb_options.flags & OPTF_OLD_MEM)
-		pm2_WR(p, PM2R_MEM_CONFIG, CVPPC_MEM_CONFIG_OLD);
-	else
-		pm2_WR(p, PM2R_MEM_CONFIG, CVPPC_MEM_CONFIG_NEW);
+	pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
 }
-#endif /* CONFIG_FB_PM2_CVPPC */
-
-/*
- * Generic PCI detection routines
- */
-#ifdef CONFIG_FB_PM2_PCI
-struct {
-	unsigned short vendor, device;
-	char *name;
-	pm2type_t type;
-} pm2pci_cards[] __initdata = {
-	{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
-		"Texas Instruments TVP4020", PM2_TYPE_PERMEDIA2 },
-	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
-		"3dLabs Permedia 2", PM2_TYPE_PERMEDIA2 },
-	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
-		"3dLabs Permedia 2v", PM2_TYPE_PERMEDIA2V },
-	{ 0, 0 }
-};
 
-static int __init pm2pci_detect(struct pm2fb_info* p) {
-	struct pm2pci_par* pci=&p->board_par.pci;
-	struct pci_dev* dev = NULL;
+static void set_pixclock(struct pm2fb_par* par, u32 clk)
+{
 	int i;
-	unsigned char* m;
-#ifdef __sparc__
-	struct pcidev_cookie *pcp;
-#endif
-
-	memset(pci, 0, sizeof(struct pm2pci_par));
-	DPRINTK("scanning PCI bus for known chipsets...\n");
+	unsigned char m, n, p;
 
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		for (i = 0; pm2pci_cards[i].vendor; i++)
-			if (pm2pci_cards[i].vendor == dev->vendor &&
-			    pm2pci_cards[i].device == dev->device) {
-				pci->dev = dev;
-				p->type = pm2pci_cards[i].type;
-				DPRINTK("... found %s\n", pm2pci_cards[i].name);
-				break;
-			}
-		if (pci->dev)
-			break;
-	}
-	if (!pci->dev) {
-		DPRINTK("no PCI board found.\n");
-		return 0;
-	}
-	DPRINTK("PCI board @%08lx %08lx %08lx rom %08lx\n",
-			pci->dev->resource[0].start,
-			pci->dev->resource[1].start,
-			pci->dev->resource[2].start,
-			pci->dev->resource[PCI_ROM_RESOURCE].start);
-#ifdef __sparc__
-	p->regions.rg_base= pci->dev->resource[0].start;
-	p->regions.fb_base= pci->dev->resource[1].start;
-	pcp = pci->dev->sysdata;
-	/* If the user has not asked for a particular mode, lets guess */
-	if (pcp->prom_node &&
-	    !(pm2fb_options.flags & (OPTF_USER|OPTF_USER_VAR))) {
-		char timing[256], *q, *r;
-		unsigned long w, h;
-		int i;
-		prom_getstring(pcp->prom_node, "timing-numbers", timing, 256);
-		/* FIXME: Find out what the actual pixclock is
-		 * and other values as well */
-		if (timing[0]) {
-			w = simple_strtoul(timing, &q, 0);
-			h = 0;
-			if (q == timing) w = 0;
-			if (w) {
-				for (i = 0; i < 3; i++) {
-					for (r = q;
-					     *r && (*r < '0' || *r > '9');
-					     r++)
-						;
-					simple_strtoul(r, &q, 0);
-					if (r == q) break;
-				}
-				if (i < 3) w = 0;
-			}
-			if (w) {
-				for (r = q; *r && (*r < '0' || *r > '9'); r++);
-				h = simple_strtoul(r, &q, 0);
-				if (r == q) w = 0;
-			}
-			if (w == 640 && h == 480) w = 0;
-			if (w) {
-				for (i=0; user_mode[i].name[0] &&
-					  (w != user_mode[i].par.width ||
-					   h != user_mode[i].par.height); i++);
-				if (user_mode[i].name[0])
-					memcpy(&p->current_par,
-					       &user_mode[i].par,
-					       sizeof(user_mode[i].par));
-			}
-		}
-	}
-#else
-	if (pm2fb_options.flags & OPTF_VIRTUAL) {
-		p->regions.rg_base = __pa(pci_resource_start(pci->dev, 0));
-		p->regions.fb_base = __pa(pci_resource_start(pci->dev, 1));
-	}
-	else {
-		p->regions.rg_base = pci_resource_start(pci->dev, 0);
-		p->regions.fb_base = pci_resource_start(pci->dev, 1);
-	}
-#endif
-#ifdef PM2FB_BE_APERTURE
-	p->regions.rg_base += PM2_REGS_SIZE;
-#endif
-	if ((m=MMAP(p->regions.rg_base, PM2_REGS_SIZE))) {
-		pci->mem_control=RD32(m, PM2R_MEM_CONTROL);
-		pci->boot_address=RD32(m, PM2R_BOOT_ADDRESS);
-		pci->mem_config=RD32(m, PM2R_MEM_CONFIG);
-		switch (pci->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
-			case PM2F_MEM_BANKS_1:
-				p->regions.fb_size=0x200000;
-				break;
-			case PM2F_MEM_BANKS_2:
-				p->regions.fb_size=0x400000;
-				break;
-			case PM2F_MEM_BANKS_3:
-				p->regions.fb_size=0x600000;
-				break;
-			case PM2F_MEM_BANKS_4:
-				p->regions.fb_size=0x800000;
-				break;
-		}
-		p->memclock=CVPPC_MEMCLOCK;
-		UNMAP(m, PM2_REGS_SIZE);
-		return 1;
+	switch (par->type) {
+	case PM2_TYPE_PERMEDIA2:
+		pm2_mnp(clk, &m, &n, &p);
+		WAIT_FIFO(par, 8);
+		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
+		DEFW();
+		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
+		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
+		DEFW();
+		pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
+		DEFW();
+		pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
+		DEFR();
+		for (i = 256;
+		     i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED);
+		     i--)
+			;
+		break;
+	case PM2_TYPE_PERMEDIA2V:
+		pm2v_mnp(clk/2, &m, &n, &p);
+		WAIT_FIFO(par, 8);
+		pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CLK0_PRESCALE >> 8);
+		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_PRESCALE, m);
+		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_FEEDBACK, n);
+		pm2v_RDAC_WR(par, PM2VI_RD_CLK0_POSTSCALE, p);
+		pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+		break;
 	}
-	DPRINTK("MMAP() failed.\n");
-	return 0;
 }
 
-static void pm2pci_init(struct pm2fb_info* p) {
-	struct pm2pci_par* pci=&p->board_par.pci;
-
-	WAIT_FIFO(p, 3);
-	pm2_WR(p, PM2R_MEM_CONTROL, pci->mem_control);
-	pm2_WR(p, PM2R_BOOT_ADDRESS, pci->boot_address);
-	DEFW();
-	pm2_WR(p, PM2R_MEM_CONFIG, pci->mem_config);
-}
-#endif /* CONFIG_FB_PM2_PCI */
+static void set_video(struct pm2fb_par* p, u32 video) {
+	u32 tmp;
+	u32 vsync;
 
-/***************************************************************************
- * Console hw acceleration
- ***************************************************************************/
+	vsync = video;
+
+	/*
+	 * The hardware cursor needs +vsync to recognise vert retrace.
+	 * We may not be using the hardware cursor, but the X Glint
+	 * driver may well. So always set +hsync/+vsync and then set
+	 * the RAMDAC to invert the sync if necessary.
+	 */
+	vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK);
+	vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH;
 
-static int pm2fb_blank(int blank_mode, struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-	u32 video;
+	WAIT_FIFO(p, 5);
+	pm2_WR(p, PM2R_VIDEO_CONTROL, vsync);
 
-	if (!i->current_par_valid)
-		return 1;
-	video=i->current_par.video;
-	if (blank_mode>0) {
-		i->is_blank=1;
-		switch (blank_mode-1) {
-			case VESA_NO_BLANKING:		/* FIXME */
-				video=video&~(PM2F_VIDEO_ENABLE);
-				break;
-			case VESA_HSYNC_SUSPEND:
-				video=video&~(PM2F_HSYNC_MASK|
-						PM2F_BLANK_LOW);
-				break;
-			case VESA_VSYNC_SUSPEND:
-				video=video&~(PM2F_VSYNC_MASK|
-						PM2F_BLANK_LOW);
-				break;
-			case VESA_POWERDOWN:
-				video=video&~(PM2F_VSYNC_MASK|
-						PM2F_HSYNC_MASK|
-						PM2F_BLANK_LOW);
-				break;
-		}
+	switch (p->type) {
+	case PM2_TYPE_PERMEDIA2:
+		tmp = PM2F_RD_PALETTE_WIDTH_8;
+		if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
+			tmp |= 4; /* invert hsync */
+		if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
+			tmp |= 8; /* invert vsync */
+		pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, tmp);
+		break;
+	case PM2_TYPE_PERMEDIA2V:
+		tmp = 0;
+		if ((video & PM2F_HSYNC_MASK) == PM2F_HSYNC_ACT_LOW)
+			tmp |= 1; /* invert hsync */
+		if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
+			tmp |= 4; /* invert vsync */
+		pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp);
+		pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1);
+		break;
 	}
-	else
-		i->is_blank=0;
-	set_video(i, video);
-	return 0;
 }
 
-static int pm2fb_pan_display(const struct fb_var_screeninfo* var,
-					struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-
-	if (!i->current_par_valid)
-		return -EINVAL;
-	i->current_par.base=to3264(var->yoffset*i->current_par.width+
-				var->xoffset, i->current_par.depth, 1);
-	WAIT_FIFO(i, 1);
-	pm2_WR(i, PM2R_SCREEN_BASE, i->current_par.base);
-	return 0;
-}
-
-static void pm2fb_pp_bmove(struct display* p, int sy, int sx,
-				int dy, int dx, int height, int width) {
-
-	if (fontwidthlog(p)) {
-		sx=sx<<fontwidthlog(p);
-		dx=dx<<fontwidthlog(p);
-		width=width<<fontwidthlog(p);
-	}
-	else {
-		sx=sx*fontwidth(p);
-		dx=dx*fontwidth(p);
-		width=width*fontwidth(p);
-	}
-	sy=sy*fontheight(p);
-	dy=dy*fontheight(p);
-	height=height*fontheight(p);
-	pm2fb_pp_copy((struct pm2fb_info* )p->fb_info, sx, sy, dx,
-							dy, width, height);
-}
-
-static void pm2fb_bmove(struct display* p, int sy, int sx,
-				int dy, int dx, int height, int width) {
-
-	if (fontwidthlog(p)) {
-		sx=sx<<fontwidthlog(p);
-		dx=dx<<fontwidthlog(p);
-		width=width<<fontwidthlog(p);
-	}
-	else {
-		sx=sx*fontwidth(p);
-		dx=dx*fontwidth(p);
-		width=width*fontwidth(p);
-	}
-	sy=sy*fontheight(p);
-	dy=dy*fontheight(p);
-	height=height*fontheight(p);
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 1, sx, sy, dx, dy,
-							width, height, 0);
-}
-
-#ifdef FBCON_HAS_CFB8
-static void pm2fb_clear8(struct vc_data* conp, struct display* p,
-				int sy, int sx, int height, int width) {
-	u32 c;
-
-	sx=sx*fontwidth(p);
-	width=width*fontwidth(p);
-	sy=sy*fontheight(p);
-	height=height*fontheight(p);
-	c=attr_bgcol_ec(p, conp);
-	c|=c<<8;
-	c|=c<<16;
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
-							width, height, c);
-}
-
-static void pm2fb_clear_margins8(struct vc_data* conp, struct display* p,
-							int bottom_only) {
-	u32 c;
-	u32 sx;
-	u32 sy;
-
-	c=attr_bgcol_ec(p, conp);
-	c|=c<<8;
-	c|=c<<16;
-	sx=conp->vc_cols*fontwidth(p);
-	sy=conp->vc_rows*fontheight(p);
-	if (!bottom_only)
-		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
-}
-
-static struct display_switch pm2_cfb8 = {
-	.setup		= fbcon_cfb8_setup,
-	.bmove		= pm2fb_pp_bmove,
-#ifdef __alpha__
-	/* Not sure why, but this works and the other does not. */
-	/* Also, perhaps we need a separate routine to wait for the
-	   blitter to stop before doing this? */
-	/* In addition, maybe we need to do this for 16 and 32 bit depths? */
-	.clear		= fbcon_cfb8_clear,
-#else
-	.clear		= pm2fb_clear8,
-#endif
-	.putc		= fbcon_cfb8_putc,
-	.putcs		= fbcon_cfb8_putcs,
-	.revc		= fbcon_cfb8_revc,
-	.cursor		= pm2fb_cursor,
-	.set_font	= pm2fb_set_font,
-	.clear_margins	= pm2fb_clear_margins8,
-	.fontwidthmask	= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };
-#endif /* FBCON_HAS_CFB8 */
-
-#ifdef FBCON_HAS_CFB16
-static void pm2fb_clear16(struct vc_data* conp, struct display* p,
-				int sy, int sx, int height, int width) {
-	u32 c;
-
-	sx=sx*fontwidth(p);
-	width=width*fontwidth(p);
-	sy=sy*fontheight(p);
-	height=height*fontheight(p);
-	c=((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	c|=c<<16;
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
-							width, height, c);
-}
-
-static void pm2fb_clear_margins16(struct vc_data* conp, struct display* p,
-							int bottom_only) {
-	u32 c;
-	u32 sx;
-	u32 sy;
-
-	c=((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	c|=c<<16;
-	sx=conp->vc_cols*fontwidth(p);
-	sy=conp->vc_rows*fontheight(p);
-	if (!bottom_only)
-		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
-}
-
-static struct display_switch pm2_cfb16 = {
-	.setup =	fbcon_cfb16_setup,
-	.bmove =	pm2fb_pp_bmove,
-	.clear =	pm2fb_clear16,
-	.putc =		fbcon_cfb16_putc,
-	.putcs =	fbcon_cfb16_putcs,
-	.revc =		fbcon_cfb16_revc,
-	.cursor =	pm2fb_cursor,
-	.set_font =	pm2fb_set_font,
-	.clear_margins =pm2fb_clear_margins16,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif /* FBCON_HAS_CFB16 */
-
-#ifdef FBCON_HAS_CFB24
 /*
- * fast fill for 24bpp works only when red==green==blue
+ *
  */
-static void pm2fb_clear24(struct vc_data* conp, struct display* p,
-				int sy, int sx, int height, int width) {
-	struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
-	u32 c;
-
-	c=attr_bgcol_ec(p, conp);
-	if (		i->palette[c].red==i->palette[c].green &&
-			i->palette[c].green==i->palette[c].blue) {
-		c=((u32 *)p->dispsw_data)[c];
-		c|=(c&0xff0000)<<8;
-		sx=sx*fontwidth(p);
-		width=width*fontwidth(p);
-		sy=sy*fontheight(p);
-		height=height*fontheight(p);
-		pm2fb_block_op(i, 0, 0, 0, sx, sy, width, height, c);
-	}
-	else
-		fbcon_cfb24_clear(conp, p, sy, sx, height, width);
-
-}
 
-static void pm2fb_clear_margins24(struct vc_data* conp, struct display* p,
-							int bottom_only) {
-	struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;
-	u32 sx;
-	u32 sy;
-
-	sx=conp->vc_cols*fontwidth(p);
-	sy=conp->vc_rows*fontheight(p);
-	if (!bottom_only)
-		pm2fb_block_op(i, 0, 0, 0, sx, 0, (p->var.xres-sx),
-			       p->var.yres_virtual, 0L);
-	pm2fb_block_op(i, 0, 0, 0, 0, p->var.yoffset+sy, sx, p->var.yres-sy, 0L);
-}
-
-static struct display_switch pm2_cfb24 = {
-	.setup =	fbcon_cfb24_setup,
-	.bmove =	pm2fb_bmove,
-	.clear =	pm2fb_clear24,
-	.putc =		fbcon_cfb24_putc,
-	.putcs =	fbcon_cfb24_putcs,
-	.revc =		fbcon_cfb24_revc,
-	.cursor =	pm2fb_cursor,
-	.set_font =	pm2fb_set_font,
-	.clear_margins =pm2fb_clear_margins24,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif /* FBCON_HAS_CFB24 */
-
-#ifdef FBCON_HAS_CFB32
-static void pm2fb_clear32(struct vc_data* conp, struct display* p,
-				int sy, int sx, int height, int width) {
-	u32 c;
-
-	sx=sx*fontwidth(p);
-	width=width*fontwidth(p);
-	sy=sy*fontheight(p);
-	height=height*fontheight(p);
-	c=((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,
-							width, height, c);
-}
-
-static void pm2fb_clear_margins32(struct vc_data* conp, struct display* p,
-							int bottom_only) {
-	u32 c;
-	u32 sx;
-	u32 sy;
-
-	c=((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-	sx=conp->vc_cols*fontwidth(p);
-	sy=conp->vc_rows*fontheight(p);
-	if (!bottom_only)
-		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);
-	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,
-				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);
-}
-
-static struct display_switch pm2_cfb32 = {
-	.setup =	fbcon_cfb32_setup,
-	.bmove =	pm2fb_bmove,
-	.clear =	pm2fb_clear32,
-	.putc =		fbcon_cfb32_putc,
-	.putcs =	fbcon_cfb32_putcs,
-	.revc =		fbcon_cfb32_revc,
-	.cursor =	pm2fb_cursor,
-	.set_font =	pm2fb_set_font,
-	.clear_margins =pm2fb_clear_margins32,
-	.fontwidthmask =FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
-};
-#endif /* FBCON_HAS_CFB32 */
-
-/***************************************************************************
- * Framebuffer functions
- ***************************************************************************/
-
-static void pm2fb_detect(void) {}
-
-static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,
-			const void* par, struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-	struct pm2fb_par* p=(struct pm2fb_par* )par;
-
-	strcpy(fix->id, permedia2_name);
-	fix->smem_start=(unsigned long )i->regions.p_fb;
-	fix->smem_len=i->regions.fb_size;
-	fix->mmio_start=(unsigned long )i->regions.p_regs;
-	fix->mmio_len=PM2_REGS_SIZE;
-	fix->accel=FB_ACCEL_3DLABS_PERMEDIA2;
-	fix->type=FB_TYPE_PACKED_PIXELS;
-	fix->visual=p->depth==8?FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;
-	fix->line_length=p->width*p->depth/8;
-	fix->xpanstep=p->depth==24?8:64/p->depth;
-	fix->ypanstep=1;
-	fix->ywrapstep=0;
-	return 0;
-}
-
-#ifdef PM2FB_MASTER_DEBUG
-static void pm2fb_display_var(const struct fb_var_screeninfo* var) {
-
-	printk( KERN_DEBUG
-"- struct fb_var_screeninfo ---------------------------------------------------\n");
-	printk( KERN_DEBUG
-		"resolution: %ux%ux%u (virtual %ux%u+%u+%u)\n",
-			var->xres, var->yres, var->bits_per_pixel,
-			var->xres_virtual, var->yres_virtual,
-			var->xoffset, var->yoffset);
-	printk( KERN_DEBUG
-		"color: %c%c "
-		"R(%u,%u,%u), G(%u,%u,%u), B(%u,%u,%u), T(%u,%u,%u)\n",
-			var->grayscale?'G':'C', var->nonstd?'N':'S',
-			var->red.offset, var->red.length, var->red.msb_right,
-			var->green.offset, var->green.length, var->green.msb_right,
-			var->blue.offset, var->blue.length, var->blue.msb_right,
-			var->transp.offset, var->transp.length,
-			var->transp.msb_right);
-	printk( KERN_DEBUG
-		"timings: %ups (%u,%u)-(%u,%u)+%u+%u\n",
-		var->pixclock,
-		var->left_margin, var->upper_margin, var->right_margin,
-		var->lower_margin, var->hsync_len, var->vsync_len);
-	printk(	KERN_DEBUG
-		"activate %08x accel_flags %08x sync %08x vmode %08x\n",
-		var->activate, var->accel_flags, var->sync, var->vmode);
-	printk(	KERN_DEBUG
-"------------------------------------------------------------------------------\n");
-}
+/**
+ *      pm2fb_check_var - Optional function. Validates a var passed in.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Checks to see if the hardware supports the state requested by
+ *	var passed in.
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	u32 lpitch;
 
-#define pm2fb_decode_var pm2fb_wrapped_decode_var
-#endif
+	if (var->bits_per_pixel != 8  && var->bits_per_pixel != 16 &&
+	    var->bits_per_pixel != 24 && var->bits_per_pixel != 32) {
+		DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
+		return -EINVAL;
+	}
 
-static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
-				void* par, struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-	struct pm2fb_par p;
-	u32 xres;
-	int data64;
+	if (var->xres != var->xres_virtual) {
+		DPRINTK("virtual x resolution != physical x resolution not supported\n");
+		return -EINVAL;
+	}
 
-	memset(&p, 0, sizeof(struct pm2fb_par));
-	if (var->accel_flags & FB_ACCELF_TEXT)
-		p.flags |= PM2FF_ACCEL;
-	p.width=(var->xres_virtual+7)&~7;
-	p.height=var->yres_virtual;
-	p.depth=(var->bits_per_pixel+7)&~7;
-	p.depth=p.depth>32?32:p.depth;
-	data64=p.depth>8 || i->type==PM2_TYPE_PERMEDIA2V;
-	xres=(var->xres+31)&~31;
-	if (p.width<xres+var->xoffset)
-		p.width=xres+var->xoffset;
-	if (p.height<var->yres+var->yoffset)
-		p.height=var->yres+var->yoffset;
-	if (!partprod(xres)) {
-		DPRINTK("width not supported: %u\n", xres);
+	if (var->yres > var->yres_virtual) {
+		DPRINTK("virtual y resolution < physical y resolution not possible\n");
 		return -EINVAL;
 	}
-	if (p.width>2047) {
-		DPRINTK("virtual width not supported: %u\n", p.width);
+
+	if (var->xoffset) {
+		DPRINTK("xoffset not supported\n");
 		return -EINVAL;
 	}
-	if (var->yres<200) {
-		DPRINTK("height not supported: %u\n",
-						(u32 )var->yres);
+
+	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+		DPRINTK("interlace not supported\n");
 		return -EINVAL;
 	}
-	if (p.height<200 || p.height>2047) {
-		DPRINTK("virtual height not supported: %u\n", p.height);
+
+	var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
+	lpitch = var->xres * ((var->bits_per_pixel + 7)>>3);
+
+	if (var->xres < 320 || var->xres > 1600) {
+		DPRINTK("width not supported: %u\n", var->xres);
 		return -EINVAL;
 	}
-	if (p.depth>32) {
-		DPRINTK("depth not supported: %u\n", p.depth);
+
+	if (var->yres < 200 || var->yres > 1200) {
+		DPRINTK("height not supported: %u\n", var->yres);
 		return -EINVAL;
 	}
-	if (p.width*p.height*p.depth/8>i->regions.fb_size) {
+
+	if (lpitch * var->yres_virtual > info->fix.smem_len) {
 		DPRINTK("no memory for screen (%ux%ux%u)\n",
-						p.width, p.height, p.depth);
+			var->xres, var->yres_virtual, var->bits_per_pixel);
 		return -EINVAL;
 	}
-	p.pixclock=PICOS2KHZ(var->pixclock);
-	if (p.pixclock>PM2_MAX_PIXCLOCK) {
-		DPRINTK("pixclock too high (%uKHz)\n", p.pixclock);
+
+	if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
+		DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock));
 		return -EINVAL;
 	}
-	p.hsstart=to3264(var->right_margin, p.depth, data64);
-	p.hsend=p.hsstart+to3264(var->hsync_len, p.depth, data64);
-	p.hbend=p.hsend+to3264(var->left_margin, p.depth, data64);
-	p.htotal=to3264(xres, p.depth, data64)+p.hbend-1;
-	p.vsstart=var->lower_margin?var->lower_margin-1:0;	/* FIXME! */
-	p.vsend=var->lower_margin+var->vsync_len-1;
-	p.vbend=var->lower_margin+var->vsync_len+var->upper_margin;
-	p.vtotal=var->yres+p.vbend-1;
-	p.stride=to3264(p.width, p.depth, 1);
-	p.base=to3264(var->yoffset*xres+var->xoffset, p.depth, 1);
+
+	switch(var->bits_per_pixel) {
+	case 8:
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	case 16:
+		var->red.offset   = 11;
+		var->red.length   = 5;
+		var->green.offset = 5;
+		var->green.length = 6;
+		var->blue.offset  = 0;
+		var->blue.length  = 5;
+		break;
+	case 24:
+		var->red.offset	  = 16;
+		var->green.offset = 8;
+		var->blue.offset  = 0;
+		var->red.length = var->green.length = var->blue.length = 8;
+	case 32:
+		var->red.offset   = 16;
+		var->green.offset = 8;
+		var->blue.offset  = 0;
+		var->red.length = var->green.length = var->blue.length = 8;
+		break;
+	}
+	var->height = var->width = -1;
+
+	var->accel_flags = 0;	/* Can't mmap if this is on */
+
+	DPRINTK("Checking graphics mode at %dx%d depth %d\n",
+		var->xres, var->yres, var->bits_per_pixel);
+	return 0;
+}
+
+/**
+ *      pm2fb_set_par - Alters the hardware state.
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Using the fb_var_screeninfo in fb_info we set the resolution of the
+ *	this particular framebuffer.
+ */
+static int pm2fb_set_par(struct fb_info *info)
+{
+	struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+	u32 pixclock;
+	u32 width, height, depth;
+	u32 hsstart, hsend, hbend, htotal;
+	u32 vsstart, vsend, vbend, vtotal;
+	u32 stride;
+	u32 base;
+	u32 video = 0;
+	u32 clrmode = PM2F_RD_COLOR_MODE_RGB;
+	u32 txtmap = 0;
+	u32 pixsize = 0;
+	u32 clrformat = 0;
+	u32 xres;
+	int data64;
+
+	reset_config(par);
+	clear_palette(par);
+
+	width = (info->var.xres_virtual + 7) & ~7;
+	height = info->var.yres_virtual;
+	depth = (info->var.bits_per_pixel + 7) & ~7;
+	depth = (depth > 32) ? 32 : depth;
+	data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V;
+
+	xres = (info->var.xres + 31) & ~31;
+	pixclock = PICOS2KHZ(info->var.pixclock);
+	if (pixclock > PM2_MAX_PIXCLOCK) {
+		DPRINTK("pixclock too high (%uKHz)\n", pixclock);
+		return -EINVAL;
+	}
+
+	hsstart = to3264(info->var.right_margin, depth, data64);
+	hsend = hsstart + to3264(info->var.hsync_len, depth, data64);
+	hbend = hsend + to3264(info->var.left_margin, depth, data64);
+	htotal = to3264(xres, depth, data64) + hbend - 1;
+	vsstart = (info->var.lower_margin)
+		? info->var.lower_margin - 1
+		: 0;	/* FIXME! */
+	vsend = info->var.lower_margin + info->var.vsync_len - 1;
+	vbend = info->var.lower_margin + info->var.vsync_len + info->var.upper_margin;
+	vtotal = info->var.yres + vbend - 1;
+	stride = to3264(width, depth, 1);
+	base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1);
 	if (data64)
-		p.video|=PM2F_DATA_64_ENABLE;
-	if (var->sync & FB_SYNC_HOR_HIGH_ACT) {
-		if (pm2fb_options.flags & OPTF_LOW_HSYNC) {
+		video |= PM2F_DATA_64_ENABLE;
+
+	if (info->var.sync & FB_SYNC_HOR_HIGH_ACT) {
+		if (lowhsync) {
 			DPRINTK("ignoring +hsync, using -hsync.\n");
-			p.video|=PM2F_HSYNC_ACT_LOW;
+			video |= PM2F_HSYNC_ACT_LOW;
 		} else
-			p.video|=PM2F_HSYNC_ACT_HIGH;
+			video |= PM2F_HSYNC_ACT_HIGH;
 	}
 	else
-		p.video|=PM2F_HSYNC_ACT_LOW;
-	if (var->sync & FB_SYNC_VERT_HIGH_ACT) {
-		if (pm2fb_options.flags & OPTF_LOW_VSYNC) {
+		video |= PM2F_HSYNC_ACT_LOW;
+	if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) {
+		if (lowvsync) {
 			DPRINTK("ignoring +vsync, using -vsync.\n");
-			p.video|=PM2F_VSYNC_ACT_LOW;
+			video |= PM2F_VSYNC_ACT_LOW;
 		} else
-			p.video|=PM2F_VSYNC_ACT_HIGH;
+			video |= PM2F_VSYNC_ACT_HIGH;
 	}
 	else
-		p.video|=PM2F_VSYNC_ACT_LOW;
-	if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {
+		video |= PM2F_VSYNC_ACT_LOW;
+	if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {
 		DPRINTK("interlaced not supported\n");
 		return -EINVAL;
 	}
-	if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
-		p.video|=PM2F_LINE_DOUBLE;
-	if (var->activate==FB_ACTIVATE_NOW)
-		p.video|=PM2F_VIDEO_ENABLE;
-	*((struct pm2fb_par* )par)=p;
-	return 0;
-}
-
-#ifdef PM2FB_MASTER_DEBUG
-#undef pm2fb_decode_var
+	if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)
+		video |= PM2F_LINE_DOUBLE;
+	if (info->var.activate==FB_ACTIVATE_NOW)
+		video |= PM2F_VIDEO_ENABLE;
+	par->video = video;
+
+	info->fix.visual =
+		(depth == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+	info->fix.line_length =
+		info->var.xres * ((info->var.bits_per_pixel + 7) >> 3);
+	info->cmap.len = (info->var.bits_per_pixel == 8) ? 256 : 16;
 
-static int pm2fb_decode_var(const struct fb_var_screeninfo* var,
-				void* par, struct fb_info_gen* info) {
-	int result;
-
-	result=pm2fb_wrapped_decode_var(var, par, info);
-	pm2fb_display_var(var);
-	return result;
-}
+	/*
+	 * Settings calculated. Now write them out.
+	 */
+	if (par->type == PM2_TYPE_PERMEDIA2V) {
+		WAIT_FIFO(par, 1);
+		pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
+	}
+
+	set_aperture(par);
+
+	DEFRW();
+	WAIT_FIFO(par, 19);
+	pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
+		    ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
+	switch (depth) {
+	case 8:
+		pm2_WR(par, PM2R_FB_READ_PIXEL, 0);
+		clrformat = 0x0e;
+		break;
+	case 16:
+		pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
+		clrmode |= PM2F_RD_TRUECOLOR | 0x06;
+		txtmap = PM2F_TEXTEL_SIZE_16;
+		pixsize = 1;
+		clrformat = 0x70;
+		break;
+	case 32:
+		pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
+		clrmode |= PM2F_RD_TRUECOLOR | 0x08;
+		txtmap = PM2F_TEXTEL_SIZE_32;
+		pixsize = 2;
+		clrformat = 0x20;
+		break;
+	case 24:
+		pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
+		clrmode |= PM2F_RD_TRUECOLOR | 0x09;
+#ifndef PM2FB_BE_APERTURE
+		clrmode &= ~PM2F_RD_COLOR_MODE_RGB;
 #endif
-
-static void pm2fb_par2var(struct fb_var_screeninfo* v,
-					const struct pm2fb_par* p) {
-	u32 base;
-
-	memset(v, 0, sizeof(struct fb_var_screeninfo));
-	if (p->flags & PM2FF_ACCEL)
-		v->accel_flags |= FB_ACCELF_TEXT;
-	v->xres_virtual=p->width;
-	v->yres_virtual=p->height;
-	v->xres=(p->htotal+1)-p->hbend;
-	v->yres=(p->vtotal+1)-p->vbend;
-	v->right_margin=p->hsstart;
-	v->hsync_len=p->hsend-p->hsstart;
-	v->left_margin=p->hbend-p->hsend;
-	v->lower_margin=p->vsstart+1;
-	v->vsync_len=p->vsend-v->lower_margin+1;
-	v->upper_margin=p->vbend-v->lower_margin-v->vsync_len;
-	v->bits_per_pixel=p->depth;
-	if (p->video & PM2F_DATA_64_ENABLE) {
-		v->xres=v->xres<<1;
-		v->right_margin=v->right_margin<<1;
-		v->hsync_len=v->hsync_len<<1;
-		v->left_margin=v->left_margin<<1;
-	}
-	switch (p->depth) {
-		case 8:
-			v->red.length=v->green.length=v->blue.length=8;
-			v->xres=v->xres<<2;
-			v->right_margin=v->right_margin<<2;
-			v->hsync_len=v->hsync_len<<2;
-			v->left_margin=v->left_margin<<2;
-			break;
-		case 16:
-			v->red.offset=11;
-			v->red.length=5;
-			v->green.offset=5;
-			v->green.length=6;
-			v->blue.length=5;
-			v->xres=v->xres<<1;
-			v->right_margin=v->right_margin<<1;
-			v->hsync_len=v->hsync_len<<1;
-			v->left_margin=v->left_margin<<1;
-			break;
-		case 32:
-			v->transp.offset=24;
-			v->red.offset=16;
-			v->green.offset=8;
-			v->red.length=v->green.length=v->blue.length=
-							v->transp.length=8;
-			break;
-		case 24:
-			v->blue.offset=16;
-			v->green.offset=8;
-			v->red.length=v->green.length=v->blue.length=8;
-			v->xres=(v->xres<<2)/3;
-			v->right_margin=(v->right_margin<<2)/3;
-			v->hsync_len=(v->hsync_len<<2)/3;
-			v->left_margin=(v->left_margin<<2)/3;
-			break;
-	}
-	base=from3264(p->base, p->depth, 1);
-	v->xoffset=base%v->xres;
-	v->yoffset=base/v->xres;
-	v->height=v->width=-1;
-	v->pixclock=KHZ2PICOS(p->pixclock);
-	if ((p->video & PM2F_HSYNC_MASK)==PM2F_HSYNC_ACT_HIGH)
-		v->sync|=FB_SYNC_HOR_HIGH_ACT;
-	if ((p->video & PM2F_VSYNC_MASK)==PM2F_VSYNC_ACT_HIGH)
-		v->sync|=FB_SYNC_VERT_HIGH_ACT;
-	if (p->video & PM2F_LINE_DOUBLE)
-		v->vmode=FB_VMODE_DOUBLE;
-}
-
-
-static int pm2fb_encode_var(struct fb_var_screeninfo* var,
-				const void* par, struct fb_info_gen* info) {
-
-	pm2fb_par2var(var, (struct pm2fb_par* )par);
-	return 0;
-}
-
-static void set_user_mode(struct pm2fb_info* i) {
-
-	memcpy(&i->current_par, &pm2fb_options.user_mode,
-	       sizeof(i->current_par));
-	if (pm2fb_options.flags & OPTF_YPAN) {
-		i->current_par.height=i->regions.fb_size/
-			(i->current_par.width*i->current_par.depth/8);
-		i->current_par.height=MIN(i->current_par.height,2047);
-		i->current_par.height=MAX(i->current_par.height,
-					  pm2fb_options.user_mode.height);
+		txtmap = PM2F_TEXTEL_SIZE_24;
+		pixsize = 4;
+		clrformat = 0x20;
+		break;
 	}
-}
-
-static void pm2fb_get_par(void* par, struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-
-	if (!i->current_par_valid) {
-		set_user_mode(i);
-		pm2fb_set_par(&i->current_par, info);
+	pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
+	pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
+	pm2_WR(par, PM2R_LB_READ_MODE, partprod(xres));
+	pm2_WR(par, PM2R_TEXTURE_MAP_FORMAT, txtmap | partprod(xres));
+	pm2_WR(par, PM2R_H_TOTAL, htotal);
+	pm2_WR(par, PM2R_HS_START, hsstart);
+	pm2_WR(par, PM2R_HS_END, hsend);
+	pm2_WR(par, PM2R_HG_END, hbend);
+	pm2_WR(par, PM2R_HB_END, hbend);
+	pm2_WR(par, PM2R_V_TOTAL, vtotal);
+	pm2_WR(par, PM2R_VS_START, vsstart);
+	pm2_WR(par, PM2R_VS_END, vsend);
+	pm2_WR(par, PM2R_VB_END, vbend);
+	pm2_WR(par, PM2R_SCREEN_STRIDE, stride);
+	DEFW();
+	pm2_WR(par, PM2R_WINDOW_ORIGIN, 0);
+	pm2_WR(par, PM2R_SCREEN_SIZE, (height << 16) | width);
+	pm2_WR(par, PM2R_SCISSOR_MODE, PM2F_SCREEN_SCISSOR_ENABLE);
+	DEFW();
+	pm2_WR(par, PM2R_SCREEN_BASE, base);
+	DEFW();
+	set_video(par, video);
+	WAIT_FIFO(par, 4);
+	switch (par->type) {
+	case PM2_TYPE_PERMEDIA2:
+		pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE,
+			    PM2F_RD_COLOR_MODE_RGB | PM2F_RD_GUI_ACTIVE | clrmode);
+		break;
+	case PM2_TYPE_PERMEDIA2V:
+		pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
+		pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat);
+		break;
 	}
-	get_screen(i, (struct pm2fb_par* )par);
+	set_pixclock(par, pixclock);
+	return 0;
 }
 
-static void pm2fb_set_par(const void* par, struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-	struct pm2fb_par* p=(struct pm2fb_par* )par;
+/**
+ *  	pm2fb_setcolreg - Sets a color register.
+ *      @regno: boolean, 0 copy local, 1 get_user() function
+ *      @red: frame buffer colormap structure
+ *	@green: The green value which can be up to 16 bits wide
+ *	@blue:  The blue value which can be up to 16 bits wide.
+ *	@transp: If supported the alpha value which can be up to 16 bits wide.
+ *      @info: frame buffer info structure
+ *
+ *  	Set a single color register. The values supplied have a 16 bit
+ *  	magnitude which needs to be scaled in this function for the hardware.
+ *	Pretty much a direct lift from tdfxfb.c.
+ *
+ *	Returns negative errno on error, or zero on success.
+ */
+static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
+			   unsigned blue, unsigned transp,
+			   struct fb_info *info)
+{
+	struct pm2fb_par *par = (struct pm2fb_par *) info->par;
 
-	if (screen_is_valid(i)) {
-		i->current_par.base=p->base;
-		if (!memcmp(p, &i->current_par, sizeof(struct pm2fb_par))) {
-			WAIT_FIFO(i, 1);
-			pm2_WR(i, PM2R_SCREEN_BASE, p->base);
-			return;
-		}
-	}
+	if (regno >= info->cmap.len)  /* no. of hw registers */
+		return 1;
+	/*
+	 * Program hardware... do anything you want with transp
+	 */
 
-	wait_pm2(i);
-	reset_units(i);
-	set_screen(i, p);
-	i->current_par=*p;
-	i->current_par_valid=1;
-#ifdef PM2FB_HW_CURSOR	
-	if (i->cursor) {
-		pm2v_set_cursor_color(i, cursor_color_map,
-				cursor_color_map, cursor_color_map);
-		pm2v_set_cursor_shape(i);
+	/* grayscale works only partially under directcolor */
+	if (info->var.grayscale) {
+		/* grayscale = 0.30*R + 0.59*G + 0.11*B */
+		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
+	}
+
+	/* Directcolor:
+	 *   var->{color}.offset contains start of bitfield
+	 *   var->{color}.length contains length of bitfield
+	 *   {hardwarespecific} contains width of DAC
+	 *   cmap[X] is programmed to (X << red.offset) | (X << green.offset) | (X << blue.offset)
+	 *   RAMDAC[X] is programmed to (red, green, blue)
+	 *
+	 * Pseudocolor:
+	 *    uses offset = 0 && length = DAC register width.
+	 *    var->{color}.offset is 0
+	 *    var->{color}.length contains widht of DAC
+	 *    cmap is not used
+	 *    DAC[X] is programmed to (red, green, blue)
+	 * Truecolor:
+	 *    does not use RAMDAC (usually has 3 of them).
+	 *    var->{color}.offset contains start of bitfield
+	 *    var->{color}.length contains length of bitfield
+	 *    cmap is programmed to (red << red.offset) | (green << green.offset) |
+	 *                      (blue << blue.offset) | (transp << transp.offset)
+	 *    RAMDAC does not exist
+	 */
+#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16)
+	switch (info->fix.visual) {
+	case FB_VISUAL_TRUECOLOR:
+	case FB_VISUAL_PSEUDOCOLOR:
+		red = CNVT_TOHW(red, info->var.red.length);
+		green = CNVT_TOHW(green, info->var.green.length);
+		blue = CNVT_TOHW(blue, info->var.blue.length);
+		transp = CNVT_TOHW(transp, info->var.transp.length);
+		set_color(par, regno, red, green, blue);
+		break;
+	case FB_VISUAL_DIRECTCOLOR:
+		/* example here assumes 8 bit DAC. Might be different
+		 * for your hardware */
+		red = CNVT_TOHW(red, 8);
+		green = CNVT_TOHW(green, 8);
+		blue = CNVT_TOHW(blue, 8);
+		/* hey, there is bug in transp handling... */
+		transp = CNVT_TOHW(transp, 8);
+		break;
 	}
-#endif
-}
+#undef CNVT_TOHW
+	/* Truecolor has hardware independent palette */
+	if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
+		u32 v;
+
+		if (regno >= 16)
+			return 1;
+
+		v = (red << info->var.red.offset) |
+			(green << info->var.green.offset) |
+			(blue << info->var.blue.offset) |
+			(transp << info->var.transp.offset);
 
-static int pm2fb_getcolreg(unsigned regno,
-			unsigned* red, unsigned* green, unsigned* blue,
-				unsigned* transp, struct fb_info* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-
-	if (regno<256) {
-		*red=i->palette[regno].red<<8|i->palette[regno].red;
-		*green=i->palette[regno].green<<8|i->palette[regno].green;
-		*blue=i->palette[regno].blue<<8|i->palette[regno].blue;
-		*transp=i->palette[regno].transp<<8|i->palette[regno].transp;
-	}
-	return regno>255;
-}
-
-static int pm2fb_setcolreg(unsigned regno,
-			unsigned red, unsigned green, unsigned blue,
-				unsigned transp, struct fb_info* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-
-	if (regno<16) {
-		switch (i->current_par.depth) {
-#ifdef FBCON_HAS_CFB8
-			case 8:
-				break;
-#endif
-#ifdef FBCON_HAS_CFB16
-			case 16:
-				i->cmap.cmap16[regno]=
-					((u32 )red & 0xf800) |
-					(((u32 )green & 0xfc00)>>5) |
-					(((u32 )blue & 0xf800)>>11);
-				break;
-#endif
-#ifdef FBCON_HAS_CFB24
-			case 24:
-				i->cmap.cmap24[regno]=
-					(((u32 )blue & 0xff00) << 8) |
-					((u32 )green & 0xff00) |
-					(((u32 )red & 0xff00) >> 8);
-				break;
-#endif
-#ifdef FBCON_HAS_CFB32
-			case 32:
-	   			i->cmap.cmap32[regno]=
-					(((u32 )transp & 0xff00) << 16) |
-		    			(((u32 )red & 0xff00) << 8) |
-					(((u32 )green & 0xff00)) |
-			 		(((u32 )blue & 0xff00) >> 8);
-				break;
-#endif
-			default:
-				DPRINTK("bad depth %u\n",
-						i->current_par.depth);
-				break;
-		}
-	}
-	if (regno<256) {
-		i->palette[regno].red=red >> 8;
-		i->palette[regno].green=green >> 8;
-		i->palette[regno].blue=blue >> 8;
-		i->palette[regno].transp=transp >> 8;
-		if (i->current_par.depth==8)
-			set_color(i, regno, red>>8, green>>8, blue>>8);
-	}
-	return regno>255;
-}
-
-static void pm2fb_set_disp(const void* par, struct display* disp,
-						struct fb_info_gen* info) {
-	struct pm2fb_info* i=(struct pm2fb_info* )info;
-	struct pm2fb_par* p=(struct pm2fb_par* )par;
-	unsigned long flags;
-
-	local_irq_save(flags);
-#ifdef __alpha__
-	disp->screen_base=i->regions.v_fb + dense_mem(i->regions.v_fb);
-#else
-	disp->screen_base=i->regions.v_fb;
-#endif
-	switch (p->depth) {
-#ifdef FBCON_HAS_CFB8
+		switch (info->var.bits_per_pixel) {
 		case 8:
-			if (p->flags & PM2FF_ACCEL)
-				disp->dispsw=&pm2_cfb8;
-			else
-				disp->dispsw=&fbcon_cfb8;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB16
-		case 16:
-			if (p->flags & PM2FF_ACCEL)
-				disp->dispsw=&pm2_cfb16;
-			else
-				disp->dispsw=&fbcon_cfb16;
-			disp->dispsw_data=i->cmap.cmap16;
+			/* Yes some hand held devices have this. */
+           		((u8*)(info->pseudo_palette))[regno] = v;
+			break;
+   		case 16:
+           		((u16*)(info->pseudo_palette))[regno] = v;
 			break;
-#endif
-#ifdef FBCON_HAS_CFB24
 		case 24:
-			if (p->flags & PM2FF_ACCEL)
-				disp->dispsw=&pm2_cfb24;
-			else
-				disp->dispsw=&fbcon_cfb24;
-			disp->dispsw_data=i->cmap.cmap24;
-			break;
-#endif
-#ifdef FBCON_HAS_CFB32
-		case 32:
-			if (p->flags & PM2FF_ACCEL)
-				disp->dispsw=&pm2_cfb32;
-			else
-				disp->dispsw=&fbcon_cfb32;
-			disp->dispsw_data=i->cmap.cmap32;
-			break;
-#endif
-		default:
-			disp->dispsw=&fbcon_dummy;
+		case 32:
+           		((u32*)(info->pseudo_palette))[regno] = v;
 			break;
-	}
-	local_irq_restore(flags);
-}
-
-#ifdef PM2FB_HW_CURSOR
-/***************************************************************************
- * Hardware cursor support
- ***************************************************************************/
- 
-static u8 cursor_bits_lookup[16] = {
-	0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
-	0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
-};
-
-static u8 cursor_mask_lookup[16] = {
-	0x00, 0x80, 0x20, 0xa0, 0x08, 0x88, 0x28, 0xa8,
-	0x02, 0x82, 0x22, 0xa2, 0x0a, 0x8a, 0x2a, 0xaa
-};
-
-static void pm2v_set_cursor_color(struct pm2fb_info *fb, u8 *red, u8 *green, u8 *blue)
-{
-	struct pm2_cursor *c = fb->cursor;
-	int i;
-
-	for (i = 0; i < 2; i++) {
-		c->color[3*i] = red[i];
-		c->color[3*i+1] = green[i];
-		c->color[3*i+2] = blue[i];
-	}
-
-	WAIT_FIFO(fb, 14);
-	pm2_WR(fb, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CURSOR_PALETTE >> 8);
-	for (i = 0; i < 6; i++)
-		pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PALETTE+i, c->color[i]);
-	pm2_WR(fb, PM2VR_RD_INDEX_HIGH, 0);
-}
-
-static void pm2v_set_cursor_shape(struct pm2fb_info *fb)
-{
-	struct pm2_cursor *c = fb->cursor;
-	u8 m, b;
-	int i, x, y;
-
-	WAIT_FIFO(fb, 1);
-	pm2_WR(fb, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CURSOR_PATTERN >> 8);
-	for (y = 0, i = 0; y < c->size.y; y++) {
-		WAIT_FIFO(fb, 32);
-		for (x = 0; x < c->size.x >> 3; x++) {
-			m = c->mask[x][y];
-			b = c->bits[x][y];
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i,
-				     cursor_mask_lookup[m >> 4] |
-				     cursor_bits_lookup[(b & m) >> 4]);
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i + 1,
-				     cursor_mask_lookup[m & 0x0f] |
-				     cursor_bits_lookup[(b & m) & 0x0f]);
-			i+=2;
-		}
-		for ( ; x < 8; x++) {
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i, 0);
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i + 1, 0);
-			i+=2;
-		}
-	}
-	for (; y < 64; y++) {
-		WAIT_FIFO(fb, 32);
-		for (x = 0; x < 8; x++) {
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i, 0);
-			pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_PATTERN + i + 1, 0);
-			i+=2;
 		}
+		return 0;
 	}
-	WAIT_FIFO(fb, 1);
-	pm2_WR(fb, PM2VR_RD_INDEX_HIGH, 0);
+	/* ... */
+	return 0;
 }
 
-static void pm2v_set_cursor(struct pm2fb_info *fb, int on)
+/**
+ *      pm2fb_pan_display - Pans the display.
+ *      @var: frame buffer variable screen structure
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *	Pan (or wrap, depending on the `vmode' field) the display using the
+ *  	`xoffset' and `yoffset' fields of the `var' structure.
+ *  	If the values don't fit, return -EINVAL.
+ *
+ *      Returns negative errno on error, or zero on success.
+ *
+ */
+static int pm2fb_pan_display(struct fb_var_screeninfo *var,
+			     struct fb_info *info)
 {
-	struct pm2_cursor *c = fb->cursor;
-	int x = c->pos.x;
+	struct pm2fb_par *p = (struct pm2fb_par *) info->par;
+	u32 base;
+	u32 depth;
+	u32 xres;
 
-	if (!on) x = 4000;
-	WAIT_FIFO(fb, 14);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_X_LOW, x & 0xff);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_X_HIGH, (x >> 8) & 0x0f);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_Y_LOW, c->pos.y & 0xff);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_Y_HIGH, (c->pos.y >> 8) & 0x0f);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_X_HOT, c->hot.x & 0x3f);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_Y_HOT, c->hot.y & 0x3f);
-	pm2v_RDAC_WR(fb, PM2VI_RD_CURSOR_MODE, 0x11);
+	xres = (var->xres + 31) & ~31;
+	depth = (var->bits_per_pixel + 7) & ~7;
+	depth = (depth > 32) ? 32 : depth;
+	base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
+	WAIT_FIFO(p, 1);
+	pm2_WR(p, PM2R_SCREEN_BASE, base);
+	return 0;
 }
 
-static void pm2_cursor_timer_handler(unsigned long dev_addr)
+/**
+ *      pm2fb_blank - Blanks the display.
+ *      @blank_mode: the blank mode we want.
+ *      @info: frame buffer structure that represents a single frame buffer
+ *
+ *      Blank the screen if blank_mode != 0, else unblank. Return 0 if
+ *      blanking succeeded, != 0 if un-/blanking failed due to e.g. a
+ *      video mode which doesn't support it. Implements VESA suspend
+ *      and powerdown modes on hardware that supports disabling hsync/vsync:
+ *      blank_mode == 2: suspend vsync
+ *      blank_mode == 3: suspend hsync
+ *      blank_mode == 4: powerdown
+ *
+ *      Returns negative errno on error, or zero on success.
+ *
+ */
+static int pm2fb_blank(int blank_mode, struct fb_info *info)
 {
-	struct pm2fb_info *fb = (struct pm2fb_info *)dev_addr;
+	struct pm2fb_par *par = (struct pm2fb_par *) info->par;
+	u32 video = par->video;
 
-	if (!fb->cursor->enable)
-		goto out;
-
-	if (fb->cursor->vbl_cnt && --fb->cursor->vbl_cnt == 0) {
-		fb->cursor->on ^= 1;
-		pm2v_set_cursor(fb, fb->cursor->on);
-		fb->cursor->vbl_cnt = fb->cursor->blink_rate;
+	switch (blank_mode) {
+	case 0: 	/* Screen: On; HSync: On, VSync: On */
+		break;
+	case 1: 	/* Screen: Off; HSync: On, VSync: On */
+		video &= ~PM2F_VIDEO_ENABLE;
+		break;
+	case 2: /* Screen: Off; HSync: On, VSync: Off */
+		video &= ~(PM2F_VIDEO_ENABLE | PM2F_VSYNC_MASK | PM2F_BLANK_LOW );
+		break;
+	case 3: /* Screen: Off; HSync: Off, VSync: On */
+		video &= ~(PM2F_VIDEO_ENABLE | PM2F_HSYNC_MASK | PM2F_BLANK_LOW );
+		break;
+	case 4: /* Screen: Off; HSync: Off, VSync: Off */
+		video &= ~(PM2F_VIDEO_ENABLE | PM2F_VSYNC_MASK | PM2F_HSYNC_MASK|
+			   PM2F_BLANK_LOW);
+		break;
 	}
-
-out:
-	fb->cursor->timer->expires = jiffies + (HZ / 50);
-	add_timer(fb->cursor->timer);
+	set_video(par, video);
+	return 0;
 }
 
-static void pm2fb_cursor(struct display *p, int mode, int x, int y)
-{
-	struct pm2fb_info *fb = (struct pm2fb_info *)p->fb_info;
-	struct pm2_cursor *c = fb->cursor;
+/* ------------ Hardware Independent Functions ------------ */
 
-	if (!c) return;
+/*
+ *  Frame buffer operations
+ */
 
-	x *= fontwidth(p);
-	y *= fontheight(p);
-	if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->enable)
-		return;
+static struct fb_ops pm2fb_ops = {
+	.owner		= THIS_MODULE,
+	.fb_check_var	= pm2fb_check_var,
+	.fb_set_par	= pm2fb_set_par,
+	.fb_setcolreg	= pm2fb_setcolreg,
+	.fb_blank	= pm2fb_blank,
+	.fb_pan_display	= pm2fb_pan_display,
+	.fb_fillrect	= cfb_fillrect,
+	.fb_copyarea	= cfb_copyarea,
+	.fb_imageblit	= cfb_imageblit,
+	.fb_cursor	= soft_cursor,
+};
 
-	c->enable = 0;
-	if (c->on)
-		pm2v_set_cursor(fb, 0);
-	c->pos.x = x;
-	c->pos.y = y;
+/*
+ * PCI stuff
+ */
 
-	switch (mode) {
-	case CM_ERASE:
-		c->on = 0;
-		break;
 
-	case CM_DRAW:
-	case CM_MOVE:
-		if (c->on)
-			pm2v_set_cursor(fb, 1);
-		else
-			c->vbl_cnt = CURSOR_DRAW_DELAY;
-		c->enable = 1;
+/**
+ * Device initialisation
+ *
+ * Initialise and allocate resource for PCI device.
+ *
+ * @param	pdev	PCI device.
+ * @param	id	PCI device ID.
+ */
+static int __devinit pm2fb_probe(struct pci_dev *pdev,
+				 const struct pci_device_id *id)
+{
+	struct pm2fb_par *default_par;
+	struct fb_info *info;
+	int size, err;
+	u32 pci_mem_config;
+	int err_retval = -ENXIO;
+
+	err = pci_enable_device(pdev);
+	if ( err ) {
+		printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
+		return err;
+	}
+
+	size = sizeof(struct fb_info) + sizeof(struct pm2fb_par) + 16 * sizeof(u32);
+
+	info = kmalloc(size, GFP_KERNEL);
+	if ( !info )
+		return -ENOMEM;
+	memset(info, 0, size);
+
+	default_par = (struct pm2fb_par *) (info + 1);
+
+	switch (pdev->device) {
+	case  PCI_DEVICE_ID_TI_TVP4020:
+		strcpy(pm2fb_fix.id, "TVP4020");
+		default_par->type = PM2_TYPE_PERMEDIA2;
+		break;
+	case  PCI_DEVICE_ID_3DLABS_PERMEDIA2:
+		strcpy(pm2fb_fix.id, "Permedia2");
+		default_par->type = PM2_TYPE_PERMEDIA2;
+		break;
+	case  PCI_DEVICE_ID_3DLABS_PERMEDIA2V:
+		strcpy(pm2fb_fix.id, "Permedia2v");
+		default_par->type = PM2_TYPE_PERMEDIA2V;
 		break;
 	}
-}
 
-static struct pm2_cursor * __init pm2_init_cursor(struct pm2fb_info *fb)
-{
-	struct pm2_cursor *cursor;
+	pm2fb_fix.mmio_start = pci_resource_start(pdev, 0);
+	pm2fb_fix.mmio_len = PM2_REGS_SIZE;
 
-	if (fb->type != PM2_TYPE_PERMEDIA2V)
-		return 0; /* FIXME: Support hw cursor everywhere */
+#ifdef PM2FB_BE_APERTURE
+	pm2fb_fix.mmio_start += PM2_REGS_SIZE;
+#endif
+
+	/* Registers - request region and map it. */
+	if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
+				 "pm2fb regbase") ) {
+		printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n");
+		goto err_exit_neither;
+	}
+	default_par->v_regs =
+		ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+	if ( !default_par->v_regs ) {
+		printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
+		       pm2fb_fix.id);
+		release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+		goto err_exit_neither;
+	}
+
+	/* Now work out how big lfb is going to be. */
+	pci_mem_config = RD32(default_par->v_regs, PM2R_MEM_CONFIG);
+	switch(pci_mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
+	case PM2F_MEM_BANKS_1:
+		default_par->fb_size=0x200000;
+		break;
+	case PM2F_MEM_BANKS_2:
+		default_par->fb_size=0x400000;
+		break;
+	case PM2F_MEM_BANKS_3:
+		default_par->fb_size=0x600000;
+		break;
+	case PM2F_MEM_BANKS_4:
+		default_par->fb_size=0x800000;
+		break;
+	}
+	default_par->memclock = CVPPC_MEMCLOCK;
+	pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
+	pm2fb_fix.smem_len = default_par->fb_size;
+
+	/* Linear frame buffer - request region and map it. */
+	if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
+				 "pm2fb smem") ) {
+		printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
+		goto err_exit_mmio;
+	}
+	info->screen_base = default_par->v_fb =
+		ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
+	if ( !default_par->v_fb ) {
+		printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
+		release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
+		goto err_exit_mmio;
+	}
+
+	info->fbops		= &pm2fb_ops;
+	info->fix		= pm2fb_fix;
+	info->par		= default_par;
+	info->pseudo_palette	= (void *)(default_par + 1);
+	info->flags		= FBINFO_FLAG_DEFAULT;
+
+#ifndef MODULE
+	if (!mode)
+		mode = "640x480@60";
+
+	err = fb_find_mode(&info->var, info, mode, NULL, 0, NULL, 8);
+	if (!err || err == 4)
+#endif
+		info->var = pm2fb_var;
 
-	cursor = kmalloc(sizeof(struct pm2_cursor), GFP_ATOMIC);
-	if (!cursor)
-		return 0;
-	memset(cursor, 0, sizeof(*cursor));
+	size = (info->var.bits_per_pixel == 8) ? 256 : 16;
+	fb_alloc_cmap(&info->cmap, size, 0);
 
-	cursor->timer = kmalloc(sizeof(*cursor->timer), GFP_KERNEL);
-	if (!cursor->timer) {
-		kfree(cursor);
-		return 0;
-	}
-	memset(cursor->timer, 0, sizeof(*cursor->timer));
+	if (register_framebuffer(info) < 0)
+		goto err_exit_both;
 
-	cursor->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
+	printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n",
+	       info->node, info->fix.id, default_par->fb_size / 1024);
 
-	if (curblink) {
-		init_timer(cursor->timer);
-		cursor->timer->expires = jiffies + (HZ / 50);
-		cursor->timer->data = (unsigned long)fb;
-		cursor->timer->function = pm2_cursor_timer_handler;
-		add_timer(cursor->timer);
-	}
+	/*
+	 * Our driver data
+	 */
+	pci_set_drvdata(pdev, info);
+
+	return 0;
 
-	return cursor;
+ err_exit_both:
+	iounmap((void*) pm2fb_fix.smem_start);
+	release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
+ err_exit_mmio:
+	iounmap((void*) pm2fb_fix.mmio_start);
+	release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
+ err_exit_neither:
+	kfree(info);
+	return err_retval;
 }
 
-static int pm2fb_set_font(struct display *d, int width, int height)
+/**
+ * Device removal.
+ *
+ * Release all device resources.
+ *
+ * @param	pdev	PCI device to clean up.
+ */
+static void __devexit pm2fb_remove(struct pci_dev *pdev)
 {
-	struct pm2fb_info *fb = (struct pm2fb_info *)d->fb_info;
-	struct pm2_cursor *c = fb->cursor;
-	int i, j;
+	struct fb_info* info = pci_get_drvdata(pdev);
+	struct fb_fix_screeninfo* fix = &info->fix;
+
+	unregister_framebuffer(info);
+
+	iounmap((void*) fix->smem_start);
+	release_mem_region(fix->smem_start, fix->smem_len);
+	iounmap((void*) fix->mmio_start);
+	release_mem_region(fix->mmio_start, fix->mmio_len);
 
-	if (c) {
-		if (!width || !height) {
-			width = 8;
-			height = 16;
-		}
+	pci_set_drvdata(pdev, NULL);
+	kfree(info);
+}
 
-		c->hot.x = 0;
-		c->hot.y = 0;
-		c->size.x = width;
-		c->size.y = height;
-
-		memset(c->bits, 0xff, sizeof(c->bits));
-		memset(c->mask, 0, sizeof(c->mask));
-
-		for (i = 0, j = width; j >= 0; j -= 8, i++) {
-			c->mask[i][height-2] = (j >= 8) ? 0xff : (0xff << (8 - j));
-			c->mask[i][height-1] = (j >= 8) ? 0xff : (0xff << (8 - j));
-		}
+static struct pci_device_id pm2fb_id_table[] = {
+	{ PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
+	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+	  0xff0000, 0 },
+	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
+	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+	  0xff0000, 0 },
+	{ PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
+	  PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
+	  0xff0000, 0 },
+	{ 0, }
+};
 
-		pm2v_set_cursor_color(fb, cursor_color_map, cursor_color_map, cursor_color_map);
-		pm2v_set_cursor_shape(fb);
-	}
-	return 1;
-}
-#endif /* PM2FB_HW_CURSOR */
+static struct pci_driver pm2fb_driver = {
+	.name		= "pm2fb",
+	.id_table 	= pm2fb_id_table,
+	.probe 		= pm2fb_probe,
+	.remove 	= __devexit_p(pm2fb_remove),
+};
 
-/***************************************************************************
- * Begin of public functions
- ***************************************************************************/
+MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
 
-#ifdef MODULE
-static void pm2fb_cleanup(void) {
-	struct pm2fb_info* i=&fb_info;
 
-	unregister_framebuffer((struct fb_info* )info);
-	pm2fb_reset(i);
-	
- 	UNMAP(i->regions.v_fb, i->regions.fb_size);
- 	release_mem_region(i->regions.p_fb, i->regions.fb_size);
- 
- 	UNMAP(i->regions.v_regs, PM2_REGS_SIZE);
- 	release_mem_region(i->regions.p_regs, PM2_REGS_SIZE);
-	
-	if (board_table[i->board].cleanup)
-		board_table[i->board].cleanup(i);
+/*
+ *  Initialization
+ */
+
+int __init pm2fb_init(void)
+{
+	return pci_module_init(&pm2fb_driver);
 }
-#endif /* MODULE */
 
-int __init pm2fb_init(void) {
+/*
+ *  Cleanup
+ */
 
-	MOD_INC_USE_COUNT;
-	memset(&fb_info, 0, sizeof(fb_info));
-
-	if (!pm2fb_conf(&fb_info)) {
-		MOD_DEC_USE_COUNT;
-		return -ENXIO;
-	}
-
-        /* Pick up user_var settings if set. */
-	if ((pm2fb_options.flags & OPTF_USER_VAR) &&
-	    pm2fb_decode_var(&user_var, &pm2fb_options.user_mode,
-			     &fb_info.gen)<0) {
-		printk("pm2fb: user supplied var: mode is bad.\n");
-		memcpy(&pm2fb_options.user_mode,
-		       &user_mode[DEFAULT_USER_MODE].par,
-		       sizeof(struct pm2fb_par));
-	}
-	memcpy(&fb_info.current_par, &pm2fb_options.user_mode,
-					sizeof(fb_info.current_par));
-
-	pm2fb_reset(&fb_info);
-	fb_info.disp.scrollmode=SCROLL_YNOMOVE;
-	fb_info.gen.parsize=sizeof(struct pm2fb_par);
-	fb_info.gen.fbhw=&pm2fb_hwswitch;
-	strcpy(fb_info.gen.info.modename, permedia2_name);
-	fb_info.gen.info.flags=FBINFO_FLAG_DEFAULT;
-	fb_info.gen.info.fbops=&pm2fb_ops;
-	fb_info.gen.info.disp=&fb_info.disp;
-	strcpy(fb_info.gen.info.fontname, pm2fb_options.font);
-	fb_info.gen.info.switch_con=&fbgen_switch;
-	fb_info.gen.info.updatevar=&fbgen_update_var;
-
-	fbgen_get_var(&fb_info.disp.var, -1, &fb_info.gen.info);
-	fbgen_do_set_var(&fb_info.disp.var, 1, &fb_info.gen);
-	fbgen_set_disp(-1, &fb_info.gen);
-	fbgen_install_cmap(0, &fb_info.gen);
-
-	if (register_framebuffer(&fb_info.gen.info)<0) {
-		printk(KERN_ERR "pm2fb: unable to register.\n");
-		MOD_DEC_USE_COUNT;
-		return -EINVAL;
-	}
-	printk(KERN_INFO "fb%d: %s (%s), using %uK of video memory.\n",
-				fb_info.gen.info.node,
-				board_table[fb_info.board].name,
-				permedia2_name,
-				(u32 )(fb_info.regions.fb_size>>10));
-	return 0;
+static void __exit pm2fb_exit(void)
+{
+	pci_unregister_driver(&pm2fb_driver);
 }
 
-static void __init pm2fb_mode_setup(char* options) {
-	int i;
+/*
+ *  Setup
+ */
+
+/**
+ * Parse user speficied options.
+ *
+ * This is, comma-separated options following `video=pm2fb:'.
+ */
+int __init pm2fb_setup(char *options)
+{
+	char* this_opt;
 
-	for (i=0; user_mode[i].name[0] &&
-		strcmp(options, user_mode[i].name); i++);
-	if (user_mode[i].name[0]) {
-		memcpy(&pm2fb_options.user_mode, &user_mode[i].par,
-					sizeof(pm2fb_options.user_mode));
-		pm2fb_options.flags|=OPTF_USER;
-	}
-}
-
-static void __init pm2fb_font_setup(char* options) {
-	strlcpy(pm2fb_options.font, options, sizeof(pm2fb_options.font));
-}
-
-static void __init pm2fb_var_setup(char* options) {
-	char* next;
-
-	pm2fb_par2var(&user_var, &pm2fb_options.user_mode);
-
-	while (options) {
-		if ((next=strchr(options, ';')))
-			*(next++)='\0';
-		if (!strncmp(options, "bpp:", 4))
-			user_var.bits_per_pixel=
-				simple_strtoul(options+4, NULL, 0);
-		else if (!strncmp(options, "xres:", 5))
-			user_var.xres=simple_strtoul(options+5, NULL, 0);
-		else if (!strncmp(options, "yres:", 5))
-			user_var.yres=simple_strtoul(options+5, NULL, 0);
-		else if (!strncmp(options, "vxres:", 6))
-			user_var.xres_virtual=
-				simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "vyres:", 6))
-			user_var.yres_virtual=
-				simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "left:", 5))
-			user_var.left_margin=
-				simple_strtoul(options+5, NULL, 0);
-		else if (!strncmp(options, "right:", 6))
-			user_var.right_margin=
-				simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "lower:", 6))
-			user_var.lower_margin=
-				simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "upper:", 6))
-			user_var.upper_margin=
-				simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "hslen:", 6))
-			user_var.hsync_len=simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "vslen:", 6))
-			user_var.vsync_len=simple_strtoul(options+6, NULL, 0);
-		else if (!strncmp(options, "pixclock:", 9))
-			user_var.pixclock=simple_strtoul(options+9, NULL, 0);
-		else if (!strcmp(options, "+hsync"))
-			user_var.sync|=FB_SYNC_HOR_HIGH_ACT;
-		else if (!strcmp(options, "-hsync"))
-			user_var.sync&=~FB_SYNC_HOR_HIGH_ACT;
-		else if (!strcmp(options, "+vsync"))
-			user_var.sync|=FB_SYNC_VERT_HIGH_ACT;
-		else if (!strcmp(options, "-vsync"))
-			user_var.sync&=~FB_SYNC_VERT_HIGH_ACT;
-		else if (!strcmp(options, "+double"))
-			user_var.vmode|=FB_VMODE_DOUBLE;
-		else if (!strcmp(options, "-double"))
-			user_var.vmode&=~FB_VMODE_DOUBLE;
-		else if (!strcmp(options, "+accel"))
-			user_var.accel_flags|=FB_ACCELF_TEXT;
-		else if (!strcmp(options, "-accel"))
-			user_var.accel_flags&=~FB_ACCELF_TEXT;
-		options=next;
-	}
-	pm2fb_options.flags|=OPTF_USER_VAR;
-}
-
-int __init pm2fb_setup(char* options) {
-	char* next;
-
-	while (options) {
-		if ((next=strchr(options, ',')))
-			*(next++)='\0';
-		if (!strncmp(options, "font:", 5))
-			pm2fb_font_setup(options+5);
-		else if (!strncmp(options, "mode:", 5))
-			pm2fb_mode_setup(options+5);
-		else if (!strncmp(options, "var:", 4))
-			pm2fb_var_setup(options+4);
-		else if (!strcmp(options, "ypan"))
-			pm2fb_options.flags |= OPTF_YPAN;
-		else if (!strcmp(options, "oldmem"))
-			pm2fb_options.flags |= OPTF_OLD_MEM;
-		else if (!strcmp(options, "virtual"))
-			pm2fb_options.flags |= OPTF_VIRTUAL;
-		else if (!strcmp(options, "lowhsync"))
-			pm2fb_options.flags |= OPTF_LOW_HSYNC;
-		else if (!strcmp(options, "lowvsync"))
-			pm2fb_options.flags |= OPTF_LOW_VSYNC;
-		else if (!strcmp(options, "noblink"))
-			curblink=0;
-		options=next;
+	if (!options || !*options)
+		return 0;
+
+	while ((this_opt = strsep(&options, ",")) != NULL) {
+		if (!*this_opt)
+			continue;
+		if(!strcmp(this_opt, "lowhsync")) {
+			lowhsync = 1;
+		} else if(!strcmp(this_opt, "lowvsync")) {
+			lowvsync = 1;
+		} else {
+			mode = this_opt;
+		}
 	}
-	user_var.activate=FB_ACTIVATE_NOW;
 	return 0;
 }
 
-/***************************************************************************
- * Begin of module functions
- ***************************************************************************/
-
-#ifdef MODULE
-
-MODULE_LICENSE("GPL");
 
-static char *mode = NULL;
+/* ------------------------------------------------------------------------- */
 
-MODULE_PARM(mode, "s");
+/* ------------------------------------------------------------------------- */
 
-int init_module(void) {
 
-	if (mode)
-		pm2fb_mode_setup(mode);
-	return pm2fb_init();
-}
 
-void cleanup_module(void) {
+#ifdef MODULE
+module_init(pm2fb_init);
+#endif
+module_exit(pm2fb_exit);
 
-	pm2fb_cleanup();
-}
-#endif /* MODULE */
+MODULE_PARM(mode,"s");
+MODULE_PARM(lowhsync,"i");
+MODULE_PARM(lowvsync,"i");
 
-/***************************************************************************
- * That's all folks!
- ***************************************************************************/
+MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
+MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
+MODULE_LICENSE("GPL");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/pvr2fb.c fbdev-2.6/drivers/video/pvr2fb.c
--- linus-2.6/drivers/video/pvr2fb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/pvr2fb.c	Thu Oct 16 14:13:31 2003
@@ -166,6 +166,11 @@
 static int cable_type = -1;
 static int video_output = -1;
 
+#ifdef CONFIG_MTRR
+static int enable_mtrr = 1;
+static int mtrr_handle;
+#endif
+
 static int nopan = 0;
 static int nowrap = 1;
 
@@ -385,6 +390,7 @@
 
 static int pvr2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
 {
+	struct pvr2fb_par *par = (struct pvr2fb_par *)info->par;
 	u_short vtotal, hsync_total;
 	u_long line_length;
 
@@ -413,7 +419,7 @@
 
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->xoffset || var->yoffset < 0 || 
-		    var->yoffset >= var->yres_virtual) {
+		    var->yoffset >= var->yres_virtual)
 			var->xoffset = var->yoffset = 0;
 		} else {
 			if (var->xoffset > var->xres_virtual - var->xres ||
@@ -421,9 +427,8 @@
 			    var->xoffset < 0 || var->yoffset < 0)
 				var->xoffset = var->yoffset = 0;
 		}
-	} else {
+	} else
 		var->xoffset = var->yoffset = 0;
-	}
 
 	/* 
 	 * XXX: Need to be more creative with this (i.e. allow doublecan for
@@ -456,7 +461,6 @@
 				DPRINTK("invalid hsync total for NTSC\n");
 				return -EINVAL;
 			}
-		}
 	}
 	/* Check memory sizes */
 	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
@@ -599,10 +603,10 @@
 
 int __init pvr2fb_init(void)
 {
+	struct fb_var_screeninfo var;
 	u_long modememused;
-	int err = -EINVAL;
 
-	if (!mach_is_dreamcast())
+	if (!MACH_DREAMCAST)
 		return -ENXIO;
 
 	fb_info = kmalloc(sizeof(struct fb_info) + sizeof(struct pvr2fb_par) +
@@ -650,8 +654,8 @@
 	
 	if (!fb_info->screen_base) {
 		printk("Failed to remap MMIO space\n");
-		err = -ENXIO;
-		goto out_err;
+		kfree(fb_info);
+		return -ENXIO;
 	}
 
 	memset_io((unsigned long)fb_info->screen_base, 0, pvr2_fix.smem_len);
@@ -665,6 +669,8 @@
 	fb_info->pseudo_palette	= (void *)(fb_info->par + 1);
 	fb_info->flags		= FBINFO_FLAG_DEFAULT;
 
+	memset(&var, 0, sizeof(var));
+
 	if (video_output == VO_VGA)
 		defmode = DEFMODE_VGA;
 
@@ -677,41 +683,46 @@
 
 	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, 0,
 	                "pvr2 VBL handler", fb_info)) {
-		err = -EBUSY;
-		goto out_err;
+		DPRINTK("couldn't register VBL int\n");
+		kfree(fb_info);
+		return 	-EBUSY;
 	}
 
-	if (register_framebuffer(fb_info) < 0)
-		goto reg_failed;
+#ifdef CONFIG_MTRR
+	if (enable_mtrr) {
+		mtrr_handle = mtrr_add(videomemory, videomemorysize, MTRR_TYPE_WRCOMB, 1);
+		printk("pvr2fb: MTRR turned on\n");
+	}
+#endif
 
-	modememused = get_line_length(fb_info->var.xres_virtual,
-				      fb_info->var.bits_per_pixel);
-	modememused *= fb_info->var.yres_virtual;
+	if (register_framebuffer(fb_info) < 0) {
+		kfree(fb_info);
+		return -EINVAL;
+	}
 
+	modememused = get_line_length(var.xres_virtual, var.bits_per_pixel);
+	modememused *= var.yres_virtual;
 	printk("fb%d: %s frame buffer device, using %ldk/%ldk of video memory\n",
 	       fb_info->node, fb_info->fix.id, modememused>>10,
 	       videomemorysize>>10);
 	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", 
-	       fb_info->node, fb_info->var.xres, fb_info->var.yres,
-	       fb_info->var.bits_per_pixel, 
-	       get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),
+	       fb_info->node, var.xres, var.yres, var.bits_per_pixel,
+	       get_line_length(var.xres, var.bits_per_pixel),
 	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),
 	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));
 
 	return 0;
-
-reg_failed:
-	free_irq(HW_EVENT_VSYNC, 0);
-out_err:
-	kfree(fb_info);
-
-	return err;
 }
 
 static void __exit pvr2fb_exit(void)
 {
+#ifdef CONFIG_MTRR
+	if (enable_mtrr) {
+		mtrr_del(mtrr_handle, videomemory, videomemorysize);
+		printk("pvr2fb: MTRR turned off\n");
+	}
+#endif
 	unregister_framebuffer(fb_info);
-	free_irq(HW_EVENT_VSYNC, 0);
 	kfree(fb_info);
 }
 
@@ -767,6 +778,10 @@
 			nopan = 1;
 		} else if (!strncmp(this_opt, "nowrap", 6)) {
 			nowrap = 1;
+#ifdef CONFIG_MTRR
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			enable_mtrr = 0;
+#endif
 		} else {
 			mode_option = this_opt;
 		}
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/radeonfb.c fbdev-2.6/drivers/video/radeonfb.c
--- linus-2.6/drivers/video/radeonfb.c	Thu Oct 16 14:13:31 2003
+++ fbdev-2.6/drivers/video/radeonfb.c	Thu Oct 16 14:13:31 2003
@@ -2090,7 +2090,7 @@
 	
 	}
 	/* Update fix */
-        info->fix.line_length = rinfo->pitch*64;
+        info->fix.line_length = mode->xres_virtual*(mode->bits_per_pixel/8);
         info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
 
 #ifdef CONFIG_BOOTX_TEXT
@@ -2234,12 +2234,10 @@
 
 	info = &rinfo->info;
 
-	info->currcon = -1;
 	info->par = rinfo;
 	info->pseudo_palette = rinfo->pseudo_palette;
         info->flags = FBINFO_FLAG_DEFAULT;
         info->fbops = &radeonfb_ops;
-        info->display_fg = NULL;
         info->screen_base = (char *)rinfo->fb_base;
 
 	/* Fill fix common fields */
@@ -3033,6 +3031,7 @@
 	pci_set_drvdata(pdev, rinfo);
 	rinfo->next = board_list;
 	board_list = rinfo;
+	rinfo->info.dev = &pdev->dev;
 
 	if (register_framebuffer ((struct fb_info *) rinfo) < 0) {
 		printk ("radeonfb: could not register framebuffer\n");
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/fbdev.c fbdev-2.6/drivers/video/riva/fbdev.c
--- linus-2.6/drivers/video/riva/fbdev.c	Thu Oct 16 14:13:40 2003
+++ fbdev-2.6/drivers/video/riva/fbdev.c	Thu Oct 16 14:13:40 2003
@@ -143,7 +143,17 @@
 	CH_GEFORCE4_TI_4200,
 	CH_QUADRO4_900XGL,
 	CH_QUADRO4_750XGL,
-	CH_QUADRO4_700XGL
+	CH_QUADRO4_700XGL,
+	CH_GEFORCE4_TI_4800,
+	CH_GEFORCE4_TI_4280,
+	CH_GEFORCE4_TI_4800SE,
+	CH_GEFORCE4_4200_GO,
+	CH_GEFORCE_FX_5800_U,
+	CH_GEFORCE_FX_5800,
+	CH_GEFORCE_FX_5600_U,
+	CH_GEFORCE_FX_5600,
+	CH_GEFORCE_FX_5200_U,
+	CH_GEFORCE_FX_5200
 };
 
 /* directly indexed by riva_chips enum, above */
@@ -190,7 +200,17 @@
 	{ "GeForce4 Ti 4200", NV_ARCH_20 },
 	{ "Quadro4-900-XGL", NV_ARCH_20 },
 	{ "Quadro4-750-XGL", NV_ARCH_20 },
-	{ "Quadro4-700-XGL", NV_ARCH_20 }
+	{ "Quadro4-700-XGL", NV_ARCH_20 },
+	{ "GeForce4 Ti 4800", NV_ARCH_20 },
+	{ "GeForce4 Ti 4280", NV_ARCH_20},
+	{ "GeForce4 Ti 4800 SE", NV_ARCH_20},
+	{ "GeForce4 4200 GO", NV_ARCH_20},
+	{ "GeForce FX 5800 ULTRA", NV_ARCH_20},
+	{ "GeForce FX 5800", NV_ARCH_20},
+	{ "GeForce FX 5600 ULTRA", NV_ARCH_20},
+	{ "GeForce FX 5600", NV_ARCH_20},
+	{ "GeForce FX 5200 ULTRA", NV_ARCH_20},
+	{ "GeForce FX 5200", NV_ARCH_20}
 };
 
 static struct pci_device_id rivafb_pci_tbl[] = {
@@ -274,6 +294,26 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
 	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4280 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4800SE },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_4200_GO },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800_U },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5800 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600_U },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5600 },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200_U },
+	{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_FX_5200 },
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
@@ -473,7 +513,7 @@
 /**
  * rivafb_load_cursor_image - load cursor image to hardware
  * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
- * @par:  pointer to private data
+ * @info: pointer to fb_info data
  * @w:    width of cursor image in pixels
  * @h:    height of cursor image in scanlines
  * @bg:   background color (ARGB1555) - alpha bit determines opacity
@@ -488,11 +528,28 @@
  * CALLED FROM:
  * rivafb_cursor()
  */
-static void rivafb_load_cursor_image(struct riva_par *par, u8 *data, 
-				     u8 *mask, u16 bg, u16 fg, u32 w, u32 h)
+static void rivafb_load_cursor_image(struct fb_info *info, u8 *data,
+				     u32 w, u32 h)
 {
+	struct riva_par *par = (struct riva_par *) info->par;
+	u32 bg_idx = info->cursor.image.bg_color;
+	u32 fg_idx = info->cursor.image.fg_color;
+	u8 *mask = (u8 *) info->cursor.mask;
 	int i, j, k = 0;
 	u32 b, m, tmp;
+	u16 fg, bg;
+
+	bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
+	     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
+	     ((info->cmap.blue[bg_idx] & 0xf8) >> 3) | 1 << 15;
+
+	fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
+	     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
+	     ((info->cmap.blue[fg_idx] & 0xf8) >> 3) | 1 << 15;
+
+	par->riva.LockUnlock(&par->riva, 0);
+
+	memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
 
 	for (i = 0; i < h; i++) {
 		b = *((u32 *)data)++;
@@ -502,35 +559,23 @@
 		for (j = 0; j < w/2; j++) {
 			tmp = 0;
 #if defined (__BIG_ENDIAN)
-			if (m & (1 << 31)) {
-				fg |= 1 << 15;
-				bg |= 1 << 15;
-			}
-			tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
+			if (m & (1 << 31))
+				tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
 			b <<= 1;
 			m <<= 1;
 
-			if (m & (1 << 31)) {
-				fg |= 1 << 15;
-				bg |= 1 << 15;
-			}
-			tmp |= (b & (1 << 31)) ? fg : bg;
+			if (m & (1 << 31))
+				tmp |= (b & (1 << 31)) ? fg : bg;
 			b <<= 1;
 			m <<= 1;
 #else
-			if (m & 1) {
-				fg |= 1 << 15;
-				bg |= 1 << 15;
-			}
-			tmp = (b & 1) ? fg : bg;
+			if (m & 1)
+				tmp = (b & 1) ? fg : bg;
 			b >>= 1;
 			m >>= 1;
 			
-			if (m & 1) {
-				fg |= 1 << 15;
-				bg |= 1 << 15;
-			}
-			tmp |= (b & 1) ? fg << 16 : bg << 16;
+			if (m & 1)
+				tmp |= (b & 1) ? fg << 16 : bg << 16;
 			b >>= 1;
 			m >>= 1;
 #endif
@@ -1469,10 +1514,6 @@
 static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 	struct riva_par *par = (struct riva_par *) info->par;
-	u8 data[MAX_CURS * MAX_CURS/8];
-	u8 mask[MAX_CURS * MAX_CURS/8];
-	u16 fg, bg;
-	int i;
 
 	par->riva.ShowHideCursor(&par->riva, 0);
 
@@ -1492,7 +1533,6 @@
 	if (cursor->set & FB_CUR_SETSIZE) {
 		info->cursor.image.height = cursor->image.height;
 		info->cursor.image.width = cursor->image.width;
-		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
 	}
 
 	if (cursor->set & FB_CUR_SETCMAP) {
@@ -1501,42 +1541,9 @@
 	}
 
 	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
-		u32 bg_idx = info->cursor.image.bg_color;
-		u32 fg_idx = info->cursor.image.fg_color;
-		u32 s_pitch = (info->cursor.image.width+7) >> 3;
-		u32 d_pitch = MAX_CURS/8;
-		u8 *dat = (u8 *) cursor->image.data;
-		u8 *msk = (u8 *) info->cursor.mask;
-		u8 src[64];	
+		u8 *data = (u8 *) info->cursor.image.data;
 		
-		switch (info->cursor.rop) {
-		case ROP_XOR:
-			for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-					src[i] = dat[i] ^ msk[i];
-			break;
-		case ROP_COPY:
-		default:
-			for (i = 0; i < s_pitch * info->cursor.image.height; i++)
-				
-					src[i] = dat[i] & msk[i];
-			break;
-		}
-		
-		move_buf_aligned(info, data, src, d_pitch, s_pitch, info->cursor.image.height);
-
-		move_buf_aligned(info, mask, msk, d_pitch, s_pitch, info->cursor.image.height);
-
-		bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
-		     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
-		     ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
-
-		fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
-		     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
-		     ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
-
-		par->riva.LockUnlock(&par->riva, 0);
-
-		rivafb_load_cursor_image(par, data, mask, bg, fg,
+		rivafb_load_cursor_image(info, data,
 					 info->cursor.image.width, 
 					 info->cursor.image.height);
 	}
@@ -1603,6 +1610,13 @@
 	info->pixmap.buf_align = 4;
 	info->pixmap.scan_align = 4;
 	info->pixmap.flags = FB_PIXMAP_SYSTEM;
+
+	info->sprite.size = MAX_CURS * MAX_CURS/8; // * 2;
+	info->sprite.addr = kmalloc(info->sprite.size, GFP_KERNEL);//(char *) par->riva.CURSOR;
+	info->sprite.buf_align = MAX_CURS >> 3;
+	info->sprite.scan_align = MAX_CURS >> 3;
+	info->sprite.access_align = 2;
+	info->sprite.flags = FB_PIXMAP_IO;
 	return 0;
 }
 
@@ -1736,20 +1750,15 @@
 	assert(pd != NULL);
 	assert(rci != NULL);
 
-	info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
+	info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);
 	if (!info)
 		goto err_out;
 
-	default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
-	if (!default_par)
-		goto err_out_kfree;
-
-	memset(info, 0, sizeof(struct fb_info));
-	memset(default_par, 0, sizeof(struct riva_par));
+	default_par = info->par;
 
 	info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
 	if (info->pixmap.addr == NULL)
-		goto err_out_kfree1;
+		goto err_out_kfree;
 	memset(info->pixmap.addr, 0, 64 * 1024);
 
 	strcat(rivafb_fix.id, rci->name);
@@ -1781,7 +1790,7 @@
 	if (!request_mem_region(rivafb_fix.mmio_start,
 				rivafb_fix.mmio_len, "rivafb")) {
 		printk(KERN_ERR PFX "cannot reserve MMIO region\n");
-		goto err_out_kfree2;
+		goto err_out_kfree1;
 	}
 
 	default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
@@ -1897,10 +1906,8 @@
 	iounmap(default_par->ctrl_base);
 err_out_free_base0:
 	release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
-err_out_kfree2:
-	kfree(info->pixmap.addr);
 err_out_kfree1:
-	kfree(default_par);
+	kfree(info->pixmap.addr);
 err_out_kfree:
 	kfree(info);
 err_out:
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/riva/nv_type.h fbdev-2.6/drivers/video/riva/nv_type.h
--- linus-2.6/drivers/video/riva/nv_type.h	Thu Oct 16 14:13:40 2003
+++ fbdev-2.6/drivers/video/riva/nv_type.h	Thu Oct 16 14:13:40 2003
@@ -50,8 +50,16 @@
 #define NV_CHIP_QUADRO4_900XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL)
 #define NV_CHIP_QUADRO4_750XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL)
 #define NV_CHIP_QUADRO4_700XGL      ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL)
-#define NV_CHIP_0x0280              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0280)
-#define NV_CHIP_0x0281              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0281)
+#define NV_CHIP_GEFORCE4_TI_4800    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800)
+#define NV_CHIP_GEFORCE4_TI_4280    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280)
+#define NV_CHIP_GEFORCE4_TI_4800SE  ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE)
+#define NV_CHIP_GEFORCE4_4200_GO    ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO)
+#define NV_CHIP_GEFORCE_FX_5800_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U)
+#define NV_CHIP_GEFORCE_FX_5800     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800)
+#define NV_CHIP_GEFORCE_FX_5600_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U)
+#define NV_CHIP_GEFORCE_FX_5600     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600)
+#define NV_CHIP_GEFORCE_FX_5200_U   ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U)
+#define NV_CHIP_GEFORCE_FX_5200     ((PCI_VENDOR_ID_NVIDIA << 16) | PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200)
 #define NV_CHIP_0x0288              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0288)
 #define NV_CHIP_0x0289              ((PCI_VENDOR_ID_NVIDIA << 16) | 0x0289)
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sa1100fb.c fbdev-2.6/drivers/video/sa1100fb.c
--- linus-2.6/drivers/video/sa1100fb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/sa1100fb.c	Thu Oct 16 14:13:32 2003
@@ -1701,7 +1701,6 @@
 	fbi->fb.fbops		= &sa1100fb_ops;
 	fbi->fb.flags		= FBINFO_FLAG_DEFAULT;
 	fbi->fb.monspecs	= monspecs;
-	fbi->fb.currcon		= -1;
 	fbi->fb.pseudo_palette	= (fbi + 1);
 
 	fbi->rgb[RGB_8]		= &rgb_8;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sgivwfb.c fbdev-2.6/drivers/video/sgivwfb.c
--- linus-2.6/drivers/video/sgivwfb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/sgivwfb.c	Thu Oct 16 14:13:32 2003
@@ -319,14 +319,14 @@
 		var->transp.length = 0;
 		break;
 	case 16:		/* RGBA 5551 */
-		var->red.offset = 11;
+		var->red.offset = 10;
 		var->red.length = 5;
-		var->green.offset = 6;
+		var->green.offset = 5;
 		var->green.length = 5;
-		var->blue.offset = 1;
+		var->blue.offset = 0;
 		var->blue.length = 5;
-		var->transp.offset = 0;
-		var->transp.length = 0;
+		var->transp.offset = 15;
+		var->transp.length = 1;
 		break;
 	case 32:		/* RGB 8888 */
 		var->red.offset = 0;
@@ -509,7 +509,7 @@
 		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
 		break;
 	case 2:
-		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
+		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_ARGB5);
 		break;
 	case 4:
 		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/300vtbl.h fbdev-2.6/drivers/video/sis/300vtbl.h
--- linus-2.6/drivers/video/sis/300vtbl.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/300vtbl.h	Thu Oct 16 14:13:41 2003
@@ -1,7 +1,37 @@
-
-
-/* Register settings for SiS 300 series */
-
+/* $XFree86$ */
+/*
+ * Register settings for SiS 300 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
 
 typedef struct _SiS300_StStruct
 {
@@ -39,470 +69,109 @@
 	{0xff,     0,   0,   0,   0,   0,   0,   0}
 };
 
-typedef struct _SiS300_StandTableStruct
-{
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
-} SiS300_StandTableStruct;
-
-static const SiS300_StandTableStruct  SiS300_StandTable[] =
-{
- {0x28,0x18,0x08,0x0800,			/* 0x00 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x0800,			/* 0x01 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x1000,			/* 0x02 */
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x1000,			/* 0x03 */
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x4000,			/* 0x04 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff} },
- {0x28,0x18,0x08,0x4000,			/* 0x05 */
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff} },
- {0x50,0x18,0x08,0x4000,			/* 0x06 */
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x07 */
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff} },
-/* MDA_DAC*/
- {0x00,0x00,0x00,0x0000,			/* 0x08 */
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f} },
-/* CGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x09 */
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f} },
-/* EGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x0a */
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f} },
-/* VGA_DAC*/
- {0x00,0x10,0x04,0x0114,			/* 0x0b */
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04} },
- {0x08,0x0c,0x10,0x0a08,			/* 0x0c */
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00} },
- {0x28,0x18,0x08,0x2000,			/* 0x0d */
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x50,0x18,0x08,0x4000,			/* 0x0e */
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x00,0x00,0x00,0x0000,			/* 0x0f */	/* TW: Standtable for VGA modes */
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff} },
- {0x4a,0x36,0x00,0x00c0,			/* 0x10 */
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x3a,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0x57,0x39,0x00,0xc0,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00} },
- {0x50,0x18,0x0e,0x8000,			/* 0x11 */
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff} },
- {0x50,0x18,0x0e,0x8000,			/* 0x12 */
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x28,0x18,0x0e,0x0800,			/* 0x13 */
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x0e,0x0800,			/* 0x14 */
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x15 */
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x0e,0x1000,			/* 0x16 */
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x28,0x18,0x10,0x0800,			/* 0x17 */
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x10,0x1000,			/* 0x18 */
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff} },
- {0x50,0x18,0x10,0x1000,			/* 0x19 */
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff} },
- {0x50,0x1d,0x10,0xa000,			/* 0x1a */
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff} },
- {0x50,0x1d,0x10,0xa000,			/* 0x1b */
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff} },
- {0x28,0x18,0x08,0x2000,			/* 0x1c */
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff} }
-};
-
 typedef struct _SiS300_ExtStruct
 {
-	UCHAR Ext_ModeID;
+	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
 	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
-	UCHAR Ext_RESINFO;
-	UCHAR VB_ExtTVFlickerIndex;
-	UCHAR VB_ExtTVEdgeIndex;
-	UCHAR VB_ExtTVYFilterIndex;
-	UCHAR REFindex;
+	UCHAR  Ext_RESINFO;
+	UCHAR  VB_ExtTVFlickerIndex;
+	UCHAR  VB_ExtTVEdgeIndex;
+	UCHAR  VB_ExtTVYFilterIndex;
+	UCHAR  REFindex;
 } SiS300_ExtStruct;
 
 static const SiS300_ExtStruct  SiS300_EModeIDTable[] =
 {
-	{0x6a,0x2212,0x47,0x3563,0x0102,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600x? */
-	{0x2e,0x0a1b,0x36,0x3539,0x0101,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x2f,0x021b,0x35,0x3532,0x0100,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x8 */
-	{0x30,0x2a1b,0x47,0x3563,0x0103,0x08,0x07,0x00,0x00,0x00,0x00},
-	{0x31,0x0a1b,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x8 */
-	{0x32,0x2a1b,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x8 */
-	{0x33,0x0a1d,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x16 */
-	{0x34,0x2a1d,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x16 */
-	{0x35,0x0a1f,0xad,0x3630,0x0000,0x08,0x0c,0x00,0x00,0x00,0x11},  /* 720x480x32 */
-	{0x36,0x2a1f,0xae,0x3637,0x0000,0x08,0x0d,0x00,0x00,0x00,0x12},  /* 720x576x32 */
-	{0x37,0x0212,0x58,0x358d,0x0104,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x? */
-	{0x38,0x0a1b,0x58,0x358d,0x0105,0x08,0x08,0x00,0x00,0x00,0x13},  /* 1024x768x8 */
-	{0x3a,0x0e3b,0x69,0x35be,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
-	{0x3c,0x063b,0x7a,0x35d4,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x3d,0x067d,0x7a,0x35d4,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x40,0x921c,0x00,0x3516,0x010d,0x08,0x00,0x00,0x00,0x00,0x23},
-	{0x41,0x921d,0x00,0x3516,0x010e,0x08,0x00,0x00,0x00,0x00,0x23},
-	{0x43,0x0a1c,0x36,0x3539,0x0110,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x44,0x0a1d,0x36,0x3539,0x0111,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x46,0x2a1c,0x47,0x3563,0x0113,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
-	{0x47,0x2a1d,0x47,0x3563,0x0114,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
-	{0x49,0x0a3c,0x58,0x358d,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4a,0x0a3d,0x58,0x358d,0x0117,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4c,0x0e7c,0x69,0x35be,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x4d,0x0e7d,0x69,0x35be,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x50,0x921b,0x01,0x351d,0x0132,0x08,0x01,0x00,0x00,0x00,0x24},
-	{0x51,0xb21b,0x13,0x3524,0x0133,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
-	{0x52,0x921b,0x24,0x352b,0x0134,0x08,0x04,0x00,0x00,0x00,0x26},
-	{0x56,0x921d,0x01,0x351d,0x0135,0x08,0x01,0x00,0x00,0x00,0x24},
-	{0x57,0xb21d,0x13,0x3524,0x0136,0x08,0x03,0x00,0x00,0x00,0x25},  /* 400x300 */
-	{0x58,0x921d,0x24,0x352b,0x0137,0x08,0x04,0x00,0x00,0x00,0x26},  
-	{0x59,0x921b,0x00,0x3516,0x0138,0x08,0x00,0x00,0x00,0x00,0x23}, 
-	{0x5c,0x921f,0x24,0x352b,0x0000,0x08,0x04,0x00,0x00,0x00,0x26},  /* TW: inserted 512x384x32 */
-	{0x5d,0x021d,0x35,0x3532,0x0139,0x08,0x05,0x00,0x00,0x00,0x10},  /* 640x400x16 */
- 	{0x5e,0x021f,0x35,0x3532,0x0000,0x08,0x05,0x00,0x00,0x00,0x10},  /* TW: inserted 640x400x32 */
-	{0x62,0x0a3f,0x36,0x3539,0x013a,0x08,0x06,0x00,0x00,0x00,0x08},
-	{0x63,0x2a3f,0x47,0x3563,0x013b,0x08,0x07,0x00,0x00,0x00,0x00},  /* 800x600 */
-	{0x64,0x0a7f,0x58,0x358d,0x013c,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x65,0x0eff,0x69,0x35be,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x66,0x06ff,0x7a,0x35d4,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},
-	{0x68,0x067b,0x8b,0x35ef,0x013f,0x08,0x0b,0x00,0x00,0x00,0x27},
-	{0x69,0x06fd,0x8b,0x35ef,0x0140,0x08,0x0b,0x00,0x00,0x00,0x27},
-	{0x6b,0x07ff,0x8b,0x35ef,0x0000,0x10,0x0b,0x00,0x00,0x00,0x27},
-	{0x6c,0x067b,0x9c,0x35f6,0x0000,0x08,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x8 - not in BIOS! */
-	{0x6d,0x06fd,0x9c,0x35f6,0x0000,0x10,0x11,0x00,0x00,0x00,0x28},  /* TW: 2048x1536x16 - not in BIOS! */
-	{0x6e,0x0a3b,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x8 */
-	{0x6f,0x0a7d,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},  /* 1280x960x16 */
-	/* TW: 16:9 modes copied from 310/325 series - not in ANY BIOS */
-	{0x70,0x2a1b,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x8 */
-	{0x71,0x0a1b,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x8 */
-	{0x74,0x0a1d,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},    /* 1024x576x16 */
-	{0x75,0x0e3d,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x16 */
-	{0x76,0x2a1f,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x32 */
-	{0x77,0x0a3f,0x51,0x3b63,0x0000,0x08,0x13,0x00,0x00,0x00,0x30},	   /* 1024x576x32 */
-	{0x78,0x0eff,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x32 */
-	{0x79,0x0e3b,0x62,0x3b74,0x0000,0x08,0x14,0x00,0x00,0x00,0x33},	   /* 1280x720x8 */
-	{0x7a,0x2a1d,0x40,0x3b52,0x0000,0x08,0x12,0x00,0x00,0x07,0x2d},    /* 800x480x16 */
-	/* TW: End of new 16:9 modes */
-	{0x7b,0x0aff,0x6f,0x35b2,0x0000,0x08,0x0e,0x00,0x00,0x00,0x29},    /* 1280x960x32 */
-	{0x20,0x0a1b,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},    /* 1024x600 */
-	{0x21,0x0a3d,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
-	{0x22,0x0a7f,0x54,0x0000,0x0000,0x08,0x0f,0x00,0x00,0x00,0x2b},
-	{0x23,0x0a1b,0xc5,0x0000,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},    /* 1152x768 */
-	{0x24,0x0a3d,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
-	{0x25,0x0a7f,0xc5,0x431d,0x0000,0x08,0x10,0x00,0x00,0x00,0x2c},
-	{0x29,0x0e1b,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},    /* TW: NEW 1152x864 - not in BIOS */
-	{0x2a,0x0e3d,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
-	{0x2b,0x0e7f,0xc5,0x0000,0x0000,0x08,0x15,0x00,0x00,0x00,0x36},
-	{0x39,0x2a1b,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},    /* TW: NEW 848x480 - not in BIOS */
-	{0x3b,0x2a3d,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
-	{0x3e,0x2a7f,0xd6,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x38},
-	{0x3f,0x2a1b,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},    /* TW: NEW 856x480 - not in BIOS */
-	{0x42,0x2a3d,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
-	{0x45,0x2a7f,0xd7,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x3a},
-	{0x48,0x223b,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},    /* TW: NEW 1360x768 - not in BIOS */
-	{0x4b,0x227d,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
-	{0x4e,0x22ff,0xe8,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x3c},
-	{0xff,0x0000,0x00,0x0000,0xffff,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x? */
+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x2f,0x021b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x8 */
+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x00,0x00},
+	{0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x8 */
+	{0x32,0x2a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x8 */
+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x16 */
+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x16 */
+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x00,0x11},  /* 720x480x32 */
+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x00,0x12},  /* 720x576x32 */
+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},  /* 1024x768x8 */
+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},  /* 1280x1024x8 */
+	{0x3c,0x063b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x3d,0x067d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x40,0x921c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x15 */
+	{0x41,0x921d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x16 */
+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x15 */
+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x16 */
+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x50,0x921b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x8  */
+	{0x51,0xb21b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x8  */
+	{0x52,0x921b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x8  */
+	{0x56,0x921d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x16 */
+	{0x57,0xb21d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x16 */
+	{0x58,0x921d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x16 */
+	{0x59,0x921b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x8  */
+	{0x5c,0x921f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x26},  /* 512x384x32 */
+	{0x5d,0x021d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x16 */
+ 	{0x5e,0x021f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x00,0x10},  /* 640x400x32 */
+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x00,0x08},
+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x00,0x00},  /* 800x600x32 */
+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x66,0x06ff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e},
+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x6b,0x07ff,0x080b,0x0000,SIS_RI_1920x1440,0x00,0x00,0x00,0x27},
+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x8 - not in BIOS! */
+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x28},  /* 2048x1536x16 - not in BIOS! */
+	{0x70,0x2a1b,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x8 */
+	{0x71,0x0a1b,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x8 */
+	{0x74,0x0a1d,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x16 */
+	{0x75,0x0e3d,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x16 */
+	{0x76,0x2a1f,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x32 */
+	{0x77,0x0a3f,0x0501,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x30},  /* 1024x576x32 */
+	{0x78,0x0eff,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x32 */
+	{0x79,0x0e3b,0x0602,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x33},  /* 1280x720x8 */
+	{0x7a,0x2a1d,0x0400,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x2d},  /* 800x480x16 */
+	{0x7c,0x0a3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x8 */
+	{0x7d,0x0a7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x16 */
+	{0x7e,0x0aff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x29},  /* 1280x960x32 */
+	{0x20,0x0a1b,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},  /* 1024x600 */
+	{0x21,0x0a3d,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
+	{0x22,0x0a7f,0x0504,0x0000,SIS_RI_1024x600, 0x00,0x00,0x00,0x2b},
+	{0x23,0x0a1b,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},  /* 1152x768 */
+	{0x24,0x0a3d,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
+	{0x25,0x0a7f,0x0c05,0x0000,SIS_RI_1152x768, 0x00,0x00,0x00,0x2c},
+	{0x29,0x0e1b,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},  /* 1152x864 */
+	{0x2a,0x0e3d,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
+	{0x2b,0x0e7f,0x0c05,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x36},
+	{0x39,0x2a1b,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},  /* 848x480 */
+	{0x3b,0x2a3d,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
+	{0x3e,0x2a7f,0x0d06,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x38},
+	{0x3f,0x2a1b,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},  /* 856x480 */
+	{0x42,0x2a3d,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
+	{0x45,0x2a7f,0x0d07,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x3a},
+	{0x48,0x223b,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},  /* 1360x768 */
+	{0x4b,0x227d,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
+	{0x4e,0x22ff,0x0e08,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x3c},
+	{0x4f,0x921f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x00,0x23},  /* 320x200x32 */
+	{0x53,0x921f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x00,0x24},  /* 320x240x32 */
+	{0x54,0xb21f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x00,0x25},  /* 400x300x32 */
+	{0x55,0x2e3b,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},  /* 1280x768   */
+	{0x5a,0x2e7d,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
+	{0x5b,0x2eff,0x0609,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x3d},
+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x8 */
+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x16 */
+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x00,0x3e},  /* 768x576x32 */
+	{0x67,0x2e3b,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x8 (BARCO) */
+	{0x6f,0x2e7d,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x16 (BARCO) */
+	{0x72,0x2eff,0x0e08,0x0000,SIS_RI_1360x1024,0x00,0x00,0x00,0x3f},  /* 1360x1024x32 (BARCO) */
+	{0xff,0x0000,0x0000,0xffff,0x00,            0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS300_Ext2Struct
@@ -514,76 +183,77 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS300_Ext2Struct;
 
 static const SiS300_Ext2Struct  SiS300_RefIndex[] =
 { /* TW: Don't ever insert anything here, table is indexed */
-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3563}, /* 00 */
-	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600,0x3568}, /* 01 */
-	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600,0x356d}, /* 02 - CRT1CRTC was 0x4f */
-	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600,0x3572}, /* 03 */
-	{0x0147,0x11,0x08,0x00,0x6a, 800, 600,0x3577}, /* 04 */
-	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600,0x357c}, /* 05 */
-	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600,0x3581}, /* 06 - CRT1CRTC was 0x51 */
-	{0x0047,0x11,0x13,0x00,0x6a, 800, 600,0x3586}, /* 07 */
-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3539}, /* 08 */
-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x353e}, /* 09 */
-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3543}, /* 0a */
-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3548}, /* 0b */
-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x354d}, /* 0c */
-	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480,0x3552}, /* 0d */
-	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480,0x3557}, /* 0e */
-	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480,0x355c}, /* 0f */
-	{0x487f,0x04,0x00,0x00,0x2f, 640, 400,0x3532}, /* 10 */
-	{0xc00f,0x31,0x01,0x06,0x31, 720, 480,0x3630}, /* 11 */
-	{0x000f,0x32,0x03,0x06,0x32, 720, 576,0x3637}, /* 12 */
-	{0x0187,0x15,0x05,0x00,0x37,1024, 768,0x358d}, /* 13 */
-        {0xc877,0x16,0x09,0x06,0x37,1024, 768,0x3592}, /* 14 */
-	{0xc067,0x17,0x0b,0x49,0x37,1024, 768,0x3597}, /* 15 - CRT1CRTC was 0x97 */
-	{0x0267,0x18,0x0d,0x00,0x37,1024, 768,0x359c}, /* 16 */
-	{0x0047,0x19,0x11,0x8c,0x37,1024, 768,0x35a1}, /* 17 - CRT1CRTC was 0x59 */
-	{0x0047,0x1a,0x52,0x00,0x37,1024, 768,0x35a6}, /* 18 */
-	{0x0007,0x1b,0x16,0x00,0x37,1024, 768,0x35ab}, /* 19 - CRT1CRTC was 0x5b */
-	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024,0x35be}, /* 1a - CRT1CRTC was 0x5c */
-	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024,0x35c3}, /* 1b */
-	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024,0x35c8}, /* 1c */
-	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024,0x35cd}, /* 1d */
-	{0x0007,0x20,0x59,0x00,0x3c,1600,1200,0x35d4}, /* 1e - CRT1CRTC was 0x60 */
-	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200,0x35d9}, /* 1f */
-	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200,0x35de}, /* 20 */
-	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200,0x35e3}, /* 21 - CRT1CRTC was 0x63 */
-	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200,0x35e8}, /* 22 */
-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3516}, /* 23 */
-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x351d}, /* 24 */
-	{0x0077,0x02,0x04,0x05,0x51, 400, 300,0x3524}, /* 25 */
-	{0xc877,0x03,0x09,0x06,0x52, 512, 384,0x352b}, /* 26 */  /* was c077 */
-	{0x8207,0x25,0x1f,0x00,0x68,1920,1440,0x35ef}, /* 27 */
-	{0x0007,0x26,0x20,0x00,0x6c,2048,1536,0x35f6}, /* 28 */
-	{0x0067,0x27,0x14,0x08,0x6e,1280, 960,0x35b7}, /* 29 - TW: 1280x960-60 */
-	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960,0x35b7}, /* 2a - TW: 1280x960-85 */
-	{0xc077,0x33,0x09,0x06,0x20,1024, 600,0x0000}, /* 2b */
-	{0xc077,0x34,0x0b,0x06,0x23,1152, 768,0x0000}, /* 2c */	/* VCLK 0x09 */
-	{0x0057,0x35,0x27,0x08,0x70, 800, 480,0x3b52}, /* 2d - TW: 16:9 modes */
-	{0x0047,0x36,0x37,0x08,0x70, 800, 480,0x3b57}, /* 2e */
-	{0x0047,0x37,0x08,0x08,0x70, 800, 480,0x3b5c}, /* 2f */
-	{0x0057,0x38,0x09,0x09,0x71,1024, 576,0x3b63}, /* 30 */
-	{0x0047,0x39,0x38,0x09,0x71,1024, 576,0x3b68}, /* 31 */
-	{0x0047,0x3a,0x11,0x09,0x71,1024, 576,0x3b6d}, /* 32 */
-	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720,0x3b74}, /* 33 */
-	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720,0x3b79}, /* 34 */
-	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720,0x3b7e}, /* 35 - TW: END of 16:9 modes */
-	{0x0047,0x3e,0x34,0x06,0x29,1152, 864,0x0000}, /* 36 TW: 1152x864-75Hz - Non-BIOS, new */
-	{0x0047,0x44,0x3a,0x06,0x29,1152, 864,0x0000}, /* 37 TW: 1152x864-85Hz - Non-BIOS, new */
-	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480,0x0000}, /* 38 TW: 848x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x40,0x3d,0x00,0x39, 848, 480,0x0000}, /* 39 TW: 848x480-60Hz  - Non-BIOS, new */
-	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3a TW: 856x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x42,0x28,0x00,0x3f, 856, 480,0x0000}, /* 3b TW: 856x480-60Hz  - Non-BIOS, new */
-	{0x0047,0x43,0x3e,0x00,0x48,1360, 768,0x0000}, /* 3c TW: 1360x768-60Hz - Non-BIOS, new */
-	{0xffff,0,0,0,0,0,0,0}
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 00 */
+	{0x0467,0x0e,0x44,0x05,0x6a, 800, 600}, /* 01 */
+	{0x0067,0x0f,0x07,0x48,0x6a, 800, 600}, /* 02 - CRT1CRTC was 0x4f */
+	{0x0067,0x10,0x06,0x8b,0x6a, 800, 600}, /* 03 */
+	{0x0147,0x11,0x08,0x00,0x6a, 800, 600}, /* 04 */
+	{0x0147,0x12,0x0c,0x00,0x6a, 800, 600}, /* 05 */
+	{0x0047,0x11,0x4e,0x00,0x6a, 800, 600}, /* 06 - CRT1CRTC was 0x51 */
+	{0x0047,0x11,0x13,0x00,0x6a, 800, 600}, /* 07 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 08 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 09 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0a */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0b */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0c */
+	{0xc047,0x0a,0x08,0x00,0x2e, 640, 480}, /* 0d */
+	{0xc047,0x0b,0x0a,0x00,0x2e, 640, 480}, /* 0e */
+	{0xc047,0x0c,0x10,0x00,0x2e, 640, 480}, /* 0f */
+	{0x487f,0x04,0x00,0x00,0x2f, 640, 400}, /* 10 */
+	{0xc00f,0x31,0x01,0x06,0x31, 720, 480}, /* 11 */
+	{0x000f,0x32,0x03,0x06,0x32, 720, 576}, /* 12 */
+	{0x0187,0x15,0x05,0x00,0x37,1024, 768}, /* 13 */
+        {0xc877,0x16,0x09,0x06,0x37,1024, 768}, /* 14 */
+	{0xc067,0x17,0x0b,0x49,0x37,1024, 768}, /* 15 - CRT1CRTC was 0x97 */
+	{0x0267,0x18,0x0d,0x00,0x37,1024, 768}, /* 16 */
+	{0x0047,0x19,0x11,0x8c,0x37,1024, 768}, /* 17 - CRT1CRTC was 0x59 */
+	{0x0047,0x1a,0x52,0x00,0x37,1024, 768}, /* 18 */
+	{0x0007,0x1b,0x16,0x00,0x37,1024, 768}, /* 19 - CRT1CRTC was 0x5b */
+	{0x0387,0x1c,0x4d,0x00,0x3a,1280,1024}, /* 1a - CRT1CRTC was 0x5c */
+	{0x0077,0x1d,0x14,0x07,0x3a,1280,1024}, /* 1b */
+	{0x0047,0x1e,0x17,0x00,0x3a,1280,1024}, /* 1c */
+	{0x0007,0x1f,0x98,0x00,0x3a,1280,1024}, /* 1d */
+	{0x0007,0x20,0x59,0x00,0x3c,1600,1200}, /* 1e - CRT1CRTC was 0x60 */
+	{0x0007,0x21,0x5a,0x00,0x3c,1600,1200}, /* 1f */
+	{0x0007,0x22,0x1b,0x00,0x3c,1600,1200}, /* 20 */
+	{0x0007,0x23,0x1d,0x00,0x3c,1600,1200}, /* 21 - CRT1CRTC was 0x63 */
+	{0x0007,0x24,0x1e,0x00,0x3c,1600,1200}, /* 22 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 23 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 24 */
+	{0x0077,0x02,0x04,0x05,0x51, 400, 300}, /* 25 */
+	{0xc877,0x03,0x09,0x06,0x52, 512, 384}, /* 26 */  /* was c077 */
+	{0x8207,0x25,0x1f,0x00,0x68,1920,1440}, /* 27 */
+	{0x0007,0x26,0x20,0x00,0x6c,2048,1536}, /* 28 */
+	{0x0067,0x27,0x14,0x08,0x6e,1280, 960}, /* 29 - TW: 1280x960-60 */
+	{0x0027,0x45,0x3c,0x08,0x6e,1280, 960}, /* 2a - TW: 1280x960-85 */
+	{0xc077,0x33,0x09,0x06,0x20,1024, 600}, /* 2b */
+	{0xc077,0x34,0x0b,0x06,0x23,1152, 768}, /* 2c */	/* VCLK 0x09 */
+	{0x0057,0x35,0x27,0x08,0x70, 800, 480}, /* 2d */
+	{0x0047,0x36,0x37,0x08,0x70, 800, 480}, /* 2e */
+	{0x0047,0x37,0x08,0x08,0x70, 800, 480}, /* 2f */
+	{0x0057,0x38,0x09,0x09,0x71,1024, 576}, /* 30 */
+	{0x0047,0x39,0x38,0x09,0x71,1024, 576}, /* 31 */
+	{0x0047,0x3a,0x11,0x09,0x71,1024, 576}, /* 32 */
+	{0x0057,0x3b,0x39,0x0a,0x75,1280, 720}, /* 33 */
+	{0x0047,0x3c,0x3a,0x0a,0x75,1280, 720}, /* 34 */
+	{0x0007,0x3d,0x3b,0x0a,0x75,1280, 720}, /* 35 */
+	{0x0047,0x3e,0x34,0x06,0x29,1152, 864}, /* 36 1152x864-75Hz */
+	{0x0047,0x44,0x3a,0x06,0x29,1152, 864}, /* 37 1152x864-85Hz */
+	{0x00c7,0x3f,0x28,0x00,0x39, 848, 480}, /* 38 848x480-38Hzi */
+	{0xc067,0x40,0x3d,0x0b,0x39, 848, 480}, /* 39 848x480-60Hz  */
+	{0x00c7,0x41,0x28,0x00,0x3f, 856, 480}, /* 3a 856x480-38Hzi */
+	{0xc047,0x42,0x28,0x00,0x3f, 856, 480}, /* 3b 856x480-60Hz  */
+	{0x0067,0x43,0x3e,0x0c,0x48,1360, 768}, /* 3c 1360x768-60Hz */
+	{0x0077,0x46,0x3f,0x08,0x55,1280, 768}, /* 3d 1280x768-60Hz */
+	{0x000f,0x47,0x03,0x06,0x5f, 768, 576}, /* 3e 768x576 */
+	{0x0027,0x48,0x13,0x08,0x67,1360,1024}, /* 3f 1360x1024-59Hz (BARCO1366 only) */
+	{0xffff,   0,   0,   0,   0,   0,   0}
 };
 
-/*add for 300 oem util*/
 typedef struct _SiS_VBModeIDTableStruct
 {
 	UCHAR  ModeID;
@@ -649,9 +319,8 @@
 	{0x6e,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0x6f,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
 	{0x7b,0x00,0x00,0x01,0x00,0x00,0x0b,0x0d},
-	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}  /* TW: added! */
+	{0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
 };
-/*end*/
 
 typedef struct _SiS300_CRT1TableStruct
 {
@@ -660,15 +329,32 @@
 
 static const SiS300_CRT1TableStruct  SiS300_CRT1Table[] =
 {
- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 */
-  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,
+#if 1
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,    /* 0x00 - 320x200 */
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
+  0x00}},
+#endif
+#if 0
+ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0xbf,0x1f,    /* 0x00 - corrected 320x200-72 - does not work */
+  0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x04,
   0x00}},
- {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,
-  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+#endif
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e,    /* 0x01 */
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,     /* HRE [4],[15] is invalid - but correcting it does not work */
   0x00}},
- {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,
+#if 0
+ {{0x2d,0x27,0x27,0x91,0x2c,0x92,0x0b,0x3e,    /* 0x01 - corrected 320x240-60 - does not work */
+  0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x04,
+  0x00}},
+#endif
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 */
+  0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
+  0x01}},
+#if 0
+ {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0,    /* 0x02 - corrected 400x300-60 */
   0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05,
   0x01}},
+#endif
  {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
   0x01}},
@@ -683,7 +369,7 @@
  {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e,    /* 0x05 - corrected 640x480-60 */
   0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05,
   0x00}},
- #if 0  
+#if 0
  {{0x63,0x4f,0x50,0x86,0x56,0x9b,0x06,0x3e,    /* 0x06 */
   0xe8,0x8b,0xdf,0xe7,0xff,0x10,0x00,0x01,
   0x00}},
@@ -841,15 +527,10 @@
  {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1,  /* 0x33 - 1024x600 */
   0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02,
   0x01}},
-#if 0
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,  /* 0x34 - 1152x768 */
-  0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-  0x01}},
-#endif
- {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - TW: corrected */
+ {{0xa3,0x8f,0x8f,0x97,0x96,0x97,0x24,0xf5,  /* 0x34 - 1152x768 - corrected */
   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
   0x01}},
- {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 - NEW 16:9 modes, not in BIOS ------ */
+ {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba,  /* 0x35 */
    0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06,
    0x01}}, /* 0x35 */
  {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba,
@@ -864,7 +545,7 @@
  {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1,
    0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02,
    0x01}}, /* 0x39 */
- {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,   	/* TW: 95 was 15 - illegal HBE! */
+ {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1,  /* 95 was 15 - illegal HBE! */
    0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02,
    0x01}}, /* 0x3a */
  {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4,
@@ -875,36 +556,40 @@
    0x01}}, /* 0x3c */
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4,
    0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07,
-   0x01}}, /* 0x3d */			     /* TW: End of 16:9 modes --------------- */
- {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* TW: New, 1152x864-75 (not in any BIOS)   */
+   0x01}}, /* 0x3d */
+ {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef,  /* 1152x864-75 */
    0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07,
    0x01}},  /* 0x3e */
- {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 848x480-38i, not in BIOS */
+ {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15,  /* 848x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}}, /* 0x3f */
-#if 0
- {{0x81,0x69,0x69,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 848x480-60, not in BIOS - incorrect for Philips panel */
-   0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
-   0x00}}, /* 0x40 */
-#endif
- {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* TW: New, 848x480-60, not in BIOS */
+ {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E,  /* 848x480-60  */
    0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06,
    0x00}}, /* 0x40 */
- {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* TW: New, 856x480-38i, not in BIOS */
+ {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15,  /* 856x480-38i */
    0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02,
    0x00}}, /* 0x41 */
- {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* TW: New, 856x480-60, not in BIOS */
+ {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E,  /* 856x480-60  */
    0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02,
    0x00}}, /* 0x42 */
- {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* TW: New, 1360x768-60, not in BIOS */
+ {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd,  /* 1360x768-60 */
    0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03,
    0x01}}, /* 0x43 */
- {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* TW: New, 1152x864-84 (not in any BIOS)   */
+ {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff,  /* 1152x864-84 */
    0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03,
-   0x01}}, /* 0x44 */   
- {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* TW: New, 1280x960-85 (not in any BIOS)   */
+   0x01}}, /* 0x44 */
+ {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff,  /* 1280x960-85 */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
-   0x01}}  /* 0x45 */
+   0x01}}, /* 0x45 */
+ {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5,  /* 1280x768-60 */
+   0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07,
+   0x01}},  /* 0x46 */
+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0,  /* 768x576 */
+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+   0x01}},  /* 0x47 */
+ {{0xce,0xa9,0xa9,0x92,0xb1,0x07,0x28,0x52,  /* 1360x1024 (Barco iQ Pro R300) */
+   0x02,0x8e,0xff,0x00,0x29,0x0d,0x00,0x03,
+   0x00}}   /* 0x48 */
 };
 
 typedef struct _SiS300_MCLKDataStruct
@@ -913,8 +598,8 @@
 	USHORT CLOCK;
 } SiS300_MCLKDataStruct;
 
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =	/* 630 */
-{ /* TW: at 0x54 in BIOS */
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_630[] =
+{
 	{ 0x5a,0x64,0x80, 66},
 	{ 0xb3,0x45,0x80, 83},
 	{ 0x37,0x61,0x80,100},
@@ -925,8 +610,8 @@
 	{ 0x37,0x61,0x80,100}
 };
 
-static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =  /* 300 */
-{ /* TW: at 0x54 in BIOS */
+static const SiS300_MCLKDataStruct  SiS300_MCLKData_300[] =
+{
 	{ 0x68,0x43,0x80,125},
 	{ 0x68,0x43,0x80,125},
 	{ 0x68,0x43,0x80,125},
@@ -937,6 +622,7 @@
 	{ 0x37,0x61,0x80,100}
 };
 
+#ifdef LINUXBIOS
 typedef struct _SiS300_ECLKDataStruct
 {
 	UCHAR SR2E,SR2F,SR30;
@@ -954,6 +640,7 @@
 	{ 0x54,0x43,0x80,100},
 	{ 0x54,0x43,0x80,100}
 };
+#endif
 
 typedef struct _SiS300_VCLKDataStruct
 {
@@ -964,71 +651,77 @@
 static const SiS300_VCLKDataStruct  SiS300_VCLKData[] =
 {
 	{ 0x1b,0xe1, 25}, /* 0x00 */
-	{ 0x4e,0xe4, 28},
+	{ 0x4e,0xe4, 28}, /* 0x01 */
 	{ 0x57,0xe4, 32}, /* 0x02 */
-	{ 0xc3,0xc8, 36},
+	{ 0xc3,0xc8, 36}, /* 0x03 */
 	{ 0x42,0xc3, 40}, /* 0x04 */
-	{ 0x5d,0xc4, 45},
+	{ 0x5d,0xc4, 45}, /* 0x05 */
 	{ 0x52,0x65, 50}, /* 0x06 */
-	{ 0x53,0x65, 50},
+	{ 0x53,0x65, 50}, /* 0x07 */
 	{ 0x6d,0x66, 56}, /* 0x08 */
-	{ 0x5a,0x64, 65},
+	{ 0x5a,0x64, 65}, /* 0x09 */
 	{ 0x46,0x44, 68}, /* 0x0a */
-	{ 0x3e,0x43, 75},
-	{ 0x6d,0x46, 76}, /* 0x0c: 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
-	{ 0x41,0x43, 79},
+	{ 0x3e,0x43, 75}, /* 0x0b */
+	{ 0x6d,0x46, 76}, /* 0x0c */  /* 800x600 | LVDS_2(CH), MITAC(CH);  - 730, A901(301B): 0xb1,0x46, 76 */
+	{ 0x41,0x43, 79}, /* 0x0d */
 	{ 0x31,0x42, 79}, /* 0x0e */
-	{ 0x46,0x25, 85},
+	{ 0x46,0x25, 85}, /* 0x0f */
 	{ 0x78,0x29, 87}, /* 0x10 */
-	{ 0x62,0x44, 95},
+	{ 0x62,0x44, 95}, /* 0x11 */
 	{ 0x2b,0x22,105}, /* 0x12 */
-	{ 0x49,0x24,106},
+	{ 0x49,0x24,106}, /* 0x13 */
 	{ 0xc3,0x28,108}, /* 0x14 */
-	{ 0x3c,0x23,109},
+	{ 0x3c,0x23,109}, /* 0x15 */
 	{ 0xf7,0x2c,132}, /* 0x16 */
-	{ 0xd4,0x28,136},
+	{ 0xd4,0x28,136}, /* 0x17 */
 	{ 0x41,0x05,158}, /* 0x18 */
-	{ 0x43,0x05,162},
+	{ 0x43,0x05,162}, /* 0x19 */
 	{ 0xe1,0x0f,175}, /* 0x1a */
 	{ 0xfc,0x12,189}, /* 0x1b */
 	{ 0xde,0x26,194}, /* 0x1c */
-	{ 0x54,0x05,203},
+	{ 0x54,0x05,203}, /* 0x1d */
 	{ 0x3f,0x03,230}, /* 0x1e */
-	{ 0x30,0x02,234},
+	{ 0x30,0x02,234}, /* 0x1f */
 	{ 0x24,0x01,266}, /* 0x20 */
-	{ 0x52,0x2a, 54}, /* 301 TV */
-	{ 0x52,0x6a, 27}, /* 301 TV */
-	{ 0x62,0x24, 70}, /* 301 TV */
-	{ 0x62,0x64, 70}, /* 301 TV */
-	{ 0xa8,0x4c, 30}, /* 301 TV */
-	{ 0x20,0x26, 33}, /* 301 TV */
-	{ 0x31,0xc2, 39},
-	{ 0xbf,0xc8, 35}, /* 0x28 - 856x480 */
-	{ 0x60,0x36, 30}, /* 0x29  CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
-	{ 0x40,0x4a, 28},
-	{ 0x9f,0x46, 44},
-	{ 0x97,0x2c, 26},
-	{ 0x44,0xe4, 25},
-	{ 0x7e,0x32, 47},
-	{ 0x8a,0x24, 31}, /* 0x2f  CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
-	{ 0x97,0x2c, 26},
-	{ 0xce,0x3c, 39},
-	{ 0x52,0x4a, 36}, /* 0x32  CH/PAL 800x600 5/6 */
-	{ 0x34,0x61, 95},
-	{ 0x78,0x27,108},
-	{ 0xce,0x25,189}, /* 0x35 */
-	{ 0x45,0x6b, 21}, /* 0x36 */  /* TW: Added from Mitac */
-	{ 0x52,0xe2, 49}, /* 0x37 - added for 16:9 modes (not in any BIOS) */
-	{ 0x2b,0x61, 78}, /* 0x38 - added for 16:9 modes (not in any BIOS) */
-	{ 0x70,0x44,108}, /* 0x39 - added for 16:9 modes (not in any BIOS) */
-	{ 0x54,0x42,135}, /* 0x3a - added for 16:9 modes (not in any BIOS) */
-	{ 0x41,0x22,157}, /* 0x3b - added for 16:9 modes (not in any BIOS) */
-	{ 0x52,0x07,149}, /* 0x3c - added for 1280x960-85 (not in any BIOS)*/
-	{ 0x62,0xc6, 34}, /* 0x3d - added for 848x480-60 (not in any BIOS) */
-	{ 0x30,0x23, 88}, /* 0x3e - added for 1360x768-60 (not in any BIOS)*/
-	{ 0x3f,0x64, 46}, /* 0x3f - added for 640x480-100 (not in any BIOS)*/
-	{ 0x72,0x2a, 76}, /* 0x40 - test for SiS730 */
-	{ 0x15,0x21, 79}, /* 0x41 - test for SiS730 */
+	{ 0x52,0x2a, 54}, /* 0x21 */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x22 */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x23 */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x24 */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x25 */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x26 */  /* 301 TV */
+	{ 0x31,0xc2, 39}, /* 0x27 */
+	{ 0xbf,0xc8, 35}, /* 0x28 */  /* 856x480 */
+	{ 0x60,0x36, 30}, /* 0x29 */  /* CH/UNTSC TEXT | LVDS_2(CH) - 730, A901(301B), Mitac(CH): 0xe0, 0xb6, 30 */
+	{ 0x40,0x4a, 28}, /* 0x2a */  /* CH-TV */
+	{ 0x9f,0x46, 44}, /* 0x2b */  /* CH-TV */
+	{ 0x97,0x2c, 26}, /* 0x2c */  /* CH-TV */
+	{ 0x44,0xe4, 25}, /* 0x2d */  /* CH-TV */
+	{ 0x7e,0x32, 47}, /* 0x2e */  /* CH-TV */
+	{ 0x8a,0x24, 31}, /* 0x2f */  /* CH/PAL TEXT | LVDS_2(CH), Mitac(CH) -  730, A901(301B): 0x57, 0xe4, 31 */
+	{ 0x97,0x2c, 26}, /* 0x30 */  /* CH-TV */
+	{ 0xce,0x3c, 39}, /* 0x31 */  /* CH-TV */
+	{ 0x52,0x4a, 36}, /* 0x32 */  /* CH/PAL 800x600 5/6 */
+	{ 0x34,0x61, 95}, /* 0x33 */
+	{ 0x78,0x27,108}, /* 0x34 */  /* Replacement for index 0x14 for 630 (?) */
+	{ 0xce,0x25,189}, /* 0x35 */  /* Replacement for index 0x1b for 730 (and 540?) */
+	{ 0x45,0x6b, 21}, /* 0x36 */  /* Chrontel SuperOverscan */
+	{ 0x52,0xe2, 49}, /* 0x37 */  /* 16:9 modes  */
+	{ 0x2b,0x61, 78}, /* 0x38 */  /* 16:9 modes  */
+	{ 0x70,0x44,108}, /* 0x39 */  /* 16:9 modes  */
+	{ 0x54,0x42,135}, /* 0x3a */  /* 16:9 modes  */
+	{ 0x41,0x22,157}, /* 0x3b */  /* 16:9 modes  */
+	{ 0x52,0x07,149}, /* 0x3c */  /* 1280x960-85 */
+	{ 0x62,0xc6, 34}, /* 0x3d */  /* 848x480-60  */
+	{ 0x30,0x23, 88}, /* 0x3e */  /* 1360x768-60 */
+#if 0
+	{ 0x3f,0x64, 46}, /* 0x3f */  /* 640x480-100 */
+#endif
+        { 0x70,0x29, 81}, /* 0x3f */  /* 1280x768-60 */
+	{ 0x72,0x2a, 76}, /* 0x40 */  /* test for SiS730 */
+	{ 0x15,0x21, 79}, /* 0x41 */  /* test for SiS730 */
+	{ 0xa1,0x42,108}, /* 0x42 */  /* 1280x960 LCD */
+	{ 0x37,0x61,100}, /* 0x43 */  /* 1280x960 LCD */
+	{ 0xe3,0x9a,106}, /* 0x44 */  /* 1360x1024 - special for Barco iQ R300 */
 	{ 0xff,0x00,  0}   
 };
 
@@ -1089,66 +782,10 @@
 static const UCHAR  SiS300_ScreenOffset[] =
 {
 	0x14,0x19,0x20,0x28,0x32,0x40,0x50,
-        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,  /* 0x35 for 848 and 856 */
-	0x55,0xff			     /* 0x55 for 1360 */	
+        0x64,0x78,0x80,0x2d,0x35,0x48,0x35,
+	0x55,0x30,0xff
 };
 
-typedef struct _SiS300_StResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-} SiS300_StResInfoStruct;
-
-static const SiS300_StResInfoStruct  SiS300_StResInfo[] =
-{
-	{ 640,400},
-	{ 640,350},
-	{ 720,400},
-	{ 720,350},
-	{ 640,480}
-};
-
-typedef struct _SiS300_ModeResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR  XChar;
-	UCHAR  YChar;
-} SiS300_ModeResInfoStruct;
-
-static const SiS300_ModeResInfoStruct  SiS300_ModeResInfo[] =
-{
-	{  320, 200, 8, 8},  /* 0x00 */
-	{  320, 240, 8, 8},  /* 0x01 */
-	{  320, 400, 8, 8},  /* 0x02 */
-	{  400, 300, 8, 8},  /* 0x03 */
-	{  512, 384, 8, 8},  /* 0x04 */
-	{  640, 400, 8,16},  /* 0x05 */
-	{  640, 480, 8,16},  /* 0x06 */
-	{  800, 600, 8,16},  /* 0x07 */
-	{ 1024, 768, 8,16},  /* 0x08 */
-	{ 1280,1024, 8,16},  /* 0x09 */
-	{ 1600,1200, 8,16},  /* 0x0a */
-	{ 1920,1440, 8,16},  /* 0x0b */
-	{  720, 480, 8,16},  /* 0x0c */
-	{  720, 576, 8,16},  /* 0x0d */
-	{ 1280, 960, 8,16},  /* 0x0e */
-	{ 1024, 600, 8,16},  /* 0x0f */
-	{ 1152, 768, 8,16},  /* 0x10 */
-	{ 2048,1536, 8,16},  /* 0x11 - TW: Not in BIOS! */
-	{  800, 480, 8,16},  /* 0x12 - TW: New, not in any BIOS */
-	{ 1024, 576, 8,16},  /* 0x13 - TW: New, not in any BIOS */
-	{ 1280, 720, 8,16},  /* 0x14 - TW: New, not in any BIOS */
-	{ 1152, 864, 8,16},  /* 0x15 - TW: New, not in any BIOS */
-	{  848, 480, 8,16},  /* 0x16 - TW: New, not in any BIOS */
-	{  856, 480, 8,16},  /* 0x17 - TW: New, not in any BIOS */
-	{ 1360, 768, 8,16}   /* 0x18 - TW: New, not in any BIOS */
-};
-
-static const UCHAR SiS300_OutputSelect = 0x40;
-
-static const UCHAR SiS300_SoftSetting  = 0x30;
-
 #ifndef LINUX_XF86
 static UCHAR SiS300_SR07 = 0x10;
 #endif
@@ -1183,7 +820,7 @@
 static const USHORT SiS300_RGBSenseData = 0xd1;
 static const USHORT SiS300_VideoSenseData = 0xb3;
 static const USHORT SiS300_YCSenseData = 0xb9;
-static const USHORT SiS300_RGBSenseData2 = 0x0190;     /*301b*/
+static const USHORT SiS300_RGBSenseData2 = 0x0190;
 static const USHORT SiS300_VideoSenseData2 = 0x0174;
 static const USHORT SiS300_YCSenseData2 = 0x016b;
 
@@ -1192,15 +829,6 @@
 static UCHAR SiS300_CR49[2];
 #endif
 
-static const UCHAR SiS300_NTSCPhase[]  = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
-static const UCHAR SiS300_PALPhase[]   = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00};  */
-static const UCHAR SiS300_PALMPhase[]  = {0x21,0xE4,0x2E,0x9B};  /* palmn */
-static const UCHAR SiS300_PALNPhase[]  = {0x21,0xF4,0x3E,0xBA};
-static const UCHAR SiS300_NTSCPhase2[] = {0x21,0xF0,0x7B,0xD6};  /* 301b */
-static const UCHAR SiS300_PALPhase2[]  = {0x2a,0x09,0x86,0xe9};  /* 301b */
-static const UCHAR SiS300_PALMPhase2[] = {0x21,0xE6,0xEF,0xA4}; /* TW: palm 301b*/
-static const UCHAR SiS300_PALNPhase2[] = {0x21,0xF6,0x94,0x46}; /* TW: paln 301b*/
-
 typedef struct _SiS300_PanelDelayTblStruct
 {
 	UCHAR timer[2];
@@ -1208,7 +836,7 @@
 
 static const SiS300_PanelDelayTblStruct  SiS300_PanelDelayTbl[] =
 {
-	{{0x05,0xaa}}, /* TW: From 2.04.5a */
+	{{0x05,0xaa}},
 	{{0x05,0x14}},
 	{{0x05,0x36}},
 	{{0x05,0x14}},
@@ -1355,309 +983,6 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS300_LCDDataStruct  SiS300_LCD1280x960Data[] =
-{
-	{    9,   2, 800, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{   30,  11,1056, 625,1800,1000},
-	{    5,   3,1350, 800,1800,1000},
-	{    1,   1,1576,1050,1576,1050},
-	{    1,   1,1800,1000,1800,1000}
-};
-
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1400x1050Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_ExtLCD1600x1200Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1400x1050Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_StLCD1600x1200Data[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1400x1050[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS300_LCDDataStruct  SiS300_NoScaleData1600x1200[] =  /* TW: New */
-{
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0},
-	{    0,   0,   0,   0,   0,   0}
-};
-
-
-typedef struct _SiS300_TVDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
-} SiS300_TVDataStruct;
-
-static const SiS300_TVDataStruct  SiS300_StPALData[] =
-{
-	{    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-	{    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
-	{    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtPALData[] =
-{
-	{   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-	{  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
-	{   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
-	{    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
-	{    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},
-	{   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},
-	{    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},
-	{    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}
-
-};
-
-static const SiS300_TVDataStruct  SiS300_StNTSCData[] =
-{
-	{    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
-	{    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
-	{    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtNTSCData[] =
-{
-	{  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-	{   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
-	{  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
-	{  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
-	{  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
-	{  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
-	{  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
-	{   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
-};
-
-#if 0
-static const SiS300_TVDataStruct  SiS300_St1HiTVData[]=
-{
-  
-};
-#endif
-
-static const SiS300_TVDataStruct  SiS300_St2HiTVData[]=
-{
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const SiS300_TVDataStruct  SiS300_ExtHiTVData[]=
-{
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const UCHAR SiS300_NTSCTiming[] =
-{
-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,  /* (in 2.06.50) */
-/*	0x0c,0x50,0x00,0x99,0x00,0xec,0x4a,0x17,     (in 2.04.5a) */
-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,  /* (in 2.06.50) */
-/*	0x88,0x00,0x4b,0x00,0x00,0xe2,0x00,0x02,     (in 2.04.5a) */
-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
-};
-
-static const UCHAR SiS300_PALTiming[] =
-{
-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-        0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,  /* (in 2.06.50) */
-/*	0x70,0x50,0x00,0x97,0x00,0xd7,0x5d,0x17,     (in 2.04.5a) */
-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,  /* (in 2.06.50) */
-/*	0x88,0x00,0x45,0x00,0x00,0xe8,0x00,0x02,     (in 2.04.5a) */
-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
-};
-
-static const UCHAR SiS300_HiTVExtTiming[] =	 /* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS300_HiTVSt1Timing[] =   	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
-};
-
-static const UCHAR SiS300_HiTVSt2Timing[] =	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS300_HiTVTextTiming[] =   	/* TW: New */
-{
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
-};
-
-static const UCHAR SiS300_HiTVGroup3Data[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS300_HiTVGroup3Simu[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS300_HiTVGroup3Text[] =   	/* TW: New */
-{
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
 typedef struct _SiS300_LVDSDataStruct
 {
 	USHORT VGAHT;
@@ -1666,366 +991,14 @@
 	USHORT LCDVT;
 } SiS300_LVDSDataStruct;
 
-static const SiS300_LVDSDataStruct  SiS300_LVDS320x480Data_1[] =
-{
-	{848, 433,400, 525},
-	{848, 389,400, 525},
-	{848, 433,400, 525},
-	{848, 389,400, 525},
-	{848, 518,400, 525},
-	{1056,628,400, 525},
-	{400, 525,400, 525},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_1[] =
-{
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 433,1060, 629},
-	{848, 389,1060, 629},
-	{848, 518,1060, 629},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS800x600Data_2[] =
-{
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{800, 449,1000, 644},
-	{800, 525,1000, 635}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_1[] =
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x768Data_2[] =
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_1[]=  
-{	
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 522,1688,1066},
-	{1208, 642,1688,1066},
-	{1432, 810,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x1024Data_2[]=  
-{	
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_1[] =   
-{
-        {928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{928, 496, 1688, 1066},
-	{1088, 616, 1688, 1066},
-	{1312, 784, 1688, 1066},
-	{1568, 1040, 1688, 1066},
-	{1688, 1066, 1688, 1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1400x1050Data_2[] =  
-{
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_1[]=  
-{
-        {1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 530, 2048,1250},
-	{1248, 650, 2048,1250},
-	{1472, 818, 2048,1250},
-	{1728,1066, 2048,1250},
-	{1848,1066, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1600x1200Data_2[]= 
-{
-        {2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_1[]= 
-{	
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 518, 1408, 806},
-	{ 928, 638, 1408, 806},
-	{1152, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x768Data_2[]=  
-{	
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_1[] =
-{
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 604,1344, 800},
-	{840, 560,1344, 800},
-	{840, 689,1344, 800},
-	{1050, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{800, 449,1280, 789},
-	{800, 525,1280, 785}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1024x600Data_2[] =
-{
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{1344, 800,1344, 800},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_1[] =
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1152x768Data_2[] =
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-/* TW: pass 1:1 data */
-static const SiS300_LVDSDataStruct  SiS300_LVDSXXXxXXXData_1[]=  
-{
-        { 800, 449,  800, 449},
-	{ 800, 449,  800, 449},
-	{ 900, 449,  900, 449},
-	{ 900, 449,  900, 449},
-	{ 800, 525,  800, 525},  /*  640x480   */
-	{1056, 628, 1056, 628},  /*  800x600   */
-	{1344, 806, 1344, 806},  /* 1024x768   */
-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
-	/* No other panels ! */
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS640x480Data_1[] =
-{
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 449, 800, 449},
-	{800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_1[] =   /* TW: New */
-{
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 438,1344, 806},
-	{840, 409,1344, 806},
-	{840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LVDS1280x960Data_2[] =   /* TW: New */
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_1[] =   /* TW: New */
-{	/* TW: Might be temporary (invalid) data */
-        {928, 416, 1688, 1066},
-	{928, 366, 1688, 1066},
-	{1008, 416, 1688, 1066},
-	{1008, 366, 1688, 1066},
-	{1200, 530, 1688, 1066},
-	{1088, 616, 1688, 1066},
-	{1312, 784, 1688, 1066},
-	{1568, 1040, 1688, 1066},
-	{1688, 1066, 1688, 1066}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1400x1050Data_2[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_1[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{800, 449,1280, 801},
-	{800, 525,1280, 813}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_LCDA1600x1200Data_2[] =   /* TW: New */
-{	/* TW: Temporary data. Not valid */
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0}
-};
-
-
-/* TW: New: */
-static const SiS300_LVDSDataStruct  SiS300_CHTVUNTSCData[] =
-{
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{840, 600, 840, 600},
-	{784, 600, 784, 600},
-	{1064, 750,1064, 750}
-};
-
-static const SiS300_LVDSDataStruct  SiS300_CHTVONTSCData[] =
-{
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{840, 525, 840, 525},
-	{784, 525, 784, 525},
-	{1040, 700,1040, 700}
-};
-
 static const SiS300_LVDSDataStruct  SiS300_CHTVUPALData[] =
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 750, 840, 750},
-	{936, 836, 936, 836}
+	{ 840, 750, 840, 750},
+	{ 936, 836, 936, 836}
 };
 
 static const SiS300_LVDSDataStruct  SiS300_CHTVOPALData[] =
@@ -2034,8 +1007,8 @@
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 625, 840, 625},
-	{960, 750, 960, 750}
+	{ 840, 625, 840, 625},
+	{ 960, 750, 960, 750}
 };
 
 static const SiS300_LVDSDataStruct  SiS300_CHTVSOPALData[] =
@@ -2044,12 +1017,10 @@
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
-	{840, 500, 840, 500},
-	{944, 625, 944, 625}
+	{ 840, 500, 840, 500},
+	{ 944, 625, 944, 625}
 };
 
-/* TW: new end */
-
 typedef struct _SiS300_LVDSDesStruct
 {
 	USHORT LCDHDES;
@@ -2058,57 +1029,90 @@
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType00_1[] =
 {
+	{ 1059, 626 },   /* 2.08 */
+	{ 1059, 624 },
+	{ 1059, 626 },
+	{ 1059, 624 },
+	{ 1059, 624 },
+	{    0, 627 },
+	{    0, 627 },
+	{    0,   0 },
+	{    0,   0 }
+#if 0
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{0, 627},
+	{0, 627},
+	{0,   0},
+	{0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType01_1[] =
 {
+	{   0,   0 },  /* 2.08 */
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 },
+	{   0,   0 }
+#if 0
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType02_1[] =
 {
+	{ 1059, 626 },  /* 2.08 */
+	{ 1059, 624 },
+	{ 1059, 626 },
+	{ 1059, 624 },
+	{ 1059, 624 },
+	{    0, 627 },
+	{    0, 627 },
+	{    0,   0 },
+	{    0,   0 }
+#if 0
 	{0, 626},
 	{0, 624},
 	{0, 626},
 	{0, 624},
 	{0, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{0, 627},
+	{0, 627},
+	{0,   0},
+	{0,   0}
+#endif
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType03_1[] =
 {
-	{ 8, 436},
-	{ 8, 440},
-	{ 8, 436},
-	{ 8, 440},
-	{ 8, 512},
+	{   8, 436},
+	{   8, 440},
+	{   8, 436},
+	{   8, 440},
+	{   8, 512},
 	{1343, 798},
 	{1343, 794},
 	{1343, 798},
 	{1343, 794}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1[] =	/* 1280x1024 */
 {
 	{1343, 798},
 	{1343, 794},
@@ -2116,9 +1120,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType05_1[] =
@@ -2129,9 +1133,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType06_1[] =
@@ -2142,9 +1146,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType07_1[] =
@@ -2155,9 +1159,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType08_1[] =
@@ -2167,10 +1171,10 @@
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{   0, 627},
+	{   0, 627},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType09_1[] =
@@ -2181,9 +1185,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0a_1[] =
@@ -2193,23 +1197,23 @@
 	{1059, 626},
 	{1059, 624},
 	{1059, 624},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{   0, 627},
+	{   0, 627},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0b_1[] =
 {
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},
-	{1343, 0},   /* 640x480 - BIOS 1343, 0 */
-	{1343, 0},
-	{ 0, 799},
-	{ 0, 0},
-	{ 0, 0}
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{1343,   0},
+	{   0, 799},
+	{   0,   0},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0c_1[] =
@@ -2220,9 +1224,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0d_1[] =
@@ -2233,9 +1237,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0e_1[] =
@@ -2244,11 +1248,11 @@
 	{1343, 794},
 	{1343, 798},
 	{1343, 794},
-	{1343,   0},  /* 640x480 */
-	{1343,   0},  /* 800x600 */
-	{ 0, 805},    /* 1024x768 */
-	{ 0, 794},    /* 1280x1024 */
-	{ 0,   0}     /* 1280x960 - not applicable */
+	{1343,   0},    /* 640x480 */
+	{1343,   0},    /* 800x600 */
+	{   0, 805},    /* 1024x768 */
+	{   0, 794},    /* 1280x1024 */
+	{   0,   0}     /* 1280x960 - not applicable */
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType0f_1[] =
@@ -2259,9 +1263,9 @@
 	{1343, 794},
 	{1343,   0},
 	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType00_2[] =
@@ -2271,10 +1275,10 @@
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{  0, 627},
+	{  0, 627},
+	{  0,   0},
+	{  0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType01_2[] =
@@ -2285,9 +1289,9 @@
 	{1152, 597},
 	{1152, 662},
 	{1232, 722},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{   0, 805},
+	{   0, 794},
+	{   0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType02_2[] =
@@ -2297,10 +1301,10 @@
 	{976, 527},
 	{976, 502},
 	{976, 567},
-	{ 0, 627},
-	{ 0, 627},
-	{ 0,   0},
-	{ 0,   0}
+	{  0, 627},
+	{  0, 627},
+	{  0,   0},
+	{  0,   0}
 };
 
 static const SiS300_LVDSDesStruct  SiS300_PanelType03_2[] =
@@ -2472,156 +1476,57 @@
  	{   0,   0}
 };
 
-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_1[]= 
+/* Custom data for Barco iQ R200/300/400 (BIOS 2.00.07) */
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1a[] =	/* 1280x1024 (1366x1024) */
 {
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0, 806},
-	{ 0, 0 }
-};
-
-static const SiS300_LVDSDesStruct  SiS300_PanelTypeNS_2[] = 
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1076_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1076_2[] =   /* TW: New */
-{
-	{ 1152, 622 },
-	{ 1152, 597 },
-	{ 1152, 622 },
-	{ 1152, 597 },
-	{ 1152, 622 },
-	{ 1232, 722 },
-	{    0, 0   },
-	{    0, 794 },
-	{    0, 0   }
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1210_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1210_2[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1296_1[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS300_LVDSDesStruct SiS300_PanelType1296_2[] =   /* TW: New */
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-
-/* TW: New */
-static const SiS300_LVDSDesStruct  SiS300_CHTVUNTSCDesData[] =
-{
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0}
-};
-
-static const SiS300_LVDSDesStruct  SiS300_CHTVONTSCDesData[] =
-{
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0},
- 	{ 0,   0}
-};
-
-static const SiS300_LVDSDesStruct  SiS300_CHTVUPALDesData[] =
-{
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{  0,   0},
- 	{  0,   0}
+	{1330, 798},  /* 320x200 */
+	{1330, 794},
+	{1330, 798},
+	{1330, 794},
+	{1330,   0},  /* 640x480 / 320x240  */
+	{1343,   0},  /* 800x600 / 400x300  */
+	{   0, 805},  /* 1024x768 / 512x384 */
+	{1688,1066},  /* 1280x1024          */
+	{   0,   0}   /* 1360x1024          */
 };
 
-static const SiS300_LVDSDesStruct  SiS300_CHTVOPALDesData[] =
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2a[] =
 {
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{256,   0},
- 	{  0,   0},
- 	{  0,   0}
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805},
+	{1688,1066},
+	{   0,   0}
+};
+
+/* Custom data for Barco iQ G200/300/400 (BIOS 2.00.07) */
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_1b[] =	/* 1024x768 */
+{
+	{1330, 798},  /* 320x200 */
+	{1330, 794},
+	{1330, 798},
+	{1330, 794},
+	{1330,   0},  /* 640x480 / 320x240  */
+	{1343,   0},  /* 800x600 / 400x300  */
+	{   0, 805}   /* 1024x768 / 512x384 */
+};
+
+static const SiS300_LVDSDesStruct  SiS300_PanelType04_2b[] =
+{
+	{1152, 622},
+	{1152, 597},
+	{1152, 622},
+	{1152, 597},
+	{1152, 662},
+	{1232, 722},
+	{   0, 805}
 };
-/* TW: New end */
 
-/* TW: New for SiS300+301LV */
+
 typedef struct _SiS300_Part2PortTblStruct
 {
  	UCHAR CR[12];
@@ -2726,6 +1631,28 @@
 	  0x01 }}
 };
 
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
+{
+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
+	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
+	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
+	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+	  0x00 }},
+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+	  0x01 }}
+};
+
 static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1[] =
 { 
 	{{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
@@ -2751,55 +1678,31 @@
 	  0x01}}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
-{
-	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00 }},
-	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-	  0x00 }},
-	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-	  0x01 }},
-	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01 }}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_1_H[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
 {
-	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-	  0x00 }},
-	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-	  0x00 }},
-	{{0x30,0x27,0x94,0x2c,0x92,0xaf,0x1f,
-	  0x90,0x85,0x8f,0xab,0x30,0x00,0x04,
-	  0x00 }},
-	{{0x30,0x27,0x94,0x2c,0x92,0x83,0x1f,
-	  0x5e,0x83,0x5d,0x79,0x10,0x00,0x04,
-	  0x00 }},
-	{{0x30,0x27,0x94,0x2c,0x92,0x04,0x3e,
-	  0xe0,0x85,0xdf,0xfb,0x10,0x00,0x04,
+	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
 	  0x00 }},
-	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
+	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
+	  0x00}},
+	{{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5D,0x83,0x10,0x00,0x44,
+	  0x00}},
+	{{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xE2,0x89,0xdf,0x05,0x00,0x00,0x44,
+	  0x00}},
+	{{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5A,0x8F,0x57,0x7D,0x20,0x00,0x55,
+	  0x01}},
+	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
 	  0x01 }}
-};
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_1_H[] =
-{
+#if 0
 	{{0x37,0x27,0x9B,0x2b,0x94,0xc4,0x1f,
 	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
 	  0x00 }},
@@ -2821,6 +1724,32 @@
 	{{0x4f,0x3F,0x93,0x45,0x0D,0x24,0xf5,
 	  0x02,0x88,0xFf,0x25,0x10,0x00,0x01,
 	  0x01 }}
+#endif
+};
+
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1[] =
+{
+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0xb4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x82,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00 }},
+	{{0x63,0x4f,0x87,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+	  0x00 }},
+	{{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+	  0x01 }},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01 }}
 };
 
 static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_1_H[] =
@@ -2870,32 +1799,29 @@
 	  0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
 {
-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
 	  0x00 }},
-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
 	  0x00 }},
-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
+	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
 	  0x00 }},
-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
+	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
 	  0x00 }},
-	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
+	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
 	  0x00 }},
-	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01 }},
-	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
+	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
 	  0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2[] =
 {
 	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
 	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
@@ -2920,28 +1846,6 @@
 	  0x01 }}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT1800x600_2_H[] =
-{
-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0x3e,
-	  0xf4,0x88,0x8f,0x73,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x3d,0x27,0x81,0x3a,0x1a,0x72,0x3e,
-	  0xdb,0x8f,0x5d,0x73,0x20,0x00,0x05,
-	  0x00 }},
-	{{0x3d,0x27,0x81,0x32,0x1a,0x72,0xba,
-	  0x1c,0x80,0xdf,0x73,0x00,0x00,0x05,
-	  0x00 }},
-	{{0x3d,0x31,0x81,0x37,0x1f,0x72,0xf0,
-	  0x58,0x8c,0x57,0x73,0x20,0x00,0x05,
-	  0x01 }}
-};
-
 static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x768_2_H[] =
 {
 	{{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
@@ -2967,6 +1871,31 @@
 	  0x01 }}
 };
 
+static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2[] =
+{
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00 }},
+	{{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01 }},
+	{{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01 }}
+};
+
 static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11280x1024_2_H[] =
 {
 	{{0x4f,0x27,0x93,0x39,0x81,0x24,0xbb,
@@ -2992,207 +1921,6 @@
 	  0x01}}
 };
 
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-          0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11024x600_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS300_LVDSCRT1DataStruct  SiS300_LVDSCRT11152x768_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-/* TW: New */
 static const SiS300_LVDSCRT1DataStruct  SiS300_CHTVCRT1UNTSC[] =
 {
 	{{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
@@ -3302,9 +2030,7 @@
 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
 	  0x01 }}
 };
-/* TW: New end */
 
-/* TW: New */
 typedef struct _SiS300_CHTVRegDataStruct
 {
 	UCHAR Reg[16];
@@ -3354,16 +2080,14 @@
 
 static const SiS300_CHTVRegDataStruct SiS300_CHTVReg_SOPAL[] =
 {
-	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 5/4 */
+	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}}, /* Mode 9: 640x400 PAL 1/1 */
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x01,0x50,0x34,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x41,0x12,0x00,0x50,0x00,0,0,0,0,0,0,0,0,0,0,0}},
 	{{0x60,0x30,0x00,0x10,0x00,0,0,0,0,0,0,0,0,0,0,0}}, /* TW: Mode 13: 640x480 PAL 5/4 */
 	{{0x81,0x50,0x00,0x1b,0x00,0,0,0,0,0,0,0,0,0,0,0}}  /* TW: Mode 19: 800x600 PAL 1/1 */
 };
-/* TW: New end */
 
-/* TW: New */
 static const UCHAR SiS300_CHTVVCLKUNTSC[]  = {0x29,0x29,0x29,0x29,0x2a,0x2e};
 
 static const UCHAR SiS300_CHTVVCLKONTSC[]  = {0x2c,0x2c,0x2c,0x2c,0x2d,0x2b};
@@ -3375,6 +2099,5 @@
 static const UCHAR SiS300_CHTVVCLKOPAL[]   = {0x2f,0x2f,0x2f,0x2f,0x30,0x32};
 
 static const UCHAR SiS300_CHTVVCLKSOPAL[]  = {0x2f,0x2f,0x2f,0x2f,0x36,0x29};
-/* TW: New end */
 
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/310vtbl.h fbdev-2.6/drivers/video/sis/310vtbl.h
--- linus-2.6/drivers/video/sis/310vtbl.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/310vtbl.h	Thu Oct 16 14:13:41 2003
@@ -1,7 +1,37 @@
-
-
-/* Register settings for SiS 310/325/330 series */
-
+/* $XFree86$ */
+/*
+ * Register settings for SiS 315/330 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
 
 typedef struct _SiS310_StStruct
 {
@@ -39,466 +69,12 @@
 	{0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
 };
 
-typedef struct _SiS310_StandTableStruct
-{
-	UCHAR CRT_COLS;
-	UCHAR ROWS;
-	UCHAR CHAR_HEIGHT;
-	USHORT CRT_LEN;
-	UCHAR SR[4];
-	UCHAR MISC;
-	UCHAR CRTC[0x19];
-	UCHAR ATTR[0x14];
-	UCHAR GRC[9];
-} SiS310_StandTableStruct;
-
-static const SiS310_StandTableStruct SiS310_StandTable[]=
-{
-/* 0x00: MD_0_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x01: MD_1_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x02: MD_2_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x03: MD_3_200 - mode 0x03 - 0 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x04: MD_4 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* 0x05: MD_5 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
-/* 0x06: MD_6 */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff}
- },
-/* 0x07: MD_7 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* 0x08: MDA_DAC */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f}
- },
-/* 0x09: CGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* 0x0a: EGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
-/* 0x0b: VGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04}
- },
-/* 0x0c */ 
- {
-  0x08,0x0c,0x10,0x0a08,
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* 0x0d: MD_D */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x0e: MD_E */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x0f: ExtVGATable - modes > 0x13 */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- },
-/* 0x10: ROM_SAVEPTR */
- {
-  0x9f,0x3b,0x00,0x00c0,
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
-/* 0x11: MD_F */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff}
- },
-/* 0x12: MD_10 */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x13: MD_0_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x14: MD_1_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x15: MD_2_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x16: MD_3_350 - mode 0x03 - 1 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x17: MD_0_1_400 */
- {
-  0x28,0x18,0x10,0x0800,
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
-/* 0x19: MD_7_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
-/* 0x1a: MD_11 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff}
- },
-/* 0x1b: ExtEGATable - Modes <= 0x02 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
-/* 0x1c: MD_13 */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- }
-};
-
 typedef struct _SiS310_ExtStruct
 {
 	UCHAR Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;    /* TW: Address of table entry in (older) BIOS image */
 	USHORT Ext_VESAID;
-	UCHAR Ext_VESAMEMSize;
 	UCHAR Ext_RESINFO;
 	UCHAR VB_ExtTVFlickerIndex;
 	UCHAR VB_ExtTVEdgeIndex;
@@ -506,93 +82,93 @@
 	UCHAR REFindex;
 } SiS310_ExtStruct;
 
-/* TW: Checked with 650/LVDS and 650/301LVx 1.10.6s */
 static const SiS310_ExtStruct  SiS310_EModeIDTable[]=
 {
-	{0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x? */
-	{0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x8 */
-/*	{0x2e,0x021b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x08},    */    /* 640x480x8 - 650/LVDS BIOS (no CRt2Mode) */
-	{0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},          /* 640x400x8 */
-/*	{0x2f,0x021b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x10},    */    /* 640x400x8 - 650/LVDS BIOS (no CRt2Mode) */
-	{0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x8 */
-/*	{0x30,0x221b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x00},    */    /* 800x600x8 - 650/LVDS BIOS (no CRt2Mode) */
-/*      {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},    */    /* 720x480x8 */
-        {0x31,0x0a1b,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x8 BIOS (301/LVDS) */
-	{0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x8 */
-	{0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x16 */
-	{0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x16 */
-	{0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x11},          /* 720x480x32 */
-	{0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x12},          /* 720x576x32 */
-	{0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x? */
-	{0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x8 */
-	{0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x8 */
-	{0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x8 */
-	{0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x16 - 650/301LVx - no CRT2Mode? */
-	{0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x25},
-	{0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x25},
-	{0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x08},
-	{0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x16 */
-	{0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x00},
-	{0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x16 */
-	{0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x13},
-	{0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x16 */
-	{0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1a},
-	{0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x16 */
-	{0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x26},	   /* 320x240 */
-	{0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x27},
-  	{0x52,0xba1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x28},          /* 650/301 BIOS */
-	{0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x26},
-	{0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x27},
- 	{0x58,0xba1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x28},          /* BIOS (301+LVDS) */
-	{0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x25},	   /* 320x200 */
-	{0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x8 fstn add new mode*/
-	{0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},          /* 320x480x16 fstn add new mode*/
-	{0x5c,0xba1f,0x0204,0x3a49,0x0000,0x08,0x04,0x00,0x00,0x00,0x28},          /* TW: inserted 512x384x32 */
-	{0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x10},
-	{0x5e,0x0a1f,0x0305,0x3a50,0x0000,0x08,0x05,0x00,0x00,0x07,0x10},          /* TW: Inserted 640x400x32 */
-	{0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x08},          /* 640x480x32 */
-	{0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x00},          /* 800x600x32 */
-	{0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x08,0x13},          /* 1024x768x32 */
-	{0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1a},          /* 1280x1024x32 */
-	{0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x1e},          /* 1600x1200x32 */
-	{0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x8 */
-	{0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x16 */
-	{0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},          /* 1920x1440x32 */
-	{0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x8 */
-	{0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x16 */
-	{0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},          /* 2048x1536x32 */
-	{0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x8 */
-	{0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x8 */
-	{0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},          /* 1024x576x16 */
-	{0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x16 */
-	{0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x32 */
-	{0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},	   /* 1024x576x32 */
-	{0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x32 */
-	{0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},	   /* 1280x720x8 */
-	{0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},          /* 800x480x16 */
-	{0x7c,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x8 - TW */
-	{0x7d,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x16 - TW */
-	{0x7e,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x3d},          /* 1280x960x32 - TW */
-        /* TW: 650/LVDS BIOS new modes */
-	{0x23,0x0e3b,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x8 */
-	{0x24,0x0e7d,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x16 */
-	{0x25,0x0eff,0x0614,0x36f7,0x0000,0x08,0x14,0x00,0x00,0x00,0x40},          /* 1280x768x32 */
-	{0x26,0x0e3b,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x8 */
-	{0x27,0x0e7d,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x16 */
-	{0x28,0x0eff,0x0c15,0x36fe,0x0000,0x08,0x15,0x00,0x00,0x00,0x41},          /* 1400x1050x32*/
-	{0x29,0x0e1b,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},    /* TW: NEW 1152x864 - not in BIOS */
-	{0x2a,0x0e3d,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
-	{0x2b,0x0e7f,0x0d16,0x0000,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
-	{0x39,0x2a1b,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},    /* TW: NEW 848x480 - not in BIOS */
-	{0x3b,0x2a3d,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
-	{0x3e,0x2a7f,0x0b17,0x0000,0x0000,0x08,0x17,0x00,0x00,0x00,0x45},
-	{0x3f,0x2a1b,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},    /* TW: NEW 856x480 - not in BIOS */
-	{0x42,0x2a3d,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
-	{0x45,0x2a7f,0x0b13,0x0000,0x0000,0x08,0x13,0x00,0x00,0x00,0x47},
-	{0x48,0x2a1b,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},    /* TW: NEW 1360x768 - not in BIOS */
-	{0x4b,0x2a3d,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
-	{0x4e,0x2a7f,0x0e18,0x0000,0x0000,0x08,0x18,0x00,0x00,0x00,0x49},
-	{0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x6a,0x2212,0x0407,0x0102,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x? */
+	{0x2e,0x0a1b,0x0306,0x0101,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x8 */
+        {0x2f,0x0a1b,0x0305,0x0100,SIS_RI_640x400,  0x00,0x00,0x05,0x10}, /* 640x400x8 */
+	{0x30,0x2a1b,0x0407,0x0103,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x8 */
+        {0x31,0x0a1b,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x8 */
+	{0x32,0x0a1b,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x8 */
+	{0x33,0x0a1d,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x16 */
+	{0x34,0x2a1d,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x16 */
+	{0x35,0x0a1f,0x0a0d,0x0000,SIS_RI_720x480,  0x00,0x00,0x06,0x11}, /* 720x480x32 */
+	{0x36,0x2a1f,0x0a0e,0x0000,SIS_RI_720x576,  0x00,0x00,0x06,0x12}, /* 720x576x32 */
+	{0x37,0x0212,0x0508,0x0104,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x? */
+	{0x38,0x0a1b,0x0508,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x8 */
+	{0x3a,0x0e3b,0x0609,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x8 */
+	{0x3c,0x0e3b,0x070a,0x0130,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x8 */
+	{0x3d,0x0e7d,0x070a,0x0131,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x16 */
+	{0x40,0x9a1c,0x0000,0x010d,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x15 */
+	{0x41,0x9a1d,0x0000,0x010e,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x16 */
+	{0x43,0x0a1c,0x0306,0x0110,SIS_RI_640x480,  0x00,0x00,0x05,0x08},
+	{0x44,0x0a1d,0x0306,0x0111,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x16 */
+	{0x46,0x2a1c,0x0407,0x0113,SIS_RI_800x600,  0x00,0x00,0x07,0x00},
+	{0x47,0x2a1d,0x0407,0x0114,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x16 */
+	{0x49,0x0a3c,0x0508,0x0116,SIS_RI_1024x768, 0x00,0x00,0x00,0x13},
+	{0x4a,0x0a3d,0x0508,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x16 */
+	{0x4c,0x0e7c,0x0609,0x0119,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a},
+	{0x4d,0x0e7d,0x0609,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x16 */
+	{0x50,0x9a1b,0x0001,0x0132,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x8  */
+	{0x51,0xba1b,0x0103,0x0133,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x8  */
+  	{0x52,0xba1b,0x0204,0x0134,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x8  */
+	{0x56,0x9a1d,0x0001,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x16 */
+	{0x57,0xba1d,0x0103,0x0136,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x16 */
+ 	{0x58,0xba1d,0x0204,0x0137,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x16 */
+	{0x59,0x9a1b,0x0000,0x0138,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x8  */
+	{0x5a,0x021b,0x0014,0x0138,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x8  fstn */
+	{0x5b,0x0a1d,0x0014,0x0135,SIS_RI_320x240,  0x00,0x00,0x04,0x3f}, /* 320x240x16 fstn */
+	{0x5c,0xba1f,0x0204,0x0000,SIS_RI_512x384,  0x00,0x00,0x00,0x28}, /* 512x384x32 */
+	{0x5d,0x0a1d,0x0305,0x0139,SIS_RI_640x400,  0x00,0x00,0x05,0x10},
+	{0x5e,0x0a1f,0x0305,0x0000,SIS_RI_640x400,  0x00,0x00,0x05,0x10}, /* 640x400x32 */
+	{0x62,0x0a3f,0x0306,0x013a,SIS_RI_640x480,  0x00,0x00,0x05,0x08}, /* 640x480x32 */
+	{0x63,0x2a3f,0x0407,0x013b,SIS_RI_800x600,  0x00,0x00,0x07,0x00}, /* 800x600x32 */
+	{0x64,0x0a7f,0x0508,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x13}, /* 1024x768x32 */
+	{0x65,0x0eff,0x0609,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x1a}, /* 1280x1024x32 */
+	{0x66,0x0eff,0x070a,0x013e,SIS_RI_1600x1200,0x00,0x00,0x00,0x1e}, /* 1600x1200x32 */
+	{0x68,0x067b,0x080b,0x013f,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x8 */
+	{0x69,0x06fd,0x080b,0x0140,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x16 */
+	{0x6b,0x07ff,0x080b,0x0141,SIS_RI_1920x1440,0x00,0x00,0x00,0x29}, /* 1920x1440x32 */
+	{0x6c,0x067b,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x8 */
+	{0x6d,0x06fd,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x16 */
+	{0x6e,0x07ff,0x090c,0x0000,SIS_RI_2048x1536,0x00,0x00,0x00,0x2f}, /* 2048x1536x32 */
+	{0x70,0x2a1b,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x8 */
+	{0x71,0x0a1b,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x8 */
+	{0x74,0x0a1d,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x16 */
+	{0x75,0x0a3d,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x16 */
+	{0x76,0x2a1f,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x32 */
+	{0x77,0x0a1f,0x0511,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x37}, /* 1024x576x32 */
+	{0x78,0x0a3f,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x32 */
+	{0x79,0x0a3b,0x0612,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x3a}, /* 1280x720x8 */
+	{0x7a,0x2a1d,0x0410,0x0000,SIS_RI_800x480,  0x00,0x00,0x07,0x34}, /* 800x480x16 */
+	{0x7c,0x0e3b,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x8 */
+	{0x7d,0x0e7d,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x16 */
+	{0x7e,0x0eff,0x060f,0x0000,SIS_RI_1280x960, 0x00,0x00,0x00,0x3d}, /* 1280x960x32 */
+	{0x23,0x0e3b,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x8 */
+	{0x24,0x0e7d,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x16 */
+	{0x25,0x0eff,0x0614,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x40}, /* 1280x768x32 */
+	{0x26,0x0e3b,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x8 */
+	{0x27,0x0e7d,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x16 */
+	{0x28,0x0eff,0x0c15,0x0000,SIS_RI_1400x1050,0x00,0x00,0x00,0x41}, /* 1400x1050x32*/
+	{0x29,0x0e1b,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43}, /* 1152x864 */
+	{0x2a,0x0e3d,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
+	{0x2b,0x0e7f,0x0d16,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x43},
+	{0x39,0x2a1b,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45}, /* 848x480 */
+	{0x3b,0x2a3d,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
+	{0x3e,0x2a7f,0x0b17,0x0000,SIS_RI_848x480,  0x00,0x00,0x00,0x45},
+	{0x3f,0x2a1b,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47}, /* 856x480 */
+	{0x42,0x2a3d,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
+	{0x45,0x2a7f,0x0b13,0x0000,SIS_RI_856x480,  0x00,0x00,0x00,0x47},
+	{0x48,0x2a1b,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49}, /* 1360x768 */
+	{0x4b,0x2a3d,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
+	{0x4e,0x2a7f,0x0e18,0x0000,SIS_RI_1360x768, 0x00,0x00,0x00,0x49},
+	{0x4f,0x9a1f,0x0000,0x0000,SIS_RI_320x200,  0x00,0x00,0x04,0x25}, /* 320x200x32 */
+	{0x53,0x9a1f,0x0001,0x0000,SIS_RI_320x240,  0x00,0x00,0x04,0x26}, /* 320x240x32 */
+	{0x54,0xba1f,0x0103,0x0000,SIS_RI_400x300,  0x00,0x00,0x07,0x27}, /* 400x300x32 */
+	{0x5f,0x2a1b,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x4a}, /* 768x576x8 */
+	{0x60,0x2a1d,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x4a}, /* 768x576x16 */
+	{0x61,0x2a1f,0x0f0e,0x0000,SIS_RI_768x576,  0x00,0x00,0x06,0x4a}, /* 768x576x32 */
+	{0xff,0x0000,0x0000,0x0000,0x00,            0x00,0x00,0x00,0x00}
 };
 
 typedef struct _SiS310_Ext2Struct
@@ -604,89 +180,87 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS310_Ext2Struct;
 
 static const SiS310_Ext2Struct SiS310_RefIndex[]=
 {
-/*	{0x005f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81},    0x0 - TW: Patch for Chrontel 7019  */
-	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600,0x3a81}, /* 0x0 */
-	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600,0x3a86}, /* 0x1 */
-	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600,0x3a8b}, /* 0x2 */
-	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600,0x3a90}, /* 0x3 */
-	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600,0x3a95}, /* 0x4 */
-	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600,0x3a9a}, /* 0x5 - 4147 TW: Test sync change */
-	{0x0047,0x13,0x13,0x00,0x6a, 800, 600,0x3a9f}, /* 0x6 - 4047 */
-	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600,0x3aa4}, /* 0x7 - 4047 */
-/*	{0xc05f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57},    0x8 - TW: Patch for Chrontel 7019  */
-	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480,0x3a57}, /* 0x8 */
-	{0xc067,0x06,0x02,0x04,0x2e, 640, 480,0x3a5c}, /* 0x9 */
-	{0xc067,0x07,0x02,0x47,0x2e, 640, 480,0x3a61}, /* 0xa */
-	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480,0x3a66}, /* 0xb */
-	{0xc047,0x09,0x05,0x00,0x2e, 640, 480,0x3a6b}, /* 0xc - 4047 */
-	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480,0x3a70}, /* 0xd - 4047 */
-	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480,0x3a75}, /* 0xe - 4047 */
-	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480,0x3a7a}, /* 0xf */
-	{0x407f,0x04,0x00,0x00,0x2f, 640, 400,0x3a50}, /* 0x10 */
-	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480,0x3b85}, /* 0x11 */
-	{0x000f,0x3d,0x03,0x06,0x32, 720, 576,0x3b8c}, /* 0x12 */
-	{0x0187,0x15,0x06,0x00,0x37,1024, 768,0x3aab}, /* 0x13 */
-	{0xc877,0x16,0x0b,0x06,0x37,1024, 768,0x3ab0}, /* 0x14 */
-	{0xc067,0x17,0x0f,0x49,0x37,1024, 768,0x3ab5}, /* 0x15 */
-	{0x0267,0x18,0x11,0x00,0x37,1024, 768,0x3aba}, /* 0x16 */
-	{0x0047,0x19,0x16,0x8c,0x37,1024, 768,0x3abf}, /* 0x17 */
-	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768,0x3ac4}, /* 0x18 - 4047 */
-	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768,0x3ac9}, /* 0x19 - 4047 */
-	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024,0x3adc}, /* 0x1a */
-	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024,0x3ae1}, /* 0x1b */
-	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024,0x3ae6}, /* 0x1c */
-	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024,0x3aeb}, /* 0x1d */
-	{0x0027,0x20,0x21,0x09,0x3c,1600,1200,0x3af2}, /* 0x1e */
-	{0x0007,0x21,0x22,0x00,0x3c,1600,1200,0x3af7}, /* 0x1f */
-	{0x0007,0x22,0x23,0x00,0x3c,1600,1200,0x3afc}, /* 0x20 */
-	{0x0007,0x23,0x25,0x00,0x3c,1600,1200,0x3b01}, /* 0x21 */
-	{0x0007,0x24,0x26,0x00,0x3c,1600,1200,0x3b06}, /* 0x22 */
-	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200,0x3b0b}, /* 0x23 */
-	{0x0007,0x26,0x34,0x00,0x3c,1600,1200,0x3b10}, /* 0x24 */
-	{0x407f,0x00,0x00,0x00,0x40, 320, 200,0x3a34}, /* 0x25 */
-	{0xc07f,0x01,0x00,0x04,0x50, 320, 240,0x3a3b}, /* 0x26 */
-	{0x007f,0x02,0x04,0x05,0x51, 400, 300,0x3a42}, /* 0x27 */
-	{0xc077,0x03,0x0b,0x06,0x52, 512, 384,0x3a49}, /* 0x28 */
-	{0x8007,0x27,0x27,0x00,0x68,1920,1440,0x3b17}, /* 0x29 */
-	{0x4007,0x28,0x29,0x00,0x68,1920,1440,0x3b1c}, /* 0x2a */
-	{0x4007,0x29,0x2e,0x00,0x68,1920,1440,0x3b21}, /* 0x2b */
-	{0x4007,0x2a,0x30,0x00,0x68,1920,1440,0x3b26}, /* 0x2c */
-	{0x4007,0x2b,0x35,0x00,0x68,1920,1440,0x3b2b}, /* 0x2d */
-	{0x4005,0x2c,0x39,0x00,0x68,1920,1440,0x3b30}, /* 0x2e */
-	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536,0x3b37}, /* 0x2f */
-	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536,0x3b3c}, /* 0x30 */
-	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536,0x3b41}, /* 0x31 */
-	{0x4007,0x30,0x37,0x00,0x6c,2048,1536,0x3b46}, /* 0x32 */
-	{0x4005,0x31,0x38,0x00,0x6c,2048,1536,0x3b4b}, /* 0x33 */
-	{0x0057,0x32,0x40,0x08,0x70, 800, 480,0x3b52}, /* 0x34 */
-	{0x0047,0x33,0x07,0x08,0x70, 800, 480,0x3b57}, /* 0x35 */
-	{0x0047,0x34,0x0a,0x08,0x70, 800, 480,0x3b5c}, /* 0x36 */
-	{0x0057,0x35,0x0b,0x09,0x71,1024, 576,0x3b63}, /* 0x37 */
-	{0x0047,0x36,0x11,0x09,0x71,1024, 576,0x3b68}, /* 0x38 */
-	{0x0047,0x37,0x16,0x09,0x71,1024, 576,0x3b6d}, /* 0x39 */
-	{0x0057,0x38,0x19,0x0a,0x75,1280, 720,0x3b74}, /* 0x3a */
-	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720,0x3b79}, /* 0x3b */
-	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720,0x3b7e}, /* 0x3c */
-	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3d */
-	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960,0x3ad0}, /* 0x3e */
-	{0xc07f,0x01,0x00,0x06,0x5a, 320, 480,0x3b83}, /* 0x3f */    /* FSTN mode */
-        {0x0077,0x42,0x12,0x08,0x23,1280, 768,0x0000}, /* 0x40 */  
-	{0x0067,0x43,0x4d,0x08,0x26,1400,1050,0x0000}, /* 0x41 */  
-	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050,0x0000}, /* 0x42 */    /* TW: new, not in any BIOS */
-	{0x0047,0x44,0x19,0x00,0x29,1152, 864,0x0000}, /* 0x43 TW: Non-BIOS, new */
-	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864,0x0000}, /* 0x44 TW: Non-BIOS, new */
-	{0x00c7,0x45,0x57,0x00,0x39, 848, 480,0x0000}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x46,0x55,0x00,0x39, 848, 480,0x0000}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
-	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
-	{0xc047,0x48,0x57,0x00,0x3f, 856, 480,0x0000}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
-	{0x0047,0x49,0x58,0x00,0x48,1360, 768,0x0000}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
-	{0xffff,0x00,0x00,0x00,0x00,   0,   0,0x0000}
-}; 
+	{0x085f,0x0d,0x03,0x05,0x6a, 800, 600}, /* 0x0 */
+	{0x0467,0x0e,0x04,0x05,0x6a, 800, 600}, /* 0x1 */
+	{0x0067,0x0f,0x08,0x48,0x6a, 800, 600}, /* 0x2 */
+	{0x0067,0x10,0x07,0x8b,0x6a, 800, 600}, /* 0x3 */
+	{0x0147,0x11,0x0a,0x00,0x6a, 800, 600}, /* 0x4 */
+	{0x0147,0x12,0x0d,0x00,0x6a, 800, 600}, /* 0x5 - TW: Test sync change */
+	{0x0047,0x13,0x13,0x00,0x6a, 800, 600}, /* 0x6 */
+	{0x0047,0x14,0x1c,0x00,0x6a, 800, 600}, /* 0x7 */
+	{0xc85f,0x05,0x00,0x04,0x2e, 640, 480}, /* 0x8 */
+	{0xc067,0x06,0x02,0x04,0x2e, 640, 480}, /* 0x9 */
+	{0xc067,0x07,0x02,0x47,0x2e, 640, 480}, /* 0xa */
+	{0xc067,0x08,0x03,0x8a,0x2e, 640, 480}, /* 0xb */
+	{0xc047,0x09,0x05,0x00,0x2e, 640, 480}, /* 0xc */
+	{0xc047,0x0a,0x09,0x00,0x2e, 640, 480}, /* 0xd */
+	{0xc047,0x0b,0x0e,0x00,0x2e, 640, 480}, /* 0xe */
+	{0xc047,0x0c,0x15,0x00,0x2e, 640, 480}, /* 0xf */
+	{0x407f,0x04,0x00,0x00,0x2f, 640, 400}, /* 0x10 */
+	{0xc00f,0x3c,0x01,0x06,0x31, 720, 480}, /* 0x11 */
+	{0x000f,0x3d,0x03,0x06,0x32, 720, 576}, /* 0x12 */
+	{0x0187,0x15,0x06,0x00,0x37,1024, 768}, /* 0x13 */
+	{0xc877,0x16,0x0b,0x06,0x37,1024, 768}, /* 0x14 */
+	{0xc067,0x17,0x0f,0x49,0x37,1024, 768}, /* 0x15 */
+	{0x0267,0x18,0x11,0x00,0x37,1024, 768}, /* 0x16 */
+	{0x0047,0x19,0x16,0x8c,0x37,1024, 768}, /* 0x17 */
+	{0x0047,0x1a,0x1b,0x00,0x37,1024, 768}, /* 0x18 */
+	{0x0007,0x1b,0x1f,0x00,0x37,1024, 768}, /* 0x19 */
+	{0x0387,0x1c,0x11,0x00,0x3a,1280,1024}, /* 0x1a */
+	{0x0077,0x1d,0x19,0x07,0x3a,1280,1024}, /* 0x1b */
+	{0x0047,0x1e,0x1e,0x00,0x3a,1280,1024}, /* 0x1c */
+	{0x0007,0x1f,0x20,0x00,0x3a,1280,1024}, /* 0x1d */
+	{0x0867,0x20,0x21,0x09,0x3c,1600,1200}, /* 0x1e */
+	{0x0007,0x21,0x22,0x00,0x3c,1600,1200}, /* 0x1f */
+	{0x0007,0x22,0x23,0x00,0x3c,1600,1200}, /* 0x20 */
+	{0x0007,0x23,0x25,0x00,0x3c,1600,1200}, /* 0x21 */
+	{0x0007,0x24,0x26,0x00,0x3c,1600,1200}, /* 0x22 */
+	{0x0007,0x25,0x2c,0x00,0x3c,1600,1200}, /* 0x23 */
+	{0x0007,0x26,0x34,0x00,0x3c,1600,1200}, /* 0x24 */
+	{0x407f,0x00,0x00,0x00,0x40, 320, 200}, /* 0x25 */
+	{0xc07f,0x01,0x00,0x04,0x50, 320, 240}, /* 0x26 */
+	{0x007f,0x02,0x04,0x05,0x51, 400, 300}, /* 0x27 */
+	{0xc077,0x03,0x0b,0x06,0x52, 512, 384}, /* 0x28 */
+	{0x8007,0x27,0x27,0x00,0x68,1920,1440}, /* 0x29 */
+	{0x4007,0x28,0x29,0x00,0x68,1920,1440}, /* 0x2a */
+	{0x4007,0x29,0x2e,0x00,0x68,1920,1440}, /* 0x2b */
+	{0x4007,0x2a,0x30,0x00,0x68,1920,1440}, /* 0x2c */
+	{0x4007,0x2b,0x35,0x00,0x68,1920,1440}, /* 0x2d */
+	{0x4005,0x2c,0x39,0x00,0x68,1920,1440}, /* 0x2e */
+	{0x4007,0x2d,0x2b,0x00,0x6c,2048,1536}, /* 0x2f */
+	{0x4007,0x2e,0x31,0x00,0x6c,2048,1536}, /* 0x30 */
+	{0x4007,0x2f,0x33,0x00,0x6c,2048,1536}, /* 0x31 */
+	{0x4007,0x30,0x37,0x00,0x6c,2048,1536}, /* 0x32 */
+	{0x4005,0x31,0x38,0x00,0x6c,2048,1536}, /* 0x33 */
+	{0x0057,0x32,0x40,0x08,0x70, 800, 480}, /* 0x34 */
+	{0x0047,0x33,0x07,0x08,0x70, 800, 480}, /* 0x35 */
+	{0x0047,0x34,0x0a,0x08,0x70, 800, 480}, /* 0x36 */
+	{0x0057,0x35,0x0b,0x09,0x71,1024, 576}, /* 0x37 */
+	{0x0047,0x36,0x11,0x09,0x71,1024, 576}, /* 0x38 */
+	{0x0047,0x37,0x16,0x09,0x71,1024, 576}, /* 0x39 */
+	{0x0057,0x38,0x19,0x0a,0x75,1280, 720}, /* 0x3a */
+	{0x0047,0x39,0x1e,0x0a,0x75,1280, 720}, /* 0x3b */
+	{0x0007,0x3a,0x20,0x0a,0x75,1280, 720}, /* 0x3c */
+	{0x0067,0x3b,0x19,0x08,0x7c,1280, 960}, /* 0x3d */
+	{0x0027,0x4c,0x59,0x08,0x7c,1280, 960}, /* 0x3e */
+	{0xc07f,0x4e,0x00,0x06,0x5a, 320, 240}, /* 0x3f */    /* FSTN 320x240 */
+        {0x0077,0x42,0x5b,0x08,0x23,1280, 768}, /* 0x40 */    /* TW: 0x5b was 0x12 */
+	{0x0067,0x43,0x4d,0x08,0x26,1400,1050}, /* 0x41 */
+	{0x0007,0x4b,0x5a,0x08,0x26,1400,1050}, /* 0x42 TW: not in any BIOS */
+	{0x0047,0x44,0x19,0x00,0x29,1152, 864}, /* 0x43 TW: Non-BIOS, new */
+	{0x0047,0x4a,0x1e,0x00,0x29,1152, 864}, /* 0x44 TW: Non-BIOS, new */
+	{0x00c7,0x45,0x57,0x00,0x39, 848, 480}, /* 0x45 TW: 848x480-38Hzi - Non-BIOS, new */
+	{0xc067,0x46,0x55,0x0b,0x39, 848, 480}, /* 0x46 TW: 848x480-60Hz  - Non-BIOS, new */
+	{0x00c7,0x47,0x57,0x00,0x3f, 856, 480}, /* 0x47 TW: 856x480-38Hzi - Non-BIOS, new */
+	{0xc047,0x48,0x57,0x00,0x3f, 856, 480}, /* 0x48 TW: 856x480-60Hz  - Non-BIOS, new */
+	{0x0067,0x49,0x58,0x0c,0x48,1360, 768}, /* 0x49 TW: 1360x768-60Hz - Non-BIOS, new */
+	{0x000f,0x4d,0x03,0x06,0x5f, 768, 576}, /* 0x4a TW: 768x576 */
+	{0xffff,0x00,0x00,0x00,0x00,   0,   0}
+};
 
 typedef struct _SiS310_CRT1TableStruct
 {
@@ -710,7 +284,7 @@
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
    0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05,
    0x00}}, /* 0x4 */
-#if 0   
+#if 0
  {{0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
    0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05,
    0x00}}, /* 0x5 */
@@ -940,19 +514,25 @@
    0x00}},  /* 0x4b */ 
  {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, /* TW: New, 1280x960-85, not in any BIOS */
    0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07,
-   0x01}}   /* 0x4c */
+   0x01}},  /* 0x4c */
+ {{0x7b,0x5f,0x63,0x9f,0x6a,0x93,0x6f,0xf0, /* 768x576 */
+   0x58,0x8a,0x3f,0x57,0x70,0x20,0x00,0x05,
+   0x01}},  /* 0x4d */
+ {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, /* FSTN 320x480, TEMP - possibly invalid */
+   0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}   /* 0x4e */
 };
 
-
 typedef struct _SiS310_MCLKDataStruct
 {
 	UCHAR SR28,SR29,SR2A;
 	USHORT CLOCK;
 } SiS310_MCLKDataStruct;
 
+#ifdef LINUXBIOS
 static const SiS310_MCLKDataStruct SiS310_MCLKData_0_315[] =
 {
-	{ 0x3b,0x22,0x01,143},   /* TW: Was { 0x5c,0x23,0x01,166}, */
+	{ 0x3b,0x22,0x01,143},
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
@@ -962,7 +542,7 @@
 	{ 0x5c,0x23,0x01,166}
 };
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =	/* @ 0x54 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_650[] =
 {
 	{ 0x5a,0x64,0x82, 66},
 	{ 0xb3,0x45,0x82, 83},
@@ -973,8 +553,22 @@
 	{ 0x37,0x22,0x82,133},
 	{ 0x37,0x22,0x82,133}
 };
+#endif
+
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =
+{
+	{ 0x5c,0x23,0x01,166},
+	{ 0x5c,0x23,0x01,166},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x7c,0x08,0x01,200},
+	{ 0x79,0x06,0x01,250}
+};
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_0_330[] =   /* @ 0x54 */
+#ifdef LINUXBIOS
+static const SiS310_MCLKDataStruct SiS310_MCLKData_0_660[] =  /* TODO */
 {
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166},
@@ -985,8 +579,9 @@
 	{ 0x7c,0x08,0x01,200},
 	{ 0x79,0x06,0x01,250}
 };
+#endif
 
-static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =	/* @ 0x155 */
+static const SiS310_MCLKDataStruct SiS310_MCLKData_1[] =
 {
         { 0x29,0x21,0x82,150},
 	{ 0x5c,0x23,0x82,166},
@@ -998,6 +593,7 @@
 	{ 0x37,0x22,0x82,133}
 };
 
+#ifdef LINUXBIOS
 typedef struct _SiS310_ECLKDataStruct
 {
  	UCHAR SR2E,SR2F,SR30;
@@ -1011,6 +607,7 @@
 	{ 0x5c,0x23,0x01,166},
 	{ 0x5c,0x23,0x01,166}
 };
+#endif
 
 typedef struct _SiS310_VCLKDataStruct
 {
@@ -1020,22 +617,22 @@
 
 static const SiS310_VCLKDataStruct SiS310_VCLKData[]=
 {
-	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x5647 */
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0xe2, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0xe2, 49}, /* 0x7 */
-	{ 0x53,0xe2, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x5a,0x64, 65}, /* 0xb */   /* TW: was 6c c3 - WRONG */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x1b,0xe1, 25}, /* 0x00 */
+	{ 0x4e,0xe4, 28}, /* 0x01 */
+	{ 0x57,0xe4, 31}, /* 0x02 */
+	{ 0xc3,0xc8, 36}, /* 0x03 */
+	{ 0x42,0xe2, 40}, /* 0x04 */
+	{ 0xfe,0xcd, 43}, /* 0x05 */
+	{ 0x5d,0xc4, 44}, /* 0x06 */
+	{ 0x52,0xe2, 49}, /* 0x07 */
+	{ 0x53,0xe2, 50}, /* 0x08 */
+	{ 0x74,0x67, 52}, /* 0x09 */
+	{ 0x6d,0x66, 56}, /* 0x0a */
+	{ 0x5a,0x64, 65}, /* 0x0b */  /* TW: was 6c c3 - WRONG */
+	{ 0x46,0x44, 67}, /* 0x0c */
+	{ 0xb1,0x46, 68}, /* 0x0d */
+	{ 0xd3,0x4a, 72}, /* 0x0e */
+	{ 0x29,0x61, 75}, /* 0x0f */
 	{ 0x6e,0x46, 76}, /* 0x10 */
 	{ 0x2b,0x61, 78}, /* 0x11 */
 	{ 0x31,0x42, 79}, /* 0x12 */
@@ -1045,7 +642,7 @@
 	{ 0x62,0x44, 94}, /* 0x16 */
 	{ 0x2b,0x41,104}, /* 0x17 */
 	{ 0x3a,0x23,105}, /* 0x18 */
-	{ 0x70,0x44,108}, /* 0x19 */
+	{ 0x70,0x44,108}, /* 0x19 */  /* 1400x1050 LCD */
 	{ 0x3c,0x23,109}, /* 0x1a */
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
@@ -1078,12 +675,12 @@
 	{ 0xea,0x08,340}, /* 0x37 */
 	{ 0xe8,0x07,376}, /* 0x38 */
 	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
 	{ 0x31,0xc2, 39}, /* 0x40 */
 	{ 0x60,0x36, 30}, /* 0x41 */  /* Chrontel */
 	{ 0x40,0x4a, 28}, /* 0x42 */  /* Chrontel */
@@ -1096,7 +693,7 @@
 	{ 0xce,0x3c, 39}, /* 0x49 */
 	{ 0x52,0x4a, 36}, /* 0x4a */  /* Chrontel */
 	{ 0x34,0x61, 95}, /* 0x4b */
-	{ 0x78,0x27,108}, /* 0x4c - was 102 */  /* TW: Last entry in 650/301 BIOS */
+	{ 0x78,0x27,108}, /* 0x4c - was 102 */
 	{ 0x66,0x43,123}, /* 0x4d */  /* Modes 0x26-0x28 (1400x1050) */
 	{ 0x41,0x4e, 21}, /* 0x4e */
 	{ 0xa1,0x4a, 29}, /* 0x4f */  /* Chrontel */
@@ -1110,7 +707,8 @@
 	{ 0xbf,0xc8, 35}, /* 0x57 - added for 856x480-38i,60 (not in any BIOS) */
 	{ 0x30,0x23, 88}, /* 0x58 - added for 1360x768-62 (is 60Hz!) (not in any BIOS) */
 	{ 0x52,0x07,149}, /* 0x59 - added for 1280x960-85 (Not in any BIOS) */
-	{ 0x56,0x07,156}  /* 0x5a - added for 1400x1050-75 */
+	{ 0x56,0x07,156}, /* 0x5a - added for 1400x1050-75 */
+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
 };
 
 typedef struct _SiS310_VBVCLKDataStruct
@@ -1121,22 +719,22 @@
 
 static const SiS310_VBVCLKDataStruct SiS310_VBVCLKData[]=
 {
-	{ 0x1b,0xe1, 25}, /* 0x0 */   /* 650/LVDS BIOS: @ 0x579c */
-	{ 0x4e,0xe4, 28}, /* 0x1 */
-	{ 0x57,0xe4, 31}, /* 0x2 */
-	{ 0xc3,0xc8, 36}, /* 0x3 */
-	{ 0x42,0x47, 40}, /* 0x4 */
-	{ 0xfe,0xcd, 43}, /* 0x5 */
-	{ 0x5d,0xc4, 44}, /* 0x6 */
-	{ 0x52,0x47, 49}, /* 0x7 */
-	{ 0x53,0x47, 50}, /* 0x8 */
-	{ 0x74,0x67, 52}, /* 0x9 */
-	{ 0x6d,0x66, 56}, /* 0xa */
-	{ 0x35,0x62, 65}, /* 0xb */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
-	{ 0x46,0x44, 67}, /* 0xc */
-	{ 0xb1,0x46, 68}, /* 0xd */
-	{ 0xd3,0x4a, 72}, /* 0xe */
-	{ 0x29,0x61, 75}, /* 0xf */
+	{ 0x1b,0xe1, 25}, /* 0x00 */
+	{ 0x4e,0xe4, 28}, /* 0x01 */
+	{ 0x57,0xe4, 31}, /* 0x02 */
+	{ 0xc3,0xc8, 36}, /* 0x03 */
+	{ 0x42,0x47, 40}, /* 0x04 */
+	{ 0xfe,0xcd, 43}, /* 0x05 */
+	{ 0x5d,0xc4, 44}, /* 0x06 */
+	{ 0x52,0x47, 49}, /* 0x07 */
+	{ 0x53,0x47, 50}, /* 0x08 */
+	{ 0x74,0x67, 52}, /* 0x09 */
+	{ 0x6d,0x66, 56}, /* 0x0a */
+	{ 0x35,0x62, 65}, /* 0x0b */  /* Was 0x5a,0x64 - 650/LVDS+301 bios: 35,62  */
+	{ 0x46,0x44, 67}, /* 0x0c */
+	{ 0xb1,0x46, 68}, /* 0x0d */
+	{ 0xd3,0x4a, 72}, /* 0x0e */
+	{ 0x29,0x61, 75}, /* 0x0f */
 	{ 0x6d,0x46, 75}, /* 0x10 */
 	{ 0x41,0x43, 78}, /* 0x11 */
 	{ 0x31,0x42, 79}, /* 0x12 */
@@ -1146,7 +744,7 @@
 	{ 0x62,0x44, 94}, /* 0x16 */
 	{ 0x2b,0x22,104}, /* 0x17 */
 	{ 0x49,0x24,105}, /* 0x18 */
-	{ 0xf8,0x2f,108}, /* 0x19 */
+	{ 0xf8,0x2f,108}, /* 0x19 */  /* 1400x1050 LCD */
 	{ 0x3c,0x23,109}, /* 0x1a */
 	{ 0x5e,0x43,113}, /* 0x1b */
 	{ 0xbc,0x44,116}, /* 0x1c */
@@ -1179,19 +777,19 @@
 	{ 0xea,0x08,340}, /* 0x37 */
 	{ 0xe8,0x07,376}, /* 0x38 */
 	{ 0xde,0x06,389}, /* 0x39 */
-	{ 0x52,0x2a, 54}, /* 0x3a */
-	{ 0x52,0x6a, 27}, /* 0x3b */
-	{ 0x62,0x24, 70}, /* 0x3c */
-	{ 0x62,0x64, 70}, /* 0x3d */
-	{ 0xa8,0x4c, 30}, /* 0x3e */
-	{ 0x20,0x26, 33}, /* 0x3f */
+	{ 0x52,0x2a, 54}, /* 0x3a */  /* 301 TV */
+	{ 0x52,0x6a, 27}, /* 0x3b */  /* 301 TV */
+	{ 0x62,0x24, 70}, /* 0x3c */  /* 301 TV */
+	{ 0x62,0x64, 70}, /* 0x3d */  /* 301 TV */
+	{ 0xa8,0x4c, 30}, /* 0x3e */  /* 301 TV */
+	{ 0x20,0x26, 33}, /* 0x3f */  /* 301 TV */
 	{ 0x31,0xc2, 39}, /* 0x40 */
-	{ 0x2e,0x48, 25}, /* 0x41 */
-	{ 0x24,0x46, 25}, /* 0x42 */
-	{ 0x26,0x64, 28}, /* 0x43 */
-	{ 0x37,0x64, 40}, /* 0x44 */
-	{ 0xa1,0x42,108}, /* 0x45 */
-	{ 0x37,0x61,100}, /* 0x46 */
+	{ 0x2e,0x48, 25}, /* 0x41 */  /* Replacement for LCD on 315 for index 0 */
+	{ 0x24,0x46, 25}, /* 0x42 */  /* Replacement for LCD on 315 for modes 0x01, 0x03, 0x0f, 0x10, 0x12 */
+	{ 0x26,0x64, 28}, /* 0x43 */  /* Replacement for LCD on 315 for index 1 */
+	{ 0x37,0x64, 40}, /* 0x44 */  /* Replacement for LCD on 315 for index 4 */
+	{ 0xa1,0x42,108}, /* 0x45 */  /* 1280x960 LCD */
+	{ 0x37,0x61,100}, /* 0x46 */  /* 1280x960 LCD */
 	{ 0x78,0x27,108}, /* 0x47 */
 	{ 0x97,0x2c, 26}, /* 0x48 */  /* UNUSED - Entries from here new, not in any BIOS */
 	{ 0xce,0x3c, 39}, /* 0x49 */  /* UNUSED */
@@ -1211,72 +809,17 @@
 	{ 0xbf,0xc8, 35}, /* 0x57 */  /* 856x480-38i,60  */
 	{ 0x30,0x23, 88}, /* 0x58 */  /* 1360x768-62 (is 60Hz!) TEMP, UNUSED */
 	{ 0x52,0x07,149}, /* 0x59 */  /* 1280x960-85  - UNUSED */
-	{ 0x56,0x07,156}  /* 0x5a */  /* 1400x1050-75 - UNUSED */
+	{ 0x56,0x07,156}, /* 0x5a */  /* 1400x1050-75 - UNUSED */
+   	{ 0x70,0x29, 81}  /* 0x5b */  /* 1280x768 LCD */
 };
 
 static const UCHAR SiS310_ScreenOffset[] = 
 {
         0x14,0x19,0x20,0x28,0x32,0x40,0x50,0x64,
-	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,
+	0x78,0x80,0x2d,0x35,0x57,0x48,0x55,0x30,
 	0xff
-};      /* TW: Added 1400x1050, 1152x864, 848/856x480, 1360x768 */
-
-typedef struct _SiS310_StResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-} SiS310_StResInfoStruct;
-
-static const SiS310_StResInfoStruct SiS310_StResInfo[]=
-{
-	{ 640,400},
-	{ 640,350},
-	{ 720,400},
-	{ 720,350},
-	{ 640,480}
-};
-
-typedef struct _SiS310_ModeResInfoStruct
-{
-	USHORT HTotal;
-	USHORT VTotal;
-	UCHAR  XChar;
-	UCHAR  YChar;
-} SiS310_ModeResInfoStruct;
-
-static const SiS310_ModeResInfoStruct SiS310_ModeResInfo[] =
-{
-	{  320, 200, 8, 8},   /* 0x00 */
-	{  320, 240, 8, 8},   /* 0x01 */
-	{  320, 400, 8, 8},   /* 0x02 */
-	{  400, 300, 8, 8},   /* 0x03 */
-	{  512, 384, 8, 8},   /* 0x04 */
-	{  640, 400, 8,16},   /* 0x05 */
-	{  640, 480, 8,16},   /* 0x06 */
-	{  800, 600, 8,16},   /* 0x07 */
-	{ 1024, 768, 8,16},   /* 0x08 */
-	{ 1280,1024, 8,16},   /* 0x09 */
-	{ 1600,1200, 8,16},   /* 0x0a */
-	{ 1920,1440, 8,16},   /* 0x0b */
-	{ 2048,1536, 8,16},   /* 0x0c */
-	{  720, 480, 8,16},   /* 0x0d */
-	{  720, 576, 8,16},   /* 0x0e */
-	{ 1280, 960, 8,16},   /* 0x0f */
-	{  800, 480, 8,16},   /* 0x10 */
-	{ 1024, 576, 8,16},   /* 0x11 */
-	{ 1280, 720, 8,16},   /* 0x12 */
-	{  856, 480, 8,16},   /* 0x13 - TW: New, not in any BIOS */
-	{ 1280, 768, 8,16},   /* 0x14 20; TW: New */
-	{ 1400,1050, 8,16},   /* 0x15 21; TW: New */
-	{ 1152, 864, 8,16},   /* 0x16 - TW: New, not in any BIOS */
-	{  848, 480, 8,16},   /* 0x17 - TW: New, not in any BIOS */
-	{ 1360, 768, 8,16}    /* 0x18 - TW: New, not in any BIOS */
 };
 
-static const UCHAR SiS310_OutputSelect = 0x40;
-
-static const UCHAR SiS310_SoftSetting  = 0x30;   /* TW: RAM setting */
-
 static const UCHAR SiS310_SR15[8][4]={
 	{0x00,0x04,0x60,0x60},
 	{0x0f,0x0f,0x0f,0x0f},
@@ -1322,16 +865,6 @@
 static const USHORT SiS310_YCSenseData2    = 0x016b;
 #endif
 
-static const UCHAR SiS310_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* TW: Was {0x21,0xed,0x8a,0x08}; */
-static const UCHAR SiS310_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* TW: Was {0x2a,0x05,0xd3,0x00}; */
-static const UCHAR SiS310_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};  /* TW: palm*/
-static const UCHAR SiS310_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};  /* TW: paln*/
-static const UCHAR SiS310_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
-static const UCHAR SiS310_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
-static const UCHAR SiS310_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};  /* TW: palm 301b*/
-static const UCHAR SiS310_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};  /* TW: paln 301b*/
-static const UCHAR SiS310_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
-
 typedef struct _SiS310_LCDDataStruct
 {
 	USHORT RVBHCMAX;
@@ -1353,25 +886,6 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-#if 0   /* Seems out-dated, all BIOSes since 03/27/2002 have the other version */
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] = 
-{
-	{   12,   5, 896, 512,1344, 806},
-	{   12,   5, 896, 510,1344, 806},
-	{   32,  15,1008, 505,1344, 806},
-	{   32,  15,1008, 514,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806},
-	{   12,   5, 896, 500,1344, 806},
-	{   42,  25,1024, 625,1344, 806},
-	{    1,   1,1344, 806,1344, 806}
-};
-#endif
-
 static const SiS310_LCDDataStruct  SiS310_ExtLCD1024x768Data[] =   
 {
 	{   42,  25,1536, 419,1344, 806},
@@ -1413,7 +927,7 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] = 
+static const SiS310_LCDDataStruct  SiS310_ExtLCD1280x1024Data[] =
 {
 	{  211,  60,1024, 501,1688,1066},
 	{  211,  60,1024, 508,1688,1066},
@@ -1450,7 +964,7 @@
 	{    1,   1,1344, 806,1344, 806}
 };
 
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =  
+static const SiS310_LCDDataStruct  SiS310_NoScaleData1280x1024[] =
 {
         {    1,   1,1688,1066,1688,1066},
 	{    1,   1,1688,1066,1688,1066},
@@ -1463,272 +977,15 @@
 	{    1,   1,1688,1066,1688,1066}
 };
 
-static const SiS310_LCDDataStruct  SiS310_LCD1280x960Data[] =
-{
-	{    9,   2, 800, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    4,   1, 900, 500,1800,1000},
-	{    9,   2, 800, 500,1800,1000},
-	{   30,  11,1056, 625,1800,1000},
-	{    5,   3,1350, 800,1800,1000},
-	{    1,   1,1576,1050,1576,1050},
-	{    1,   1,1800,1000,1800,1000}
-};
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1400x1050Data[] = 
-{  /* TW: New from 1.11.6s */
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,   48,  840,  488, 1688, 1066 },
-	{ 211,   72, 1008,  609, 1688, 1066 },
-	{ 211,  128, 1400,  776, 1688, 1066 },
-	{ 211,  205, 1680, 1041, 1688, 1066 },
-	{   1,    1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1400x1050Data[] = 
-{  /* TW: New from 1.11.6s */
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,  100, 2100,  408, 1688, 1066 },
-	{ 211,   64, 1536,  358, 1688, 1066 },
-	{ 211,   48,  840,  488, 1688, 1066 },
-	{ 211,   72, 1008,  609, 1688, 1066 },
-	{ 211,  128, 1400,  776, 1688, 1066 },
-	{ 211,  205, 1680, 1041, 1688, 1066 },
-	{   1,    1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1400x1050[] = 
-{  /* TW: To be checked (BIOS uses 1280x1024 data, one line too short) */
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 },
-	{ 1, 1, 1688, 1066, 1688, 1066 }
-};
-
-static const SiS310_LCDDataStruct  SiS310_StLCD1600x1200Data[] = 
-{  /* TODO */
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS310_LCDDataStruct  SiS310_ExtLCD1600x1200Data[] = 
-{  /* TODO */
-	{    0,   0,   0,   0,   0,   0}
-};
-
-static const SiS310_LCDDataStruct  SiS310_NoScaleData1600x1200[] = 
-{  /* TODO */
-	{    0,   0,   0,   0,   0,   0}
-};
-
-typedef struct _SiS310_TVDataStruct
-{
-	USHORT RVBHCMAX;
-	USHORT RVBHCFACT;
-	USHORT VGAHT;
-	USHORT VGAVT;
-	USHORT TVHDE;
-	USHORT TVVDE;
-	USHORT RVBHRS;
-	UCHAR FlickerMode;
-	USHORT HALFRVBHRS;
-	UCHAR RY1COE;
-	UCHAR RY2COE;
-	UCHAR RY3COE;
-	UCHAR RY4COE;
-} SiS310_TVDataStruct;
-
-static const SiS310_TVDataStruct  SiS310_StPALData[]=
-{
- {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
- {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtPALData[] =   
-{
- {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
- {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
- {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
- {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480 */
- {   36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600 */
- {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x480/576 */
- {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
-};
-
-static const SiS310_TVDataStruct  SiS310_StNTSCData[]=
-{
- {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtNTSCData[]=
-{
- {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
- {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
- {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},  /* 640x480 */
- {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},  /* 800x600  */
- {    2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},  /* 720x480/576 */
- {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08}   /* 1024x768 */
-};
-
-#if 0
-static const SiS310_TVDataStruct  SiS310_St1HiTVData[]=
-{
-  
-};
-#endif
-
-static const SiS310_TVDataStruct  SiS310_St2HiTVData[]=
-{
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const SiS310_TVDataStruct  SiS310_ExtHiTVData[]=
-{
- {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},
- {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},
- {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},
- {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
- {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}
-};
-
-static const UCHAR SiS310_NTSCTiming[] = { 
-	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
-};
-
-static const UCHAR SiS310_PALTiming[] = {  
-	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
-	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
-	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
-};
-
-static const UCHAR SiS310_HiTVExtTiming[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS310_HiTVSt1Timing[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
-	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
-	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
-	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
-};
-
-static const UCHAR SiS310_HiTVSt2Timing[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
-	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
-	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
-	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
-	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
-};
-
-static const UCHAR SiS310_HiTVTextTiming[] = {  
-        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
-	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
-	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
-	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
-	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
-        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
-	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
-};
-
-static const UCHAR SiS310_HiTVGroup3Data[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
-	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
-	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS310_HiTVGroup3Simu[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
-	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
-
-static const UCHAR SiS310_HiTVGroup3Text[] = {  
-        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
-	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
-	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
-	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
-	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
-	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
-	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
-	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
-};
 
 typedef struct _SiS310_PanelDelayTblStruct
 {
  	UCHAR timer[2];
 } SiS310_PanelDelayTblStruct;
 
-static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=  
+static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTbl[]=
 {
-        {{0x10,0x40}},		/* TW: from 650/301LVx 1.10.6s BIOS */
+        {{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}},
@@ -1744,24 +1001,6 @@
 	{{0x10,0x40}},
 	{{0x10,0x40}},
 	{{0x10,0x40}}
-#if 0
-	{{0x28,0xc8}},		/* TW: from 650/301LV BIOS */
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}},
-	{{0x28,0xc8}}
-#endif
 };
 
 static const SiS310_PanelDelayTblStruct SiS310_PanelDelayTblLVDS[]=
@@ -1792,363 +1031,7 @@
 	USHORT LCDVT;
 } SiS310_LVDSDataStruct;
 
-static const SiS310_LVDSDataStruct  SiS310_LVDS320x480Data_1[]=
-{
-	{ 848, 433, 400, 525},
-	{ 848, 389, 400, 525},
-	{ 848, 433, 400, 525},
-	{ 848, 389, 400, 525},
-	{ 848, 518, 400, 525},
-	{1056, 628, 400, 525},
-	{ 400, 525, 400, 525},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_1[]= 
-{
-	{ 848, 433,1060, 629},
-	{ 848, 389,1060, 629},
-	{ 848, 433,1060, 629},
-	{ 848, 389,1060, 629},
-	{ 848, 518,1060, 629},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS800x600Data_2[]=  
-{
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{ 800, 449,1000, 644},
-	{ 800, 525,1000, 635}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_1[]=  
-{
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 518,1344, 806},   /* 640x480 */
-	{1050, 638,1344, 806},   /* 800x600 */
-	{1344, 806,1344, 806},   /* 1024x768 */
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x768Data_2[]= 
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_1[]=  
-{	
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 442,1688,1066},
-	{1048, 392,1688,1066},
-	{1048, 522,1688,1066},
-	{1208, 642,1688,1066},
-	{1432, 810,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x1024Data_2[]=  
-{	
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066},
-	{1688,1066,1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_1[]=  
-{
-        { 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{ 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{ 928, 496, 1688,1066},
-	{1088, 616, 1688,1066},
-	{1312, 784, 1688,1066},
-	{1568,1040, 1688,1066},
-	{1688,1066, 1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1400x1050Data_2[]= 
-{
-        {1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-	{1688,1066, 1688,1066},
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_1[]=  
-{
-        {1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 450, 2048,1250},
-	{1088, 400, 2048,1250},
-	{1088, 530, 2048,1250},
-	{1248, 650, 2048,1250},
-	{1472, 818, 2048,1250},
-	{1728,1066, 2048,1250},
-	{1848,1066, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1600x1200Data_2[]= 
-{
-        {2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250},
-	{2048,1250, 2048,1250}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_1[]= 
-{	
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 438, 1408, 806},
-	{ 768, 388, 1408, 806},
-	{ 768, 518, 1408, 806},
-	{ 928, 638, 1408, 806},
-	{1152, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x768Data_2[]=  
-{	
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806},
-	{1408, 806, 1408, 806}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_1[]=
-{
-	{ 840, 604, 1344, 800},
-	{ 840, 560, 1344, 800},
-	{ 840, 604, 1344, 800},
-	{ 840, 560, 1344, 800},
-	{ 840, 689, 1344, 800},
-	{1050, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1024x600Data_2[]=
-{
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{1344, 800, 1344, 800},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_1[]=
-{
-	{ 840, 438, 1344, 806},
-	{ 840, 409, 1344, 806},
-	{ 840, 438, 1344, 806},
-	{ 840, 409, 1344, 806},
-	{ 840, 518, 1344, 806},
-	{1050, 638, 1344, 806},
-	{1344, 806, 1344, 806},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1152x768Data_2[]=
-{
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{1344, 806, 1344, 806},
-	{ 800, 449, 1280, 801},
-	{ 800, 525, 1280, 813}
-};
-
-/* TW: Pass 1:1 data */
-static const SiS310_LVDSDataStruct  SiS310_LVDSXXXxXXXData_1[]=  
-{
-        { 800, 449,  800, 449},
-	{ 800, 449,  800, 449},
-	{ 900, 449,  900, 449},
-	{ 900, 449,  900, 449},
-	{ 800, 525,  800, 525},  /*  640x480   */
-	{1056, 628, 1056, 628},  /*  800x600   */
-	{1344, 806, 1344, 806},  /* 1024x768   */
-	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
- 	{1688, 806, 1688, 806},  /* 1280x768 ! */
-	/* No other panels ! */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS640x480Data_1[]=  
-{
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 449, 800, 449},
-	{ 800, 525, 800, 525},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628},
-	{1056, 628,1056, 628}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_1[]=   
-{
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 438,1344, 806},
-	{ 840, 409,1344, 806},
-	{ 840, 518,1344, 806},
-	{1050, 638,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LVDS1280x960Data_2[]=  
-{
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-/* LCDA */
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_1[]=   
-{	/* TW: Might be temporary (invalid) data */
-        { 928, 416, 1688,1066},
-	{ 928, 366, 1688,1066},
-	{1008, 416, 1688,1066},
-	{1008, 366, 1688,1066},
-	{1200, 530, 1688,1066},
-	{1088, 616, 1688,1066},
-	{1312, 784, 1688,1066},
-	{1568,1040, 1688,1066},
-	{1688,1066, 1688,1066}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1400x1050Data_2[]=   
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_1[]=  
-{	/* TW: Temporary data. Not valid */
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{1344, 806,1344, 806},
-	{ 800, 449,1280, 801},
-	{ 800, 525,1280, 813}
-};
-
-static const SiS310_LVDSDataStruct  SiS310_LCDA1600x1200Data_2[]=  
-{	/* TW: Temporary data. Not valid */
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0},
-	{0, 0, 0, 0}
-};
-
-/* Chrontel TV */
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVUNTSCData[]=   
-{
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 840, 600, 840, 600},
-	{ 784, 600, 784, 600},
-	{1064, 750,1064, 750},
-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVONTSCData[]=   
-{
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 840, 525, 840, 525},
-	{ 784, 525, 784, 525},
-	{1040, 700,1040, 700},
-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
-};
-
-static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=   
+static const SiS310_LVDSDataStruct  SiS310_CHTVUPALData[]=
 {
 	{1008, 625,1008, 625},
 	{1008, 625,1008, 625},
@@ -2156,7 +1039,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
+	{1400,1000,1400,1000}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALData[]= 
@@ -2167,7 +1050,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
+        {1400, 875,1400, 875}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVUPALMData[]=  
@@ -2178,7 +1061,7 @@
 	{ 840, 600, 840, 600},
 	{ 784, 600, 784, 600},
 	{1064, 750,1064, 750},
-        {1160, 945,1160, 945}           /* TW: For Ch7019 1024 */
+        {1160, 945,1160, 945}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALMData[]=  
@@ -2189,7 +1072,7 @@
 	{ 840, 525, 840, 525},
 	{ 784, 525, 784, 525},
 	{1040, 700,1040, 700},
-        {1160, 840,1160, 840}          	/* TW: For Ch7019 1024 */
+        {1160, 840,1160, 840}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVUPALNData[]=  
@@ -2200,7 +1083,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 960, 750, 960, 750},
-	{1400,1000,1400,1000}   	/*  TW: For Ch7019 1024 */
+	{1400,1000,1400,1000}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVOPALNData[]= 
@@ -2211,7 +1094,7 @@
 	{1008, 625,1008, 625},
 	{ 840, 625, 840, 625},
 	{ 944, 625, 944, 625},
-        {1400, 875,1400, 875}       	/*  TW: For Ch7019 1024 */
+        {1400, 875,1400, 875}
 };
 
 static const SiS310_LVDSDataStruct  SiS310_CHTVSOPALData[]=   /* TW: (super overscan - no effect on 7019) */
@@ -2231,7 +1114,7 @@
 	USHORT LCDVDES;
 } SiS310_LVDSDesStruct;
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType00_1[]=  /* 800x600 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2244,7 +1127,7 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=   
+static const SiS310_LVDSDesStruct  SiS310_PanelType01_1[]=  /* 1024x768 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2257,7 +1140,7 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType02_1[]=  /* 1280x1024 */
 {
 	{ 0, 0},
 	{ 0, 0},
@@ -2382,33 +1265,31 @@
 	{ 0, 0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]= 
-{
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_1[]=  /* 640x480_2 */
 {
-	{1343, 798},
-	{1343, 794},
-	{1343, 798},
-	{1343, 794},
-	{1343,   0},
-	{1343,   0},
-	{ 0, 805},
-	{ 0, 794},
-	{ 0,   0}
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
+};
+
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_1[]=  /* 640x480_3 */
+{
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 0, 524},
+	{ 8, 524},
+	{ 0, 524}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]= 
+static const SiS310_LVDSDesStruct  SiS310_PanelType0d_1[]=
 {
 	{1343, 798},
 	{1343, 794},
@@ -2604,7 +1485,7 @@
 	{   0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  
+static const SiS310_LVDSDesStruct  SiS310_PanelType0b_2[]=  /* 640x480_2 */
 {
 	{1152, 622},
 	{1152, 597},
@@ -2617,7 +1498,7 @@
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]= 
+static const SiS310_LVDSDesStruct  SiS310_PanelType0c_2[]=  /* 640x480_3 */
 {
 	{1152, 622},
 	{1152, 597},
@@ -2669,184 +1550,6 @@
 	{ 0,   0}
 };
 
-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_1[]= 
-{
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 8,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0, 806},
-	{ 0, 0 }
-};
-
-static const SiS310_LVDSDesStruct  SiS310_PanelTypeNS_2[] = 
-{
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1076_1[]=  
-{  /* 1024x768 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1076_2[]=  
-{  /* 1024x768 - Checked (1.10.6s) */
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1184, 622 },
-	{ 1184, 597 },
-	{ 1152, 622 },
-	{ 1232, 722 },
-	{    0, 0   },
-	{    0, 794 },
-	{    0, 0   }
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1210_1[]=  
-{  /* 1280x1024 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1210_2[]=  
-{  /* 1280x1024 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1296_1[]=  
-{  /* 1400x1050 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1296_2[]=  
-{  /* 1400x1050 - Checked (1.10.6s) - looks heavily invalid */
-	{ 808 , 740},
-	{ 0   , 715},
-	{ 632 , 740},
-	{ 632 , 715},
-	{ 1307, 780},
-	{ 1387,1157},
-	{ 1499, 924},
-	{ 1627,1052},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1600_1[]= 
-{  /* 1600x1200 - Checked (1.10.6s) */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct SiS310_PanelType1600_2[]= 
-{  /* 1600x1200 - Checked (1.10.6s) - looks heavily invalid, not copied */
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0},
-	{ 0 , 0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVUNTSCDesData[]=
-{
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVONTSCDesData[]=
-{
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVUPALDesData[]=
-{
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
-static const SiS310_LVDSDesStruct  SiS310_CHTVOPALDesData[]=
-{
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{256,   0},
-	{ 0,   0},
-	{ 0,   0},
-	{ 0,   0}
-};
-
 typedef struct _SiS310_Part2PortTblStruct
 {
  	UCHAR CR[12];
@@ -2865,45 +1568,6 @@
  {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
-{	/* TW: Temporary data, invalid */
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
- {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
-};
-
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_2[] =
 {
  {{0x25,0x12,0x51,0x6e,0x48,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
@@ -2912,11 +1576,50 @@
  {{0x2c,0x12,0x38,0x55,0x2f,0xc1,0x35,0xb1,0x47,0xe9,0x71,0x33}},
  {{0x2d,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xc1,0x49,0x33}},
  {{0x29,0x12,0xb5,0xd2,0xac,0xe9,0x35,0xd9,0x47,0x11,0x99,0x33}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},  /* others  */
+/* 0x36,0x13,0x02,0x25,0xff,0x03,0x45,0x09,0x07,0xf9,0x00,0x24        my      */
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
+{
+#if 1   /* Data from 650/301LVx 1.10.6s and others */
+ {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
+#endif
+#if 0    /* Data from my 301LV */
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},   /* TEST */
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}},
+ {{0x36,0x13,0x02,0x25,0xff,0x21,0x45,0x09,0x07,0x88,0x09,0x24}}
+#endif
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_1[] =
+{	/* TW: BIOS data invalid, last row taken from _3 */
+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
+ {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+ {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
+ {{0x36,0x13,0x02,0x25,0xFF,0x03,0x45,0x09,0x07,0xF9,0x00,0x24}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+};
+
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_2[] =
 {
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
@@ -2930,21 +1633,34 @@
  {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
+/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
 {
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x33,0x13,0x01,0x0d,0xfd,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
- {{0x3f,0x1b,0x3d,0x49,0x39,0x54,0x23,0xc0,0x27,0x66,0x30,0x42}},
- {{0x33,0x1b,0x91,0x9d,0x8d,0x8c,0x23,0xf8,0x27,0x9e,0x68,0x42}},
- {{0x43,0x24,0x11,0x1d,0x0d,0xcc,0x23,0x38,0x37,0xde,0xa8,0x42}},
+ {{0x31,0x1B,0xC4,0xDA,0xB0,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x34,0x1B,0x9F,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x3E,0x1B,0xCF,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+};
+
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_1[] =
+{
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
-{	/* TW: Temporary data, invalid */
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_2[] =
+{
  {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
  {{0x22,0x12,0xc0,0xcc,0xbc,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
  {{0x2b,0x12,0xd9,0xe5,0xd5,0x2c,0x23,0x98,0x27,0x3e,0x08,0x42}},
@@ -2956,68 +1672,59 @@
  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}}
 };
 
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
+{
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
+ {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+};
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1024x768_3[] =
-{	/* TW: Data from 650/301LVx 1.10.6s */
- {{0x25,0x13,0xc9,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x13,0x9a,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x13,0xc9,0x24,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x25,0x13,0xc9,0x25,0xff,0xf9,0x45,0x09,0x07,0xf9,0x09,0x24}}
-#if 0	/* TW: Data from 650/301LV */
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x2c,0x12,0x9a,0xae,0x88,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x25,0x12,0xc9,0xdc,0xb6,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
- {{0x38,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x36,0x13,0x13,0x25,0xff,0x59,0x45,0x09,0x07,0xf9,0x09,0x24}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}
-#endif
-};
-
-/*   1     2    4    5    6   1c   1d   1f   20   21   23   25   */
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1280x1024_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_1[] =
+{
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
 };
 
-static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1400x1050_3[] =
-{	
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_2[] =
+{
+ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x32,0x1B,0x2C,0x52,0x20,0x80,0x20,0x52,0x30,0xA3,0x3A,0x02}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x3A,0x1B,0x54,0x7A,0x48,0x80,0x24,0x52,0x30,0xA3,0x3A,0x02}},
+ {{0x36,0x1B,0x90,0xB6,0x84,0xA8,0x24,0x7A,0x30,0xCB,0x62,0x02}},
+ {{0x3A,0x1C,0xE4,0x0A,0xD8,0xE0,0x24,0xB2,0x30,0x03,0x9A,0x02}},
+ {{0x4A,0x24,0x64,0x8A,0x58,0x20,0x34,0xF2,0x30,0x43,0xDA,0x52}},
+ {{0x47,0x24,0x71,0x97,0x65,0x3E,0x34,0x10,0x40,0x61,0xF8,0x02}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
 };
 
 static const SiS310_Part2PortTblStruct SiS310_CRT2Part2_1600x1200_3[] =
-{	/* TW: Temporary data, invalid */
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x42}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}},
-  {{0x43,0x24,0x21,0x29,0x19,0xea,0x23,0x0a,0x07,0x32,0xc6,0x32}}
+{
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}},
+ {{0x4C,0x24,0xC8,0xE1,0xAF,0x70,0x34,0x0A,0x07,0xFC,0x2A,0x53}}
 };
 
 typedef struct _SiS310_LCDACRT1DataStruct
@@ -3025,36 +1732,30 @@
  	UCHAR CR[17];
 }SiS310_LCDACRT1DataStruct;
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1[] =
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
 {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x82,0x1f,
+   0x60,0x87,0x5d,0x5d,0x83,0x10,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x4f,0x4f,0x97,0x59,0x84,0x04,0x3e,
+   0xE2,0x89,0xdf,0xdf,0x05,0x00,0x00,0x05,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1[]=
-{  /* TW: Checked (1.10.6s) */
+ {{0x87,0x63,0x63,0x8B,0x6D,0x18,0x7c,0xf0,
+   0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x06,
+   0x01}},
+ {{0xA3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
+   0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+#if 0
  {{0x73,0x4f,0x4f,0x97,0x55,0x86,0xc4,0x1f,
    0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
@@ -3076,160 +1777,213 @@
  {{0xA3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
    0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x02,
    0x01}}
+#endif
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
-{  /* Checked (1.10.6s) */
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
+{
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
    0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
-   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0xb4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x05,
    0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
-   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x82,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x10,0x00,0x05,
    0x00}},
- {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
-   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
+ {{0x4b,0x27,0x27,0x8f,0x31,0x1c,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x05,
    0x00}},
- {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
-   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
+ {{0x55,0x31,0x31,0x99,0x3b,0x06,0x7c,0xf0,
+   0x5A,0x81,0x57,0x57,0x7D,0x00,0x00,0x01,
    0x01}},
- {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
-   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
-   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
+ {{0x63,0x3F,0x3F,0x87,0x49,0x94,0x24,0xF5,
+   0x02,0x89,0xFF,0xFF,0x25,0x10,0x00,0x01,
    0x01}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
-{    /* Checked (1.10.6s) */
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+#if 0
+{{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
    0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
    0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
-   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
+   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
    0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
-   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+ {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
+   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
    0x00}},
- {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
-   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+ {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
+   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
    0x00}},
- {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
-   0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
-   0x01}},
- {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
-   0x01}},
- {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
-   0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
+ {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
+   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
    0x01}},
- {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
-   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
-   0x00}}
+ {{0x63,0x3F,0x3F,0x87,0x4A,0x93,0x24,0xF5,
+   0x02,0x88,0xFF,0xFF,0x25,0x10,0x00,0x01,
+   0x01}}
+#endif
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1[]=
-{   /* MISSING */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
+{
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xbb,
+   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x06,
+   0x01}},
+ {{0xa3,0x4f,0x4f,0x0f,0x6e,0x1f,0x24,0xb3,
+   0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x06,
+   0x01}},
+ {{0xa3,0x63,0x63,0x98,0x78,0x19,0x24,0xf1,
+   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x89,0x94,0x24,0xf5,
+   0x02,0x89,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+#if 0
+{{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
+ {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
+   0x01}}
+#endif
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_1_H[]=
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
 {
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
+   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
+   0x4a,0x81,0x8f,0xdb,0xda,0x20,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xbb,
+   0x31,0x88,0x5d,0xc2,0xc1,0x20,0x00,0x01,
+   0x00 }},
+ {{0x7b,0x27,0x27,0x0f,0x46,0x97,0x24,0xb3,
+   0x72,0x89,0xdf,0x03,0x02,0x30,0x00,0x01,
+   0x01 }},
+ {{0x71,0x31,0x31,0x98,0x46,0x17,0x24,0xf1,
+   0xbb,0x82,0x57,0x57,0x25,0x10,0x00,0x02,
+   0x01 }},
+ {{0x63,0x3f,0x3f,0x87,0x4c,0x97,0x24,0xf5,
+   0x0f,0x86,0xff,0xff,0x25,0x30,0x00,0x01,
+   0x01 }}
+#if 0
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01,   /* <-- invalid data */
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x31,0x93,0x3e,0x06,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,  /* <-- invalid data */
+   0x01 }},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+#endif
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1[]=
+{
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x06,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_1_H[]=
-{  /* TW: Checked (1.10.6s) */
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+ {{0x92,0x63,0x63,0x96,0x6c,0x1a,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
+   0x01}},
+ {{0xae,0x7f,0x7f,0x92,0x88,0x96,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x9f,0x92,0xa8,0x16,0x28,0x5a,
+   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
+   0x01}}
+#if 0
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0xc4,0x1f,
-   0x92,0x89,0x8f,0x8f,0xb5,0x30,0x00,0x44,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0xb8,0x1f,
+   0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x06,
    0x00}},
- {{0x4b,0x27,0x27,0x8f,0x2b,0x03,0x97,0x1f,
-   0x60,0x87,0x5D,0x5D,0x83,0x01,0x00,0x44,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x86,0x1f,
+   0x5e,0x82,0x5d,0x5d,0x87,0x10,0x00,0x06,
    0x00}},
- {{0x4b,0x27,0x27,0x8f,0x32,0x1b,0x04,0x3e,
-   0xE2,0x89,0xDf,0xDf,0x05,0x00,0x00,0x45,
+ {{0x7e,0x4f,0x4f,0x82,0x58,0x04,0x08,0x3e,
+   0xe0,0x84,0xdf,0xdf,0x09,0x00,0x00,0x06,
    0x00}},
- {{0x55,0x31,0x31,0x99,0x46,0x1d,0x7c,0xf0,
-   0x5A,0x8F,0x57,0x57,0x7D,0x20,0x00,0x55,
+ {{0x92,0x63,0x63,0x96,0x6c,0x18,0x80,0xf0,
+   0x58,0x8c,0x57,0x57,0x81,0x20,0x00,0x06,
+   0x01}},
+ {{0xae,0x7f,0x7f,0x92,0x88,0x94,0x28,0xf5,
+   0x00,0x84,0xff,0xff,0x29,0x10,0x00,0x02,
    0x01}},
- {{0x63,0x3F,0x3F,0x87,0x4a,0x93,0x24,0xf5,
-   0x02,0x88,0xFf,0xFf,0x25,0x10,0x00,0x01,
+ {{0xce,0x9f,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0xff,0x29,0x01,0x00,0x07,
    0x01}}
+#endif
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_1_H[]=
-{   /* Checked (1.10.6s) */
+{
  {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
    0x90,0x84,0x8f,0x8f,0xb9,0x30,0x00,0x05,
    0x00}},
- {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,    /* <-- Invalid data - one byte missing in BIOS */
+ {{0x3c,0x4f,0x4f,0x82,0x58,0x06,0x86,0xd1,
    0xbc,0x80,0xbb,0xbb,0xe5,0x00,0x00,0x06,
    0x01}},
  {{0x56,0x27,0x27,0x9a,0x30,0x1e,0xb8,0x1f,
@@ -3249,101 +2003,8 @@
    0x01}}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
-{   /* Checked (1.10.6s) */
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-    0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
-    0x00}},
-  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-    0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
-    0x00}},
-  {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
-    0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
-    0x01}},
-  {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-    0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
-    0x01}},
-  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-    0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
-    0x01}},
-  {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
-    0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
-    0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1_H[]=
-{   /* MISSING */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2[]=
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2[]=
-{   /* Checked (1.10.6s) */
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
+{  /* Illegal data in BIOS */
  {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
    0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
    0x00}},
@@ -3367,33 +2028,95 @@
    0x01}}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2[]=
-{   /* Checked (1.10.6s) */
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
+{  /* Illegal data in BIOS */
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
+   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
+   0x00 }},
+ {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
+   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
+   0x01 }},
+ {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
+   0x01 }}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1[]=
+{
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
    0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x06,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
+   0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
    0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x06,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x6c,0x1f,
+   0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
    0x00}},
- {{0xa3,0x4f,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x06,
+ {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0xee,0x1f,
+   0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
    0x00}},
- {{0xa3,0x63,0x63,0x87,0x78,0x89,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x02,
+ {{0x83,0x63,0x63,0x87,0x68,0x16,0x66,0xf0,
+   0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x06,
    0x01}},
- {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02,
-   0x01}}
+ {{0x9f,0x7f,0x7f,0x83,0x84,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x02,
+   0x01}},
+ {{0xbf,0x9f,0x9f,0x83,0xa4,0x12,0x0e,0x5a,
+   0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0xae,0xae,0x92,0xb3,0x01,0x28,0x10,
+   0x1a,0x80,0x19,0x19,0x29,0x0f,0x00,0x03,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_1_H[]=
+{
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+    0x93,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+    0x92,0x86,0x8f,0x8f,0x9f,0x30,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+    0x60,0x84,0x5d,0x5d,0x6d,0x10,0x00,0x05,
+    0x00}},
+  {{0x47,0x27,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+    0xe2,0x86,0xdf,0xdf,0xef,0x10,0x00,0x05,
+    0x00}},
+  {{0x51,0x31,0x31,0x95,0x36,0x04,0x66,0xf0,
+    0x5a,0x8e,0x57,0x57,0x67,0x20,0x00,0x01,
+    0x01}},
+  {{0x5f,0x3f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+    0x02,0x86,0xff,0xff,0x0f,0x10,0x00,0x01,
+    0x01}},
+  {{0x6f,0x4f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+    0x02,0x86,0xff,0xff,0x0f,0x09,0x00,0x05,
+    0x01}},
+  {{0x76,0x56,0x56,0x9a,0x5b,0x89,0x28,0x10,
+    0x1c,0x80,0x19,0x19,0x29,0x0b,0x00,0x05,
+    0x00}}
 };
 
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2[]=
-{    /* Checked (1.10.6s) */
+{
  {{0xce,0x4f,0x4f,0x92,0x8c,0x1a,0x28,0x9a,
    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x03,
    0x00}},
@@ -3423,120 +2146,8 @@
    0x00}}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2[]=
-{    /* MISSING */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT1800x600_2_H[]=
-{
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11024x768_2_H[]=
-{   /* Checked (1.10.6s) */
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x8d,0x5d,0x25,0x30,0x00,0x01,   /* <-- invalid data */
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x01,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x31,0x31,0x93,0x3e,0x06,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,  /* <-- invalid data */
-   0x01 }},
- {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-   0x01 }}
-};
-
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11280x1024_2_H[]=
-{   /* Checked (1.10.6s) */
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x4a,0x80,0x8f,0x8f,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x31,0x87,0x5d,0x5d,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x27,0x27,0x93,0x39,0x81,0x24,0xbb,
-   0x72,0x88,0xdf,0xdf,0x25,0x30,0x00,0x01,
-   0x00 }},
- {{0x4f,0x31,0x31,0x93,0x3e,0x86,0x24,0xf1,
-   0xae,0x84,0x57,0x57,0x25,0x30,0x00,0x01,
-   0x01 }},
- {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-   0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01,
-   0x01 }}
-};
-
 static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11400x1050_2_H[]=
-{  /* Checked (1.10.6s) */
+{
  {{0xa6,0x27,0x27,0x8a,0x64,0x92,0x28,0x9a,
    0xdb,0x8f,0x8f,0x8f,0x29,0x21,0x00,0x06,
    0x00}},
@@ -3566,71 +2177,148 @@
    0x00}}
 };
 
-static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2_H[]=
-{  /* MISSING */
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1[]=
+{
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
+   0x00}},
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x8F,0x10,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x83,0x4F,0x4F,0x87,0x51,0x09,0x10,0x3E,
+   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x06,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x97,0x63,0x63,0x9B,0x65,0x1D,0x88,0xF0,
+   0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x06,
+   0x01}},
+ {{0xB3,0x7F,0x7F,0x97,0x81,0x99,0x30,0xF5,
+   0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x02,
+   0x01}},
+ {{0xD3,0x9F,0x9F,0x97,0xA1,0x19,0x30,0x5A,
+   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x07,
+   0x01}},
+ {{0xE2,0xAE,0xAE,0x86,0xB0,0x88,0x4A,0x10,
+   0x1A,0x8E,0x19,0x19,0x4B,0x2F,0x00,0x03,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0xFB,0xC7,0xC7,0x9F,0xC9,0x81,0xE0,0x10,
+   0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x07,
+   0x00}}
+};
+
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_1_H[]=
+{
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0xC0,0x1F,
+   0x90,0x84,0x8F,0x8F,0xC1,0x30,0x00,0x01,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x8E,0x1F,
+   0x5E,0x82,0x5D,0x5D,0x87,0x10,0x00,0x01,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x69,0x27,0x27,0x8D,0x30,0x88,0x10,0x3E,
+   0xE0,0x84,0xDF,0xDF,0x11,0x00,0x00,0x01,
    0x00}},
- {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ {{0x73,0x31,0x31,0x97,0x3A,0x92,0x88,0xF0,
+   0x58,0x8C,0x57,0x57,0x89,0x20,0x00,0x01,
+   0x01}},
+ {{0x81,0x3F,0x3F,0x85,0x48,0x00,0x30,0xF5,
+   0x00,0x84,0xFF,0xFF,0x31,0x10,0x00,0x06,
+   0x01}},
+ {{0x91,0x4F,0x4F,0x95,0x58,0x10,0x30,0x5A,
+   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x06,
+   0x01}},
+ {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
+   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
+   0x01}},
+ {{0xA5,0x63,0x63,0x89,0x6C,0x84,0xE0,0x10,
+   0xB0,0x84,0xAF,0xAF,0xE1,0x2F,0x00,0x02,
    0x00}}
 };
 
-typedef struct _SiS310_LVDSCRT1DataStruct
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2[]=
 {
- 	UCHAR CR[15];
-} SiS310_LVDSCRT1DataStruct;
+ {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
+   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
+   0x00}},
+ {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
+   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
+   0x00}},
+ {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
+   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x01,0x04,
+   0x00}},
+ {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
+   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x01,0x04,
+   0x00}},
+ {{0x09,0x4F,0x4F,0x8D,0xA3,0x1B,0xE0,0x9E,
+   0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x01,0x04,
+   0x00}},
+ {{0x09,0x63,0x63,0x8D,0xAD,0x05,0xE0,0xD4,
+   0x9B,0x8F,0x57,0x57,0xE1,0x21,0x01,0x00,
+   0x01}},
+ {{0x09,0x7F,0x7F,0x8D,0xBB,0x13,0xE0,0xD4,
+   0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x01,0x00,
+   0x01}},
+ {{0x09,0x9F,0x9F,0x8D,0xCB,0x03,0xE0,0x5A,
+   0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x01,0x04,
+   0x01}},
+ {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
+   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
+   0x01}},
+ {{0x09,0xC7,0xC7,0x8D,0xDF,0x17,0xE0,0x10,
+   0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x01,0x04,
+   0x00}}
+};
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1320x480_1[] =
+static const SiS310_LCDACRT1DataStruct  SiS310_LCDACRT11600x1200_2_H[]=
 {
- {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
-   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
-   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
-   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
-   0x00 }},
- {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
-   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
-   0x00 }},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01 }},
- {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00 }}
+ {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
+   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
+   0x00}},
+ {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
+   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
+   0x00}},
+ {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
+   0x37,0x8B,0x8F,0x8F,0xE1,0x21,0x00,0x03,
+   0x00}},
+ {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
+   0x1E,0x82,0x5D,0x5D,0xE1,0x01,0x00,0x03,
+   0x00}},
+ {{0xE1,0x27,0x27,0x85,0x7B,0x93,0xE0,0x9E,
+   0x5F,0x83,0xDF,0xDF,0xE1,0x01,0x00,0x03,
+   0x00}},
+ {{0xD7,0x31,0x31,0x9B,0x7B,0x13,0xE0,0xD4,
+   0x9B,0x8F,0x57,0x57,0xE1,0x21,0x00,0x03,
+   0x01}},
+ {{0xC9,0x3F,0x3F,0x8D,0x7B,0x13,0xE0,0xD4,
+   0xEF,0x83,0xFF,0xFF,0xE1,0x21,0x00,0x03,
+   0x01}},
+ {{0xB9,0x4F,0x4F,0x9D,0x7B,0x93,0xE0,0x5A,
+   0x6F,0x83,0xFF,0xFF,0xE1,0x29,0x00,0x02,
+   0x01}},
+ {{0xD4,0x9F,0x9F,0x98,0xA8,0x00,0x30,0x5A,
+   0x00,0x84,0xFF,0xFF,0x31,0x09,0x00,0x03,
+   0x01}},
+ {{0xA5,0x63,0x63,0x89,0x7B,0x93,0xE0,0x10,
+   0xC7,0x8B,0xAF,0xAF,0xE1,0x0F,0x00,0x02,
+   0x00}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =   
+typedef struct _SiS310_LVDSCRT1DataStruct
+{
+ 	UCHAR CR[15];
+} SiS310_LVDSCRT1DataStruct;
+
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1800x600_1[] =
 {
  {{0x6b,0x4f,0x8f,0x55,0x85,0xaa,0x1f,
    0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
@@ -3924,63 +2612,7 @@
    0x01}}
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1[] =  
-{
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
-   0x00}},
- {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
-   0x00}},
- {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
-   0x01}},
- {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
-   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
-   0x01}},
- {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT1XXXxXXX_1_H[] = 
-{
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
-   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
-   0x00}},
- {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
-   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
-   0x00}},
- {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
-   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
-   0x01}},
- {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
-   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =  
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11400x1050_1[] =
 {
   {{0x6f,0x4f,0x93,0x54,0x82,0x9e,0x1f,
     0x8f,0x81,0x8f,0x9f,0x30,0x00,0x05,
@@ -4220,332 +2852,8 @@
 #endif   
 };
 
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1[] =  
-{	
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
-   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
-   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
-   0x00}},
- {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
-   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
-   0x00}},
- {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
-   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
-   0x01}},
- {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
-   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_1_H[] = 
-{
- {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
-   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
-   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
-   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
-   0x00}},
- {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
-   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
-   0x00}},
- {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
-   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
-   0x01}},
- {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
-   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}},
- {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
-   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2[] = 
-{
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
-   0x00}},
- {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
-   0x01}},
- {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11280x768_2_H[] =
-{
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
-   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
-   0x00}},
- {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
-   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
-   0x01}},
- {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
-   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
-   0x01}},
- {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}},
- {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
-   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
-   0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1[] =
+static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =
 {
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
-	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
-	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
-	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
-	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-          0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11024x600_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1[] =
-{
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
-	  0x00}},
-        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
-	  0x00}},
-        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_1_H[] =
-{
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
-	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
-	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
-	  0x00}},
-        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
-	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
-	  0x00}},
-        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
-	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2[] =
-{
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
-	  0x00}},
-        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
-	  0x01}},
-        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11152x768_2_H[] =
-{
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
-	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
-	  0x00}},
-        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
-	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
-	  0x01}},
-        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
-	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
-	  0x01}}
-};
-
-static const SiS310_LVDSCRT1DataStruct  SiS310_LVDSCRT11600x1200_1[] =  
-{    
  {{0x83,0x4f,0x87,0x51,0x09,0xc0,0x1f,
    0x90,0x84,0x8f,0xc1,0x30,0x00,0x06,
    0x00}},
@@ -4701,7 +3009,7 @@
 	{{0x80,0x63,0x84,0x6d,0x0f,0xec,0xf0,
 	  0x7a,0x8f,0x57,0xed,0x20,0x00,0x06,
 	  0x01 }},
-	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,  /* TW: 1024x768 */
+	{{0x8c,0x7f,0x90,0x86,0x09,0xaf,0xf5,
 	  0x36,0x88,0xff,0xb0,0x10,0x00,0x02,
 	  0x01}}
 };
@@ -4726,7 +3034,7 @@
 	{{0x7d,0x63,0x81,0x68,0x0e,0xba,0xf0,
 	  0x78,0x8a,0x57,0xbb,0x20,0x00,0x06,
 	  0x01 }},
-	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,   /* TW: 1024x768 */
+	{{0x8c,0x7f,0x90,0x82,0x06,0x46,0xf5,
 	  0x15,0x88,0xff,0x47,0x70,0x00,0x02,
 	  0x01 }}
 };
@@ -4751,7 +3059,7 @@
 	{{0x73,0x63,0x97,0x69,0x8b,0xec,0xf0,
 	  0x90,0x8c,0x57,0xed,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,   /* TW: 1024x768 */
+	{{0xaa,0x7f,0x8e,0x8e,0x96,0xe6,0xf5,
 	  0x50,0x88,0xff,0xe7,0x10,0x00,0x02,
 	  0x01}}
 };
@@ -4776,7 +3084,7 @@
 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
 	  0x01 }}
 };
@@ -4801,12 +3109,11 @@
 	{{0x71,0x63,0x95,0x69,0x8c,0x6f,0xf0,
 	  0x5a,0x8b,0x57,0x70,0x20,0x00,0x05,
 	  0x01 }},
-	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,   /* TW:  1024x768 */
+	{{0xaa,0x7f,0x8e,0x8f,0x96,0x69,0xf5,
 	  0x28,0x88,0xff,0x6a,0x10,0x00,0x02,
 	  0x01 }}
 };
 
-/* TW: Data for Chrontel 7019  */
 typedef struct _SiS310_CHTVRegDataStruct
 {
  	UCHAR Reg[16];
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/init.c fbdev-2.6/drivers/video/sis/init.c
--- linus-2.6/drivers/video/sis/init.c	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/init.c	Thu Oct 16 14:13:41 2003
@@ -1,24 +1,18 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init.c,v 1.3 2002/24/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT1 section) for SiS 300/540/630/730/315/550/650/740/330
+ * Mode initializing code (CRT1 section) for
+ * for SiS 300/305/540/630/730 and
+ *     SiS 315/550/650/M650/651/661FX/M661FX/740/741/330/660/M660/760/M760
  * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
  * Assembler-To-C translation
- * Copyright 2002 by Thomas Winischhofer <thomas@winischhofer.net>
- * Minor parts Copyright SiS, Inc.
+ * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
+ * Formerly based on non-functional code-fragements by SiS, Inc.
  *
- * Based on BIOS
- *     1.10.07, 1.10a for 650/CH7019
- *     1.11.21a for 740/CH7019
- *     1.11.05 for 650/LVDS (w/o Chrontel)
- *     1.07.1b, 1.11.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV)
- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
- *     2.06.50 for 630/301B (dual VGA)
- *     2.02.3b, 2.03.02, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
- *     1.09b for 315/301(B)
- *     1.16.51 for 300+301LV (ECS A907)
- *     1.01.03 for 330 (Xabre 400)
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -58,98 +52,200 @@
 #include "310vtbl.h"
 #endif
 
-#ifdef LINUX_XF86
-BOOLEAN SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
-DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn);
-#ifdef SISDUALHEAD /* TW: For dual head */
-BOOLEAN SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode, BOOLEAN IsCustom);
-BOOLEAN SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                       ScrnInfoPtr pScrn, DisplayModePtr mode);
-#endif /* dual head */
-#endif /* linux_xf86 */
-
-#ifdef LINUXBIOS
-BOOLEAN SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
-
-#ifdef LINUX_XF86
-BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                   ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
-#else
-BOOLEAN SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                   USHORT ModeNo);
-#endif
-
 #if defined(ALLOC_PRAGMA)
 #pragma alloc_text(PAGE,SiSSetMode)
 #pragma alloc_text(PAGE,SiSInit)
 #endif
 
-static ULONG GetDRAMSize(SiS_Private *SiS_Pr,
-                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
-
-static void DelaySeconds(int seconds);
-void SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code);
+/*********************************************/
+/*         POINTER INITIALIZATION            */
+/*********************************************/
 
 static void
-DelaySeconds(int seconds)
-{
-  int i;
-#ifdef WIN2000
-  int j;
-#endif
-
-  for (i=0;i<seconds;i++) {
-#ifdef TC
-    delay(1000);
-#endif
-
-#ifdef WIN2000
-    for (j=0;j<20000;j++)
-      VideoPortStallExecution(50);
-#endif
-
-#ifdef WINCE_HEADER
-#endif
-
-#ifdef LINUX_KERNEL
-#endif
-  }
-}
-
-void
-SiS_DebugCode(SiS_Private *SiS_Pr, UCHAR code)
+InitCommonPointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  OutPortByte(0x80, code);
-  DelaySeconds(0x3);
+   SiS_Pr->SiS_StResInfo     = SiS_StResInfo;
+   SiS_Pr->SiS_ModeResInfo   = SiS_ModeResInfo;
+   SiS_Pr->SiS_StandTable    = SiS_StandTable;
+
+   SiS_Pr->SiS_NTSCPhase    = SiS_NTSCPhase;
+   SiS_Pr->SiS_PALPhase     = SiS_PALPhase;
+   SiS_Pr->SiS_NTSCPhase2   = SiS_NTSCPhase2;
+   SiS_Pr->SiS_PALPhase2    = SiS_PALPhase2;
+   SiS_Pr->SiS_PALMPhase    = SiS_PALMPhase;
+   SiS_Pr->SiS_PALNPhase    = SiS_PALNPhase;
+   SiS_Pr->SiS_PALMPhase2   = SiS_PALMPhase2;
+   SiS_Pr->SiS_PALNPhase2   = SiS_PALNPhase2;
+   SiS_Pr->SiS_SpecialPhase = SiS_SpecialPhase;
+
+   SiS_Pr->SiS_NTSCTiming     = SiS_NTSCTiming;
+   SiS_Pr->SiS_PALTiming      = SiS_PALTiming;
+   SiS_Pr->SiS_HiTVSt1Timing  = SiS_HiTVSt1Timing;
+   SiS_Pr->SiS_HiTVSt2Timing  = SiS_HiTVSt2Timing;
+   SiS_Pr->SiS_HiTVTextTiming = SiS_HiTVTextTiming;
+   SiS_Pr->SiS_HiTVExtTiming  = SiS_HiTVExtTiming;
+   SiS_Pr->SiS_HiTVGroup3Data = SiS_HiTVGroup3Data;
+   SiS_Pr->SiS_HiTVGroup3Simu = SiS_HiTVGroup3Simu;
+   SiS_Pr->SiS_HiTVGroup3Text = SiS_HiTVGroup3Text;
+
+   SiS_Pr->SiS_StPALData   = SiS_StPALData;
+   SiS_Pr->SiS_ExtPALData  = SiS_ExtPALData;
+   SiS_Pr->SiS_StNTSCData  = SiS_StNTSCData;
+   SiS_Pr->SiS_ExtNTSCData = SiS_ExtNTSCData;
+/* SiS_Pr->SiS_St1HiTVData = SiS_St1HiTVData;  */
+   SiS_Pr->SiS_St2HiTVData = SiS_St2HiTVData;
+   SiS_Pr->SiS_ExtHiTVData = SiS_ExtHiTVData;
+
+   SiS_Pr->pSiS_OutputSelect = &SiS_OutputSelect;
+   SiS_Pr->pSiS_SoftSetting  = &SiS_SoftSetting;
+
+   SiS_Pr->SiS_LCD1280x960Data      = SiS_LCD1280x960Data;
+   SiS_Pr->SiS_ExtLCD1400x1050Data  = SiS_ExtLCD1400x1050Data;
+   SiS_Pr->SiS_ExtLCD1600x1200Data  = SiS_ExtLCD1600x1200Data;
+   SiS_Pr->SiS_StLCD1400x1050Data   = SiS_StLCD1400x1050Data;
+   SiS_Pr->SiS_StLCD1600x1200Data   = SiS_StLCD1600x1200Data;
+   SiS_Pr->SiS_NoScaleData1400x1050 = SiS_NoScaleData1400x1050;
+   SiS_Pr->SiS_NoScaleData1600x1200 = SiS_NoScaleData1600x1200;
+   SiS_Pr->SiS_ExtLCD1280x768Data   = SiS_ExtLCD1280x768Data;
+   SiS_Pr->SiS_StLCD1280x768Data    = SiS_StLCD1280x768Data;
+   SiS_Pr->SiS_NoScaleData1280x768  = SiS_NoScaleData1280x768;
+   SiS_Pr->SiS_NoScaleData          = SiS_NoScaleData;
+
+   SiS_Pr->SiS_LVDS320x480Data_1   = SiS_LVDS320x480Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_1   = SiS_LVDS800x600Data_1;
+   SiS_Pr->SiS_LVDS800x600Data_2   = SiS_LVDS800x600Data_2;
+   SiS_Pr->SiS_LVDS1024x768Data_1  = SiS_LVDS1024x768Data_1;
+   SiS_Pr->SiS_LVDS1024x768Data_2  = SiS_LVDS1024x768Data_2;
+   SiS_Pr->SiS_LVDS1280x1024Data_1 = SiS_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x1024Data_2 = SiS_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS1400x1050Data_1 = SiS_LVDS1400x1050Data_1;
+   SiS_Pr->SiS_LVDS1400x1050Data_2 = SiS_LVDS1400x1050Data_2;
+   SiS_Pr->SiS_LVDS1600x1200Data_1 = SiS_LVDS1600x1200Data_1;
+   SiS_Pr->SiS_LVDS1600x1200Data_2 = SiS_LVDS1600x1200Data_2;
+   SiS_Pr->SiS_LVDS1280x768Data_1  = SiS_LVDS1280x768Data_1;
+   SiS_Pr->SiS_LVDS1280x768Data_2  = SiS_LVDS1280x768Data_2;
+   SiS_Pr->SiS_LVDS1024x600Data_1  = SiS_LVDS1024x600Data_1;
+   SiS_Pr->SiS_LVDS1024x600Data_2  = SiS_LVDS1024x600Data_2;
+   SiS_Pr->SiS_LVDS1152x768Data_1  = SiS_LVDS1152x768Data_1;
+   SiS_Pr->SiS_LVDS1152x768Data_2  = SiS_LVDS1152x768Data_2;
+   SiS_Pr->SiS_LVDSXXXxXXXData_1   = SiS_LVDSXXXxXXXData_1;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x960Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x960Data_2;
+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_1  = SiS_LVDS1280x1024Data_1;
+   SiS_Pr->SiS_LVDS1280x960Data_2  = SiS_LVDS1280x1024Data_2;
+   SiS_Pr->SiS_LVDS640x480Data_1   = SiS_LVDS640x480Data_1;
+   SiS_Pr->SiS_LVDS640x480Data_2   = SiS_LVDS640x480Data_2;
+
+   SiS_Pr->SiS_LVDSBARCO1366Data_1 = SiS_LVDSBARCO1366Data_1;
+   SiS_Pr->SiS_LVDSBARCO1366Data_2 = SiS_LVDSBARCO1366Data_2;
+   SiS_Pr->SiS_LVDSBARCO1024Data_1 = SiS_LVDSBARCO1024Data_1;
+   SiS_Pr->SiS_LVDSBARCO1024Data_2 = SiS_LVDSBARCO1024Data_2;
+   SiS_Pr->SiS_LVDS848x480Data_1   = SiS_LVDS848x480Data_1;
+   SiS_Pr->SiS_LVDS848x480Data_2   = SiS_LVDS848x480Data_2;
+
+   SiS_Pr->SiS_CHTVUNTSCData = SiS_CHTVUNTSCData;
+   SiS_Pr->SiS_CHTVONTSCData = SiS_CHTVONTSCData;
+
+   SiS_Pr->SiS_LCDA1024x768Data_1  = SiS_LCDA1024x768Data_1;
+   SiS_Pr->SiS_LCDA1024x768Data_2  = SiS_LCDA1024x768Data_2;
+   SiS_Pr->SiS_LCDA1280x1024Data_1 = SiS_LCDA1280x1024Data_1;
+   SiS_Pr->SiS_LCDA1280x1024Data_2 = SiS_LCDA1280x1024Data_2;
+   SiS_Pr->SiS_LCDA1400x1050Data_1 = SiS_LCDA1400x1050Data_1;
+   SiS_Pr->SiS_LCDA1400x1050Data_2 = SiS_LCDA1400x1050Data_2;
+   SiS_Pr->SiS_LCDA1600x1200Data_1 = SiS_LCDA1600x1200Data_1;
+   SiS_Pr->SiS_LCDA1600x1200Data_2 = SiS_LCDA1600x1200Data_2;
+
+   SiS_Pr->LVDS1024x768Des_1  = SiS_PanelType1076_1;
+   SiS_Pr->LVDS1280x1024Des_1 = SiS_PanelType1210_1;
+   SiS_Pr->LVDS1400x1050Des_1 = SiS_PanelType1296_1;
+   SiS_Pr->LVDS1600x1200Des_1 = SiS_PanelType1600_1;
+   SiS_Pr->LVDS1024x768Des_2  = SiS_PanelType1076_2;
+   SiS_Pr->LVDS1280x1024Des_2 = SiS_PanelType1210_2;
+   SiS_Pr->LVDS1400x1050Des_2 = SiS_PanelType1296_2;
+   SiS_Pr->LVDS1600x1200Des_2 = SiS_PanelType1600_2;
+
+   SiS_Pr->SiS_PanelTypeNS_1 = SiS_PanelTypeNS_1;
+   SiS_Pr->SiS_PanelTypeNS_2 = SiS_PanelTypeNS_2;
+
+   SiS_Pr->SiS_CHTVUNTSCDesData = SiS_CHTVUNTSCDesData;
+   SiS_Pr->SiS_CHTVONTSCDesData = SiS_CHTVONTSCDesData;
+   SiS_Pr->SiS_CHTVUPALDesData  = SiS_CHTVUPALDesData;
+   SiS_Pr->SiS_CHTVOPALDesData  = SiS_CHTVOPALDesData;
+
+   SiS_Pr->SiS_LVDSCRT11280x768_1    = SiS_LVDSCRT11280x768_1;
+   SiS_Pr->SiS_LVDSCRT11024x600_1    = SiS_LVDSCRT11024x600_1;
+   SiS_Pr->SiS_LVDSCRT11152x768_1    = SiS_LVDSCRT11152x768_1;
+   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = SiS_LVDSCRT11280x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = SiS_LVDSCRT11024x600_1_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = SiS_LVDSCRT11152x768_1_H;
+   SiS_Pr->SiS_LVDSCRT11280x768_2    = SiS_LVDSCRT11280x768_2;
+   SiS_Pr->SiS_LVDSCRT11024x600_2    = SiS_LVDSCRT11024x600_2;
+   SiS_Pr->SiS_LVDSCRT11152x768_2    = SiS_LVDSCRT11152x768_2;
+   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = SiS_LVDSCRT11280x768_2_H;
+   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = SiS_LVDSCRT11024x600_2_H;
+   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = SiS_LVDSCRT11152x768_2_H;
+   SiS_Pr->SiS_LVDSCRT1320x480_1     = SiS_LVDSCRT1320x480_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = SiS_LVDSCRT1XXXxXXX_1;
+   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = SiS_LVDSCRT1XXXxXXX_1_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_1     = SiS_LVDSCRT1640x480_1;
+   SiS_Pr->SiS_LVDSCRT1640x480_1_H   = SiS_LVDSCRT1640x480_1_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_2     = SiS_LVDSCRT1640x480_2;
+   SiS_Pr->SiS_LVDSCRT1640x480_2_H   = SiS_LVDSCRT1640x480_2_H;
+   SiS_Pr->SiS_LVDSCRT1640x480_3     = SiS_LVDSCRT1640x480_3;
+   SiS_Pr->SiS_LVDSCRT1640x480_3_H   = SiS_LVDSCRT1640x480_3_H;
 }
 
 #ifdef SIS300
 static void
-InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+InitTo300Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+   InitCommonPointer(SiS_Pr, HwInfo);
+
+   SiS_StandTable[0x04].CRTC[4] = 0x2b;
+   SiS_StandTable[0x05].CRTC[4] = 0x2b;
+   SiS_StandTable[0x06].CRTC[4] = 0x54;
+   SiS_StandTable[0x06].CRTC[5] = 0x80;
+   SiS_StandTable[0x0d].CRTC[4] = 0x2b;
+   SiS_StandTable[0x0e].CRTC[4] = 0x54;
+   SiS_StandTable[0x0e].CRTC[5] = 0x80;
+   SiS_StandTable[0x11].CRTC[4] = 0x54;
+   SiS_StandTable[0x11].CRTC[5] = 0x80;
+   SiS_StandTable[0x11].CRTC[16] = 0x83;
+   SiS_StandTable[0x11].CRTC[17] = 0x85;
+   SiS_StandTable[0x12].CRTC[4] = 0x54;
+   SiS_StandTable[0x12].CRTC[5] = 0x80;
+   SiS_StandTable[0x12].CRTC[16] = 0x83;
+   SiS_StandTable[0x12].CRTC[17] = 0x85;
+   SiS_StandTable[0x13].CRTC[5] = 0xa0;
+   SiS_StandTable[0x17].CRTC[5] = 0xa0;
+   SiS_StandTable[0x1a].CRTC[4] = 0x54;
+   SiS_StandTable[0x1a].CRTC[5] = 0x80;
+   SiS_StandTable[0x1a].CRTC[16] = 0xea;
+   SiS_StandTable[0x1a].CRTC[17] = 0x8c;
+   SiS_StandTable[0x1b].CRTC[4] = 0x54;
+   SiS_StandTable[0x1b].CRTC[5] = 0x80;
+   SiS_StandTable[0x1b].CRTC[16] = 0xea;
+   SiS_StandTable[0x1b].CRTC[17] = 0x8c;
+   SiS_StandTable[0x1c].CRTC[4] = 0x54;
+   SiS_StandTable[0x1c].CRTC[5] = 0x80;
+
    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS300_SModeIDTable;
    SiS_Pr->SiS_VBModeIDTable = (SiS_VBModeStruct *)SiS300_VBModeIDTable;
-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS300_StandTable;
    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS300_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS300_RefIndex;
    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS300_CRT1Table;
-   if(HwDeviceExtension->jChipType == SIS_300) {
+   if(HwInfo->jChipType == SIS_300) {
       SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_300; /* 300 */
    } else {
       SiS_Pr->SiS_MCLKData_0    = (SiS_MCLKDataStruct *)SiS300_MCLKData_630; /* 630, 730 */
    }
+#ifdef LINUXBIOS
    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS300_ECLKData;
+#endif
    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS300_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS300_VCLKData;
    SiS_Pr->SiS_ScreenOffset  = SiS300_ScreenOffset;
-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS300_StResInfo;
-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS300_ModeResInfo;
-
-   SiS_Pr->pSiS_OutputSelect = &SiS300_OutputSelect;
-   SiS_Pr->pSiS_SoftSetting  = &SiS300_SoftSetting;
 
    SiS_Pr->SiS_SR15  = SiS300_SR15;
 
@@ -178,15 +274,6 @@
    SiS_Pr->pSiS_YCSenseData2    = &SiS300_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_NTSCPhase  = SiS300_NTSCPhase;
-   SiS_Pr->SiS_PALPhase   = SiS300_PALPhase;
-   SiS_Pr->SiS_NTSCPhase2 = SiS300_NTSCPhase2;
-   SiS_Pr->SiS_PALPhase2  = SiS300_PALPhase2;
-   SiS_Pr->SiS_PALMPhase  = SiS300_PALMPhase;
-   SiS_Pr->SiS_PALNPhase  = SiS300_PALNPhase;
-   SiS_Pr->SiS_PALMPhase2 = SiS300_PALMPhase2;
-   SiS_Pr->SiS_PALNPhase2 = SiS300_PALNPhase2;
-
    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS300_StLCD1024x768Data;
    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_ExtLCD1024x768Data;
    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS300_St2LCD1024x768Data;
@@ -195,68 +282,18 @@
    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS300_St2LCD1280x1024Data;
    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS300_NoScaleData1024x768;
    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS300_NoScaleData1280x1024;
-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS300_LCD1280x960Data;
-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1400x1050Data;
-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS300_ExtLCD1600x1200Data;
-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS300_StLCD1400x1050Data;
-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS300_StLCD1600x1200Data;
-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS300_NoScaleData1400x1050;
-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS300_NoScaleData1600x1200;
-
-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS300_StPALData;
-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS300_ExtPALData;
-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS300_StNTSCData;
-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS300_ExtNTSCData;
-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS300_St1HiTVData;  */
-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS300_St2HiTVData;
-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS300_ExtHiTVData;
-
-   SiS_Pr->SiS_NTSCTiming     = SiS300_NTSCTiming;
-   SiS_Pr->SiS_PALTiming      = SiS300_PALTiming;
-   SiS_Pr->SiS_HiTVSt1Timing  = SiS300_HiTVSt1Timing;
-   SiS_Pr->SiS_HiTVSt2Timing  = SiS300_HiTVSt2Timing;
-   SiS_Pr->SiS_HiTVTextTiming = SiS300_HiTVTextTiming;
-   SiS_Pr->SiS_HiTVGroup3Data = SiS300_HiTVGroup3Data;
-   SiS_Pr->SiS_HiTVGroup3Simu = SiS300_HiTVGroup3Simu;
-   SiS_Pr->SiS_HiTVGroup3Text = SiS300_HiTVGroup3Text;
 
    SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS300_PanelDelayTblLVDS;
 
-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_1;
-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS300_LVDS800x600Data_2;
-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_1;
-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x768Data_2;
-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_1;
-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1400x1050Data_2;
-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_1;
-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LVDS1600x1200Data_2;
-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_1;
-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1280x768Data_2;
-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_1;
-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1024x600Data_2;
-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_1;
-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS300_LVDS1152x768Data_2;
-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS300_LVDSXXXxXXXData_1;
-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS320x480Data_1;
-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS300_LVDS640x480Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1400x1050Data_2;
-   SiS_Pr->SiS_LCDA1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_1;
-   SiS_Pr->SiS_LCDA1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS300_LCDA1600x1200Data_2;
-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData;
    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;
-   SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVUNTSCData; /* not supported on 300 series */
-   SiS_Pr->SiS_CHTVOPALMData = (SiS_LVDSDataStruct *)SiS300_CHTVONTSCData; /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVUPALMData = SiS_CHTVUNTSCData; 			   /* not supported on 300 series */
+   SiS_Pr->SiS_CHTVOPALMData = SiS_CHTVONTSCData; 			   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVUPALData;  /* not supported on 300 series */
    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS300_CHTVOPALData;  /* not supported on 300 series */
    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS300_CHTVSOPALData;
+
    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS300_PanelType00_1;
    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS300_PanelType01_1;
    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS300_PanelType02_1;
@@ -289,32 +326,28 @@
    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0d_2;
    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0e_2;
    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS300_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS300_PanelTypeNS_2;
-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS300_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS300_CHTVOPALDesData;
+
+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1a;
+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2a;
+   }
+   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+      SiS_Pr->SiS_PanelType04_1 = (SiS_LVDSDesStruct *)SiS300_PanelType04_1b;
+      SiS_Pr->SiS_PanelType04_2 = (SiS_LVDSDesStruct *)SiS300_PanelType04_2b;
+   }
+
    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1;
    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1;
    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1;
-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1;
-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1;
    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_1_H;
    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_1_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_1_H;
    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2;
    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2;
    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2;
-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2;
-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2;
    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT1800x600_2_H;
    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x768_2_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11280x1024_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11024x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS300_LVDSCRT11152x768_2_H;
    SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UNTSC;
    SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1ONTSC;
    SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS300_CHTVCRT1UPAL;
@@ -339,7 +372,6 @@
    SiS_Pr->SiS_CHTVVCLKOPALN = SiS300_CHTVVCLKOPAL;   /* not supported on 300 series */
    SiS_Pr->SiS_CHTVVCLKSOPAL = SiS300_CHTVVCLKSOPAL;
 
-   /* TW: New from 300/301LV BIOS */
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1024x768_1;
    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1280x1024_1;
    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_1;
@@ -353,7 +385,7 @@
    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1400x1050_3;
    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS300_CRT2Part2_1600x1200_3;
 
-   /* TW: LCDResInfo will on 300 series be translated to 310/325 series definitions */
+   /* LCDResInfo will on 300 series be translated to 315 series definitions */
    SiS_Pr->SiS_Panel320x480   = Panel_320x480;
    SiS_Pr->SiS_Panel640x480   = Panel_640x480;
    SiS_Pr->SiS_Panel800x600   = Panel_800x600;
@@ -362,43 +394,79 @@
    SiS_Pr->SiS_Panel1280x960  = Panel_1280x960;
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
    SiS_Pr->SiS_Panel1152x768  = Panel_1152x768;
-   SiS_Pr->SiS_Panel1600x1200 = 16;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1400x1050 = 16;  		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1152x864  = 16;   		/* TW: Something illegal */
-   SiS_Pr->SiS_Panel1280x768  = 16;   		/* TW: Something illegal */
-   SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* TW: highest value */
-   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* TW: Lowest value LVDS */
-   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* TW: lowest value 301 */
+   SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
+   SiS_Pr->SiS_Panel1600x1200 = 255;  		   /* Something illegal */
+   SiS_Pr->SiS_Panel1400x1050 = 255;
+   SiS_Pr->SiS_Panel640x480_2 = 255;
+   SiS_Pr->SiS_Panel640x480_3 = 255;
+   SiS_Pr->SiS_Panel1152x864  = 255;
+   SiS_Pr->SiS_PanelMax       = Panel_320x480;     /* highest value */
+   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;     /* Lowest value LVDS */
+   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;    /* lowest value 301 */
+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
+   SiS_Pr->SiS_PanelBarco1366 = Panel_Barco1366;
 }
 #endif
 
 #ifdef SIS315H
 static void
-InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+InitTo310Pointer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+   InitCommonPointer(SiS_Pr, HwInfo);
+
+   SiS_StandTable[0x04].CRTC[4] = 0x2c;
+   SiS_StandTable[0x05].CRTC[4] = 0x2c;
+   SiS_StandTable[0x06].CRTC[4] = 0x55;
+   SiS_StandTable[0x06].CRTC[5] = 0x81;
+   SiS_StandTable[0x0d].CRTC[4] = 0x2c;
+   SiS_StandTable[0x0e].CRTC[4] = 0x55;
+   SiS_StandTable[0x0e].CRTC[5] = 0x81;
+   SiS_StandTable[0x11].CRTC[4] = 0x55;
+   SiS_StandTable[0x11].CRTC[5] = 0x81;
+   SiS_StandTable[0x11].CRTC[16] = 0x82;
+   SiS_StandTable[0x11].CRTC[17] = 0x84;
+   SiS_StandTable[0x12].CRTC[4] = 0x55;
+   SiS_StandTable[0x12].CRTC[5] = 0x81;
+   SiS_StandTable[0x12].CRTC[16] = 0x82;
+   SiS_StandTable[0x12].CRTC[17] = 0x84;
+   SiS_StandTable[0x13].CRTC[5] = 0xb1;
+   SiS_StandTable[0x17].CRTC[5] = 0xb1;
+   SiS_StandTable[0x1a].CRTC[4] = 0x55;
+   SiS_StandTable[0x1a].CRTC[5] = 0x81;
+   SiS_StandTable[0x1a].CRTC[16] = 0xe9;
+   SiS_StandTable[0x1a].CRTC[17] = 0x8b;
+   SiS_StandTable[0x1b].CRTC[4] = 0x55;
+   SiS_StandTable[0x1b].CRTC[5] = 0x81;
+   SiS_StandTable[0x1b].CRTC[16] = 0xe9;
+   SiS_StandTable[0x1b].CRTC[17] = 0x8b;
+   SiS_StandTable[0x1c].CRTC[4] = 0x55;
+   SiS_StandTable[0x1c].CRTC[5] = 0x81;
+
    SiS_Pr->SiS_SModeIDTable  = (SiS_StStruct *)SiS310_SModeIDTable;
-   SiS_Pr->SiS_StandTable    = (SiS_StandTableStruct *)SiS310_StandTable;
    SiS_Pr->SiS_EModeIDTable  = (SiS_ExtStruct *)SiS310_EModeIDTable;
    SiS_Pr->SiS_RefIndex      = (SiS_Ext2Struct *)SiS310_RefIndex;
    SiS_Pr->SiS_CRT1Table     = (SiS_CRT1TableStruct *)SiS310_CRT1Table;
    /* TW: MCLK is different */
-   if(HwDeviceExtension->jChipType == SIS_330) {
+#ifdef LINUXBIOS
+   if(HwInfo->jChipType >= SIS_660) {
+      SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_660;  /* 660/760 */
+   } else if(HwInfo->jChipType == SIS_330) {
+#endif
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_330;  /* 330 */
-   } else if(HwDeviceExtension->jChipType > SIS_315PRO) {
+#ifdef LINUXBIOS
+   } else if(HwInfo->jChipType > SIS_315PRO) {
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_650;  /* 550, 650, 740 */
    } else {
       SiS_Pr->SiS_MCLKData_0 = (SiS_MCLKDataStruct *)SiS310_MCLKData_0_315;  /* 315 */
    }
+#endif
    SiS_Pr->SiS_MCLKData_1    = (SiS_MCLKDataStruct *)SiS310_MCLKData_1;
+#ifdef LINUXBIOS
    SiS_Pr->SiS_ECLKData      = (SiS_ECLKDataStruct *)SiS310_ECLKData;
+#endif
    SiS_Pr->SiS_VCLKData      = (SiS_VCLKDataStruct *)SiS310_VCLKData;
    SiS_Pr->SiS_VBVCLKData    = (SiS_VBVCLKDataStruct *)SiS310_VBVCLKData;
    SiS_Pr->SiS_ScreenOffset  = SiS310_ScreenOffset;
-   SiS_Pr->SiS_StResInfo     = (SiS_StResInfoStruct *)SiS310_StResInfo;
-   SiS_Pr->SiS_ModeResInfo   = (SiS_ModeResInfoStruct *)SiS310_ModeResInfo;
-
-   SiS_Pr->pSiS_OutputSelect = &SiS310_OutputSelect;
-   SiS_Pr->pSiS_SoftSetting  = &SiS310_SoftSetting;
 
    SiS_Pr->SiS_SR15  = SiS310_SR15;
 
@@ -427,16 +495,6 @@
    SiS_Pr->pSiS_YCSenseData2    = &SiS310_YCSenseData2;
 #endif
 
-   SiS_Pr->SiS_NTSCPhase    = SiS310_NTSCPhase;
-   SiS_Pr->SiS_PALPhase     = SiS310_PALPhase;
-   SiS_Pr->SiS_NTSCPhase2   = SiS310_NTSCPhase2;
-   SiS_Pr->SiS_PALPhase2    = SiS310_PALPhase2;
-   SiS_Pr->SiS_PALMPhase    = SiS310_PALMPhase;
-   SiS_Pr->SiS_PALNPhase    = SiS310_PALNPhase;
-   SiS_Pr->SiS_PALMPhase2   = SiS310_PALMPhase2;
-   SiS_Pr->SiS_PALNPhase2   = SiS310_PALNPhase2;
-   SiS_Pr->SiS_SpecialPhase = SiS310_SpecialPhase;
-
    SiS_Pr->SiS_StLCD1024x768Data    = (SiS_LCDDataStruct *)SiS310_StLCD1024x768Data;
    SiS_Pr->SiS_ExtLCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_ExtLCD1024x768Data;
    SiS_Pr->SiS_St2LCD1024x768Data   = (SiS_LCDDataStruct *)SiS310_St2LCD1024x768Data;
@@ -445,62 +503,10 @@
    SiS_Pr->SiS_St2LCD1280x1024Data  = (SiS_LCDDataStruct *)SiS310_St2LCD1280x1024Data;
    SiS_Pr->SiS_NoScaleData1024x768  = (SiS_LCDDataStruct *)SiS310_NoScaleData1024x768;
    SiS_Pr->SiS_NoScaleData1280x1024 = (SiS_LCDDataStruct *)SiS310_NoScaleData1280x1024;
-   SiS_Pr->SiS_LCD1280x960Data      = (SiS_LCDDataStruct *)SiS310_LCD1280x960Data;
-   SiS_Pr->SiS_ExtLCD1400x1050Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1400x1050Data;
-   SiS_Pr->SiS_ExtLCD1600x1200Data  = (SiS_LCDDataStruct *)SiS310_ExtLCD1600x1200Data;
-   SiS_Pr->SiS_StLCD1400x1050Data   = (SiS_LCDDataStruct *)SiS310_StLCD1400x1050Data;
-   SiS_Pr->SiS_StLCD1600x1200Data   = (SiS_LCDDataStruct *)SiS310_StLCD1600x1200Data;
-   SiS_Pr->SiS_NoScaleData1400x1050 = (SiS_LCDDataStruct *)SiS310_NoScaleData1400x1050;
-   SiS_Pr->SiS_NoScaleData1600x1200 = (SiS_LCDDataStruct *)SiS310_NoScaleData1600x1200;
-
-   SiS_Pr->SiS_StPALData   = (SiS_TVDataStruct *)SiS310_StPALData;
-   SiS_Pr->SiS_ExtPALData  = (SiS_TVDataStruct *)SiS310_ExtPALData;
-   SiS_Pr->SiS_StNTSCData  = (SiS_TVDataStruct *)SiS310_StNTSCData;
-   SiS_Pr->SiS_ExtNTSCData = (SiS_TVDataStruct *)SiS310_ExtNTSCData;
-/* SiS_Pr->SiS_St1HiTVData = (SiS_TVDataStruct *)SiS310_St1HiTVData;  */
-   SiS_Pr->SiS_St2HiTVData = (SiS_TVDataStruct *)SiS310_St2HiTVData;
-   SiS_Pr->SiS_ExtHiTVData = (SiS_TVDataStruct *)SiS310_ExtHiTVData;
-
-   SiS_Pr->SiS_NTSCTiming     = SiS310_NTSCTiming;
-   SiS_Pr->SiS_PALTiming      = SiS310_PALTiming;
-   SiS_Pr->SiS_HiTVSt1Timing  = SiS310_HiTVSt1Timing;
-   SiS_Pr->SiS_HiTVSt2Timing  = SiS310_HiTVSt2Timing;
-   SiS_Pr->SiS_HiTVTextTiming = SiS310_HiTVTextTiming;
-   SiS_Pr->SiS_HiTVExtTiming  = SiS310_HiTVExtTiming;
-   SiS_Pr->SiS_HiTVGroup3Data = SiS310_HiTVGroup3Data;
-   SiS_Pr->SiS_HiTVGroup3Simu = SiS310_HiTVGroup3Simu;
-   SiS_Pr->SiS_HiTVGroup3Text = SiS310_HiTVGroup3Text;
 
-   SiS_Pr->SiS_PanelDelayTbl = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
+   SiS_Pr->SiS_PanelDelayTbl     = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTbl;
    SiS_Pr->SiS_PanelDelayTblLVDS = (SiS_PanelDelayTblStruct *)SiS310_PanelDelayTblLVDS;
 
-   SiS_Pr->SiS_LVDS800x600Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_1;
-   SiS_Pr->SiS_LVDS800x600Data_2   = (SiS_LVDSDataStruct *)SiS310_LVDS800x600Data_2;
-   SiS_Pr->SiS_LVDS1024x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_1;
-   SiS_Pr->SiS_LVDS1024x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x768Data_2;
-   SiS_Pr->SiS_LVDS1280x1024Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_1;
-   SiS_Pr->SiS_LVDS1280x1024Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1280x1024Data_2;
-   SiS_Pr->SiS_LVDS1280x960Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_1;
-   SiS_Pr->SiS_LVDS1280x960Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x960Data_2;
-   SiS_Pr->SiS_LVDS1400x1050Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_1;
-   SiS_Pr->SiS_LVDS1400x1050Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1400x1050Data_2;
-   SiS_Pr->SiS_LVDS1600x1200Data_1 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_1;
-   SiS_Pr->SiS_LVDS1600x1200Data_2 = (SiS_LVDSDataStruct *)SiS310_LVDS1600x1200Data_2;
-   SiS_Pr->SiS_LVDS1280x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_1;
-   SiS_Pr->SiS_LVDS1280x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1280x768Data_2;
-   SiS_Pr->SiS_LVDS1024x600Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_1;
-   SiS_Pr->SiS_LVDS1024x600Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1024x600Data_2;
-   SiS_Pr->SiS_LVDS1152x768Data_1  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_1;
-   SiS_Pr->SiS_LVDS1152x768Data_2  = (SiS_LVDSDataStruct *)SiS310_LVDS1152x768Data_2;
-   SiS_Pr->SiS_LVDSXXXxXXXData_1   = (SiS_LVDSDataStruct *)SiS310_LVDSXXXxXXXData_1;
-   SiS_Pr->SiS_LVDS320x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS320x480Data_1;
-   SiS_Pr->SiS_LVDS640x480Data_1   = (SiS_LVDSDataStruct *)SiS310_LVDS640x480Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_1;
-   SiS_Pr->SiS_LCDA1400x1050Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1400x1050Data_2;
-   SiS_Pr->SiS_LCDA1600x1200Data_1  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_1;
-   SiS_Pr->SiS_LCDA1600x1200Data_2  = (SiS_LVDSDataStruct *)SiS310_LCDA1600x1200Data_2;
-   SiS_Pr->SiS_CHTVUNTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVUNTSCData;
-   SiS_Pr->SiS_CHTVONTSCData = (SiS_LVDSDataStruct *)SiS310_CHTVONTSCData;
    SiS_Pr->SiS_CHTVUPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVUPALData;
    SiS_Pr->SiS_CHTVOPALData  = (SiS_LVDSDataStruct *)SiS310_CHTVOPALData;
    SiS_Pr->SiS_CHTVUPALMData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALMData;
@@ -508,6 +514,7 @@
    SiS_Pr->SiS_CHTVUPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVUPALNData;
    SiS_Pr->SiS_CHTVOPALNData = (SiS_LVDSDataStruct *)SiS310_CHTVOPALNData;
    SiS_Pr->SiS_CHTVSOPALData = (SiS_LVDSDataStruct *)SiS310_CHTVSOPALData;
+
    SiS_Pr->SiS_PanelType00_1 = (SiS_LVDSDesStruct *)SiS310_PanelType00_1;
    SiS_Pr->SiS_PanelType01_1 = (SiS_LVDSDesStruct *)SiS310_PanelType01_1;
    SiS_Pr->SiS_PanelType02_1 = (SiS_LVDSDesStruct *)SiS310_PanelType02_1;
@@ -540,19 +547,7 @@
    SiS_Pr->SiS_PanelType0d_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0d_2;
    SiS_Pr->SiS_PanelType0e_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0e_2;
    SiS_Pr->SiS_PanelType0f_2 = (SiS_LVDSDesStruct *)SiS310_PanelType0f_2;
-   SiS_Pr->SiS_PanelTypeNS_1 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_1;
-   SiS_Pr->SiS_PanelTypeNS_2 = (SiS_LVDSDesStruct *)SiS310_PanelTypeNS_2;
-
-   SiS_Pr->LVDS1024x768Des_1  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_1;
-   SiS_Pr->LVDS1280x1024Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_1;
-   SiS_Pr->LVDS1400x1050Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_1 ;
-   SiS_Pr->LVDS1600x1200Des_1 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_1 ;
-   SiS_Pr->LVDS1024x768Des_2  = (SiS_LVDSDesStruct *)SiS310_PanelType1076_2;
-   SiS_Pr->LVDS1280x1024Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1210_2;
-   SiS_Pr->LVDS1400x1050Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1296_2;
-   SiS_Pr->LVDS1600x1200Des_2 = (SiS_LVDSDesStruct *)SiS310_PanelType1600_2 ;
 
-   /* TW: New from 650/301LV BIOS */
    SiS_Pr->SiS_CRT2Part2_1024x768_1  = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1024x768_1;
    SiS_Pr->SiS_CRT2Part2_1280x1024_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1280x1024_1;
    SiS_Pr->SiS_CRT2Part2_1400x1050_1 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_1;
@@ -566,51 +561,32 @@
    SiS_Pr->SiS_CRT2Part2_1400x1050_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1400x1050_3;
    SiS_Pr->SiS_CRT2Part2_1600x1200_3 = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_1600x1200_3;
 
-   SiS_Pr->SiS_CHTVUNTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVUNTSCDesData;
-   SiS_Pr->SiS_CHTVONTSCDesData = (SiS_LVDSDesStruct *)SiS310_CHTVONTSCDesData;
-   SiS_Pr->SiS_CHTVUPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVUPALDesData;
-   SiS_Pr->SiS_CHTVOPALDesData  = (SiS_LVDSDesStruct *)SiS310_CHTVOPALDesData;
-
    SiS_Pr->SiS_LVDSCRT1800x600_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1;
    SiS_Pr->SiS_LVDSCRT11024x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1;
    SiS_Pr->SiS_LVDSCRT11280x1024_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1;
    SiS_Pr->SiS_LVDSCRT11400x1050_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1;
-   SiS_Pr->SiS_LVDSCRT11280x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1;
-   SiS_Pr->SiS_LVDSCRT11024x600_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1;
-   SiS_Pr->SiS_LVDSCRT11152x768_1    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1;
    SiS_Pr->SiS_LVDSCRT11600x1200_1   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1;
    SiS_Pr->SiS_LVDSCRT1800x600_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_1_H;
    SiS_Pr->SiS_LVDSCRT11024x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_1_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_1_H;
    SiS_Pr->SiS_LVDSCRT11400x1050_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_1_H;
-   SiS_Pr->SiS_LVDSCRT11280x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_1_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_1_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_1_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_1_H;
    SiS_Pr->SiS_LVDSCRT11600x1200_1_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_1_H;
    SiS_Pr->SiS_LVDSCRT1800x600_2     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2;
    SiS_Pr->SiS_LVDSCRT11024x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2;
    SiS_Pr->SiS_LVDSCRT11280x1024_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2;
    SiS_Pr->SiS_LVDSCRT11400x1050_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2;
-   SiS_Pr->SiS_LVDSCRT11280x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2;
-   SiS_Pr->SiS_LVDSCRT11024x600_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2;
-   SiS_Pr->SiS_LVDSCRT11152x768_2    = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2;
    SiS_Pr->SiS_LVDSCRT11600x1200_2   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2;
    SiS_Pr->SiS_LVDSCRT1800x600_2_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1800x600_2_H;
    SiS_Pr->SiS_LVDSCRT11024x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x768_2_H;
    SiS_Pr->SiS_LVDSCRT11280x1024_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x1024_2_H;
    SiS_Pr->SiS_LVDSCRT11400x1050_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11400x1050_2_H;
-   SiS_Pr->SiS_LVDSCRT11280x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11280x768_2_H;
-   SiS_Pr->SiS_LVDSCRT11024x600_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11024x600_2_H;
-   SiS_Pr->SiS_LVDSCRT11152x768_2_H  = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11152x768_2_H;
    SiS_Pr->SiS_LVDSCRT11600x1200_2_H = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT11600x1200_2_H;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1;
-   SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H   = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1XXXxXXX_1_H;
-   SiS_Pr->SiS_LVDSCRT1320x480_1     = (SiS_LVDSCRT1DataStruct *)SiS310_LVDSCRT1320x480_1;
-   SiS_Pr->SiS_CHTVCRT1UNTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
-   SiS_Pr->SiS_CHTVCRT1ONTSC = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
-   SiS_Pr->SiS_CHTVCRT1UPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
-   SiS_Pr->SiS_CHTVCRT1OPAL  = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
-   SiS_Pr->SiS_CHTVCRT1SOPAL = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+   SiS_Pr->SiS_CHTVCRT1UNTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UNTSC;
+   SiS_Pr->SiS_CHTVCRT1ONTSC         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1ONTSC;
+   SiS_Pr->SiS_CHTVCRT1UPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1UPAL;
+   SiS_Pr->SiS_CHTVCRT1OPAL          = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1OPAL;
+   SiS_Pr->SiS_CHTVCRT1SOPAL         = (SiS_LVDSCRT1DataStruct *)SiS310_CHTVCRT1SOPAL;
+
    SiS_Pr->SiS_CHTVReg_UNTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UNTSC;
    SiS_Pr->SiS_CHTVReg_ONTSC = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_ONTSC;
    SiS_Pr->SiS_CHTVReg_UPAL  = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPAL;
@@ -620,26 +596,24 @@
    SiS_Pr->SiS_CHTVReg_UPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_UPALN;
    SiS_Pr->SiS_CHTVReg_OPALN = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_OPALN;
    SiS_Pr->SiS_CHTVReg_SOPAL = (SiS_CHTVRegDataStruct *)SiS310_CHTVReg_SOPAL;
-   SiS_Pr->SiS_LCDACRT1800x600_1     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1;
+
    SiS_Pr->SiS_LCDACRT11024x768_1    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1;
    SiS_Pr->SiS_LCDACRT11280x1024_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1;
    SiS_Pr->SiS_LCDACRT11400x1050_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1;
    SiS_Pr->SiS_LCDACRT11600x1200_1   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1;
-   SiS_Pr->SiS_LCDACRT1800x600_1_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_1_H;
    SiS_Pr->SiS_LCDACRT11024x768_1_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_1_H;
    SiS_Pr->SiS_LCDACRT11280x1024_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_1_H;
    SiS_Pr->SiS_LCDACRT11400x1050_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_1_H;
    SiS_Pr->SiS_LCDACRT11600x1200_1_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_1_H;
-   SiS_Pr->SiS_LCDACRT1800x600_2     = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2;
    SiS_Pr->SiS_LCDACRT11024x768_2    = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2;
    SiS_Pr->SiS_LCDACRT11280x1024_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2;
    SiS_Pr->SiS_LCDACRT11400x1050_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2;
    SiS_Pr->SiS_LCDACRT11600x1200_2   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2;
-   SiS_Pr->SiS_LCDACRT1800x600_2_H   = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT1800x600_2_H;
    SiS_Pr->SiS_LCDACRT11024x768_2_H  = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11024x768_2_H;
    SiS_Pr->SiS_LCDACRT11280x1024_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11280x1024_2_H;
    SiS_Pr->SiS_LCDACRT11400x1050_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11400x1050_2_H;
    SiS_Pr->SiS_LCDACRT11600x1200_2_H = (SiS_LCDACRT1DataStruct *)SiS310_LCDACRT11600x1200_2_H;
+
    SiS_Pr->SiS_CHTVVCLKUNTSC = SiS310_CHTVVCLKUNTSC;
    SiS_Pr->SiS_CHTVVCLKONTSC = SiS310_CHTVVCLKONTSC;
    SiS_Pr->SiS_CHTVVCLKUPAL  = SiS310_CHTVVCLKUPAL;
@@ -662,1245 +636,630 @@
    SiS_Pr->SiS_Panel1152x864  = Panel_1152x864;
    SiS_Pr->SiS_Panel1280x768  = Panel_1280x768;
    SiS_Pr->SiS_Panel1024x600  = Panel_1024x600;
-   SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* TW: highest value */
-   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* TW: lowest value LVDS/LCDA */
-   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* TW: lowest value 301 */
+   SiS_Pr->SiS_Panel640x480_2 = Panel_640x480_2;
+   SiS_Pr->SiS_Panel640x480_3 = Panel_640x480_3;
+   SiS_Pr->SiS_PanelMax       = Panel_320x480;    /* highest value */
+   SiS_Pr->SiS_PanelMinLVDS   = Panel_800x600;    /* lowest value LVDS/LCDA */
+   SiS_Pr->SiS_PanelMin301    = Panel_1024x768;   /* lowest value 301 */
+   SiS_Pr->SiS_PanelCustom    = Panel_Custom;
+   SiS_Pr->SiS_PanelBarco1366 = 255;
 }
 #endif
 
-#ifdef LINUXBIOS
-/* -------------- SiSInit -----------------*/
-/* TW: I degraded this for LINUXBIOS only, because we
- *     don't need this otherwise. Under normal
- *     circumstances, the video BIOS has initialized
- *     the adapter for us. BTW, this code is incomplete
- *     and very possibly not working on newer chipsets.
- */
-BOOLEAN
-SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   UCHAR   i, temp=0;
-   UCHAR   SR11;
-#ifdef LINUX_KERNEL
-   UCHAR   temp1;
-   ULONG   base;
-#endif
-   UCHAR   SR13=0, SR14=0, SR16=0
-   UCHAR   SR17=0, SR19=0, SR1A=0;
-#ifdef SIS300
-   UCHAR   SR18=0, SR12=0;
-#endif
-#ifdef SIS315H
-   UCHAR   CR37=0, CR38=0, CR79=0,
-   UCHAR   CR7A=0, CR7B=0, CR7C=0;
-   UCHAR   SR1B=0, SR15=0;
-   PSIS_DSReg pSR;
-   ULONG   Temp;
-#endif
-   UCHAR   VBIOSVersion[5];
-
-   if(FBAddr==0)    return (FALSE);
-   if(BaseAddr==0)  return (FALSE);
-
-   SiS_SetReg3((USHORT)(BaseAddr+0x12),  0x67);  /* Misc */
-
-#ifdef SIS315H
-   if(HwDeviceExtension->jChipType > SIS_315PRO) {
-     if(!HwDeviceExtension->bIntegratedMMEnabled)
-     	return (FALSE);
-   }
-#endif
-
-   SiS_MemoryCopy(VBIOSVersion,HwDeviceExtension->szVBIOSVer,4);
-   VBIOSVersion[4]= 0x00;
-
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
-
-   /* TW: Init pointers */
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315) ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
-     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
-#endif
-
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540) ||
-      (HwDeviceExtension->jChipType == SIS_630) ||
-      (HwDeviceExtension->jChipType == SIS_730) ||
-      (HwDeviceExtension->jChipType == SIS_300))
-     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
-#endif
-
-   /* TW: Set SiS Register definitions */
-   SiSRegInit(SiS_Pr, BaseAddr);
-
-   /* TW: Determine LVDS/CH70xx/TRUMPION */
-   SiS_Set_LVDS_TRUMPION(SiS_Pr, HwDeviceExtension);
-
-   /* TW: Unlock registers */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-
-#ifdef LINUX_KERNEL
-
-#ifdef SIS300                                         	/* Set SR14 */
-   if((HwDeviceExtension->jChipType==SIS_540) ||
-      (HwDeviceExtension->jChipType==SIS_630) ||
-      (HwDeviceExtension->jChipType==SIS_730)) {
-     base=0x80000060;
-     OutPortLong(base,0xcf8);
-     temp1 = InPortLong(0xcfc);
-     temp1 >>= (16+8+4);
-     temp1 &= 0x07;
-     temp1++;
-     temp1 = 1 << temp1;
-     SR14 = temp1 - 1;
-     base = 0x80000064;
-     OutPortLong(base,0xcf8);
-     temp1 = InPortLong(0xcfc);
-     temp1 &= 0x00000020;
-     if(temp1) 	SR14 |= 0x80;
-     else      	SR14 |= 0x40;
-   }
-#endif
-
-#ifdef SIS315H                                          /* Set SR14 */
-   if(HwDeviceExtension->jChipType == SIS_550) {
-     base = 0x80000060;
-     OutPortLong(base,0xcf8);
-     temp1 = InPortLong(0xcfc);
-     temp1 >>= (16+8+4);
-     temp1 &= 0x07;
-     temp1++;
-     temp1 = 1 << temp1;
-     SR14 = temp1 - 1;
-     base = 0x80000064;
-     OutPortLong(base,0xcf8);
-     temp1 = InPortLong(0xcfc);
-     temp1 &= 0x00000020;
-     if(temp1)  SR14 |= 0x80;
-     else       SR14 |= 0x40;
-   }
-
-   if((HwDeviceExtension->jChipType == SIS_740) ||     /* Set SR14 */
-      (HwDeviceExtension->jChipType == SIS_650))  {
-     base = 0x80000064;
-     OutPortLong(base,0xcf8);
-     temp1=InPortLong(0xcfc);
-     temp1 >>= 4;
-     temp1 &= 0x07;
-     if(temp1 > 2) {
-       temp = temp1;
-       switch(temp) {
-        case 3: temp1 = 0x07;  break;
-        case 4: temp1 = 0x0F;  break;
-        case 5: temp1 = 0x1F;  break;
-        case 6: temp1 = 0x05;  break;
-        case 7: temp1 = 0x17;  break;
-        case 8: break;
-        case 9: break;
-       }
-     }
-     SR14 = temp1;
-     base = 0x8000007C;
-     OutPortLong(base,0xcf8);
-     temp1 = InPortLong(0xcfc);
-     temp1 &= 0x00000020;
-     if(temp1)  SR14 |= 0x80;
-   }
-#endif
-
-#endif  /* Linux kernel */
-
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540)||
-      (HwDeviceExtension->jChipType == SIS_630)||
-      (HwDeviceExtension->jChipType == SIS_730)) {
-     SR12 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x12);
-     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
-     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-     SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-     SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
-     SR18 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
-     SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-   } else if(HwDeviceExtension->jChipType == SIS_300){
-     SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
-     SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-   }
-#endif
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_650)) {
-     SR19 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x19);
-     SR19 = (SR19)||0x01;  /* TW: ??? || ??? */
-     if(SR19==0x00) {
-     	SR13 = 0x22;
-     	SR14 = 0x00;
-    	SR15 = 0x01;
-     	SR16 = 0x00;
-     	SR17 = 0x00;
-     	SR1A = 0x00;
-     	SR1B = 0x00;
-     	CR37 = 0x00;
-     	CR38 = 0x00;
-     	CR79 = 0x00;
-     	CR7A = 0x00;
-     	CR7B = 0x00;
-     	CR7C = 0x00;
-     } else {
-     	SR13 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
-     	SR14 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-     	SR15 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
-     	SR16 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-     	SR17 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17);
-     	SR1A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-     	SR1B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1B);
-     	CR37 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);  /* TW: Was 0x02 - why? */
-     	CR38 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     	CR79 = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
-     	CR7A = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7A);
-     	CR7B = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7B);
-     	CR7C = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x7C);
-     }
-   }
-#endif
-
-   /* Reset extended registers */
-
-   for(i=0x06; i< 0x20; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
-   for(i=0x21; i<=0x27; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
-   for(i=0x31; i<=0x3D; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
-
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540) ||
-      (HwDeviceExtension->jChipType == SIS_630) ||
-      (HwDeviceExtension->jChipType == SIS_730) ||
-      (HwDeviceExtension->jChipType == SIS_300)) {
-     	for(i=0x38; i<=0x3F; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
-   }
-#endif
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315) ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
-   	for(i=0x12; i<=0x1B; i++) SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0);
-   	for(i=0x79; i<=0x7C; i++) SiS_SetReg1(SiS_Pr->SiS_P3d4,i,0);
-   }
-#endif
-
-   /* Restore Extended Registers */
-
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540) ||
-      (HwDeviceExtension->jChipType == SIS_630) ||
-      (HwDeviceExtension->jChipType == SIS_730)) {
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
-   }
-#endif
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_650)) {
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,SR15);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1B,SR1B);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,CR37);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,CR38);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x79,CR79);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7A,CR7A);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7B,CR7B);
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x7C,CR7C);
-   }
-#endif
-
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType==SIS_540) ||
-      (HwDeviceExtension->jChipType==SIS_630) ||
-      (HwDeviceExtension->jChipType==SIS_730)) {
-     	temp = (UCHAR)SR1A & 0x03;
-   } else if(HwDeviceExtension->jChipType == SIS_300) {
-        /* TW: Nothing */
-   }
-#endif
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)   ||
-      (HwDeviceExtension->jChipType == SIS_315)    ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_330) ) {
-      	if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
-          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A) & 0x03;
-        }
-   }
-   if((HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_650)) {
-        if((*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) == 0) {
-          	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
-        }
-   }
-#endif
-
-   SiS_Pr->SiS_RAMType = temp;
-   SiS_SetMemoryClock(SiS_Pr, ROMAddr, HwDeviceExtension);
-
-   /* Set default register contents */
-
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x07,*SiS_Pr->pSiS_SR07); 		/* DAC speed */
-
-   if((HwDeviceExtension->jChipType != SIS_540) &&
-      (HwDeviceExtension->jChipType != SIS_630) &&
-      (HwDeviceExtension->jChipType != SIS_730)){
-     	for(i=0x15;i<0x1C;i++) {
-       	    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SiS_Pr->SiS_SR15[i-0x15][SiS_Pr->SiS_RAMType]);
-     	}
-   }
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315)  ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
-     	for(i=0x40;i<=0x44;i++) {
-       	    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,SiS_Pr->SiS_CR40[i-0x40][SiS_Pr->SiS_RAMType]);
-     	}
-     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x48,0x23);
-     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[0]);
-    /*  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);  */
-   }
-#endif
-
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,*SiS_Pr->pSiS_SR1F); 	/* DAC pedestal */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xA0);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x23,*SiS_Pr->pSiS_SR23);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x24,*SiS_Pr->pSiS_SR24);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[0]);
-
-#ifdef SIS300
-   if(HwDeviceExtension->jChipType == SIS_300) {
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,0x84);
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,0x00);
-   }
-#endif
-
-   SR11 = 0x0F;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x11,SR11);		/* Power Management & DDC port */
-
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x00);
-   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,*SiS_Pr->pSiS_CRT2Data_1_2);
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315) ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2E,0x08);    /* use VB */
-#endif
-
-   temp = *SiS_Pr->pSiS_SR32;
-   if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)) {
-     	temp &= 0xEF;
-   }
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)   ||
-      (HwDeviceExtension->jChipType == SIS_315)    ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
-     HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,0x50,0,&Temp);
-     Temp >>= 20;
-     Temp &= 0xF;
-     if (Temp != 1) {
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x25,SiS_Pr->SiS_SR25[1]);
-     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x49,SiS_Pr->SiS_CR49[1]);
-     }
-
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x27,0x1F);
-
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,*SiS_Pr->pSiS_SR31);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,*SiS_Pr->pSiS_SR32);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x33,*SiS_Pr->pSiS_SR33);
-   }
-#endif
-
-   if (SiS_BridgeIsOn(SiS_Pr, BaseAddr) == 0) {
-     	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-       		SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1C);
-       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0D,*SiS_Pr->pSiS_CRT2Data_4_D);
-       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0E,*SiS_Pr->pSiS_CRT2Data_4_E);
-       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,*SiS_Pr->pSiS_CRT2Data_4_10);
-       		SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0F,0x3F);
-     	}
-     	SiS_LockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
-   }
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x83,0x00);
-
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H)   ||
-      (HwDeviceExtension->jChipType == SIS_315)    ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
-       	if(HwDeviceExtension->bSkipDramSizing==TRUE) {
-         	SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr,HwDeviceExtension);
-         	pSR = HwDeviceExtension->pSR;
-         	if(pSR != NULL) {
-           		while(pSR->jIdx != 0xFF) {
-             			SiS_SetReg1(SiS_Pr->SiS_P3c4,pSR->jIdx,pSR->jVal);
-             			pSR++;
-           		}
-         	}
-       } else SiS_SetDRAMSize_310(SiS_Pr, HwDeviceExtension);
-   }
-#endif
-
+   switch(HwInfo->jChipType) {
 #ifdef SIS315H
-   if(HwDeviceExtension->jChipType == SIS_550) {
-       /* SetDRAMConfig begin */
-/*     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);   */
-       /* SetDRAMConfig end */
-   }
+   case SIS_315H:
+   case SIS_315:
+   case SIS_315PRO:
+   case SIS_550:
+   case SIS_650:
+   case SIS_740:
+   case SIS_330:
+   case SIS_660:
+   case SIS_760:
+      InitTo310Pointer(SiS_Pr, HwInfo);
+      break;
 #endif
-
 #ifdef SIS300
-   if(HwDeviceExtension->jChipType == SIS_300) {
-       	if (HwDeviceExtension->bSkipDramSizing == TRUE) {
-/*       	SiS_SetDRAMModeRegister(ROMAddr,HwDeviceExtension);
-         	temp = (HwDeviceExtension->pSR)->jVal;
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,temp);
-         	temp = (HwDeviceExtension->pSR)->jVal;
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,temp);   */
-       } else {
-#ifdef TC
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-         	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x15,0xFF,0x04);
-#else
-         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
-         	SiS_SetDRAMSize_300(SiS_Pr, HwDeviceExtension);
-#endif
-       }
-   }
-   if((HwDeviceExtension->jChipType==SIS_540)||
-      (HwDeviceExtension->jChipType==SIS_630)||
-      (HwDeviceExtension->jChipType==SIS_730)) {
-#if 0
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x12,SR12);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SR16);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SR17);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x18,SR18);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SR19);
-       	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1A,SR1A);
+   case SIS_300:
+   case SIS_540:
+   case SIS_630:
+   case SIS_730:
+      InitTo300Pointer(SiS_Pr, HwInfo);
+      break;
 #endif
+   default:
+      break;
    }
-/* SetDRAMSize end */
-#endif /* SIS300 */
-
-   /* Set default Ext2Regs */
-#if 0
-   AGP=1;
-   temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-   temp &= 0x30;
-   if(temp == 0x30) AGP=0;
-   if(AGP == 0) *SiS_Pr->pSiS_SR21 &= 0xEF;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
-   if(AGP == 1) *SiS_Pr->pSiS_SR22 &= 0x20;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
-#endif
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,*SiS_Pr->pSiS_SR21);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x22,*SiS_Pr->pSiS_SR22);
-
-#if 0
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
-   SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
-#endif
+}
 
-#ifdef LINUXBIOS   /* TW: This is not needed for our purposes */
-   SiS_DetectMonitor(SiS_Pr, HwDeviceExtension,BaseAddr);    /* Sense CRT1 */
-   SiS_GetSenseStatus(SiS_Pr, HwDeviceExtension,ROMAddr);    /* Sense CRT2 */
-#endif
+/*********************************************/
+/*          HELPER: SetReg, GetReg           */
+/*********************************************/
 
-   return(TRUE);
+void
+SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data)
+{
+   OutPortByte(port,index);
+   OutPortByte(port + 1,data);
 }
 
 void
-SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetRegByte(SISIOADDRESS port, USHORT data)
 {
-  USHORT temp = 0;
-
-#ifdef SiS300
-  if((HwDeviceExtension->jChipType == SIS_540) ||
-     (HwDeviceExtension->jChipType == SIS_630) ||
-     (HwDeviceExtension->jChipType == SIS_730)) {
-        /* TW: Read POWER_ON_TRAP and copy to CR37 */
-    	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-    	temp = (temp & 0xE0) >> 4;
-   	SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
-  }
-#endif
-#ifdef SIS315H
-  if((HwDeviceExtension->jChipType == SIS_650) ||
-     (HwDeviceExtension->jChipType == SIS_740) ||
-     (HwDeviceExtension->jChipType == SIS_330)) {
-#if 0 /* TW: This is not required */
-        /* TW: Read POWER_ON_TRAP and copy to CR37 */
-    	temp = (UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-    	temp = (temp & 0xE0) >> 4;
-   	SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,0xF1,temp);
-#endif
-  }
-#endif
-
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, 0);
+   OutPortByte(port,data);
 }
 
-/* ===============  SiS 300 dram sizing begin  =============== */
-#ifdef SIS300
 void
-SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetRegShort(SISIOADDRESS port, USHORT data)
 {
-   ULONG   FBAddr = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
-   USHORT  SR13, SR14=0, buswidth, Done;
-   SHORT   i, j, k;
-   USHORT  data, TotalCapacity, PhysicalAdrOtherPage=0;
-   ULONG   Addr;
-   UCHAR   temp;
-   int     PseudoRankCapacity, PseudoTotalCapacity, PseudoAdrPinCount;
-   int     RankCapacity, AdrPinCount, BankNumHigh, BankNumMid, MB2Bank;
-   int     PageCapacity, PhysicalAdrHigh, PhysicalAdrHalfPage;
-
-   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
-
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);        /* Turn OFF Display  */
-
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0xBF);
-
-   buswidth = SiS_ChkBUSWidth_300(SiS_Pr, FBAddr);
-
-   MB2Bank = 16;
-   Done = 0;
-   for(i=6; i>=0; i--) {
-      if(Done == 1) break;
-      PseudoRankCapacity = 1 << i;
-      for(j=4; j>=1; j--) {
-         if(Done == 1) break;
-         PseudoTotalCapacity = PseudoRankCapacity * j;
-         PseudoAdrPinCount = 15 - j;
-         if(PseudoTotalCapacity <= 64) {
-            for(k=0; k<=16; k++) {
-               if(Done == 1) break;
-               RankCapacity = buswidth * SiS_DRAMType[k][3];
-               AdrPinCount = SiS_DRAMType[k][2] + SiS_DRAMType[k][0];
-               if(RankCapacity == PseudoRankCapacity)
-                 if(AdrPinCount <= PseudoAdrPinCount) {
-                    if(j == 3) {             /* Rank No */
-                       BankNumHigh = RankCapacity * MB2Bank * 3 - 1;
-                       BankNumMid = RankCapacity * MB2Bank * 1 - 1;
-                    } else {
-                       BankNumHigh = RankCapacity * MB2Bank * j - 1;
-                       BankNumMid = RankCapacity * MB2Bank * j / 2 - 1;
-                    }
-                    PageCapacity = (1 << SiS_DRAMType[k][1]) * buswidth * 4;
-                    PhysicalAdrHigh = BankNumHigh;
-                    PhysicalAdrHalfPage = (PageCapacity / 2 + PhysicalAdrHigh) % PageCapacity;
-                    PhysicalAdrOtherPage = PageCapacity * SiS_DRAMType[k][2] + PhysicalAdrHigh;
-                    /* Write data */
-                    /*Test*/
-                    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x15,0xFB);
-                    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x15,0x04);
-                    /*/Test*/
-                    TotalCapacity = SiS_DRAMType[k][3] * buswidth;
-                    SR13 = SiS_DRAMType[k][4];
-                    if(buswidth == 4) SR14 = (TotalCapacity - 1) | 0x80;
-                    if(buswidth == 2) SR14 = (TotalCapacity - 1) | 0x40;
-                    if(buswidth == 1) SR14 = (TotalCapacity - 1) | 0x00;
-                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,SR13);
-                    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,SR14);
-
-                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
-                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHigh;
-                    Addr = FBAddr + (BankNumMid) * 64 * 1024 + PhysicalAdrHigh;
-                    *((USHORT *)(Addr)) = (USHORT)BankNumMid;
-                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHalfPage;
-                    *((USHORT *)(Addr)) = (USHORT)PhysicalAdrHalfPage;
-                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrOtherPage;
-                    *((USHORT *)(Addr)) = PhysicalAdrOtherPage;
-
-                    /* Read data */
-                    Addr = FBAddr + (BankNumHigh) * 64 * 1024 + PhysicalAdrHigh;
-                    data = *((USHORT *)(Addr));
-                    if(data == PhysicalAdrHigh) Done = 1;
-                 }  /* if struct */
-            }  /* for loop (k) */
-         }  /* if struct */
-      }  /* for loop (j) */
-   }  /* for loop (i) */
+   OutPortWord(port,data);
 }
 
-USHORT
-SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress)
+void
+SiS_SetRegLong(SISIOADDRESS port, ULONG data)
 {
-   PULONG  pVideoMemory;
-
-   pVideoMemory = (PULONG)FBAddress;
+   OutPortLong(port,data);
+}
 
-   pVideoMemory[0] = 0x01234567L;
-   pVideoMemory[1] = 0x456789ABL;
-   pVideoMemory[2] = 0x89ABCDEFL;
-   pVideoMemory[3] = 0xCDEF0123L;
-   if (pVideoMemory[3]==0xCDEF0123L) {  /* Channel A 128bit */
-     return(4);
-   }
-   if (pVideoMemory[1]==0x456789ABL) {  /* Channel B 64bit */
-     return(2);
-   }
-   return(1);
+UCHAR
+SiS_GetReg(SISIOADDRESS port, USHORT index)
+{
+   OutPortByte(port,index);
+   return(InPortByte(port + 1));
 }
-#endif
-/* ===============  SiS 300 dram sizing end    =============== */
 
-/* ============  SiS 310/325 dram sizing begin  ============== */
-#ifdef SIS315H
+UCHAR
+SiS_GetRegByte(SISIOADDRESS port)
+{
+   return(InPortByte(port));
+}
 
-/* TW: Moved Get310DRAMType further down */
+USHORT
+SiS_GetRegShort(SISIOADDRESS port)
+{
+   return(InPortWord(port));
+}
 
-void
-SiS_Delay15us(SiS_Private *SiS_Pr, ULONG ulMicrsoSec)
+ULONG
+SiS_GetRegLong(SISIOADDRESS port)
 {
+   return(InPortLong(port));
 }
 
 void
-SiS_SDR_MRS(SiS_Private *SiS_Pr, )
+SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR)
 {
-   USHORT  data;
+  USHORT temp;
 
-   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-   data &= 0x3F;          		        /* SR16 D7=0, D6=0 */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) low */
-   SiS_Delay15us(SiS_Pr, 0x100);
-   data |= 0x80;          		        /* SR16 D7=1, D6=0 */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);   	/* enable mode register set(MRS) high */
-   SiS_Delay15us(SiS_Pr, 0x100);
+  temp = SiS_GetReg(Port,Index);
+  temp = (temp & (DataAND)) | DataOR;
+  SiS_SetReg(Port,Index,temp);
 }
 
 void
-SiS_DDR_MRS(SiS_Private *SiS_Pr)
+SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND)
 {
-   USHORT  data;
-
-   /* SR16 <- 1F,DF,2F,AF */
-
-   /* enable DLL of DDR SD/SGRAM , SR16 D4=1 */
-   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-   data &= 0x0F;
-   data |= 0x10;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
-
-   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
-     data &= 0x0F;
+  USHORT temp;
 
-   /* SR16 D7=1,D6=1 */
-   data |= 0xC0;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
-   
-   /* SR16 D7=1,D6=0,D5=1,D4=0 */
-   data &= 0x0F;
-   data |= 0x20;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
-   if (!(SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType] & 0x10))
-     data &= 0x0F;
-
-   /* SR16 D7=1 */
-   data |= 0x80;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,data);
+  temp = SiS_GetReg(Port,Index);
+  temp &= DataAND;
+  SiS_SetReg(Port,Index,temp);
 }
 
 void
-SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR)
 {
-    if (SiS_Get310DRAMType(ROMAddr,HwDeviceExtension) < 2)
-        SiS_SDR_MRS(SiS_Pr);
-    else
-        /* SR16 <- 0F,CF,0F,8F */
-        SiS_DDR_MRS(SiS_Pr);
+  USHORT temp;
+
+  temp = SiS_GetReg(Port,Index);
+  temp |= DataOR;
+  SiS_SetReg(Port,Index,temp);
 }
 
+/*********************************************/
+/*      HELPER: DisplayOn, DisplayOff        */
+/*********************************************/
+
 void
-SiS_DisableRefresh(SiS_Private *SiS_Pr)
+SiS_DisplayOn(SiS_Private *SiS_Pr)
 {
-   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x17,0xF8);
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x19,0x03);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
 }
 
 void
-SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr)
+SiS_DisplayOff(SiS_Private *SiS_Pr)
 {
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,SiS_Pr->SiS_SR15[2][SiS_Pr->SiS_RAMType]);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x19,SiS_Pr->SiS_SR15[4][SiS_Pr->SiS_RAMType]);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
 }
 
-void
-SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,
-                               USHORT SiS_DDRDRAM_TYPE[][5])
-{
-   USHORT  data;
 
-   data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
-   data &= 0x1F;
-   switch (SiS_DDRDRAM_TYPE[index][3])
-   {
-     case 64: data |= 0; 	break;
-     case 32: data |= 0x20;	break;
-     case 16: data |= 0x40;     break;
-     case 4:  data |= 0x60;     break;
-   }
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
-}
+/*********************************************/
+/*        HELPER: Init Port Addresses        */
+/*********************************************/
 
 void
-SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index, USHORT DRAMTYPE_TABLE[][5])
+SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr)
 {
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,DRAMTYPE_TABLE[index][4]);
-   /* should delay 50 ns */
-}
+   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
+   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
+   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
+   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
+   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
+   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
+   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
+   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
+   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
+   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
+   SiS_Pr->SiS_P3cb = BaseAddr + 0x1b;
+   SiS_Pr->SiS_P3cd = BaseAddr + 0x1d;
+   SiS_Pr->SiS_P3da = BaseAddr + 0x2a;
+   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;     /* Digital video interface registers (LCD) */
+   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;     /* 301 TV Encoder registers */
+   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;     /* 301 Macrovision registers */
+   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;     /* 301 VGA2 (and LCD) registers */
+   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14 + 2; /* 301 palette address port registers */
+   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                  /* DDC Port ( = P3C4, SR11/0A) */
+   SiS_Pr->SiS_VidCapt = BaseAddr + SIS_VIDEO_CAPTURE;
+   SiS_Pr->SiS_VidPlay = BaseAddr + SIS_VIDEO_PLAYBACK;
+}
+
+/*********************************************/
+/*             HELPER: GetSysFlags           */
+/*********************************************/
 
-void
-SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
-                      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_GetSysFlags(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   USHORT  data, temp;
-   PULONG  volatile pVideoMemory;
+   unsigned char cr5f, temp1, temp2;
 
-   pVideoMemory = (PULONG)FBAddress;
+   /* You should use the macros, not these flags directly */
 
-   if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
-   else temp = 2;
-
-   if(SiS_Get310DRAMType(ROMAddress,HwDeviceExtension) < temp) {
+   SiS_Pr->SiS_SysFlags = 0;
+   if(HwInfo->jChipType == SIS_650) {
+      cr5f = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0;
+      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x5c,0x07);
+      temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+      SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x5c,0xf8);
+      temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+      if((!temp1) || (temp2)) {
+         switch(cr5f) {
+	    case 0x80:
+	    case 0x90:
+	    case 0xc0:
+	       SiS_Pr->SiS_SysFlags |= SF_IsM650;  break;
+	    case 0xa0:
+	    case 0xb0:
+	    case 0xe0:
+	       SiS_Pr->SiS_SysFlags |= SF_Is651;   break;
+	 }
+      } else {
+         switch(cr5f) {
+	    case 0x90:
+	       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5c) & 0xf8;
+	       switch(temp1) {
+	          case 0x00: SiS_Pr->SiS_SysFlags |= SF_IsM652; break;
+		  case 0x40: SiS_Pr->SiS_SysFlags |= SF_IsM653; break;
+		  default:   SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+	       }
+	       break;
+	    case 0xb0:
+	       SiS_Pr->SiS_SysFlags |= SF_Is652;  break;
+	    default:
+	       SiS_Pr->SiS_SysFlags |= SF_IsM650; break;
+	 }
+      }
+   }
+}
 
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
-     if(HwDeviceExtension->jChipType != SIS_330) {
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x12);
-     } else {
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02);
-     }
-     /* should delay */
-     SiS_SDR_MRS(SiS_Pr);
+/*********************************************/
+/*         HELPER: Init PCI & Engines        */
+/*********************************************/
 
-     SiS_Pr->SiS_ChannelAB = 0;
-     SiS_Pr->SiS_DataBusWidth = 128;
-     pVideoMemory[0] = 0x01234567L;
-     pVideoMemory[1] = 0x456789ABL;
-     pVideoMemory[2] = 0x89ABCDEFL;
-     pVideoMemory[3] = 0xCDEF0123L;
-     pVideoMemory[4] = 0x55555555L;
-     pVideoMemory[5] = 0x55555555L;
-     pVideoMemory[6] = 0xFFFFFFFFL;
-     pVideoMemory[7] = 0xFFFFFFFFL;
-     if((pVideoMemory[3] != 0xCDEF0123L) || (pVideoMemory[2] != 0x89ABCDEFL)) {
-       /* Channel A 64Bit */
-       SiS_Pr->SiS_DataBusWidth = 64;
-       SiS_Pr->SiS_ChannelAB = 0;
-       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x14, 0xFD);
-     }
-     if((pVideoMemory[1] != 0x456789ABL) || (pVideoMemory[0] != 0x01234567L)) {
-       /* Channel B 64Bit */
-       SiS_Pr->SiS_DataBusWidth = 64;
-       SiS_Pr->SiS_ChannelAB = 1;
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x14,0xfd,0x01);
-     }
-     return;
-
-   } else {
-
-     /* DDR Dual channel */
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x13,0x00);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x02); /* Channel A, 64bit */
-     /* should delay */
-     SiS_DDR_MRS(SiS_Pr);
-
-     SiS_Pr->SiS_ChannelAB = 0;
-     SiS_Pr->SiS_DataBusWidth = 64;
-     pVideoMemory[0] = 0x01234567L;
-     pVideoMemory[1] = 0x456789ABL;
-     pVideoMemory[2] = 0x89ABCDEFL;
-     pVideoMemory[3] = 0xCDEF0123L;
-     pVideoMemory[4] = 0x55555555L;
-     pVideoMemory[5] = 0x55555555L;
-     pVideoMemory[6] = 0xAAAAAAAAL;
-     pVideoMemory[7] = 0xAAAAAAAAL;
-
-     if (pVideoMemory[1] == 0x456789ABL) {
-       if (pVideoMemory[0] == 0x01234567L) {
-         /* Channel A 64bit */
-         return;
-       }
-     } else {
-       if (pVideoMemory[0] == 0x01234567L) {
-         /* Channel A 32bit */
-         SiS_Pr->SiS_DataBusWidth = 32;
-         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x00);
-         return;
-       }
-     }
-
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x03); /* Channel B, 64bit */
-     SiS_DDR_MRS(SiS_Pr);
-
-     SiS_Pr->SiS_ChannelAB = 1;
-     SiS_Pr->SiS_DataBusWidth = 64;
-     pVideoMemory[0] = 0x01234567L;
-     pVideoMemory[1] = 0x456789ABL;
-     pVideoMemory[2] = 0x89ABCDEFL;
-     pVideoMemory[3] = 0xCDEF0123L;
-     pVideoMemory[4] = 0x55555555L;
-     pVideoMemory[5] = 0x55555555L;
-     pVideoMemory[6] = 0xAAAAAAAAL;
-     pVideoMemory[7] = 0xAAAAAAAAL;
-     if(pVideoMemory[1] == 0x456789ABL) {
-       /* Channel B 64 */
-       if(pVideoMemory[0] == 0x01234567L) {
-         /* Channel B 64bit */
-         return;
-       } else {
-         /* error */
-       }
-     } else {
-       if(pVideoMemory[0] == 0x01234567L) {
-         /* Channel B 32 */
-         SiS_Pr->SiS_DataBusWidth = 32;
-         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,0x01);
-       } else {
-         /* error */
-       }
-     }
+static void
+SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   switch(HwInfo->jChipType) {
+   case SIS_300:
+   case SIS_540:
+   case SIS_630:
+   case SIS_730:
+      /* Set - PCI LINEAR ADDRESSING ENABLE (0x80)
+       *     - RELOCATED VGA IO  (0x20)
+       *     - MMIO ENABLE (0x1)
+       */
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      /*  - Enable 2D (0x40)
+       *  - Enable 3D (0x02)
+       *  - Enable 3D Vertex command fetch (0x10) ?
+       *  - Enable 3D command parser (0x08) ?
+       */
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x5A);
+      break;
+   case SIS_315H:
+   case SIS_315:
+   case SIS_315PRO:
+   case SIS_650:
+   case SIS_740:
+   case SIS_330:
+   case SIS_660:
+   case SIS_760:
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      /*  - Enable 2D (0x40)
+       *  - Enable 3D (0x02)
+       *  - Enable 3D vertex command fetch (0x10)
+       *  - Enable 3D command parser (0x08)
+       *  - Enable 3D G/L transformation engine (0x80)
+       */
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0xDA);
+      break;
+   case SIS_550:
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x20,0xa1);
+      /* No 3D engine ! */
+      /*  - Enable 2D (0x40)
+       */
+      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x40);
    }
 }
 
-int
-SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5])
+/*********************************************/
+/*             HELPER: SetLVDSetc            */
+/*********************************************/
+
+void
+SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  USHORT  data;
-  int RankSize;
+   ULONG   temp;
 
-  if ((RankNo==2)&&(DRAMTYPE_TABLE[index][0]==2))
-         return 0;
+   SiS_Pr->SiS_IF_DEF_LVDS = 0;
+   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
+   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
+   SiS_Pr->SiS_IF_DEF_HiVision = 0;
+   SiS_Pr->SiS_IF_DEF_DSTN = 0;
+   SiS_Pr->SiS_IF_DEF_FSTN = 0;
 
-  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
+   SiS_Pr->SiS_ChrontelInit = 0;
 
-  if (RankNo * RankSize <= 128) {
-    data = 0;
-    while((RankSize >>= 1) > 0) {
-      data += 0x10;
-    }
-    data |= (RankNo - 1) << 2;
-    data |= (SiS_Pr->SiS_DataBusWidth / 64) & 2;
-    data |= SiS_Pr->SiS_ChannelAB;
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
-    /* should delay */
-    SiS_SDR_MRS(SiS_Pr);
-    return 1;
-  } else
-    return 0;
+   switch(HwInfo->jChipType) {
+#ifdef SIS300
+   case SIS_540:
+   case SIS_630:
+   case SIS_730:
+        /* Check for SiS30x first */
+        temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+	if((temp == 1) || (temp == 2)) return;
+      	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+      	temp = (temp & 0x0E) >> 1;
+      	if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+      	if(temp == 3)   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
+      	if((temp == 4) || (temp == 5)) {
+		/* Save power status (and error check) - UNUSED */
+		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
+		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
+        }
+	break;
+#endif
+#ifdef SIS315H
+   case SIS_550:
+   case SIS_650:
+   case SIS_740:
+   case SIS_330:
+   case SIS_660:
+   case SIS_760:
+	temp=SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+      	temp = (temp & 0x0E) >> 1;
+      	if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
+      	if(temp == 3)  SiS_Pr->SiS_IF_DEF_CH70xx = 2;
+        break;
+#endif
+   default:
+        break;
+   }
 }
 
-int
-SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
-                  USHORT DRAMTYPE_TABLE[][5])
-{
-  USHORT  data;
-  int RankSize;
+/*********************************************/
+/*          HELPER: Enable DSTN/FSTN         */
+/*********************************************/
 
-  RankSize = DRAMTYPE_TABLE[index][3]/2 * SiS_Pr->SiS_DataBusWidth / 32;
-  /* RankSize = DRAMTYPE_TABLE[index][3]; */
-  if (ChannelNo * RankSize <= 128) {
-    data = 0;
-    while((RankSize >>= 1) > 0) {
-      data += 0x10;
-    }
-    if(ChannelNo == 2) data |= 0x0C;
-    data |= (SiS_Pr->SiS_DataBusWidth / 32) & 2;
-    data |= SiS_Pr->SiS_ChannelAB;
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
-    /* should delay */
-    SiS_DDR_MRS(SiS_Pr);
-    return 1;
-  } else
-    return 0;
+void
+SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable)
+{
+   SiS_Pr->SiS_IF_DEF_DSTN = enable ? 1 : 0;
 }
 
-int
-SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+void
+SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable)
 {
-  int i;
-  ULONG Increment,Position;
-
-  /*Increment = 1<<(DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 1); */
-  Increment = 1 << (10 + SiS_Pr->SiS_DataBusWidth / 64);
-
-  for (i=0,Position=0;i<2;i++) {
-         *((PULONG)(FBAddress + Position)) = Position;
-         Position += Increment;
-  }
-
-  for (i=0,Position=0;i<2;i++) {
-/*    if (FBAddress[Position]!=Position) */
-         if((*(PULONG)(FBAddress + Position)) != Position)
-                return 0;
-         Position += Increment;
-  }
-  return 1;
+   SiS_Pr->SiS_IF_DEF_FSTN = enable ? 1 : 0;
 }
 
-int
-SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+/*********************************************/
+/*        HELPER: Determine ROM usage        */
+/*********************************************/
+
+static void
+SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  int i;
-  ULONG Increment,Position;
-  Increment = 1 << (DRAMTYPE_TABLE[index][2] + SiS_Pr->SiS_DataBusWidth / 64 + 2);
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
 
-  for (i=0,Position=0;i<4;i++) {
-/*    FBAddress[Position]=Position; */
-    *((PULONG)(FBAddress + Position)) = Position;
-    Position += Increment;
-  }
+   if((ROMAddr) && (HwInfo->UseROM)) {
+      if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
+         SiS_Pr->SiS_UseROM = FALSE;
+      } else if(HwInfo->jChipType == SIS_300) {
+        /* 300: We check if the code starts below 0x220 by
+	 * checking the jmp instruction at the beginning
+	 * of the BIOS image.
+	 */
+	 if((ROMAddr[3] == 0xe9) &&
+	    ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
+	    SiS_Pr->SiS_UseROM = TRUE;
+	 else
+	    SiS_Pr->SiS_UseROM = FALSE;
+      } else if(HwInfo->jChipType < SIS_315H) {
+#if 0
+        /* Rest of 300 series: We don't use the ROM image if
+	 * the BIOS version < 2.0.0 as such old BIOSes don't
+	 * have the needed data at the expected locations.
+	 */
+         if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
+	 else                     SiS_Pr->SiS_UseROM = TRUE;
+#else
+	/* Sony's VAIO BIOS 1.09 follows the standard, so perhaps
+	 * the others do as well
+	 */
+	 SiS_Pr->SiS_UseROM = TRUE;
+#endif
+      } else {
+         /* 315/330 series stick to the standard */
+	 SiS_Pr->SiS_UseROM = TRUE;
+      }
+   } else SiS_Pr->SiS_UseROM = FALSE;
 
-  for (i=0,Position=0;i<4;i++) {
-/*    if (FBAddress[Position]!=Position) */
-    if((*(PULONG)(FBAddress + Position)) != Position)
-      return 0;
-    Position += Increment;
-  }
-  return 1;
 }
 
-int
-SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
-{
-  int i;
-  ULONG Increment,Position;
-  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
-
-  for (i=0,Position=0;i<2;i++) {
-/*    FBAddress[Position]=Position; */
-    *((PULONG)(FBAddress+Position))=Position;
-    /* *((PULONG)(FBAddress))=Position; */
-    Position += Increment;
-  }
-
-  for (i=0,Position=0;i<2;i++) {
-/*    if (FBAddress[Position]!=Position) */
-         if ( (*(PULONG) (FBAddress + Position)) !=Position)
-    /*if ( (*(PULONG) (FBAddress )) !=Position) */
-      return 0;
-    Position += Increment;
-  }
-  return 1;
-}
+/*********************************************/
+/*        HELPER: SET SEGMENT REGISTERS      */
+/*********************************************/
 
-int
-SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+static void
+SiS_SetSegRegLower(SiS_Private *SiS_Pr, USHORT value)
 {
-  ULONG Increment,Position;
-  USHORT  data;
-
-  Increment = 1<<(DRAMTYPE_TABLE[index][2] + DRAMTYPE_TABLE[index][1] +
-                  DRAMTYPE_TABLE[index][0] + SiS_Pr->SiS_DataBusWidth / 64 + RankNo);
+   USHORT temp;
 
-  Increment += Increment/2;
-
-  Position =0;
-  *((PULONG)(FBAddress+Position + 0)) = 0x01234567;
-  *((PULONG)(FBAddress+Position + 1)) = 0x456789AB;
-  *((PULONG)(FBAddress+Position + 2)) = 0x55555555;
-  *((PULONG)(FBAddress+Position + 3)) = 0x55555555;
-  *((PULONG)(FBAddress+Position + 4)) = 0xAAAAAAAA;
-  *((PULONG)(FBAddress+Position + 5)) = 0xAAAAAAAA;
-
-  if ( (*(PULONG) (FBAddress + 1)) == 0x456789AB)
-    return 1;
-
-  if ( (*(PULONG) (FBAddress + 0)) == 0x01234567)
-    return 0;
-
-  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-  data &= 0xF3;
-  data |= 0x08;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x14,data);
-  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15);
-  data += 0x20;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x15,data);
-
-  return 1;
+   value &= 0x00ff;
+   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0xf0;
+   temp |= (value >> 4);
+   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
+   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0xf0;
+   temp |= (value & 0x0f);
+   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
 }
 
-int
-SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress)
+static void
+SiS_SetSegRegUpper(SiS_Private *SiS_Pr, USHORT value)
 {
-  int r;
+   USHORT temp;
 
-  for (r=RankNo;r>=1;r--) {
-    if (!SiS_CheckRank(SiS_Pr, r, index, DRAMTYPE_TABLE, FBAddress))
-      return 0;
-  }
-  if (!SiS_CheckBanks(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
-    return 0;
-
-  if (!SiS_CheckColumn(SiS_Pr, index, DRAMTYPE_TABLE, FBAddress))
-    return 0;
-
-  return 1;
+   value &= 0x00ff;
+   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cb) & 0x0f;
+   temp |= (value & 0xf0);
+   SiS_SetRegByte(SiS_Pr->SiS_P3cb, temp);
+   temp = SiS_GetRegByte(SiS_Pr->SiS_P3cd) & 0x0f;
+   temp |= (value << 4);
+   SiS_SetRegByte(SiS_Pr->SiS_P3cd, temp);
 }
 
-int
-SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],
-                  ULONG FBAddress)
+static void
+SiS_SetSegmentReg(SiS_Private *SiS_Pr, USHORT value)
 {
-  int r;
-
-  for (r=RankNo;r>=1;r--) {
-    if (!SiS_CheckDDRRank(SiS_Pr, r,index,DRAMTYPE_TABLE,FBAddress))
-      return 0;
-  }
-  if (!SiS_CheckBanks(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
-    return 0;
-
-  if (!SiS_CheckColumn(SiS_Pr, index,DRAMTYPE_TABLE,FBAddress))
-    return 0;
-
-  return 1;
+   SiS_SetSegRegLower(SiS_Pr, value);
+   SiS_SetSegRegUpper(SiS_Pr, value);
 }
 
-int
-SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
+static void
+SiS_ResetSegmentReg(SiS_Private *SiS_Pr)
 {
-  int    i;
-  UCHAR  j;
-
-  for (i=0;i<13;i++) {
-    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_SDRDRAM_TYPE);
-    for (j=2;j>0;j--) {
-      if (!SiS_SetRank(SiS_Pr, i,(UCHAR) j, SiS_SDRDRAM_TYPE))
-        continue;
-      else {
-        if (SiS_CheckRanks(SiS_Pr, j,i,SiS_SDRDRAM_TYPE, FBAddress))
-          return 1;
-      }
-    }
-  }
-  return 0;
+   SiS_SetSegmentReg(SiS_Pr, 0);
 }
 
-int
-SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress)
+static void
+SiS_SetSegmentRegOver(SiS_Private *SiS_Pr, USHORT value)
 {
+   USHORT temp = value >> 8;
 
-  int    i;
-  UCHAR  j;
-
-  for (i=0; i<4; i++){
-    SiS_SetDRAMSizingType(SiS_Pr, i, SiS_DDRDRAM_TYPE);
-    SiS_DisableChannelInterleaving(SiS_Pr, i, SiS_DDRDRAM_TYPE);
-    for (j=2; j>0; j--) {
-      SiS_SetDDRChannel(SiS_Pr, i, j, SiS_DDRDRAM_TYPE);
-      if (!SiS_SetRank(SiS_Pr, i, (UCHAR) j, SiS_DDRDRAM_TYPE))
-        continue;
-      else {
-        if (SiS_CheckDDRRanks(SiS_Pr, j, i, SiS_DDRDRAM_TYPE, FBAddress))
-          return 1;
-      }
-    }
-  }
-  return 0;
+   temp &= 0x07;
+   temp |= (temp << 4);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1d,temp);
+   SiS_SetSegmentReg(SiS_Pr, value);
 }
 
-/*
- check if read cache pointer is correct
-*/
-void
-SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr)
+static void
+SiS_ResetSegmentRegOver(SiS_Private *SiS_Pr)
 {
-   PUCHAR  pVideoMemory = (PUCHAR) FBAddr;
-   UCHAR   i, j;
-   USHORT  Temp,SR21;
-
-   pVideoMemory[0] = 0xaa;  /* alan */
-   pVideoMemory[16] = 0x55; /* note: PCI read cache is off */
-
-   if((pVideoMemory[0] != 0xaa) || (pVideoMemory[16] != 0x55)) {
-     for (i=0,j=16; i<2; i++,j+=16)  {
-       SR21 = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
-       Temp = SR21 & 0xFB;           /* disable PCI post write buffer empty gating */
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,Temp);
-
-       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x3C);
-       Temp |= 0x01;                 /* MCLK reset */
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
-       Temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3C);
-       Temp &= 0xFE;                 /* MCLK normal operation */
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3C,Temp);
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x21,SR21);
-
-       pVideoMemory[16+j] = j;
-       if(pVideoMemory[16+j] == j) {
-         pVideoMemory[j] = j;
-         break;
-       }
-     }
-   }
+   SiS_SetSegmentRegOver(SiS_Pr, 0);
 }
 
-/* TW: Is this a 315E? */
-int
-Is315E(SiS_Private *SiS_Pr)
+static void
+SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo)
 {
-   USHORT  data;
-
-   data = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5F);
-   if(data & 0x10) return 1;
-   else return 0;
+   if(IS_SIS65x) {
+      SiS_ResetSegmentReg(SiS_Pr);
+      SiS_ResetSegmentRegOver(SiS_Pr);
+   }
 }
 
-/* TW: For 315 only */
+/*********************************************/
+/*             HELPER: GetVBType             */
+/*********************************************/
+
 void
-SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   ULONG   FBAddr   = (ULONG)HwDeviceExtension->pjVideoMemoryAddress;
-   USHORT  data;
+  USHORT flag=0, rev=0, nolcd=0;
 
-#ifdef SIS301	/* TW: SIS301 ??? */
-   /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x40);   */
-#endif
-#ifdef SIS302   /* TW: SIS302 ??? */
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x4D);  /* alan,should change value */
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0xc0);  /* alan,should change value */
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,0x3F);  /* alan,should change value */
-#endif
+  SiS_Pr->SiS_VBType = 0;
 
-   SiSSetMode(SiS_Pr, HwDeviceExtension, 0x2e);
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
 
-   data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x21);
-   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x21,0xDF);                 /* disable read cache */
+  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
 
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x20);                  /* Turn OFF Display */
+  if(flag > 3) return;
 
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x16,0x0F);                  /* assume lowest speed DRAM */
+  rev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
 
-   SiS_SetDRAMModeRegister(SiS_Pr, ROMAddr, HwDeviceExtension);
-   SiS_DisableRefresh(SiS_Pr);
-   SiS_CheckBusWidth_310(SiS_Pr, ROMAddr, FBAddr, HwDeviceExtension);
+  if(flag >= 2) {
+        SiS_Pr->SiS_VBType = VB_SIS302B;
+  } else if(flag == 1) {
+        SiS_Pr->SiS_VBType = VB_SIS301;
+	if(rev >= 0xC0) {
+            	SiS_Pr->SiS_VBType = VB_SIS301C;
+        } else if(rev >= 0xB0) {
+            	SiS_Pr->SiS_VBType = VB_SIS301B;
+		/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
+    		nolcd = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
+                if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
+        }
+  }
+  if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS301C | VB_SIS302B)) {
+        if(rev >= 0xD0) {
+	        SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS301C | VB_SIS302B);
+          	SiS_Pr->SiS_VBType |= VB_SIS301LV;
+		SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
+		if(rev >= 0xE0) {
+		    SiS_Pr->SiS_VBType &= ~(VB_SIS301LV);
+		    SiS_Pr->SiS_VBType |= VB_SIS302LV;
+		}
+        }
+  }
+}
 
-   SiS_VerifyMclk(SiS_Pr, FBAddr);
+/*********************************************/
+/*            HELPER: GetDRAMSize            */
+/*********************************************/
 
-   if(HwDeviceExtension->jChipType == SIS_330) temp = 1;
-   else temp = 2;
+#ifndef LINUX_XF86
+static ULONG
+GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  ULONG   AdapterMemorySize = 0;
+#ifdef SIS315H
+  USHORT  counter;
+#endif
 
-   if(SiS_Get310DRAMType(SiS_Pr, ROMAddr, HwDeviceExtension) < temp)
-     SiS_SDRSizing(SiS_Pr, FBAddr);
-   else
-     SiS_DDRSizing(SiS_Pr, FBAddr);
+  switch(HwInfo->jChipType) {
+#ifdef SIS315H
+  case SIS_315H:
+  case SIS_315:
+  case SIS_315PRO:
+    	counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+	counter >>= 2;
+	counter &= 0x03;
+	if(counter == 0x02) {
+		AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
+	} else if(counter != 0) {
+		AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
+	}
+	AdapterMemorySize *= (1024*1024);
+        break;
 
-   if(HwDeviceExtension->jChipType != SIS_330) {
-     if(Is315E(SiS_Pr)) {
-       data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if((data & 0x0C) == 0x0C) { 	/* dual channel */
-     	 if((data & 0xF0) > 0x40)
-     	   data = (data & 0x0F) | 0x40;
-       } else { 				/* single channel */
-     	 if((data & 0xF0) > 0x50)
-     	   data = (data & 0x0F) | 0x50;
-       }
-     }
-   }
+  case SIS_330:
+    	counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
+	counter &= 0x0c;
+	if(counter != 0) {
+		AdapterMemorySize <<= 1;
+	}
+	AdapterMemorySize *= (1024*1024);
+	break;
+
+  case SIS_550:
+  case SIS_650:
+  case SIS_740:
+  case SIS_660:
+  case SIS_760:
+  	counter = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+      	counter++;
+      	AdapterMemorySize = counter * 4;
+      	AdapterMemorySize *= (1024*1024);
+	break;
+#endif
 
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x16,SiS_Pr->SiS_SR15[1][SiS_Pr->SiS_RAMType]);  /* restore SR16 */
+#ifdef SIS300
+  case SIS_300:
+  case SIS_540:
+  case SIS_630:
+  case SIS_730:
+      	AdapterMemorySize = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
+      	AdapterMemorySize++;
+      	AdapterMemorySize *= (1024*1024);
+	break;
+#endif
+  default:
+        break;
+  }
 
-   SiS_EnableRefresh(SiS_Pr, ROMAddr);
-   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x21,0x20);      	/* enable read cache */
+  return AdapterMemorySize;
 }
 #endif
 
-void
-SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*           HELPER: Check RAM size          */
+/*********************************************/
+
+#ifndef LINUX_XF86
+static BOOLEAN
+SiS_CheckMemorySize(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                    USHORT ModeNo, USHORT ModeIdIndex)
 {
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR28);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR29);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2A,SiS_Pr->SiS_MCLKData_0[SiS_Pr->SiS_RAMType].SR2A);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2E);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR2F);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x30,SiS_Pr->SiS_ECLKData[SiS_Pr->SiS_RAMType].SR30);
+  USHORT memorysize,modeflag;
+  ULONG  temp;
 
-#ifdef SIS315H
-   if (Is315E(SiS_Pr)) {
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x28,0x3B); /* 143 */
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x29,0x22);
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2E,0x3B); /* 143 */
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2F,0x22);
-   }
-#endif
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }
+
+  memorysize = modeflag & MemoryInfoFlag;
+  memorysize >>= MemorySizeShift;			/* Get required memory size */
+  memorysize++;
+
+  temp = GetDRAMSize(SiS_Pr, HwInfo);       	/* Get adapter memory size */
+  temp /= (1024*1024);   				/* (in MB) */
+
+  if(temp < memorysize) return(FALSE);
+  else return(TRUE);
 }
+#endif
 
-#endif /* ifdef LINUXBIOS */
+/*********************************************/
+/*           HELPER: Get DRAM type           */
+/*********************************************/
 
 #ifdef SIS315H
-UCHAR
-SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static UCHAR
+SiS_Get310DRAMType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    UCHAR data, temp;
 
    if(*SiS_Pr->pSiS_SoftSetting & SoftDRAMType) {
      data = *SiS_Pr->pSiS_SoftSetting & 0x03;
    } else {
-     if((HwDeviceExtension->jChipType > SIS_315PRO) &&
-        (HwDeviceExtension->jChipType < SIS_330)) {
-        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x07;
-     } else {	/* TW: 315, 330 */
-        data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
-        if(HwDeviceExtension->jChipType == SIS_330) {
+     if(IS_SIS550650740660) {
+        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x07;
+     } else {	/* 315, 330 */
+        data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3a) & 0x03;
+        if(HwInfo->jChipType == SIS_330) {
 	   if(data > 1) {
-	      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
+	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0x30;
 	      switch(temp) {
 	      case 0x00: data = 1; break;
 	      case 0x10: data = 3; break;
@@ -1916,1560 +1275,1211 @@
 
    return data;
 }
-#endif
 
-/* SiSInit END */
-
-/* ----------------------------------------- */
-
-void SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr)
+USHORT
+SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   SiS_Pr->SiS_P3c4 = BaseAddr + 0x14;
-   SiS_Pr->SiS_P3d4 = BaseAddr + 0x24;
-   SiS_Pr->SiS_P3c0 = BaseAddr + 0x10;
-   SiS_Pr->SiS_P3ce = BaseAddr + 0x1e;
-   SiS_Pr->SiS_P3c2 = BaseAddr + 0x12;
-   SiS_Pr->SiS_P3ca = BaseAddr + 0x1a;
-   SiS_Pr->SiS_P3c6 = BaseAddr + 0x16;
-   SiS_Pr->SiS_P3c7 = BaseAddr + 0x17;
-   SiS_Pr->SiS_P3c8 = BaseAddr + 0x18;
-   SiS_Pr->SiS_P3c9 = BaseAddr + 0x19;
-   SiS_Pr->SiS_P3da = BaseAddr + 0x2A;
-   SiS_Pr->SiS_Part1Port = BaseAddr + SIS_CRT2_PORT_04;   /* Digital video interface registers (LCD) */
-   SiS_Pr->SiS_Part2Port = BaseAddr + SIS_CRT2_PORT_10;   /* 301 TV Encoder registers */
-   SiS_Pr->SiS_Part3Port = BaseAddr + SIS_CRT2_PORT_12;   /* 301 Macrovision registers */
-   SiS_Pr->SiS_Part4Port = BaseAddr + SIS_CRT2_PORT_14;   /* 301 VGA2 (and LCD) registers */
-   SiS_Pr->SiS_Part5Port = BaseAddr + SIS_CRT2_PORT_14+2; /* 301 palette address port registers */
-   SiS_Pr->SiS_DDC_Port = BaseAddr + 0x14;                /* DDC Port ( = P3C4, SR11/0A) */
-}
+  USHORT index;
 
-void
-SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-/* #ifdef LINUX_XF86 */
-   if ((HwDeviceExtension->jChipType == SIS_540)||
-       (HwDeviceExtension->jChipType == SIS_630)||
-       (HwDeviceExtension->jChipType == SIS_730)||
-       (HwDeviceExtension->jChipType == SIS_300)) {
-       /* TW: Set - PCI LINEAR ADDRESSING ENABLE (0x80)
-		  - PCI IO ENABLE  (0x20)
-		  - MMIO ENABLE (0x1)
-  	*/
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
-       /* TW: Enable 2D (0x42) & 3D accelerator (0x18) */
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
-   }
-   if((HwDeviceExtension->jChipType == SIS_315H)||
-      (HwDeviceExtension->jChipType == SIS_315) ||
-      (HwDeviceExtension->jChipType == SIS_315PRO)||
-      (HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330)) {
-      /* TW: This seems to be done the same way on these chipsets */
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x20,0xa1);
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1E,0xFF,0x5A);
-   }
-/* #endif */
+  index = SiS_Get310DRAMType(SiS_Pr, HwInfo);
+  if(index >= 4) {
+     index -= 4;
+     return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
+  } else {
+     return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+  }
 }
+#endif
 
-void
-SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+/*********************************************/
+/*           HELPER: ClearBuffer             */
+/*********************************************/
+
+#ifndef LINUX_XF86
+static void
+SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 {
-   ULONG   temp;
+  UCHAR   *VideoMemoryAddress = HwInfo->pjVideoMemoryAddress;
+  ULONG   AdapterMemorySize  = (ULONG)HwInfo->ulVideoMemorySize;
+  USHORT  *pBuffer;
+  int i;
 
-   SiS_Pr->SiS_IF_DEF_LVDS = 0;
-   SiS_Pr->SiS_IF_DEF_TRUMPION = 0;
-   SiS_Pr->SiS_IF_DEF_CH70xx = 0;
-   SiS_Pr->SiS_IF_DEF_HiVision = 0;
-   SiS_Pr->SiS_IF_DEF_DSTN = 0;
-   SiS_Pr->SiS_IF_DEF_FSTN = 0;
+  if(SiS_Pr->SiS_ModeType >= ModeEGA) {
+     if(ModeNo > 0x13) {
+        AdapterMemorySize = GetDRAMSize(SiS_Pr, HwInfo);
+        SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
+     } else {
+        pBuffer = (USHORT *)VideoMemoryAddress;
+        for(i=0; i<0x4000; i++)
+           pBuffer[i] = 0x0000;
+     }
+  } else {
+     pBuffer = (USHORT *)VideoMemoryAddress;
+     if(SiS_Pr->SiS_ModeType < ModeCGA) {
+        for(i=0; i<0x4000; i++)
+           pBuffer[i] = 0x0720;
+     } else {
+        SiS_SetMemory(VideoMemoryAddress,0x8000,0);
+     }
+  }
+}
+#endif
 
-   SiS_Pr->SiS_ChrontelInit = 0;
+/*********************************************/
+/*           HELPER: SearchModeID            */
+/*********************************************/
 
-   if((ModeNo == 0x5a) || (ModeNo == 0x5b)) {
-   	SiS_Pr->SiS_IF_DEF_DSTN = 1;   /* for 550 dstn */
-   	SiS_Pr->SiS_IF_DEF_FSTN = 1;   /* for fstn */
-   }
+BOOLEAN
+SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex)
+{
+   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
 
-#ifdef SIS300
-   if((HwDeviceExtension->jChipType == SIS_540) ||
-      (HwDeviceExtension->jChipType == SIS_630) ||
-      (HwDeviceExtension->jChipType == SIS_730))
-    {
-        /* TW: Check for SiS30x first */
-        temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
-	if((temp == 1) || (temp == 2)) return;
-      	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-      	temp = (temp & 0x0E) >> 1;
-      	if((temp >= 2) && (temp <= 5)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
-      	if(temp == 3)   SiS_Pr->SiS_IF_DEF_TRUMPION = 1;
-      	if((temp == 4) || (temp == 5)) {
-		/* TW: Save power status (and error check) - UNUSED */
-		SiS_Pr->SiS_Backup70xx = SiS_GetCH700x(SiS_Pr, 0x0e);
-		SiS_Pr->SiS_IF_DEF_CH70xx = 1;
-        }
-   }
-#endif
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
-    {
-        /* TW: CR37 is different on 310/325 series */
-        if(SiS_Pr->SiS_IF_DEF_FSTN)                       /* fstn: set CR37=0x04 */
-             SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x04);      /* (fake LVDS bridge) */
+   if(*ModeNo <= 0x13) {
 
-	temp=SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-      	temp = (temp & 0x0E) >> 1;
-      	if((temp >= 2) && (temp <= 3)) SiS_Pr->SiS_IF_DEF_LVDS = 1;
-      	if(temp == 3)  {
-			SiS_Pr->SiS_IF_DEF_CH70xx = 2;
-        }
-	
-	/* HiVision (HDTV) is done differently now. */
-	/* SiS_Pr->SiS_IF_DEF_HiVision = 1; */
-    }
-#endif
-}
+      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
 
-void
-SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#ifdef SIS315H
-   if((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315) ||
-      (HwDeviceExtension->jChipType == SIS_315PRO) ||
-      (HwDeviceExtension->jChipType == SIS_550) ||
-      (HwDeviceExtension->jChipType == SIS_650) ||
-      (HwDeviceExtension->jChipType == SIS_740) ||
-      (HwDeviceExtension->jChipType == SIS_330))
-     InitTo310Pointer(SiS_Pr, HwDeviceExtension);
-#endif
+      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
+         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
+         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
+      }
 
-#ifdef SIS300
-   if ((HwDeviceExtension->jChipType == SIS_540) ||
-       (HwDeviceExtension->jChipType == SIS_630) ||
-       (HwDeviceExtension->jChipType == SIS_730) ||
-       (HwDeviceExtension->jChipType == SIS_300))
-     InitTo300Pointer(SiS_Pr, HwDeviceExtension);
-#endif
-}
+      if(*ModeNo == 0x07) {
+          if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
+          /* else 350 lines */
+      }
+      if(*ModeNo <= 0x03) {
+         if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
+         if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
+         /* else 350 lines  */
+      }
+      /* else 200 lines  */
 
-void
-SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
-{
-   if((ROMAddr) && (HwDeviceExtension->UseROM)) {
-     if((ROMAddr[0x00] != 0x55) || (ROMAddr[0x01] != 0xAA)) {
-        SiS_Pr->SiS_UseROM = FALSE;
-     } else if(HwDeviceExtension->jChipType == SIS_300) {
-        /* TW: 300: We check if the code starts below 0x220 by
-	 *     checking the jmp instruction at the beginning
-	 *     of the BIOS image.
-	 */
-	 if((ROMAddr[3] == 0xe9) &&
-	    ((ROMAddr[5] << 8) | ROMAddr[4]) > 0x21a)
-	      SiS_Pr->SiS_UseROM = TRUE;
-	 else SiS_Pr->SiS_UseROM = FALSE;
-     } else if(HwDeviceExtension->jChipType < SIS_315H) {
-        /* TW: Rest of 300 series: We don't use the ROM image if
-	 *     the BIOS version < 2.0.0 as such old BIOSes don't
-	 *     have the needed data at the expected locations.
-	 */
-        if(ROMAddr[0x06] < '2')  SiS_Pr->SiS_UseROM = FALSE;
-	else                     SiS_Pr->SiS_UseROM = TRUE;
-     } else {
-        /* TW: 310/325/330 series stick to the standard */
-	SiS_Pr->SiS_UseROM = TRUE;
-     }
-   } else SiS_Pr->SiS_UseROM = FALSE;
+   } else {
+
+      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
+         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
+         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)      return FALSE;
+      }
 
+   }
+   return TRUE;
 }
 
-/*
- 	=========================================
- 	======== SiS SetMode Functions ==========
- 	=========================================
-*/
-#ifdef LINUX_XF86
-/* TW: This is used for non-Dual-Head mode from X */
-BOOLEAN
-SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom)
+/*********************************************/
+/*            HELPER: GetModePtr             */
+/*********************************************/
+
+UCHAR
+SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
 {
-   SISPtr  pSiS = SISPTR(pScrn);
-   UShort  ModeNo=0;
-   
-   SiS_Pr->UseCustomMode = FALSE;
+   UCHAR index;
 
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-   
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n", 
-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
-		
-	 return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));
-   
+   if(ModeNo <= 0x13) {
+     	index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
+   } else {
+     	if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B;    /* 02 -> ModeEGA  */
+     	else index = 0x0F;
    }
-   
-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if(!ModeNo) return FALSE;
+   return index;
+}
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting mode 0x%x\n", ModeNo);
+/*********************************************/
+/*           HELPER: LowModeTests            */
+/*********************************************/
 
-   return(SiSSetMode(SiS_Pr, HwDeviceExtension, pScrn, ModeNo, TRUE));   
+BOOLEAN
+SiS_LowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
+{
+    USHORT temp,temp1,temp2;
+
+    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
+       return(1);
+    temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x11);
+    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
+    temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,0x55);
+    temp2 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x00);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,temp1);
+    SiS_SetReg(SiS_Pr->SiS_P3d4,0x11,temp);
+    if((HwInfo->jChipType >= SIS_315H) ||
+       (HwInfo->jChipType == SIS_300)) {
+       if(temp2 == 0x55) return(0);
+       else return(1);
+    } else {
+       if(temp2 != 0x55) return(1);
+       else {
+          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+          return(0);
+       }
+    }
 }
 
-#ifdef SISDUALHEAD
-/* TW: Set CRT1 mode (used for dual head) */
-BOOLEAN
-SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode, BOOLEAN IsCustom)
+/*********************************************/
+/*           HELPER: GetColorDepth           */
+/*********************************************/
+
+USHORT
+SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex)
 {
-   ULONG   temp;
-   USHORT  ModeIdIndex;
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   SISPtr  pSiS = SISPTR(pScrn);
-   SISEntPtr pSiSEnt = pSiS->entityPrivate;
-   unsigned char backupreg=0;
-   BOOLEAN backupcustom;
+  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
+  SHORT  index;
+  USHORT modeflag;
 
-   UShort  ModeNo=0;
-   
-   SiS_Pr->UseCustomMode = FALSE;
-   
-   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
-   
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting custom mode %dx%d in CRT1\n", 
-	 	SiS_Pr->CHDisplay, SiS_Pr->CVDisplay);
-	 ModeNo = 0xfe;
-	 
-   } else {
+  /* Do NOT check UseCustomMode, will skrew up FIFO */
+  if(ModeNo == 0xfe) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     if(ModeNo <= 0x13)
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     else
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
 
-         ModeNo = SiS_CalcModeIndex(pScrn, mode);
-         if(!ModeNo) return FALSE;
+  index = (modeflag & ModeInfoFlag) - ModeEGA;
+  if(index < 0) index = 0;
+  return(ColorDepth[index]);
+}
 
-         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-	 	"Setting mode 0x%x on CRT1\n", ModeNo);
-   }
+/*********************************************/
+/*             HELPER: GetOffset             */
+/*********************************************/
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+USHORT
+SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,colordepth;
+  USHORT modeinfo,index,infoflag;
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
+     temp = SiS_Pr->CHDisplay / 16;
+  } else {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+     modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
+     index = (modeinfo >> 8) & 0x00FF;
+     temp = SiS_Pr->SiS_ScreenOffset[index];
+  }
 
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+  colordepth = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+  if(infoflag & InterlaceMode) temp <<= 1;
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+  temp *= colordepth;
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) ||
+        ModeNo == 0x3f ||
+	ModeNo == 0x42 ||
+	ModeNo == 0x45 ) ||
+      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
+     colordepth >>= 1;
+     temp += colordepth;
+  }
 
-   /* TW: We don't clear the buffer under X */
-   SiS_Pr->SiS_flag_clearbuffer = 0;
+  return(temp);
+}
 
-   /* 1.Openkey */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+/*********************************************/
+/*                   SEQ                     */
+/*********************************************/
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+static void
+SiS_SetSeqRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+   UCHAR SRdata;
+   USHORT i;
 
-   if(!SiS_Pr->UseCustomMode) {
-      /* 2.Get ModeID Table  */
-      temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-      if(temp == 0)  return(0);
-   } else {
-      ModeIdIndex = 0;
-   }
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);           	/* Set SR0  */
 
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
 
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-      } else {
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         SRdata |= 0x01;
+      }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+               SRdata |= 0x01;          		/* 8 dot clock  */
+            }
+	 }
       }
    }
-
-   /* TW: Get VB information (connectors, connected devices) */
-   /* (We don't care if the current mode is a CRT2 mode) */
-   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,0);
-   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+            if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+               SRdata |= 0x01;        			/* 8 dot clock  */
+            }
          }
       }
-
-      /* TW: New from 650/LV 1.10.6x */
-      if(IS_SIS650) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	  }
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+            SRdata |= 0x01;          			/* 8 dot clock  */
+         }
       }
    }
 
-   /* TW: Set mode on CRT1 */
-   SiS_SetCRT1Group(SiS_Pr, ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
-
-   pSiSEnt->CRT1ModeNo = ModeNo;
-   pSiSEnt->CRT1DMode = mode;
-
-   /* TW: SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
-
-   /* We have to reset CRT2 if changing mode on CRT1 */
-   if(pSiSEnt->CRT2ModeNo != -1) {
-        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-				"(Re-)Setting mode 0x%x on CRT2\n",
-				pSiSEnt->CRT2ModeNo);
-	backupcustom = SiS_Pr->UseCustomMode;
-	if(SiS_Pr->UseCustomMode) {
-	   SiS_Pr->CRT1UsesCustomMode = TRUE;
-	} else {
-	   SiS_Pr->CRT1UsesCustomMode = FALSE;
-	}
-	SiSBIOSSetModeCRT2(SiS_Pr, HwDeviceExtension, pSiSEnt->pScrn_1,
-				pSiSEnt->CRT2DMode);
-	SiS_Pr->UseCustomMode = backupcustom;
-	SiS_Pr->CRT1UsesCustomMode = FALSE;
+   SRdata |= 0x20;                			/* screen off  */
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x01,SRdata);
+
+   for(i = 2; i <= 4; i++) {
+      SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
+      SiS_SetReg(SiS_Pr->SiS_P3c4,i,SRdata);
    }
-   
-   SiS_HandleCRT1(SiS_Pr);
+}
 
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+/*********************************************/
+/*                  MISC                     */
+/*********************************************/
+
+static void
+SiS_SetMiscRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+   UCHAR Miscdata;
+
+   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630/301B 2.06.50 */
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
-      } else if((HwDeviceExtension->jChipType == SIS_630) ||
-                (HwDeviceExtension->jChipType == SIS_730)) {
-         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+         Miscdata |= 0x0C;
       }
    }
 
-   /* Backup/Set ModeNo in BIOS scratch area */
-   SiS_GetSetModeID(pScrn,ModeNo);
-
-   return TRUE;
+   SiS_SetRegByte(SiS_Pr->SiS_P3c2,Miscdata);
 }
 
-/* TW: Set CRT2 mode (used for dual head) */
-BOOLEAN
-SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, ScrnInfoPtr pScrn,
-               DisplayModePtr mode)
+/*********************************************/
+/*                  CRTC                     */
+/*********************************************/
+
+static void
+SiS_SetCRTCRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                USHORT StandTableIndex)
 {
-   ULONG   temp;
-   USHORT  ModeIdIndex;
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   UShort  ModeNo   = 0;
-   SISPtr  pSiS     = SISPTR(pScrn);
-   SISEntPtr pSiSEnt = pSiS->entityPrivate;
-   unsigned char tempr1, tempr2, backupreg=0;
-   
-   SiS_Pr->UseCustomMode = FALSE;
-   
-   ModeNo = SiS_CalcModeIndex(pScrn, mode);
-   if(!ModeNo) return FALSE;
+  UCHAR CRTCdata;
+  USHORT i;
 
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+  for(i = 0; i <= 0x18; i++) {
+     CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
+     SiS_SetReg(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
+  }
+  if( ( (HwInfo->jChipType == SIS_630) ||
+        (HwInfo->jChipType == SIS_730) )  &&
+      (HwInfo->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
+           SiS_SetReg(SiS_Pr->SiS_P3d4,0x18,0xFE);
+        }
+     }
+  }
+}
 
-   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+/*********************************************/
+/*                   ATT                     */
+/*********************************************/
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+static void
+SiS_SetATTRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex,
+               PSIS_HW_INFO HwInfo)
+{
+   UCHAR ARdata;
+   USHORT i;
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+   for(i = 0; i <= 0x13; i++) {
+      ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
+#if 0
+      if((i <= 0x0f) || (i == 0x11)) {
+         if(ds:489 & 0x08) {
+	    continue;
+         }
+      }
+#endif
+      if(i == 0x13) {
+         /* Pixel shift. If screen on LCD or TV is shifted left or right,
+          * this might be the cause.
+          */
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
+         }
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+               if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+                  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+               }
+            }
+         }
+         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+            if(HwInfo->jChipType >= SIS_315H) {
+	       if(IS_SIS550650740660) {
+	          /* 315, 330 don't do this */
+	          if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	             if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
+	          } else {
+	             ARdata = 0;
+	          }
+	       }
+	    } else {
+               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  ARdata=0;
+	    }
+         }
+      }
+      SiS_GetRegByte(SiS_Pr->SiS_P3da);                         /* reset 3da  */
+      SiS_SetRegByte(SiS_Pr->SiS_P3c0,i);                       /* set index  */
+      SiS_SetRegByte(SiS_Pr->SiS_P3c0,ARdata);                  /* set data   */
+   }
+   SiS_GetRegByte(SiS_Pr->SiS_P3da);                            /* reset 3da  */
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x14);                       /* set index  */
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x00);                       /* set data   */
+
+   SiS_GetRegByte(SiS_Pr->SiS_P3da);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c0,0x20);			/* Enable Attribute  */
+   SiS_GetRegByte(SiS_Pr->SiS_P3da);
+}
+
+/*********************************************/
+/*                   GRC                     */
+/*********************************************/
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+static void
+SiS_SetGRCRegs(SiS_Private *SiS_Pr, USHORT StandTableIndex)
+{
+   UCHAR GRdata;
+   USHORT i;
 
-   /* TW: We don't clear the buffer under X */
-   SiS_Pr->SiS_flag_clearbuffer=0;
+   for(i = 0; i <= 0x08; i++) {
+      GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
+      SiS_SetReg(SiS_Pr->SiS_P3ce,i,GRdata);
+   }
 
-   /* TW: Save ModeNo so we can set it from within SetMode for CRT1 */
-   pSiSEnt->CRT2ModeNo = ModeNo;
-   pSiSEnt->CRT2DMode = mode;
-
-   /* TW: We can't set CRT2 mode before CRT1 mode is set */
-   if(pSiSEnt->CRT1ModeNo == -1) {
-   	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
-   	return TRUE;
+   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+      /* 256 color disable */
+      SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);
    }
+}
 
-   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
-   		"Setting mode 0x%x on CRT2\n", ModeNo);
+/*********************************************/
+/*          CLEAR EXTENDED REGISTERS         */
+/*********************************************/
 
-   /* 1.Openkey */
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+static void
+SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT i;
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+  for(i = 0x0A; i <= 0x0E; i++) {
+     SiS_SetReg(SiS_Pr->SiS_P3c4,i,0x00);
+  }
 
-   /* 2.Get ModeID */
-   temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&ModeNo,&ModeIdIndex);
-   if(temp == 0)  return(0);
+  if(HwInfo->jChipType >= SIS_315H) {
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+  }
+}
 
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(SiS_Pr, BaseAddr,HwDeviceExtension);
+/*********************************************/
+/*                 RESET VCLK                */
+/*********************************************/
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-	 if(HwDeviceExtension->jChipType < SIS_330) {
-           if(ROMAddr && SiS_Pr->SiS_UseROM) {
-             temp = ROMAddr[VB310Data_1_2_Offset];
-	     temp |= 0x40;
-             SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
-           }
-	 }
-	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
-
-	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
-
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-      } else {
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+static void
+SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 0) return;
+   } else {
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
+         (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+	 return;
       }
    }
 
-   /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo(SiS_Pr, BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-   SiS_SetHiVision(SiS_Pr, BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         }
-      }
+   if(HwInfo->jChipType >= SIS_315H) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
+   } else {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
    }
-
-   /* Set mode on CRT2 */
-   switch (HwDeviceExtension->ujVBChipID) {
-     case VB_CHIP_301:
-     case VB_CHIP_301B:
-     case VB_CHIP_301LV:
-     case VB_CHIP_302:
-     case VB_CHIP_302B:
-     case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
-     case VB_CHIP_UNKNOWN:
-        if (SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
-	    SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
-	    SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-  	}
-        break;
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[1].SR2B);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[1].SR2C);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
+   if(HwInfo->jChipType >= SIS_315H) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
+   } else {
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
    }
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[0].SR2B);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[0].SR2C);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
+}
 
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+/*********************************************/
+/*                  SYNC                     */
+/*********************************************/
 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
-	     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
-	 }
-      }
-   }
+static void
+SiS_SetCRT1Sync(SiS_Private *SiS_Pr, USHORT RefreshRateTableIndex)
+{
+  USHORT sync;
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w, 630 2.06.50 */
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-	 } else {
-	     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
-	 }
+  if(SiS_Pr->UseCustomMode) {
+     sync = SiS_Pr->CInfoFlag >> 8;
+  } else {
+     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
+  }
 
-	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+  sync &= 0xC0;
+  sync |= 0x2f;
+  SiS_SetRegByte(SiS_Pr->SiS_P3c2,sync);
+}
 
-	 tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-	 tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
-	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
-	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
-	 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+/*********************************************/
+/*                  CRTC/2                   */
+/*********************************************/
 
-	 if(tempr1 & SetCRT2ToLCD) {
-	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
-	 }
-      } else if((HwDeviceExtension->jChipType == SIS_630) ||
-                (HwDeviceExtension->jChipType == SIS_730)) {
-         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
-      }
-   }
+#ifdef SIS315H
+static void
+SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex, USHORT *ResIndex,
+		   USHORT *DisplayType)
+ {
+  USHORT modeflag = 0;
 
-   /* TW: SetPitch: Adapt to virtual size & position */
-   SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     *ResIndex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     *ResIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
 
-   return TRUE;
-}
-#endif /* Dualhead */
-#endif /* Linux_XF86 */
+  *ResIndex &= 0x3F;
 
-#ifdef LINUX_XF86
-/* TW: We need pScrn for setting the pitch correctly */
-BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
-#else
-BOOLEAN
-SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
+  *DisplayType = SiS_Pr->SiS_LCDResInfo;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) *DisplayType += 32;
+  if(modeflag & HalfDCLK)                 *DisplayType += 16;
+}
 #endif
-{
-   ULONG   temp;
-   USHORT  ModeIdIndex,KeepLockReg;
-   UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-   USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-   unsigned char backupreg=0, tempr1, tempr2;
 
-#ifndef LINUX_XF86
-   SiS_Pr->UseCustomMode = FALSE;
-   SiS_Pr->CRT1UsesCustomMode = FALSE;
+static void
+SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex,
+		PSIS_HW_INFO HwInfo)
+{
+  UCHAR  index;
+  USHORT tempah,i,modeflag,j;
+#ifdef SIS315H
+  USHORT ResIndex,DisplayType;
+  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
 #endif
-   
-   if(SiS_Pr->UseCustomMode) {
-      ModeNo = 0xfe;
-   }      
-   
-   SiSInitPtr(SiS_Pr, HwDeviceExtension);
 
-   SiSRegInit(SiS_Pr, BaseAddr);
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
 
-#ifdef LINUX_XF86
-   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
-   else
-#endif
-         SiS_Pr->SiS_VGAINFO = 0x11;
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }
 
-#ifdef LINUX_XF86
-#ifdef TWDEBUG
-   xf86DrvMsg(0, X_INFO, "VGAInfo 0x%02x\n", SiS_Pr->SiS_VGAINFO);
-#endif
-#endif	 	 
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-   SiSInitPCIetc(SiS_Pr, HwDeviceExtension);
+#ifdef SIS315H
 
-   SiSSetLVDSetc(SiS_Pr, HwDeviceExtension, ModeNo);
+     /* LCDA */
 
-   SiSDetermineROMUsage(SiS_Pr, HwDeviceExtension, ROMAddr);
+     SiS_GetLCDACRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                        &ResIndex, &DisplayType);
 
-   if(!SiS_Pr->UseCustomMode) {
-      /* TW: Shift the clear-buffer-bit away */
-      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
-   }      
+     switch(DisplayType) {
+      case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
+      case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;    break;
+      case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;    break;
+      case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;    break;
+      case Panel_1024x768  + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;   break;
+      case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;  break;
+      case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;  break;
+      case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;  break;
+      case Panel_1024x768  + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;     break;
+      case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
+      case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;    break;
+      case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;    break;
+      case Panel_1024x768  + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;   break;
+      case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
+      case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;  break;
+      case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;  break;
+      default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
+     }
 
-#ifdef LINUX_XF86
-   /* TW: We never clear the buffer in X */
-   ModeNo |= 0x8000;
-#endif
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[0];
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
+     for(i=0x01,j=1;i<=0x07;i++,j++){
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+       SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
+     }
+     for(i=0x10,j=8;i<=0x12;i++,j++){
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+       SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
+     }
+     for(i=0x15,j=11;i<=0x16;i++,j++){
+       tempah =(LCDACRT1Ptr+ResIndex)->CR[j];
+       SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
+     }
+     for(i=0x0A,j=13;i<=0x0C;i++,j++){
+       tempah = (LCDACRT1Ptr+ResIndex)->CR[j];
+       SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
+     }
 
-   if(ModeNo & 0x8000) {
-     	ModeNo &= 0x7fff;
-     	SiS_Pr->SiS_flag_clearbuffer = 0;
-   } else {
-     	SiS_Pr->SiS_flag_clearbuffer = 1;
-   }
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16] & 0xE0;
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,tempah);
 
-   /* 1.Openkey */
-   KeepLockReg = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
+     tempah = (LCDACRT1Ptr+ResIndex)->CR[16];
+     tempah &= 0x01;
+     tempah <<= 5;
+     if(modeflag & DoubleScanMode)  tempah |= 0x080;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+#endif
 
-   if(!SiS_Pr->UseCustomMode) {
-   
-      /* 2.Get ModeID Table  */
-      temp = SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
-      if(temp == 0) return(0);
-      
-   } else {
-   
-      ModeIdIndex = 0;
-      
-   }
-    
-   /* TW: Determine VBType (301,301B,301LV,302B,302LV) */
-   SiS_GetVBType(SiS_Pr,BaseAddr,HwDeviceExtension);
+  } else {
 
-   /* TW: Init/restore some VB registers */
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
-         SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-	 if(HwDeviceExtension->jChipType < SIS_330) {
-           if(ROMAddr && SiS_Pr->SiS_UseROM) {
-             temp = ROMAddr[VB310Data_1_2_Offset];
-	     temp |= 0x40;
-             SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,temp);
-           }
-	 }
-	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
+     if(SiS_Pr->UseCustomMode) {
 
-	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+        for(i=0,j=0;i<=07;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x10;i<=10;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x15;i<=12;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
+        for(j=0x0A;i<=15;i++,j++) {
+          SiS_SetReg(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
+        }
 
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-       } else {
-         backupreg = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-       }
-   }
-   
-   /* TW: Get VB information (connectors, connected devices) */
-   SiS_GetVBInfo(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,1);
-   SiS_SetHiVision(SiS_Pr,BaseAddr,HwDeviceExtension);
-   SiS_GetLCDResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+        tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0;
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,tempah);
 
-   /* 3. Check memory size */
-   temp = SiS_CheckMemorySize(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex);
-   if(!temp) return(0);
+        tempah = SiS_Pr->CCRT1CRTC[16];
+        tempah &= 0x01;
+        tempah <<= 5;
+        if(modeflag & DoubleScanMode)  tempah |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
-            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
-         }
-      }
 
-      /* TW: New from 650/LV 1.10.6x; not in any BIOS for other chipsets */
-      if(IS_SIS650) {
-          if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
-	  }
-      }
-   }
+     } else {
 
-   /* TW: Set mode on CRT1 */
-   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) {
-   	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
-   } else {
-     if(!(SiS_Pr->SiS_VBInfo & SwitchToCRT2)) {
-       	SiS_SetCRT1Group(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,BaseAddr);
-     }
-   }
+        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
 
-   /* TW: Set mode on CRT2 */
-   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA)) {
-     switch (HwDeviceExtension->ujVBChipID) {
-     case VB_CHIP_301:
-     case VB_CHIP_301B:
-     case VB_CHIP_301LV:
-     case VB_CHIP_302:
-     case VB_CHIP_302B:
-     case VB_CHIP_302LV:
-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
-     case VB_CHIP_UNKNOWN:
-	if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
-	   SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
-	   SiS_Pr->SiS_IF_DEF_TRUMPION != 0)
-             	SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,HwDeviceExtension);
-        break;
-     }
-   }
-   
-   SiS_HandleCRT1(SiS_Pr);
-   
-   SiS_DisplayOn(SiS_Pr);
-   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
+        for(i=0,j=0;i<=07;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x10;i<=10;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x15;i<=12;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg(SiS_Pr->SiS_P3d4,j,tempah);
+        }
+        for(j=0x0A;i<=15;i++,j++) {
+          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
+          SiS_SetReg(SiS_Pr->SiS_P3c4,j,tempah);
+        }
 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))) {
-	     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
-	 }
-      }
-   }
+        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+        tempah &= 0xE0;
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x0E,tempah);
 
-   /* TW: New from 650/LV 1.10.6x and 1.10.7w */
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	 if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-	 } else {
-	     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
-	 }
+        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
+        tempah &= 0x01;
+        tempah <<= 5;
+        if(modeflag & DoubleScanMode)  tempah |= 0x80;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
 
-	 SiS_SetReg1(SiS_Pr->SiS_P3d4,0x38,backupreg);
+     }
+  }
 
-	 tempr1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-	 tempr2 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
-	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
-	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
-	 SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg(SiS_Pr->SiS_P3d4,0x14,0x4F);
+}
 
-	 if((IS_SIS650) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
-	    if((ModeNo == 0x03) || (ModeNo == 0x10)) {
-	        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
-	        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
-            }
-	 }
+/*********************************************/
+/*               OFFSET & PITCH              */
+/*********************************************/
+/*  (partly overruled by SetPitch() in XF86) */
+/*********************************************/
 
-	 if(tempr1 & SetCRT2ToLCD) {
-	       SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
-	 }
-      } else if((HwDeviceExtension->jChipType == SIS_630) ||
-                (HwDeviceExtension->jChipType == SIS_730)) {
-         SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,backupreg);
-      }
+static void
+SiS_SetCRT1Offset(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex,
+		  PSIS_HW_INFO HwInfo)
+{
+   USHORT temp, DisplayUnit, infoflag;
+
+   if(SiS_Pr->UseCustomMode) {
+      infoflag = SiS_Pr->CInfoFlag;
+   } else {
+      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
    }
 
-#ifdef LINUX_XF86
-   if(pScrn) {
-      /* TW: SetPitch: Adapt to virtual size & position */
-      if((ModeNo > 0x13) && (dosetpitch)) {
-         SiS_SetPitch(SiS_Pr, pScrn, BaseAddr);
-      }
+   DisplayUnit = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
+                     	       RefreshRateTableIndex,HwInfo);
 
-      /* Backup/Set ModeNo in BIOS scratch area */
-      SiS_GetSetModeID(pScrn, ModeNo);
-   }
-#endif
+   temp = (DisplayUnit >> 8) & 0x0f;
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
 
-#ifndef LINUX_XF86  /* TW: We never lock registers in XF86 */
-   if(KeepLockReg == 0xA1) SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-   else SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x00);
-#endif
+   temp = DisplayUnit & 0xFF;
+   SiS_SetReg(SiS_Pr->SiS_P3d4,0x13,temp);
 
-   return TRUE;
-}
+   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
 
-void
-SiS_SetEnableDstn(SiS_Private *SiS_Pr)	/* TW: Called from sis_main.c */
-{
-   /* For 550 dstn */
-   SiS_Pr->SiS_IF_DEF_DSTN = 1;
+   DisplayUnit <<= 5;
+   temp = (DisplayUnit & 0xff00) >> 8;
+   if (DisplayUnit & 0xff) temp++;
+   temp++;
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x10,temp);
 }
 
-void
-SiS_HandleCRT1(SiS_Private *SiS_Pr)
-{
-  /* TW: We don't do this at all. There is a new
-   * CRT1-is-connected-at-boot-time logic in the 650 BIOS, which
-   * confuses our own. So just clear the bit and skip the rest.
-   */
+/*********************************************/
+/*                  VCLK                     */
+/*********************************************/
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+static void
+SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+{
+  USHORT  index=0;
 
-#if 0
-  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x15) & 0x01))
-     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+  if(!SiS_Pr->UseCustomMode) {
+     index = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+	                     RefreshRateTableIndex, HwInfo);
   }
-#endif
-}
 
-void
-SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                 USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr)
-{
-  USHORT  StandTableIndex,RefreshRateTableIndex;
+  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-  SiS_Pr->SiS_CRT1Mode = ModeNo;
-  StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-  if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-    if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2)) {
-       SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
-    }
-  }
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
 
-  SiS_SetSeqRegs(SiS_Pr,ROMAddr,StandTableIndex);
-  SiS_SetMiscRegs(SiS_Pr,ROMAddr,StandTableIndex);
-  SiS_SetCRTCRegs(SiS_Pr,ROMAddr,HwDeviceExtension,StandTableIndex);
-  SiS_SetATTRegs(SiS_Pr,ROMAddr,StandTableIndex,HwDeviceExtension);
-  SiS_SetGRCRegs(SiS_Pr,ROMAddr,StandTableIndex);
-  SiS_ClearExt1Regs(SiS_Pr,HwDeviceExtension);
-  SiS_ResetCRT1VCLK(SiS_Pr,ROMAddr,HwDeviceExtension);
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
 
-  SiS_Pr->SiS_SelectCRT2Rate = 0;
-  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
 
-#ifdef LINUX_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 3, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
-                    SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
-#endif
+  } else {
 
-  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
-     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     if(HwInfo->jChipType >= SIS_315H) {
+	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
+     } else {
+	SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
      }
-  }
-
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  }
 
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+     if(SiS_Pr->UseCustomMode) {
+	SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->CSR2B);
+	SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->CSR2C);
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
+     }
 
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-	SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+     if(HwInfo->jChipType >= SIS_315H) {
+	SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x01);
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x2D,0x80);
+     }
   }
+}
 
-  if(RefreshRateTableIndex != 0xFFFF) {
-    	SiS_SetSync(SiS_Pr,ROMAddr,RefreshRateTableIndex);
-    	SiS_SetCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-    	SiS_SetCRT1Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,HwDeviceExtension);
-    	SiS_SetCRT1VCLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension,RefreshRateTableIndex);
-  }
+/*********************************************/
+/*                  FIFO                     */
+/*********************************************/
 
 #ifdef SIS300
-  if(HwDeviceExtension->jChipType == SIS_300) {
-     	SiS_SetCRT1FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
-  }
-  if((HwDeviceExtension->jChipType == SIS_630) ||
-     (HwDeviceExtension->jChipType == SIS_730) ||
-     (HwDeviceExtension->jChipType == SIS_540)) {
-     	SiS_SetCRT1FIFO_630(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension,RefreshRateTableIndex);
-  }
-#endif
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     	SiS_SetCRT1FIFO_310(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-  }
-#endif
+static USHORT
+SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
+{
+  const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
+                             43, 3,42, 5,54, 7, 78,11,
+                             34, 3,37, 5,47, 7, 67,11 };
 
-  SiS_SetCRT1ModeRegs(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,ModeIdIndex,RefreshRateTableIndex);
+  const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
+                             55, 4,54, 6,66, 8, 90,12,
+                             42, 4,45, 6,55, 8, 75,12 };
 
-  SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
 
-#ifndef LINUX_XF86
-  if(SiS_Pr->SiS_flag_clearbuffer) {
-        SiS_ClearBuffer(SiS_Pr,HwDeviceExtension,ModeNo);
-  }
-#endif
+  USHORT tempah, tempal, tempcl, tempbx, temp;
+  ULONG  longtemp;
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2 | SetCRT2ToLCDA))) {
-        SiS_LongWait(SiS_Pr);
-        SiS_DisplayOn(SiS_Pr);
+  tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
+  tempah &= 0x62;
+  tempah >>= 1;
+  tempal = tempah;
+  tempah >>= 3;
+  tempal |= tempah;
+  tempal &= 0x07;
+  tempcl = ThTiming[tempal];
+  tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
+  tempbx >>= 6;
+  tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+  tempah >>= 4;
+  tempah &= 0x0c;
+  tempbx |= tempah;
+  tempbx <<= 1;
+  if(key == 0) {
+     tempal = ThLowA[tempbx + 1];
+     tempal *= tempcl;
+     tempal += ThLowA[tempbx];
+  } else {
+     tempal = ThLowB[tempbx + 1];
+     tempal *= tempcl;
+     tempal += ThLowB[tempbx];
   }
+  longtemp = tempal * VCLK * colordepth;
+  temp = longtemp % (MCLK * 16);
+  longtemp /= (MCLK * 16);
+  if(temp) longtemp++;
+  return((USHORT)longtemp);
 }
 
-#ifdef LINUX_XF86
-void
-SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+static USHORT
+SiS_CalcDelay(SiS_Private *SiS_Pr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
 {
-   SISPtr pSiS = SISPTR(pScrn);
+  USHORT tempax, tempbx;
 
-   /* TW: We need to set pitch for CRT1 if bridge is in SlaveMode, too */
-   if( (pSiS->VBFlags & DISPTYPE_DISP1) ||
-       ( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
-         ( ((pSiS->VGAEngine == SIS_300_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
-           ((pSiS->VGAEngine == SIS_315_VGA) && (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) ) {
-   	SiS_SetPitchCRT1(SiS_Pr, pScrn, BaseAddr);
-   }
-   if (pSiS->VBFlags & DISPTYPE_DISP2) {
-   	SiS_SetPitchCRT2(SiS_Pr, pScrn, BaseAddr);
-   }
+  tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
+  tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
+  if(tempax < 4) tempax = 4;
+  tempax -= 4;
+  if(tempbx < tempax) tempbx = tempax;
+  return(tempbx);
 }
 
-void
-SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
+static void
+SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo,
+                    USHORT RefreshRateTableIndex)
 {
-    SISPtr pSiS = SISPTR(pScrn);
-    ULong  HDisplay,temp;
-
-    HDisplay = pSiS->scrnPitch / 8;
-    SiS_SetReg1(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
-    temp = (SiS_GetReg1(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
-    SiS_SetReg1(SiS_Pr->SiS_P3c4, 0x0E, temp);
-}
+  USHORT  ThresholdLow = 0;
+  USHORT  index, VCLK, MCLK, colorth=0;
+  USHORT  tempah, temp;
 
-void
-SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr)
-{
-    SISPtr pSiS = SISPTR(pScrn);
-    ULong  HDisplay,temp;
+  if(ModeNo > 0x13) {
 
-    HDisplay = pSiS->scrnPitch / 8;
+     if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+     } else {
+        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+        index &= 0x3F;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
+     }
 
-    /* Unlock CRT2 */
-    if (pSiS->VGAEngine == SIS_315_VGA)
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
-    else
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
+     switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
+        case 0 : colorth = 1; break;
+        case 1 : colorth = 1; break;
+        case 2 : colorth = 2; break;
+        case 3 : colorth = 2; break;
+        case 4 : colorth = 3; break;
+        case 5 : colorth = 4; break;
+     }
 
-    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
-    temp = (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
-    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09, temp);
-}
-#endif
+     index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
+     index &= 0x07;
+     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
 
-void
-SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag=0, rev=0, nolcd=0;
+     tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+     tempah &= 0xc3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
 
-  SiS_Pr->SiS_VBType = 0;
+     do {
+        ThresholdLow = SiS_CalcDelay(SiS_Pr, VCLK, colorth, MCLK);
+        ThresholdLow++;
+        if(ThresholdLow < 0x13) break;
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
+        ThresholdLow = 0x13;
+        tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
+        tempah >>= 6;
+        if(!(tempah)) break;
+        tempah--;
+        tempah <<= 6;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
+     } while(0);
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) return;
+  } else ThresholdLow = 2;
 
-  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
+  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+  temp = (ThresholdLow << 4) | 0x0f;
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,temp);
 
-  /* TW: Illegal values not welcome... */
-  if(flag > 3) return;
+  temp = (ThresholdLow & 0x10) << 1;
+  if(ModeNo > 0x13) temp |= 0x40;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
 
-  rev = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
+  /* What is this? */
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-  if (flag >= 2) {
-        SiS_Pr->SiS_VBType = VB_SIS302B;
-  } else if (flag == 1) {
-        SiS_Pr->SiS_VBType = VB_SIS301;
-        if(rev >= 0xB0) {
-            	SiS_Pr->SiS_VBType = VB_SIS301B;
-		/* Check if 30xB DH version (no LCD support, use Panel Link instead) */
-    		nolcd = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x23);
-                if(!(nolcd & 0x02)) SiS_Pr->SiS_VBType |= VB_NoLCD;
-        }
-  }
-  if(SiS_Pr->SiS_VBType & (VB_SIS301B | VB_SIS302B)) {
-        if(rev >= 0xD0) {
-	        SiS_Pr->SiS_VBType &= ~(VB_SIS301B | VB_SIS302B);
-          	SiS_Pr->SiS_VBType |= VB_SIS301LV;
-		SiS_Pr->SiS_VBType &= ~(VB_NoLCD);
-		if(rev >= 0xE0) {
-		    SiS_Pr->SiS_VBType &= ~(VB_SIS301LV);
-		    SiS_Pr->SiS_VBType |= VB_SIS302LV;
-		}
-        }
-  }
+  /* Write CRT/CPU threshold high */
+  temp = ThresholdLow + 3;
+  if(temp > 0x0f) temp = 0x0f;
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x09,temp);
 }
 
-BOOLEAN
-SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT *ModeNo,USHORT *ModeIdIndex)
+static USHORT
+SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR key, PSIS_HW_INFO HwInfo)
 {
-   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
-
-   if(*ModeNo <= 0x13) {
-
-      if((*ModeNo) <= 0x05) (*ModeNo) |= 0x01;
+  USHORT data,index;
+  const UCHAR  LatencyFactor[] = {
+   	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
+  };
+  const UCHAR  LatencyFactor730[] = {
+         69, 63, 61,
+	 86, 79, 77,
+	103, 96, 94,
+	120,113,111,
+	137,130,128,    /* --- Table ends with this entry, data below */
+	137,130,128,	/* to avoid using illegal values              */
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+  };
 
-      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
-         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == (*ModeNo)) break;
-         if(SiS_Pr->SiS_SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)   return FALSE;
-      }
+  if(HwInfo->jChipType == SIS_730) {
+     index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
+     data = LatencyFactor730[index];
+  } else {
+     index = (key & 0xE0) >> 5;
+     if(key & 0x10) index +=6;
+     if(!(key & 0x01)) index += 24;
+     data = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+     if(data & 0x0080) index += 12;
+     data = LatencyFactor[index];
+  }
+  return(data);
+}
 
-      if(*ModeNo == 0x07) {
-          if(VGAINFO & 0x10) (*ModeIdIndex)++;   /* 400 lines */
-          /* else 350 lines */
-      }
-      if(*ModeNo <= 0x03) {
-         if(!(VGAINFO & 0x80)) (*ModeIdIndex)++;
-         if(VGAINFO & 0x10)    (*ModeIdIndex)++; /* 400 lines  */
-         /* else 350 lines  */
-      }
-      /* else 200 lines  */
-
-   } else {
-
-      for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) {
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) break;
-         if(SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)      return FALSE;
-      }
-
-   }
-   return TRUE;
-}
-
-/* For SiS 300 oem util: Search VBModeID */
-BOOLEAN
-SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo)
-{
-   USHORT ModeIdIndex;
-   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
-
-   if(*ModeNo <= 5) *ModeNo |= 1;
-
-   for(ModeIdIndex=0; ; ModeIdIndex++) {
-        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
-        if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return FALSE;
-   }
-
-   if(*ModeNo != 0x07) {
-        if(*ModeNo > 0x03) return ((BOOLEAN)ModeIdIndex);
-	if(VGAINFO & 0x80) return ((BOOLEAN)ModeIdIndex);
-	ModeIdIndex++;
-   }
-   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
-	                               /* else 350 lines */
-   return ((BOOLEAN)ModeIdIndex);
-}
-
-BOOLEAN
-SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT ModeNo,USHORT ModeIdIndex)
-{
-  USHORT memorysize,modeflag;
-  ULONG  temp;
-
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-  }
-
-  memorysize = modeflag & MemoryInfoFlag;
-  memorysize >>= MemorySizeShift;			/* Get required memory size */
-  memorysize++;
-
-  temp = GetDRAMSize(SiS_Pr, HwDeviceExtension);       	/* Get adapter memory size */
-  temp /= (1024*1024);   				/* (in MB) */
-
-  if(temp < memorysize) return(FALSE);
-  else return(TRUE);
-}
-
-UCHAR
-SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
-{
-   UCHAR index;
-
-   if(ModeNo <= 0x13) {
-     	index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_StTableIndex;
-   } else {
-     	if(SiS_Pr->SiS_ModeType <= 0x02) index = 0x1B;    /* 02 -> ModeEGA  */
-     	else index = 0x0F;
-   }
-   return index;
-}
-
-void
-SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
+static void
+SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, USHORT ModeNo,
+ 		    PSIS_HW_INFO HwInfo,
+                    USHORT RefreshRateTableIndex)
 {
-   UCHAR SRdata;
-   USHORT i;
-
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x00,0x03);           	/* Set SR0  */
-
-   SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0];
-
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-         SRdata |= 0x01;
-      }
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-               SRdata |= 0x01;          		/* 8 dot clock  */
-            }
-	 }
-      }
-   }
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-           SRdata |= 0x01;        			/* 8 dot clock  */
-         }
-       }
-     }
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-         SRdata |= 0x01;          			/* 8 dot clock  */
-       }
-     }
-   }
-
-   SRdata |= 0x20;                			/* screen off  */
+  USHORT  i,index,data,VCLK,MCLK,colorth=0;
+  ULONG   B,eax,bl,data2;
+  USHORT  ThresholdLow=0;
+  UCHAR   FQBQData[]= {
+  	0x01,0x21,0x41,0x61,0x81,
+        0x31,0x51,0x71,0x91,0xb1,
+        0x00,0x20,0x40,0x60,0x80,
+        0x30,0x50,0x70,0x90,0xb0,
+	0xFF
+  };
+  UCHAR   FQBQData730[]= {
+        0x34,0x74,0xb4,
+	0x23,0x63,0xa3,
+	0x12,0x52,0x92,
+	0x01,0x41,0x81,
+	0x00,0x40,0x80,
+	0xff
+  };
 
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x01,SRdata);
+  i=0;
+  if(ModeNo > 0x13) {
+    if(SiS_Pr->UseCustomMode) {
+       VCLK = SiS_Pr->CSRClock;
+    } else {
+       index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+       index &= 0x3F;
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;          /* Get VCLK  */
+    }
 
-   for(i = 2; i <= 4; i++) {
-       	SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1];
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,i,SRdata);
-   }
-}
+    index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
+    index &= 0x07;
+    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
 
-void
-SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
-{
-   UCHAR Miscdata;
+    data2 = SiS_Pr->SiS_ModeType - ModeEGA;	  /* Get half colordepth */
+    switch (data2) {
+        case 0 : colorth = 1; break;
+        case 1 : colorth = 1; break;
+        case 2 : colorth = 2; break;
+        case 3 : colorth = 2; break;
+        case 4 : colorth = 3; break;
+        case 5 : colorth = 4; break;
+    }
 
-   Miscdata = SiS_Pr->SiS_StandTable[StandTableIndex].MISC;
+    if(HwInfo->jChipType == SIS_730) {
 
-   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-        Miscdata |= 0x0C;
-      }
-   }
+       do {
+          B = SiS_CalcDelay2(SiS_Pr, FQBQData730[i], HwInfo) * VCLK * colorth;
+	  bl = B / (MCLK * 16);
 
-   SiS_SetReg3(SiS_Pr->SiS_P3c2,Miscdata);
-}
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-void
-SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                USHORT StandTableIndex)
-{
-  UCHAR CRTCdata;
-  USHORT i;
+          if(bl > 0x13) {
+             if(FQBQData730[i+1] == 0xFF) {
+                ThresholdLow = 0x13;
+                break;
+             }
+             i++;
+          } else {
+             ThresholdLow = bl;
+             break;
+          }
+       } while(FQBQData730[i] != 0xFF);
+
+    } else {
+
+       do {
+          B = SiS_CalcDelay2(SiS_Pr, FQBQData[i], HwInfo) * VCLK * colorth;
+          bl = B / (MCLK * 16);
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                       /* Unlock CRTC */
+          if(B == bl * 16 * MCLK) {
+             bl = bl + 1;
+          } else {
+             bl = bl + 2;
+          }
 
-  for(i = 0; i <= 0x18; i++) {
-     CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,i,CRTCdata);                     /* Set CRTC(3d4) */
-  }
-  if( ( (HwDeviceExtension->jChipType == SIS_630) ||
-        (HwDeviceExtension->jChipType == SIS_730) )  &&
-      (HwDeviceExtension->jChipRevision >= 0x30) ) {       	   /* for 630S0 */
-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x18,0xFE);
-      }
+          if(bl > 0x13) {
+             if(FQBQData[i+1] == 0xFF) {
+                ThresholdLow = 0x13;
+                break;
+             }
+             i++;
+          } else {
+             ThresholdLow = bl;
+             break;
+          }
+       } while(FQBQData[i] != 0xFF);
     }
   }
-}
-
-void
-SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
-               PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   UCHAR ARdata;
-   USHORT i;
-
-   for(i = 0; i <= 0x13; i++) {
-    ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i];
-#if 0
-    if((i <= 0x0f) || (i == 0x11)) {
-        if(ds:489 & 0x08) {
-	   continue;
-        }
-    }
-#endif
-    if(i == 0x13) {
-      /* Pixel shift. If screen on LCD or TV is shifted left or right, 
-       * this might be the cause. 
-       */
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  ARdata=0;
-      }
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-               if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
-            }
-         }
-      }
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    if(IS_SIS650740 || IS_SIS550) {  
-	       /* 315, 330 don't do this */
-	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) { 
-	          if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) ARdata=0;
-	       } else {
-	          ARdata = 0;
-	       }
-	    }
-	 } else {
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  ARdata=0;
-	}
-      }
+  else {
+    if(HwInfo->jChipType == SIS_730) {
+    } else {
+      i = 9;
     }
-    SiS_GetReg2(SiS_Pr->SiS_P3da);                              /* reset 3da  */
-    SiS_SetReg3(SiS_Pr->SiS_P3c0,i);                            /* set index  */
-    SiS_SetReg3(SiS_Pr->SiS_P3c0,ARdata);                       /* set data   */
-   }
-   SiS_GetReg2(SiS_Pr->SiS_P3da);                               /* reset 3da  */
-   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x14);                          /* set index  */
-   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x00);                          /* set data   */
-
-   SiS_GetReg2(SiS_Pr->SiS_P3da);
-   SiS_SetReg3(SiS_Pr->SiS_P3c0,0x20);				/* Enable Attribute  */
-   SiS_GetReg2(SiS_Pr->SiS_P3da);
-}
-
-void
-SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex)
-{
-   UCHAR GRdata;
-   USHORT i;
-
-   for(i = 0; i <= 0x08; i++) {
-     GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i];
-     SiS_SetReg1(SiS_Pr->SiS_P3ce,i,GRdata);                    /* Set GR(3ce) */
-   }
-
-   if(SiS_Pr->SiS_ModeType > ModeVGA) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3ce,0x05,0xBF);			/* 256 color disable */
-   }
-}
-
-void
-SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT i;
-
-  for(i = 0x0A; i <= 0x0E; i++) {
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,i,0x00);      /* Clear SR0A-SR0E */
-  }
-
-  /* TW: 330, 650/LVDS/301LV, 740/LVDS */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x37,0xFE);
+    ThresholdLow = 0x02;
   }
-}
 
-void
-SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex)
-{
-  USHORT sync;
-  USHORT temp;
-
-  if(SiS_Pr->UseCustomMode) {
-     sync = SiS_Pr->CInfoFlag >> 8;
-  } else {
-     sync = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
-  }     
-
-  sync &= 0xC0;
-  temp = 0x2F | sync;
-  SiS_SetReg3(SiS_Pr->SiS_P3c2,temp);           /* Set Misc(3c2) */
-}
-
-void
-SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,
-		PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  UCHAR  index;
-  USHORT tempah,i,modeflag,j;
-#ifdef SIS315H
-  USHORT temp;
-  USHORT ResInfo,DisplayType;
-  const SiS_LCDACRT1DataStruct *LCDACRT1Ptr = NULL;
-#endif
-
-  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);		/*unlock cr0-7  */
-
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     if(ModeNo <= 0x13) {
-        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     } else {
-        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
-  }     
-
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-
-#ifdef SIS315H
-
-     /* LCDA */
-
-     temp = SiS_GetLCDACRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                       RefreshRateTableIndex,&ResInfo,&DisplayType);
-
-     switch(DisplayType) {
-      case Panel_800x600       : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1;      break;
-      case Panel_1024x768      : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
-      case Panel_1280x1024     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1;    break;
-      case Panel_1400x1050     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1;    break;
-      case Panel_1600x1200     : LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1;    break;
-      case Panel_800x600   + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_1_H;    break;
-      case Panel_1024x768  + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1_H;   break;
-      case Panel_1280x1024 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_1_H;  break;
-      case Panel_1400x1050 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_1_H;  break;
-      case Panel_1600x1200 + 16: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_1_H;  break;
-      case Panel_800x600   + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2;      break;
-      case Panel_1024x768  + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2;     break;
-      case Panel_1280x1024 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2;    break;
-      case Panel_1400x1050 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2;    break;
-      case Panel_1600x1200 + 32: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2;    break;
-      case Panel_800x600   + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT1800x600_2_H;    break;
-      case Panel_1024x768  + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_2_H;   break;
-      case Panel_1280x1024 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11280x1024_2_H;  break;
-      case Panel_1400x1050 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11400x1050_2_H;  break;
-      case Panel_1600x1200 + 48: LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11600x1200_2_H;  break;
-      default:                   LCDACRT1Ptr = SiS_Pr->SiS_LCDACRT11024x768_1;     break;
-     }
-
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[0];
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
-     for(i=0x01,j=1;i<=0x07;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x10,j=8;i<=0x12;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x15,j=11;i<=0x16;i++,j++){
-       tempah =(LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
-     }
-     for(i=0x0A,j=13;i<=0x0C;i++,j++){
-       tempah = (LCDACRT1Ptr+ResInfo)->CR[j];
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
-     }
-
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
-     tempah &= 0x0E0;
-     SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
-
-     tempah = (LCDACRT1Ptr+ResInfo)->CR[16];
-     tempah &= 0x01;
-     tempah <<= 5;
-     if(modeflag & DoubleScanMode)  tempah |= 0x080;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
-
-#endif
-
-  } else {
-
-     /* LVDS, 301, 301B, 301LV, 302LV, ... (non-LCDA) */
-
-     if(SiS_Pr->UseCustomMode) {
-     
-        for(i=0,j=0;i<=07;i++,j++) {
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-        }
-        for(j=0x10;i<=10;i++,j++) {
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-        }
-        for(j=0x15;i<=12;i++,j++) {
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,SiS_Pr->CCRT1CRTC[i]);
-        }
-        for(j=0x0A;i<=15;i++,j++) {
-          SiS_SetReg1(SiS_Pr->SiS_P3c4,j,SiS_Pr->CCRT1CRTC[i]);
-        }
-
-        tempah = SiS_Pr->CCRT1CRTC[16] & 0xE0;
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
+  /* Write foreground and background queue */
+  if(HwInfo->jChipType == SIS_730) {
+
+     data2 = FQBQData730[i];
+     data2 = (data2 & 0xC0) >> 5;
+     data2 <<= 8;
 
-        tempah = SiS_Pr->CCRT1CRTC[16];
-        tempah &= 0x01;
-        tempah <<= 5;
-        if(modeflag & DoubleScanMode)  tempah |= 0x80;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
-     
-     
-     } else {
-     
-        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;  	/* Get index */
-#if 0   /* Not any longer... */     
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-           index &= 0x3F;
-        }
+#ifndef LINUX_XF86
+     SiS_SetRegLong(0xcf8,0x80000050);
+     eax = SiS_GetRegLong(0xcfc);
+     eax &= 0xfffff9ff;
+     eax |= data2;
+     SiS_SetRegLong(0xcfc,eax);
+#else
+     /* We use pci functions X offers. We use pcitag 0, because
+      * we want to read/write to the host bridge (which is always
+      * 00:00.0 on 630, 730 and 540), not the VGA device.
+      */
+     eax = pciReadLong(0x00000000, 0x50);
+     eax &= 0xfffff9ff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0x50, eax);
 #endif
 
-        for(i=0,j=0;i<=07;i++,j++) {
-          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
-        }
-        for(j=0x10;i<=10;i++,j++) {
-          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
-        }
-        for(j=0x15;i<=12;i++,j++) {
-          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
-          SiS_SetReg1(SiS_Pr->SiS_P3d4,j,tempah);
-        }
-        for(j=0x0A;i<=15;i++,j++) {
-          tempah=SiS_Pr->SiS_CRT1Table[index].CR[i];
-          SiS_SetReg1(SiS_Pr->SiS_P3c4,j,tempah);
-        }
-
-        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
-        tempah &= 0xE0;
-        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x0E,tempah);
-
-        tempah = SiS_Pr->SiS_CRT1Table[index].CR[16];
-        tempah &= 0x01;
-        tempah <<= 5;
-        if(modeflag & DoubleScanMode)  tempah |= 0x80;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,0xDF,tempah);
-
-     }
-  }
-
-  if(SiS_Pr->SiS_ModeType > ModeVGA) SiS_SetReg1(SiS_Pr->SiS_P3d4,0x14,0x4F);
-}
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData730[i] << 8;
+     data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
+     data2 <<= 20;
 
-BOOLEAN
-SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-		   USHORT *DisplayType)
- {
-  USHORT tempbx=0,modeflag=0;
-  USHORT CRT2CRTC=0;
+#ifndef LINUX_XF86
+     SiS_SetRegLong(0xcf8,0x800000A0);
+     eax = SiS_GetRegLong(0xcfc);
+     eax &= 0x00ffffff;
+     eax |= data2;
+     SiS_SetRegLong(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0xA0);
+     eax &= 0x00ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0xA0, eax);
+#endif
 
-  if(ModeNo <= 0x13) {
-  	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-  	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  tempbx = SiS_Pr->SiS_LCDResInfo;
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 32;
-  if(modeflag & HalfDCLK)                 tempbx += 16;
+     data2 = FQBQData[i];
+     data2 = (data2 & 0xf0) >> 4;
+     data2 <<= 24;
 
-  *ResInfo = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
+#ifndef LINUX_XF86
+     SiS_SetRegLong(0xcf8,0x80000050);
+     eax = SiS_GetRegLong(0xcfc);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     SiS_SetRegLong(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0x50);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0x50, eax);
+#endif
 
-  return 1;
-}
+     /* Write GUI grant timer (PCI config 0xA3) */
+     data2 = FQBQData[i];
+     data2 &= 0x0f;
+     data2 <<= 24;
 
-/* TW: Set offset and pitch - partly overruled by SetPitch() in XF86 */
-void
-SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex,
-		  PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   USHORT temp, DisplayUnit, infoflag;
+#ifndef LINUX_XF86
+     SiS_SetRegLong(0xcf8,0x800000A0);
+     eax = SiS_GetRegLong(0xcfc);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     SiS_SetRegLong(0xcfc,eax);
+#else
+     eax = pciReadLong(0x00000000, 0xA0);
+     eax &= 0xf0ffffff;
+     eax |= data2;
+     pciWriteLong(0x00000000, 0xA0, eax);
+#endif
 
-   if(SiS_Pr->UseCustomMode) {
-      infoflag = SiS_Pr->CInfoFlag;
-   } else {
-      infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-   }
-   
-   DisplayUnit = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                     RefreshRateTableIndex,HwDeviceExtension);		     
+  }
 
-   temp = (DisplayUnit >> 8) & 0x0f;
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0xF0,temp);
+  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
+  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,data);
 
-   temp = DisplayUnit & 0xFF;
-   SiS_SetReg1(SiS_Pr->SiS_P3d4,0x13,temp);
+  data = (ThresholdLow & 0x10) << 1;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
 
-   if(infoflag & InterlaceMode) DisplayUnit >>= 1;
+  /* What is this? */
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x3B,0x09);
 
-   DisplayUnit <<= 5;
-   temp = (DisplayUnit & 0xff00) >> 8;
-   if (DisplayUnit & 0xff) temp++;
-   temp++;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x10,temp);
+  /* Write CRT/CPU threshold high (gap = 3) */
+  data = ThresholdLow + 3;
+  if(data > 0x0f) data = 0x0f;
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
 }
+#endif
 
-/* TW: New from 650/LVDS 1.10.07, 630/301B and 630/LVDS BIOS */
-void
-SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+#ifdef SIS315H
+static void
+SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                    PSIS_HW_INFO HwInfo)
 {
-   USHORT index;
+  USHORT modeflag;
 
-   /* TW: We only need to do this if Panel Link is to be
-    *     initialized, thus on 630/LVDS/301BDH, and 650/LVDS
-    */
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 0)  return;
-   } else {
-      if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) &&
-          (!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
-	 return;
-      }
-   }
+  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
 
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xCF,0x20);
-   } else {
-   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
-   }
-   index = 1;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
-   if(HwDeviceExtension->jChipType >= SIS_315H) {
-   	SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x31,0xcf,0x10);
-   } else {
-   	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
-   }
-   index = 0;
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
-   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
+  if(ModeNo > 0x13) {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+     if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0x34);
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+     }
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x08,0xAE);
+     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
+  }
 }
+#endif
 
-void
-SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		USHORT RefreshRateTableIndex)
+/*********************************************/
+/*              MODE REGISTERS               */
+/*********************************************/
+
+static void
+SiS_SetVCLKState(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                 USHORT ModeNo, USHORT RefreshRateTableIndex,
+                 USHORT ModeIdIndex)
 {
-  USHORT  index=0;
+  USHORT data, data2=0;
+  USHORT VCLK, index=0;
 
-  if(!SiS_Pr->UseCustomMode) {
-     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	                  RefreshRateTableIndex,HwDeviceExtension);
-  }			  
-
-  if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ){
-
-    	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
-
-    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VBVCLKData[index].Part4_A);
-    	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VBVCLKData[index].Part4_B);
-
-    	if(HwDeviceExtension->jChipType >= SIS_315H) {
-		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
-   	} else {
-    		SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
-    	}
+  if(ModeNo <= 0x13) VCLK = 0;
+  else {
+     if(SiS_Pr->UseCustomMode) {
+        VCLK = SiS_Pr->CSRClock;
+     } else {
+        index = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
+	               RefreshRateTableIndex,HwInfo);
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
+     }
+  }
 
-  } else {
+  if(HwInfo->jChipType < SIS_315H) {		/* 300 series */
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x31,0xCF);
-	} else {
-	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
-	}
+     data2 = 0x00;
+     if(VCLK > 150) data2 |= 0x80;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2);
 
-	if(SiS_Pr->UseCustomMode) {
-	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->CSR2B);
-	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->CSR2C);
-	} else {
-    	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2B,SiS_Pr->SiS_VCLKData[index].SR2B);
-    	   SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2C,SiS_Pr->SiS_VCLKData[index].SR2C);
-  	}	   
+     data2 = 0x00;
+     if(VCLK >= 150) data2 |= 0x08;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
 
-    	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x01);
-	} else {
-      	    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2D,0x80);
-        }
+  } else { 					/* 315 series */
+
+     data = 0;
+     if(VCLK >= 166) data |= 0x0c;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+
+     if(VCLK >= 166) {
+        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
+     }
   }
-}
 
-#if 0  /* TW: Not used */
-void
-SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
-{
-  USHORT ModeFlag;
+  data2 = 0x03;
+  if((VCLK >= 135) && (VCLK < 160))      data2 = 0x02;
+  else if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
+  else if(VCLK >= 260)                   data2 = 0x00;
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0x7F);
+  if(HwInfo->jChipType == SIS_540) {
+     if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
+  }
 
-  if(ModeNo > 0x13) {
-    ModeFlag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    if ((ModeFlag & HalfDCLK) && (ModeFlag & DoubleScanMode)) {
-      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x80);
-      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x01,0xF7);
-    }
+  if(HwInfo->jChipType < SIS_315H) {
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
+  } else {
+     if(HwInfo->jChipType > SIS_315PRO) {
+        /* This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
+        if(ModeNo > 0x13) data2 &= 0xfc;
+     }
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
   }
 }
-#endif
 
-void
-SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
+static void
+SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
                     USHORT ModeNo,USHORT ModeIdIndex,USHORT RefreshRateTableIndex)
 {
   USHORT data,data2,data3;
   USHORT infoflag=0,modeflag;
   USHORT resindex,xres;
+#ifdef SIS315H
+  ULONG  longdata;
+#endif
 
   if(SiS_Pr->UseCustomMode) {
      modeflag = SiS_Pr->CModeFlag;
@@ -3490,23 +2500,25 @@
 
   data2 = 0;
   if(ModeNo > 0x13) {
-    if(SiS_Pr->SiS_ModeType > 0x02) {
-       data2 |= 0x02;
-       data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
-       data2 |= data3;
-    }
+     if(SiS_Pr->SiS_ModeType > 0x02) {
+        data2 |= 0x02;
+        data3 = (SiS_Pr->SiS_ModeType - ModeVGA) << 2;
+        data2 |= data3;
+     }
   }
+
 #ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n", 
-  	data, HwDeviceExtension->jChipType);
-#endif  
+  xf86DrvMsg(0, X_INFO, "Debug: Mode infoflag = %x, Chiptype %d\n",
+  	data, HwInfo->jChipType);
+#endif
+
   if(data & InterlaceMode) data2 |= 0x20;
   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x06,0xC0,data2);
 
   if(SiS_Pr->UseCustomMode) {
      xres = SiS_Pr->CHDisplay;
   } else {
-     resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+     resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
      if(ModeNo <= 0x13) {
       	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
      } else {
@@ -3514,14 +2526,15 @@
      }
   }
 
-  if(HwDeviceExtension->jChipType != SIS_300) {
+  if(HwInfo->jChipType != SIS_300) {
      data = 0x0000;
      if(infoflag & InterlaceMode) {
-        if(xres == 1024) data = 0x0035;
+        if(xres <= 800)  data = 0x0020;
+        else if(xres <= 1024) data = 0x0035;
         else data = 0x0048;
      }
      data2 = data & 0x00FF;
-     SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data2);
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x19,data2);
      data2 = (data & 0xFF00) >> 8;
      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x1a,0xFC,data2);
   }
@@ -3530,28 +2543,22 @@
      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x01,0x08);
   }
 
-  if(HwDeviceExtension->jChipType == SIS_300) {
+  if(HwInfo->jChipType == SIS_300) {
      if(modeflag & LineCompareOff) {
         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x08);
      } else {
         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xF7);
      }
-  } else if(HwDeviceExtension->jChipType < SIS_315H) {
-     if(modeflag & LineCompareOff) {
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
-     } else {
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
-     }
-     /* 630 BIOS does something for mode 0x12 here */
   } else {
      if(modeflag & LineCompareOff) {
         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xB7,0x08);
      } else {
         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x0F,0xB7);
      }
+     /* BIOS does something for mode 0x12 here */
   }
 
-  if(HwDeviceExtension->jChipType != SIS_300) {
+  if(HwInfo->jChipType != SIS_300) {
      if(SiS_Pr->SiS_ModeType == ModeEGA) {
         if(ModeNo > 0x13) {
   	   SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x0F,0x40);
@@ -3560,1434 +2567,1136 @@
   }
 
 #ifdef SIS315H
-  /* TW: 315 BIOS sets SR17 at this point */
-  if(HwDeviceExtension->jChipType == SIS_315PRO) {
-      data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
-      data = SiS_Pr->SiS_SR15[2][data];
-      if(SiS_Pr->SiS_ModeType == ModeText) {
-          data &= 0xc7;
-      } else {
-          data2 = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                                RefreshRateTableIndex,HwDeviceExtension);
-	  data2 >>= 1;
-	  if(infoflag & InterlaceMode) data2 >>= 1;
-	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-	  data3 >>= 1;
-	  if(data3 == 0) data3++;
-	  data2 /= data3;
-	  if(data2 >= 0x50) {
-	      data &= 0x0f;
-	      data |= 0x50;
-	  }
-      }
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
-  }
-
-  /* TW: 330 BIOS sets SR17 at this point */
-  if(HwDeviceExtension->jChipType == SIS_330) {
-      data = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
-      data = SiS_Pr->SiS_SR15[2][data];
-      if(SiS_Pr->SiS_ModeType <= ModeEGA) {
-          data &= 0xc7;
-      } else {
-          if(SiS_Pr->UseCustomMode) {
-	     data2 = SiS_Pr->CSRClock;
-	  } else {
-             data2 = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                               RefreshRateTableIndex,HwDeviceExtension);
-             data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
-	  }
-
-	  data3 = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-	  data3 >>= 1;
-
-	  data2 *= data3;
-
-	  data3 = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);
-	  data3 *= 1024;
-
-	  data2 = data3 / data2;
-
-	  if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
-            if(data2 >= 0x19c)      data = 0xba;
-	    else if(data2 >= 0x140) data = 0x7a;
-	    else if(data2 >= 0x101) data = 0x3a;
-	    else if(data2 >= 0xf5)  data = 0x32;
-	    else if(data2 >= 0xe2)  data = 0x2a;
-	    else if(data2 >= 0xc4)  data = 0x22;
-	    else if(data2 >= 0xac)  data = 0x1a;
-	    else if(data2 >= 0x9e)  data = 0x12;
-	    else if(data2 >= 0x8e)  data = 0x0a;
-	    else                    data = 0x02;
-	  } else {
-	    if(data2 >= 0x127)      data = 0xba;
-	    else                    data = 0x7a;
-	  }
+  /* 315 BIOS sets SR17 at this point */
+  if(HwInfo->jChipType == SIS_315PRO) {
+     data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
+     data = SiS_Pr->SiS_SR15[2][data];
+     if(SiS_Pr->SiS_ModeType == ModeText) {
+        data &= 0xc7;
+     } else {
+        data2 = SiS_GetOffset(SiS_Pr,ModeNo,ModeIdIndex,
+                              RefreshRateTableIndex,HwInfo);
+	data2 >>= 1;
+	if(infoflag & InterlaceMode) data2 >>= 1;
+	data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
+	data3 >>= 1;
+	if(data3 == 0) data3++;
+	data2 /= data3;
+	if(data2 >= 0x50) {
+	   data &= 0x0f;
+	   data |= 0x50;
+	}
+     }
+     SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
+  }
+
+  /* 330 BIOS sets SR17 at this point */
+  if(HwInfo->jChipType == SIS_330) {
+     data = SiS_Get310DRAMType(SiS_Pr, HwInfo);
+     data = SiS_Pr->SiS_SR15[2][data];
+     if(SiS_Pr->SiS_ModeType <= ModeEGA) {
+        data &= 0xc7;
+     } else {
+        if(SiS_Pr->UseCustomMode) {
+	   data2 = SiS_Pr->CSRClock;
+	} else {
+           data2 = SiS_GetVCLK2Ptr(SiS_Pr,ModeNo,ModeIdIndex,
+                                   RefreshRateTableIndex,HwInfo);
+           data2 = SiS_Pr->SiS_VCLKData[data2].CLOCK;
+	}
+
+	data3 = SiS_GetColorDepth(SiS_Pr,ModeNo,ModeIdIndex);
+	data3 >>= 1;
+
+	data2 *= data3;
+
+	data3 = SiS_GetMCLK(SiS_Pr, HwInfo);
+	longdata = data3 * 1024;
+
+	data2 = longdata / data2;
+
+	if(SiS_Pr->SiS_ModeType != Mode16Bpp) {
+           if(data2 >= 0x19c)      data = 0xba;
+	   else if(data2 >= 0x140) data = 0x7a;
+	   else if(data2 >= 0x101) data = 0x3a;
+	   else if(data2 >= 0xf5)  data = 0x32;
+	   else if(data2 >= 0xe2)  data = 0x2a;
+	   else if(data2 >= 0xc4)  data = 0x22;
+	   else if(data2 >= 0xac)  data = 0x1a;
+	   else if(data2 >= 0x9e)  data = 0x12;
+	   else if(data2 >= 0x8e)  data = 0x0a;
+	   else                    data = 0x02;
+	 } else {
+	   if(data2 >= 0x127)      data = 0xba;
+	   else                    data = 0x7a;
+	 }
       }
-      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x17,data);
+      SiS_SetReg(SiS_Pr->SiS_P3c4,0x17,data);
   }
 #endif
 
   data = 0x60;
   if(SiS_Pr->SiS_ModeType != ModeText) {
-      data ^= 0x60;
-      if(SiS_Pr->SiS_ModeType != ModeEGA) {
-          data ^= 0xA0;
-      }
+     data ^= 0x60;
+     if(SiS_Pr->SiS_ModeType != ModeEGA) {
+        data ^= 0xA0;
+     }
   }
   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x21,0x1F,data);
 
-  SiS_SetVCLKState(SiS_Pr,ROMAddr,HwDeviceExtension,ModeNo,RefreshRateTableIndex,ModeIdIndex);
+  SiS_SetVCLKState(SiS_Pr, HwInfo, ModeNo, RefreshRateTableIndex, ModeIdIndex);
 
 #ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x2c);
-    } else {
-        SiS_SetReg1(SiS_Pr->SiS_P3d4,0x52,0x6c);
-    }
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x2c);
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_P3d4,0x52,0x6c);
+     }
   }
 #endif
 }
 
-void
-SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                 USHORT ModeNo,USHORT RefreshRateTableIndex,
-                 USHORT ModeIdIndex)
-{
-  USHORT data, data2=0;
-  USHORT VCLK, index=0;
-
-  if (ModeNo <= 0x13) VCLK = 0;
-  else {
-     if(SiS_Pr->UseCustomMode) {
-        VCLK = SiS_Pr->CSRClock;
-     } else {
-        index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	               RefreshRateTableIndex,HwDeviceExtension);
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;
-     }	
-  }
-
-  if(HwDeviceExtension->jChipType < SIS_315H) {		/* 300 series */
+/*********************************************/
+/*                 LOAD DAC                  */
+/*********************************************/
 
-    data2 = 0x00;
-    if(VCLK > 150) data2 |= 0x80;
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0x7B,data2); 	/* DAC speed */
-
-    data2 = 0x00;
-    if(VCLK >= 150) data2 |= 0x08;       	/* VCLK > 150 */
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xF7,data2);
+#if 0
+static void
+SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
+{
+   int i;
 
-  } else { 						/* 310/325 series */
+   OutPortByte(port, 0);
+   port++;
+   for (i=0; i < (256 * 3); i++) {
+      OutPortByte(port, 0);
+   }
+}
+#endif
 
-    data = 0;
-    if(VCLK >= 166) data |= 0x0c;         	/* TW: Was 200; is 166 in 650, 315 and 330 BIOSes */
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x32,0xf3,data);
+static void
+SiS_WriteDAC(SiS_Private *SiS_Pr, SISIOADDRESS DACData, USHORT shiftflag,
+             USHORT dl, USHORT ah, USHORT al, USHORT dh)
+{
+  USHORT temp,bh,bl;
 
-    if(VCLK >= 166) {				/* TW: Was 200, is 166 in 650, 315 and 330 BIOSes */
-       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1f,0xe7);
-    }
-#if 0 /* Not done in 315 and 650/301LV/LVDS BIOSes: */
-    data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);	  	/* DAC pedestal */
-    data &= 0xE7;
-    if(VCLK<200) data |= 0x10;
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,data);	  	/* DAC pedestal */
-#endif
+  bh = ah;
+  bl = al;
+  if(dl != 0) {
+     temp = bh;
+     bh = dh;
+     dh = temp;
+     if(dl == 1) {
+        temp = bl;
+        bl = dh;
+        dh = temp;
+     } else {
+        temp = bl;
+        bl = bh;
+        bh = temp;
+     }
   }
-
-  data2 = 0x03;
-  if((VCLK >= 135) && (VCLK < 160)) data2 = 0x02;
-  if((VCLK >= 160) && (VCLK < 260)) data2 = 0x01;
-  if(VCLK >= 260) data2 = 0x00;
-
-  if(HwDeviceExtension->jChipType == SIS_540) {
-    	if((VCLK == 203) || (VCLK < 234)) data2 = 0x02;
-  }
-  
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xFC,data2);  	/* DAC speed */
-  } else {
-      if(HwDeviceExtension->jChipType > SIS_315PRO) {
-         /* TW: This "if" is done in 330 and 650/LVDS/301LV BIOSes; Not in 315 BIOS */
-         if(ModeNo > 0x13) data2 &= 0xfc;
-      }
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x07,0xF8,data2);  	/* DAC speed */
+  if(shiftflag) {
+     dh <<= 2;
+     bh <<= 2;
+     bl <<= 2;
   }
+  SiS_SetRegByte(DACData,(USHORT)dh);
+  SiS_SetRegByte(DACData,(USHORT)bh);
+  SiS_SetRegByte(DACData,(USHORT)bl);
 }
 
 void
-SiS_LoadDAC(SiS_Private *SiS_Pr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-            UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+            USHORT ModeNo, USHORT ModeIdIndex)
 {
    USHORT data,data2;
-   USHORT time,i,j,k;
-   USHORT m,n,o;
-   USHORT si,di,bx,dl;
-   USHORT al,ah,dh;
-   USHORT DACAddr, DACData, shiftflag;
+   USHORT time,i,j,k,m,n,o;
+   USHORT si,di,bx,dl,al,ah,dh;
+   USHORT shiftflag;
+   SISIOADDRESS DACAddr, DACData;
    const USHORT *table = NULL;
-#if 0
-   USHORT tempah,tempch,tempcl,tempdh,tempal,tempbx;
-#endif
 
    if(ModeNo <= 0x13) {
-        data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+      data = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
    } else {
-        if(SiS_Pr->UseCustomMode) {
-	   data = SiS_Pr->CModeFlag;
-	} else {
-           data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
- 	}	   
+      if(SiS_Pr->UseCustomMode) {
+	 data = SiS_Pr->CModeFlag;
+      } else {
+         data = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+      }
    }
 
-#if 0
-   if(!(ds:489 & 0x08)) {
-#endif
-
-	data &= DACInfoFlag;
-	time = 64;
-	if(data == 0x00) table = SiS_MDA_DAC;
-	if(data == 0x08) table = SiS_CGA_DAC;
-	if(data == 0x10) table = SiS_EGA_DAC;
-	if(data == 0x18) {
-	   time = 256;
-	   table = SiS_VGA_DAC;
-	}
-	if(time == 256) j = 16;
-	else            j = time;
+   data &= DACInfoFlag;
+   time = 64;
+   if(data == 0x00) table = SiS_MDA_DAC;
+   if(data == 0x08) table = SiS_CGA_DAC;
+   if(data == 0x10) table = SiS_EGA_DAC;
+   if(data == 0x18) {
+      time = 256;
+      table = SiS_VGA_DAC;
+   }
+   if(time == 256) j = 16;
+   else            j = time;
+
+   if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
+         (SiS_Pr->SiS_VBType & VB_NoLCD) )        ||
+       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
+       (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
+      DACAddr = SiS_Pr->SiS_P3c8;
+      DACData = SiS_Pr->SiS_P3c9;
+      shiftflag = 0;
+      SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
+   } else {
+      shiftflag = 1;
+      DACAddr = SiS_Pr->SiS_Part5Port;
+      DACData = SiS_Pr->SiS_Part5Port + 1;
+   }
+
+   SiS_SetRegByte(DACAddr,0x00);
+
+   for(i=0; i<j; i++) {
+      data = table[i];
+      for(k=0; k<3; k++) {
+	data2 = 0;
+	if(data & 0x01) data2 = 0x2A;
+	if(data & 0x02) data2 += 0x15;
+	if(shiftflag) data2 <<= 2;
+	SiS_SetRegByte(DACData, data2);
+	data >>= 2;
+      }
+   }
 
-	if( ( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&        /* 301B-DH LCD */
-	      (SiS_Pr->SiS_VBType & VB_NoLCD) )        ||
-	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)       ||   /* LCDA */
-	    (!(SiS_Pr->SiS_SetFlag & ProgrammingCRT2)) ) {  /* Programming CRT1 */
-	   DACAddr = SiS_Pr->SiS_P3c8;
-	   DACData = SiS_Pr->SiS_P3c9;
-	   shiftflag = 0;
-	   SiS_SetReg3(SiS_Pr->SiS_P3c6,0xFF);
-	} else {
-	   shiftflag = 1;
-	   DACAddr = SiS_Pr->SiS_Part5Port;
-	   DACData = SiS_Pr->SiS_Part5Port + 1;
-	}
+   if(time == 256) {
+      for(i = 16; i < 32; i++) {
+   	 data = table[i];
+	 if(shiftflag) data <<= 2;
+	 for(k = 0; k < 3; k++) SiS_SetRegByte(DACData, data);
+      }
+      si = 32;
+      for(m = 0; m < 9; m++) {
+         di = si;
+         bx = si + 4;
+         dl = 0;
+         for(n = 0; n < 3; n++) {
+  	    for(o = 0; o < 5; o++) {
+	       dh = table[si];
+	       ah = table[di];
+	       al = table[bx];
+	       si++;
+	       SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
+	    }
+	    si -= 2;
+	    for(o = 0; o < 3; o++) {
+	       dh = table[bx];
+	       ah = table[di];
+	       al = table[si];
+	       si--;
+	       SiS_WriteDAC(SiS_Pr, DACData, shiftflag, dl, ah, al, dh);
+	    }
+	    dl++;
+	 }            /* for n < 3 */
+	 si += 5;
+      }               /* for m < 9 */
+   }
+}
 
-	SiS_SetReg3(DACAddr,0x00);
+/*********************************************/
+/*         SET CRT1 REGISTER GROUP           */
+/*********************************************/
 
-	for(i=0; i<j; i++) {
-	   data = table[i];
-	   for(k=0; k<3; k++) {
-		data2 = 0;
-		if(data & 0x01) data2 = 0x2A;
-		if(data & 0x02) data2 += 0x15;
-		if(shiftflag) data2 <<= 2;
-		SiS_SetReg3(DACData,data2);
-		data >>= 2;
-	   }
-	}
+static void
+SiS_SetCRT1Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                 USHORT ModeNo, USHORT ModeIdIndex)
+{
+  USHORT  StandTableIndex,RefreshRateTableIndex;
 
-	if(time == 256) {
-	   for(i = 16; i < 32; i++) {
-		data = table[i];
-		if(shiftflag) data <<= 2;
-		for(k=0; k<3; k++) SiS_SetReg3(DACData,data);
-	   }
-	   si = 32;
-	   for(m = 0; m < 9; m++) {
-	      di = si;
-	      bx = si + 4;
-	      dl = 0;
-	      for(n = 0; n < 3; n++) {
-		 for(o = 0; o < 5; o++) {
-		    dh = table[si];
-		    ah = table[di];
-		    al = table[bx];
-		    si++;
-		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
-		 }
-		 si -= 2;
-		 for(o = 0; o < 3; o++) {
-		    dh = table[bx];
-		    ah = table[di];
-		    al = table[si];
-		    si--;
-		    SiS_WriteDAC(SiS_Pr,DACData,shiftflag,dl,ah,al,dh);
-		 }
-		 dl++;
-	      }            /* for n < 3 */
-	      si += 5;
-	   }               /* for m < 9 */
-	}
-#if 0
-    }  /* ds:489 & 0x08 */
-#endif
+  SiS_Pr->SiS_CRT1Mode = ModeNo;
+  StandTableIndex = SiS_GetModePtr(SiS_Pr, ModeNo, ModeIdIndex);
+  if(SiS_LowModeTest(SiS_Pr, ModeNo, HwInfo)) {
+     if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2)) {
+        SiS_DisableBridge(SiS_Pr, HwInfo);
+     }
+  }
 
-#if 0
-    if((!(ds:489 & 0x08)) && (ds:489 & 0x06)) {
-           tempbx = 0;
-	   for(i=0; i< 256; i++) {
-               SiS_SetReg3(SiS_Pr->SiS_P3c8-1,tempbx);    	/* 7f87 */
-               tempah = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);  	/* 7f83 */
-	       tempch = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
-	       tempcl = SiS_GetReg3(SiS_Pr->SiS_P3c8+1);
-	       tempdh = tempah;
-	       tempal = 0x4d * tempdh;          	/* 7fb8 */
-	       tempbx += tempal;
-	       tempal = 0x97 * tempch;
-	       tempbx += tempal;
-	       tempal = 0x1c * tempcl;
-	       tempbx += tempal;
-	       if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
-	       tempdh = (tempbx & 0x00ff) >> 8;
-	       tempch = tempdh;
-	       tempcl = tempdh;
-	       SiS_SetReg3(SiS_Pr->SiS_P3c8,(tempbx & 0xff));  	/* 7f7c */
-	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempdh);          /* 7f92 */
-	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempch);
-	       SiS_SetReg3(SiS_Pr->SiS_P3c8+1,tempcl);
-           }
-    }
-#endif
-}
+  SiS_ResetSegmentRegisters(SiS_Pr, HwInfo);
 
-void
-SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT DACData, USHORT shiftflag,
-             USHORT dl, USHORT ah, USHORT al, USHORT dh)
-{
-  USHORT temp;
-  USHORT bh,bl;
+  SiS_SetSeqRegs(SiS_Pr, StandTableIndex);
+  SiS_SetMiscRegs(SiS_Pr, StandTableIndex);
+  SiS_SetCRTCRegs(SiS_Pr, HwInfo, StandTableIndex);
+  SiS_SetATTRegs(SiS_Pr, StandTableIndex, HwInfo);
+  SiS_SetGRCRegs(SiS_Pr, StandTableIndex);
+  SiS_ClearExt1Regs(SiS_Pr,HwInfo);
+  SiS_ResetCRT1VCLK(SiS_Pr, HwInfo);
 
-  bh = ah;
-  bl = al;
-  if(dl != 0) {
-    temp = bh;
-    bh = dh;
-    dh = temp;
-    if(dl == 1) {
-       temp = bl;
-       bl = dh;
-       dh = temp;
-    } else {
-       temp = bl;
-       bl = bh;
-       bh = temp;
-    }
-  }
-  if(shiftflag) {
-     dh <<= 2;
-     bh <<= 2;
-     bl <<= 2;
-  }
-  SiS_SetReg3(DACData,(USHORT)dh);
-  SiS_SetReg3(DACData,(USHORT)bh);
-  SiS_SetReg3(DACData,(USHORT)bl);
-}
+  SiS_Pr->SiS_SelectCRT2Rate = 0;
+  SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
 
-static ULONG
-GetDRAMSize(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  ULONG   AdapterMemorySize = 0;
-#ifdef SIS315H
-  USHORT  counter;
+#ifdef LINUX_XF86
+  xf86DrvMsgVerb(0, X_PROBED, 4, "(init: VBType=0x%04x, VBInfo=0x%04x)\n",
+                    SiS_Pr->SiS_VBType, SiS_Pr->SiS_VBInfo);
 #endif
 
-#ifdef SIS315H
-  if ((HwDeviceExtension->jChipType == SIS_315H) ||
-      (HwDeviceExtension->jChipType == SIS_315)  ||
-      (HwDeviceExtension->jChipType == SIS_315PRO)) {
+  if(SiS_Pr->SiS_VBInfo & SetSimuScanMode) {
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+     }
+  }
 
-    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
-	counter >>= 2;
-	counter &= 0x03;
-	if(counter == 0x02) {
-		AdapterMemorySize += (AdapterMemorySize / 2);      /* DDR asymetric */
-	} else if(counter != 0) {
-		AdapterMemorySize <<= 1;                           /* SINGLE_CHANNEL_2_RANK or DUAL_CHANNEL_1_RANK */
-	}
-	AdapterMemorySize *= (1024*1024);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+     SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+  }
 
-  } else if(HwDeviceExtension->jChipType == SIS_330) {
+  RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
-    	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-	AdapterMemorySize = 1 << ((counter & 0xF0) >> 4);
-	counter &= 0x0c;
-	if(counter != 0) {
-		AdapterMemorySize <<= 1;
-	}
-	AdapterMemorySize *= (1024*1024);
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+     SiS_Pr->SiS_SetFlag &= ~ProgrammingCRT2;
+  }
 
-  } else if((HwDeviceExtension->jChipType == SIS_550) ||
-            (HwDeviceExtension->jChipType == SIS_740) ||
-            (HwDeviceExtension->jChipType == SIS_650)) {
+  if(RefreshRateTableIndex != 0xFFFF) {
+     SiS_SetCRT1Sync(SiS_Pr, RefreshRateTableIndex);
+     SiS_SetCRT1CRTC(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+     SiS_SetCRT1Offset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+     SiS_SetCRT1VCLK(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+  }
 
-  	counter = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-      	counter++;
-      	AdapterMemorySize = counter * 4;
-      	AdapterMemorySize *= (1024*1024);
+#ifdef SIS300
+  if(HwInfo->jChipType == SIS_300) {
+     SiS_SetCRT1FIFO_300(SiS_Pr, ModeNo,HwInfo,RefreshRateTableIndex);
+  } else if((HwInfo->jChipType == SIS_630) ||
+            (HwInfo->jChipType == SIS_730) ||
+            (HwInfo->jChipType == SIS_540)) {
+     SiS_SetCRT1FIFO_630(SiS_Pr, ModeNo, HwInfo, RefreshRateTableIndex);
+  }
+#endif
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_315H) {
+     SiS_SetCRT1FIFO_310(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
   }
 #endif
 
-#ifdef SIS300
-  if ((HwDeviceExtension->jChipType==SIS_300) ||
-      (HwDeviceExtension->jChipType==SIS_540) ||
-      (HwDeviceExtension->jChipType==SIS_630) ||
-      (HwDeviceExtension->jChipType==SIS_730)) {
+  SiS_SetCRT1ModeRegs(SiS_Pr, HwInfo, ModeNo, ModeIdIndex, RefreshRateTableIndex);
 
-      	AdapterMemorySize = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x3F;
-      	AdapterMemorySize++;
-      	AdapterMemorySize *= (1024*1024);
+  SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
 
+#ifndef LINUX_XF86
+  if(SiS_Pr->SiS_flag_clearbuffer) {
+     SiS_ClearBuffer(SiS_Pr,HwInfo,ModeNo);
   }
 #endif
 
-  return AdapterMemorySize;
+  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA))) {
+     SiS_WaitRetrace1(SiS_Pr);
+     SiS_DisplayOn(SiS_Pr);
+  }
 }
 
-#ifndef LINUX_XF86
-void
-SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo)
-{
-  PVOID   VideoMemoryAddress = (PVOID)HwDeviceExtension->pjVideoMemoryAddress;
-  ULONG   AdapterMemorySize  = (ULONG)HwDeviceExtension->ulVideoMemorySize;
-  PUSHORT pBuffer;
-  int i;
+/*********************************************/
+/*            HELPER: ENABLE CRT1            */
+/*********************************************/
 
-  if (SiS_Pr->SiS_ModeType>=ModeEGA) {
-    if(ModeNo > 0x13) {
-      AdapterMemorySize = GetDRAMSize(SiS_Pr, HwDeviceExtension);
-      SiS_SetMemory(VideoMemoryAddress,AdapterMemorySize,0);
-    } else {
-      pBuffer = VideoMemoryAddress;
-      for(i=0; i<0x4000; i++)
-         pBuffer[i] = 0x0000;
-    }
-  } else {
-    pBuffer = VideoMemoryAddress;
-    if (SiS_Pr->SiS_ModeType < ModeCGA) {
-      for(i=0; i<0x4000; i++)
-         pBuffer[i] = 0x0720;
-    } else {
-      SiS_SetMemory(VideoMemoryAddress,0x8000,0);
-    }
+static void
+SiS_HandleCRT1(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
+#if 0
+  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x01)) {
+     if((SiS_GetReg(SiS_Pr->SiS_P3c4,0x15) & 0x0a) ||
+        (SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x01)) {
+        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x63,0x40);
+     }
   }
-}
 #endif
-
-void
-SiS_DisplayOn(SiS_Private *SiS_Pr)
-{
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x00);
 }
 
-void
-SiS_DisplayOff(SiS_Private *SiS_Pr)
+/*********************************************/
+/*         HELPER: SET VIDEO REGISTERS       */
+/*********************************************/
+
+static void
+SiS_StrangeStuff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x01,0xDF,0x20);
+   if((IS_SIS651) || (IS_SISM650)) {
+      SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x3f, 0x00);   /* Fiddle with capture regs */
+      SiS_SetReg(SiS_Pr->SiS_VidCapt, 0x00, 0x00);
+      SiS_SetReg(SiS_Pr->SiS_VidPlay, 0x00, 0x86);   /* (BIOS does NOT unlock) */
+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x30, 0xfe); /* Fiddle with video regs */
+      SiS_SetRegAND(SiS_Pr->SiS_VidPlay, 0x3f, 0xef);
+   }
+   /* !!! This does not support modes < 0x13 !!! */
 }
 
+/*********************************************/
+/*         XFree86: SET SCREEN PITCH         */
+/*********************************************/
 
-/* ========================================== */
-/*  SR CRTC GR */
-void
-SiS_SetReg1(USHORT port, USHORT index, USHORT data)
+#ifdef LINUX_XF86
+static void
+SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
-   OutPortByte(port,index);
-   OutPortByte(port+1,data);
-}
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
 
-/* ========================================== */
-/*  AR(3C0) */
-void
-SiS_SetReg2(SiS_Private *SiS_Pr, USHORT port, USHORT index, USHORT data)
-{
-   InPortByte(port+0x3da-0x3c0);
-   OutPortByte(SiS_Pr->SiS_P3c0,index);
-   OutPortByte(SiS_Pr->SiS_P3c0,data);
-   OutPortByte(SiS_Pr->SiS_P3c0,0x20);
+    HDisplay = pSiS->scrnPitch / 8;
+    SiS_SetReg(SiS_Pr->SiS_P3d4, 0x13, (HDisplay & 0xFF));
+    temp = (SiS_GetReg(SiS_Pr->SiS_P3c4, 0x0E) & 0xF0) | (HDisplay>>8);
+    SiS_SetReg(SiS_Pr->SiS_P3c4, 0x0E, temp);
 }
 
-void
-SiS_SetReg3(USHORT port, USHORT data)
+static void
+SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
-   OutPortByte(port,data);
-}
+    SISPtr pSiS = SISPTR(pScrn);
+    ULong  HDisplay,temp;
 
-void
-SiS_SetReg4(USHORT port, ULONG data)
-{
-   OutPortLong(port,data);
-}
+    HDisplay = pSiS->scrnPitch2 / 8;
 
-void
-SiS_SetReg5(USHORT port, USHORT data)
-{
-   OutPortWord(port,data);
+    /* Unlock CRT2 */
+    if (pSiS->VGAEngine == SIS_315_VGA)
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2F, 0x01);
+    else
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24, 0x01);
+
+    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07, (HDisplay & 0xFF));
+    temp = (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x09) & 0xF0) | ((HDisplay >> 8) & 0xFF);
+    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09, temp);
 }
 
-UCHAR SiS_GetReg1(USHORT port, USHORT index)
+static void
+SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn)
 {
-   UCHAR   data;
+   SISPtr pSiS = SISPTR(pScrn);
+   BOOLEAN isslavemode = FALSE;
 
-   OutPortByte(port,index);
-   data = InPortByte(port+1);
+   if( (pSiS->VBFlags & VB_VIDEOBRIDGE) &&
+       ( ((pSiS->VGAEngine == SIS_300_VGA) &&
+          (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0xa0) == 0x20) ||
+         ((pSiS->VGAEngine == SIS_315_VGA) &&
+	  (SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x50) == 0x10) ) ) {
+      isslavemode = TRUE;
+   }
 
-   return(data);
+   /* We need to set pitch for CRT1 if bridge is in slave mode, too */
+   if((pSiS->VBFlags & DISPTYPE_DISP1) || (isslavemode)) {
+      SiS_SetPitchCRT1(SiS_Pr, pScrn);
+   }
+   /* We must not set the pitch for CRT2 if bridge is in slave mode */
+   if((pSiS->VBFlags & DISPTYPE_DISP2) && (!isslavemode)) {
+      SiS_SetPitchCRT2(SiS_Pr, pScrn);
+   }
 }
+#endif
 
-UCHAR
-SiS_GetReg2(USHORT port)
+/*********************************************/
+/*                 SiSSetMode()              */
+/*********************************************/
+
+#ifdef LINUX_XF86
+/* We need pScrn for setting the pitch correctly */
+BOOLEAN
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch)
+#else
+BOOLEAN
+SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo)
+#endif
 {
-   UCHAR   data;
+   ULONG   temp;
+   USHORT  ModeIdIndex,KeepLockReg;
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   unsigned char backupreg=0, tempr1, tempr2;
 
-   data= InPortByte(port);
+#ifndef LINUX_XF86
+   SiS_Pr->UseCustomMode = FALSE;
+   SiS_Pr->CRT1UsesCustomMode = FALSE;
+#endif
 
-   return(data);
-}
+   if(SiS_Pr->UseCustomMode) {
+      ModeNo = 0xfe;
+   }
 
-ULONG
-SiS_GetReg3(USHORT port)
-{
-   ULONG   data;
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-   data = InPortLong(port);
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-   return(data);
-}
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-USHORT
-SiS_GetReg4(USHORT port)
-{
-   ULONG   data;
+#ifdef LINUX_XF86
+   if(pScrn) SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
+   else
+#endif
+         SiS_Pr->SiS_VGAINFO = 0x11;
 
-   data = InPortWord(port);
+   SiSInitPCIetc(SiS_Pr, HwInfo);
 
-   return(data);
-}
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
 
-void
-SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG port)
-{
-   int i;
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
 
-   OutPortByte(port, 0);
-   port++;
-   for (i=0; i < (256 * 3); i++) {
-      OutPortByte(port, 0);
+   if(!SiS_Pr->UseCustomMode) {
+      ModeNo = ((ModeNo & 0x80) << 8) | (ModeNo & 0x7f);
    }
 
-}
+#ifdef LINUX_XF86
+   /* We never clear the buffer in X */
+   ModeNo |= 0x8000;
+#endif
 
-#if 0  /* TW: Unused */
-void
-SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex)
-{
-  ULONG Temp;
-  USHORT data,Temp2;
+   if(ModeNo & 0x8000) {
+     	ModeNo &= 0x7fff;
+     	SiS_Pr->SiS_flag_clearbuffer = 0;
+   } else {
+     	SiS_Pr->SiS_flag_clearbuffer = 1;
+   }
+
+   KeepLockReg = SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+
+   if(!SiS_Pr->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
+
+   SiS_GetVBType(SiS_Pr, HwInfo);
+
+   /* Init/restore some VB registers */
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwInfo);
+	 if(HwInfo->jChipType < SIS_330) {
+            if(ROMAddr && SiS_Pr->SiS_UseROM) {
+               temp = ROMAddr[VB310Data_1_2_Offset];
+	       temp |= 0x40;
+               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+            }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
+
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
+
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      }
+   }
+
+   /* Get VB information (connectors, connected devices) */
+   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, (SiS_Pr->UseCustomMode) ? 0 : 1);
+   SiS_SetHiVision(SiS_Pr, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+
+#ifndef LINUX_XF86
+   /* 3. Check memory size (Kernel framebuffer driver only) */
+   temp = SiS_CheckMemorySize(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   if(!temp) return(0);
+#endif
+
+   if(HwInfo->jChipType >= SIS_315H) {
+#if 0
+      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
+#endif
+
+      if(IS_SIS650) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	 }
+      }
+   }
+
+   if(SiS_Pr->UseCustomMode) {
+      SiS_Pr->CRT1UsesCustomMode = TRUE;
+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
+   } else {
+      SiS_Pr->CRT1UsesCustomMode = FALSE;
+   }
+
+   /* Set mode on CRT1 */
+   if( (SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SetCRT2ToLCDA)) ||
+       (!(SiS_Pr->SiS_VBInfo & SwitchCRT2)) ) {
+      SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   }
+
+   /* Set mode on CRT2 */
+   if(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2 | SetCRT2ToLCDA)) {
+      if(SiS_Pr->SiS_VBType & VB_SISVB) {
+         SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+      } else if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+	        SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+	        SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+         SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+      }
+   }
+
+   SiS_HandleCRT1(SiS_Pr);
+
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
+
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
+
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	 }
+      }
+   }
+
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+	 if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+	 } else {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+	 }
 
-  if (ModeNo<=0x13) return;
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
 
-  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x01);
-  Temp++;
-  Temp <<= 3;
+	 tempr1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+	 tempr2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00);
+	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+	 else			      tempr2 |= 0x08;
+	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+	 else			      tempr2 |= 0x04;
+	 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,tempr2);
+
+	 if((IS_SIS650) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & 0xfc)) {
+	    if((ModeNo == 0x03) || (ModeNo == 0x10)) {
+	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x80);
+	       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x56,0x08);
+            }
+	 }
+
+	 if(tempr1 & SetCRT2ToLCD) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	 }
+      } else if((HwInfo->jChipType == SIS_630) ||
+                (HwInfo->jChipType == SIS_730)) {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
+      }
+   }
+
+#ifdef LINUX_XF86
+   if(pScrn) {
+      /* SetPitch: Adapt to virtual size & position */
+      if((ModeNo > 0x13) && (dosetpitch)) {
+         SiS_SetPitch(SiS_Pr, pScrn);
+      }
 
-  if(Temp == 1024) data = 0x0035;
-  else if(Temp == 1280) data = 0x0048;
-  else data = 0x0000;
+      /* Backup/Set ModeNo in BIOS scratch area */
+      SiS_GetSetModeID(pScrn, ModeNo);
+   }
+#endif
+
+#ifndef LINUX_XF86  /* We never lock registers in XF86 */
+   if(KeepLockReg == 0xA1) SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+   else SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x00);
+#endif
+
+   return TRUE;
+}
+
+/*********************************************/
+/*          XFree86: SiSBIOSSetMode()        */
+/*           for non-Dual-Head mode          */
+/*********************************************/
+
+#ifdef LINUX_XF86
+BOOLEAN
+SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom)
+{
+   SISPtr  pSiS = SISPTR(pScrn);
+   UShort  ModeNo=0;
+
+   SiS_Pr->UseCustomMode = FALSE;
 
-  Temp2 = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-  Temp2 &= InterlaceMode;
-  if(Temp2 == 0) data=0x0000;
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x19,data);
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting custom mode %dx%d\n",
+	 	SiS_Pr->CHDisplay,
+		(mode->Flags & V_INTERLACE ? SiS_Pr->CVDisplay * 2 :
+		   (mode->Flags & V_DBLSCAN ? SiS_Pr->CVDisplay / 2 :
+		      SiS_Pr->CVDisplay)));
 
-  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3d4,0x1A);
-  Temp = (USHORT)(Temp & 0xFC);
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp);
+	 return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 
-  Temp = (ULONG)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x0f);
-  Temp2 = (USHORT)Temp & 0xBF;
-  if(ModeNo==0x37) Temp2 |= 0x40;
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x1A,(USHORT)Temp2);
-}
-#endif
+   }
 
-#ifdef SIS315H
-void
-SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT modeflag;
+   ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+   if(!ModeNo) return FALSE;
 
-  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x3D,0xFE);  /* disable auto-threshold */
+   xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, "Setting standard mode 0x%x\n", ModeNo);
 
-  if(ModeNo > 0x13) {
-    if(SiS_Pr->UseCustomMode) {
-       modeflag = SiS_Pr->CModeFlag;
-    } else {
-       modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    }       
-    if( (!(modeflag & DoubleScanMode)) || (!(modeflag & HalfDCLK))) {
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0x34);
-       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x3D,0x01);
-    } else {
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
-       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-    }
-  } else {
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,0xAE);
-    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x09,0xF0);
-  }
+   return(SiSSetMode(SiS_Pr, HwInfo, pScrn, ModeNo, TRUE));
 }
-#endif
 
-#ifdef SIS300
-void
-SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT RefreshRateTableIndex)
+/*********************************************/
+/*       XFree86: SiSBIOSSetModeCRT2()       */
+/*           for Dual-Head modes             */
+/*********************************************/
+BOOLEAN
+SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom)
 {
-  USHORT  ThresholdLow = 0;
-  USHORT  index, VCLK, MCLK, colorth=0;
-  USHORT  tempah, temp;
-
-  if(ModeNo > 0x13) {
+   ULONG   temp;
+   USHORT  ModeIdIndex;
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   UShort  ModeNo   = 0;
+   SISPtr  pSiS     = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+   unsigned char tempr1, tempr2, backupreg=0;
 
-     if(SiS_Pr->UseCustomMode) {
-        VCLK = SiS_Pr->CSRClock;
-     } else {
-        index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-        index &= 0x3F;
-        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;             /* Get VCLK  */
-     }
+   SiS_Pr->UseCustomMode = FALSE;
 
-     switch (SiS_Pr->SiS_ModeType - ModeEGA) {     /* Get half colordepth */
-        case 0 : colorth = 1; break;
-        case 1 : colorth = 1; break;
-        case 2 : colorth = 2; break;
-        case 3 : colorth = 2; break;
-        case 4 : colorth = 3; break;
-        case 5 : colorth = 4; break;
-     }
+   /* Remember: Custom modes for CRT2 are ONLY supported
+    * 		-) on 315/330 series,
+    *           -) on the 301 and 30xB, and
+    *           -) if CRT2 is LCD or VGA
+    */
 
-     index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-     index &= 0x07;
-     MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-     tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-     tempah &= 0xc3;
-     SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3c,tempah);
+	 ModeNo = 0xfe;
 
-     do {
-        ThresholdLow = SiS_CalcDelay(SiS_Pr, ROMAddr, VCLK, colorth, MCLK);
-        ThresholdLow++;
-        if(ThresholdLow < 0x13) break;
-        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x16,0xfc);
-        ThresholdLow = 0x13;
-        tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-        tempah >>= 6;
-        if(!(tempah)) break;
-        tempah--;
-        tempah <<= 6;
-        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x16,0x3f,tempah);
-     } while(0);
+   } else {
 
-  } else ThresholdLow = 2;
+         BOOLEAN havecustommodes = pSiS->HaveCustomModes;
 
-  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
-  temp = (ThresholdLow << 4) | 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,temp);
+#ifdef SISMERGED
+	 if(pSiS->MergedFB) havecustommodes = pSiS->HaveCustomModes2;
+#endif
 
-  temp = (ThresholdLow & 0x10) << 1;
-  if(ModeNo > 0x13) temp |= 0x40;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0f,0x9f,temp);
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, havecustommodes);
+         if(!ModeNo) return FALSE;
 
-  /* What is this? */
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+   }
 
-  /* Write CRT/CPU threshold high */
-  temp = ThresholdLow + 3;
-  if(temp > 0x0f) temp = 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x09,temp);
-}
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-USHORT
-SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK, USHORT colordepth, USHORT MCLK)
-{
-  USHORT tempax, tempbx;
+   /* Save mode info so we can set it from within SetMode for CRT1 */
+   if(pSiS->DualHeadMode) {
+      pSiSEnt->CRT2ModeNo = ModeNo;
+      pSiSEnt->CRT2DMode = mode;
+      pSiSEnt->CRT2IsCustom = IsCustom;
+      pSiSEnt->CRT2CR30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+      pSiSEnt->CRT2CR31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+      pSiSEnt->CRT2CR38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      /* We can't set CRT2 mode before CRT1 mode is set */
+      if(pSiSEnt->CRT1ModeNo == -1) {
+    	 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+		"Setting CRT2 mode delayed until after setting CRT1 mode\n");
+   	 return TRUE;
+      }
+   }
 
-  tempbx = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 0);
-  tempax = SiS_DoCalcDelay(SiS_Pr, MCLK, VCLK, colordepth, 1);
-  if(tempax < 4) tempax = 4;
-  tempax -= 4;
-  if(tempbx < tempax) tempbx = tempax;
-  return(tempbx);
-}
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-USHORT
-SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key)
-{
-  const UCHAR ThLowA[]   = { 61, 3,52, 5,68, 7,100,11,
-                             43, 3,42, 5,54, 7, 78,11,
-                             34, 3,37, 5,47, 7, 67,11 };
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-  const UCHAR ThLowB[]   = { 81, 4,72, 6,88, 8,120,12,
-                             55, 4,54, 6,66, 8, 90,12,
-                             42, 4,45, 6,55, 8, 75,12 };
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-  const UCHAR ThTiming[] = {  1, 2, 2, 3, 0, 1,  1, 2 };
+   SiSInitPCIetc(SiS_Pr, HwInfo);
 
-  USHORT tempah, tempal, tempcl, tempbx, temp;
-  ULONG  longtemp;
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
 
-  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-  tempah &= 0x62;
-  tempah >>= 1;
-  tempal = tempah;
-  tempah >>= 3;
-  tempal |= tempah;
-  tempal &= 0x07;
-  tempcl = ThTiming[tempal];
-  tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-  tempbx >>= 6;
-  tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-  tempah >>= 4;
-  tempah &= 0x0c;
-  tempbx |= tempah;
-  tempbx <<= 1;
-  if(key == 0) {
-     tempal = ThLowA[tempbx + 1];
-     tempal *= tempcl;
-     tempal += ThLowA[tempbx];
-  } else {
-     tempal = ThLowB[tempbx + 1];
-     tempal *= tempcl;
-     tempal += ThLowB[tempbx];
-  }
-  longtemp = tempal * VCLK * colordepth;
-  temp = longtemp % (MCLK * 16);
-  longtemp /= (MCLK * 16);
-  if(temp) longtemp++;
-  return((USHORT)longtemp);
-}
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
 
-#if 0  /* TW: Old fragment, unused */
-USHORT
-SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT key)
-{
-  USHORT data,data2,temp0,temp1;
-  UCHAR   ThLowA[]=   {61,3,52,5,68,7,100,11,
-                       43,3,42,5,54,7, 78,11,
-                       34,3,37,5,47,7, 67,11};
-
-  UCHAR   ThLowB[]=   {81,4,72,6,88,8,120,12,
-                       55,4,54,6,66,8, 90,12,
-                       42,4,45,6,55,8, 75,12};
-
-  UCHAR   ThTiming[]= {1,2,2,3,0,1,1,2};
-
-  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-  data=data>>6;
-  data2=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-  data2=(data2>>4)&0x0C;
-  data=data|data2;
-  data=data<1;
-  if(key==0) {
-    temp0=(USHORT)ThLowA[data];
-    temp1=(USHORT)ThLowA[data+1];
-  } else {
-    temp0=(USHORT)ThLowB[data];
-    temp1=(USHORT)ThLowB[data+1];
-  }
+   /* We don't clear the buffer under X */
+   SiS_Pr->SiS_flag_clearbuffer=0;
 
-  data2=0;
-  data=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-  if(data&0x02) data2=data2|0x01;
-  if(data&0x20) data2=data2|0x02;
-  if(data&0x40) data2=data2|0x04;
+   if(SiS_Pr->UseCustomMode) {
 
-  data=temp1*ThTiming[data2]+temp0;
-  return(data);
-}
-#endif
+      USHORT temptemp = SiS_Pr->CVDisplay;
 
-void
-SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
- 		    PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                    USHORT RefreshRateTableIndex)
-{
-  USHORT  i,index,data,VCLK,MCLK,colorth=0;
-  ULONG   B,eax,bl,data2;
-  USHORT  ThresholdLow=0;
-  UCHAR   FQBQData[]= { 
-  	0x01,0x21,0x41,0x61,0x81,
-        0x31,0x51,0x71,0x91,0xb1,
-        0x00,0x20,0x40,0x60,0x80,
-        0x30,0x50,0x70,0x90,0xb0,
-	0xFF
-  };
-  UCHAR   FQBQData730[]= {
-        0x34,0x74,0xb4,
-	0x23,0x63,0xa3,
-	0x12,0x52,0x92,
-	0x01,0x41,0x81,
-	0x00,0x40,0x80,
-	0xff
-  };
+      if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+      else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
 
-  i=0;
-  if(ModeNo > 0x13) {
-    if(SiS_Pr->UseCustomMode) {
-       VCLK = SiS_Pr->CSRClock;
-    } else {
-       index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-       index &= 0x3F;
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;          /* Get VCLK  */
-    }       
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	  "Setting custom mode %dx%d on CRT2\n",
+	  SiS_Pr->CHDisplay, temptemp);
 
-    index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-    index &= 0x07;
-    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;           /* Get MCLK  */
+   } else {
 
-    data2 = SiS_Pr->SiS_ModeType - ModeEGA;	  /* Get half colordepth */
-    switch (data2) {
-        case 0 : colorth = 1; break;
-        case 1 : colorth = 1; break;
-        case 2 : colorth = 2; break;
-        case 3 : colorth = 2; break;
-        case 4 : colorth = 3; break;
-        case 5 : colorth = 4; break;
-    }
+      xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+   	  "Setting standard mode 0x%x on CRT2\n", ModeNo);
 
-    if(HwDeviceExtension->jChipType == SIS_730) {
-    
-       do {
-          B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData730[i], HwDeviceExtension) * VCLK * colorth;
-	  bl = B / (MCLK * 16);
+   }
 
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
 
-          if(bl > 0x13) {
-             if(FQBQData730[i+1] == 0xFF) {
-                ThresholdLow = 0x13;
-                break;
-             }
-             i++;
-          } else {
-             ThresholdLow = bl;
-             break;
-          }
-       } while(FQBQData730[i] != 0xFF);
-       
-    } else {
-    
-       do {
-          B = SiS_CalcDelay2(SiS_Pr, ROMAddr, FQBQData[i], HwDeviceExtension) * VCLK * colorth;
-          bl = B / (MCLK * 16);
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
 
-          if(B == bl * 16 * MCLK) {
-             bl = bl + 1;
-          } else {
-             bl = bl + 2;
-          }
+   if(!SiS_Pr->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
 
-          if(bl > 0x13) {
-             if(FQBQData[i+1] == 0xFF) {
-                ThresholdLow = 0x13;
-                break;
-             }
-             i++;
-          } else {
-             ThresholdLow = bl;
-             break;
-          }
-       } while(FQBQData[i] != 0xFF);
-    }
-  }
-  else {
-    if(HwDeviceExtension->jChipType == SIS_730) { 
-    } else {
-      i = 9;
-    }
-    ThresholdLow = 0x02;
-  }
+   SiS_GetVBType(SiS_Pr, HwInfo);
 
-  /* Write foreground and background queue */
-  if(HwDeviceExtension->jChipType == SIS_730) {  
-   
-     data2 = FQBQData730[i];
-     data2 = (data2 & 0xC0) >> 5;
-     data2 <<= 8;
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         SiS_UnLockCRT2(SiS_Pr,HwInfo);
+	 if(HwInfo->jChipType < SIS_330) {
+           if(ROMAddr && SiS_Pr->SiS_UseROM) {
+             temp = ROMAddr[VB310Data_1_2_Offset];
+	     temp |= 0x40;
+             SiS_SetReg(SiS_Pr->SiS_Part1Port,0x02,temp);
+           }
+	 }
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x32,0x10);
 
-#ifndef LINUX_XF86
-     SiS_SetReg4(0xcf8,0x80000050);
-     eax = SiS_GetReg3(0xcfc);
-     eax &= 0xfffff9ff;
-     eax |= data2;
-     SiS_SetReg4(0xcfc,eax);
-#else
-     /* We use pci functions X offers. We use pcitag 0, because
-      * we want to read/write to the host bridge (which is always
-      * 00:00.0 on 630, 730 and 540), not the VGA device.
-      */
-     eax = pciReadLong(0x00000000, 0x50);
-     eax &= 0xfffff9ff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0x50, eax);
-#endif
+	 SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x02,0x0c);
 
-     /* Write GUI grant timer (PCI config 0xA3) */
-     data2 = FQBQData730[i] << 8;
-     data2 = (data2 & 0x0f00) | ((data2 & 0x3000) >> 8);
-     data2 <<= 20;
-     
-#ifndef LINUX_XF86
-     SiS_SetReg4(0xcf8,0x800000A0);
-     eax = SiS_GetReg3(0xcfc);
-     eax &= 0x00ffffff;
-     eax |= data2;
-     SiS_SetReg4(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0xA0);
-     eax &= 0x00ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0xA0, eax);
-#endif          
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      }
+   }
 
-  } else {
-  
-     data2 = FQBQData[i];
-     data2 = (data2 & 0xf0) >> 4;
-     data2 <<= 24;
+   /* Get VB information (connectors, connected devices) */
+   if(!SiS_Pr->UseCustomMode) {
+      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 1);
+   } else {
+      /* If this is a custom mode, we don't check the modeflag for CRT2Mode */
+      SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, 0);
+   }
+   SiS_SetHiVision(SiS_Pr, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
-#ifndef LINUX_XF86
-     SiS_SetReg4(0xcf8,0x80000050);
-     eax = SiS_GetReg3(0xcfc);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     SiS_SetReg4(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0x50);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0x50, eax);
+#if 0
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
+   }
 #endif
 
-     /* Write GUI grant timer (PCI config 0xA3) */
-     data2 = FQBQData[i];
-     data2 &= 0x0f;
-     data2 <<= 24;
+   /* Set mode on CRT2 */
+   if(SiS_Pr->SiS_VBType & VB_SISVB) {
+      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+   } else if(SiS_Pr->SiS_IF_DEF_LVDS     == 1 ||
+	     SiS_Pr->SiS_IF_DEF_CH70xx   != 0 ||
+	     SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+   }
 
-#ifndef LINUX_XF86
-     SiS_SetReg4(0xcf8,0x800000A0);
-     eax = SiS_GetReg3(0xcfc);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     SiS_SetReg4(0xcfc,eax);
-#else
-     eax = pciReadLong(0x00000000, 0xA0);
-     eax &= 0xf0ffffff;
-     eax |= data2;
-     pciWriteLong(0x00000000, 0xA0, eax);
-#endif
-     
-  }
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
 
-  /* Write CRT/CPU threshold low, CRT/Engine threshold high */
-  data = ((ThresholdLow & 0x0f) << 4) | 0x0f;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x08,data);
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-  data = (ThresholdLow & 0x10) << 1;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0F,0xDF,data);
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+         if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+	    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	 }
+      }
+   }
 
-  /* What is this? */
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x3B,0x09);
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+	 if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
+	 } else {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0xFE);
+	 }
 
-  /* Write CRT/CPU threshold high (gap = 3) */
-  data = ThresholdLow + 3;
-  if(data > 0x0f) data = 0x0f;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x09,0x80,data);
-}
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
 
-USHORT
-SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr,UCHAR key, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT data,index;
-  const UCHAR  LatencyFactor[] = { 
-   	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
-        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
-        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
-        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
-        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
-        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
-        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
-  };
-  const UCHAR  LatencyFactor730[] = {
-         69, 63, 61, 
-	 86, 79, 77,
-	103, 96, 94,
-	120,113,111,
-	137,130,128,    /* --- Table ends with this entry, data below */
-	137,130,128,	/* to avoid using illegal values              */
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-  };
+	 tempr1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+	 tempr2 = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00);
+	 if(tempr1 & SetCRT2ToAVIDEO) tempr2 &= 0xF7;
+	 else			      tempr2 |= 0x08;
+	 if(tempr1 & SetCRT2ToSVIDEO) tempr2 &= 0xFB;
+	 else			      tempr2 |= 0x04;
+	 SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,tempr2);
 
-  if(HwDeviceExtension->jChipType == SIS_730) {
-     index = ((key & 0x0f) * 3) + ((key & 0xC0) >> 6);
-     data = LatencyFactor730[index];
-  } else {			    
-     index = (key & 0xE0) >> 5;
-     if(key & 0x10) index +=6;
-     if(!(key & 0x01)) index += 24;
-     data = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-     if(data & 0x0080) index += 12;
-     data = LatencyFactor[index];
-  }
-  return(data);
+	 if(tempr1 & SetCRT2ToLCD) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	 }
+      } else if((HwInfo->jChipType == SIS_630) ||
+                (HwInfo->jChipType == SIS_730)) {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
+      }
+   }
+
+   /* SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT2(SiS_Pr, pScrn);
+
+   return TRUE;
 }
-#endif
 
-/* =============== Autodetection ================ */
-/*             I N C O M P L E T E                */
+/*********************************************/
+/*       XFree86: SiSBIOSSetModeCRT1()       */
+/*           for Dual-Head modes             */
+/*********************************************/
 
 BOOLEAN
-SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+                   DisplayModePtr mode, BOOLEAN IsCustom)
 {
-  const USHORT PanelTypeTable300[16] = {
-      0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
-      0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
-  };
-  const USHORT PanelTypeTable31030x[16] = {
-      0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
-      0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-  };
-  const USHORT PanelTypeTable310LVDS[16] = {
-      0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
-      0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
-  };
-  USHORT tempax,tempbx,tempah,temp;
+   SISPtr  pSiS = SISPTR(pScrn);
+   SISEntPtr pSiSEnt = pSiS->entityPrivate;
+   USHORT  ModeIdIndex, ModeNo=0;
+   SISIOADDRESS BaseAddr = HwInfo->ulIOAddress;
+   unsigned char backupreg=0, backupcr30, backupcr31, backupcr38;
+   BOOLEAN backupcustom;
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+   SiS_Pr->UseCustomMode = FALSE;
 
-    tempax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-    tempbx = tempax & 0x0F;
-    if(!(tempax & 0x10)){
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
-        tempbx = 0;
-        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
-        if(temp & 0x40) tempbx |= 0x08;
-        if(temp & 0x20) tempbx |= 0x02;
-        if(temp & 0x01) tempbx |= 0x01;
-        temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x39);
-        if(temp & 0x80) tempbx |= 0x04;
-      } else {
-        return 0;
-      }
-    }
-    tempbx = PanelTypeTable300[tempbx];
-    tempbx |= LCDSync;
-    temp = tempbx & 0x00FF;
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
-    temp = (tempbx & 0xFF00) >> 8;
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+   if((IsCustom) && (SiS_CheckBuildCustomMode(pScrn, mode, pSiS->VBFlags))) {
 
-  } else {
+         USHORT temptemp = SiS_Pr->CVDisplay;
 
-    tempax = tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1a);
-    tempax &= 0x1e;
-    tempax >>= 1;
-    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-       if(tempax == 0) {
-           /* TODO: Include HUGE detection routine
-	            (Probably not worth bothering)
-	    */
-           return 0;
-       }
-       temp = tempax & 0xff;
-       tempax--;
-       tempbx = PanelTypeTable310LVDS[tempax];
-    } else {
-       tempbx = PanelTypeTable31030x[tempax];
-       temp = tempbx & 0xff;
-    }
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
-    tempbx = (tempbx & 0xff00) >> 8;
-    temp = tempbx & 0xc1;
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
-    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-       temp = tempbx & 0x04;
-       SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
-    }
+         if(SiS_Pr->CModeFlag & DoubleScanMode)     temptemp >>= 1;
+         else if(SiS_Pr->CInfoFlag & InterlaceMode) temptemp <<= 1;
 
-  }
-  return 1;
-}
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	 	"Setting custom mode %dx%d on CRT1\n",
+	 	SiS_Pr->CHDisplay, temptemp);
+	 ModeNo = 0xfe;
 
+   } else {
 
-#ifdef LINUXBIOS
+         ModeNo = SiS_CalcModeIndex(pScrn, mode, pSiS->VBFlags, pSiS->HaveCustomModes);
+         if(!ModeNo) return FALSE;
 
-void
-SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-{
-  UCHAR  DAC_TEST_PARMS[] = {0x0F,0x0F,0x0F};
-  UCHAR  DAC_CLR_PARMS[]  = {0x00,0x00,0x00};
-  USHORT SR1F;
-
-  SR1F = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);		/* backup DAC pedestal */
-  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1F,0x04);
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    if(!(SiS_BridgeIsOn(SiS_Pr, BaseAddr))) {
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x41);
-    }
-  }
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+	 	"Setting standard mode 0x%x on CRT1\n", ModeNo);
+   }
 
-  SiSSetMode(SiS_Pr,HwDeviceExtension,0x2E);
-  if(HwDeviceExtension->jChipType >= SIS_650) {
-     /* TW: On 650 only - enable CRT1 */
-     SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x63,0xbf);
-  }
-  SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
-  SiS_ClearDAC(SiS_Pr, SiS_Pr->SiS_P3c8);
-  SiS_LongWait(SiS_Pr);
-  SiS_LongWait(SiS_Pr);
-  SiS_LongWait(SiS_Pr);
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x00);
-  if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
-  } else if(SiS_TestMonitorType(SiS_Pr, DAC_TEST_PARMS[0],DAC_TEST_PARMS[1],DAC_TEST_PARMS[2])) {
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xDF,0x20);
-  }
-  SiS_TestMonitorType(SiS_Pr, DAC_CLR_PARMS[0],DAC_CLR_PARMS[1],DAC_CLR_PARMS[2]);
+   SiSInitPtr(SiS_Pr, HwInfo);
 
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1F,SR1F);
-}
+   SiSRegInit(SiS_Pr, BaseAddr);
 
-USHORT
-SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC)
-{
-   USHORT temp,tempbx;
+   SiS_GetSysFlags(SiS_Pr, HwInfo);
 
-   tempbx = R_DAC * 0x4d + G_DAC * 0x97 + B_DAC * 0x1c;
-   if((tempbx & 0x00ff) > 0x80) tempbx += 0x100;
-   tempbx = (tempbx & 0xFF00) >> 8;
-   R_DAC = (UCHAR) tempbx;
-   G_DAC = (UCHAR) tempbx;
-   B_DAC = (UCHAR) tempbx;
-
-   SiS_SetReg3(SiS_Pr->SiS_P3c8,0x00);
-   SiS_SetReg3(SiS_Pr->SiS_P3c9,R_DAC);
-   SiS_SetReg3(SiS_Pr->SiS_P3c9,G_DAC);
-   SiS_SetReg3(SiS_Pr->SiS_P3c9,B_DAC);
-   SiS_LongWait(SiS_Pr);
-   temp=SiS_GetReg2(SiS_Pr->SiS_P3c2);
-   if(temp & 0x10) return(1);
-   else return(0);
-}
+   SiS_Pr->SiS_VGAINFO = SiS_GetSetBIOSScratch(pScrn, 0x489, 0xff);
 
-void
-SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr)
-{
-  USHORT tempax=0,tempbx,tempcx,temp;
-  USHORT P2reg0=0,SenseModeNo=0,OutputSelect=*SiS_Pr->pSiS_OutputSelect;
-  USHORT ModeIdIndex,i;
-  USHORT BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
-    SiS_GetPanelID(SiS_Pr);
-    temp=LCDSense;
-    temp=temp|SiS_SenseCHTV(SiS_Pr);
-    tempbx=~(LCDSense|AVIDEOSense|SVIDEOSense);
-    SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,tempbx,temp);
-  } else {       /* for 301 */
-    if(SiS_Pr->SiS_IF_DEF_HiVision==1) {  /* for HiVision */
-      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x38);
-      temp=tempax&0x01;
-      tempax=SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-      temp=temp|(tempax&0x02);
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,0xA0,temp);
-    } else {
-      if(SiS_BridgeIsOn(SiS_Pr, BaseAddr)==0) {    /* TW: Inserted "==0" */
-        P2reg0 = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x00);
-        if(!(SiS_BridgeIsEnable(SiS_Pr, BaseAddr,HwDeviceExtension))) {
-          SenseModeNo=0x2e;
-          temp = SiS_SearchModeID(SiS_Pr, ROMAddr,&SenseModeNo,&ModeIdIndex);
-          SiS_Pr->SiS_SetFlag = 0x00;
-          SiS_Pr->SiS_ModeType = ModeVGA;
-          SiS_Pr->SiS_VBInfo = SetCRT2ToRAMDAC |LoadDACFlag |SetInSlaveMode;
-          SiS_SetCRT2Group301(SiS_Pr, BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
-          for(i=0;i<20;i++) {
-            SiS_LongWait(SiS_Pr);
-          }
-        }
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,0x1c);
-        tempax=0;
-        tempbx=*SiS_Pr->pSiS_RGBSenseData;
-	if(SiS_Is301B(SiS_Pr, BaseAddr)){
-                tempbx=*SiS_Pr->pSiS_RGBSenseData2;
-        }
-        tempcx=0x0E08;
-        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-            tempax=tempax|Monitor2Sense;
-          }
-        }
-        tempbx=*SiS_Pr->pSiS_YCSenseData;
-        if(SiS_Is301B(SiS_Pr, BaseAddr)){
-               tempbx=*SiS_Pr->pSiS_YCSenseData2;
-        }
-        tempcx=0x0604;
-        if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-          if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
-            tempax=tempax|SVIDEOSense;
-          }
-        }
+   SiSInitPCIetc(SiS_Pr, HwInfo);
 
-	if(ROMAddr && SiS_Pr->SiS_UseROM) {
-#ifdef SIS300
-	   if((HwDeviceExtension->jChipType==SIS_630)||
-              (HwDeviceExtension->jChipType==SIS_730)) {
-		OutputSelect = ROMAddr[0xfe];
-	   }
-#endif
-#ifdef SIS315H
-	   if(HwDeviceExtension->jChipType >= SIS_315H) {
-	        OutputSelect = ROMAddr[0xf3];
-		if(HwDeviceExtension->jChipType == SIS_330) {
-		     OutputSelect = ROMAddr[0x11b];
-		}
-	   }
-#endif
-        }
-        if(OutputSelect & BoardTVType){
-          tempbx = *SiS_Pr->pSiS_VideoSenseData;
-          if(SiS_Is301B(SiS_Pr, BaseAddr)){
-             tempbx = *SiS_Pr->pSiS_VideoSenseData2;
-          }
-          tempcx = 0x0804;
-          if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-            if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-              tempax |= AVIDEOSense;
-            }
-          }
-        } else {
-          if(!(tempax & SVIDEOSense)){
-            tempbx = *SiS_Pr->pSiS_VideoSenseData;
-            if(SiS_Is301B(SiS_Pr, BaseAddr)){
-              tempbx = *SiS_Pr->pSiS_VideoSenseData2;
-            }
-            tempcx = 0x0804;
-            if(SiS_Sense(SiS_Pr,tempbx,tempcx)){
-              if(SiS_Sense(SiS_Pr, tempbx,tempcx)){
-                tempax |= AVIDEOSense;
-              }
-            }
-          }
-        }
-      }
+   SiSSetLVDSetc(SiS_Pr, HwInfo);
 
-      if(SiS_SenseLCD(SiS_Pr, HwDeviceExtension)){
-        tempax |= LCDSense;
-      }
+   SiSDetermineROMUsage(SiS_Pr, HwInfo);
+
+   /* We don't clear the buffer under X */
+   SiS_Pr->SiS_flag_clearbuffer = 0;
+
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
 
-      tempbx=0;
-      tempcx=0;
-      SiS_Sense(SiS_Pr, tempbx,tempcx);
-
-      if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
-         tempax &= 0x00ef;   /* 30xlv have no VGA2*/
-      }
-      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x32,~0xDF,tempax);
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,P2reg0);
-      if(!(P2reg0 & 0x20)) {
-        SiS_Pr->SiS_VBInfo = DisableCRT2Display;
-        SiS_SetCRT2Group301(SiS_Pr,BaseAddr,ROMAddr,SenseModeNo,HwDeviceExtension);
+   if(!SiS_Pr->UseCustomMode) {
+      if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+   } else {
+      ModeIdIndex = 0;
+   }
+
+   /* Determine VBType (301, 301B, 301C, 301LV, 302B, 302LV) */
+   SiS_GetVBType(SiS_Pr, HwInfo);
+
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+      } else {
+         backupreg = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
       }
-    }
-  }
-}
+   }
 
-BOOLEAN
-SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx)
-{
-  USHORT temp,i,tempch;
+   /* Get VB information (connectors, connected devices) */
+   /* (We don't care if the current mode is a CRT2 mode) */
+   SiS_GetVBInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo,0);
+   SiS_SetHiVision(SiS_Pr, HwInfo);
+   SiS_GetLCDResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
 
-  temp = tempbx & 0xFF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x11,temp);
-  temp = (tempbx & 0xFF00) >> 8;
-  temp |= (tempcx & 0x00FF);
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x10,~0x1F,temp);
-
-  for(i=0; i<10; i++) SiS_LongWait(SiS_Pr);
-
-  tempch = (tempcx & 0x7F00) >> 8;
-  temp = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x03);
-  temp ^= 0x0E;
-  temp &= tempch;
-  if(temp>0) return 1;
-  else return 0;
-}
+   if(HwInfo->jChipType >= SIS_315H) {
+#if 0
+      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x08)  {
+         if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if(ModeNo != 0x10)  SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         } else if((IS_SIS651) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+            SiS_Pr->SiS_SetFlag |= SetDOSMode;
+         }
+      }
+#endif
 
-USHORT
-SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp;
+      if(IS_SIS650) {
+         if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x51,0x1f);
+	    if(IS_SIS651) SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x51,0x20);
+	    SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x56,0xe7);
+	 }
+      }
+   }
 
-  temp=SiS_GetPanelID(SiS_Pr);
-  if(!temp)  temp=SiS_GetLCDDDCInfo(SiS_Pr, HwDeviceExtension);
-  return(temp);
-}
+   /* Set mode on CRT1 */
+   SiS_SetCRT1Group(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+      SiS_SetCRT2Group(SiS_Pr, HwInfo, ModeNo);
+   }
 
-BOOLEAN
-SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp;
-  /*add lcd sense*/
-  if(HwDeviceExtension->ulCRT2LCDType==LCD_UNKNOWN)
-    	return 0;
-  else{
-     	temp=(USHORT)HwDeviceExtension->ulCRT2LCDType;
-     	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
-  	return 1;
-  }
-}
+   /* SetPitch: Adapt to virtual size & position */
+   SiS_SetPitchCRT1(SiS_Pr, pScrn);
+
+   if(pSiS->DualHeadMode) {
+      pSiSEnt->CRT1ModeNo = ModeNo;
+      pSiSEnt->CRT1DMode = mode;
+   }
+
+   if(SiS_Pr->UseCustomMode) {
+      SiS_Pr->CRT1UsesCustomMode = TRUE;
+      SiS_Pr->CSRClock_CRT1 = SiS_Pr->CSRClock;
+      SiS_Pr->CModeFlag_CRT1 = SiS_Pr->CModeFlag;
+   } else {
+      SiS_Pr->CRT1UsesCustomMode = FALSE;
+   }
 
-USHORT
-SiS_SenseCHTV(SiS_Private *SiS_Pr)
-{
-  USHORT temp,push0e,status;
+   /* Reset CRT2 if changing mode on CRT1 */
+   if(pSiS->DualHeadMode) {
+      if(pSiSEnt->CRT2ModeNo != -1) {
+         xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3,
+				"(Re-)Setting mode for CRT2\n");
+	 backupcustom = SiS_Pr->UseCustomMode;
+	 backupcr30 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+	 backupcr31 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+	 backupcr38 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	    SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,pSiSEnt->CRT2CR30);
+	    SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,pSiSEnt->CRT2CR31);
+	    SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,pSiSEnt->CRT2CR38);
+	 }
+	 SiSBIOSSetModeCRT2(SiS_Pr, HwInfo, pSiSEnt->pScrn_1,
+			    pSiSEnt->CRT2DMode, pSiSEnt->CRT2IsCustom);
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,backupcr30);
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x31,backupcr31);
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupcr38);
+	 SiS_Pr->UseCustomMode = backupcustom;
+      }
+   }
 
-  status=0;
-  push0e = SiS_GetCH700x(SiS_Pr, 0x0e);
-  push0e = (push0e << 8) | 0x0e;
-  SiS_SetCH700x(SiS_Pr, 0x0b0e);
-  SiS_SetCH700x(SiS_Pr, 0x0110);
-  SiS_SetCH700x(SiS_Pr, 0x0010);
-  temp = SiS_GetCH700x(SiS_Pr, 0x10);
-  if(temp & 0x08) status |= SVIDEOSense;
-  if(temp & 0x02) status |= AVIDEOSense;
-  SiS_SetCH700x(SiS_Pr, push0e);
-  return(status);
-}
-#endif /* LINUXBIOS */
+   /* Warning: From here, the custom mode entries in SiS_Pr are
+    * possibly overwritten
+    */
 
-/*  ================ for TC only =================  */
+   SiS_HandleCRT1(SiS_Pr);
 
-#ifdef TC
+   SiS_StrangeStuff(SiS_Pr, HwInfo);
 
-int
-INT1AReturnCode(union REGS regs)
-{
-  if (regs.x.cflag)
-  {
-    /*printf("Error to find pci device!\n"); */
-    return 1;
-  }
-
-  switch(regs.h.ah)
-  {
-    case 0: return 0;
-            break;
-    case 0x81: printf("Function not support\n");
-               break;
-    case 0x83: printf("bad vendor id\n");
-               break;
-    case 0x86: printf("device not found\n");
-               break;
-    case 0x87: printf("bad register number\n");
-               break;
-    case 0x88: printf("set failed\n");
-               break;
-    case 0x89: printf("buffer too small");
-               break;
-  }
-  return 1;
-}
+   SiS_DisplayOn(SiS_Pr);
+   SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xFF);
 
-unsigned
-FindPCIIOBase(unsigned index,unsigned deviceid)
-{
-  union REGS regs;
+   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+      if(HwInfo->jChipType >= SIS_315H) {
+	 SiS_SetReg(SiS_Pr->SiS_P3d4,0x38,backupreg);
+      } else if((HwInfo->jChipType == SIS_630) ||
+                (HwInfo->jChipType == SIS_730)) {
+         SiS_SetReg(SiS_Pr->SiS_P3d4,0x35,backupreg);
+      }
+   }
 
-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
-  regs.h.al = 0x02;  /*FIND_PCI_DEVICE */
-  regs.x.cx = deviceid;
-  regs.x.dx = 0x1039;
-  regs.x.si = index;  /* find n-th device */
-
-  int86(0x1A, &regs, &regs);
-
-  if (INT1AReturnCode(regs)!=0)
-    return 0;
-
-  /* regs.h.bh *//* bus number */
-  /* regs.h.bl *//* device number */
-  regs.h.ah = 0xb1;  /*PCI_FUNCTION_ID */
-  regs.h.al = 0x09;  /*READ_CONFIG_WORD */
-  regs.x.cx = deviceid;
-  regs.x.dx = 0x1039;
-  regs.x.di = 0x18;  /* register number */
-  int86(0x1A, &regs, &regs);
-
-  if (INT1AReturnCode(regs)!=0)
-    return 0;
-  return regs.x.cx;
+   /* Backup/Set ModeNo in BIOS scratch area */
+   SiS_GetSetModeID(pScrn,ModeNo);
+
+   return TRUE;
 }
+#endif /* Linux_XF86 */
 
 
-void
-main(int argc, char *argv[])
+#ifdef LINUX_XF86
+BOOLEAN
+SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-  SIS_HW_DEVICE_INFO  HwDeviceExtension;
-  USHORT temp;
-  USHORT ModeNo;
+  const USHORT PanelTypeTable300[16] = {
+      0xc101, 0xc117, 0x0121, 0xc135, 0xc142, 0xc152, 0xc162, 0xc072,
+      0xc181, 0xc192, 0xc1a1, 0xc1b6, 0xc1c2, 0xc0d2, 0xc1e2, 0xc1f2
+  };
+  const USHORT PanelTypeTable31030x[16] = {
+      0xc102, 0xc112, 0x0122, 0xc132, 0xc142, 0xc152, 0xc169, 0xc179,
+      0x0189, 0xc192, 0xc1a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  };
+  const USHORT PanelTypeTable310LVDS[16] = {
+      0xc111, 0xc122, 0xc133, 0xc144, 0xc155, 0xc166, 0xc177, 0xc188,
+      0xc199, 0xc0aa, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  };
+  USHORT tempax,tempbx,tempah,temp;
 
-  /*HwDeviceExtension.pjVirtualRomBase =(PUCHAR) MK_FP(0xC000,0); */
-  /*HwDeviceExtension.pjVideoMemoryAddress = (PUCHAR)MK_FP(0xA000,0);*/
+  if(HwInfo->jChipType < SIS_315H) {
 
-#ifdef SIS300  
-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x6300)&0xFF80) + 0x30;
-  HwDeviceExtension.jChipType = SIS_630;
-#endif
+     tempax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
+     tempbx = tempax & 0x0F;
+     if(!(tempax & 0x10)){
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1){
+           tempbx = 0;
+           temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x38);
+           if(temp & 0x40) tempbx |= 0x08;
+           if(temp & 0x20) tempbx |= 0x02;
+           if(temp & 0x01) tempbx |= 0x01;
+           temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x39);
+           if(temp & 0x80) tempbx |= 0x04;
+        } else {
+           return 0;
+        }
+     }
+     tempbx = PanelTypeTable300[tempbx];
+     tempbx |= LCDSync;
+     temp = tempbx & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
+     temp = (tempbx & 0xFF00) >> 8;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
 
-#ifdef SIS315H  
-//  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x5315)&0xFF80) + 0x30;
-//  HwDeviceExtension.jChipType = SIS_550;
-  HwDeviceExtension.ulIOAddress = (FindPCIIOBase(0,0x325)&0xFF80) + 0x30;
-  HwDeviceExtension.jChipType = SIS_315H;
-#endif
+  } else {
+
+     tempax = tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1a);
+     tempax &= 0x1e;
+     tempax >>= 1;
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if(tempax == 0) {
+           /* TODO: Include HUGE detection routine
+	            (Probably not worth bothering)
+	    */
+           return 0;
+        }
+        temp = tempax & 0xff;
+        tempax--;
+        tempbx = PanelTypeTable310LVDS[tempax];
+     } else {
+        tempbx = PanelTypeTable31030x[tempax];
+        temp = tempbx & 0xff;
+     }
+     SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
+     tempbx = (tempbx & 0xff00) >> 8;
+     temp = tempbx & 0xc1;
+     SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x37,~(LCDSyncBit|LCDRGB18Bit),temp);
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        temp = tempbx & 0x04;
+        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x39,0xfb,temp);
+     }
 
-  HwDeviceExtension.ujVBChipID = VB_CHIP_301;
-  strcpy(HwDeviceExtension.szVBIOSVer,"0.84");
-  HwDeviceExtension.bSkipDramSizing = FALSE;
-  HwDeviceExtension.ulVideoMemorySize = 0;
-  if(argc==2) {
-    ModeNo=atoi(argv[1]);
-  }
-  else {
-    ModeNo=0x2e;
-    /*ModeNo=0x37; */ /* 1024x768x 4bpp */
-    /*ModeNo=0x38; *//* 1024x768x 8bpp */
-    /*ModeNo=0x4A; *//* 1024x768x 16bpp */
-    /*ModeNo=0x47;*/ /* 800x600x 16bpp */
   }
- /* SiSInit(SiS_Pr, &HwDeviceExtension);*/
-  SiSSetMode(SiS_Pr, &HwDeviceExtension, ModeNo);
+  return 1;
 }
-#endif /* TC END */
+#endif
+
 
 /* ================ XFREE86 ================= */
 
@@ -5000,44 +3709,78 @@
    SISPtr pSiS = SISPTR(pScrn);
    int    out_n, out_dn, out_div, out_sbit, out_scale;
    int    depth = pSiS->CurrentLayout.bitsPerPixel;
-   
-#ifdef SISDUALHEAD
-   if( ((!pSiS->DualHeadMode) && (VBFlags & DISPTYPE_DISP2)) ||
-       ((pSiS->DualHeadMode) && (!pSiS->SecondHead)) ) return 0;
-#else      
-   if(VBFlags & DISPTYPE_DISP2) return 0; 
-#endif   
+   unsigned int vclk[5];
+
+#define Midx         0
+#define Nidx         1
+#define VLDidx       2
+#define Pidx         3
+#define PSNidx       4
+
+   pSiS->SiS_Pr->CModeFlag = 0;
    
    pSiS->SiS_Pr->CDClock = mode->Clock;
-   
+
    pSiS->SiS_Pr->CHDisplay = mode->HDisplay;
    pSiS->SiS_Pr->CHSyncStart = mode->HSyncStart;
    pSiS->SiS_Pr->CHSyncEnd = mode->HSyncEnd;
    pSiS->SiS_Pr->CHTotal = mode->HTotal;
-   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
-   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
-   
+
    pSiS->SiS_Pr->CVDisplay = mode->VDisplay;
    pSiS->SiS_Pr->CVSyncStart = mode->VSyncStart;
    pSiS->SiS_Pr->CVSyncEnd = mode->VSyncEnd;
    pSiS->SiS_Pr->CVTotal = mode->VTotal;
+
+   pSiS->SiS_Pr->CFlags = mode->Flags;
+
+   if(pSiS->SiS_Pr->CFlags & V_INTERLACE) {
+      pSiS->SiS_Pr->CVDisplay >>= 1;
+      pSiS->SiS_Pr->CVSyncStart >>= 1;
+      pSiS->SiS_Pr->CVSyncEnd >>= 1;
+      pSiS->SiS_Pr->CVTotal >>= 1;
+   }
+   if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) {
+      /* pSiS->SiS_Pr->CDClock <<= 1; */
+      pSiS->SiS_Pr->CVDisplay <<= 1;
+      pSiS->SiS_Pr->CVSyncStart <<= 1;
+      pSiS->SiS_Pr->CVSyncEnd <<= 1;
+      pSiS->SiS_Pr->CVTotal <<= 1;
+   }
+
+   pSiS->SiS_Pr->CHBlankStart = pSiS->SiS_Pr->CHDisplay;
+   pSiS->SiS_Pr->CHBlankEnd = pSiS->SiS_Pr->CHTotal;
    pSiS->SiS_Pr->CVBlankStart = pSiS->SiS_Pr->CVSyncStart - 1;
    pSiS->SiS_Pr->CVBlankEnd = pSiS->SiS_Pr->CVTotal;
-   
-   pSiS->SiS_Pr->CFlags = mode->Flags;
 
-   SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale);
-   
+   if(SiS_compute_vclk(pSiS->SiS_Pr->CDClock, &out_n, &out_dn, &out_div, &out_sbit, &out_scale)) {
+      pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
+      pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
+      pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
+      pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
+      pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+#ifdef TWDEBUG
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
+        	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
+#endif
+   } else {
+      SiSCalcClock(pScrn, pSiS->SiS_Pr->CDClock, 2, vclk);
+      pSiS->SiS_Pr->CSR2B = (vclk[VLDidx] == 2) ? 0x80 : 0x00;
+      pSiS->SiS_Pr->CSR2B |= (vclk[Midx] - 1) & 0x7f;
+      pSiS->SiS_Pr->CSR2C = (vclk[Nidx] - 1) & 0x1f;
+      if(vclk[Pidx] <= 4) {
+         /* postscale 1,2,3,4 */
+         pSiS->SiS_Pr->CSR2C |= ((vclk[Pidx] - 1) & 3) << 5;
+      } else {
+         /* postscale 6,8 */
+         pSiS->SiS_Pr->CSR2C |= (((vclk[Pidx] / 2) - 1) & 3) << 5;
+	 pSiS->SiS_Pr->CSR2C |= 0x80;
+      }
 #ifdef TWDEBUG
-   xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sb %d sc %d\n",
-      	pSiS->SiS_Pr->CDClock, out_n, out_dn, out_div, out_sbit, out_scale);
-#endif	
-
-   pSiS->SiS_Pr->CSR2B = (out_div == 2) ? 0x80 : 0x00;
-   pSiS->SiS_Pr->CSR2B |= ((out_n - 1) & 0x7f);
-   pSiS->SiS_Pr->CSR2C = (out_dn - 1) & 0x1f;
-   pSiS->SiS_Pr->CSR2C |= (((out_scale - 1) & 3) << 5);
-   pSiS->SiS_Pr->CSR2C |= ((out_sbit & 0x01) << 7);
+      xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Clock %d: n %d dn %d div %d sc %d\n",
+        	pSiS->SiS_Pr->CDClock, vclk[Midx], vclk[Nidx], vclk[VLDidx], vclk[Pidx]);
+#endif
+   }
+
    pSiS->SiS_Pr->CSRClock = (pSiS->SiS_Pr->CDClock / 1000) + 1;
 
    pSiS->SiS_Pr->CCRT1CRTC[0]  =  ((pSiS->SiS_Pr->CHTotal >> 3) - 5) & 0xff;
@@ -5045,9 +3788,9 @@
    pSiS->SiS_Pr->CCRT1CRTC[2]  =  (pSiS->SiS_Pr->CHBlankStart >> 3) - 1;
    pSiS->SiS_Pr->CCRT1CRTC[3]  =  (((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
    pSiS->SiS_Pr->CCRT1CRTC[4]  =  (pSiS->SiS_Pr->CHSyncStart >> 3) + 3;
-   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) | 
+   pSiS->SiS_Pr->CCRT1CRTC[5]  =  ((((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1) & 0x20) << 2) |
        				  (((pSiS->SiS_Pr->CHSyncEnd >> 3) + 3) & 0x1F);
-   
+
    pSiS->SiS_Pr->CCRT1CRTC[6]  =  (pSiS->SiS_Pr->CVTotal - 2) & 0xFF;
    pSiS->SiS_Pr->CCRT1CRTC[7]  =  (((pSiS->SiS_Pr->CVTotal - 2) & 0x100) >> 8)
  	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x100) >> 7)
@@ -5057,71 +3800,76 @@
 	 			| (((pSiS->SiS_Pr->CVTotal - 2) & 0x200)   >> 4)
 	 			| (((pSiS->SiS_Pr->CVDisplay - 1) & 0x200) >> 3)
 	 			| ((pSiS->SiS_Pr->CVSyncStart & 0x200) >> 2);
-    
+
    pSiS->SiS_Pr->CCRT1CRTC[16] = ((((pSiS->SiS_Pr->CVBlankStart - 1) & 0x200) >> 4) >> 5); 	/* cr9 */
-    
-#if 0    
+
+#if 0
    if (mode->VScan >= 32)
 	regp->CRTC[9] |= 0x1F;
    else if (mode->VScan > 1)
 	regp->CRTC[9] |= mode->VScan - 1;
-#endif	
+#endif
 
-   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart - 1) & 0xFF;	/* cr10 */
-   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd - 1) & 0x0F) | 0x80;	/* cr11 */
-   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay - 1) & 0xFF;		/* cr12 */
-   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;	/* cr15 */
-   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd - 1) & 0xFF;		/* cr16 */
-   
-   pSiS->SiS_Pr->CCRT1CRTC[13] = 
+   pSiS->SiS_Pr->CCRT1CRTC[8] =  (pSiS->SiS_Pr->CVSyncStart     ) & 0xFF;		/* cr10 */
+   pSiS->SiS_Pr->CCRT1CRTC[9] =  ((pSiS->SiS_Pr->CVSyncEnd      ) & 0x0F) | 0x80;	/* cr11 */
+   pSiS->SiS_Pr->CCRT1CRTC[10] = (pSiS->SiS_Pr->CVDisplay    - 1) & 0xFF;		/* cr12 */
+   pSiS->SiS_Pr->CCRT1CRTC[11] = (pSiS->SiS_Pr->CVBlankStart - 1) & 0xFF;		/* cr15 */
+   pSiS->SiS_Pr->CCRT1CRTC[12] = (pSiS->SiS_Pr->CVBlankEnd   - 1) & 0xFF;		/* cr16 */
+
+   pSiS->SiS_Pr->CCRT1CRTC[13] =
                         GETBITSTR((pSiS->SiS_Pr->CVTotal     -2), 10:10, 0:0) |
                         GETBITSTR((pSiS->SiS_Pr->CVDisplay   -1), 10:10, 1:1) |
                         GETBITSTR((pSiS->SiS_Pr->CVBlankStart-1), 10:10, 2:2) |
                         GETBITSTR((pSiS->SiS_Pr->CVSyncStart   ), 10:10, 3:3) |
                         GETBITSTR((pSiS->SiS_Pr->CVBlankEnd  -1),   8:8, 4:4) |
-                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd   -1),   4:4, 5:5) ;  
+                        GETBITSTR((pSiS->SiS_Pr->CVSyncEnd     ),   4:4, 5:5) ;
 
-   pSiS->SiS_Pr->CCRT1CRTC[14] = 
+   pSiS->SiS_Pr->CCRT1CRTC[14] =
                         GETBITSTR((pSiS->SiS_Pr->CHTotal      >> 3) - 5, 9:8, 1:0) |
                         GETBITSTR((pSiS->SiS_Pr->CHDisplay    >> 3) - 1, 9:8, 3:2) |
                         GETBITSTR((pSiS->SiS_Pr->CHBlankStart >> 3) - 1, 9:8, 5:4) |
                         GETBITSTR((pSiS->SiS_Pr->CHSyncStart  >> 3) + 3, 9:8, 7:6) ;
 
-        
+
    pSiS->SiS_Pr->CCRT1CRTC[15] =
                         GETBITSTR((pSiS->SiS_Pr->CHBlankEnd >> 3) - 1, 7:6, 1:0) |
-                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ; 
-			
+                        GETBITSTR((pSiS->SiS_Pr->CHSyncEnd  >> 3) + 3, 5:5, 2:2) ;
+
    switch(depth) {
-   case 8: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x223b;
+   case 8:
+      	pSiS->SiS_Pr->CModeFlag |= 0x223b;
 	break;
-   case 16: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x227d;
+   case 16:
+      	pSiS->SiS_Pr->CModeFlag |= 0x227d;
 	break;
-   case 32: 			
-      	pSiS->SiS_Pr->CModeFlag = 0x22ff;
+   case 32:
+      	pSiS->SiS_Pr->CModeFlag |= 0x22ff;
 	break;		
    default: 
    	return 0;	
    }	
    
    if(pSiS->SiS_Pr->CFlags & V_DBLSCAN) 
-   	pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
-   if((pSiS->SiS_Pr->CVDisplay >= 1024)	|| 
-      (pSiS->SiS_Pr->CVTotal >= 1024)   || 
+      pSiS->SiS_Pr->CModeFlag |= DoubleScanMode;
+
+   if((pSiS->SiS_Pr->CVDisplay >= 1024)	||
+      (pSiS->SiS_Pr->CVTotal >= 1024)   ||
       (pSiS->SiS_Pr->CHDisplay >= 1024))
-	pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+      pSiS->SiS_Pr->CModeFlag |= LineCompareOff;
+
    if(pSiS->SiS_Pr->CFlags & V_CLKDIV2)
-        pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
-   
+      pSiS->SiS_Pr->CModeFlag |= HalfDCLK;
+
    pSiS->SiS_Pr->CInfoFlag = 0x0007;
-   if(pSiS->SiS_Pr->CFlags & V_NHSYNC) 
-   	pSiS->SiS_Pr->CInfoFlag |= 0x4000;
-   if(pSiS->SiS_Pr->CFlags & V_NVSYNC) 
-   	pSiS->SiS_Pr->CInfoFlag |= 0x8000;
-   if(pSiS->SiS_Pr->CFlags & V_INTERLACE)	
-	pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
+
+   if(pSiS->SiS_Pr->CFlags & V_NHSYNC)
+      pSiS->SiS_Pr->CInfoFlag |= 0x4000;
+
+   if(pSiS->SiS_Pr->CFlags & V_NVSYNC)
+      pSiS->SiS_Pr->CInfoFlag |= 0x8000;
+
+   if(pSiS->SiS_Pr->CFlags & V_INTERLACE)
+      pSiS->SiS_Pr->CInfoFlag |= InterlaceMode;
 
    pSiS->SiS_Pr->UseCustomMode = TRUE;
 #ifdef TWDEBUG
@@ -5152,13 +3900,13 @@
    	pSiS->SiS_Pr->CSR2B,
 	pSiS->SiS_Pr->CSR2C,
 	pSiS->SiS_Pr->CSRClock);
-#endif   	
+#endif
    return 1;
 }
 
-/* TW: Build a list of supported modes */
+/* Build a list of supported modes */
 DisplayModePtr
-SiSBuildBuiltInModeList(ScrnInfoPtr pScrn)
+SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi)
 {
    SISPtr         pSiS = SISPTR(pScrn);
    unsigned short VRE, VBE, VRS, VBS, VDE, VT;
@@ -5166,23 +3914,28 @@
    unsigned char  sr_data, cr_data, cr_data2, cr_data3;
    unsigned char  sr2b, sr2c;
    float          num, denum, postscalar, divider;
-   int            A, B, C, D, E, F, temp, i, j, index, vclkindex;
-   DisplayModePtr new = NULL, current = NULL, first = NULL, backup = NULL;
+   int            A, B, C, D, E, F, temp, i, j, k, l, index, vclkindex;
+   DisplayModePtr new = NULL, current = NULL, first = NULL;
+   BOOLEAN        done = FALSE;
+#if 0
+   DisplayModePtr backup = NULL;
+#endif
 
    pSiS->backupmodelist = NULL;
-   
+   pSiS->AddedPlasmaModes = FALSE;
+
    /* Initialize our pointers */
    if(pSiS->VGAEngine == SIS_300_VGA) {
 #ifdef SIS300
-	InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+      InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
 #else
-	return NULL;
+      return NULL;
 #endif
    } else if(pSiS->VGAEngine == SIS_315_VGA) {
 #ifdef SIS315H
-       	InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+      InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
 #else
-	return NULL;
+      return NULL;
 #endif
    } else return NULL;
 
@@ -5190,19 +3943,21 @@
    while(pSiS->SiS_Pr->SiS_RefIndex[i].Ext_InfoFlag != 0xFFFF) {
 
       index = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRT1CRTC;
-#if 0 /* Not any longer */    
-      if(pSiS->VGAEngine == SIS_300_VGA) index &= 0x3F;
-#endif      
-
-      if(((pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) && (!pSiS->DSTN)) ||
-      	 ((pSiS->DSTN) &&
-	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes < 512) &&
-	  (pSiS->SiS_Pr->SiS_RefIndex[i].XRes != 320) &&
-	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes != 480)))  {
+
+      /* 0x5a (320x240) is a pure FTSN mode, not DSTN! */
+      if((!pSiS->FSTN) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID == 0x5a))  {
            i++;
       	   continue;
       }
-      
+      if((pSiS->FSTN) &&
+         (pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240) &&
+	 (pSiS->SiS_Pr->SiS_RefIndex[i].ModeID != 0x5a)) {
+	   i++;
+	   continue;
+      }
+
       if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
       memset(new, 0, sizeof(DisplayModeRec));
       if(!(new->name = xalloc(10))) {
@@ -5216,13 +3971,13 @@
       }
 
       current = new;
-      
+
       sprintf(current->name, "%dx%d", pSiS->SiS_Pr->SiS_RefIndex[i].XRes,
                                       pSiS->SiS_Pr->SiS_RefIndex[i].YRes);
 
       current->status = MODE_OK;
 
-      current->type = M_T_DEFAULT; 
+      current->type = M_T_DEFAULT;
 
       vclkindex = pSiS->SiS_Pr->SiS_RefIndex[i].Ext_CRTVCLK;
       if(pSiS->VGAEngine == SIS_300_VGA) vclkindex &= 0x3F;
@@ -5235,7 +3990,7 @@
               ( (((sr2c >> 5) & 0x03) == 0x02) ? 6.0 : 8.0) : (((sr2c >> 5) & 0x03) + 1.0);
       num = (sr2b & 0x7f) + 1.0;
       denum = (sr2c & 0x1f) + 1.0;
-      
+
 #ifdef TWDEBUG
       xf86DrvMsg(0, X_INFO, "------------\n");
       xf86DrvMsg(0, X_INFO, "sr2b: %x sr2c %x div %f ps %f num %f denum %f\n",
@@ -5303,10 +4058,29 @@
 
       D = B - F - C;
 
-      current->HDisplay   = (E * 8);
-      current->HSyncStart = (E * 8) + (F * 8);
-      current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
-      current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
+      if((pSiS->SiS_Pr->SiS_RefIndex[i].XRes == 320) &&
+	 ((pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 200) ||
+	  (pSiS->SiS_Pr->SiS_RefIndex[i].YRes == 240))) {
+
+	 /* Terrible hack, but correct CRTC data for
+	  * these modes only produces a black screen...
+	  * (HRE is 0, leading into a too large C and
+	  * a negative D. The CRT controller does not
+	  * seem to like correcting HRE to 50
+	  */
+	 current->HDisplay   = 320;
+         current->HSyncStart = 328;
+         current->HSyncEnd   = 376;
+         current->HTotal     = 400;
+
+      } else {
+
+         current->HDisplay   = (E * 8);
+         current->HSyncStart = (E * 8) + (F * 8);
+         current->HSyncEnd   = (E * 8) + (F * 8) + (C * 8);
+         current->HTotal     = (E * 8) + (F * 8) + (C * 8) + (D * 8);
+
+      }
 
 #ifdef TWDEBUG
       xf86DrvMsg(0, X_INFO,
@@ -5430,7 +4204,7 @@
 	 current->VSyncStart <<= 1;
 	 current->VSyncEnd <<= 1;
 	 current->VTotal <<= 1;
-	 current->VTotal |= 1; 
+	 current->VTotal |= 1;
       }
       if(current->Flags & V_DBLSCAN) {
          current->Clock >>= 1;
@@ -5440,6 +4214,7 @@
 	 current->VTotal >>= 1;
       }
 
+#if 0
       if((backup = xalloc(sizeof(DisplayModeRec)))) {
          if(!pSiS->backupmodelist) pSiS->backupmodelist = backup;
 	 else {
@@ -5458,6 +4233,7 @@
 	 backup->Flags = current->Flags;
 	 backup->Clock = current->Clock;
       }
+#endif
 
 #ifdef TWDEBUG
       xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@@ -5470,56 +4246,317 @@
       i++;
    }
 
+   /* Add non-standard LCD modes for panel's detailed timings */
+
+   if(!includelcdmodes) return first;
+
+   if(pSiS->SiS_Pr->CP_Vendor) {
+      xf86DrvMsg(0, X_INFO, "Checking database for vendor %x, product %x\n",
+         pSiS->SiS_Pr->CP_Vendor, pSiS->SiS_Pr->CP_Product);
+   }
+
+   i = 0;
+   while((!done) && (SiS_PlasmaTable[i].vendor) && (pSiS->SiS_Pr->CP_Vendor)) {
+
+     if(SiS_PlasmaTable[i].vendor == pSiS->SiS_Pr->CP_Vendor) {
+
+        for(j=0; j<SiS_PlasmaTable[i].productnum; j++) {
+
+	    if(SiS_PlasmaTable[i].product[j] == pSiS->SiS_Pr->CP_Product) {
+
+	       xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+	       	  "Identified %s panel, adding specific modes\n",
+		  SiS_PlasmaTable[i].plasmaname);
+
+	       for(k=0; k<SiS_PlasmaTable[i].modenum; k++) {
+
+	          if(isfordvi) {
+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x80)) continue;
+		  } else {
+		     if(!(SiS_PlasmaTable[i].plasmamodes[k] & 0x40)) continue;
+		  }
+
+	          if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+
+                  memset(new, 0, sizeof(DisplayModeRec));
+                  if(!(new->name = xalloc(10))) {
+      		     xfree(new);
+		     return first;
+                  }
+                  if(!first) first = new;
+                  if(current) {
+                     current->next = new;
+	             new->prev = current;
+                  }
+
+                  current = new;
+
+		  pSiS->AddedPlasmaModes = TRUE;
+
+		  l = SiS_PlasmaTable[i].plasmamodes[k] & 0x3f;
+
+	          sprintf(current->name, "%dx%d", SiS_PlasmaMode[l].HDisplay,
+                                                  SiS_PlasmaMode[l].VDisplay);
+
+                  current->status = MODE_OK;
+
+                  current->type = M_T_BUILTIN;
+
+		  current->Clock = SiS_PlasmaMode[l].clock;
+            	  current->SynthClock = current->Clock;
+
+                  current->HDisplay   = SiS_PlasmaMode[l].HDisplay;
+                  current->HSyncStart = current->HDisplay + SiS_PlasmaMode[l].HFrontPorch;
+                  current->HSyncEnd   = current->HSyncStart + SiS_PlasmaMode[l].HSyncWidth;
+                  current->HTotal     = SiS_PlasmaMode[l].HTotal;
+
+		  current->VDisplay   = SiS_PlasmaMode[l].VDisplay;
+                  current->VSyncStart = current->VDisplay + SiS_PlasmaMode[l].VFrontPorch;
+                  current->VSyncEnd   = current->VSyncStart + SiS_PlasmaMode[l].VSyncWidth;
+                  current->VTotal     = SiS_PlasmaMode[l].VTotal;
+
+                  current->CrtcHDisplay = current->HDisplay;
+                  current->CrtcHBlankStart = current->HSyncStart;
+                  current->CrtcHSyncStart = current->HSyncStart;
+                  current->CrtcHSyncEnd = current->HSyncEnd;
+                  current->CrtcHBlankEnd = current->HSyncEnd;
+                  current->CrtcHTotal = current->HTotal;
+
+                  current->CrtcVDisplay = current->VDisplay;
+                  current->CrtcVBlankStart = current->VSyncStart;
+                  current->CrtcVSyncStart = current->VSyncStart;
+                  current->CrtcVSyncEnd = current->VSyncEnd;
+                  current->CrtcVBlankEnd = current->VSyncEnd;
+                  current->CrtcVTotal = current->VTotal;
+
+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_HSYNCP)
+                     current->Flags |= V_PHSYNC;
+                  else
+                     current->Flags |= V_NHSYNC;
+
+                  if(SiS_PlasmaMode[l].SyncFlags & SIS_PL_VSYNCP)
+                     current->Flags |= V_PVSYNC;
+                  else
+                     current->Flags |= V_NVSYNC;
+
+		  if(current->HDisplay > pSiS->LCDwidth)
+		     pSiS->LCDwidth = pSiS->SiS_Pr->CP_MaxX = current->HDisplay;
+	          if(current->VDisplay > pSiS->LCDheight)
+		     pSiS->LCDheight = pSiS->SiS_Pr->CP_MaxY = current->VDisplay;
+
+               }
+	       done = TRUE;
+	       break;
+	    }
+	}
+     }
+
+     i++;
+
+   }
+
+   if(pSiS->SiS_Pr->CP_HaveCustomData) {
+
+      for(i=0; i<7; i++) {
+
+         if(pSiS->SiS_Pr->CP_DataValid[i]) {
+
+            if(!(new = xalloc(sizeof(DisplayModeRec)))) return first;
+
+            memset(new, 0, sizeof(DisplayModeRec));
+            if(!(new->name = xalloc(10))) {
+      		xfree(new);
+		return first;
+            }
+            if(!first) first = new;
+            if(current) {
+               current->next = new;
+	       new->prev = current;
+            }
+
+            current = new;
+
+            sprintf(current->name, "%dx%d", pSiS->SiS_Pr->CP_HDisplay[i],
+                                            pSiS->SiS_Pr->CP_VDisplay[i]);
+
+            current->status = MODE_OK;
+
+            current->type = M_T_BUILTIN;
+
+            current->Clock = pSiS->SiS_Pr->CP_Clock[i];
+            current->SynthClock = current->Clock;
+
+            current->HDisplay   = pSiS->SiS_Pr->CP_HDisplay[i];
+            current->HSyncStart = pSiS->SiS_Pr->CP_HSyncStart[i];
+            current->HSyncEnd   = pSiS->SiS_Pr->CP_HSyncEnd[i];
+            current->HTotal     = pSiS->SiS_Pr->CP_HTotal[i];
+
+            current->VDisplay   = pSiS->SiS_Pr->CP_VDisplay[i];
+            current->VSyncStart = pSiS->SiS_Pr->CP_VSyncStart[i];
+            current->VSyncEnd   = pSiS->SiS_Pr->CP_VSyncEnd[i];
+            current->VTotal     = pSiS->SiS_Pr->CP_VTotal[i];
+
+            current->CrtcHDisplay = current->HDisplay;
+            current->CrtcHBlankStart = pSiS->SiS_Pr->CP_HBlankStart[i];
+            current->CrtcHSyncStart = current->HSyncStart;
+            current->CrtcHSyncEnd = current->HSyncEnd;
+            current->CrtcHBlankEnd = pSiS->SiS_Pr->CP_HBlankEnd[i];
+            current->CrtcHTotal = current->HTotal;
+
+            current->CrtcVDisplay = current->VDisplay;
+            current->CrtcVBlankStart = pSiS->SiS_Pr->CP_VBlankStart[i];
+            current->CrtcVSyncStart = current->VSyncStart;
+            current->CrtcVSyncEnd = current->VSyncEnd;
+            current->CrtcVBlankEnd = pSiS->SiS_Pr->CP_VBlankEnd[i];
+            current->CrtcVTotal = current->VTotal;
+
+	    if(pSiS->SiS_Pr->CP_SyncValid[i]) {
+               if(pSiS->SiS_Pr->CP_HSync_P[i])
+                  current->Flags |= V_PHSYNC;
+               else
+                  current->Flags |= V_NHSYNC;
+
+               if(pSiS->SiS_Pr->CP_VSync_P[i])
+                  current->Flags |= V_PVSYNC;
+               else
+                  current->Flags |= V_NVSYNC;
+	    } else {
+	       /* No sync data? Use positive sync... */
+	       current->Flags |= V_PHSYNC;
+	       current->Flags |= V_PVSYNC;
+	    }
+         }
+      }
+   }
+
    return first;
 
 }
+
+/* Build a list of supported modes */
+int
+SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber)
+{
+   SISPtr         pSiS = SISPTR(pScrn);
+   int i;
+
+   /* Initialize our pointers */
+   if(pSiS->VGAEngine == SIS_300_VGA) {
+#ifdef SIS300
+	InitTo300Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+#else
+	return -1;
+#endif
+   } else if(pSiS->VGAEngine == SIS_315_VGA) {
+#ifdef SIS315H
+       	InitTo310Pointer(pSiS->SiS_Pr, &pSiS->sishw_ext);
+#else
+	return -1;
 #endif
+   } else return -1;
+
+   if(modenumber <= 0x13) return modenumber;
+
+   i = 0;
+   while(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID != 0xff) {
+      if(pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_ModeID == modenumber) {
+         return (int)pSiS->SiS_Pr->SiS_EModeIDTable[i].Ext_VESAID;
+      }
+      i++;
+   }
+   return -1;
+}
+#endif  /* Xfree86 */
 
 #ifdef LINUX_KERNEL
 int
-sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 			  unsigned char modeno, unsigned char rateindex)
 {
     USHORT ModeNo = modeno;
     USHORT ModeIdIndex = 0, ClockIndex = 0;
     USHORT RefreshRateTableIndex = 0;
-    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
-    ULONG  temp = 0;
     int    Clock;
-    
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+
+    if(HwInfo->jChipType < SIS_315H) {
 #ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo300Pointer(SiS_Pr, HwInfo);
 #else
-       return 65;
+       return 65 * 1000;
 #endif
     } else {
 #ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo310Pointer(SiS_Pr, HwInfo);
 #else
-       return 65;
+       return 65 * 1000;
 #endif
     }
-    
-    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
-    if(!temp) {
+
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) {;
     	printk(KERN_ERR "Could not find mode %x\n", ModeNo);
-    	return 65;
+    	return 65 * 1000;
     }
-    
+
     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
     RefreshRateTableIndex += (rateindex - 1);
     ClockIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
        ClockIndex &= 0x3F;
     }
-    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000 * 1000;
+    Clock = SiS_Pr->SiS_VCLKData[ClockIndex].CLOCK * 1000;
     
     return(Clock);
 }
 
+BOOLEAN
+sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex)
+{
+    USHORT ModeNo = modeno;
+    USHORT ModeIdIndex = 0, CRT1Index = 0;
+    USHORT RefreshRateTableIndex = 0;
+    unsigned char  sr_data, cr_data, cr_data2;
+
+    if(HwInfo->jChipType < SIS_315H) {
+#ifdef SIS300
+       InitTo300Pointer(SiS_Pr, HwInfo);
+#else
+       return FALSE;
+#endif
+    } else {
+#ifdef SIS315H
+       InitTo310Pointer(SiS_Pr, HwInfo);
+#else
+       return FALSE;
+#endif
+    }
+
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return FALSE;
+
+    RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+    RefreshRateTableIndex += (rateindex - 1);
+    CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
+    *htotal = (((cr_data & 0xff) | ((unsigned short) (sr_data & 0x03) << 8)) + 5) * 8;
+
+    sr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+    cr_data = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
+    cr_data2 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+    *vtotal = ((cr_data & 0xFF) |
+               ((unsigned short)(cr_data2 & 0x01) <<  8) |
+	       ((unsigned short)(cr_data2 & 0x20) <<  4) |
+	       ((unsigned short)(sr_data  & 0x01) << 10)) + 2;
+
+    if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag & InterlaceMode)
+       *vtotal *= 2;
+
+    return TRUE;
+}
+
 int
-sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 			 unsigned char modeno, unsigned char rateindex,
 			 ULONG *left_margin, ULONG *right_margin, 
 			 ULONG *upper_margin, ULONG *lower_margin,
@@ -5529,29 +4566,27 @@
     USHORT ModeNo = modeno;
     USHORT ModeIdIndex = 0, index = 0;
     USHORT RefreshRateTableIndex = 0;
-    UCHAR  *ROMAddr  = HwDeviceExtension->pjVirtualRomBase;
     unsigned short VRE, VBE, VRS, VBS, VDE, VT;
     unsigned short HRE, HBE, HRS, HBS, HDE, HT;
     unsigned char  sr_data, cr_data, cr_data2, cr_data3;
     int            A, B, C, D, E, F, temp, j;
    
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
 #ifdef SIS300
-       InitTo300Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo300Pointer(SiS_Pr, HwInfo);
 #else
        return 0;
 #endif
     } else {
 #ifdef SIS315H
-       InitTo310Pointer(SiS_Pr, HwDeviceExtension);
+       InitTo310Pointer(SiS_Pr, HwInfo);
 #else
        return 0;
 #endif
     }
     
-    temp = SiS_SearchModeID(SiS_Pr, ROMAddr, &ModeNo, &ModeIdIndex);
-    if(!temp) return 0;
-    
+    if(!(SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex))) return 0;
+
     RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
     RefreshRateTableIndex += (rateindex - 1);
     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
@@ -5606,17 +4641,32 @@
     C = (temp > 0) ? temp : (temp + 64);
 
     D = B - F - C;
-    
-    *left_margin = D * 8;
-    *right_margin = F * 8;
-    *hsync_len = C * 8;
+
+    if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].XRes == 320) &&
+       ((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 200) ||
+	(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].YRes == 240))) {
+
+	 /* Terrible hack, but the correct CRTC data for
+	  * these modes only produces a black screen...
+	  */
+       *left_margin = (400 - 376);
+       *right_margin = (328 - 320);
+       *hsync_len = (376 - 328);
+
+    } else {
+
+       *left_margin = D * 8;
+       *right_margin = F * 8;
+       *hsync_len = C * 8;
+
+    }
 
     sr_data = SiS_Pr->SiS_CRT1Table[index].CR[13];
 
     cr_data = SiS_Pr->SiS_CRT1Table[index].CR[6];
-    
+
     cr_data2 = SiS_Pr->SiS_CRT1Table[index].CR[7];
-    
+
     /* Vertical total */
     VT = (cr_data & 0xFF) |
          ((unsigned short) (cr_data2 & 0x01) << 8) |
@@ -5699,19 +4749,19 @@
 	  j++;
       }
     }       
-       
-#if 0  /* That's bullshit, only the resolution needs to be shifted */    
+
     if((*vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+#if 0  /* Do this? */
        *upper_margin <<= 1;
        *lower_margin <<= 1;
        *vsync_len <<= 1;
+#endif
     } else if((*vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
        *upper_margin >>= 1;
        *lower_margin >>= 1;
        *vsync_len >>= 1;
-    }  
-#endif
-          
+    }
+
     return 1;       
 }			  
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/init.h fbdev-2.6/drivers/video/sis/init.h
--- linus-2.6/drivers/video/sis/init.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/init.h	Thu Oct 16 14:13:41 2003
@@ -1,19 +1,47 @@
+/* $XFree86$ */
+/*
+ * Data and prototypes for init.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
+
 #ifndef _INIT_
 #define _INIT_
 
 #include "osdef.h"
+
 #include "initdef.h"
 #include "vgatypes.h"
 #include "vstruct.h"
 
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#include <stdlib.h>
-#endif
-
 #ifdef LINUX_XF86
 #include "xf86.h"
 #include "xf86Pci.h"
@@ -24,6 +52,9 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#ifdef SIS_CP
+#undef SIS_CP
+#endif
 #include <linux/config.h>
 #include <linux/version.h>
 #include <linux/types.h>
@@ -36,19 +67,6 @@
 #endif
 #endif
 
-#ifdef WIN2000
-#include <stdio.h>
-#include <string.h>
-#include <miniport.h>
-#include "dderror.h"
-#include "devioctl.h"
-#include "miniport.h"
-#include "ntddvdeo.h"
-#include "video.h"
-#include "sisv.h"
-#include "tools.h"
-#endif
-
 const USHORT SiS_DRAMType[17][5]={
 	{0x0C,0x0A,0x02,0x40,0x39},
 	{0x0D,0x0A,0x01,0x40,0x48},
@@ -144,187 +162,2397 @@
 	0x0B,0x0C,0x0D,0x0F,0x10
 };
 
-void     SiS_SetReg1(USHORT, USHORT, USHORT);
-void     SiS_SetReg2(SiS_Private *, USHORT, USHORT, USHORT);
-void     SiS_SetReg3(USHORT, USHORT);
-void     SiS_SetReg4(USHORT, ULONG);
-void     SiS_SetReg5(USHORT, USHORT);
-UCHAR    SiS_GetReg1(USHORT, USHORT);
-UCHAR    SiS_GetReg2(USHORT);
-ULONG    SiS_GetReg3(USHORT);
-USHORT   SiS_GetReg4(USHORT);
-void     SiS_ClearDAC(SiS_Private *SiS_Pr, ULONG);
-void     SiS_SetMemoryClock(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetDRAMModeRegister(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo);
-void     SiS_IsLowResolution(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-
-#ifdef SIS300
-void     SiS_SetDRAMSize_300(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_ChkBUSWidth_300(SiS_Private *SiS_Pr, ULONG FBAddress);
-#endif
-
-#ifdef SIS315H
-UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_DDR_MRS(SiS_Private *SiS_Pr);
-void     SiS_SDR_MRS(SiS_Private *SiS_Pr);
-void     SiS_DisableRefresh(SiS_Private *SiS_Pr);
-void     SiS_EnableRefresh(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
-void     SiS_SetDRAMSize_310(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
-void     SiS_DisableChannelInterleaving(SiS_Private *SiS_Pr, int index,USHORT SiS_DDRDRAM_TYPE[][5]);
-void     SiS_SetDRAMSizingType(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5]);
-void     SiS_CheckBusWidth_310(SiS_Private *SiS_Pr, UCHAR *ROMAddress,ULONG FBAddress,
-                               PSIS_HW_DEVICE_INFO HwDeviceExtension);
-int      SiS_SetRank(SiS_Private *SiS_Pr, int index,UCHAR RankNo,USHORT DRAMTYPE_TABLE[][5]);
-int      SiS_SetDDRChannel(SiS_Private *SiS_Pr, int index,UCHAR ChannelNo,
-                           USHORT DRAMTYPE_TABLE[][5]);
-int      SiS_CheckColumn(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckBanks(SiS_Private *SiS_Pr, int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckDDRRank(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_CheckDDRRanks(SiS_Private *SiS_Pr, int RankNo,int index,USHORT DRAMTYPE_TABLE[][5],ULONG FBAddress);
-int      SiS_SDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
-int      SiS_DDRSizing(SiS_Private *SiS_Pr, ULONG FBAddress);
-int      Is315E(SiS_Private *SiS_Pr);
-void     SiS_VerifyMclk(SiS_Private *SiS_Pr, ULONG FBAddr);
-#endif
-
-void     SiS_HandleCRT1(SiS_Private *SiS_Pr);
-void     SiS_Handle301B_1400x1050(SiS_Private *SiS_Pr, USHORT ModeNo);
-void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
-void     SiS_Delay15us(SiS_Private *SiS_Pr);
-BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
-BOOLEAN  SiS_CheckMemorySize(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                             USHORT ModeNo,USHORT ModeIdIndex);
-UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_SetSeqRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_SetMiscRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_SetCRTCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                         USHORT StandTableIndex);
-void     SiS_SetATTRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex,
-                        PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGRCRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT StandTableIndex);
-void     SiS_ClearExt1Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetSync(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT RefreshRateTableIndex);
-void     SiS_SetCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,
-			 PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
-void     SiS_ResetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT1VCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO,
-                         USHORT RefreshRateTableIndex);
-void     SiS_SetVCLKState(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO, USHORT ModeNo,
-                          USHORT RefreshRateTableIndex, USHORT ModeIdIndex);
-void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_WriteDAC(SiS_Private *SiS_Pr, USHORT, USHORT, USHORT, USHORT, USHORT, USHORT);
-void     SiS_DisplayOn(SiS_Private *SiS_Pr);
-void 	 SiS_DisplayOff(SiS_Private *SiS_Pr);
-void     SiS_SetCRT1ModeRegs(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO,USHORT ModeNo,
-                             USHORT ModeIdIndex,USHORT RefreshRateTableIndex);
-void     SiS_GetVBType(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-USHORT   SiS_ChkBUSWidth(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
-USHORT   SiS_GetModeIDLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
-USHORT   SiS_GetRefindexLength(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT);
-void     SiS_SetInterlace(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT RefreshRateTableIndex);
-void     SiS_Set_LVDS_TRUMPION(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT1Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
-#ifdef SIS315H
-void     SiS_SetCRT1FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT,USHORT,PSIS_HW_DEVICE_INFO);
-#endif
-#ifdef SIS300
-void     SiS_SetCRT1FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
-                             USHORT RefreshRateTableIndex);
-void     SiS_SetCRT1FIFO_630(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,PSIS_HW_DEVICE_INFO,
-                             USHORT RefreshRateTableIndex);
-USHORT   SiS_CalcDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT VCLK,
-                       USHORT colordepth, USHORT MCLK);
-USHORT   SiS_DoCalcDelay(SiS_Private *SiS_Pr, USHORT MCLK, USHORT VCLK, USHORT colordepth, USHORT key);
-USHORT   SiS_CalcDelay2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, UCHAR,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
-void     SiS_ClearBuffer(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT ModeNo);
-void     SiS_SetCRT1Group(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                          USHORT ModeNo,USHORT ModeIdIndex,USHORT BaseAddr);
-void     SiS_DetectMonitor(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-void     SiS_GetSenseStatus(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,UCHAR *ROMAddr);
-USHORT   SiS_TestMonitorType(SiS_Private *SiS_Pr, UCHAR R_DAC,UCHAR G_DAC,UCHAR B_DAC);
-USHORT   SiS_SenseCHTV(SiS_Private *SiS_Pr);
-BOOLEAN  SiS_Sense(SiS_Private *SiS_Pr, USHORT tempbx,USHORT tempcx);
-BOOLEAN  SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
-BOOLEAN  SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
-USHORT   SiS_SenseLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO);
-void     SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
-void     SiSInitPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT ModeNo);
-void     SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiSDetermineROMUsage(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr);
+static const SiS_StResInfoStruct SiS_StResInfo[]=
+{
+	{ 640,400},
+	{ 640,350},
+	{ 720,400},
+	{ 720,350},
+	{ 640,480}
+};
 
-#ifdef LINUX_XF86
-USHORT 		SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
-void    	SiS_SetPitch(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
-void    	SiS_SetPitchCRT1(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
-void    	SiS_SetPitchCRT2(SiS_Private *SiS_Pr, ScrnInfoPtr pScrn, UShort BaseAddr);
-extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
-	     	 		    int *out_sbit, int *out_scale);
-extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
-extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
-extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode);
+static const SiS_ModeResInfoStruct SiS_ModeResInfo[] =
+{
+	{  320, 200, 8, 8},   /* 0x00 */
+	{  320, 240, 8, 8},   /* 0x01 */
+	{  320, 400, 8, 8},   /* 0x02 */
+	{  400, 300, 8, 8},   /* 0x03 */
+	{  512, 384, 8, 8},   /* 0x04 */
+	{  640, 400, 8,16},   /* 0x05 */
+	{  640, 480, 8,16},   /* 0x06 */
+	{  800, 600, 8,16},   /* 0x07 */
+	{ 1024, 768, 8,16},   /* 0x08 */
+	{ 1280,1024, 8,16},   /* 0x09 */
+	{ 1600,1200, 8,16},   /* 0x0a */
+	{ 1920,1440, 8,16},   /* 0x0b */
+	{ 2048,1536, 8,16},   /* 0x0c */
+	{  720, 480, 8,16},   /* 0x0d */
+	{  720, 576, 8,16},   /* 0x0e */
+	{ 1280, 960, 8,16},   /* 0x0f */
+	{  800, 480, 8,16},   /* 0x10 */
+	{ 1024, 576, 8,16},   /* 0x11 */
+	{ 1280, 720, 8,16},   /* 0x12 */
+	{  856, 480, 8,16},   /* 0x13 */
+	{ 1280, 768, 8,16},   /* 0x14 */
+	{ 1400,1050, 8,16},   /* 0x15 */
+	{ 1152, 864, 8,16},   /* 0x16 */
+	{  848, 480, 8,16},   /* 0x17 */
+	{ 1360, 768, 8,16},   /* 0x18 */
+	{ 1024, 600, 8,16},   /* 0x19 */
+	{ 1152, 768, 8,16},   /* 0x1a */
+	{  768, 576, 8,16},   /* 0x1b */
+	{ 1360,1024, 8,16}    /* 0x1c */
+};
+
+static SiS_StandTableStruct SiS_StandTable[]=
+{
+/* 0x00: MD_0_200 */
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x01: MD_1_200 */
+ {
+  0x28,0x18,0x08,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x02: MD_2_200 */
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x03: MD_3_200 - mode 0x03 - 0 */
+ {
+  0x50,0x18,0x08,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x04: MD_4 */
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
+/* 0x05: MD_5 */
+ {
+  0x28,0x18,0x08,0x4000,
+  {0x09,0x03,0x00,0x02},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,   /* 0x2c is 2b for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
+   0xff},
+  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x03,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
+   0xff}
+ },
+/* 0x06: MD_6 */
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x01,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,   /* 55,81 is 54,80 for 300 */
+   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
+   0xff},
+  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
+   0x01,0x00,0x01,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
+   0xff}
+ },
+/* 0x07: MD_7 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x00,0x03,0x00,0x03},
+  0xa6,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
+/* 0x08: MDA_DAC */
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x00,0x00,0x00,0x15},
+  0x15,
+  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
+   0x15,0x15,0x15,0x15},
+  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f}
+ },
+/* 0x09: CGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x00},
+  0x10,
+  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
+   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
+   0x04},
+  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
+   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
+   0x3e,0x2b,0x3b,0x2f},
+  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
+/* 0x0a: EGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x05,0x15,0x20},
+  0x30,
+  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
+   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
+   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
+   0x06},
+  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
+   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
+   0x1e,0x0b,0x1b,0x0f},
+  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
+   0x3f}
+ },
+/* 0x0b: VGA_DAC */
+ {
+  0x00,0x10,0x04,0x0114,
+  {0x11,0x09,0x15,0x2a},
+  0x3a,
+  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
+   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
+   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
+   0x1f},
+  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
+   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
+   0x1c,0x0e,0x11,0x15},
+  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
+   0x04}
+ },
+/* 0x0c */
+ {
+  0x08,0x0c,0x10,0x0a08,
+  {0x0c,0x0e,0x10,0x0b},
+  0x0c,
+  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
+   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
+   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
+   0x06},
+  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
+   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
+/* 0x0d: MD_D */
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x09,0x0f,0x00,0x06},
+  0x63,
+  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,     /* 2c is 2b for 300 */
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x0e: MD_E */
+ {
+  0x50,0x18,0x08,0x4000,
+  {0x01,0x0f,0x00,0x06},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,     /* 55,81 is 54,80 for 300 */
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x0f: ExtVGATable - modes > 0x13 */
+ {
+  0x00,0x00,0x00,0x0000,
+  {0x01,0x0f,0x00,0x0e},
+  0x23,
+  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x01,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ },
+/* 0x10: ROM_SAVEPTR - totally different for 300 */
+ {
+  0x9f,0x3b,0x00,0x00c0,
+  {0x00,0x00,0x00,0x00},
+  0x00,
+  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
+   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
+   0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00,0x00,0x00,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x00}
+ },
+/* 0x11: MD_F */
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa2,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
+   0xff},
+  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
+   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
+   0x0b,0x00,0x05,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
+   0xff}
+ },
+/* 0x12: MD_10 */
+ {
+  0x50,0x18,0x0e,0x8000,
+  {0x01,0x0f,0x00,0x06},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,    /* 82,84 is 83,85 on 300 */
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x13: MD_0_350 */
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x14: MD_1_350 */
+ {
+  0x28,0x18,0x0e,0x0800,
+  {0x09,0x03,0x00,0x02},
+  0xa3,
+  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x15: MD_2_350 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x16: MD_3_350 - mode 0x03 - 1 */
+ {
+  0x50,0x18,0x0e,0x1000,
+  {0x01,0x03,0x00,0x02},
+  0xa3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
+   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x08,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x17: MD_0_1_400 */
+ {
+  0x28,0x18,0x10,0x0800,
+  {0x08,0x03,0x00,0x02},
+  0x67,
+  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,    /* b1 is a0 on 300 */
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x18: MD_2_3_400 - mode 0x03 - 2 */
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x67,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x0c,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
+   0xff}
+ },
+/* 0x19: MD_7_400 */
+ {
+  0x50,0x18,0x10,0x1000,
+  {0x00,0x03,0x00,0x02},
+  0x66,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
+   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
+   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+   0x0e,0x00,0x0f,0x08},
+  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
+   0xff}
+ },
+/* 0x1a: MD_11 */
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,    /* e9,8b is ea,8c on 300 */
+   0xff},
+  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
+   0xff}
+ },
+/* 0x1b: ExtEGATable - Modes <= 0x02 */
+ {
+  0x50,0x1d,0x10,0xa000,
+  {0x01,0x0f,0x00,0x06},
+  0xe3,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,    /* 55,81 is 54,80 on 300 */
+   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,    /* e9,8b is ea,8c on 300 */
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
+   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+   0x01,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
+   0xff}
+ },
+/* 0x1c: MD_13 */
+ {
+  0x28,0x18,0x08,0x2000,
+  {0x01,0x0f,0x00,0x0e},
+  0x63,
+  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,    /* 55,81 is 54,80 on 300 */
+   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
+   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
+   0xff},
+  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+   0x41,0x00,0x0f,0x00},
+  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
+   0xff}
+ }
+};
+
+static const UCHAR SiS_NTSCTiming[] = {
+	0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
+	0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
+	0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
+	0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
+	0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
+	0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
+	0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00
+};
+
+static const UCHAR SiS_PALTiming[] = {
+	0x19,0x52,0x35,0x6e,0x04,0x38,0x3d,0x70,
+	0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
+	0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
+	0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
+	0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
+	0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00
+};
+
+static const UCHAR SiS_HiTVExtTiming[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS_HiTVSt1Timing[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0x7b,0xa8,0x03,0xf0,0x87,0x03,
+	0x11,0x15,0x11,0xcf,0x10,0x11,0xcf,0x10,
+	0x35,0x35,0x3b,0x69,0x1d,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x86,
+	0xaf,0x5d,0x0e,0x00,0xfc,0xff,0x2d,0x00
+};
+
+static const UCHAR SiS_HiTVSt2Timing[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x64,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x64,0x90,0x33,0x8c,0x18,0x36,0x3e,0x13,
+	0x2a,0xde,0x2a,0x44,0x40,0x2a,0x44,0x40,
+	0x8e,0x8e,0x82,0x07,0x0b,0x92,0x0f,0x40,
+	0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x3d,
+	0x63,0x4f,0x27,0x00,0xfc,0xff,0x6a,0x00
+};
+
+static const UCHAR SiS_HiTVTextTiming[] = {
+        0x32,0x65,0x2c,0x5f,0x08,0x31,0x3a,0x65,
+	0x28,0x02,0x01,0x3d,0x06,0x3e,0x35,0x6d,
+	0x06,0x14,0x3e,0x35,0x6d,0x00,0xc5,0x3f,
+	0x65,0x90,0xe7,0xbc,0x03,0x0c,0x97,0x03,
+	0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
+	0xc8,0xc8,0x3b,0xd2,0x26,0x92,0x0f,0x40,
+        0x60,0x80,0x14,0x90,0x8c,0x60,0x04,0x96,
+	0x72,0x5c,0x11,0x00,0xfc,0xff,0x32,0x00
+};
+
+static const UCHAR SiS_HiTVGroup3Data[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x5f,
+	0x05,0x21,0xb2,0xb2,0x55,0x77,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x2e,0x58,0x48,0x72,0x44,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x4f,0x7f,0x03,0xa8,0x7d,0x20,0x1a,0xa9,
+	0x14,0x05,0x03,0x7e,0x64,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_HiTVGroup3Simu[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0x95,
+	0xdb,0x20,0xb8,0xb8,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x15,0x26,0xd3,0xe4,0x11,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x67,0x36,0x01,0x47,0x0e,0x10,0xbe,0xb4,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_HiTVGroup3Text[] = {
+        0x00,0x1a,0x22,0x63,0x62,0x22,0x08,0xa7,
+	0xf5,0x20,0xce,0xce,0x55,0x47,0x2a,0xa6,
+	0x25,0x2f,0x47,0xfa,0xc8,0xff,0x8e,0x20,
+	0x8c,0x6e,0x60,0x18,0x2c,0x0c,0x20,0x22,
+	0x56,0x36,0x4f,0x6e,0x3f,0x80,0x00,0x80,
+	0x93,0x3c,0x01,0x50,0x2f,0x10,0xf4,0xca,
+	0x01,0x05,0x03,0x7e,0x65,0x31,0x14,0x75,
+	0x18,0x05,0x18,0x05,0x4c,0xa8,0x01
+};
+
+static const UCHAR SiS_NTSCPhase[]    = {0x21,0xed,0xba,0x08};  /* Was {0x21,0xed,0x8a,0x08}; */
+static const UCHAR SiS_PALPhase[]     = {0x2a,0x05,0xe3,0x00};  /* Was {0x2a,0x05,0xd3,0x00};  */
+static const UCHAR SiS_PALMPhase[]    = {0x21,0xE4,0x2E,0x9B};
+static const UCHAR SiS_PALNPhase[]    = {0x21,0xF4,0x3E,0xBA};
+static const UCHAR SiS_NTSCPhase2[]   = {0x21,0xF0,0x7B,0xD6};
+static const UCHAR SiS_PALPhase2[]    = {0x2a,0x09,0x86,0xe9};
+static const UCHAR SiS_PALMPhase2[]   = {0x21,0xE6,0xEF,0xA4};
+static const UCHAR SiS_PALNPhase2[]   = {0x21,0xF6,0x94,0x46};
+static const UCHAR SiS_SpecialPhase[] = {0x1e,0x8c,0x5c,0x7a};
+
+static const SiS_TVDataStruct  SiS_StPALData[]=
+{
+ {    1,   1, 864, 525,1270, 400, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 350, 100,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 864, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 864, 525,1270, 480,  50,   0, 760,0xf4,0xff,0x1c,0x22},
+ {    1,   1, 864, 525,1270, 600,  50,   0,   0,0xf4,0xff,0x1c,0x22}
+};
+
+static const SiS_TVDataStruct  SiS_ExtPALData[] =
+{
+ {   27,  10, 848, 448,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},  /* 640x400, 320x200 */
+ {  108,  35, 848, 398,1270, 530,  50,   0,  50,0xf4,0xff,0x1c,0x22},
+ {   12,   5, 954, 448,1270, 530,  50,   0,  50,0xf1,0x04,0x1f,0x18},
+ {    9,   4, 960, 463,1644, 438,  50,   0,  50,0xf4,0x0b,0x1c,0x0a},
+ {    9,   4, 848, 528,1270, 530,   0,   0,  50,0xf5,0xfb,0x1b,0x2a},  /* 640x480, 320x240 */
+/*{  36,  25,1060, 648,1316, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},*//* 800x600, 400x300 */
+ {   36,  25,1060, 648,1270, 530, 438,   0, 438,0xeb,0x05,0x25,0x16},  /* 800x600, 400x300 - better */
+ {    3,   2,1080, 619,1270, 540, 438,   0, 438,0xf3,0x00,0x1d,0x20},  /* 720x576 */
+ {    1,   1,1170, 821,1270, 520, 686,   0, 686,0xF3,0x00,0x1D,0x20}   /* 1024x768 */
+};
+
+static const SiS_TVDataStruct  SiS_StNTSCData[]=
+{
+ {    1,   1, 858, 525,1270, 400,  50,   0, 760,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,  50,   0, 640,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 400,   0,   0, 720,0xf1,0x04,0x1f,0x18},
+ {    1,   1, 858, 525,1270, 350,   0,   0, 720,0xf4,0x0b,0x1c,0x0a},
+ {    1,   1, 858, 525,1270, 480,   0,   0, 760,0xf1,0x04,0x1f,0x18}
+};
+
+static const SiS_TVDataStruct  SiS_ExtNTSCData[]=
+{
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},    /* 640x400, 320x200 */
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},    /* 640x480, 320x240 */
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},    /* 800x600, 400x300  */
+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},    /* 720x480 - BETTER (from 300 series) */
+/*{   2,   1, 858, 503,1270, 480,   0, 128,   0,0xee,0x0c,0x22,0x08},*/  /* 720x480  (old, from 650) */
+ {    1,   1,1100, 811,1412, 440,   0, 128,   0,0xee,0x0c,0x22,0x08}     /* 1024x768 CORRECTED */
+/*{  65,  64,1056, 791,1270, 480, 638,   0,   0,0xEE,0x0C,0x22,0x08} */  /* 1024x768 */
+#if 0  /* 300 series was: */
+ {  143,  65, 858, 443,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {   88,  35, 858, 393,1270, 440, 171,   0, 171,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 443,1270, 440,  92,   0,  92,0xf1,0x04,0x1f,0x18},
+ {  143,  70, 924, 393,1270, 440,  92,   0,  92,0xf4,0x0b,0x1c,0x0a},
+ {  143,  76, 836, 523,1270, 440, 224,   0,   0,0xf1,0x05,0x1f,0x16},
+ {  143, 120,1056, 643,1270, 440,   0, 128,   0,0xf4,0x10,0x1c,0x00},
+ {  143,  76, 836, 523,1270, 440,   0, 128,   0,0xee,0x0c,0x22,0x08},
+ {   65,  64,1056, 791,1270, 480, 638,   0,   0,0xf1,0x04,0x1f,0x18}
 #endif
+};
 
-extern USHORT    SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern USHORT    SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-extern void      SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern BOOLEAN   SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                                     PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_PresetScratchregister(SiS_Private *SiS_Pr, USHORT SiS_P3d4,
-                                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr);
-extern BOOLEAN   SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr);
-extern BOOLEAN   SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO );
-extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                               USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension, int chkcrt2mode);
-extern BOOLEAN   SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                                   USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern USHORT    SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-                                    PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern void      SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
-extern void      SiS_LongWait(SiS_Private *SiS_Pr);
-extern void      SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
-extern void      SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
-extern void      SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-extern USHORT    SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-extern void      SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-extern USHORT    SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-extern void      SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-extern USHORT    SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-extern void      SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-extern USHORT    SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-extern BOOLEAN   SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                                    USHORT RefreshRateTableIndex,
-		                    USHORT *ResInfo,USHORT *DisplayType);
-extern USHORT    SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                                 USHORT RefreshRateTableIndex,
-				 PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
-extern BOOLEAN   SiS_IsM650(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern BOOLEAN   SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN   SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern BOOLEAN   SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-extern USHORT    SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
 
+static const SiS_TVDataStruct  SiS_St2HiTVData[]=
+{
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x37c,0x233,0x2b2,0x2bc, 	  0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},
+ {    1,   1, 0x3e8,0x233,0x311,0x2bc,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   2, 0x348,0x233,0x670,0x3c0,0x08d,128, 0, 0x00,0x00,0x00,0x00},
+ {    8,   5, 0x41a,0x2ab,0x670,0x3c0,0x17c,128, 0, 0x00,0x00,0x00,0x00}
+};
+
+static const SiS_TVDataStruct  SiS_ExtHiTVData[]=
+{
+ {    6,   1, 0x348,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x348,0x1e3,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    3,   1, 0x3c0,0x233,0x660,0x3c0,    0,  0, 0, 0x00,0x00,0x00,0x00},
+ {    5,   1, 0x348,0x233,0x670,0x3c0,0x166,128, 0, 0x00,0x00,0x00,0x00},  /* 640x480   */
+ {   16,   5, 0x41a,0x2ab,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x600   */
+ {   25,  12, 0x4ec,0x353,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x768  */
+ {    5,   4, 0x627,0x464,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00},  /* 1280x1024 */
+ {    4,   1, 0x41a,0x233,0x670,0x3c0,0x143,128, 0, 0x00,0x00,0x00,0x00},  /* 800x480   */
+ {    5,   2, 0x578,0x293,0x670,0x3c0,0x032,  0, 0, 0x00,0x00,0x00,0x00},  /* 1024x576  */
+ {    8,   5, 0x6d6,0x323,0x670,0x3c0,0x128,  0, 0, 0x00,0x00,0x00,0x00}   /* 1280x720  */
+};
+
+static const UCHAR SiS_OutputSelect = 0x40;
+
+static const UCHAR SiS_SoftSetting  = 0x30;   /* RAM setting */
+
+static const SiS_LCDDataStruct  SiS_LCD1280x960Data[] =
+{
+	{    9,   2, 800, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    4,   1, 900, 500,1800,1000},
+	{    9,   2, 800, 500,1800,1000},
+	{   30,  11,1056, 625,1800,1000},
+	{    5,   3,1350, 800,1800,1000},
+	{    1,   1,1576,1050,1576,1050},
+	{    1,   1,1800,1000,1800,1000}
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1280x768Data[] =
+{
+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
+	{ 211,  100, 2100,  408, 1688,  802 },
+	{ 211,   64, 1536,  358, 1688,  802 },
+	{ 211,   48,  840,  488, 1688,  802 },
+	{ 211,   72, 1008,  609, 1688,  802 },
+	{ 211,  128, 1400,  776, 1688,  802 },
+	{ 211,  205, 1680, 1041, 1688,  802 },
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1280x768Data[] =
+{
+	{ 211,  100, 2100,  408, 1688,  802 }, /* These values are *wrong* */
+	{ 211,   64, 1536,  358, 1688,  802 }, /* (which is why they aren't used yet) */
+	{ 211,  100, 2100,  408, 1688,  802 },
+	{ 211,   64, 1536,  358, 1688,  802 },
+	{ 211,   48,  840,  488, 1688,  802 },
+	{ 211,   72, 1008,  609, 1688,  802 },
+	{ 211,  128, 1400,  776, 1688,  802 },
+	{ 211,  205, 1680, 1041, 1688,  802 },
+	{ 1,      1, 1688,  802, 1688,  802 }  /* That's the only one that *might* be correct */
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1280x768[] =
+{  /* All values guessed */
+        { 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802},
+	{ 1, 1, 1688,  802, 1688,  802}
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1400x1050Data[] =
+{
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1400x1050Data[] =
+{
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,  100, 2100,  408, 1688, 1066 },
+	{ 211,   64, 1536,  358, 1688, 1066 },
+	{ 211,   48,  840,  488, 1688, 1066 },
+	{ 211,   72, 1008,  609, 1688, 1066 },
+	{ 211,  128, 1400,  776, 1688, 1066 },
+	{ 211,  205, 1680, 1041, 1688, 1066 },
+	{   1,    1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1400x1050[] =
+{
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 },
+	{ 1, 1, 1688, 1066, 1688, 1066 }
+};
+
+static const SiS_LCDDataStruct  SiS_StLCD1600x1200Data[] =
+{
+	{27,  4, 800, 500, 2160, 1250 },
+	{27,  4, 800, 500, 2160, 1250 },
+	{ 6,  1, 900, 500, 2160, 1250 },
+	{ 6,  1, 900, 500, 2160, 1250 },
+	{27,  1, 800, 500, 2160, 1250 },
+	{ 4,  1,1080, 625, 2160, 1250 },
+	{ 5,  2,1350, 800, 2160, 1250 },
+	{135,88,1600,1100, 2160, 1250 },
+	{135,88,1600,1100, 2160, 1250 },
+	{ 1,  1,2160,1250, 2160, 1250 }
+};
+
+static const SiS_LCDDataStruct  SiS_ExtLCD1600x1200Data[] =
+{
+	{27, 4, 800, 500, 2160, 1250 },
+	{27, 4, 800, 500, 2160, 1250 },
+	{ 6, 1, 900, 500, 2160, 1250 },
+	{ 6, 1, 900, 500, 2160, 1250 },
+	{27, 1, 800, 500, 2160, 1250 },
+	{ 4, 1,1080, 625, 2160, 1250 },
+	{ 5, 2,1350, 800, 2160, 1250 },
+	{27,16,1500,1064, 2160, 1250 },
+	{27,16,1500,1064, 2160, 1250 },
+	{ 1, 1,2160,1250, 2160, 1250 }
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData1600x1200[] =
+{
+        {1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+	{1,  1, 2160, 1250, 2048, 1250},
+};
+
+static const SiS_LCDDataStruct  SiS_NoScaleData[] =
+{
+	{ 1, 1, 800, 449, 800, 449 },
+	{ 1, 1, 800, 449, 800, 449 },
+	{ 1, 1, 900, 449, 900, 449 },
+	{ 1, 1, 900, 449, 900, 449 },
+	{ 1, 1, 800, 525, 800, 525 },
+	{ 1, 1,1056, 628,1056, 628 },
+	{ 1, 1,1344, 806,1344, 806 },
+	{ 1, 1,1688,1066,1688,1066 },
+        { 1, 1,1688, 802,1688, 802 },  /* 1280x768: 802 was 806 in both cases */
+        { 1, 1,2160,1250,2160,1250 },  /* 1600x1200 */
+	{ 1, 1,1800,1000,1800,1000 }   /* 1280x960 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS320x480Data_1[]=
+{
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 433, 400, 525},
+	{ 848, 389, 400, 525},
+	{ 848, 518, 400, 525},
+	{1056, 628, 400, 525},
+	{ 400, 525, 400, 525},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_1[]=
+{
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 433,1060, 629},
+	{ 848, 389,1060, 629},
+	{ 848, 518,1060, 629},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS800x600Data_2[]=
+{
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{1056, 628,1056, 628},
+	{ 800, 449,1000, 644},
+	{ 800, 525,1000, 635}
+};
+
+
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_1[]=
+{
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x1024Data_2[]=
+{
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_1[]=
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},   /* 640x480 */
+	{1050, 638,1344, 806},   /* 800x600 */
+	{1344, 806,1344, 806},   /* 1024x768 */
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x768Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+/* Custom data for Barco iQ R300 */
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_1[]=
+{
+	{ 832, 438,1331, 806},
+	{ 832, 388,1331, 806},
+	{ 832, 438,1331, 806},
+	{ 832, 388,1331, 806},
+	{ 832, 518,1331, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+/* Custom data for Barco iQ R300 */
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1366Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}   /* 1360x1024 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_1[]=
+{
+	{ 832, 438,1331, 806},
+	{ 832, 409,1331, 806},
+	{ 832, 438,1331, 806},
+	{ 832, 409,1331, 806},
+	{ 832, 518,1331, 806},   /* 640x480 */
+	{1050, 638,1344, 806},   /* 800x600 */
+	{1344, 806,1344, 806},   /* 1024x768 */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDSBARCO1024Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_1[]=
+{
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{ 928, 496, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1400x1050Data_2[]=
+{
+        {1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_1[]=
+{
+        {1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 450, 2048,1250},
+	{1088, 400, 2048,1250},
+	{1088, 530, 2048,1250},
+	{1248, 650, 2048,1250},
+	{1472, 818, 2048,1250},
+	{1728,1066, 2048,1250},
+	{1848,1066, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1600x1200Data_2[]=
+{
+        {2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250},
+	{2048,1250, 2048,1250}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_1[]=
+{
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 438, 1408, 806},
+	{ 768, 388, 1408, 806},
+	{ 768, 518, 1408, 806},
+	{ 928, 638, 1408, 806},
+	{1152, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x768Data_2[]=
+{
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_1[] =
+{
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 604,1344, 800},
+	{840, 560,1344, 800},
+	{840, 689,1344, 800},
+	{1050, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{800, 449,1280, 789},
+	{800, 525,1280, 785}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1024x600Data_2[] =
+{
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{1344, 800,1344, 800},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_1[] =
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1152x768Data_2[] =
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+/* TW: Pass 1:1 data */
+static const SiS_LVDSDataStruct  SiS_LVDSXXXxXXXData_1[]=
+{
+        { 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 900, 449,  900, 449},
+	{ 900, 449,  900, 449},
+	{ 800, 525,  800, 525},  /*  640x480   */
+	{1056, 628, 1056, 628},  /*  800x600   */
+	{1344, 806, 1344, 806},  /* 1024x768   */
+	{1344,1066, 1344,1066},  /* 1280x1024  */  /* INSERTED ! */
+ 	{1688, 806, 1688, 806},  /* 1280x768   */
+	/* No other panels ! */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_1[]=
+{
+	{ 800, 445, 800, 525},   /* 800, 449, 800, 449 */
+	{ 800, 395, 800, 525},
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 525, 800, 525},
+	{ 800, 525, 800, 525},   /* pseudo */
+	{ 800, 525, 800, 525}    /* pseudo */
+};
+
+/* FSTN 320x240 */
+static const SiS_LVDSDataStruct  SiS_LVDS640x480Data_2[]=
+{
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 445, 800, 525},
+	{ 800, 395, 800, 525},
+	{ 800, 525, 800, 525},
+        { 800, 525, 800, 525},   /* pseudo */
+	{ 800, 525, 800, 525}    /* pseudo */
+};
+
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_1[]=
+{
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},
+	{1050, 638,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS1280x960Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{ 800, 449,1280, 801},
+	{ 800, 525,1280, 813}
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_1[]=
+{
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{1088, 525,1088, 525},  /* 640x480 TODO */
+	{1088, 525,1088, 525},  /* 800x600 TODO */
+	{1088, 525,1088, 525},  /* 1024x768 TODO */
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{1088, 525,1088, 525},  /* 848x480 */
+	{1088, 525,1088, 525}   /* 1360x768 TODO */
+};
+
+static const SiS_LVDSDataStruct  SiS_LVDS848x480Data_2[]=
+{
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{1088, 525,1088, 525},  /*  640x480 */
+	{1088, 525,1088, 525},  /*  800x600 */
+	{1088, 525,1088, 525},  /* 1024x768 */
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{   0,   0,   0,   0},
+	{1088, 525,1088, 525},  /* 848x480 */
+	{1088, 525,1088, 525}	/* 1360x768 TODO */
+};
+
+/* LCDA */
+
+static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_1[]=
+{
+	{  960, 438,1344, 806},
+	{  960, 388,1344, 806},
+	{ 1040, 438,1344, 806},
+	{ 1040, 438,1344, 806},
+	{  960, 518,1344, 806},   /* 640x480 */
+	{ 1120, 638,1344, 806},   /* 800x600 */
+	{ 1344, 806,1344, 806},   /* 1024x768 */
+#if 0
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 438,1344, 806},
+	{ 840, 409,1344, 806},
+	{ 840, 518,1344, 806},   /* 640x480 */
+	{1050, 638,1344, 806},   /* 800x600 */
+	{1344, 806,1344, 806},   /* 1024x768 */
+#endif
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1024x768Data_2[]=
+{
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+	{1344, 806,1344, 806},
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_1[]=
+{
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1128, 442,1688,1066},
+	{1128, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+#if 0
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 442,1688,1066},
+	{1048, 392,1688,1066},
+	{1048, 522,1688,1066},
+	{1208, 642,1688,1066},
+	{1432, 810,1688,1066},
+	{1688,1066,1688,1066}
+#endif
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1280x1024Data_2[]=
+{
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066},
+	{1688,1066,1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_1[]=
+{
+        { 928, 416, 1688,1066},
+	{ 928, 366, 1688,1066},
+	{1008, 416, 1688,1066},
+	{1008, 366, 1688,1066},
+	{1200, 530, 1688,1066},
+	{1088, 616, 1688,1066},
+	{1312, 784, 1688,1066},
+	{1568,1040, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1400x1050Data_2[]=
+{
+    	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066},
+	{1688,1066, 1688,1066}
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_1[]=
+{	/* TW: Temporary data.  */
+	{1200, 450, 2048,1250},
+	{1200, 400, 2048,1250},
+	{1280, 450, 2048,1250},
+	{1280, 400, 2048,1250},
+	{1200, 530, 2048,1250},
+	{1360, 650, 2048,1250},
+	{1584, 818, 2048,1250},
+	{1688,1066, 2048,1250},
+	{1688,1066, 2048,1250},
+	{2160,1250, 2048,1250},  /* ? */
+};
+
+static const SiS_LVDSDataStruct  SiS_LCDA1600x1200Data_2[]=
+{	/* Temporary data. */
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250},
+	{2160,1250, 2160,1250}
+};
+
+static const SiS_LVDSDataStruct  SiS_CHTVUNTSCData[]=
+{
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 840, 600, 840, 600},
+	{ 784, 600, 784, 600},
+	{1064, 750,1064, 750},
+        {1160, 945,1160, 945}
+};
+
+static const SiS_LVDSDataStruct  SiS_CHTVONTSCData[]=
+{
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 840, 525, 840, 525},
+	{ 784, 525, 784, 525},
+	{1040, 700,1040, 700},
+        {1160, 840,1160, 840}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1076_1[]=
+{  /* 1024x768 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},   /* 805; was 0, 0 -> top line cut away (26/09/03) */
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1076_2[]=
+{  /* 1024x768; not expanded */
+	{ 1184, 622 },
+	{ 1184, 597 },
+	{ 1184, 622 },
+	{ 1184, 597 },
+	{ 1152, 650 },  /* 622 */
+	{ 1232, 722 },
+	{    0, 0   },  /* 805; was 0, 0 -> top line cut away (26/09/03) */
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1210_1[]=
+{  /* 1280x1024 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1210_2[]=
+{  /* 1280x1024 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1296_1[]=
+{  /* 1400x1050 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1296_2[]=
+{  /* 1400x1050 - non expanded */
+	{ 1308, 741 },
+	{ 1308, 716 },
+	{ 1308, 741 },
+	{ 1308, 716 },
+	{ 1308, 781 },
+	{ 1388, 841 },
+	{ 1500, 925 },
+	{ 1628,1053 },
+	{    0,1065 }
+#if 0
+	{ 808 , 740},
+	{ 0   , 715},
+	{ 632 , 740},
+	{ 632 , 715},
+	{ 1307, 780},
+	{ 1387,1157},
+	{ 1499, 924},
+	{ 1627,1052},
+	{ 0 , 0}
+#endif
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1600_1[]=
+{  /* 1600x1200 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct SiS_PanelType1600_2[]=
+{  /* 1600x1200 */
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_1[]=
+{
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 8,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0, 806},
+	{ 0, 0 }
+};
+
+static const SiS_LVDSDesStruct  SiS_PanelTypeNS_2[] =
+{
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0},
+	{ 0 , 0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVUNTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVONTSCDesData[]=
+{
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVUPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSDesStruct  SiS_CHTVOPALDesData[]=
+{
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{256,   0},
+	{ 0,   0},
+	{ 0,   0},
+	{ 0,   0}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1320x480_1[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00 }},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00 }},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01 }},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00 }}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x5a,0x3e,
+	  0xe8,0x8f,0x8f,0x5b,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x2e,0x3e,
+	  0xb9,0x80,0x5d,0x2f,0x00,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0xaf,0xba,
+	  0x3b,0x82,0xdf,0xb0,0x00,0x00,0x01,
+	  0x00}},
+        {{0x7e,0x63,0x82,0x68,0x15,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x26,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x1e,0xf1,
+	  0xae,0x85,0x57,0x1f,0x30,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+          0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+	  0x00}},
+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+          0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11024x600_2_H[] =
+{
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1[] =
+{
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x01,
+	  0x00}},
+        {{0x64,0x4f,0x88,0x54,0x9f,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x01,
+	  0x00}},
+        {{0x7e,0x63,0x82,0x68,0x15,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x26,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_1_H[] =
+{
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0xc4,0x1f,
+	  0x92,0x89,0x8f,0xb5,0x30,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x97,0x1f,
+	  0x60,0x87,0x5d,0x83,0x10,0x00,0x44,
+	  0x00}},
+        {{0x2f,0x27,0x93,0x2b,0x90,0x04,0x3e,
+	  0xe2,0x89,0xdf,0x05,0x00,0x00,0x44,
+	  0x00}},
+        {{0x3c,0x31,0x80,0x35,0x1c,0x7c,0xf0,
+	  0x5a,0x8f,0x57,0x7d,0x20,0x00,0x55,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2[] =
+{
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x4f,0x87,0x6e,0x9f,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x06,
+	  0x00}},
+        {{0xa3,0x63,0x87,0x78,0x89,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x02,
+	  0x01}},
+        {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11152x768_2_H[] =
+{
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x4a,0x80,0x8f,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x31,0x87,0x5d,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x27,0x93,0x39,0x01,0x24,0xbb,
+	  0x72,0x88,0xdf,0x25,0x30,0x00,0x01,
+	  0x00}},
+        {{0x4f,0x31,0x93,0x3e,0x06,0x24,0xf1,
+	  0xae,0x84,0x57,0x25,0x30,0x00,0x01,
+	  0x01}},
+        {{0x4f,0x3f,0x93,0x45,0x0d,0x24,0xf5,
+	  0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+	  0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1[] =
+{
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0xb4,0x1f,
+   0x9c,0x8e,0x8f,0xb5,0x10,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x82,0x1f,
+   0x6a,0x8c,0x5d,0x83,0x30,0x00,0x01,
+   0x00}},
+ {{0x5b,0x4f,0x9f,0x55,0x19,0x04,0x3e,
+   0xec,0x8e,0xdf,0x05,0x20,0x00,0x01,
+   0x00}},
+ {{0x6f,0x63,0x93,0x69,0x8d,0x7c,0xf0,
+   0x64,0x86,0x57,0x7d,0x20,0x00,0x05,
+   0x01}},
+ {{0x8b,0x7f,0x8f,0x85,0x09,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa5,0x89,0x24,0xf5,
+   0x0c,0x8e,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_1_H[] =
+{
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x9e,0x1f,
+   0x93,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x30,0x1e,0x9e,0x1f,
+   0x92,0x86,0x8f,0x9f,0x30,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0x6c,0x1f,
+   0x60,0x84,0x5d,0x6d,0x10,0x00,0x05,
+   0x00}},
+ {{0x47,0x27,0x8b,0x2c,0x1a,0xee,0x1f,
+   0xe2,0x86,0xdf,0xef,0x10,0x00,0x05,
+   0x00}},
+ {{0x51,0x31,0x95,0x36,0x04,0x66,0xf0,
+   0x5a,0x8e,0x57,0x67,0x20,0x00,0x01,
+   0x01}},
+ {{0x5f,0x3f,0x83,0x44,0x92,0x0e,0xf5,
+   0x02,0x86,0xff,0x0f,0x10,0x00,0x01,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}},
+ {{0x6f,0x4f,0x93,0x54,0x82,0x0e,0x5a,
+   0x02,0x86,0xff,0x0f,0x09,0x00,0x05,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2[] =
+{
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x02,
+   0x00}},
+ {{0xab,0x60,0x9f,0x80,0x04,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x63,0x8f,0x8a,0x8e,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xab,0x7f,0x8f,0x98,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x02,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT11280x768_2_H[] =
+{
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x54,0x86,0xdb,0xda,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xbb,
+   0x3b,0x8d,0xc2,0xc1,0x00,0x00,0x01,
+   0x00}},
+ {{0x83,0x38,0x97,0x58,0x9c,0x24,0xb3,
+   0x7c,0x8e,0x03,0x02,0x10,0x00,0x01,
+   0x01}},
+ {{0x79,0x31,0x9d,0x58,0x9c,0x24,0xf1,
+   0xb6,0x88,0x57,0x25,0x10,0x00,0x01,
+   0x01}},
+ {{0x6b,0x3f,0x8f,0x58,0x9c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x01,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}},
+ {{0xab,0x9f,0x8f,0xa8,0x8c,0x24,0xf5,
+   0x0a,0x8c,0xff,0x25,0x30,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0xa3,0x7f,0x87,0x86,0x97,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x02,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa8,0x14,0x28,0x5a,
+   0x00,0x84,0xff,0x29,0x09,0x00,0x07,
+   0x01}},
+ {{0xce,0x9f,0x92,0xa9,0x17,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x07,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1XXXxXXX_1_H[] =
+{
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x30,0x00,0x00,
+   0x00}},
+ {{0x38,0x27,0x9c,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}},
+ {{0x4d,0x31,0x91,0x3b,0x03,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x01,
+   0x01}},
+ {{0x63,0x3f,0x87,0x4a,0x92,0x24,0xf5,
+   0x02,0x88,0xff,0x25,0x10,0x00,0x01,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_1_H[] =
+{
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x9c,0x8e,0x96,0xb9,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
+   0x83,0x85,0x63,0xba,0x00,0x00,0x00,
+   0x00}},
+ {{0x2d,0x28,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x30,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_2_H[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3[] =
+{
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x5f,0x4f,0x82,0x55,0x81,0x0b,0x3e,
+   0xe9,0x8b,0xdf,0x04,0x00,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+static const SiS_LVDSCRT1DataStruct  SiS_LVDSCRT1640x480_3_H[] =
+{
+ {{0x65,0x4f,0x89,0x56,0x83,0xaa,0x1f,
+   0x90,0x85,0x8f,0xab,0x30,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x54,0x9f,0xc4,0x1f,
+   0x92,0x89,0x8f,0xb5,0x30,0x00,0x01,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x83,0x1f,
+   0x5e,0x83,0x5d,0x79,0x10,0x00,0x05,
+   0x00}},
+ {{0x65,0x4f,0x89,0x56,0x83,0x04,0x3e,
+   0xe0,0x85,0xdf,0xfb,0x10,0x00,0x05,
+   0x00}},
+ {{0x7f,0x63,0x83,0x6c,0x1c,0x72,0xf0,
+   0x58,0x8c,0x57,0x73,0x20,0x00,0x06,
+   0x01}},
+ {{0x2d,0x27,0x90,0x2c,0x80,0x0b,0x3e,
+   0xe9,0x8b,0xe7,0x04,0x00,0x00,0x00,
+   0x00}}
+};
+
+#define SIS_PL_HSYNCP 0x01
+#define SIS_PL_HSYNCN 0x02
+#define SIS_PL_VSYNCP 0x04
+#define SIS_PL_VSYNCN 0x08
+#define SIS_PL_DVI    0x80
+
+typedef struct _SiS_PlasmaModes
+{
+  const char *name;
+  ULONG  clock;
+  USHORT HDisplay, HTotal, HFrontPorch, HSyncWidth;
+  USHORT VDisplay, VTotal, VFrontPorch, VSyncWidth;
+  UCHAR  SyncFlags;
+} SiS_PlasmaModes;
+
+
+typedef struct _SiS_PlasmaTables
+{
+   USHORT vendor;
+   UCHAR  productnum;
+   USHORT product[5];
+   const char *DDCnames[5];
+   const char *plasmaname;
+   UCHAR  modenum;
+   UCHAR  plasmamodes[20];  /* | 0x80 = DVI-capable, | 0x40 = analog */
+} SiS_PlasmaTables;
+
+static const SiS_PlasmaModes SiS_PlasmaMode[] = {
+   {  "640x400",		/* 00: IBM 400@70 */
+      25175,
+       640,  800, 17,  64,
+       400,  449, 13,   2,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "640x480",		/* 01: VESA 480@72 */
+      31500,
+       640,  832, 24,  40,
+       480,  520,  9,   3,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "800x600",		/* 02: VESA 600@72 */
+      50000,
+       800, 1040, 56, 120,
+       600,  666, 37,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "864x480",		/* 03: Cereb wide 1 */
+      42526,
+       864, 1134, 22,  86,
+       480,  500,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
+   {  "848x480",		/* 04: VESA wide (NEC1) */
+      33750,
+       848, 1088, 16, 112,
+       480,  517,  6,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1024x576",		/* 05: VESA wide (NEC2) */
+      47250,
+      1024, 1320, 16, 144,
+       576,  596,  2,   4,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x720",		/* 06: VESA wide (NEC3) */
+      76500,
+      1280, 1696, 48, 176,
+       720,  750,  4,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1360x765",		/* 07: VESA wide (NEC4) */
+      85500,
+      1360, 1792, 64, 176,
+       765,  795,  4,   8,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1024x600",		/* 08: CEREB wide 2 */
+      51200,
+      1024, 1352, 51, 164,
+       600,  628,  1,   4,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
+   {  "1024x768",		/* 09: VESA 768@75 */
+      78750,
+      1024, 1312,  16, 96,
+       768,  800,   1,  3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1152x864",		/* 10: VESA 1152x864@75 */
+      108000,
+      1152, 1600, 64, 128,
+       864,  900,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x1024",		/* 11: VESA 1024@60 */
+      108000,
+      1280, 1688, 48, 112,
+      1024, 1066,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1280x768",		/* 12: W_XGA */
+      81000,
+      1280, 1688, 48, 112,
+       768,  802,  3,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCN },
+   {  "1280x768",		/* 13: I/O Data W_XGA@56Hz */
+      76064,
+      1280, 1688, 48, 112,
+       768,  802,  2,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1376x768",		/* 14: I/O Wide XGA */
+      87340,
+      1376, 1808, 32, 128,
+       768,  806,  3,   6,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCP },
+   {  "1280x960",		/* 15: VESA 960@60 */
+      108000,
+      1280, 1800, 96, 112,
+       960, 1000,  1,   3,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "1400x1050",		/* 16: VESA 1050@60Hz */
+      108000,
+      1400, 1688, 48, 112,
+      1050, 1066,  1,   3,
+      SIS_PL_HSYNCN | SIS_PL_VSYNCN },
+   {  "1360x768",		/* 17: VESA wide (NEC4/2) */
+      85500,
+      1360, 1792, 64, 112,
+       765,  795,  3,   6,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP },
+   {  "800x600",		/* 18: VESA 600@56 */
+      36000,
+       800, 1024, 24,   2,
+       600,  625,  1,   2,
+      SIS_PL_HSYNCP | SIS_PL_VSYNCP }
+};
+
+static const SiS_PlasmaTables SiS_PlasmaTable[] = {
+#if 0  /* Product IDs missing */
+   { 0x38a3, 4,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 42VP4/42VP4D/42VP4G/42VP4DG",
+     11,   /* All DVI, except 0, 7, 13 */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
+      17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#endif
+#if 0  /* Product IDs missing */
+   { 0x38a3, 3,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 42PD1/50PD1/50PD2",
+     5,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0, 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 42PD3",
+     10,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 7|0x40, 8|0xc0, 9|0xc0,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 2,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 42VM3/61XM1",
+     11,  /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 3|0xc0, 4|0xc0, 5|0xc0, 6|0xc0, 8|0xc0, 9|0xc0,11|0xc0,
+      17|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 2,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 42MP1/42MP2",
+     6,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 50MP1",
+     10,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#endif
+   { 0x38a3, 4,
+     { 0xa482, 0xa483, 0x0000, 0x0000, 0x0000 },
+     { "PX-42VM", "", "", "", "" },
+     "NEC PlasmaSync 42MP3/42MP4/50MP2/61MP1",
+     11,   /* All DVI except 0, 7, 13, 17 */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,10|0xc0,11|0xc0,13|0x40,14|0xc0,
+      17|0x40, 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#if 0  /* Product IDs missing */
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 3300W",
+     3,
+     { 0|0x40, 1|0xc0,18|0xc0, 0     , 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 4200W",
+     4,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 0     , 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 4210W",
+     6,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 9|0xc0,11|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x38a3, 1,
+     { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "NEC PlasmaSync 5000W",
+     7,   /* DVI entirely unknown */
+     { 0|0x40, 1|0xc0, 2|0xc0, 4|0xc0, 7|0x40, 9|0xc0,11|0xc0, 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+#endif
+   { 0x412f, 2,
+     { 0x000c, 0x000b, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "Pioneer 503CMX/PDA-5002",
+     6,   /* DVI unknown */
+     { 1|0xc0, 2|0xc0, 9|0xc0,11|0xc0,12|0xc0,15|0xc0, 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x34a9, 1,
+     { 0xa00e, 0x0000, 0x0000, 0x0000, 0x0000 },
+     { "", "", "", "", "" },
+     "Panasonic TH-42",
+     5,   /* No DVI output */
+     { 1|0x40, 2|0x40, 4|0x40, 9|0x40,15|0x40, 0     , 0     , 0     , 0     , 0     ,
+       0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0     , 0       }
+   },
+   { 0x0000 }
+};
+
+void 	SiS_SetReg(SISIOADDRESS port, USHORT index, USHORT data);
+void 	SiS_SetRegByte(SISIOADDRESS port, USHORT data);
+void  	SiS_SetRegShort(SISIOADDRESS port, USHORT data);
+void	SiS_SetRegLong(SISIOADDRESS port, ULONG data);
+UCHAR	SiS_GetReg(SISIOADDRESS port, USHORT index);
+UCHAR 	SiS_GetRegByte(SISIOADDRESS port);
+USHORT	SiS_GetRegShort(SISIOADDRESS port);
+ULONG	SiS_GetRegLong(SISIOADDRESS port);
+void	SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+void 	SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND);
+void	SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR);
+void	SiS_DisplayOn(SiS_Private *SiS_Pr);
+void	SiS_DisplayOff(SiS_Private *SiS_Pr);
+void	SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+void	SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
+void	SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+void	SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+USHORT	SiS_GetMCLK(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+BOOLEAN	SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex);
+UCHAR	SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+BOOLEAN	SiS_LowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo);
+USHORT	SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+USHORT	SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
+void	SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo, USHORT ModeIdIndex);
+#ifdef LINUX_XF86
+BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,ScrnInfoPtr pScrn,USHORT ModeNo, BOOLEAN dosetpitch);
+BOOLEAN	SiSBIOSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN	SiSBIOSSetModeCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom);
+BOOLEAN	SiSBIOSSetModeCRT1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, ScrnInfoPtr pScrn,
+               DisplayModePtr mode, BOOLEAN IsCustom);
+int	SiSTranslateToVESA(ScrnInfoPtr pScrn, int modenumber);
+BOOLEAN	SiS_GetPanelID(SiS_Private *SiS_Pr, PSIS_HW_INFO);
+USHORT 	SiS_CheckBuildCustomMode(ScrnInfoPtr pScrn, DisplayModePtr mode, int VBFlags);
+DisplayModePtr SiSBuildBuiltInModeList(ScrnInfoPtr pScrn, BOOLEAN includelcdmodes, BOOLEAN isfordvi);
+#else
+BOOLEAN	SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,USHORT ModeNo);
+#endif
 #ifdef LINUX_KERNEL
-int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+int    sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 			      unsigned char modeno, unsigned char rateindex);
-int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+int    sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
 			 unsigned char modeno, unsigned char rateindex,
-			 ULONG *left_margin, ULONG *right_margin, 
+			 ULONG *left_margin, ULONG *right_margin,
 			 ULONG *upper_margin, ULONG *lower_margin,
 			 ULONG *hsync_len, ULONG *vsync_len,
 			 ULONG *sync, ULONG *vmode);
+BOOLEAN sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
+#endif
+
+extern void      SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+			       PSIS_HW_INFO HwInfo, int chkcrt2mode);
+extern void      SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+			           PSIS_HW_INFO HwInfo);
+extern void      SiS_SetHiVision(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void      SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void      SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+extern void      SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO);
+extern BOOLEAN   SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT);
+extern USHORT    SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                                PSIS_HW_INFO HwInfo);
+extern void      SiS_WaitRetrace1(SiS_Private *SiS_Pr);
+extern USHORT    SiS_GetResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex);
+extern USHORT    SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+extern USHORT    SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
+extern BOOLEAN   SiS_IsVAMode(SiS_Private *, PSIS_HW_INFO);
+extern BOOLEAN   SiS_IsDualEdge(SiS_Private *, PSIS_HW_INFO);
+
+#ifdef LINUX_XF86
+extern int      SiS_compute_vclk(int Clock, int *out_n, int *out_dn, int *out_div,
+	     	 		 int *out_sbit, int *out_scale);
+extern void 	SiSCalcClock(ScrnInfoPtr pScrn, int clock, int max_VLD, unsigned int *vclk);
+
+extern unsigned char SiS_GetSetBIOSScratch(ScrnInfoPtr pScrn, USHORT offset, unsigned char value);
+extern unsigned char SiS_GetSetModeID(ScrnInfoPtr pScrn, unsigned char id);
+extern USHORT 	     SiS_CalcModeIndex(ScrnInfoPtr pScrn, DisplayModePtr mode, unsigned long VBFlags,
+					BOOLEAN hcm);
 #endif
 
 #endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/init301.c fbdev-2.6/drivers/video/sis/init301.c
--- linus-2.6/drivers/video/sis/init301.c	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/init301.c	Thu Oct 16 14:13:41 2003
@@ -1,27 +1,17 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.c,v 1.3 2002/22/04 01:16:16 dawes Exp $ */
 /*
- * Mode switching code (CRT2 section) for SiS 300/540/630/730/315/550/650/740/330
- * (Universal module for Linux kernel framebuffer, XFree86 4.x)
+ * Mode initializing code (CRT2 section)
+ * for SiS 300/305/540/630/730 and
+ *     SiS 315/550/650/M650/651/661FX/M661FX/740/741/330/660/M660/760/M760
+ * (Universal module for Linux kernel framebuffer and XFree86 4.x)
  *
- * Assembler-To-C translation
  * Copyright 2002, 2003 by Thomas Winischhofer <thomas@winischhofer.net>
- * Minor parts Copyright SiS, Inc.
+ * Formerly based on non-functional code-fragements for 300 series by SiS, Inc.
  *
- * Based on BIOS
- *     1.10.07, 1.10a for 650/CH7019
- *     1.11.21a for 740/CH7019
- *     1.11.05 for 650/LVDS (w/o Chrontel)
- *     1.07.1b, 1.10.6s, 1.11.6w, 1.11.7w, 1.11.8r for 650/301(B/LV), 650/302LV
- *     2.04.50 (I) and 2.04.5c (II) for 630/301(B)
- *     2.02.3b, 2.03.02, 2.04.2c, 2.04.5c, 2.07a and 2.08.b3 for 630/LVDS/LVDS+CH7005
- *     2.04.5c, 2.04.6c for 730+LVDS+CH7005
- *     1.09b for 315/301(B)
- *     1.16.51 for 300+301LV (ECS A907)
- *     1.01.03 for 330 (Xabre 400)
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
  *
- * Known bugs:
- *   1024x768 panel, expanding (CR37=1): Mode 640x480 does not work on SOME panels
- *       therefore, we always do the scaling ourselves for now.
+ * Otherwise, the following terms apply:
  *
  * Permission to use, copy, modify, distribute, and sell this software and its
  * documentation for any purpose is hereby granted without fee, provided that
@@ -47,12 +37,12 @@
  * video bridges and combinations thereof. If anything is changed, extreme
  * care has to be taken that that change doesn't break it for other chipsets,
  * bridges or combinations thereof.
- * All comments in this file are by me, regardless if they are marked TW or not.
+ * All comments in this file are by me, regardless if marked TW or not.
  *
  */
  
-#if 1 
-#define NEWCH701x
+#if 0
+#define SET_EMI
 #endif
 
 #include "init301.h"
@@ -72,3182 +62,2891 @@
 #define SiS_I2CDELAY      1000
 #define SiS_I2CDELAYSHORT  150
 
-BOOLEAN
-SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-   USHORT ModeIdIndex;
-   USHORT RefreshRateTableIndex;
-
-   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-
-   if(!SiS_Pr->UseCustomMode) {
-      SiS_SearchModeID(SiS_Pr,ROMAddr,&ModeNo,&ModeIdIndex);
-   } else {
-      ModeIdIndex = 0;
-   }      
-
-   /* TW: Used for shifting CR33 */
-   SiS_Pr->SiS_SelectCRT2Rate = 4;
+/*********************************************/
+/*         HELPER: Lock/Unlock CRT2          */
+/*********************************************/
 
-   SiS_UnLockCRT2(SiS_Pr, HwDeviceExtension, BaseAddr);
+void
+SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  if(HwInfo->jChipType >= SIS_315H)
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
+  else
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
+}
 
-   RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr, ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
+void
+SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  if(HwInfo->jChipType >= SIS_315H)
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
+  else
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
+}
 
-   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
+/*********************************************/
+/*            HELPER: Enable CRT2            */
+/*********************************************/
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      SiS_DisableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
-      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwDeviceExtension->jChipType == SIS_730)) {
-         SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,0x80);
-      }
-      SiS_SetCRT2ModeRegs(SiS_Pr,BaseAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   }
+void
+SiS_EnableCRT2(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
+}
 
-   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
-      SiS_DisplayOn(SiS_Pr);
-      return(TRUE);
-   }
+/*********************************************/
+/*           Adjust Rate for CRT2            */
+/*********************************************/
+
+static BOOLEAN
+SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, USHORT *i,
+		   PSIS_HW_INFO HwInfo)
+{
+  USHORT tempax,tempbx,resinfo;
+  USHORT modeflag,infoflag;
 
-   if(SiS_Pr->UseCustomMode) return(FALSE);
-   
-   SiS_GetCRT2Data(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   HwDeviceExtension);
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = 0;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
 
-   /* Set up Panel Link for LVDS, 301BDH and 650/30xLV(for LCDA) */
-   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
-       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
-       ((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
-   	SiS_GetLVDSDesData(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                   HwDeviceExtension);
-   } else {
-        SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
-   }
+  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
 
-#ifdef LINUX_XF86
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
-  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
-  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
-  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
-#endif
-#endif
+  tempax = 0;
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      SiS_SetGroup1(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-                    HwDeviceExtension,RefreshRateTableIndex);
-   }
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
 
-        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
+      	tempax |= SupportRAMDAC2;
+	if(HwInfo->jChipType >= SIS_315H) {
+	   tempax |= SupportTV;
+	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		 if(resinfo == SIS_RI_1600x1200) tempax |= SupportTV1024;
+	      }
+	   }
+	}
 
-	   SiS_SetGroup2(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                 RefreshRateTableIndex,HwDeviceExtension);
-      	   SiS_SetGroup3(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                 HwDeviceExtension);
-      	   SiS_SetGroup4(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                 RefreshRateTableIndex,HwDeviceExtension);
-      	   SiS_SetGroup5(SiS_Pr,HwDeviceExtension, BaseAddr,ROMAddr,
-	                 ModeNo,ModeIdIndex);
+     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 
-	   /* TW: For 301BDH (Panel link initialization): */
-	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {	 
-		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
-		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-		       SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-		                       RefreshRateTableIndex,HwDeviceExtension);
+     	tempax |= SupportLCD;
+	if(HwInfo->jChipType >= SIS_315H) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+	         if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+		    (*i) = 0;
+                    return(1);
+	         } else {
+      	            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
+        	       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+           		  if((resinfo == SIS_RI_640x480) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+			     return(0);
+			  } else {
+             		     if((resinfo >= SIS_RI_1280x1024) && (resinfo != SIS_RI_1280x768)) {
+               			return(0);
+             		     }
+           		  }
+        	       }
 		    }
-                 }
+	         }
 	      }
-	      SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-		              RefreshRateTableIndex,HwDeviceExtension);
+      	   }
+	} else {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	      if( (resinfo != SIS_RI_1024x600) &&
+	          ((resinfo == SIS_RI_512x384) || (resinfo >= SIS_RI_1024x768))) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+	      if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768)) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+	      if((resinfo != SIS_RI_1280x960) && (resinfo > SIS_RI_1024x768)) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	      if(resinfo > SIS_RI_1280x1024) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	      if(resinfo > SIS_RI_1024x768) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+	      if((resinfo == SIS_RI_512x384) || (resinfo > SIS_RI_800x600)) return(0);
+	   } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+	      if((resinfo == SIS_RI_512x384) ||
+	         (resinfo == SIS_RI_400x300) ||
+		 (resinfo > SIS_RI_640x480)) return(0);
 	   }
-        }
-
-   } else {
+	}
 
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-    	      SiS_ModCRT1CRTC(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	                      RefreshRateTableIndex,HwDeviceExtension);
+     } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+	if(SiS_Pr->SiS_HiVision == 3) {
+	   tempax |= SupportHiVisionTV2;
+      	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+              if(resinfo == SIS_RI_512x384) return(0);
+              if(resinfo == SIS_RI_400x300) return(0);
+	      if(resinfo == SIS_RI_800x600) {
+	       	 if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+              }
+              if(resinfo > SIS_RI_800x600) return(0);
+	   }
+	} else {
+      	   tempax |= SupportHiVisionTV;
+      	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
+              if(resinfo == SIS_RI_512x384) return(0);
+              if((resinfo == SIS_RI_400x300) || (resinfo == SIS_RI_800x600)) {
+	       	 if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
+              }
+              if(resinfo > SIS_RI_800x600) return(0);
 	   }
 	}
-        if(SiS_Pr->SiS_IF_DEF_FSTN == 0) {
-     	   SiS_SetCRT2ECLK(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	 	           RefreshRateTableIndex,HwDeviceExtension);
-	}
-	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-     	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-	         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef SIS315H		 
-		    SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
-#endif		    
+
+     } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
+
+        tempax |= SupportTV;
+	tempax |= SupportTV1024;
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	      if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
+	         if(resinfo != SIS_RI_1024x768) {
+		    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+			((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384)) ) {
+		       tempax &= ~(SupportTV1024);
+		       if(HwInfo->jChipType >= SIS_315H) {
+                          if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+		                 ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+		                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		             }
+			  }
+		       } else {
+			  if( (resinfo != SIS_RI_400x300) ||
+			      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+			      (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+			     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+				if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+				   if(resinfo == SIS_RI_400x300) return(0);
+				   if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+				}
+		             }
+                          } else return(0);
+		       }
+		    }
 		 }
+	      } else {
+		 tempax &= ~(SupportTV1024);
+		 if(HwInfo->jChipType >= SIS_315H) {
+		    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		       if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+		           ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+		          if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+		       }
+		    }
+		 } else {
+		    if( (resinfo != SIS_RI_400x300) ||
+		        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+			(SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+		       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+			  if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+			     if(resinfo == SIS_RI_400x300) return(0);
+			     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
+			  }
+		       }
+                    } else return(0);
+                 }
 	      }
-	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       		 SiS_SetCHTVReg(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-		               RefreshRateTableIndex);
+	   } else {  /* not slavemode */
+	      if(resinfo != SIS_RI_1024x768) {
+		 if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+		     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_512x384) ) ) {
+		    tempax &= ~(SupportTV1024);
+	  	 }
 	      }
-     	   }
-	}
-
-   }
-
-#ifdef SIS300
-   if ( (HwDeviceExtension->jChipType == SIS_540) ||
-        (HwDeviceExtension->jChipType == SIS_630) ||
-        (HwDeviceExtension->jChipType == SIS_730) ||
-        (HwDeviceExtension->jChipType == SIS_300) )
-    {
-	if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-	   if(SiS_Pr->SiS_UseOEM) {
-	      if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
-	         if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
-	            SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
+	   }
+	} else {   /* 301 */
+	   tempax &= ~(SupportTV1024);
+	   if(HwInfo->jChipType >= SIS_315H) {
+	      if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+	         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
+	             ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != SIS_RI_800x600)) ) {
+	            if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
 	         }
-	      } else {
-       	         SiS_OEM300Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
 	      }
+	   } else {
+	      if( (resinfo != SIS_RI_400x300) ||
+		  (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		  (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
+	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		    if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+		       if(resinfo == SIS_RI_400x300) return(0);
+		       if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
+		    }
+	         }
+              } else return(0);
 	   }
-	}
-    }
-#endif
-
-#ifdef SIS315H
-   if ( (HwDeviceExtension->jChipType == SIS_315H)  ||
-        (HwDeviceExtension->jChipType == SIS_315)   ||
-	(HwDeviceExtension->jChipType == SIS_315PRO)||
-        (HwDeviceExtension->jChipType == SIS_550)   ||
-        (HwDeviceExtension->jChipType == SIS_740)   ||
-        (HwDeviceExtension->jChipType == SIS_650)   ||
-	(HwDeviceExtension->jChipType == SIS_330) )
-   {
-        if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-	   SiS_FinalizeLCD(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex, HwDeviceExtension);
-#if 0      /* Instead of FinalizeLCD(), older BIOSes (A92x) used OEMLCD() */
-	   SiS_OEMLCD(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-#endif
-           if(SiS_Pr->SiS_UseOEM) {
-              SiS_OEM310Setting(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-           }
-           SiS_CRT2AutoThreshold(SiS_Pr,BaseAddr);
         }
-   }
-#endif
-
-   if(HwDeviceExtension->jChipType < SIS_315H) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          if(HwDeviceExtension->jChipType != SIS_730) {
-             SiS_DisplayOn(SiS_Pr);
-	  }
-      }
-   }
+     }
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-         if(HwDeviceExtension->jChipType == SIS_730) {
-            SiS_DisplayOn(SiS_Pr);
-	 }
-      }
-      SiS_EnableBridge(SiS_Pr,HwDeviceExtension,BaseAddr);
-   }
+  } else {	/* for LVDS  */
 
-   SiS_DisplayOn(SiS_Pr);
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           tempax |= SupportCHTV;
+      	}
+     }
 
-   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	     /* TW: Disable LCD panel when using TV */
-	     SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
-	} else {
-	     /* TW: Disable TV when using LCD */
-	     SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     	tempax |= SupportLCD;
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	   if((resinfo != SIS_RI_1280x768) && (resinfo >= SIS_RI_1280x1024)) return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	   if((resinfo != SIS_RI_1024x600) && (resinfo >= SIS_RI_1024x768))  return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+	   if((resinfo != SIS_RI_1152x768) && (resinfo > SIS_RI_1024x768))   return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   if((resinfo != SIS_RI_1400x1050) && (resinfo > SIS_RI_1280x1024)) return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+           if(resinfo > SIS_RI_1600x1200) return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+           if(resinfo > SIS_RI_1280x1024) return(0);
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	   if(resinfo > SIS_RI_1024x768)  return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
+	   if(resinfo > SIS_RI_800x600)   return(0);
+	   if(resinfo == SIS_RI_512x384)  return(0);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
+           if((resinfo != SIS_RI_1360x1024) && (resinfo > SIS_RI_1280x1024)) return(0);
+	}  else if(SiS_Pr->SiS_LCDResInfo == Panel_848x480) {
+           if((resinfo != SIS_RI_1360x768) &&
+	      (resinfo != SIS_RI_848x480)  &&
+	      (resinfo > SIS_RI_1024x768)) return(0);
 	}
-   }
+     }
+  }
 
-   if(SiS_LowModeStuff(SiS_Pr,ModeNo,HwDeviceExtension)) {
-      SiS_LockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
-   }
+  /* Look backwards in table for matching CRT2 mode */
+  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     if(infoflag & tempax) {
+     	return(1);
+     }
+     if ((*i) == 0) break;
+  }
 
-   return 1;
+  /* Look through the whole mode-section of the table from the beginning
+   *     for a matching CRT2 mode if no mode was found yet.
+   */
+  for((*i) = 0; ; (*i)++) {
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
+     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
+     	return(0);
+     }
+     if(infoflag & tempax) {
+     	return(1);
+     }
+  }
+  return(1);
 }
 
-BOOLEAN
-SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,
-                 PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*              Get rate pointer             */
+/*********************************************/
+
+USHORT
+SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+               PSIS_HW_INFO HwInfo)
 {
-    USHORT temp,temp1,temp2;
+  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x01, 0x01,
+                               0x01, 0x01, 0x01, 0x01,
+			       0x01, 0x01, 0x01, 0x01,
+			       0x01, 0x01, 0x01, 0x01,
+			       0x00, 0x00, 0x00, 0x00 };
+  USHORT RefreshRateTableIndex,i,backup_i;
+  USHORT modeflag,index,temp,backupindex;
 
-    if((ModeNo != 0x03) && (ModeNo != 0x10) && (ModeNo != 0x12))
-         return(1);
-    temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x11);
-    SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x11,0x80);
-    temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,0x55);
-    temp2 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x00);
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,temp1);
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x11,temp);
-    if((HwDeviceExtension->jChipType >= SIS_315H) ||
-       (HwDeviceExtension->jChipType == SIS_300)) {
-       if(temp2 == 0x55) return(0);
-       else return(1);
-    } else {
-       if(temp2 != 0x55) return(1);
-       else {
-          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x35,0x01);
-          return(0);
-       }
-    }
-}
+  /* Do NOT check for UseCustomMode here, will skrew up FIFO */
+  if(ModeNo == 0xfe) return 0;
 
-/* TW: Set Part1 registers */
-void
-SiS_SetGroup1(SiS_Private *SiS_Pr,USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-	      USHORT RefreshRateTableIndex)
-{
-  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
-  USHORT  pushbx=0, CRT1Index=0;
-#ifdef SIS315H
-  USHORT  pushcx=0, tempbl=0;
-#endif
-  USHORT  modeflag, resinfo=0;
+  if(ModeNo <= 0x13)
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  else
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-  if(ModeNo<=0x13) {
-	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  } else {
-    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     	if(modeflag & HalfDCLK) return(0);
+     }
   }
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+  if(ModeNo < 0x14) return(0xFFFF);
 
-	   SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                           RefreshRateTableIndex,HwDeviceExtension);
-#ifdef SIS315H
-	   SiS_SetGroup1_LCDA(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-     	                      HwDeviceExtension,RefreshRateTableIndex);
-#endif
-  } else {
+ /* CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
+  *     On LVDS machines, CRT2 index is always 0 and will be
+  *     set to 0 by the following code; this causes the function
+  *     to take the first non-interlaced mode in SiS_Ext2Struct
+  */
 
-     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
-	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+  index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x33);
+  index >>= SiS_Pr->SiS_SelectCRT2Rate;
+  index &= 0x0F;
+  backupindex = index;
 
-        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                        RefreshRateTableIndex,HwDeviceExtension);
+  if(index > 0) index--;
 
+  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
      } else {
-
-        SiS_SetCRT2Offset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-      		          RefreshRateTableIndex,HwDeviceExtension);
-
-        if (HwDeviceExtension->jChipType < SIS_315H ) {
-#ifdef SIS300
-    	      SiS_SetCRT2FIFO_300(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
-#endif
-        } else {
-#ifdef SIS315H
-              SiS_SetCRT2FIFO_310(SiS_Pr,ROMAddr,ModeNo,HwDeviceExtension);
-#endif
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	   if(SiS_Pr->SiS_VBType & VB_NoLCD)
+	      index = 0;
+	   else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
+	      index = backupindex = 0;
 	}
+     }
 
-        SiS_SetCRT2Sync(SiS_Pr,BaseAddr,ROMAddr,ModeNo,
-                        RefreshRateTableIndex,HwDeviceExtension);
-
-	/* 1. Horizontal setup */
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+           index = 0;
+        }
+     }
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	   if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
+              temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
+              if(index > temp) index = temp;
+	   }
+      	} else {
+           index = 0;
+      	}
+     }
+  }
 
-        if (HwDeviceExtension->jChipType < SIS_315H ) {
+  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
+  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
 
-#ifdef SIS300   /* ------------- 300 series --------------*/
+  /* 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
+        if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
+            (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
+           if(backupindex <= 1) RefreshRateTableIndex++;
+        }
+     }
+  }
 
-    		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* TW: CRT2 Horizontal Total */
+  i = 0;
+  do {
+     if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
+     temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+     temp &= ModeInfoFlag;
+     if(temp < SiS_Pr->SiS_ModeType) break;
+     i++;
+     index--;
+  } while(index != 0xFFFF);
 
-    		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
-    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* TW: CRT2 Horizontal Total Overflow [7:4] */
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+      	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
+      	if(temp & InterlaceMode) i++;
+     }
+  }
 
-    		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* TW: CRT2 Horizontal Display Enable End */
+  i--;
 
-    		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
-    		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
-    		tempbx = pushbx + tempcx;
-    		tempcx <<= 1;
-    		tempcx += tempbx;
+  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
+     backup_i = i;
+     if(!(SiS_AdjustCRT2Rate(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+			      &i, HwInfo))) {
+	/* This is for avoiding random data to be used; i is
+	 * in an undefined state if no matching CRT2 mode is
+	 * found.
+	 */
+	i = backup_i;
+     }
+  }
 
-    		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-      			if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-			        /* CRT1Index &= 0x3F; - Not any longer */
-        			tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-        			tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
-        			tempbx = (tempbx - 1) << 3;
-        			tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-        			tempcx &= 0x1F;
-        			temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-        			temp = (temp & 0x04) << (6-2);
-        			tempcx = (tempcx | temp);
-				tempcx--;
-				tempcx <<= 3;
-      			}
-
-    			if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-        			if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-      					tempbx = 1040;
-      					tempcx = 1042;
-      				}
-    			}
-	        }
+  return(RefreshRateTableIndex + i);
+}
 
-    		temp = tempbx & 0x00FF;
-    		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* TW: CRT2 Horizontal Retrace Start */
-#endif /* SIS300 */
+/*********************************************/
+/*            STORE CRT2 INFO in CR34        */
+/*********************************************/
 
- 	} else {
+static void
+SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+  USHORT temp1,temp2;
 
-#ifdef SIS315H  /* ----------------- 310/325/330 series ------------- */
+  /* We store CRT1 ModeNo in CR34 */
+  SiS_SetReg(SiS_Pr->SiS_P3d4,0x34,ModeNo);
+  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
+  temp2 = ~(SetInSlaveMode >> 8);
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
+}
 
-	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
-		pushcx = tempcx;
-		if(modeflag & HalfDCLK) {
-#ifndef NEWCH701x		
-		    if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_IF_DEF_CH70xx == 0)) {
-#endif		    
-		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
-			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
-			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-			      tempcx = SiS_Pr->SiS_HT - tempax;
-			  }
-#ifndef NEWCH701x					  
-		    } else {
-			  tempcx >>= 1;
-		    }
-#endif		    
-		}
-		tempcx--;
+/*********************************************/
+/*    HELPER: GET SOME DATA FROM BIOS ROM    */
+/*********************************************/
 
-		temp = tempcx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* TW: CRT2 Horizontal Total */
+static BOOLEAN
+SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-		temp = ((tempcx & 0xff00) >> 8) << 4;
-		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* TW: CRT2 Horizontal Total Overflow [7:4] */
+  if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+        temp >>= 4;
+        temp = 1 << temp;
+        temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
+        if(temp1 & temp) return(1);
+        else return(0);
+     } else return(0);
+  } else {
+     return(0);
+  }
+}
 
-		tempcx = pushcx;					       /* BTVGA2HDEE 0x0A,0x0C */
-		tempbx = SiS_Pr->SiS_VGAHDE;
-		tempcx -= tempbx;
-		tempcx >>= 2;
-		if(modeflag & HalfDCLK) {
-		    tempbx >>= 1;
-		    tempcx >>= 1;
-		}
-		tempbx += 16;
+static BOOLEAN
+SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT temp,temp1;
+  UCHAR *ROMAddr;
 
-		temp = tempbx & 0xff;
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* TW: CRT2 Horizontal Display Enable End */
+  if((ROMAddr = (UCHAR *)HwInfo->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
+     if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xff;
+        temp >>= 4;
+        temp = 1 << temp;
+        temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
+        if(temp1 & temp) return(1);
+        else return(0);
+     } else return(0);
+  } else {
+     return(0);
+  }
+}
 
-		pushbx = tempbx;
-		tempcx >>= 1;
-		tempbx += tempcx;
-		tempcx += tempbx;
+/*********************************************/
+/*          HELPER: DELAY FUNCTIONS          */
+/*********************************************/
 
-		if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
-             	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-                	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
-                	tempbx |= ((SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] & 0xC0) << 2);
-                	tempbx = (tempbx - 3) << 3;         		/*(VGAHRS-3)*8 */
-                	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
-               		tempcx &= 0x1F;
-                	temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
-                	temp = (temp & 0x04) << (5-2);      		/* VGAHRE D[5] */
-                	tempcx = (tempcx | temp);	  	  	/* (VGAHRE-3)*8 */
-			tempcx -= 3;
-			tempcx <<= 3;
-			tempcx &= 0x00FF;
-			tempcx |= (tempbx & 0xFF00);
-                	tempbx += 16;
-                	tempcx += 16;
-			tempax = SiS_Pr->SiS_VGAHT;
-			if(modeflag & HalfDCLK)  tempax >>= 1;
-			tempax--;
-			if(tempcx > tempax)  tempcx = tempax;
-             	   }
-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-             	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
-      		 	 tempbx = 1040;
-      		 	 tempcx = 1042;
-      	     	      }
-         	   }
-		   /* TW: Makes no sense, but is in 650/302LV 1.10.6s */
-         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == 0x08)){
-		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-             	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-      		 	    tempbx = 1040;
-      		 	    tempcx = 1042;
-      	     	         }
-		      }
-         	   }
-                }
+void
+SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
+{
+  USHORT i;
 
-		temp = tempbx & 0xff;
-	 	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* TW: CRT2 Horizontal Retrace Start */
-#endif  /* SIS315H */
+  for(i=0; i<delaytime; i++) {
+     SiS_GetReg(SiS_Pr->SiS_P3c4,0x05);
+  }
+}
 
-     	}  /* 310/325/330 series */
+static void
+SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  USHORT temp,flag;
 
-  	/* TW: The following is done for all bridge/chip types/series */
+  flag = SiS_GetRegByte(0x61) & 0x10;
 
-  	tempax = tempbx & 0xFF00;
-  	tempbx = pushbx;
-  	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
-  	tempax |= (tempbx & 0xFF00);
-  	temp = (tempax & 0xFF00) >> 8;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* TW: Overflow */
+  while(delay) {
+     temp = SiS_GetRegByte(0x61) & 0x10;
+     if(temp == flag) continue;
+     flag = temp;
+     delay--;
+  }
+}
 
-  	temp = tempcx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* TW: CRT2 Horizontal Retrace End */
+#ifdef SIS315H
+static void
+SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  while(delay--) {
+     SiS_GenericDelay(SiS_Pr,0x19df);
+  }
+}
+#endif
 
-  	/* 2. Vertical setup */
+static void
+SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+{
+  while(delay--) {
+     SiS_GenericDelay(SiS_Pr,0x42);
+  }
+}
 
-  	tempcx = SiS_Pr->SiS_VGAVT - 1;
-  	temp = tempcx & 0x00FF;
+static void
+SiS_PanelDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT DelayTime)
+{
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT PanelID, DelayIndex, Delay;
+#ifdef SIS300
+  USHORT temp;
+#endif
 
-        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-	     if(HwDeviceExtension->jChipType < SIS_315H) {
-	          if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-		       if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
-		           temp--;
-		       }
-                  }
-	     } else {
- 		      temp--;
-             }
-        } else if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    /* TW: 650/30xLV 1.10.6s */
-	    temp--;
-	}
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* TW: CRT2 Vertical Total */
+  if(HwInfo->jChipType < SIS_315H) {
 
-  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
-  	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* TW: CRT2 Vertical Display Enable End */
+#ifdef SIS300
 
-  	temp = ((tempbx & 0xFF00) << 3) >> 8;
-  	temp |= ((tempcx & 0xFF00) >> 8);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* TW: Overflow (and HWCursor Test Mode) */
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 300 series, LVDS */
 
-	/* TW: 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-           tempbx++;
-   	   tempax = tempbx;
-	   tempcx++;
-	   tempcx -= tempax;
-	   tempcx >>= 2;
-	   tempbx += tempcx;
-	   if(tempcx < 4) tempcx = 4;
-	   tempcx >>= 2;
-	   tempcx += tempbx;
-	   tempcx++;
-	} else {
-	   /* TW: 300 series, LVDS/301B: */
-  	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
-  	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
-	}
+	  PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 
-  	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-      		tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
-      		if(temp & 0x04) tempbx |= 0x0100;
-      		if(temp & 0x80) tempbx |= 0x0200;
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
-      		if(temp & 0x08) tempbx |= 0x0400;
-      		temp = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
-      		tempcx = (tempcx & 0xFF00) | (temp & 0x00FF);
-    	   }
-  	}
-  	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);           /* TW: CRT2 Vertical Retrace Start */
+	  DelayIndex = PanelID >> 4;
 
-  	temp = ((tempbx & 0xFF00) >> 8) << 4;
-  	temp |= (tempcx & 0x000F);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,temp);           /* TW: CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+              Delay = 3;
+          } else {
+              if(DelayTime >= 2) DelayTime -= 2;
 
-  	/* 3. Panel compensation delay */
+              if(!(DelayTime & 0x01)) {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+              } else {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+              }
+	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                  if(ROMAddr[0x220] & 0x40) {
+                      if(!(DelayTime & 0x01)) {
+	    	          Delay = (USHORT)ROMAddr[0x225];
+                      } else {
+	    	          Delay = (USHORT)ROMAddr[0x226];
+                      }
+                  }
+              }
+          }
+	  SiS_ShortDelay(SiS_Pr,Delay);
 
-  	if(HwDeviceExtension->jChipType < SIS_315H) {
+      } else {							/* 300 series, 301(B) */
 
-#ifdef SIS300  /* ---------- 300 series -------------- */
+	  PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+	  temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
+          if(!(temp & 0x10))  PanelID = 0x12;
 
-	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-	        temp = 0x20;
+          DelayIndex = PanelID >> 4;
 
-		if(HwDeviceExtension->jChipType == SIS_300) {
-		   temp = 0x10;
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
-		}
-		if(SiS_Pr->SiS_VBType & VB_SIS301) {
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-		}
-		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
-      		   else 					temp = 0x20;
-    	        }
-		if((ROMAddr) && (SiS_Pr->SiS_UseROM) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-		    if(ROMAddr[0x220] & 0x80) {
-		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
-				temp = ROMAddr[0x221];
-			else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)
-				temp = ROMAddr[0x222];
-		        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
-				temp = ROMAddr[0x223];
-			else
-				temp = ROMAddr[0x224];
-			temp &= 0x3c;
-		    }
-		}
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-		   if(HwDeviceExtension->pdc) {
-			temp = HwDeviceExtension->pdc & 0x3c;
-		   }
-		}
-	   } else {
-	        temp = 0x20;
-		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
-		}
-		if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-		    if(ROMAddr[0x220] & 0x80) {
-		        temp = ROMAddr[0x220] & 0x3c;
-		    }
-		}
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-		   if(HwDeviceExtension->pdc) {
-			temp = HwDeviceExtension->pdc & 0x3c;
-		   }
-		}
-	   }
+	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+              Delay = 3;
+          } else {
+              if(DelayTime >= 2) DelayTime -= 2;
+
+              if(!(DelayTime & 0x01)) {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+              } else {
+       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+              }
+	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                  if(ROMAddr[0x220] & 0x40) {
+                      if(!(DelayTime & 0x01)) {
+	    	          Delay = (USHORT)ROMAddr[0x225];
+                      } else {
+	    	          Delay = (USHORT)ROMAddr[0x226];
+                      }
+                  }
+              }
+          }
+	  SiS_ShortDelay(SiS_Pr,Delay);
 
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* TW: Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+      }
 
 #endif  /* SIS300 */
 
-  	} else {
+   } else {
 
-#ifdef SIS315H   /* ----------- 310/325/330 series ---------------*/
+      if(HwInfo->jChipType == SIS_330) return;
 
-	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-                temp = 0x10;
-                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
-    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
-    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-		   temp = 0x08;
-		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-		      switch(SiS_Pr->SiS_HiVision) {
-		      case 2:
-		      case 1:
-		      case 0:
-		         temp = 0x08;
-			 break;
-		      default:
-      		         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  temp = 0x2c;
-      		         else 					  temp = 0x20;
-		      }
-    	           }
-		}
-		if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-		   tempbl = 0x00;
-		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-		      if(HwDeviceExtension->jChipType < SIS_330) {
-		         if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
-		      } else {
-		         if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
-		      }
-		   }
-		} else {  /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
-		   tempbl = 0xF0;
-		}
-	   } else {
-	        if(HwDeviceExtension->jChipType == SIS_740) {
-		   temp = 0x03;
-	        } else {
-		   temp = 0x00;
-		}
-		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
-		tempbl = 0xF0;
-		if(HwDeviceExtension->jChipType == SIS_650) {
-		   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
-		   }
-		}
-	   }
-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* TW: Panel Link Delay Compensation */
-
-    	   tempax = 0;
-    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
-    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
-
-#endif  /* SIS315H */
-
-  	}
-
-     }  /* Slavemode */
+#ifdef SIS315H
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 315 series, LVDS */
 
-        /* TW: For 301BDH, we set up the Panel Link */
-        if( (SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	    (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
+          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
+              PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+	      DelayIndex = PanelID >> 4;
+	      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
+                 Delay = 3;
+              } else {
+                 if(DelayTime >= 2) DelayTime -= 2;
 
-	    SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                       HwDeviceExtension,RefreshRateTableIndex);
+                 if(!(DelayTime & 0x01)) {
+       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
+                 } else {
+       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
+                 }
+	         if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+                    if(ROMAddr[0x13c] & 0x40) {
+                        if(!(DelayTime & 0x01)) {
+	    	           Delay = (USHORT)ROMAddr[0x17e];
+                        } else {
+	    	           Delay = (USHORT)ROMAddr[0x17f];
+                        }
+                    }
+                 }
+              }
+	      SiS_ShortDelay(SiS_Pr,Delay);
+	  }
 
-        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {                             
+      } else {							/* 315 series, 301(B) */
 
-    	    SiS_SetGroup1_301(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                      HwDeviceExtension,RefreshRateTableIndex);
-        }
+          PanelID = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
+	  DelayIndex = PanelID >> 4;
+          if(!(DelayTime & 0x01)) {
+       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
+          } else {
+       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
+          }
+	  SiS_DDC2Delay(SiS_Pr, Delay * 4);
 
-     } else {
+      }
 
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-	
-	   SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                        HwDeviceExtension,RefreshRateTableIndex);
-	} else {
-	
-	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-              if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-    	          SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                              HwDeviceExtension,RefreshRateTableIndex);
-              }
-	   } else {
-	      SiS_SetGroup1_LVDS(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-	                         HwDeviceExtension,RefreshRateTableIndex);
-	   }
-	
-	}
+#endif /* SIS315H */
 
-     }
-   } /* LCDA */
+   }
 }
 
-void
-SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                  PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
+#ifdef SIS315H
+static void
+SiS_PanelDelayLoop(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                      USHORT DelayTime, USHORT DelayLoop)
 {
-  USHORT  push1,push2;
-  USHORT  tempax,tempbx,tempcx,temp;
-  USHORT  resinfo,modeflag;
-
-  if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-  } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  }
-
-  /* TW: The following is only done if bridge is in slave mode: */
-
-  tempax = 0xFFFF;
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
+   int i;
+   for(i=0; i<DelayLoop; i++) {
+      SiS_PanelDelay(SiS_Pr, HwInfo, DelayTime);
+   }
+}
+#endif
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-  	modeflag |= Charx8Dot;
-  }
+/*********************************************/
+/*    HELPER: WAIT-FOR-RETRACE FUNCTIONS     */
+/*********************************************/
 
-  if(modeflag & Charx8Dot) tempcx = 0x08;
-  else                     tempcx = 0x09;
+void
+SiS_WaitRetrace1(SiS_Private *SiS_Pr)
+{
+  USHORT watchdog;
 
-  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+  if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
 
-  if(modeflag & HalfDCLK) tempax >>= 1;
+  if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80)) return;
 
-  tempax = (tempax / tempcx) - 5;
-  tempbx = tempax & 0x00FF;
+  watchdog = 65535;
+  while((SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
+  watchdog = 65535;
+  while((!(SiS_GetRegByte(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
+}
 
-  temp = 0xFF;                                                  /* set MAX HT */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
+static void
+SiS_WaitRetrace2(SiS_Private *SiS_Pr, USHORT reg)
+{
+  USHORT watchdog;
 
-  tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
-  if(modeflag & HalfDCLK) tempax >>= 1;
-  tempax = (tempax / tempcx) - 1;
-  tempbx |= ((tempax & 0x00FF) << 8);
-  temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,temp);
+  watchdog = 65535;
+  while((SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02) && --watchdog);
+  watchdog = 65535;
+  while((!(SiS_GetReg(SiS_Pr->SiS_Part1Port,reg) & 0x02)) && --watchdog);
+}
 
-  temp = (tempbx & 0xFF00) >> 8;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {        
-    	    temp += 2;
-        }
-  }	
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-     if(SiS_Pr->SiS_HiVision == 3) {
-              if(resinfo == 7) temp -= 2;
+static void
+SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  if(HwInfo->jChipType < SIS_315H) {
+#ifdef SIS300
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
+     }
+     if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
+        SiS_WaitRetrace1(SiS_Pr);
+     } else {
+        SiS_WaitRetrace2(SiS_Pr, 0x25);
+     }
+#endif
+  } else {
+#ifdef SIS315H
+     if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
+        SiS_WaitRetrace1(SiS_Pr);
+     } else {
+        SiS_WaitRetrace2(SiS_Pr, 0x30);
      }
+#endif
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
+}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
+static void
+SiS_VBWait(SiS_Private *SiS_Pr)
+{
+  USHORT tempal,temp,i,j;
 
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-     (SiS_Pr->SiS_HiVision == 3)) {
-    temp = (tempbx & 0x00FF) - 1;
-    if(!(modeflag & HalfDCLK)) {
-      temp -= 6;
-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-        temp -= 2;
-        if(ModeNo > 0x13) temp -= 10;
-      }
-    }
-  } else {
-    tempcx = tempbx & 0x00FF;
-    tempbx = (tempbx & 0xFF00) >> 8;
-    tempcx = (tempcx + tempbx) >> 1;
-    temp = (tempcx & 0x00FF) + 2;
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV){
-       temp--;
-       if(!(modeflag & HalfDCLK)){
-          if((modeflag & Charx8Dot)){
-             temp += 4;
-             if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
-             if(HwDeviceExtension->jChipType >= SIS_315H) {
-	        if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
-             }
-          }
-       }
-    } else {
-       if(!(modeflag & HalfDCLK)) {
-          temp -= 4;
-          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-             if(SiS_Pr->SiS_VGAHDE >= 800) {
-                temp -= 7;
-	        if(HwDeviceExtension->jChipType < SIS_315H) {
-	           /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
-                   if(SiS_Pr->SiS_ModeType == ModeEGA) {
-                      if(SiS_Pr->SiS_VGAVDE == 1024) {
-                         temp += 15;
-                         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) 
-			    temp += 7;
-                      }
-                   }
-	        }
-                if(SiS_Pr->SiS_VGAHDE >= 1280) {
-                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-                      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
-                   }
-                }
-             }
-          }
+  temp = 0;
+  for(i=0; i<3; i++) {
+    for(j=0; j<100; j++) {
+       tempal = SiS_GetRegByte(SiS_Pr->SiS_P3da);
+       if(temp & 0x01) {
+          if((tempal & 0x08))  continue;
+          if(!(tempal & 0x08)) break;
+       } else {
+          if(!(tempal & 0x08)) continue;
+          if((tempal & 0x08))  break;
        }
     }
+    temp ^= 0x01;
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);               	/* 0x07 Horizontal Retrace Start */
-
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);                 /* 0x08 Horizontal Retrace End   */
+}
 
+static void
+SiS_VBLongWait(SiS_Private *SiS_Pr)
+{
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-            if(ModeNo <= 0x01) {
-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2a);
-		if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x61);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x41);
-		}
-	    } else if(SiS_Pr->SiS_ModeType == ModeText) {
-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x54);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x55);
-		}
-		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x00);
-	    } else if(ModeNo <= 0x13) {
-	        if(modeflag & HalfDCLK) {
-		    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		    } else {
-		        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
-			SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x02);
-		    }
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x5b);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		}
-	    } else if( ((HwDeviceExtension->jChipType >= SIS_315H) && (ModeNo == 0x50)) ||
-	               ((HwDeviceExtension->jChipType < SIS_315H) && (resinfo == 0 || resinfo == 1)) ) {
-	        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x30);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		} else {
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0x2f);
-		    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x08,0x03);
-		}
-	    }
-
-     }
-  }
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-     if(SiS_Pr->SiS_HiVision & 0x03) {
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xb2);
-	if(SiS_Pr->SiS_HiVision & 0x02) {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,0xab);
-	}
-     }
+     SiS_VBWait(SiS_Pr);
+  } else {
+     SiS_WaitRetrace1(SiS_Pr);
   }
+}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
+/*********************************************/
+/*               HELPER: MISC                */
+/*********************************************/
 
-  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+static BOOLEAN
+SiS_Is301B(SiS_Private *SiS_Pr)
+{
+  USHORT flag;
 
-  tempbx = SiS_Pr->SiS_VGAVT;
-  push1 = tempbx;
+  flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);
+  if(flag >= 0xb0) return TRUE;
+  else return FALSE;
+}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+static BOOLEAN
+SiS_CRT2IsLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  tempcx = 0x121;
-  tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
-  if(tempbx == 357) tempbx = 350;
-  if(tempbx == 360) tempbx = 350;
-  if(tempbx == 375) tempbx = 350;
-  if(tempbx == 405) tempbx = 400;
-  if(tempbx == 420) tempbx = 400;
-  if(tempbx == 525) tempbx = 480;
-  push2 = tempbx;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-    	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-      		if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-        		if(tempbx == 350) tempbx += 5;
-        		if(tempbx == 480) tempbx += 5;
-      		}
-    	}
+  if(HwInfo->jChipType == SIS_730) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3c4,0x13);
+     if(flag & 0x20) return TRUE;
+  }
+  flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+  if(flag & 0x20) return TRUE;
+  else return FALSE;
+}
+
+BOOLEAN
+SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT flag;
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     if((HwInfo->jChipType != SIS_650) || (SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
+        flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+        if(flag & EnableDualEdge) return TRUE;
+        else return FALSE;
+     } else return FALSE;
   }
-  tempbx--;
-  temp = tempbx & 0x00FF;
-  tempbx--;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
+#endif
+  return FALSE;
+}
 
-  tempbx = push2;
-  tempbx--;
-  temp = tempbx & 0x00FF;
-#if 0
-  /* TW: Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
-  if(xxx()) {
-      if(temp == 0xdf) temp = 0xda;
+BOOLEAN
+SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT flag;
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if((flag & EnableDualEdge) && (flag & SetToLCDA)) return TRUE;
+     else return FALSE;
   }
 #endif
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0E,temp);
+  return FALSE;
+}
 
-  if(tempbx & 0x0100) {
-  	tempcx |= 0x0002;
-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x000a;
+static BOOLEAN
+SiS_IsDualLink(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_315H) {
+     if((SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ||
+        (SiS_IsVAMode(SiS_Pr, HwInfo))) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x04) return TRUE;
+     }
   }
+#endif
+  return FALSE;
+}
 
-  tempax = 0x000B;
-  if(modeflag & DoubleScanMode) tempax |= 0x8000;
+#ifdef SIS315H
+static BOOLEAN
+SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  if(tempbx & 0x0200) {
-  	tempcx |= 0x0040;
-	if(SiS_Pr->SiS_VBType & VB_SIS301) tempax |= 0x2000;
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+     if(flag & 0x10)  return TRUE;
+     else             return FALSE;
   }
+  return FALSE;
+}
+#endif
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
-        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	      if(SiS_Pr->SiS_VGAVDE == 480) {
-	             tempax = (tempax & 0x00ff) | 0x2000;
-		     if(modeflag & DoubleScanMode)  tempax |= 0x8000;
-	      }
-	}
-  }
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0B,temp);
+  if(HwInfo->jChipType == SIS_650) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f);
+     flag &= 0xF0;
+     /* Check for revision != A0 only */
+     if((flag == 0xe0) || (flag == 0xc0) ||
+        (flag == 0xb0) || (flag == 0x90)) return FALSE;
+     else return TRUE;
+  }
+  return TRUE;
+}
+#endif
 
-  if(tempbx & 0x0400) tempcx |= 0x0600;
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSHiVision)  return TRUE;  /* = YPrPb = 0x08 */
+     else      	                    return FALSE;
+  }
+  return FALSE;
+}
+#endif
 
-  tempax = push1;
-  tempax -= tempbx;
-  tempax >>= 2;
-  push1 = tempax;
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-        /* TW: 650/30xLV 1.10.6s */
-        if(ModeNo > 0x13) {
-	    if(resinfo != 0x09) {  /* 1280x1024 */
-	        tempax <<= 1;
-		tempbx += tempax;
-	    }
-	} else {
-	    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-	        tempax <<= 1;
-		tempbx += tempax;
-	    }
-	}
-  } else if((resinfo != 0x09) || (SiS_Pr->SiS_VBType & VB_SIS301)) {
-    	tempax <<= 1;
-    	tempbx += tempax;
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSScart)     return TRUE;  /* = Scart = 0x04 */
+     else      	                    return FALSE;
   }
+  return FALSE;
+}
+#endif
 
-  if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
-      (SiS_Pr->SiS_HiVision == 3) ) {
-    	tempbx -= 10;
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV)        return TRUE;
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & EnableLVDSHiVision) return TRUE;  /* = YPrPb = 0x08 */
+     if(flag & EnableLVDSScart)    return TRUE;  /* = Scart = 0x04 - TW */
+     else                          return FALSE;
   } else {
-    	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-      	   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	       if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-                    tempbx += 40;
-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
-		       if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
-		    }
-      	       }
-	   }
-    	}
-  }
-  tempax = push1;
-  tempax >>= 2;
-  tempax++;
-  tempax += tempbx;
-  push1 = tempax;
-  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    	if(tempbx <= 513)  {
-      		if(tempax >= 513) tempbx = 513;
-    	}
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToTV) return TRUE;
   }
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
+  return FALSE;
+}
+#endif
 
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
-  	tempbx--;
-  	temp = tempbx & 0x00FF;
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x10,temp);
+#ifdef SIS315H
+static BOOLEAN
+SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-	if(tempbx & 0x0100) tempcx |= 0x0008;
+  if(HwInfo->jChipType >= SIS_315H) {
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+     if(flag & SetCRT2ToLCD) return TRUE;
+     flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+     if(flag & SetToLCDA)    return TRUE;
+     else                    return FALSE;
+  } else {
+   flag = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+   if(flag & SetCRT2ToLCD)   return TRUE;
+  }
+  return FALSE;
+}
+#endif
 
-  	if(tempbx & 0x0200) {
-    	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
-	}
+static BOOLEAN
+SiS_BridgeIsOn(SiS_Private *SiS_Pr)
+{
+  USHORT flag;
 
-  	tempbx++;
-  }
-  if(tempbx & 0x0100) tempcx |= 0x0004;
-  if(tempbx & 0x0200) tempcx |= 0x0080;
-  if(tempbx & 0x0400) {
-        if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
-  	else                               tempcx |= 0x0C00;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     return FALSE;
+  } else {
+     flag = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x00);
+     if((flag == 1) || (flag == 2)) return FALSE;
+     else return TRUE;
   }
+}
 
-  tempbx = push1;
-  temp = tempbx & 0x00FF;
-  temp &= 0x0F;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
-
-  if(tempbx & 0x0010) tempcx |= 0x2000;
+static BOOLEAN
+SiS_BridgeIsEnabled(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  USHORT flag;
 
-  temp = tempcx & 0x00FF;
-  if(SiS_Pr->SiS_VBType & VB_SIS301) {
-	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-	      if(SiS_Pr->SiS_VGAVDE == 480)  temp = 0xa3;
-	}
+  if(!(SiS_BridgeIsOn(SiS_Pr))) {
+    flag = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+    if(HwInfo->jChipType < SIS_315H) {
+      flag &= 0xa0;
+      if((flag == 0x80) || (flag == 0x20)) return FALSE;
+      else	                           return TRUE;
+    } else {
+      flag &= 0x50;
+      if((flag == 0x40) || (flag == 0x10)) return FALSE;
+      else                                 return TRUE;
+    }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
+  return TRUE;
+}
 
-  temp = (tempcx & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
+static BOOLEAN
+SiS_BridgeInSlave(SiS_Private *SiS_Pr)
+{
+  USHORT flag1;
 
-  tempax = modeflag;
-  temp = (tempax & 0xFF00) >> 8;
-  temp = (temp >> 1) & 0x09;
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
-       /* Only use 8 dot clock */
-       temp |= 0x01;
-  }
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
+  flag1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31);
+  if(flag1 & (SetInSlaveMode >> 8)) return TRUE;
+  else return FALSE;
+}
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
+/*********************************************/
+/*       GET VIDEO BRIDGE CONFIG INFO        */
+/*********************************************/
 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
+/* Setup general purpose IO for Chrontel communication */
+void
+SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo)
+{
+   unsigned long  acpibase;
+   unsigned short temp;
 
-  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-       if(IS_SIS650) {
-           /* TW: 650/30xLV 1.10.6s */
-           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-	       temp = 0x80;
-	   }
-       } else temp = 0x80;
-  } else  temp = 0x00;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
+   if(!(SiS_Pr->SiS_ChSW)) return;
 
-  return;
+#ifndef LINUX_XF86
+   SiS_SetRegLong(0xcf8,0x80000874);		   /* get ACPI base */
+   acpibase = SiS_GetRegLong(0xcfc);
+#else
+   acpibase = pciReadLong(0x00000800, 0x74);
+#endif
+   acpibase &= 0xFFFF;
+   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));  /* ACPI register 0x3c: GP Event 1 I/O mode select */
+   temp &= 0xFEFF;
+   SiS_SetRegShort((USHORT)(acpibase + 0x3c), temp);
+   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3c));
+   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));  /* ACPI register 0x3a: GP Pin Level (low/high) */
+   temp &= 0xFEFF;
+   if(!(myvbinfo & SetCRT2ToTV)) {
+      temp |= 0x0100;
+   }
+   SiS_SetRegShort((USHORT)(acpibase + 0x3a), temp);
+   temp = SiS_GetRegShort((USHORT)(acpibase + 0x3a));
 }
 
 void
-SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr,USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-		   USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		   USHORT RefreshRateTableIndex)
+SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
+	      int checkcrt2mode)
 {
-  USHORT modeflag, resinfo;
-  USHORT push1, push2, tempax, tempbx, tempcx, temp;
-#ifdef SIS315H
-  USHORT pushcx;
-#endif
-  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
+  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  USHORT tempax,tempbx,temp;
+  USHORT modeflag, resinfo=0;
+  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  }
-
-  /* TW: Set up Panel Link */
-
-  /* 1. Horizontal setup */
-
-  tempax = SiS_Pr->SiS_LCDHDES;
-
-  if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
-      (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
-  	tempax -= 8;
-  }
-
-  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
-
-  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
-
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
- 	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempbx =  800;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempbx = 1024;  /* TW */
-    	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempbx = 1024;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempbx = 1152;  /* TW */
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempbx = 1280;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1280; 
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400; 
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600; 
-        }
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
+   	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      }
   }
-  tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
-
-  push1 = tempax;
 
-  tempax += tempbx;
+  SiS_Pr->SiS_SetFlag = 0;
 
-  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
 
-  push2 = tempax;
-  
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) { 
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if((!SiS_Pr->SiS_IF_DEF_DSTN) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
-     	   else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
-	  	   if(HwDeviceExtension->jChipType < SIS_315H) {
-		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-		         tempcx = 0x0017;
-#ifdef TWNEWPANEL
-			 tempcx = 0x0018;
-#endif
-		      } else {
-		         tempcx = 0x0017;  /* A901; sometimes 0x0018; */
-		      }
-		   } else {
-		      tempcx = 0x0018;
-		   }
+  tempbx = 0;
+  if(SiS_BridgeIsOn(SiS_Pr) == 0) {
+    	temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+#if 0
+	/* SiS_HiVision is only used on 315/330+30xLV */
+	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
+	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* New from 650/30xLV 1.10.6s */
+	      temp &= (SetCRT2ToHiVisionTV | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
 	   }
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
-        }
-     }
-  }
-
-  tempcx += tempax;                              /* lcdhrs  */
-  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* New from 650/30xLV 1.10.6s */
+	      temp &= (SetCRT2ToHiVisionTV | SwitchCRT2 | SetSimuScanMode); 	/* 0x83 */
+	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
+	   }
+	}
+#endif
+#if 0
+    	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
+       		temp = (SetCRT2ToLCD | SetSimuScanMode);
+       		SiS_SetReg(SiS_Pr->SiS_P3d4,0x30,temp);
+    	}
+#endif
+    	tempbx |= temp;
+    	tempax = SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) << 8;
+        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
+    	tempbx |= tempax;
+    	tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);;
 
-  tempax = tempcx >> 3;                          /* BPLHRS */
-  temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; TW: Panel Link Horizontal Retrace Start  */
+#ifdef SIS315H
 
-  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-     temp = (tempax & 0x00FF) + 2;
-  } else {
-     temp = (tempax & 0x00FF) + 10;
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
-           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	      temp += 6;
-              if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-	         temp++;
-	         if(HwDeviceExtension->jChipType >= SIS_315H) {
-	            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-	               temp += 7;
-		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-		          temp -= 0x14;
-			  if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
-			     temp -= 10;
+	if(HwInfo->jChipType >= SIS_315H) {
+    	   if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV)) {
+	      if(ModeNo == 0x03) {
+	         /* Mode 0x03 is never in driver mode */
+		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
+	      }
+	      if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
+	         /* Reset LCDA setting */
+		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
+	      }
+	      if(IS_SIS650) {
+	         if(SiS_Pr->SiS_UseLCDA) {
+		    if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+		          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
+		       }
+		    }
+		 }
+#if 0		 /* We can't detect it this way; there are machines which do not use LCDA despite
+                  * the chip revision
+		  */
+		 if((tempbx & SetCRT2ToLCD) && (SiS_GetReg(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD)) {
+                    if((SiS_GetReg(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+		          if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
 			  }
 		       }
-	            }
-	         }
+		    } else {
+		       if((ModeNo <= 0x13) || (!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
+			  if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
+			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));
+		          }
+		       }
+		    }
+		 }
+#endif
 	      }
-           }
-        }
-     }
-  }
+	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+       	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
+          	 tempbx |= SetCRT2ToLCDA;
+	      }
+    	   }
 
-  temp &= 0x1F;
-  temp |= ((tempcx & 0x0007) << 5);
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; TW: Panel Link Horizontal Retrace End/Skew */
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+	      if(temp & SetToLCDA) {
+		 tempbx |= SetCRT2ToLCDA;
+	      }
+	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	         if(temp & EnableLVDSHiVision) {
+		    tempbx |= SetCRT2ToHiVisionTV;
+		 }
+	      }
+	   }
+	}
 
-  tempbx = push2;
-  tempcx = push1;                                /* lcdhdes  */
+#endif  /* SIS315H */
 
-  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; TW: Panel Link Vertical Retrace Start (2:0) */
+    	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD    |
+		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO |
+                       SetCRT2ToHiVisionTV;
+    	} else {
+                if(HwInfo->jChipType >= SIS_315H) {
+                    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
+        		temp = SetCRT2ToLCDA   | SetCRT2ToSCART |
+			       SetCRT2ToLCD    | SetCRT2ToHiVisionTV |
+			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;
+      		    else
+        		temp = SetCRT2ToLCDA | SetCRT2ToLCD;
+		} else {
+      		    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
+        		temp = SetCRT2ToTV | SetCRT2ToLCD;
+      		    else
+        		temp = SetCRT2ToLCD;
+		}
+    	}
 
-  tempcx >>= 3;                                  /* BPLHDES */
-  temp = (tempcx & 0x00FF);
-  if(ModeNo == 0x5b) temp--;                     
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; TW: Panel Link Horizontal Display Enable Start  */
+    	if(!(tempbx & temp)) {
+      		tempax = DisableCRT2Display;
+      		tempbx = 0;
+    	}
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {  
-     if(tempbx & 0x07) tempbx += 8;              
-  }
-  tempbx >>= 3;                                  /* BPLHDEE  */
-  temp = tempbx & 0x00FF;
-  if(ModeNo == 0x5b) temp--;			 
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; TW: Panel Link Horizontal Display Enable End  */
+   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+      		if(tempbx & SetCRT2ToLCDA) {
+        		tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
+      		}
+		if(tempbx & SetCRT2ToRAMDAC) {
+        		tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchCRT2|SetSimuScanMode);
+      		}
+		if((tempbx & SetCRT2ToLCD) /* && (!(SiS_Pr->SiS_VBType & VB_NoLCD)) */ ) {
+		        /* We initialize the Panel Link if the type of bridge is DH */
+        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
+      		}
+		if(tempbx & SetCRT2ToSCART) {
+        		tempbx &= (0xFF00|SetCRT2ToSCART|SwitchCRT2|SetSimuScanMode);
+        		tempbx |= SetPALTV;
+      		}
+		if(tempbx & SetCRT2ToHiVisionTV) {
+        		tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchCRT2|SetSimuScanMode);
+        		tempbx |= SetPALTV;
+      		}
+   	} else {
+	        if(HwInfo->jChipType >= SIS_315H) {
+		    if(tempbx & SetCRT2ToLCDA)
+		        tempbx &= (0xFF00|SwitchCRT2|SetSimuScanMode);
+		}
+      		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        	    if(tempbx & SetCRT2ToTV) {
+          		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchCRT2|SetSimuScanMode);
+		    }
+      		}
+      		if(tempbx & SetCRT2ToLCD) {
+        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchCRT2|SetSimuScanMode);
+		}
+	        if(HwInfo->jChipType >= SIS_315H) {
+		    if(tempbx & SetCRT2ToLCDA) {
+		        tempbx |= SetCRT2ToLCD;
+		    }
+		}
+	}
 
-  /* 2. Vertical setup */
+    	if(tempax & DisableCRT2Display) {
+      		if(!(tempbx & (SwitchCRT2 | SetSimuScanMode))) {
+        		tempbx = SetSimuScanMode | DisableCRT2Display;
+      		}
+    	}
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-     tempcx = SiS_Pr->SiS_VGAVT;
-     tempbx = SiS_Pr->SiS_VGAVDE;
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)       tempbx =  600;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) tempbx =  600;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx =  768;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) tempbx =  768;
-	   else								tempbx = 1024;
-        }
-     }
-     tempcx -= tempbx;
+    	if(!(tempbx & DriverMode)){
+      		tempbx |= SetSimuScanMode;
+    	}
 
-  } else {
+	/* LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
+	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
+	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
+	       modeflag &= (~CRT2Mode);
+	   }
+	}
+
+    	if(!(tempbx & SetSimuScanMode)) {
+      	    if(tempbx & SwitchCRT2) {
+        	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+		     if( (HwInfo->jChipType >= SIS_315H) &&
+			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+			 if(resinfo != SIS_RI_1600x1200) {
+                              tempbx |= SetSimuScanMode;
+			 }
+		     } else {
+            		      tempbx |= SetSimuScanMode;
+	             }
+        	}
+      	    } else {
+        	if(!(SiS_BridgeIsEnabled(SiS_Pr,HwInfo))) {
+          	     if(!(tempbx & DriverMode)) {
+            		  if(SiS_BridgeInSlave(SiS_Pr)) {
+			      tempbx |= SetSimuScanMode;
+            		  }
+                     }
+                }
+      	    }
+    	}
 
-     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;          /* VGAVT-VGAVDE  */
+    	if(!(tempbx & DisableCRT2Display)) {
+            if(tempbx & DriverMode) {
+                if(tempbx & SetSimuScanMode) {
+          	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
+	                if( (HwInfo->jChipType >= SIS_315H) &&
+			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
+			     if(resinfo != SIS_RI_1600x1200) {
+			          tempbx |= SetInSlaveMode;
+            		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+              		 	     if(tempbx & SetCRT2ToTV) {
+                		         if(!(tempbx & SetNotSimuMode)) {
+					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
+					 }
+              			     }
+                                  }
+			     }
+		        } else {
+            		    tempbx |= SetInSlaveMode;
+            		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+              		        if(tempbx & SetCRT2ToTV) {
+                		    if(!(tempbx & SetNotSimuMode)) {
+					SiS_Pr->SiS_SetFlag |= TVSimuMode;
+				    }
+              			}
+            		    }
+                        }
+	            }
+                }
+            } else {
+                tempbx |= SetInSlaveMode;
+        	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+          	    if(tempbx & SetCRT2ToTV) {
+            		if(!(tempbx & SetNotSimuMode)) {
+			    SiS_Pr->SiS_SetFlag |= TVSimuMode;
+			}
+          	    }
+        	}
+      	    }
+    	}
 
+	if(SiS_Pr->SiS_CHOverScan) {
+    	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+      	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+      	      if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1)) {
+		 tempbx |= SetCHTVOverScan;
+              }
+    	   }
+	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+      	      temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x79);
+      	      if((temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1)) {
+		 tempbx |= SetCHTVOverScan;
+ 	      }
+    	   }
+	   if(SiS_Pr->SiS_CHSOverScan) {
+	      tempbx |= SetCHTVOverScan;
+	   }
+	}
   }
 
-  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
-  push1 = tempbx;
-
-  tempax = SiS_Pr->SiS_VGAVDE;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+#ifdef SIS300
+     	if((HwInfo->jChipType==SIS_630) ||
+           (HwInfo->jChipType==SIS_730)) {
+	   if(ROMAddr && SiS_Pr->SiS_UseROM) {
+	      OutputSelect = ROMAddr[0xfe];
+           }
+           if(!(OutputSelect & EnablePALMN)) {
+              SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F);
+	   }
+           if(tempbx & SetCRT2ToTV) {
+              if(tempbx & SetPALTV) {
+               	 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
+                 if(temp & EnablePALM) tempbx &= (~SetPALTV);
+              }
+           }
+      	}
+#endif
+#ifdef SIS315H
+     	if(HwInfo->jChipType >= SIS_315H) {
+	   if(ROMAddr && SiS_Pr->SiS_UseROM) {
+	      OutputSelect = ROMAddr[0xf3];
+	      if(HwInfo->jChipType >= SIS_330) {
+	  	 OutputSelect = ROMAddr[0x11b];
+	      }
+           }
+	   if(!(OutputSelect & EnablePALMN)) {
+              SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F);
+	   }
+   	   if(tempbx & SetCRT2ToTV) {
+    	      if(tempbx & SetPALTV) {
+                 temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+               	 if(temp & EnablePALM) tempbx &= (~SetPALTV);
+              }
+           }
+  	}
+#endif
+  }
 
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
-     if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   && 
-         (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
-         (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempax =  600;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempax =  600;  
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempax =  768;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)  tempax =  768;  
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempax =  768;  
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempax = 1024; 
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempax = 1050; 
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempax = 1200; 
+  /* PALM/PALN on Chrontel 7019 */
+  SiS_Pr->SiS_CHPALM = SiS_Pr->SiS_CHPALN = FALSE;
+  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+     if(tempbx & SetCRT2ToTV) {
+     	if(tempbx & SetPALTV) {
+           temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+           if(temp & EnablePALM)      SiS_Pr->SiS_CHPALM = TRUE;
+	   else if(temp & EnablePALN) SiS_Pr->SiS_CHPALN = TRUE;
+       	}
      }
   }
 
-  tempbx += tempax;
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+  SiS_Pr->SiS_VBInfo = tempbx;
 
-  push2 = tempbx;
+  if(HwInfo->jChipType == SIS_630) {
+     SiS_SetChrontelGPIO(SiS_Pr, SiS_Pr->SiS_VBInfo);
+  }
 
-  tempcx >>= 1;
+#ifdef TWDEBUG
+#ifdef LINUX_KERNEL
+  printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n",
+      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n",
+      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
+#endif
+#endif
+}
 
-  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)) {
-     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-        if(!SiS_Pr->SiS_IF_DEF_DSTN) {
-     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0001;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0001;
-     	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
-	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
-		   if(HwDeviceExtension->jChipType < SIS_315H) {
-		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-			    tempcx = 0x0002;
-#ifdef TWNEWPANEL
-			    tempcx = 0x0003;
+/*********************************************/
+/*           DETERMINE HiVision MODE         */
+/*********************************************/
+
+void
+SiS_SetHiVision(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT temp;
 #endif
-		      } else {
-		            tempcx = 0x0002;   /* TW: A901; sometimes 0x0003; */
-		      }
-		   } else tempcx = 0x0003;
-           }
-     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
-     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
-     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
-     	   else 							 tempcx = 0x0057;
-	}
-     }
-  }
 
-  tempbx += tempcx;			 	/* BPLVRS  */
+  /* Note: This variable is only used on 30xLV systems.
+     CR38 has a different meaning on LVDS/CH7019 systems.
+   */
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      tempbx++;
+  SiS_Pr->SiS_HiVision = 0;
+  if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+           temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
+	   temp &= 0x38;
+	   SiS_Pr->SiS_HiVision = (temp >> 3);
+	}
+     }
+#endif /* SIS315H */
   }
+}
 
-  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+/*********************************************/
+/*               GET LCD INFO                */
+/*********************************************/
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; TW: Panel Link Vertical Retrace Start  */
+void
+SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+		  PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS300
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+#endif
+  USHORT temp,modeflag,resinfo=0;
+  const unsigned char SiS300SeriesLCDRes[] =
+         { 0,  1,  2,  3,  7,  4,  5,  8,
+	   0,  0, 10,  0,  0,  0,  0, 15 };
 
-  tempcx >>= 3;
+  SiS_Pr->SiS_LCDResInfo = 0;
+  SiS_Pr->SiS_LCDTypeInfo = 0;
+  SiS_Pr->SiS_LCDInfo = 0;
 
-  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if( (HwDeviceExtension->jChipType < SIS_315H) &&
-            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;	 
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
-        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
-        else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-     		if(HwDeviceExtension->jChipType < SIS_315H) {
-		        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-				tempcx = 0x0004;
-#ifdef TWNEWPANEL
-				tempcx = 0x0005;
-#endif
-		        } else {
-				tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
-			}
-		} else {
-			tempcx = 0x0005;
-		}
-        }
+  if(SiS_Pr->UseCustomMode) {
+     modeflag = SiS_Pr->CModeFlag;
+  } else {
+     if(ModeNo <= 0x13) {
+    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
      }
   }
 
-  tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
-  temp = tempcx & 0x000F;
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; TW: Panel Link Vertical Retrace End (3:0); Misc.  */
-
-  temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
-  if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
-  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
-            temp |= 0x80;
-         }
-      } else {
-	 if( (HwDeviceExtension->jChipType == SIS_630) ||
-	     (HwDeviceExtension->jChipType == SIS_730) ) {
-	    if(HwDeviceExtension->jChipRevision >= 0x30) {
-	       temp |= 0x80;
-	    }
-	 }
-      }
+#ifdef SIS315H
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x39,~0x04);
+     }
   }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; TW: Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+#endif
 
-  if (HwDeviceExtension->jChipType < SIS_315H) {
+  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return;
 
-#ifdef SIS300      /* 300 series */
+  /* Commented during LCDA tests; does this any harm? */
+  /* if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchCRT2))) return; @@@@@ */
 
-        tempeax = SiS_Pr->SiS_VGAVDE << 6;
-        temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
-        tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
-        if(temp != 0) tempeax++;
-        tempebx = tempeax;                         /* BPLVCFACT  */
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36);
 
-  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
-	   tempebx = 0x003F;
-	}
-
-  	temp = (USHORT)(tempebx & 0x00FF);
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; TW: Panel Link Vertical Scaling Factor */
-
-#endif /* SIS300 */
+#if 0
+  /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
+   	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
+   	SiS_SetReg(SiS_Pr->SiS_P3d4,0x36,temp);
+  }
+#endif
 
+  if(HwInfo->jChipType < SIS_315H) {
+  	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
   } else {
-
-#ifdef SIS315H  /* 310/325 series */
-
-#ifdef NEWCH701x
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
-#else
-	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x23);
-#endif	
-
-	tempeax = SiS_Pr->SiS_VGAVDE << 18;
-    	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
-    	tempeax = tempeax / SiS_Pr->SiS_VDE;
-    	if(temp != 0) tempeax++;
-    	tempebx = tempeax;                         /* BPLVCFACT  */
-        tempvcfact = tempeax;
-    	temp = (USHORT)(tempebx & 0x00FF);
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; TW: Panel Link Vertical Scaling Factor */
-    	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; TW: Panel Link Vertical Scaling Factor */
-    	temp = (USHORT)((tempebx & 0x00030000) >> 16);
-    	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-    	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; TW: Panel Link Vertical Scaling Factor */
-
-#endif /* SIS315H */
-
+        SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
   }
+  temp &= 0x0f;
+  if(HwInfo->jChipType < SIS_315H) {
+      /* Translate 300 series LCDRes to 315 series for unified usage */
+      temp = SiS300SeriesLCDRes[temp];
+  }
+  SiS_Pr->SiS_LCDResInfo = temp;
 
-  tempbx = push2;                                  /* BPLVDEE  */
-  tempcx = push1;
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN){
+       	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
+  }
+#endif
 
-  push1 = temp;					   
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
+		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
+  } else {
+    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
+		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+  }
 
-  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-   	if(!SiS_Pr->SiS_IF_DEF_DSTN){
-		if(HwDeviceExtension->jChipType < SIS_315H) {
-			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-      				if(resinfo == 15) tempcx++;
-				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-					if(resinfo == 7) tempcx++;
-		    		}
-			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      				if(resinfo == 7) tempcx++;
-				if(resinfo == 8) tempcx++; /* TW: Doesnt make sense anyway... */
-			} else  if(resinfo == 8) tempcx++;
-		} else {
-			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      				if(resinfo == 7) tempcx++;
-			}
-		}
-	}
+  if((!SiS_Pr->CP_HaveCustomData) || (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_PanelCustom)) {
+     if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
+  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
   }
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-     tempcx = SiS_Pr->SiS_VGAVDE;
-     tempbx = SiS_Pr->SiS_VGAVDE - 1;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+        SiS_Pr->SiS_LCDResInfo = Panel_Barco1366;
+     } else if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+        SiS_Pr->SiS_LCDResInfo = Panel_848x480;
+     }
   }
 
-  temp = ((tempbx & 0x0700) >> 8) << 3;
-  temp |= ((tempcx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; TW: Vertical Display Overflow; Control Signal */
+  switch(SiS_Pr->SiS_LCDResInfo) {
+     case Panel_800x600:   SiS_Pr->PanelXRes =  800; SiS_Pr->PanelYRes =  600; break;
+     case Panel_1024x768:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1280x1024: SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes = 1024; break;
+     case Panel_640x480_3:
+     case Panel_640x480_2:
+     case Panel_640x480:   SiS_Pr->PanelXRes =  640; SiS_Pr->PanelYRes =  480; break;
+     case Panel_1024x600:  SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  600; break;
+     case Panel_1152x864:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  864; break;
+     case Panel_1280x960:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  960; break;
+     case Panel_1152x768:  SiS_Pr->PanelXRes = 1152; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1400x1050: SiS_Pr->PanelXRes = 1400; SiS_Pr->PanelYRes = 1050; break;
+     case Panel_1280x768:  SiS_Pr->PanelXRes = 1280; SiS_Pr->PanelYRes =  768; break;
+     case Panel_1600x1200: SiS_Pr->PanelXRes = 1600; SiS_Pr->PanelYRes = 1200; break;
+     case Panel_320x480:   SiS_Pr->PanelXRes =  320; SiS_Pr->PanelYRes =  480; break;
+     case Panel_Custom:    SiS_Pr->PanelXRes = SiS_Pr->CP_MaxX;
+    			   SiS_Pr->PanelYRes = SiS_Pr->CP_MaxY;
+			   break;
+     case Panel_Barco1366: SiS_Pr->PanelXRes = 1360; SiS_Pr->PanelYRes = 1024; break;
+     case Panel_848x480:   SiS_Pr->PanelXRes =  848; SiS_Pr->PanelYRes =  480; break;
+     default:		   SiS_Pr->PanelXRes = 1024; SiS_Pr->PanelYRes =  768; break;
+  }
 
-  temp = tempbx & 0x00FF;
-  if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; TW: Panel Link Vertical Display Enable End  */
+  temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN){
+        /* Fake LVDS bridge for FSTN */
+      	temp = 0x04;
+      	SiS_SetReg(SiS_Pr->SiS_P3d4,0x37,temp);
+  }
+#endif
+  SiS_Pr->SiS_LCDInfo = temp;
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; TW: Panel Link Vertical Display Enable Start  */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+        SiS_Pr->SiS_LCDInfo = 0x80 | 0x40 | 0x20;   /* neg sync, RGB24 */
+     }
+  }
 
-  /* 3. Additional horizontal setup (scaling, etc) */
+  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
 
-  tempecx = SiS_Pr->SiS_VGAHDE;
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(modeflag & HalfDCLK)
-        tempecx >>= 1;
-  }
-  tempebx = SiS_Pr->SiS_HDE;
-  if(tempecx == tempebx) tempeax = 0xFFFF;
-  else {
-     tempeax = tempecx;
-     tempeax <<= 16;
-     temp = (USHORT)(tempeax % tempebx);
-     tempeax = tempeax / tempebx;
-     if(HwDeviceExtension->jChipType >= SIS_315H) {
-         if(temp) tempeax++;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) {
+	   /* For non-standard LCD resolution, we let the panel scale */
+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	   if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
+	      /* Bridge does not scale to 1280x960 */
+              SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+           /* TEMP - no idea about the timing and zoom factors */
+           SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+	      /* Bridge does not scale to 1280x1024 */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+	   if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	      /* TEMP - no idea about the timing and zoom factors */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	}
+	if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+           if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	      SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
+	   }
+	}
+     }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
+	      /* Bridge does not scale to 1280x1024 - TODO: TEST */
+	      SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+	   }
+	}
      }
   }
-  tempecx = tempeax;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = SiS_Pr->SiS_VGAHDE;
-      if(modeflag & HalfDCLK) tempeax >>= 1;
-      tempeax <<= 16;
-      tempeax = (tempeax / tempecx) - 1;
+
+  if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
+        SiS_Pr->SiS_LCDInfo &= 0xFFEF;
+	SiS_Pr->SiS_LCDInfo |= LCDPass11;
+     }
+#endif
   } else {
-      tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+#ifdef SIS300
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	   if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+              if(!(ROMAddr[0x235] & 0x02)) {
+	         SiS_Pr->SiS_LCDInfo &= 0xEF;
+ 	      }
+	   }
+        }
+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
+           SiS_Pr->SiS_LCDInfo &= 0xEF;
+	}
+     }
+#endif
   }
-  tempecx <<= 16;
-  tempecx |= (tempeax & 0xFFFF);
-  temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; TW: Panel Link DDA Operational Number in each horiz. line */
 
-  tempbx = SiS_Pr->SiS_VDE;
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-      tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
-      tempbx = (USHORT)(tempeax & 0x0FFFF);
-  } else {
-      tempax = SiS_Pr->SiS_VGAVDE << 6;
-      tempbx = push1;
-      tempbx &= 0x3f;
-      if(tempbx == 0) tempbx = 64;
-      tempax = tempax / tempbx;
-      tempbx = tempax;
+  /* Trumpion: Assume non-expanding */
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0) {
+     SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
   }
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)                 tempbx = 1;
 
-  temp = ((tempbx & 0xFF00) >> 8) << 3;
-  temp |= (USHORT)((tempecx & 0x0700) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; TW: Overflow register */
+  if(!((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; TW: Panel Link Vertical Accumulator Register */
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	   if(ModeNo > 0x13) {
+	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+                 if((resinfo == SIS_RI_800x600) || (resinfo == SIS_RI_400x300)) {
+                    SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+		 }
+              }
+           }
+        }
+	if(ModeNo == 0x12) {
+	   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+	      SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+	   }
+	}
+     }
 
-  tempecx >>= 16;                               /* BPLHCFACT  */
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      if(modeflag & HalfDCLK) tempecx >>= 1;
-  }
-  temp = (USHORT)((tempecx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; TW: Panel Link Horizontal Scaling Factor High */
+     if(modeflag & HalfDCLK) {
+        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+           if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+	      if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwInfo->jChipType < SIS_315H)) &&
+	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
+                 if(ModeNo > 0x13) {
+                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+                       if(resinfo == SIS_RI_512x384) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+                       if(resinfo == SIS_RI_400x300) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+                    }
+                 }
+	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+           } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+        } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+     }
 
-  temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; TW: Panel Link Horizontal Scaling Factor Low */
+  }
 
-  /* 630/301B and 630/LVDS do something for 640x480 panels here */
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+     if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
+     	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+     }
+  } else {
+     SiS_Pr->SiS_SetFlag |= LCDVESATiming;
+  }
 
 #ifdef SIS315H
-  /* TW: DSTN/FSTN initialisation - hardcoded for 320x480 panel */
-  if(SiS_Pr->SiS_IF_DEF_DSTN) {
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1E,0x01);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x25,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x26,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x27,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x28,0x87);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x29,0x5A);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
-     	tempbx = SiS_Pr->SiS_HDE + 64;                       	/*Blps = lcdhdee(lcdhdes+HDE) + 64*/
-     	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x38,temp);
-     	temp=((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
-     	tempbx += 32;		                     		/*Blpe=lBlps+32*/
-     	temp = tempbx & 0x00FF;
-     	if(SiS_Pr->SiS_IF_DEF_FSTN)  temp=0;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x39,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/*Bflml=0*/
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
-     	tempbx = SiS_Pr->SiS_VDE / 2;
-     	temp = tempbx & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3B,temp);
-     	temp = ((tempbx & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
-     	tempeax = SiS_Pr->SiS_HDE << 2;                       	/* BDxFIFOSTOP = (HDE*4)/128 */
-     	tempebx = 128;
-     	temp = (USHORT)(tempeax % tempebx);
-     	tempeax = tempeax / tempebx;
-     	if(temp != 0)  tempeax++;
-     	temp = (USHORT)(tempeax & 0x003F);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3E,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x3D,0x10);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
-     	tempax = SiS_Pr->SiS_HDE >> 4;                        	/* BDxWadroff = HDE*4/8/8 */
-     	pushcx = tempax;
-     	temp = tempax & 0x00FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x43,temp);
-     	temp = ((tempax & 0xFF00) >> 8) << 3;
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
-     	tempax = SiS_Pr->SiS_VDE;                             /*BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
-     	tempeax = (tempax * pushcx);
-     	tempebx = 0x00100000 + tempeax;
-     	temp = (USHORT)tempebx & 0x000000FF;
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x42,temp);
-     	temp = (USHORT)((tempebx & 0x0000FF00)>>8);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x41,temp);
-     	temp = (USHORT)((tempebx & 0x00FF0000)>>16);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x40,temp);
-     	temp = (USHORT)(((tempebx & 0x01000000)>>24) << 7);
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x03);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x50);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x04,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2F,0x01);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x13,0x00);
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);        /* Unlock */
-     	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
-     	if(SiS_Pr->SiS_IF_DEF_FSTN){
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2b,0x1b);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2c,0xe3);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x1e,0x62);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2e,0x04);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x2f,0x42);
-         	SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,0x01);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2b,0x02);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2c,0x00);
-         	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x00);
-     	}
-     	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0f,0x30);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x7d);
-     	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2e,0xe0);
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
+	/* Enable 302B/302LV dual link mode.
+         * (302B is a theory - not in any BIOS)
+	 */
+        if((SiS_Pr->SiS_CustomT == CUT_CLEVO1024) &&
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)) {
+	   /* (Sets this in SenseLCD; new paneltypes) */
+	   SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
+	}
+        if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+	   SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x39,0x04);
+	}
+     }
   }
-#endif  /* SIS315H */
-
-  return;
+#endif
 
+#ifdef LINUX_KERNEL
+#ifdef TWDEBUG
+  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
+	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
+#endif
+#endif
+#ifdef LINUX_XF86
+  xf86DrvMsgVerb(0, X_PROBED, 4,
+  	"(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
+	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
+#endif
 }
 
-#ifdef SIS315H
-void
-SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT BaseAddr)
+/*********************************************/
+/*                 GET VCLK                  */
+/*********************************************/
+
+USHORT
+SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
-}
+  USHORT tempbx;
+  const USHORT LCDXlat0VCLK[4]    = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
+  const USHORT LVDSXlat1VCLK[4]   = {VCLK40,       VCLK40,       VCLK40,       VCLK40};
+  const USHORT LVDSXlat4VCLK[4]   = {VCLK28,       VCLK28,       VCLK28,       VCLK28};
+#ifdef SIS300
+  const USHORT LCDXlat1VCLK300[4] = {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
+  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2_300,VCLK108_2_300,VCLK108_2_300,VCLK108_2_300};
+  const USHORT LVDSXlat2VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
+  const USHORT LVDSXlat3VCLK300[4]= {VCLK65_300,   VCLK65_300,   VCLK65_300,   VCLK65_300};
 #endif
-
-
 #ifdef SIS315H
-/* TW: For LVDS / 302B/30xLV - LCDA (this must only be called on 310/325 series!) */
-void
-SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex)
-{
+  const USHORT LCDXlat1VCLK310[4] = {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
+  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
+  const USHORT LVDSXlat2VCLK310[4]= {VCLK65_315,   VCLK65_315,   VCLK65_315,   VCLK65_315};
+  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2_315,VCLK108_2_315,VCLK108_2_315,VCLK108_2_315};
+#endif
+  USHORT CRT2Index,VCLKIndex=0;
   USHORT modeflag,resinfo;
-  USHORT push1,push2,tempax,tempbx,tempcx,temp;
-  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
+  const UCHAR  *CHTVVCLKPtr = NULL;
+  const USHORT *LCDXlatVCLK1 = NULL;
+  const USHORT *LCDXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK2 = NULL;
+  const USHORT *LVDSXlatVCLK3 = NULL;
 
-  if(IS_SIS330) {
-     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
-  } else if(IS_SIS740) {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 740/LVDS */
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
-	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
-     } else {
-        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV 1.10.1i */
-     }
+  if(HwInfo->jChipType >= SIS_315H) {
+#ifdef SIS315H
+     LCDXlatVCLK1 = LCDXlat1VCLK310;
+     LCDXlatVCLK2 = LCDXlat2VCLK310;
+     LVDSXlatVCLK2 = LVDSXlat2VCLK310;
+     LVDSXlatVCLK3 = LVDSXlat3VCLK310;
+#endif
   } else {
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
-        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 650/LVDS */
-	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);			/* 650/LVDS 1.10.07 */
-     } else {
-        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);			/* 650/30xLv 1.10.6s */
-     }
+#ifdef SIS300
+     LCDXlatVCLK1 = LCDXlat1VCLK300;
+     LCDXlatVCLK2 = LCDXlat2VCLK300;
+     LVDSXlatVCLK2 = LVDSXlat2VCLK300;
+     LVDSXlatVCLK3 = LVDSXlat3VCLK300;
+#endif
   }
 
   if(ModeNo <= 0x13) {
-    modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
   }
 
-  tempax = SiS_Pr->SiS_LCDHDES;
-  tempbx = SiS_Pr->SiS_HDE;
-  tempcx = SiS_Pr->SiS_HT;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 30x/B/LV */
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 1024;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 1400;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1600;
-	else 							      tempbx = 1280;
-  }
-  tempcx -= tempbx;                        	            	/* HT-HDE  */
-  push1 = tempax;
-  tempax += tempbx;	                                    	/* lcdhdee  */
-  tempbx = SiS_Pr->SiS_HT;
-  if(tempax >= tempbx)	tempax -= tempbx;
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
 
-  push2 = tempax;						/* push ax   lcdhdee  */
+        CRT2Index >>= 6;
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {      /*  LCD */
 
-  tempcx >>= 2;
+           if(HwInfo->jChipType < SIS_315H) {
+	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+	         VCLKIndex = LCDXlat0VCLK[CRT2Index];
+	      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	    	 VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	    	 VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+	    	 VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	         VCLKIndex = VCLK81_300;	/* guessed */
+	      } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+		 VCLKIndex = VCLK108_3_300;
+		 if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_300;
+	      } else {
+	    	 VCLKIndex = LCDXlatVCLK2[CRT2Index];
+	      }
+	   } else {
+	      if( (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) ||
+	          (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+      	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		    VCLKIndex = VCLK108_2_315;
+		 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+		    VCLKIndex = VCLK81_315;  	/* guessed */
+		 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+		    VCLKIndex = VCLK108_2_315;
+		 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+		    VCLKIndex = VCLK162_315;
+		 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+		    VCLKIndex = VCLK108_3_315;
+		    if(resinfo == SIS_RI_1280x1024) VCLKIndex = VCLK100_315;
+		 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+		    VCLKIndex = LCDXlatVCLK1[CRT2Index];
+	         } else {
+		    VCLKIndex = LCDXlatVCLK2[CRT2Index];
+      	         }
+	      } else {
+                 VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
+         	 VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        	 if(ModeNo > 0x13) {
+          	    VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+        	 }
+		 if(ModeNo <= 0x13) {
+		    if(HwInfo->jChipType <= SIS_315PRO) {
+		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
+	            } else {
+		       if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x00;
+		    }
+		 }
+		 if(HwInfo->jChipType <= SIS_315PRO) {
+		    if(VCLKIndex == 0) VCLKIndex = 0x41;
+		    if(VCLKIndex == 1) VCLKIndex = 0x43;
+		    if(VCLKIndex == 4) VCLKIndex = 0x44;
+		 }
+	      }
+	   }
 
-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
-  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
- 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
-	else                                                          tempcx = 0x30;
-     }
-  }
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
 
-  tempcx += tempax;  	                                  	/* lcdhrs  */
-  if(tempcx >= tempbx) tempcx -= tempbx;
-                                                           	/* v ah,cl  */
-  tempax = tempcx;
-  tempax >>= 3;   	                                     	/* BPLHRS */
-  temp = tempax & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,temp);                 	/* Part1_14h  */
+           if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+	       (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
+              if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = HiTVVCLKDIV2;
+     	      else                                 VCLKIndex = HiTVVCLK;
+              if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+            	 if(modeflag & Charx8Dot) VCLKIndex = HiTVSimuVCLK;
+            	 else 			   VCLKIndex = HiTVTextVCLK;
+              }
+           } else {
+       	      if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO) VCLKIndex = TVVCLKDIV2;
+              else         		            VCLKIndex = TVVCLK;
+           }
+	   if(HwInfo->jChipType < SIS_315H) {
+              VCLKIndex += TVCLKBASE_300;
+  	   } else {
+	      VCLKIndex += TVCLKBASE_315;
+	   }
 
-  temp += 10;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	   temp += 6;
-	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
-	      temp++;
-	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-	         temp += 7;
-		 if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-		    temp -= 10;
+        } else {         					/* VGA2 */
+
+           VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+           if(ModeNo > 0x13) {
+              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+	      if(HwInfo->jChipType < SIS_315H) {
+          	 VCLKIndex &= 0x3f;
+		 if( (HwInfo->jChipType == SIS_630) &&
+		     (HwInfo->jChipRevision >= 0x30)) {
+		     /* This is certainly wrong: It replaces clock
+		      * 108 by 47...
+		      */
+		    /* if(VCLKIndex == 0x14) VCLKIndex = 0x2e; */
+		    if(VCLKIndex == 0x14) VCLKIndex = 0x34;
 		 }
 	      }
+           }
+        }
+
+     } else {   /* If not programming CRT2 */
+
+        VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        if(ModeNo > 0x13) {
+           VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+	   if(HwInfo->jChipType < SIS_315H) {
+              VCLKIndex &= 0x3f;
+	      if( (HwInfo->jChipType != SIS_630) &&
+		  (HwInfo->jChipType != SIS_300) ) {
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+	      }
 	   }
-	}
+        }
      }
-  }
-  temp &= 0x1F;
-  temp |= ((tempcx & 0x07) << 5);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
 
-  tempbx = push2;                                          	/* lcdhdee  */
-  tempcx = push1;                                          	/* lcdhdes  */
-  temp = (tempcx & 0x00FF);
-  temp &= 0x07;                                  		/* BPLHDESKEW  */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+  } else {       /*   LVDS  */
 
-  tempcx >>= 3;   	                                     	/* BPLHDES */
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+     VCLKIndex = CRT2Index;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-     if(tempbx & 0x07) tempbx += 8;
-  }
-  tempbx >>= 3;                                        		/* BPLHDEE  */
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
+     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
 
-  tempcx = SiS_Pr->SiS_VGAVT;
-  tempbx = SiS_Pr->SiS_VGAVDE;
-  tempcx -= tempbx; 	                                   	/* GAVT-VGAVDE  */
-  tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
-  push1 = tempbx;                                      		
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)        tempax = 768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempax = 768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempax = 1024;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempax = 1050;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempax = 1200;
-    else                                                           tempax = 960;
-  } else tempax = SiS_Pr->SiS_VGAVDE;  /* Trumpion */
+        if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
 
-  tempbx += tempax;
-  tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
-  if(tempbx >= tempax)  tempbx -= tempax;
+	   VCLKIndex &= 0x1f;
+           tempbx = 0;
+	   if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+           if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	      tempbx += 2;
+	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
+	      }
+	      if(SiS_Pr->SiS_CHPALM) {
+		 tempbx = 4;
+		 if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+	      } else if(SiS_Pr->SiS_CHPALN) {
+		 tempbx = 6;
+		 if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+	      }
+	   }
+       	   switch(tempbx) {
+             case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
+             case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
+             case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
+             case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
+	     case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
+             case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
+             case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
+             case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
+	     case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
+	     default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
+           }
+           VCLKIndex = CHTVVCLKPtr[VCLKIndex];
 
-  push2 = tempbx;                                      		
- 
-  tempcx >>= 2;	
+        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-  /* TW: 650/30xLV 1.10.6s, 740/LVDS */
-  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
-      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
-   	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
-	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 1;
-	else                                                           tempcx = 0x0057;
-     }
-  }
+	   VCLKIndex >>= 6;
+     	   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
+	      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
+     	      VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480   ||
+	           SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+		   SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)
+	      VCLKIndex = LVDSXlat4VCLK[VCLKIndex];
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+     	      VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
+              VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
+              VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)
+	      VCLKIndex = VCLK68_315;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+	      VCLKIndex = VCLK162_315;
+     	   else
+	      VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
+
+	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+	      /* Special Timing: Barco iQ Pro R300/400/... */
+	      VCLKIndex = 0x44;
+	   }
+
+	   if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+	      if(HwInfo->jChipType < SIS_315H) {
+		 VCLKIndex = VCLK34_300;
+	         /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
+	      } else {
+		 VCLKIndex = VCLK34_315;
+		 /* if(resinfo == SIS_RI_1360x768) VCLKIndex = ?; */
+	      }
+	   }
 
-  tempbx += tempcx;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-     tempbx++;                                                	/* BPLVRS  */
-  }
-  if(tempbx >= tempax)   tempbx -= tempax;
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
+        } else {
+
+	   VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+           if(ModeNo > 0x13) {
+              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+	      if(HwInfo->jChipType < SIS_315H) {
+    	 	 VCLKIndex &= 0x3F;
+              }
+	      if( (HwInfo->jChipType == SIS_630) &&
+                  (HwInfo->jChipRevision >= 0x30) ) {
+		 if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
+	      }
+	   }
+        }
+
+     } else {  /* if not programming CRT2 */
+
+        VCLKIndex = (UCHAR)SiS_GetRegByte((USHORT)(SiS_Pr->SiS_P3ca+0x02));
+        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
+        if(ModeNo > 0x13) {
+           VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
+           if(HwInfo->jChipType < SIS_315H) {
+	      VCLKIndex &= 0x3F;
+	      if( (HwInfo->jChipType != SIS_630) &&
+	          (HwInfo->jChipType != SIS_300) ) {
+		 if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
+	      }
+#if 0
+	      if(HwInfo->jChipType == SIS_730) {
+		 if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
+		 if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */
+	      }
+#endif
+	   }
+        }
 
-  tempcx >>= 3;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 3;
-   	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 5;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 5;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 5;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 2;
-	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 2;
-	}
      }
+
   }
-  tempcx += tempbx;
-  tempcx++;                                                	/* BPLVRE  */
-  temp = tempcx & 0x00FF;
-  temp &= 0x0F;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
-  } else {
-     /* TW: 650/30xLV 1.10.6s, Xabre */
-     temp |= 0xC0;
-     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
-  }
+
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
+#endif
 
-  temp = (tempbx & 0xFF00) >> 8;
-  temp &= 0x07;
-  temp <<= 3;  		                               		/* BPLDESKEW =0 */
-  tempbx = SiS_Pr->SiS_VGAVDE;
-  if(tempbx != SiS_Pr->SiS_VDE)              temp |= 0x40;
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-        if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-     }
+  return(VCLKIndex);
+}
+
+/*********************************************/
+/*        SET CRT2 MODE TYPE REGISTERS       */
+/*********************************************/
+
+static void
+SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                    PSIS_HW_INFO HwInfo)
+{
+  USHORT i,j,modeflag;
+  USHORT tempcl,tempah=0;
+#ifdef SIS300
+  USHORT temp;
+#endif
+#ifdef SIS315H
+  USHORT tempbl;
+#endif
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-     if(IS_SIS650) {
-        /* TW: 650/30xLV 1.10.6s */
-        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-           if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
-        }
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
      } else {
-	if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
      }
   }
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);            /* Part1_1Ah */
+
+  /* BIOS does not do this (neither 301 nor LVDS) */
+  /*     (But it's harmless; see SetCRT2Offset) */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
 
-  tempbx = push2;                                      		/* BPLVDEE  */
-  tempcx = push1;                                      		/* NPLVDES */
-  push1 = (USHORT)(tempeax & 0xFFFF);
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
-  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-      if(resinfo == 7) tempcx++;
-    }
-  }
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-    tempbx = SiS_Pr->SiS_VGAVDE;
-    tempcx = tempbx;
-    tempbx--;
-  }
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
 
-  temp = (tempbx & 0xFF00) >> 8;
-  temp &= 0x07;
-  temp <<= 3;
-  temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+  } else {
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+     for(i=0,j=4; i<3; i++,j++) SiS_SetReg(SiS_Pr->SiS_Part1Port,j,0);
 
-  temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
+     tempcl = SiS_Pr->SiS_ModeType;
 
-  tempecx = SiS_Pr->SiS_VGAVT;
-  tempebx = SiS_Pr->SiS_VDE;
-  tempeax = SiS_Pr->SiS_VGAVDE;
-  tempecx -= tempeax;    	                             	/* VGAVT-VGAVDE  */
-  tempeax <<= 18;
-  temp = (USHORT)(tempeax % tempebx);
-  tempeax = tempeax / tempebx;
-  if(temp)  tempeax++;
-  tempebx = tempeax;                                        	/* BPLVCFACT  */
-  tempvcfact = tempeax;
-  temp = (USHORT)(tempebx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x37,temp);
+     if(HwInfo->jChipType < SIS_315H) {
 
-  temp = (USHORT)((tempebx & 0x00FF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x36,temp);
+#ifdef SIS300    /* ---- 300 series ---- */
 
-  temp = (USHORT)((tempebx & 0x00030000) >> 16);
-  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x35,temp);
+        /* For 301BDH: (with LCD via LVDS) */
+        if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+	   temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32);
+	   temp &= 0xef;
+	   temp |= 0x02;
+	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+	      temp |= 0x10;
+	      temp &= 0xfd;
+	   }
+	   SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+        }
 
-  tempecx = SiS_Pr->SiS_VGAHDE;
-  if(modeflag & HalfDCLK) tempecx >>= 1;
-  tempebx = SiS_Pr->SiS_HDE;
-  tempeax = tempecx;
-  tempeax <<= 16;
-  temp = tempeax % tempebx;
-  tempeax = tempeax / tempebx;
-  if(temp) tempeax++;
-  if(tempebx == tempecx)  tempeax = 0xFFFF;
-  tempecx = tempeax;
-  tempeax = SiS_Pr->SiS_VGAHDE;
-  if(modeflag & HalfDCLK) tempeax >>= 1;
-  tempeax <<= 16;
-  tempeax = tempeax / tempecx;
-  tempecx <<= 16;
-  tempeax--;
-  tempecx = tempecx | (tempeax & 0xFFFF);
-  temp = (USHORT)(tempecx & 0x00FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
+        if(ModeNo > 0x13) {
+           tempcl -= ModeVGA;
+           if((tempcl > 0) || (tempcl == 0)) {      /* tempcl is USHORT -> always true! */
+              tempah = ((0x10 >> tempcl) | 0x80);
+           }
+        } else tempah = 0x80;
 
-  tempeax = SiS_Pr->SiS_VGAVDE;
-  tempeax <<= 18;
-  tempeax = tempeax / tempvcfact;
-  tempbx = (USHORT)(tempeax & 0x0FFFF);
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+#endif  /* SIS300 */
 
-  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
+     } else {
 
-  temp = ((tempbx & 0xFF00) >> 8) << 3;
-  temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+#ifdef SIS315H    /* ------- 315/330 series ------ */
 
-  temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+           if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
+           }
+        }
 
-  tempecx >>= 16;   	                                  	/* BPLHCFACT  */
-  if(modeflag & HalfDCLK) tempecx >>= 1;
-  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+        if(ModeNo > 0x13) {
+           tempcl -= ModeVGA;
+           if((tempcl > 0) || (tempcl == 0)) {  /* tempcl is USHORT -> always true! */
+              tempah = (0x08 >> tempcl);
+              if (tempah == 0) tempah = 1;
+              tempah |= 0x40;
+           }
+        } else tempah = 0x40;
 
-  temp=(USHORT)(tempecx & 0x000000FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x23,temp);
+        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
 
-#if 0
-  /* TW: Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
-  if(xxx()) {
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x0e,0xda);
-  }
-#endif
+#endif  /* SIS315H */
 
-  /* TW: Only for LVDS and 301LV/302LV */
-  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)){
-  	SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1e,0x20);
-  }
+     }
 
-  return;
-}
-#endif  /* SIS 315 */
+     if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
 
-void SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                       USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
-		       PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT offset;
-  UCHAR temp;
+     if(HwInfo->jChipType < SIS_315H) {
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
+     } else {
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
+        } else {
+           if(IS_SIS740) {
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
+	   } else {
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
+	   }
+        }
+     }
 
-  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-  offset = SiS_GetOffset(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                         HwDeviceExtension);
-#if 0
-  if(SiS_Pr->LCDResInfo == 13) offset >>= 1;
-  if(SiS_Pr->LCDResInfo == 12) offset >>= 1;
-#endif			 
-  temp = (UCHAR)(offset & 0xFF);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x07,temp);
-  temp = (UCHAR)((offset & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x09,temp);
-  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,temp);
-}
+        tempah = 0x01;
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+      	   tempah |= 0x02;
+        }
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
+      	   tempah ^= 0x05;
+      	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+              tempah ^= 0x01;
+      	   }
+        }
 
-USHORT
-SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-              USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp,colordepth;
-  USHORT modeinfo,index,infoflag;
+        if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
 
-  if(SiS_Pr->UseCustomMode) {
-     infoflag = SiS_Pr->CInfoFlag;
-     temp = SiS_Pr->CHDisplay / 16;
-  } else {
-     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
-     modeinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeInfo;
-  
-     if(HwDeviceExtension->jChipType < SIS_315H ) {
-    	index = (modeinfo >> 4) & 0xFF;
-     } else {
-    	index = (modeinfo >> 8) & 0xFF;
-     }
+        if(HwInfo->jChipType < SIS_315H) {
 
-     temp = SiS_Pr->SiS_ScreenOffset[index];
-  }
-  
-  colordepth = SiS_GetColorDepth(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+      	   tempah = (tempah << 5) & 0xFF;
+      	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
+      	   tempah = (tempah >> 5) & 0xFF;
 
-  if(infoflag & InterlaceMode) temp <<= 1;
+        } else {
 
-  temp *= colordepth;
+      	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
 
-  /* TW: For 1400x1050 and 856x480 */
-  if( ( ((ModeNo >= 0x26) && (ModeNo <= 0x28)) || 
-        ModeNo == 0x3f || 
-	ModeNo == 0x42 || 
-	ModeNo == 0x45 ) ||
-      (SiS_Pr->UseCustomMode && (SiS_Pr->CHDisplay % 16)) ) {
-        colordepth >>= 1;
-	temp += colordepth;
-  }
+        }
 
-  return(temp);
-}
+        if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
+      	   tempah |= 0x10;
+        }
 
-USHORT
-SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
-{
-  USHORT ColorDepth[6] = { 1, 2, 4, 4, 6, 8};
-  SHORT  index;
-  USHORT modeflag;
+        if((HwInfo->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
+	   if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+	      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
+	      tempah |= 0x80;
+	   }
+        } else {
+	   tempah |= 0x80;
+        }
 
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
-  } else {
-     if(ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-     else
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }	
+        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+      	   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	      if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+           	tempah |= 0x20;
+	      }
+      	   }
+        }
 
-  index = (modeflag & ModeInfoFlag) - ModeEGA;
-  if(index < 0) index = 0;
-  return(ColorDepth[index]);
-}
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
 
-void
-SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempah=0,tempbl,infoflag,flag;
+        tempah = 0;
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+      	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+       	            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+             	       SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+             	       tempah |= 0x40;
+       		    } else {
+        	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) {
+          		  SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+            		  tempah |= 0x40;
+        	       }
+      		    }
+		 }
+     	      } else {
+        	 SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
+        	 tempah |= 0x40;
+      	      }
+	   }
+        }
 
-  flag = 0;
-  tempbl = 0xC0;
+        /* For 302LV dual-channel */
+        if(HwInfo->jChipType >= SIS_315H) {
+	   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	      if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempah |= 0x40;
+	   }
+        }
 
-  infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+        if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  ||
+	   ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) &&
+	    (SiS_Pr->CP_MaxX >= 1280) && (SiS_Pr->CP_MaxY >= 960))) {
+	   tempah |= 0x80;
+        }
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
+        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0C,tempah);
 
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       tempah = 0;
-    } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
-       tempah = SiS_Pr->SiS_LCDInfo;
-    } else tempah = infoflag >> 8;
-    
-    tempah &= 0xC0;
-    
-    tempah |= 0x20;
-    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+     } else {  /* LVDS */
 
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
-          tempah >>= 3;
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
-       }
-    } else {
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
-    }
+        if(HwInfo->jChipType >= SIS_315H) {
 
-  } else {
+	   /* LVDS can only be slave in 8bpp modes */
+	   tempah = 0x80;
+	   if((modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA)) {
+	      if(SiS_Pr->SiS_VBInfo & DriverMode) {
+	         tempah |= 0x02;
+	      }
+	   }
 
-     if(HwDeviceExtension->jChipType < SIS_315H) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+              tempah |= 0x02;
+    	   }
 
-#ifdef SIS300  /* ---- 300 series --- */
+	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	      tempah ^= 0x01;
+	   }
 
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 1;
+	   }
 
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-               tempah = SiS_Pr->SiS_LCDInfo;
-	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-                  flag = 1;
-               }
-            }
-            if(flag != 1) tempah = infoflag >> 8;
-            tempah &= 0xC0;
-	    
-            tempah |= 0x20;
-            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
 
-            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-	       	/* TW: BIOS does something here @@@ */
-            }
+        } else {
 
- 	    tempah &= 0x3f;
-  	    tempah |= tempbl;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+	   tempah = 0;
+	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
+              tempah |= 0x02;
+    	   }
+	   tempah <<= 5;
 
-         } else {							/* 630 - 301 */
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
 
-            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-               tempah = SiS_Pr->SiS_LCDInfo;
-	       if(SiS_Pr->SiS_LCDInfo & DontExpandLCDShift) { /* ! */
-	          flag = 1;
-	       }
-            }
-            if(flag != 1) tempah = infoflag >> 8;
-            tempah &= 0xC0;
-            tempah |= 0x30;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x3F,tempah);
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,tempah);
 
-         }
+        }
 
-#endif /* SIS300 */
+     }
 
-      } else {
+  }  /* LCDA */
 
-#ifdef SIS315H  /* ----- 310/325 series ---- */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 310/325 - 30xLV */
+     if(HwInfo->jChipType >= SIS_315H) {
 
-            tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-            tempah &= 0xC0;
-            tempah |= 0x20;
-            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+#ifdef SIS315H
 
-         } else {							/* 310/325 - 301, 301B */
+        unsigned char bridgerev = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x01);;
 
-            tempah = infoflag >> 8;
-            tempah &= 0xC0;
-	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
-	          tempah = SiS_Pr->SiS_LCDInfo;
-	          tempah &= 0xC0;
-	       }
-	    }
-	    
-            tempah |= 0x20;
-            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
-#if 0
-            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-		/* TW: BIOS does something here @@@ */
-            }
-#endif	    
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+	/* The following is nearly unpreditable and varies from machine
+	 * to machine. Especially the 301DH seems to be a real trouble
+	 * maker. Some BIOSes simply set the registers (like in the
+	 * NoLCD-if-statements here), some set them according to the
+	 * LCDA stuff. It is very likely that some machines are not
+	 * treated correctly in the following, very case-orientated
+	 * code. What do I do then...?
+	 */
+
+	/* 740 variants match for 30xB, 301B-DH, 30xLV */
+
+        if(!(IS_SIS740)) {
+           tempah = 0x04;						   /* For all bridges */
+           tempbl = 0xfb;
+           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+              tempah = 0x00;
+	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+	         tempbl = 0xff;
+	      }
+           }
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+	}
 
-         } 
-	 
-#endif  /* SIS315H */
-      }
-   }
-}
+	/* The following two are responsible for eventually wrong colors
+	 * in TV output. The DH (VB_NoLCD) conditions are unknown; the
+	 * b0 was found in some 651 machine (Pim); the b1 version in a
+	 * 650 box (Jake). What is the criteria?
+	 */
+
+	if(IS_SIS740) {
+	   tempah = 0x30;
+	   tempbl = 0xcf;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+	} else if(SiS_Pr->SiS_VBType & VB_SIS301) {
+	   /* Fixes "TV-blue-bug" on 315+301 */
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);          /* For 301   */
+	} else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
+	} else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xB-DH rev b0 (or "DH on 651"?) */
+	} else {
+	   tempah = 0x30;					     /* For 30xB (and 301BDH rev b1) */
+	   tempbl = 0xcf;
+	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	      tempah = 0x00;
+	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+		 tempbl = 0xff;
+	      }
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);
+	}
 
-/* TW: Set CRT2 FIFO on 300/630/730 */
-#ifdef SIS300
-void
-SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp,index;
-  USHORT modeidindex,refreshratetableindex;
-  USHORT VCLK=0,MCLK,colorth=0,data2=0;
-  USHORT tempal, tempah, tempbx, tempcl, tempax;
-  USHORT CRT1ModeNo,CRT2ModeNo;
-  USHORT SelectRate_backup;
-  ULONG  data,eax;
-  const UCHAR  LatencyFactor[] = {
-  	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
-        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
-        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
-        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
-        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
-        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
-        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
-        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
-  };
-  const UCHAR  LatencyFactor730[] = {
-         69, 63, 61, 
-	 86, 79, 77,
-	103, 96, 94,
-	120,113,111,
-	137,130,128,    /* <-- last entry, data below */
-	137,130,128,	/* to avoid using illegal values */
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-	137,130,128,
-  };
-  const UCHAR ThLowB[]   = {
-  	81, 4, 72, 6, 88, 8,120,12,
-        55, 4, 54, 6, 66, 8, 90,12,
-        42, 4, 45, 6, 55, 8, 75,12
-  };
-  const UCHAR ThTiming[] = {
-  	1, 2, 2, 3, 0, 1, 1, 2
-  };
-  
-  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
+	if(IS_SIS740) {
+	   tempah = 0xc0;
+  	   tempbl = 0x3f;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+	} else if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xLV */
+	} else if((SiS_Pr->SiS_VBType & VB_NoLCD) && (bridgerev == 0xb0)) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);	/* For 30xB-DH rev b0 (or "DH on 651"? */
+	} else {
+	   tempah = 0xc0;						/* For 301, 301B (and 301BDH rev b1) */
+	   tempbl = 0x3f;
+	   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+	      tempah = 0x00;
+	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+	         tempbl = 0xff;
+	      }
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);
+	}
 
-  if(!SiS_Pr->CRT1UsesCustomMode) {
-  
-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
-     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&modeidindex);
-     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-     SiS_Pr->SiS_SelectCRT2Rate = 0;
-     refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
-						modeidindex,HwDeviceExtension);
+	if(IS_SIS740) {
+	   tempah = 0x80;
+	   tempbl = 0x7f;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+	} else {
+	   tempah = 0x00;						/* For all bridges */
+           tempbl = 0x7f;
+           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+              tempbl = 0xff;
+	      if(!(SiS_IsDualEdge(SiS_Pr, HwInfo))) {
+	         tempah |= 0x80;
+	      }
+           }
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
+	}
 
-     if(CRT1ModeNo >= 0x13) {
-       index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
-       index &= 0x3F;
-       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;			/* Get VCLK */
-       data2 = SiS_Pr->SiS_ModeType - 2;
-     }
-     
-  } else {
-  
-     CRT1ModeNo = 0xfe;
-     VCLK = SiS_Pr->CSRClock;						/* Get VCLK */
-     data2 = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
-  
-  }			
-     
-  if(CRT1ModeNo >= 0x13) {
-    if(HwDeviceExtension->jChipType == SIS_300) {
-       index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x3A);
-    } else {
-       index = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1A);
-    }
-    index &= 0x07;
-    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
-    
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1Mode 0x%x VCLK %d MCLK %d modetype-2 = %d\n",
-    	CRT1ModeNo, VCLK, MCLK, data2);
-#endif  
-  
-    switch(data2) {							/* Get color depth */
-      case 0 : 	colorth = 1; break;
-      case 1 : 	colorth = 1; break;
-      case 2 : 	colorth = 2; break;
-      case 3 : 	colorth = 2; break;
-      case 4 : 	colorth = 3; break;
-      case 5 : 	colorth = 4; break;
-      default:  colorth = 2; break;
-    }
-    data2 = (colorth * VCLK) / MCLK;  
+#endif /* SIS315H */
 
-    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-    temp = ((temp & 0x00FF) >> 6) << 1;
-    if(temp == 0) temp = 1;
-    temp <<= 2;
-    temp &= 0xff;
+     } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-    data2 = temp - data2;
-    
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step1) = %d\n",
-    	data2);
-#endif    
+        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
 
-    if((28 * 16) % data2) {
-      	data2 = (28 * 16) / data2;
-      	data2++;
-    } else {
-      	data2 = (28 * 16) / data2;
-    }
-    
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "FIFO2: data2 (step2) = %d\n",
-    	data2);
-#endif
+        if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
+           (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
+	       (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
+	   SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
+	} else {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
+	}
 
-    if(HwDeviceExtension->jChipType == SIS_300) {
+     }
 
-	tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-	tempah &= 0x62;
-	tempah >>= 1;
-	tempal = tempah;
-	tempah >>= 3;
-	tempal |= tempah;
-	tempal &= 0x07;
-	tempcl = ThTiming[tempal];
-	tempbx = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-	tempbx >>= 6;
-	tempah = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-	tempah >>= 4;
-	tempah &= 0x0c;
-	tempbx |= tempah;
-	tempbx <<= 1;
-	tempal = ThLowB[tempbx + 1];
-	tempal *= tempcl;
-	tempal += ThLowB[tempbx];
-	data = tempal;
-
-    } else if(HwDeviceExtension->jChipType == SIS_730) {
-       
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x80000050);
-       eax = SiS_GetReg3(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0x50);
-#endif
-       tempal = (USHORT)(eax >> 8);
-       tempal &= 0x06;
-       tempal <<= 5;
+  } else {  /* LVDS */
 
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x800000A0);
-       eax = SiS_GetReg3(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0xA0);
-#endif
-       temp = (USHORT)(eax >> 28);
-       temp &= 0x0F;   
-       tempal |= temp;
+#ifdef SIS315H
+     if(HwInfo->jChipType >= SIS_315H) {
 
-#ifdef TWDEBUG
-       xf86DrvMsg(0, X_INFO, "FIFO2: Latencyfactorindex = 0x%x\n", tempal);
-#endif
-      
-       tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
-       tempbx = 0;        /* -- do it like the BIOS anyway... */
-       tempax = tempbx;
-       tempbx &= 0xc0;
-       tempbx >>= 6;
-       tempax &= 0x0f;
-       tempax *= 3;
-       tempbx += tempax;
-       
-       data = LatencyFactor730[tempbx];
-       data += 15;
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if(!(temp & 0x80)) data += 5;
-       
-    } else {
+        if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
 
-       index = 0;
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if(temp & 0x0080) index += 12;
+           tempah = 0x04;
+	   tempbl = 0xfb;
+           if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+              tempah = 0x00;
+	      if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
+	         tempbl = 0xff;
+	      }
+           }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
 
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x800000A0);
-       eax = SiS_GetReg3(0xcfc);
-#else
-       /* TW: We use pci functions X offers. We use tag 0, because
-        * we want to read/write to the host bridge (which is always
-        * 00:00.0 on 630, 730 and 540), not the VGA device.
-        */
-       eax = pciReadLong(0x00000000, 0xA0);
-#endif
-       temp = (USHORT)(eax >> 24);
-       if(!(temp&0x01)) index += 24;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
+	   }
 
-#ifndef LINUX_XF86
-       SiS_SetReg4(0xcf8,0x80000050);
-       eax = SiS_GetReg3(0xcfc);
-#else
-       eax = pciReadLong(0x00000000, 0x50);
-#endif
-       temp=(USHORT)(eax >> 24);
-       if(temp & 0x01) index += 6;
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
 
-       temp = (temp & 0x0F) >> 1;
-       index += temp;
-       
-       data = LatencyFactor[index];
-       data += 15;
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14);
-       if(!(temp & 0x80)) data += 5;
-    }
-    
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: latencyfactor (CRT1) = %d\n", data);
-#endif
+	} else if(HwInfo->jChipType == SIS_550) {
 
-    data += data2;				/* CRT1 Request Period */
-    
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT1 request period = %d\n", data);
+#if 0
+	   tempah = 0x00;
+	   tempbl = 0xfb;
+	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+	      tempah = 0x00;
+	      tempbl = 0xfb;
+	   }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
 #endif
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
 
-    CRT2ModeNo = ModeNo;
-    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
-    SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&modeidindex);    
-
-    refreshratetableindex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                               modeidindex,HwDeviceExtension);
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+	}
 
-    index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,modeidindex,
-                            refreshratetableindex,HwDeviceExtension);
-    VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
-    
-    data2 = SiS_Pr->SiS_ModeType - 2;
-    switch(data2) {							/* Get color depth */
-      case 0 : 	colorth = 1; break;
-      case 1 : 	colorth = 1; break;
-      case 2 : 	colorth = 2; break;
-      case 3 : 	colorth = 2; break;
-      case 4 : 	colorth = 3; break;
-      case 5 : 	colorth = 4; break;
-      default:  colorth = 2; break;
-    }
-    
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: CRT2Mode 0x%x VCLK %d MCLK %d modetype-2 = %d, colorth %d\n",
-    	CRT2ModeNo, VCLK, MCLK, data2, colorth);
+     }
 #endif
 
-    data = data * VCLK * colorth;
-    if(data % (MCLK << 4)) {
-      	data = data / (MCLK << 4);
-      	data++;
-    } else {
-      	data = data / (MCLK << 4);
-    }
-    
-#ifdef TWDEBUG    
-    xf86DrvMsg(0, X_INFO, "FIFO2: data (unclipped) = 0x%x\n", data);
-#endif    
-    
-    if(data <= 6) data = 6;
-    if(data > 0x14) data = 0x14;
-
-    temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x01);
-    if(HwDeviceExtension->jChipType == SIS_300) {
-       if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
-       else             temp = (temp & (~0x1F)) | 0x16;
-       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-       		temp = (temp & (~0x1F)) | 0x13;
-       }
-    } else {
-       if( ( (HwDeviceExtension->jChipType == SIS_630) ||
-             (HwDeviceExtension->jChipType == SIS_730) )  &&
-           (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
-      {
-	  temp = (temp & (~0x1F)) | 0x1b;
-      } else {
-	  temp = (temp & (~0x1F)) | 0x16;
-      }
-    }
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
-
-    if( (HwDeviceExtension->jChipType == SIS_630) &&
-        (HwDeviceExtension->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
-    {
-   	if(data > 0x13) data = 0x13;
-    }
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
-    
-  } else {  /* If mode <= 0x13, we just restore everything */
-  
-    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
-    
   }
+
 }
-#endif
 
-/* TW: Set FIFO on 310/325/330 series */
-#ifdef SIS315H
-void
-SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*            GET RESOLUTION DATA            */
+/*********************************************/
+
+USHORT
+SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex)
 {
+  USHORT resindex;
 
-  UCHAR CombCode[]  = { 1, 1, 1, 4, 3, 1, 3, 4,
-                        4, 1, 4, 4, 5, 1, 5, 4};
-  UCHAR CRT2ThLow[] = { 39, 63, 55, 79, 78,102, 90,114,
-                        55, 87, 84,116,103,135,119,151};
-  USHORT temp3,tempax,tempbx,tempcx;
-  USHORT tempcl, tempch;
-  USHORT index;
-  USHORT CRT1ModeNo,CRT2ModeNo;
-  USHORT ModeIdIndex;
-  USHORT RefreshRateTableIndex;
-  USHORT SelectRate_backup;
-  
-  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
-  
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+  if(ModeNo <= 0x13)
+     resindex = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  else
+     resindex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
-  if(!SiS_Pr->CRT1UsesCustomMode) {
-  
-     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 /* get CRT1 ModeNo */
-     SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT1ModeNo,&ModeIdIndex);
+  return(resindex);
+}
 
-     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);   
-     SiS_Pr->SiS_SelectCRT2Rate = 0;
+static void
+SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                   PSIS_HW_INFO HwInfo)
+{
+  USHORT xres,yres,modeflag=0,resindex;
 
-     /* Get REFIndex for crt1 refreshrate */
-     RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT1ModeNo,
-                                             ModeIdIndex,HwDeviceExtension);
-
-     index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex,
-                          RefreshRateTableIndex,HwDeviceExtension);
-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                        /* Get VCLK */
-     
-     tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT1ModeNo,ModeIdIndex); /* Get colordepth */
-     tempbx >>= 1;
-     if(!tempbx) tempbx++; 
-     
-  } else {
-  
-     tempax = SiS_Pr->CSRClock;						/* Get VCLK */
-     tempbx = (SiS_Pr->CModeFlag & ModeInfoFlag) - 2;
-     switch(tempbx) {							/* Get color depth */
-       case 0 : 	tempbx = 1; break;
-       case 1 : 	tempbx = 1; break;
-       case 2 : 	tempbx = 2; break;
-       case 3 : 	tempbx = 2; break;
-       case 4 : 	tempbx = 3; break;
-       case 5 : 	tempbx = 4; break;
-       default:  	tempbx = 2; break;
-     }
-  
+  if(SiS_Pr->UseCustomMode) {
+     SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = SiS_Pr->CHDisplay;
+     SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = SiS_Pr->CVDisplay;
+     return;
   }
-    
-  tempax *= tempbx;
 
-  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);     		/* Get MCLK */
+  resindex = SiS_GetResInfo(SiS_Pr,ModeNo,ModeIdIndex);
 
-  tempax /= tempbx;
-
-  tempbx = tempax;
-
-#if 0 /* TW: BIOS code is skrewed */
-  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x14) & 0x02) {
-   	tempax = 16;
+  if(ModeNo <= 0x13) {
+     xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
+     yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
   } else {
-    	tempax = 8;
+     xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
+     yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
-#endif
-  tempax = 16;
 
-  tempax -= tempbx;
+  if((!SiS_Pr->SiS_IF_DEF_DSTN) && (!SiS_Pr->SiS_IF_DEF_FSTN)) {
 
-  tempbx = tempax;    /* tempbx = 16-DRamBus - DCLK*BytePerPixel/MCLK */
-
-  tempax = ((52 * 16) / tempbx);
-
-  if ((52*16 % tempbx) != 0) {
-    	tempax++;
-  }
-  tempcx = tempax;
-  tempcx += 40;
+     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
+        if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if(yres == 350) yres = 400;
+        }
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
+ 	   if(ModeNo == 0x12) yres = 400;
+        }
+     }
 
-  /* get DRAM latency */
-  tempcl = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 3) & 0x7;     /* SR17[5:3] DRAM Queue depth */
-  tempch = (SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) >> 6) & 0x3;     /* SR17[7:6] DRAM Grant length */
+     if(ModeNo > 0x13) {
+  	if(modeflag & HalfDCLK)       xres *= 2;
+  	if(modeflag & DoubleScanMode) yres *= 2;
+     }
 
-  for (temp3 = 0; temp3 < 16; temp3 += 2) {
-    if ((CombCode[temp3] == tempcl) && (CombCode[temp3+1] == tempch)) {
-      temp3 = CRT2ThLow[temp3 >> 1];
-    }
   }
 
-  tempcx +=  temp3;                                      /* CRT1 Request Period */
-
-  CRT2ModeNo = ModeNo;                                                 /* get CRT2 ModeNo */
-  SiS_SearchModeID(SiS_Pr,ROMAddr,&CRT2ModeNo,&ModeIdIndex);           /* Get ModeID Table */
-
-  SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
-
-  RefreshRateTableIndex = SiS_GetRatePtrCRT2(SiS_Pr,ROMAddr,CRT2ModeNo,
-                                           ModeIdIndex,HwDeviceExtension);
-
-  index = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex,
-                          RefreshRateTableIndex,HwDeviceExtension);
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     tempax = SiS_Pr->SiS_VCLKData[index].CLOCK;                       /* Get VCLK  */
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+           if(xres == 720) xres = 640;
+	} else {
+	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* 301BDH */
+	        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVisionTV)) {
+                   if(xres == 720) xres = 640;
+		}
+		if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+	           yres = 400;
+	           if(HwInfo->jChipType >= SIS_315H) {
+	              if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+	           } else {
+	              if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+	           }
+	        }
+	   } else {
+	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToHiVisionTV)) {
+	         if(xres == 720) xres = 640;
+	      }
+	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		 if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+		    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+		       /* BIOS bug - does this regardless of scaling */
+      		       if(yres == 400) yres = 405;
+		    }
+      		    if(yres == 350) yres = 360;
+      		    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+        	       if(yres == 360) yres = 375;
+      		    }
+   	         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+      		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+        	       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+          	          if(yres == 350) yres = 357;
+          	          if(yres == 400) yres = 420;
+            	          if(yres == 480) yres = 525;
+        	       }
+      		    }
+    	         }
+	      }
+	   }
+	}
   } else {
-     tempax = SiS_Pr->SiS_VBVCLKData[index].CLOCK;                     /* Get VCLK  */
-  }
-
-  tempbx = SiS_GetColorDepth(SiS_Pr,ROMAddr,CRT2ModeNo,ModeIdIndex);   /* Get colordepth */
-  tempbx >>= 1;
-  if(!tempbx) tempbx++;
-
-  tempax *= tempbx;
-
-  tempax *= tempcx;
-
-  tempbx = SiS_GetMCLK(SiS_Pr,ROMAddr, HwDeviceExtension);	       /* Get MCLK */
-  tempbx <<= 4;
-
-  tempcx = tempax;
-  tempax /= tempbx;
-  if(tempcx % tempbx) tempax++;		/* CRT1 Request period * TCLK * BytePerPixel / (MCLK*16) */
-
-  if (tempax > 0x37)  tempax = 0x37;
-
-  /* TW: 650/LVDS (1.10.07, 1.10.00), 650/301LV, 740, 330 overrule calculated value; 315 does not */
-  if(HwDeviceExtension->jChipType >= SIS_650) {
-  	tempax = 0x04;
+    	if(xres == 720) xres = 640;
+	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+	   yres = 400;
+	   if(HwInfo->jChipType >= SIS_315H) {
+	      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
+	   } else {
+	      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
+	   }
+	   if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+	      yres = 480;
+	   }
+	}
   }
-  
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,tempax);
+  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
+  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
 }
 
-USHORT
-SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT index;
+/*********************************************/
+/*           GET CRT2 TIMING DATA            */
+/*********************************************/
+
+static BOOLEAN
+SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+		   USHORT RefreshRateTableIndex, USHORT *ResIndex,
+		   USHORT *DisplayType)
+ {
+  USHORT tempbx,modeflag=0;
+  USHORT Flag,CRT2CRTC;
 
-  index = SiS_Get310DRAMType(SiS_Pr,ROMAddr,HwDeviceExtension);
-  if(index >= 4) {
-    index -= 4;
-    return(SiS_Pr->SiS_MCLKData_1[index].CLOCK);
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
+     }
   } else {
-    return(SiS_Pr->SiS_MCLKData_0[index].CLOCK);
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return FALSE;
   }
-}
-#endif
-
-/* TW: Checked against 650/LVDS 1.10.07 BIOS */
-void
-SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT modeflag;
-  USHORT PanelIndex,ResIndex;
-  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
-  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
 
-#ifdef SIS315H  
-     SiS_GetLVDSDesPtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                        &PanelIndex,&ResIndex);
-			
-     switch (PanelIndex)
-     {
-     	case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
-     	case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
-	case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
-	case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
-     	case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
-     	case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
-	case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
-	case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
-	default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
-     }
-#endif
-
-  } else {
-
-     SiS_GetLVDSDesPtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                       &PanelIndex,&ResIndex,HwDeviceExtension);
-
-     switch (PanelIndex)
-     {
-     	case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break;   /* ---  */
-     	case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
-     	case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
-     	case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
-     	case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
-     	case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
-     	case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
-     	case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
-     	case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
-     	case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
-     	case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
-     	case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
-     	case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;
-     	case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
-     	case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;
-     	case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
-     	case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;    /* --- */
-     	case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
-     	case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
-     	case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
-     	case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
-     	case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
-     	case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
-     	case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
-     	case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
-     	case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
-     	case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
-     	case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
-     	case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;
-     	case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
-     	case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
-     	case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
-	case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;   break;    /* pass 1:1 */
-	case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;   break;
-     	case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break; /* TV */
-     	case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
-     	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
-     	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
-	default:
-		if(HwDeviceExtension->jChipType < SIS_315H)
-		   PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
-		else
-		   PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
-		break;
-     }
-  }
-  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
-  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
-     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-        if(ModeNo <= 0x13) {
-           modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	   if(!(modeflag & HalfDCLK)) {
-	      SiS_Pr->SiS_LCDHDES = 632;
+  Flag = 1;
+  tempbx = 0;
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+        Flag = 0;
+        tempbx = 18;
+        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+      	   tempbx += 2;
+	   if(SiS_Pr->SiS_ModeType > ModeVGA) {
+	      if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+	   }
+	   if(SiS_Pr->SiS_CHPALM) {
+	      tempbx = 18;  /* PALM uses NTSC data */
+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
+	   } else if(SiS_Pr->SiS_CHPALN) {
+	      tempbx = 20;  /* PALN uses PAL data  */
+	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
 	   }
-        }
-     } else {
-        if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-           if( (HwDeviceExtension->jChipType < SIS_315H) || 
-	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {  
-              if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
-                 if(ModeNo <= 0x13) {
-	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	            if(HwDeviceExtension->jChipType < SIS_315H) {
-	               if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
-	            } else {
-	               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-	                  SiS_Pr->SiS_LCDHDES = 480;
-                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
-	                  SiS_Pr->SiS_LCDHDES = 804;
-		       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
-	                  SiS_Pr->SiS_LCDHDES = 704;
-                       if(!(modeflag & HalfDCLK)) {
-                          SiS_Pr->SiS_LCDHDES = 320;
-	                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
-	                     SiS_Pr->SiS_LCDHDES = 632;
-		          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
-	                     SiS_Pr->SiS_LCDHDES = 542;
-                       }
-                    }
-                 }
-              }
-           }
         }
      }
   }
-  return;
-}
-
-void
-SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                  USHORT RefreshRateTableIndex,USHORT *PanelIndex,
-		  USHORT *ResIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempbx,tempal,modeflag;
-
-  if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
+  if(Flag) {
+     tempbx = SiS_Pr->SiS_LCDResInfo;
+     tempbx -= SiS_Pr->SiS_PanelMinLVDS;
+     if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
+        if(modeflag & HalfDCLK) tempbx += 3;
+     } else {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+           tempbx = 14;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+           tempbx = 23;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+           tempbx = 27;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+           tempbx = 36;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+           tempbx = 40;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
+	   if(modeflag & HalfDCLK) tempbx++;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+           tempbx = 54;
+	   if(modeflag & HalfDCLK) tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
+           tempbx = 52;
+	   if(modeflag & HalfDCLK) tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+           tempbx = 50;
+	   if(modeflag & HalfDCLK) tempbx++;
+        }
 
-  tempbx = 0;
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        tempbx = 50;
-        if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
-        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-        /* TW: Nothing special needed for SOverscan    */
-        /*     PALM uses NTSC data, PALN uses PAL data */
      }
-  }
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-     tempbx = SiS_Pr->SiS_LCDTypeInfo;
-     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
      if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        tempbx = 32;
-        if(modeflag & HalfDCLK) tempbx++;
+        tempbx = 12;
+	if(modeflag & HalfDCLK) tempbx++;
      }
   }
-  /* TW: 630/LVDS and 650/LVDS (1.10.07) BIOS */
-  if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
-        tempal = 0x07;
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-           if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
-        }
+
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+        tempbx = 22;
      }
   }
+#endif
 
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
-}
-
-#ifdef SIS315H
-void
-SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex)
-{
-  USHORT tempbx=0,tempal;
-
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      tempbx = 2;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
-  else tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
-
-  if(ModeNo <= 0x13)
-     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
-  *PanelIndex = tempbx;
-  *ResIndex = tempal & 0x1F;
+  *ResIndex = CRT2CRTC & 0x3F;
+  *DisplayType = tempbx;
+  return TRUE;
 }
-#endif
 
-void
-SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr, USHORT ModeNo, USHORT ModeIdIndex,
-                    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_GetCRT2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
+	       PSIS_HW_INFO HwInfo)
 {
-  USHORT i,j,modeflag;
-  USHORT tempcl,tempah=0;
-#ifdef SIS300
-  USHORT temp;
-#endif
-#ifdef SIS315H
-  USHORT tempbl;
-#endif
+  USHORT tempbx=0,tempal=0;
+  USHORT Flag,resinfo=0;
 
   if(ModeNo <= 0x13) {
-     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-     if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-     } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-     }
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
-  
-  /* TW: BIOS does not do this (neither 301 nor LVDS) */
-  /*     (But it's harmless; see SetCRT2Offset) */
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x03,0x00);   /* fix write part1 index 0  BTDRAM bit Bug */
 
-  /* TW: Removed 301B302B301LV302LV check here to match 650/LVDS BIOS */
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-	/* TW:   1. for LVDS/302B/302LV **LCDA** */
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
 
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xAF,0x40); /* FUNCTION CONTROL */
-      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2E,0xF7);
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+	   tempbx = 15;
+  	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   tempbx = 20;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 21;
+	   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
+ 	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+	   tempbx = 23;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
+	   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
+#if 0
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	   tempbx = 26;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 27;
+	   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 28;
+#endif
+ 	} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx = 13;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 14;
+	      else 							    tempbx = 29;
+	   } else {
+	      tempbx = 29;
+	      if(ModeNo >= 0x13) {
+	         /* 1280x768 and 1280x960 have same CRT2CRTC,
+	          * so we change it here if 1280x960 is chosen
+	          */
+	         if(resinfo == SIS_RI_1280x960) tempal = 10;
+	      }
+   	   }
+	} else {
+      	   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
+      	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+              tempbx += 10;
+       	   }
+	}
 
-  } else {
+#ifdef SIS315H
+	if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+	   tempbx = 50;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 51;
+	   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 52;
+	}
+#endif
 
-    for(i=0,j=4; i<3; i++,j++) SiS_SetReg1(SiS_Pr->SiS_Part1Port,j,0);
+     } else {						  	/* TV */
 
-    tempcl = SiS_Pr->SiS_ModeType;
+     	if((SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+	   (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+           if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode);
+           tempbx = 2;
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+              if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12;
+           }
+       	} else {
+           if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
+           else tempbx = 4;
+           if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5;
+       	}
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+     }
 
-#ifdef SIS300    /* ---- 300 series ---- */
+     tempal &= 0x3F;
 
-      /* For 301BDH: */
-      if(SiS_Pr->SiS_VBType & VB_NoLCD) {
-	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32);
-	  temp &= 0xef;
-	  temp |= 0x02;
-	  if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) || (SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-	     temp |= 0x10;
-	     temp &= 0xfd;
-	  }
-	  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
-      }
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
+	if(ModeNo > 0x13) {
+      	   if(tempal == 6) tempal = 7;
+           if((resinfo == SIS_RI_720x480) ||
+	      (resinfo == SIS_RI_720x576) ||
+	      (resinfo == SIS_RI_768x576)) {
+	      tempal = 6;
+	   }
+	}
+     }
 
-      if(ModeNo > 0x13) {
-        tempcl -= ModeVGA;
-        if((tempcl > 0) || (tempcl == 0)) {      /* TW: tempcl is USHORT -> always true! */
-           tempah = ((0x10 >> tempcl) | 0x80);
-        }
-      } else tempah = 0x80;
+     *CRT2Index = tempbx;
+     *ResIndex = tempal;
 
-      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0xA0;
+  } else {   /* LVDS, 301B-DH (if running on LCD) */
 
-#endif  /* SIS300 */
+     Flag = 1;
+     tempbx = 0;
+     if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+           Flag = 0;
+           tempbx = 10;
+	   if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+           if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	      tempbx += 2;
+	      if(SiS_Pr->SiS_ModeType > ModeVGA) {
+		 if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
+	      }
+	      if(SiS_Pr->SiS_CHPALM) {
+		 tempbx = 90;
+		 if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+	      } else if(SiS_Pr->SiS_CHPALN) {
+		 tempbx = 92;
+		 if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+	      }
+           }
+        }
+     }
 
-    } else {
+     if(Flag) {
 
-#ifdef SIS315H    /* ---- 310/325/330 series ---- */
+	if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
+	   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
+   	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
+
+	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+	      tempbx = 82;
+	      if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	   }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
+	   tempbx = 18;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+	   tempbx = 6;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2) {
+	   tempbx = 30;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+	   tempbx = 30;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+	   tempbx = 15;
+  	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
+	   tempbx = 16;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+	   tempbx = 8;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+	   tempbx = 21;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelBarco1366) {
+	   tempbx = 80;
+   	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	}
+
+	if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+	   tempbx = 7;
+        }
+
+	if(SiS_Pr->SiS_CustomT == CUT_PANEL848) {
+	   tempbx = 84;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
+	}
 
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag) {
-	    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x08);
-         }
-      }
+     }
 
-      if(ModeNo > 0x13) {
-        tempcl -= ModeVGA;
-        if((tempcl > 0) || (tempcl == 0)) {  /* TW: tempcl is USHORT -> always true! */
-           tempah = (0x08 >> tempcl);
-           if (tempah == 0) tempah = 1;
-           tempah |= 0x40;
+#if 0
+     if(SiS_Pr->SiS_IF_DEF_FSTN){
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
+           tempbx = 14;
+           tempal = 6;
         }
-      } else tempah = 0x40;
+     }
+#endif
 
-      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  tempah ^= 0x50;
+     if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
+  	   if(HwInfo->jChipType < SIS_315H) {
+	      if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+	   }
+     }
 
-#endif  /* SIS315H */
-
-    }
-
-    if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
-
-    if(HwDeviceExtension->jChipType < SIS_315H) {
-       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
-    } else {
-       if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
-       } else {
-          if(IS_SIS740) {
-	     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,tempah);  		/* FUNCTION CONTROL */
-	  } else {
-             SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x00,0xa0,tempah);  	/* FUNCTION CONTROL */
-	  }
-       }
-    }
-
-    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-
-	/* TW:   2. for 301 (301B, 302B 301LV, 302LV non-LCDA) */
-
-    	tempah = 0x01;
-    	if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-      		tempah |= 0x02;
-    	}
-    	if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-      		tempah ^= 0x05;
-      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        		tempah ^= 0x01;
-      		}
-    	}
-
-	if(SiS_Pr->SiS_VBInfo & CRT2DisplayFlag)  tempah = 0;
-
-    	if(HwDeviceExtension->jChipType < SIS_315H) {
-
-		/* --- 300 series --- */
-
-      		tempah = (tempah << 5) & 0xFF;
-      		SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
-      		tempah = (tempah >> 5) & 0xFF;
-
-    	} else {
-
-		/* --- 310 series --- */
-
-      		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2E,0xF8,tempah);
-
-    	}
-
-    	if((SiS_Pr->SiS_ModeType == ModeVGA) && (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode))) {
-      		tempah |= 0x10;
-	}
-
-	/* TW: 630/301 BIOS */
-	if((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301)) {
-		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-			tempah |= 0x80;
-		}
-	} else {
-		tempah |= 0x80;
-	}
-
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
-      		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-			if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-          			tempah |= 0x20;
-			}
-      		}
-    	}
-
-    	SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x0D,0x40,tempah);
-
-    	tempah = 0;
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-      	      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-	         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-       		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-            	       SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
-            	       tempah |= 0x40;
-       		    } else {
-        	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) {
-          		  SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
-            		  tempah |= 0x40;
-        	       }
-      		    }
-		 }
-     	      } else {
-        	SiS_Pr->SiS_SetFlag |= RPLLDIV2XO;
-        	tempah |= 0x40;
-      	      }
-	   }
-    	}
-	/* TW: For 302LV dual-channel */
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04)
-		    tempah |= 0x40;
-	    }
-	}
-
-	if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-	   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)) {
-		tempah |= 0x80;
-	}
-
-    	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0C,tempah);
-
-    } else {
-
-    	/* TW: 3. for LVDS */
-
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-
-	   /* TW: Inserted this entire section (BIOS 650/LVDS); added ModeType check
-	    *     (LVDS can only be slave in 8bpp modes)
-	    */
-	   tempah = 0x80;
-	   if( (modeflag & CRT2Mode) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
-	       if (SiS_Pr->SiS_VBInfo & DriverMode) {
-	           tempah |= 0x02;
-	       }
-	   }
-
-	   if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-               tempah |= 0x02;
-    	   }
-
-	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	       tempah ^= 0x01;
-	   }
-
-	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-	       tempah = 1;
-	   }
-
-    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2e,0xF0,tempah);
-
-	} else {
-
-	   /* TW: (added ModeType check) */
-	   tempah = 0;
-	   if( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) && (SiS_Pr->SiS_ModeType > ModeVGA) ) {
-               	  tempah |= 0x02;
-    	   }
-	   tempah <<= 5;
-
-	   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)  tempah = 0;
-
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x01,tempah);
-
-	}
-
-    }
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+        if(ModeNo > 0x13) {
+           if((resinfo == SIS_RI_720x480) ||
+              (resinfo == SIS_RI_720x576) ||
+   	      (resinfo == SIS_RI_768x576))
+	      tempal = 6;
+        }
+     }
 
+     *CRT2Index = tempbx;
+     *ResIndex = tempal & 0x1F;
   }
-
-  /* TW: Inserted the entire following section */
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
+}
 
 #ifdef SIS315H
-         if(!(IS_SIS740)) {
-            tempah = 0x04;						   /* For all bridges */
-            tempbl = 0xfb;
-            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-               tempah = 0x00;
-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
-	          tempbl = 0xff;
-            }
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);   
-	 }
-	 
-	 if(IS_SIS740) {						
-	    tempah = 0x30;
-	    tempbl = 0xcf;
-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-	       tempah = 0x00;
-	    }
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
-	 } else {
-	    /* TW: This in order to fix "TV-blue-bug" on 315+301 */
-            if(SiS_Pr->SiS_VBType & VB_SIS301) {
-	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2c,0xCF);             /* For 301   */
-	    } else {
-	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xCF,0x30);   /* For 30xLV */
-	       } else {
-	          tempah = 0x30;					   /* For 301B  */
-	          tempbl = 0xcf;
-	          if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-	             tempah = 0x00;
-		     if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-		        tempbl = 0xff;
-		     }
-	          }
-	          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,tempbl,tempah);    
-	       }
-	    }
-	 }
-
-	 if(IS_SIS740) {
-	    tempah = 0xc0;
-  	    tempbl = 0x3f;
-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-	       tempah = 0x00;
-	    } 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
-	 } else {
-	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* For 30xLV */
-	       SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0x3f,0xc0);
-	    } else {							/* For 301, 301B */ 
-	        tempah = 0xc0;
-	        tempbl = 0x3f;
-	        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-	           tempah = 0x00;
-		   if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)) {
-		      tempbl = 0xff;
-		   }
-	        }
-	        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,tempbl,tempah);     
-	    }
-	 }
-
-	 if(IS_SIS740) {						
-	    tempah = 0x80;
-	    tempbl = 0x7f;
-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
-	       tempah = 0x00;
-	    } 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
-	 } else {
-	    tempah = 0x00;						/* For all bridges */	
-            tempbl = 0x7f;
-            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-               tempbl = 0xff;
-	       if(!(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr)))
-	          tempah |= 0x80;
-            }
-            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x23,tempbl,tempah);
-	 }
-
-#endif /* SIS315H */
+static void
+SiS_GetCRT2PtrA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		USHORT *ResIndex)
+{
+  USHORT tempbx,tempal;
 
-      } else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+  tempbx = SiS_Pr->SiS_LCDResInfo;
 
-         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x21,0x3f);
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)      tempbx = 4;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
+  else tempbx -= SiS_Pr->SiS_Panel1024x768;
 
-         if((SiS_Pr->SiS_VBInfo & DisableCRT2Display) ||
-            (   (SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	        (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) ) {
-	    SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7F);
-	 } else {
-	    SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
-	 }
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
 
-      }
+  if(ModeNo <= 0x13)
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-  } else {  /* LVDS */
+  *CRT2Index = tempbx;
+  *ResIndex = tempal & 0x1F;
+}
+#endif
 
-#ifdef SIS315H
-      if(HwDeviceExtension->jChipType >= SIS_315H) {
+static void
+SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo)
+{
+  USHORT tempax=0,tempbx=0;
+  USHORT temp1=0,modeflag=0,tempcx=0;
+  USHORT index;
 
-         if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+  SiS_Pr->SiS_RVBHCMAX  = 1;
+  SiS_Pr->SiS_RVBHCFACT = 1;
 
-            tempah = 0x04;
-	    tempbl = 0xfb;
-            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-               tempah = 0x00;
-	       if(SiS_IsDualEdge(SiS_Pr, HwDeviceExtension, BaseAddr))
-	          tempbl = 0xff;
-            }
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,tempbl,tempah);
+  if(ModeNo <= 0x13) {
 
-	    if(SiS_Pr->SiS_VBInfo & DisableCRT2Display)
-	       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x00);
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     index = SiS_GetModePtr(SiS_Pr,ModeNo,ModeIdIndex);
 
-	    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2c,0xcf,0x30);
+     tempax = SiS_Pr->SiS_StandTable[index].CRTC[0];
+     tempbx = SiS_Pr->SiS_StandTable[index].CRTC[6];
+     temp1 = SiS_Pr->SiS_StandTable[index].CRTC[7];
 
-	 }
+  } else {
 
-      }
-#endif
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+
+     tempax = SiS_Pr->SiS_CRT1Table[index].CR[0];
+     tempax |= (SiS_Pr->SiS_CRT1Table[index].CR[14] << 8);
+     tempax &= 0x03FF;
+     tempbx = SiS_Pr->SiS_CRT1Table[index].CR[6];
+     tempcx = SiS_Pr->SiS_CRT1Table[index].CR[13] << 8;
+     tempcx &= 0x0100;
+     tempcx <<= 2;
+     tempbx |= tempcx;
+     temp1  = SiS_Pr->SiS_CRT1Table[index].CR[7];
 
   }
 
-}
-
-void
-SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,
-		PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-
-           SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                      HwDeviceExtension);
-        } else {
+  if(temp1 & 0x01) tempbx |= 0x0100;
+  if(temp1 & 0x20) tempbx |= 0x0200;
+
+  tempax += 5;
 
-	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-	       (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-	       
-	      /* TW: Need LVDS Data for LCD on 301BDH */
-	      SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                          HwDeviceExtension);
-				  
-	   } else {
-	
-	      SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                         HwDeviceExtension);
-           }
+  /* Charx8Dot is no more used (and assumed), so we set it */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     modeflag |= Charx8Dot;
+  }
 
-        }
+  if(modeflag & Charx8Dot) tempax *= 8;
+  else                     tempax *= 9;
 
-     } else {
+  if(modeflag & HalfDCLK)  tempax <<= 1;
 
-     	SiS_GetCRT2Data301(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-	                   HwDeviceExtension);
-     }
+  tempbx++;
 
-  } else {
-  
-     SiS_GetCRT2DataLVDS(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                         HwDeviceExtension);
-  }
+  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
+  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
 }
 
-/* Checked with 650/LVDS 1.10.07 BIOS */
-void
-SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+static void
+SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                     USHORT RefreshRateTableIndex,
-		    PSIS_HW_DEVICE_INFO HwDeviceExtension)
+		    PSIS_HW_INFO HwInfo)
 {
    USHORT CRT2Index, ResIndex;
    const SiS_LVDSDataStruct *LVDSData = NULL;
 
-   SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-   
+   SiS_GetCRT2ResInfo(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+
    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       SiS_Pr->SiS_RVBHCMAX  = 1;
       SiS_Pr->SiS_RVBHCFACT = 1;
@@ -3261,40 +2960,36 @@
 
    if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
-#ifdef SIS315H   
-      SiS_GetCRT2PtrA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+#ifdef SIS315H
+      SiS_GetCRT2PtrA(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
                       &CRT2Index,&ResIndex);
 
       switch (CRT2Index) {
-      	case  0:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;    break;
-      	case  1:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_1;   break;
-        case  2:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_1;    break;
+      	case  0:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_1;    break;
+      	case  1:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_1;   break;
 	case  3:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_1;   break;
 	case  4:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_1;   break;
-      	case  5:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_2;    break;
-      	case  6:  LVDSData = SiS_Pr->SiS_LVDS1280x1024Data_2;   break;
-      	case  7:  LVDSData = SiS_Pr->SiS_LVDS1280x960Data_2;    break;
+      	case  5:  LVDSData = SiS_Pr->SiS_LCDA1024x768Data_2;    break;
+      	case  6:  LVDSData = SiS_Pr->SiS_LCDA1280x1024Data_2;   break;
 	case  8:  LVDSData = SiS_Pr->SiS_LCDA1400x1050Data_2;   break;
 	case  9:  LVDSData = SiS_Pr->SiS_LCDA1600x1200Data_2;   break;
 	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;    break;
       }
-#endif      
+#endif
 
    } else {
 
-      /* TW: 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
+      /* 301BDH needs LVDS Data */
+      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
 	      SiS_Pr->SiS_IF_DEF_LVDS = 1;
       }
 
-      SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                     &CRT2Index,&ResIndex,HwDeviceExtension);
+      SiS_GetCRT2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                     &CRT2Index, &ResIndex, HwInfo);
 
-      /* TW: 301BDH needs LVDS Data */
-      if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
-          (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
-              SiS_Pr->SiS_IF_DEF_LVDS = 0;
+      /* 301BDH needs LVDS Data */
+      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) {
+         SiS_Pr->SiS_IF_DEF_LVDS = 0;
       }
 
       switch (CRT2Index) {
@@ -3321,11 +3016,18 @@
 	case 20:  LVDSData = SiS_Pr->SiS_LVDS1280x768Data_2;   break;
 	case 21:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_1;  break;
 	case 22:  LVDSData = SiS_Pr->SiS_LVDS1600x1200Data_2;  break;
+	case 30:  LVDSData = SiS_Pr->SiS_LVDS640x480Data_2;    break;
+	case 80:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_1;  break;
+	case 81:  LVDSData = SiS_Pr->SiS_LVDSBARCO1366Data_2;  break;
+	case 82:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_1;  break;
+	case 83:  LVDSData = SiS_Pr->SiS_LVDSBARCO1024Data_2;  break;
+	case 84:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_1;    break;
+	case 85:  LVDSData = SiS_Pr->SiS_LVDS848x480Data_2;    break;
 	case 90:  LVDSData = SiS_Pr->SiS_CHTVUPALMData;        break;
       	case 91:  LVDSData = SiS_Pr->SiS_CHTVOPALMData;        break;
       	case 92:  LVDSData = SiS_Pr->SiS_CHTVUPALNData;        break;
       	case 93:  LVDSData = SiS_Pr->SiS_CHTVOPALNData;        break;
-	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* TW: Super Overscan */
+	case 99:  LVDSData = SiS_Pr->SiS_CHTVSOPALData;	       break;  /* Super Overscan */
 	default:  LVDSData = SiS_Pr->SiS_LVDS1024x768Data_1;   break;
      }
    }
@@ -3337,74 +3039,43 @@
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-    if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)){
-         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
-           SiS_Pr->SiS_HDE = 1024;
-           SiS_Pr->SiS_VDE =  768;
-         } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024){
-           SiS_Pr->SiS_HDE = 1280;
-           SiS_Pr->SiS_VDE = 1024;
-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050){
-           SiS_Pr->SiS_HDE = 1400;
-           SiS_Pr->SiS_VDE = 1050;
-	 } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200){
-           SiS_Pr->SiS_HDE = 1600;
-           SiS_Pr->SiS_VDE = 1200;
-         } else {
-	   SiS_Pr->SiS_HDE = 1280;
-	   SiS_Pr->SiS_VDE =  960;
-	 }
-    }
+     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
+        SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+        SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+     }
 
   } else {
 
-    if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-      if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
-        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
-          if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-              SiS_Pr->SiS_HDE =  800;
-              SiS_Pr->SiS_VDE =  600;
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-	      SiS_Pr->SiS_HDE = 1024;
-              SiS_Pr->SiS_VDE =  600;  
-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-              SiS_Pr->SiS_HDE = 1024;
-              SiS_Pr->SiS_VDE =  768;
- 	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-	      SiS_Pr->SiS_HDE = 1152;
-	      SiS_Pr->SiS_VDE =  768;	
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x864) {
-	      SiS_Pr->SiS_HDE = 1152;
-	      SiS_Pr->SiS_VDE =  864;  
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-	      SiS_Pr->SiS_HDE = 1280;
-	      SiS_Pr->SiS_VDE =  768;        
-            } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-              SiS_Pr->SiS_HDE = 1280;
-              SiS_Pr->SiS_VDE = 1024;
-	    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	      SiS_Pr->SiS_HDE = 1400;
-              SiS_Pr->SiS_VDE = 1050;
-	    } else {
-	      SiS_Pr->SiS_HDE = 1600;
-	      SiS_Pr->SiS_VDE = 1200;
-	    }
-            if(SiS_Pr->SiS_IF_DEF_FSTN) {
-              SiS_Pr->SiS_HDE = 320;
-              SiS_Pr->SiS_VDE = 480;
-            }
-          }
+     if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+        if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (!(SiS_Pr->SiS_LCDInfo & LCDPass11))) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+              if((!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) || (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+	         SiS_Pr->SiS_HDE = SiS_Pr->PanelXRes;
+                 SiS_Pr->SiS_VDE = SiS_Pr->PanelYRes;
+
+		 if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+		    if(ResIndex < 0x08) {
+		       SiS_Pr->SiS_HDE = 1280;
+                       SiS_Pr->SiS_VDE = 1024;
+		    }
+		 }
+#if 0
+                 if(SiS_Pr->SiS_IF_DEF_FSTN) {
+                    SiS_Pr->SiS_HDE = 320;
+                    SiS_Pr->SiS_VDE = 480;
+                 }
+#endif
+              }
+           }
         }
-      }
-    }
+     }
   }
 }
 
-void
-SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+static void
+SiS_GetCRT2Data301(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
                    USHORT RefreshRateTableIndex,
-		   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+		   PSIS_HW_INFO HwInfo)
 {
   USHORT tempax,tempbx,modeflag;
   USHORT resinfo;
@@ -3413,11 +3084,16 @@
   const SiS_TVDataStruct  *TVPtr  = NULL;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
   
   SiS_Pr->SiS_NewFlickerMode = 0;
@@ -3427,32 +3103,40 @@
   SiS_Pr->SiS_RY3COE = 0;
   SiS_Pr->SiS_RY4COE = 0;
 
-  SiS_GetCRT2ResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,HwDeviceExtension);
-
-  /* TW: For VGA2 ("RAMDAC2") */
+  SiS_GetCRT2ResInfo(SiS_Pr,ModeNo,ModeIdIndex,HwInfo);
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC){
-     SiS_GetRAMDAC2DATA(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                        HwDeviceExtension);
-     return;
-  }
 
-  /* TW: For TV */
+     if(SiS_Pr->UseCustomMode) {
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        SiS_Pr->SiS_RVBHCMAX  = 1;
+        SiS_Pr->SiS_RVBHCFACT = 1;
+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
+
+     } else {
 
-    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   &CRT2Index,&ResIndex,HwDeviceExtension);
+        SiS_GetRAMDAC2DATA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+     }
+
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+
+    SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                   &CRT2Index,&ResIndex,HwInfo);
 
     switch (CRT2Index) {
-      case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
-/*    case  7:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;  */
-      case 12:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
-      case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
-      case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
-      case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
-      case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
-      default:  TVPtr = SiS_Pr->SiS_StPALData;     break;  /* TW: Just to avoid a crash */
+       case  2:  TVPtr = SiS_Pr->SiS_ExtHiTVData;   break;
+/*     case  7:  TVPtr = SiS_Pr->SiS_St1HiTVData;   break;  */
+       case 12:  TVPtr = SiS_Pr->SiS_St2HiTVData;   break;
+       case  3:  TVPtr = SiS_Pr->SiS_ExtPALData;    break;
+       case  4:  TVPtr = SiS_Pr->SiS_ExtNTSCData;   break;
+       case  8:  TVPtr = SiS_Pr->SiS_StPALData;     break;
+       case  9:  TVPtr = SiS_Pr->SiS_StNTSCData;    break;
+       default:  TVPtr = SiS_Pr->SiS_StPALData;     break;
     }
 
     SiS_Pr->SiS_RVBHCMAX  = (TVPtr+ResIndex)->RVBHCMAX;
@@ -3464,18 +3148,16 @@
     SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->RVBHRS;
     SiS_Pr->SiS_NewFlickerMode = (TVPtr+ResIndex)->FlickerMode;
     if(modeflag & HalfDCLK) {
-	SiS_Pr->SiS_RVBHRS    = (TVPtr+ResIndex)->HALFRVBHRS;
+       SiS_Pr->SiS_RVBHRS = (TVPtr+ResIndex)->HALFRVBHRS;
     }
 
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {  
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
     
        if(SiS_Pr->SiS_HiVision != 3) {
-       
-      	  if(resinfo == 0x08) SiS_Pr->SiS_NewFlickerMode = 0x40;
-      	  if(resinfo == 0x09) SiS_Pr->SiS_NewFlickerMode = 0x40;
-	  if(resinfo == 0x12) SiS_Pr->SiS_NewFlickerMode = 0x40;
-	  
-       } 
+      	  if(resinfo == SIS_RI_1024x768)  SiS_Pr->SiS_NewFlickerMode = 0x40;
+      	  if(resinfo == SIS_RI_1280x1024) SiS_Pr->SiS_NewFlickerMode = 0x40;
+	  if(resinfo == SIS_RI_1280x720)  SiS_Pr->SiS_NewFlickerMode = 0x40;
+       }
        
        switch(SiS_Pr->SiS_HiVision) {
        case 2:
@@ -3504,1672 +3186,729 @@
 
     } else {
 
-      SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
-      SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
-      SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
-      SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
-
-      if(modeflag & HalfDCLK) {
-         SiS_Pr->SiS_RY1COE = 0x00;
-         SiS_Pr->SiS_RY2COE = 0xf4;
-         SiS_Pr->SiS_RY3COE = 0x10;
-         SiS_Pr->SiS_RY4COE = 0x38;
-      }
-
-      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-        SiS_Pr->SiS_HT = NTSCHT;
-	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
-	   if((ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
-	}  
-        SiS_Pr->SiS_VT = NTSCVT;
-      } else {
-        SiS_Pr->SiS_HT = PALHT;
-        SiS_Pr->SiS_VT = PALVT;
-      }
+       SiS_Pr->SiS_RY1COE = (TVPtr+ResIndex)->RY1COE;
+       SiS_Pr->SiS_RY2COE = (TVPtr+ResIndex)->RY2COE;
+       SiS_Pr->SiS_RY3COE = (TVPtr+ResIndex)->RY3COE;
+       SiS_Pr->SiS_RY4COE = (TVPtr+ResIndex)->RY4COE;
+
+       if(modeflag & HalfDCLK) {
+          SiS_Pr->SiS_RY1COE = 0x00;
+          SiS_Pr->SiS_RY2COE = 0xf4;
+          SiS_Pr->SiS_RY3COE = 0x10;
+          SiS_Pr->SiS_RY4COE = 0x38;
+       }
+
+       if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+          SiS_Pr->SiS_HT = NTSCHT;
+	  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	     if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) SiS_Pr->SiS_HT = NTSC2HT;
+	  }
+          SiS_Pr->SiS_VT = NTSCVT;
+       } else {
+          SiS_Pr->SiS_HT = PALHT;
+          SiS_Pr->SiS_VT = PALVT;
+       }
 
     }
 
-    return;
-  }
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
 
-  /* TW: For LCD */
+     if(SiS_Pr->UseCustomMode) {
 
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        SiS_Pr->SiS_RVBHCMAX  = 1;
+        SiS_Pr->SiS_RVBHCFACT = 1;
+        SiS_Pr->SiS_VGAHT     = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VGAVT     = SiS_Pr->CVTotal;
+        SiS_Pr->SiS_HT        = SiS_Pr->CHTotal;
+        SiS_Pr->SiS_VT        = SiS_Pr->CVTotal;
+	SiS_Pr->SiS_HDE       = SiS_Pr->SiS_VGAHDE;
+        SiS_Pr->SiS_VDE       = SiS_Pr->SiS_VGAVDE;
 
-    SiS_GetCRT2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                   &CRT2Index,&ResIndex,HwDeviceExtension);
+     } else {
 
-    switch (CRT2Index) {
-      case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
-      case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
-      case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
-      case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
-      case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
-      case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
-      case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
-      case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
-      case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
-      case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
-      case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
-      case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;	       break; /* Non-VESA Timing (let panel scale) */
-      case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
-      case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
-      case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;	       break; /* Non-VESA Timing */
-      default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	       break; /* Just to avoid a crash */
-    }
+        SiS_GetCRT2Ptr(SiS_Pr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
+                      &CRT2Index,&ResIndex,HwInfo);
+
+        switch(CRT2Index) {
+         case  0: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;        break; /* VESA Timing */
+         case  1: LCDPtr = SiS_Pr->SiS_ExtLCD1280x1024Data;       break; /* VESA Timing */
+         case  5: LCDPtr = SiS_Pr->SiS_StLCD1024x768Data;         break; /* Obviously unused */
+         case  6: LCDPtr = SiS_Pr->SiS_StLCD1280x1024Data;        break; /* Obviously unused */
+         case 10: LCDPtr = SiS_Pr->SiS_St2LCD1024x768Data;        break; /* Non-VESA Timing */
+         case 11: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;       break; /* Non-VESA Timing */
+         case 13: LCDPtr = SiS_Pr->SiS_NoScaleData1024x768;       break; /* Non-expanding */
+         case 14: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;      break; /* Non-expanding */
+         case 15: LCDPtr = SiS_Pr->SiS_LCD1280x960Data;           break; /* 1280x960 */
+         case 20: LCDPtr = SiS_Pr->SiS_ExtLCD1400x1050Data;       break; /* VESA Timing */
+         case 21: LCDPtr = SiS_Pr->SiS_NoScaleData1400x1050;      break; /* Non-expanding (let panel scale) */
+         case 22: LCDPtr = SiS_Pr->SiS_StLCD1400x1050Data;        break; /* Non-VESA Timing (let panel scale) */
+         case 23: LCDPtr = SiS_Pr->SiS_ExtLCD1600x1200Data;       break; /* VESA Timing */
+         case 24: LCDPtr = SiS_Pr->SiS_NoScaleData1600x1200;      break; /* Non-expanding */
+         case 25: LCDPtr = SiS_Pr->SiS_StLCD1600x1200Data;        break; /* Non-VESA Timing */
+         case 26: LCDPtr = SiS_Pr->SiS_ExtLCD1280x768Data;        break; /* VESA Timing */
+         case 27: LCDPtr = SiS_Pr->SiS_NoScaleData1280x768;       break; /* Non-expanding */
+         case 28: LCDPtr = SiS_Pr->SiS_StLCD1280x768Data;         break; /* Non-VESA Timing */
+         case 29: LCDPtr = SiS_Pr->SiS_NoScaleData;	          break; /* Generic no-scale data */
+#ifdef SIS315H
+	 case 50: LCDPtr = (SiS_LCDDataStruct *)SiS310_ExtCompaq1280x1024Data;	break;
+	 case 51: LCDPtr = SiS_Pr->SiS_NoScaleData1280x1024;			break;
+	 case 52: LCDPtr = SiS_Pr->SiS_St2LCD1280x1024Data;	  		break;
+#endif
+         default: LCDPtr = SiS_Pr->SiS_ExtLCD1024x768Data;	  break;
+        }
+
+        SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
+        SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
+        SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
+        SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
+        SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
+        SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
 
-    SiS_Pr->SiS_RVBHCMAX  = (LCDPtr+ResIndex)->RVBHCMAX;
-    SiS_Pr->SiS_RVBHCFACT = (LCDPtr+ResIndex)->RVBHCFACT;
-    SiS_Pr->SiS_VGAHT     = (LCDPtr+ResIndex)->VGAHT;
-    SiS_Pr->SiS_VGAVT     = (LCDPtr+ResIndex)->VGAVT;
-    SiS_Pr->SiS_HT        = (LCDPtr+ResIndex)->LCDHT;
-    SiS_Pr->SiS_VT        = (LCDPtr+ResIndex)->LCDVT;
-    
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO,
-    	"GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
-#endif    
-
-    tempax = 1024;
-    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-      if(HwDeviceExtension->jChipType < SIS_315H) {
-         if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-         else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-         else                               tempbx = 768;
-      } else {      
-         tempbx = 768; 
-      }
-    } else {
-      if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
-      else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
-      else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
-      else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
-      else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
-      else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
-      else                               tempbx = 768;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-      tempax = 1280;
-      if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
-      else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
-      else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
-      else                               tempbx = 1024;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-      tempax = 1280;
-      if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
-      else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
-      else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
-      else                                tempbx = 960;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-      tempax = 1400;
-      tempbx = 1050;
-    }
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-      tempax = 1600;
-      tempbx = 1200;
-    }
-    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-       tempax = SiS_Pr->SiS_VGAHDE;
-       tempbx = SiS_Pr->SiS_VGAVDE;
-    }
-    SiS_Pr->SiS_HDE = tempax;
-    SiS_Pr->SiS_VDE = tempbx;
-    return;
+        xf86DrvMsg(0, X_INFO,
+    	    "GetCRT2Data: Index %d ResIndex %d\n", CRT2Index, ResIndex);
+#endif
+
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+           tempax = 1024;
+           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+              if(HwInfo->jChipType < SIS_315H) {
+                 if     (SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+                 else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+                 else                               tempbx = 768;
+              } else {
+                 tempbx = 768;
+              }
+           } else {
+              if     (SiS_Pr->SiS_VGAVDE == 357) tempbx = 527;
+              else if(SiS_Pr->SiS_VGAVDE == 420) tempbx = 620;
+              else if(SiS_Pr->SiS_VGAVDE == 525) tempbx = 775;
+              else if(SiS_Pr->SiS_VGAVDE == 600) tempbx = 775;
+              else if(SiS_Pr->SiS_VGAVDE == 350) tempbx = 560;
+              else if(SiS_Pr->SiS_VGAVDE == 400) tempbx = 640;
+              else                               tempbx = 768;
+           }
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+           tempax = 1280;
+           if     (SiS_Pr->SiS_VGAVDE == 360) tempbx = 768;
+           else if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 800;
+           else if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 864;
+           else                               tempbx = 1024;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
+           tempax = 1280;
+           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 700;
+           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 800;
+           else if(SiS_Pr->SiS_VGAVDE == 1024) tempbx = 960;
+           else                                tempbx = 960;
+        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+           tempax = 1600;
+           if     (SiS_Pr->SiS_VGAVDE == 350)  tempbx = 875;
+           else if(SiS_Pr->SiS_VGAVDE == 400)  tempbx = 1000;
+           else                                tempbx = 1200;
+        } else {
+	   tempax = SiS_Pr->PanelXRes;
+           tempbx = SiS_Pr->PanelYRes;
+	}
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+           tempax = SiS_Pr->SiS_VGAHDE;
+           tempbx = SiS_Pr->SiS_VGAVDE;
+        }
+        SiS_Pr->SiS_HDE = tempax;
+        SiS_Pr->SiS_VDE = tempbx;
+     }
   }
 }
 
-USHORT
-SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+static void
+SiS_GetCRT2Data(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT resindex;
 
-  if(ModeNo <= 0x13)
-    	resindex=SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-  else
-    	resindex=SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-  return(resindex);
-}
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-void
-SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT xres,yres,modeflag=0,resindex;
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 
-  resindex = SiS_GetResInfo(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
+           SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-  if(ModeNo <= 0x13) {
-    	xres = SiS_Pr->SiS_StResInfo[resindex].HTotal;
-    	yres = SiS_Pr->SiS_StResInfo[resindex].VTotal;
-  } else {
-	xres = SiS_Pr->SiS_ModeResInfo[resindex].HTotal;
-    	yres = SiS_Pr->SiS_ModeResInfo[resindex].VTotal;
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-  }
+        } else {
 
-  if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_IF_DEF_LVDS == 1)) {
-      if((ModeNo != 0x03) && (SiS_Pr->SiS_SetFlag & SetDOSMode)) {
-          if(yres == 350) yres = 400;
-      }
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x3a) & 0x01) {
- 	  if(ModeNo == 0x12) yres = 400;
-      }
-  }
+	   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD) ) {
 
-  if(ModeNo > 0x13) {
-      if(SiS_Pr->SiS_IF_DEF_FSTN == 1){
-            xres *= 2;
-            yres *= 2;
-      } else {
-  	    if(modeflag & HalfDCLK)       xres *= 2;
-  	    if(modeflag & DoubleScanMode) yres *= 2;
-      }
-  }
+	      /* Need LVDS Data for LCD on 301B-DH */
+	      SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-           if(xres == 720) xres = 640;
-	} else {
-	   if(SiS_Pr->SiS_VBType & VB_NoLCD) {           /* TW: 301BDH */
-	        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-                   if(xres == 720) xres = 640;
-		}
-		if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-	           yres = 400;
-	           if(HwDeviceExtension->jChipType >= SIS_315H) {
-	              if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-	           } else {
-	              if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-	           }
-	        }
 	   } else {
-	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO |           /* (Allow 720 for VGA2) */
-	      			       SetCRT2ToSVIDEO |
-	                               SetCRT2ToSCART  | 
-				       SetCRT2ToLCD    | 
-				       SetCRT2ToHiVisionTV)) {
-	         if(xres == 720) xres = 640;
-	      }
-	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		    if(ModeNo <= 0x13) {
-		       /* TW: This is wrong for 640x400 *graphics* mode */
-      		       if(yres == 400) yres = 405;
-		    }
-      		    if(yres == 350) yres = 360;
-      		    if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-        	       if(yres == 360) yres = 375;
-      		    }
-   	         }
-    	         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768){
-      		    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-        	       if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-          	          if(yres == 350) yres = 357;
-          	          if(yres == 400) yres = 420;
-            	          if(yres == 480) yres = 525;
-        	       }
-      		    }
-    	         }
-	      }
-	   }
-	}
-  } else {
-    	if(xres == 720) xres = 640;
-	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-	      yres = 400;
-	      if(HwDeviceExtension->jChipType >= SIS_315H) {
-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x17) & 0x80) yres = 480;
-	      } else {
-	          if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) yres = 480;
-	      }
-	}
-  }
-  SiS_Pr->SiS_VGAHDE = SiS_Pr->SiS_HDE = xres;
-  SiS_Pr->SiS_VGAVDE = SiS_Pr->SiS_VDE = yres;
-}
-
-void
-SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-	       USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
-	       PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempbx=0,tempal=0;
-  USHORT Flag,resinfo=0;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	      SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {                            /* LCD */
+           }
 
-	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-			tempbx = 15;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		        tempbx = 20;
-			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 21;
-			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 22;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-		        tempbx = 23;
-			if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)         tempbx = 24;
-			else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx = 25;
-		} else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-			tempbx = 13;
-			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx++;
-		} else {
-      		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_Panel1024x768;
-      		   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-        		tempbx += 5;
-                        /* GetRevisionID();  */
-			/* TW: BIOS only adds 5 once */
-        		tempbx += 5;
-       		   }
-	        }
+        }
 
-     	} else {						  	/* TV */
-	
-       		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-		   (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-         		if(SiS_Pr->SiS_VGAVDE > 480) SiS_Pr->SiS_SetFlag &= (~TVSimuMode);
-         		tempbx = 2;
-         		if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-            			if(!(SiS_Pr->SiS_SetFlag & TVSimuMode)) tempbx = 12; 
-         		}
-       		} else {
-         		if(SiS_Pr->SiS_VBInfo & SetPALTV) tempbx = 3;
-         		else tempbx = 4;
-         		if(SiS_Pr->SiS_SetFlag & TVSimuMode) tempbx += 5;
-       		}
-		
-     	}
-
-     	if(ModeNo <= 0x13) {
-       		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-     	} else {
-       		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-        }
-
-     	tempal &= 0x3F;
-
-      	if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
-           (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))) {
-      		if(tempal == 0x06) tempal = 0x07;
-        }
-
-	/* TW: 300/301LV BIOS */
-	if((HwDeviceExtension->jChipType == SIS_300) &&
-	   (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-	    if(ModeNo > 0x13) {
-	        if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 (index diff. on 310/325!) */
-		    tempal = 6;
-	    }
-	}
+     } else {
 
-	if(HwDeviceExtension->jChipType != SIS_300) {
-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-              if((ModeNo == 0x31) || (ModeNo == 0x32)) tempal = 6;
-	   }
-	}
+     	SiS_GetCRT2Data301(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-     	*CRT2Index = tempbx;
-     	*ResIndex = tempal;
+     }
 
-  } else {   /* LVDS, 301B-DH (if running on LCD) */
+  } else {
 
-    	Flag = 1;
-    	tempbx = 0;
-    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-	
-      		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        		Flag = 0;
-        		tempbx = 10;
-			if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-        		if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-				tempbx += 2;
-				if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-				if(SiS_Pr->SiS_CHPALM) {
-					tempbx = 90;
-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-				} else if(SiS_Pr->SiS_CHPALN) {
-					tempbx = 92;
-					if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-				}
-				
-			}
-      		}
-		
-    	}
+     SiS_GetCRT2DataLVDS(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
 
-    	if(Flag) {
-      		
-		if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
-		   tempbx = SiS_Pr->SiS_LCDResInfo - SiS_Pr->SiS_PanelMinLVDS;
-   	      	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 3;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-		   tempbx = 18;
-		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++; 
-	        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) { 
-		   tempbx = 6;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-		   tempbx = 15;
-  		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-		   tempbx = 16;
-		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 2;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		   tempbx = 8;
-		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-		   tempbx = 21;
-		   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx++;
-		}
-		
-		if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-		   tempbx = 7;
-        	}
-		
-	}
+  }
+}
 
-    	if(ModeNo <= 0x13)
-      		tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-    	else {
-      		tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-		resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	}
+/*********************************************/
+/*            GET LVDS DES DATA              */
+/*********************************************/
 
-	if(SiS_Pr->SiS_IF_DEF_FSTN){
-       	 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-         		tempbx = 14;
-         		tempal = 6;
-        	}
-    	}
+static void
+SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                  USHORT RefreshRateTableIndex, USHORT *PanelIndex,
+		  USHORT *ResIndex, PSIS_HW_INFO HwInfo)
+{
+  USHORT tempbx,tempal,modeflag;
 
-	if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
-	        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) tempal = 7;
-		if(HwDeviceExtension->jChipType < SIS_315H) {
-		    if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
-		}
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
 
-	}
+  tempbx = 0;
+  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        tempbx = 50;
+        if((SiS_Pr->SiS_VBInfo & SetPALTV) && (!SiS_Pr->SiS_CHPALM)) tempbx += 2;
+        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
+        /* Nothing special needed for SOverscan    */
+        /*     PALM uses NTSC data, PALN uses PAL data */
+     }
+  }
 
-	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	    if(ModeNo > 0x13) {
-	        if(HwDeviceExtension->jChipType < SIS_315H) {
-	           if((resinfo == 0x0c) || (resinfo == 0x0d))  /* 720 */
-		       tempal = 6;
-	        } else {
-		   if((resinfo == 0x0d) || (resinfo == 0x0e))  /* 720 */
-		       tempal = 6;
-		}
-	    }
-	}
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     tempbx = SiS_Pr->SiS_LCDTypeInfo;
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 16;
+     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+        tempbx = 32;
+        if(modeflag & HalfDCLK) tempbx++;
+     }
+  }
 
-    	*CRT2Index = tempbx;
-    	*ResIndex = tempal & 0x1F;
+  if(SiS_Pr->SiS_SetFlag & SetDOSMode) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
+        tempal = 0x07;
+        if(HwInfo->jChipType < SIS_315H) {
+           if(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x80) tempal++;
+        }
+     }
   }
+
+  *PanelIndex = tempbx;
+  *ResIndex = tempal & 0x1F;
 }
 
 #ifdef SIS315H
-void
-SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-		USHORT *ResIndex)
+static void
+SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, USHORT *PanelIndex, USHORT *ResIndex,
+		   PSIS_HW_INFO HwInfo)
 {
-  USHORT tempbx,tempal;
+  USHORT tempbx=0,tempal;
 
-  tempbx = SiS_Pr->SiS_LCDResInfo;
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      tempbx = 2;
+  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 3;
+  else tempbx = SiS_Pr->SiS_LCDResInfo - 2;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)      tempbx = 4;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempbx = 3;
-  else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  tempbx = 2;
-  else tempbx -= SiS_Pr->SiS_Panel1024x768;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 4;
 
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx += 5;
+  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+	   tempbx = 80;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+	}
+     }
+  }
+  if(SiS_Pr->SiS_CustomT == CUT_UNIWILL1024) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	tempbx = 82;
+	if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx++;
+     }
+  }
 
   if(ModeNo <= 0x13)
-      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+     tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   else
-      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-  *CRT2Index = tempbx;
+  *PanelIndex = tempbx;
   *ResIndex = tempal & 0x1F;
 }
 #endif
 
-void
-SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
-		    USHORT *ResIndex)
-{
-  USHORT tempbx,tempal;
-
-  if(ModeNo <= 0x13)
-      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  else
-      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-
-  tempbx = SiS_Pr->SiS_LCDResInfo;
-
-  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
-  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
-
-  *CRT2Index = tempbx;
-  *ResIndex = tempal & 0x3F;
-}
-
-USHORT
-SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex,
-                   PSIS_HW_DEVICE_INFO HwDeviceExtension)
+static void
+SiS_GetLVDSDesData(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
+                   USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  SHORT  LCDRefreshIndex[] = { 0x00, 0x00, 0x03, 0x01,
-                               0x01, 0x01, 0x01, 0x01,
-			       0x01, 0x01, 0x01, 0x01,
-			       0x01, 0x01, 0x01, 0x01 };
-  USHORT RefreshRateTableIndex,i,backup_i;
-  USHORT modeflag,index,temp,backupindex;
-
-  if(SiS_Pr->UseCustomMode) return 0;
-  
-  if(ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  USHORT modeflag;
+  USHORT PanelIndex,ResIndex;
+  const  SiS_LVDSDesStruct *PanelDesPtr = NULL;
 
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      		if(modeflag & HalfDCLK) return(0);
-    	}
+  if((SiS_Pr->UseCustomMode) ||
+     (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) ||
+     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
+     SiS_Pr->SiS_LCDHDES = 0;
+     SiS_Pr->SiS_LCDVDES = 0;
+     return;
   }
 
-  if(ModeNo < 0x14) return(0xFFFF);
+  if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
 
- /* TW: CR33 holds refresh rate index for CRT1 [3:0] and CRT2 [7:4].
-  *     On LVDS machines, CRT2 index is always 0 and will be
-  *     set to 0 by the following code; this causes the function
-  *     to take the first non-interlaced mode in SiS_Ext2Struct
-  */
+#ifdef SIS315H
+     SiS_GetLVDSDesPtrA(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                        &PanelIndex, &ResIndex, HwInfo);
 
-  index = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x33);
-  index >>= SiS_Pr->SiS_SelectCRT2Rate;
-  index &= 0x0F;
-  backupindex = index;
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;  /* --- expanding --- */
+     	case  1: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_1;  break;
+	case  2: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_1;  break;
+	case  3: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_1;  break;
+     	case  4: PanelDesPtr = SiS_Pr->LVDS1024x768Des_2;   break;  /* --- non expanding --- */
+     	case  5: PanelDesPtr = SiS_Pr->LVDS1280x1024Des_2;  break;
+	case  6: PanelDesPtr = SiS_Pr->LVDS1400x1050Des_2;  break;
+	case  7: PanelDesPtr = SiS_Pr->LVDS1600x1200Des_2;  break;
+	case 80: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_1;   break;  /*  custom  */
+	case 81: PanelDesPtr = (SiS_LVDSDesStruct *)Clevo1024x768Des_2;   break;
+	case 82: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_1; break;
+	case 83: PanelDesPtr = (SiS_LVDSDesStruct *)Uniwill1024x768Des_2; break;
+	default: PanelDesPtr = SiS_Pr->LVDS1024x768Des_1;   break;
+     }
+#endif
 
-  if(index > 0) index--;
+  } else {
 
-  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA))  index = 0;
-      } else {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	    if(SiS_Pr->SiS_VBType & VB_NoLCD)
-	       	    index = 0;
-	    else if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)
-	    	    index = backupindex = 0;
-	}
-      }
-  }
+     SiS_GetLVDSDesPtr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                       &PanelIndex, &ResIndex, HwInfo);
 
-  if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        		index = 0;
-      		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-			if(!(SiS_Pr->SiS_VBType & VB_NoLCD)) {
-           		   temp = LCDRefreshIndex[SiS_Pr->SiS_LCDResInfo];
-        		   if(index > temp) index = temp;
-			}
-      		} else {
-        		index = 0;
-      		}
-    	}
+     switch (PanelIndex)
+     {
+     	case  0: PanelDesPtr = SiS_Pr->SiS_PanelType00_1;   break;   /* ---  */
+     	case  1: PanelDesPtr = SiS_Pr->SiS_PanelType01_1;   break;
+     	case  2: PanelDesPtr = SiS_Pr->SiS_PanelType02_1;   break;
+     	case  3: PanelDesPtr = SiS_Pr->SiS_PanelType03_1;   break;
+     	case  4: PanelDesPtr = SiS_Pr->SiS_PanelType04_1;   break;
+     	case  5: PanelDesPtr = SiS_Pr->SiS_PanelType05_1;   break;
+     	case  6: PanelDesPtr = SiS_Pr->SiS_PanelType06_1;   break;
+     	case  7: PanelDesPtr = SiS_Pr->SiS_PanelType07_1;   break;
+     	case  8: PanelDesPtr = SiS_Pr->SiS_PanelType08_1;   break;
+     	case  9: PanelDesPtr = SiS_Pr->SiS_PanelType09_1;   break;
+     	case 10: PanelDesPtr = SiS_Pr->SiS_PanelType0a_1;   break;
+     	case 11: PanelDesPtr = SiS_Pr->SiS_PanelType0b_1;   break;
+     	case 12: PanelDesPtr = SiS_Pr->SiS_PanelType0c_1;   break;
+     	case 13: PanelDesPtr = SiS_Pr->SiS_PanelType0d_1;   break;
+     	case 14: PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;   break;
+     	case 15: PanelDesPtr = SiS_Pr->SiS_PanelType0f_1;   break;
+     	case 16: PanelDesPtr = SiS_Pr->SiS_PanelType00_2;   break;    /* --- */
+     	case 17: PanelDesPtr = SiS_Pr->SiS_PanelType01_2;   break;
+     	case 18: PanelDesPtr = SiS_Pr->SiS_PanelType02_2;   break;
+     	case 19: PanelDesPtr = SiS_Pr->SiS_PanelType03_2;   break;
+     	case 20: PanelDesPtr = SiS_Pr->SiS_PanelType04_2;   break;
+     	case 21: PanelDesPtr = SiS_Pr->SiS_PanelType05_2;   break;
+     	case 22: PanelDesPtr = SiS_Pr->SiS_PanelType06_2;   break;
+     	case 23: PanelDesPtr = SiS_Pr->SiS_PanelType07_2;   break;
+     	case 24: PanelDesPtr = SiS_Pr->SiS_PanelType08_2;   break;
+     	case 25: PanelDesPtr = SiS_Pr->SiS_PanelType09_2;   break;
+     	case 26: PanelDesPtr = SiS_Pr->SiS_PanelType0a_2;   break;
+     	case 27: PanelDesPtr = SiS_Pr->SiS_PanelType0b_2;   break;
+     	case 28: PanelDesPtr = SiS_Pr->SiS_PanelType0c_2;   break;
+     	case 29: PanelDesPtr = SiS_Pr->SiS_PanelType0d_2;   break;
+     	case 30: PanelDesPtr = SiS_Pr->SiS_PanelType0e_2;   break;
+     	case 31: PanelDesPtr = SiS_Pr->SiS_PanelType0f_2;   break;
+	case 32: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_1;   break;    /* pass 1:1 */
+	case 33: PanelDesPtr = SiS_Pr->SiS_PanelTypeNS_2;   break;
+     	case 50: PanelDesPtr = SiS_Pr->SiS_CHTVUNTSCDesData;   break; /* TV */
+     	case 51: PanelDesPtr = SiS_Pr->SiS_CHTVONTSCDesData;   break;
+     	case 52: PanelDesPtr = SiS_Pr->SiS_CHTVUPALDesData;    break;
+     	case 53: PanelDesPtr = SiS_Pr->SiS_CHTVOPALDesData;    break;
+	default:
+		 if(HwInfo->jChipType < SIS_315H)
+		    PanelDesPtr = SiS_Pr->SiS_PanelType0e_1;
+		 else
+		    PanelDesPtr = SiS_Pr->SiS_PanelType01_1;
+		 break;
+     }
   }
+  SiS_Pr->SiS_LCDHDES = (PanelDesPtr+ResIndex)->LCDHDES;
+  SiS_Pr->SiS_LCDVDES = (PanelDesPtr+ResIndex)->LCDVDES;
 
-  RefreshRateTableIndex = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex;
-  ModeNo = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].ModeID;
-
-  /* TW: 650/LVDS 1.10.07, 650/30xLV 1.10.6s */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if(!(SiS_Pr->SiS_VBInfo & DriverMode)) {
-        if( (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x105) ||
-            (SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_VESAID == 0x107) ) {
-           if(backupindex <= 1) RefreshRateTableIndex++;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD){
+     if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
+        if(ModeNo <= 0x13) {
+           modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	   if(!(modeflag & HalfDCLK)) {
+	      SiS_Pr->SiS_LCDHDES = 632;
+	   }
+        }
+     } else {
+        if(!(SiS_Pr->SiS_SetFlag & SetDOSMode)) {
+           if( (HwInfo->jChipType < SIS_315H) ||
+	       (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) ) {
+              if(SiS_Pr->SiS_LCDResInfo >= SiS_Pr->SiS_Panel1024x768){
+                 if(ModeNo <= 0x13) {
+	            modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	            if(HwInfo->jChipType < SIS_315H) {
+	               if(!(modeflag & HalfDCLK)) SiS_Pr->SiS_LCDHDES = 320;
+	            } else {
+	               if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
+	                  SiS_Pr->SiS_LCDHDES = 480;
+                       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+	                  SiS_Pr->SiS_LCDHDES = 804;
+		       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+	                  SiS_Pr->SiS_LCDHDES = 704;
+                       if(!(modeflag & HalfDCLK)) {
+                          SiS_Pr->SiS_LCDHDES = 320;
+	                  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)
+	                     SiS_Pr->SiS_LCDHDES = 632;
+		          else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)
+	                     SiS_Pr->SiS_LCDHDES = 542;
+                       }
+                    }
+                 }
+              }
+           }
         }
      }
   }
+}
 
-  i = 0;
-  do {
-    	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].ModeID != ModeNo) break;
-    	temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
-    	temp &= ModeInfoFlag;
-    	if(temp < SiS_Pr->SiS_ModeType) break;
-    	i++;
-    	index--;
-  } while(index != 0xFFFF);
+/*********************************************/
+/*          SET CRT2 AUTO-THRESHOLD          */
+/*********************************************/
 
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC)) {
-    	if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      		temp = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + i - 1].Ext_InfoFlag;
-      		if(temp & InterlaceMode) {
-        		i++;
-      		}
-    	}
-  }
+#ifdef SIS315H
+static void
+SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr)
+{
+  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x40);
+}
+#endif
 
-  i--;
+/*********************************************/
+/*           DISABLE VIDEO BRIDGE            */
+/*********************************************/
+
+/* NEVER use any variables (VBInfo), this will be called
+ * from outside the context of modeswitch!
+ * MUST call getVBType before calling this
+ */
+void
+SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+#ifdef SIS315H
+  USHORT tempah,pushax=0,modenum;
+#endif
+  USHORT temp=0;
 
-  if((SiS_Pr->SiS_SetFlag & ProgrammingCRT2) && (!(SiS_Pr->SiS_VBInfo & DisableCRT2Display))) {
-    	backup_i = i;
-    	if (!(SiS_AdjustCRT2Rate(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-	                             RefreshRateTableIndex,&i,HwDeviceExtension))) {
-		/* TW: This is for avoiding random data to be used; i is
-		 *     in an undefined state if no matching CRT2 mode is
-		 *     found.
-		 */
-		i = backup_i;
-	}
-  }
 
-  return(RefreshRateTableIndex + i);
-}
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-/* Checked against all (incl 650/LVDS (1.10.07), 630/301) BIOSes */
-BOOLEAN
-SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempax,tempbx,resinfo;
-  USHORT modeflag,infoflag;
+      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== For 30xB/LV ===== */
 
-  if (ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+        if(HwInfo->jChipType < SIS_315H) {
 
-  resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-  tempbx = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID;
+#ifdef SIS300	   /* 300 series */
 
-  tempax = 0;
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
-      		tempax |= SupportRAMDAC2;
-		if(HwDeviceExtension->jChipType >= SIS_315H) {
-		    tempax |= SupportTV;
-		    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-		        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-			    if(resinfo == 0x0a) tempax |= SupportTV1024;
-			}
-		    }
-		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-      		tempax |= SupportLCD;
-		if(HwDeviceExtension->jChipType >= SIS_315H) {
-                   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
-		         if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-			    (*i) = 0;
-                            return(1);
-		         } else {
-      		            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
-        		      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
-           			if((resinfo == 6) && (SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-				    return(0);
-				} else {
-             			    if((resinfo >= 9) && (resinfo != 0x14)) {
-               				return(0);
-             			    }
-           			}
-        		      }
-		            }
-		         }
-		      }
-      		   }
-		} else {
-		  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-		     if((resinfo != 0x0f) && ((resinfo == 4) || (resinfo >= 8))) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-		     if((resinfo != 0x10) && (resinfo > 8)) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-		     if((resinfo != 0x0e) && (resinfo > 8)) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		     if(resinfo > 9) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-		     if(resinfo > 8) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-		     if((resinfo == 4) || (resinfo > 7)) return(0);
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
-		     if((resinfo == 4) || (resinfo == 3) || (resinfo > 6)) return(0);
-		  }
-		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) { 
-	        if(SiS_Pr->SiS_HiVision == 3) {
-		      	tempax |= SupportHiVisionTV2;
-      			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
-        			if(resinfo == 4) return(0);
-        			if(resinfo == 3) return(0);
-				if(resinfo == 7) {
-	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
-        			}
-        			if(resinfo > 7) return(0);
-			}
-		} else {  
-      			tempax |= SupportHiVisionTV;
-      			if(SiS_Pr->SiS_VBInfo & SetInSlaveMode){
-        			if(resinfo == 4) return(0);
-        			if((resinfo == 3) || (resinfo == 7)) {
-	          			if(SiS_Pr->SiS_SetFlag & TVSimuMode) return(0);
-        			}
-        			if(resinfo > 7) return(0);
-			}
-		}
-    	} else {
-      	   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToAVIDEO|SetCRT2ToSVIDEO|SetCRT2ToSCART)) {
-        	tempax |= SupportTV;
-		tempax |= SupportTV1024;
-		if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-		        if((SiS_Pr->SiS_VBInfo & SetNotSimuMode) && (SiS_Pr->SiS_VBInfo & SetPALTV)) {
-			     if(resinfo != 8) {
-			         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-				     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4)) ) {
-				     tempax &= ~(SupportTV1024);
-				     if(HwDeviceExtension->jChipType >= SIS_315H) {
-                                         if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				             if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                         ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			                         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		                             }
-				         }
-		                     } else {
-				         if( (resinfo != 3) ||
-					     (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-					     (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-					     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-						 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-						     if(resinfo == 3) return(0);
-						     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-						 }
-		                             }
-                                         } else return(0);
-				     }
-				 }
-			     }
-			} else {
-			    tempax &= ~(SupportTV1024);
-			    if(HwDeviceExtension->jChipType >= SIS_315H) {
-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-			            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			                if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		                    }
-		                }
-			    } else {
-			        if( (resinfo != 3) ||
-				    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-				    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-				     if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-					 if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-					     if(resinfo == 3) return(0);
-					     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-					 }
-		                     }
-                                } else return(0);
-                            }
-			}
-		    } else {  /* slavemode */
-			if(resinfo != 8) {
-			    if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 4) ) ) {
-				 tempax &= ~(SupportTV1024);
-				 if(HwDeviceExtension->jChipType >= SIS_315H) {
-				     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				         if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			                     ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			                     if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode))  return(0);
-		                         }
-		                     }
-			        } else {
-				    if( (resinfo != 3) ||
-				        (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-				        (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-				         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-					     if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-					         if(resinfo == 3) return(0);
-					         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-					     }
-		                         }
-                                    } else return(0);
-				}
-			    }
-			}
-		    }
-		} else {   /* 301 */
-		    tempax &= ~(SupportTV1024);
-		    if(HwDeviceExtension->jChipType >= SIS_315H) {
-		        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-		            if( (!(SiS_Pr->SiS_VBInfo & SetPALTV)) ||
-			        ((SiS_Pr->SiS_VBInfo & SetPALTV) && (resinfo != 7)) ) {
-			        if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return(0);
-		            }
-		        }
-		    } else {
-		        if( (resinfo != 3) ||
-			    (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-			    (SiS_Pr->SiS_VBInfo & SetNotSimuMode) ) {
-			    if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-			        if((modeflag & NoSupportSimuTV) && (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-				    if(resinfo == 3) return(0);
-				    if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) return (0);
-				}
-		            }
-                        } else return(0);
-		    }
-		}
-           }
-    	}
-	
-  } else {	/* TW: for LVDS  */
+           if(HwInfo->jChipType == SIS_300) {  /* For 300+301LV (A907) */
 
-    	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-      		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-        		tempax |= SupportCHTV;
-      		}
-    	}
-    	if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-      		tempax |= SupportLCD;
-		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-		     if((resinfo != 0x14) && (resinfo > 0x09)) return(0);
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-		     if((resinfo != 0x0f) && (resinfo > 0x08)) return(0);
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-		     if((resinfo != 0x10) && (resinfo > 0x08)) return(0);
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		     if((resinfo != 0x15) && (resinfo > 0x09)) return(0);
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-                     if(resinfo > 0x09) return(0);
-                } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-		     if(resinfo > 0x08) return(0);
-		} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600){
-		     if(resinfo > 0x07) return(0);
-		     if(resinfo == 0x04) return(0);
-		}
-    	}
-  }
-  /* TW: Look backwards in table for matching CRT2 mode */
-  for(; SiS_Pr->SiS_RefIndex[RefreshRateTableIndex+(*i)].ModeID == tempbx; (*i)--) {
-     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-     	if(infoflag & tempax) {
-       		return(1);
-     	}
-     	if ((*i) == 0) break;
-  }
-  /* TW: Look through the whole mode-section of the table from the beginning
-   *     for a matching CRT2 mode if no mode was found yet.
-   */
-  for((*i) = 0; ; (*i)++) {
-     	infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].Ext_InfoFlag;
-     	if(SiS_Pr->SiS_RefIndex[RefreshRateTableIndex + (*i)].ModeID != tempbx) {
-       		return(0);
-     	}
-     	if(infoflag & tempax) {
-       		return(1);
-     	}
-  }
-  return(1);
-}
+	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+	         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+		    SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+		 }
+	      }
+	      if(SiS_Is301B(SiS_Pr)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+	         SiS_ShortDelay(SiS_Pr,1);
+	      }
+	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	      SiS_DisplayOff(SiS_Pr);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	      if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+	          (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
+	         SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	      }
 
-void
-SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo)
-{
-  USHORT temp1,temp2;
+	   } else {
 
-  /* TW: We store CRT1 ModeNo in CR34 */
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x34,ModeNo);
-  temp1 = (SiS_Pr->SiS_VBInfo & SetInSlaveMode) >> 8;
-  temp2 = ~(SetInSlaveMode >> 8);
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x31,temp2,temp1);
-}
+	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+	         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	         SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+	      }
+	      if(SiS_Is301B(SiS_Pr)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
+	         SiS_ShortDelay(SiS_Pr,1);
+	      }
+	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
+	      SiS_DisplayOff(SiS_Pr);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	      SiS_UnLockCRT2(SiS_Pr,HwInfo);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
+	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
+	      if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+	          (!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) ) {
+	         SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	      }
+	   }
 
-void
-SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension,
-	      int checkcrt2mode)
-{
-  USHORT tempax,tempbx,temp;
-  USHORT modeflag, resinfo=0;
-  UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
+#endif  /* SIS300 */
 
-  if(SiS_Pr->UseCustomMode) {
-        modeflag = SiS_Pr->CModeFlag;
-  } else {
-    if (ModeNo <= 0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    else {
-   	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-    }
-  }    
+        } else {
 
-  SiS_Pr->SiS_SetFlag = 0;
+#ifdef SIS315H	   /* 315 series */
 
-  SiS_Pr->SiS_ModeType = modeflag & ModeInfoFlag;
+           if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
-  tempbx = 0;
-  if(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension) == 0) {  
-    	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-#if 0	
-	/* SiS_HiVision is only used on 310/325/330+30xLV */
-	if(SiS_Pr->SiS_VBType & (VB_SIS301LV302LV)) {
-	   if(SiS_Pr->SiS_HiVision & 0x03) {	/* TW: New from 650/30xLV 1.10.6s */
-	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
-	      temp |= SetCRT2ToHiVisionTV;   					/* 0x80 */
-	   }
-	   if(SiS_Pr->SiS_HiVision & 0x04) {	/* TW: New from 650/30xLV 1.10.6s */
-	      temp &= (SetCRT2ToHiVisionTV | SwitchToCRT2 | SetSimuScanMode); 	/* 0x83 */
-	      temp |= SetCRT2ToSVIDEO;  					/* 0x08 */
-	   }
-	}
-#endif	
-    	if(SiS_Pr->SiS_IF_DEF_FSTN) {   /* fstn must set CR30=0x21 */
-       		temp = (SetCRT2ToLCD | SetSimuScanMode);
-       		SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,temp);
-    	}
-    	tempbx |= temp;
-    	tempax = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) << 8;
-        tempax &= (LoadDACFlag | DriverMode | SetDispDevSwitch | SetNotSimuMode | SetPALTV);
-    	tempbx |= tempax;
-    	tempbx &= ~(SetCHTVOverScan | SetInSlaveMode | DisableCRT2Display);;
+	      modenum = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
 
-#ifdef SIS315H
+              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {			/* LV */
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-    	   if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS301LV | VB_SIS302LV)) {
-	      /* From 1.10.7w, not in 1.10.8r */
-	      if(ModeNo == 0x03) {   
-	         /* Mode 0x03 is never in driver mode */
-		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x31,0xbf);
-	      }
-	      /* From 1.10.7w, not in 1.10.8r */
-	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8))) {
-	         /* Reset LCDA setting */
-		 SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0xfc);
-	      }
-	      if(IS_SIS650) {
-	         if(SiS_Pr->SiS_UseLCDA) {
-		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
-		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
-		          SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
-		       }
+#ifdef SET_EMI
+	         if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	            if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+	               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
 		    }
 		 }
-#if 0		 /* We can't detect it this way; there are machines which do not use LCDA despite
-                  * the chip revision
-		  */      	      
-		 if((tempbx & SetCRT2ToLCD) && (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30) & SetCRT2ToLCD)) {
-                    if((SiS_GetReg1(SiS_Pr->SiS_P3d4, 0x36) & 0x0f) == SiS_Pr->SiS_Panel1400x1050) {
-		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
-		          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
-			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
-			  }
-		       }
-		    } else {
-		       if((ModeNo <= 0x13) || (!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & (DriverMode >> 8)))) {
-			  if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xF0) {
-			     SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x38,(EnableDualEdge | SetToLCDA));  /* 3 */
-		          }
-		       }
-		    }
-		 }
-#endif		 
-	      }
-	      temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-       	      if((temp & (EnableDualEdge | SetToLCDA)) == (EnableDualEdge | SetToLCDA)) {
-          		tempbx |= SetCRT2ToLCDA;
-	      }
-    	   }
-
-	   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-	        temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-	        if(temp & SetToLCDA)
-		   tempbx |= SetCRT2ToLCDA;
-		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-	           if(temp & EnableLVDSHiVision)
-		      tempbx |= SetCRT2ToHiVisionTV;
-		}
-	   }
-	}
-
-#endif  /* SIS315H */
+#endif
 
-    	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-	        temp = SetCRT2ToLCDA   | SetCRT2ToSCART      | SetCRT2ToLCD    |
-		       SetCRT2ToRAMDAC | SetCRT2ToSVIDEO     | SetCRT2ToAVIDEO |  /* = 0x807C; */
-                       SetCRT2ToHiVisionTV; 					  /* = 0x80FC; */
-    	} else {
-                if(HwDeviceExtension->jChipType >= SIS_315H) {
-                    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
-        		temp = SetCRT2ToLCDA   | SetCRT2ToSCART |
-			       SetCRT2ToLCD    | SetCRT2ToHiVisionTV |
-			       SetCRT2ToAVIDEO | SetCRT2ToSVIDEO;  /* = 0x80bc */
-      		    else
-        		temp = SetCRT2ToLCDA | SetCRT2ToLCD;
-		} else {
-      		    if(SiS_Pr->SiS_IF_DEF_CH70xx != 0)
-        		temp = SetCRT2ToTV | SetCRT2ToLCD;
-      		    else
-        		temp = SetCRT2ToLCD;
-		}
-    	}
+		 if( (modenum <= 0x13) ||
+		     (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+		     (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
+	     	      SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+		      if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		         SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+		      }
+	         }
 
-    	if(!(tempbx & temp)) {
-      		tempax = DisableCRT2Display;
-      		tempbx = 0;
-    	}
+		 if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+		    (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+		    SiS_DDC2Delay(SiS_Pr,0xff00);
+		    SiS_DDC2Delay(SiS_Pr,0xe000);
 
-   	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-      		if(tempbx & SetCRT2ToLCDA) {
-        		tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
-      		}
-		if(tempbx & SetCRT2ToRAMDAC) {
-        		tempbx &= (0xFF00|SetCRT2ToRAMDAC|SwitchToCRT2|SetSimuScanMode);
-      		}
-		if((tempbx & SetCRT2ToLCD) /* && (!(SiS_Pr->SiS_VBType & VB_NoLCD)) */ ) {
-		        /* We initialize the Panel Link of the type of bridge is DH */
-        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
-      		}
-		if(tempbx & SetCRT2ToSCART) {
-        		tempbx &= (0xFF00|SetCRT2ToSCART|SwitchToCRT2|SetSimuScanMode);
-        		tempbx |= SetPALTV;
-      		}
-		if(tempbx & SetCRT2ToHiVisionTV) {
-        		tempbx &= (0xFF00|SetCRT2ToHiVisionTV|SwitchToCRT2|SetSimuScanMode);
-        		tempbx |= SetPALTV;
-      		}
-   	} else { /* LVDS */
-	        if(HwDeviceExtension->jChipType >= SIS_315H) {
-		    if(tempbx & SetCRT2ToLCDA)
-		        tempbx &= (0xFF00|SwitchToCRT2|SetSimuScanMode);
-		}
-      		if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-        	    if(tempbx & SetCRT2ToTV)
-          		 tempbx &= (0xFF00|SetCRT2ToTV|SwitchToCRT2|SetSimuScanMode);
-      		}
-      		if(tempbx & SetCRT2ToLCD) {
-        		tempbx &= (0xFF00|SetCRT2ToLCD|SwitchToCRT2|SetSimuScanMode);
-		}
-	        if(HwDeviceExtension->jChipType >= SIS_315H) {
-		    if(tempbx & SetCRT2ToLCDA)
-		        tempbx |= SetCRT2ToLCD;
-		}
-	}
+	            SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
 
-    	if(tempax & DisableCRT2Display) {
-      		if(!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
-        		tempbx = SetSimuScanMode | DisableCRT2Display;
-      		}
-    	}
+                    pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
 
-    	if(!(tempbx & DriverMode)){
-      		tempbx |= SetSimuScanMode;
-    	}
+		    if(IS_SIS740) {
+		       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+		    }
 
-	/* TW: LVDS (LCD/TV) and 301BDH (LCD) can only be slave in 8bpp modes */
-	if(SiS_Pr->SiS_ModeType <= ModeVGA) {
-	   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
-	       ((tempbx & SetCRT2ToLCD) && (SiS_Pr->SiS_VBType & VB_NoLCD)) ) {
-	       modeflag &= (~CRT2Mode);
-	   }
-	}
-	
-    	if(!(tempbx & SetSimuScanMode)){
-      	    if(tempbx & SwitchToCRT2) {
-        	if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
-		     if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-			 (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-			 if(resinfo != 0x0a)
-                              tempbx |= SetSimuScanMode;
-		     } else {
-            		      tempbx |= SetSimuScanMode;
-	             }
-        	}
-      	    } else {
-        	if(!(SiS_BridgeIsEnable(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-          	     if(!(tempbx & DriverMode)) {
-            		  if(SiS_BridgeInSlave(SiS_Pr)) {
-			      tempbx |= SetSimuScanMode;
-            		  }
-                     }
-                }
-      	    }
-    	}
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
 
-    	if(!(tempbx & DisableCRT2Display)) {
-            if(tempbx & DriverMode) {
-                if(tempbx & SetSimuScanMode) {
-          	    if((!(modeflag & CRT2Mode)) && (checkcrt2mode)) {
-	                if( (HwDeviceExtension->jChipType >= SIS_315H) &&
-			    (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) ) {
-			     if(resinfo != 0x0a) {  /* TW: 650/301 BIOS */
-			          tempbx |= SetInSlaveMode;
-            		          if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-              		 	     if(tempbx & SetCRT2ToTV) {
-                		         if(!(tempbx & SetNotSimuMode))
-					     SiS_Pr->SiS_SetFlag |= TVSimuMode;
-              			     }
-                                  }
-			     }                      /* TW: 650/301 BIOS */
-		        } else {
-            		    tempbx |= SetInSlaveMode;
-            		    if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-              		        if(tempbx & SetCRT2ToTV) {
-                		    if(!(tempbx & SetNotSimuMode))
-					SiS_Pr->SiS_SetFlag |= TVSimuMode;
-              			}
-            		    }
-                        }
+		    if(!(IS_SIS740)) {
+		       if(!(SiS_IsNotM650or651(SiS_Pr, HwInfo))) {
+	                  tempah = 0xef;
+	                  if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	                     tempah = 0xf7;
+                          }
+	                  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		       }
 	            }
-                }
-            } else {
-                tempbx |= SetInSlaveMode;
-        	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-          	    if(tempbx & SetCRT2ToTV) {
-            		if(!(tempbx & SetNotSimuMode))
-			    SiS_Pr->SiS_SetFlag |= TVSimuMode;
-          	    }
-        	}
-      	    }
-    	}
-	
-	if(SiS_Pr->SiS_CHOverScan) {
-    	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-      		if((temp & TVOverScan) || (SiS_Pr->SiS_CHOverScan == 1) )
-		      tempbx |= SetCHTVOverScan;
-    	   }
-	   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-      		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
-      		if( (temp & 0x80) || (SiS_Pr->SiS_CHOverScan == 1) )
-		      tempbx |= SetCHTVOverScan;
-    	   }
-	}
-  }
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-#ifdef SIS300
-     	if((HwDeviceExtension->jChipType==SIS_630) ||
-           (HwDeviceExtension->jChipType==SIS_730)) {
-	   	if(ROMAddr && SiS_Pr->SiS_UseROM) {
-			OutputSelect = ROMAddr[0xfe];
-                }
-           	if(!(OutputSelect & EnablePALMN))
-             		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x35,0x3F);
-           	if(tempbx & SetCRT2ToTV) {
-              		if(tempbx & SetPALTV) {
-                  		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
-                  		if(temp & EnablePALM) tempbx &= (~SetPALTV);
-             		}
-          	}
-      	}
-#endif
-#ifdef SIS315H
-     	if(HwDeviceExtension->jChipType >= SIS_315H) {
-	        if(ROMAddr && SiS_Pr->SiS_UseROM) {
-		    OutputSelect = ROMAddr[0xf3];
-		    if(HwDeviceExtension->jChipType == SIS_330) {
-			OutputSelect = ROMAddr[0x11b];
-		    }
-                }
-		if(!(OutputSelect & EnablePALMN))
-        		SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x38,0x3F);
-   		if(tempbx & SetCRT2ToTV) {
-    			if(tempbx & SetPALTV) {
-               			temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-               			if(temp & EnablePALM) tempbx &= (~SetPALTV);
-              		}
-        	}
-  	}
-#endif
-  }
-  
-  /* PALM/PALN on Chrontel 7019 */
-  SiS_Pr->SiS_CHPALM = SiS_Pr->SiS_CHPALN = FALSE;
-  if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-  	if(tempbx & SetCRT2ToTV) {
-    		if(tempbx & SetPALTV) {
-        		temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-        		if(temp & EnablePALM)      SiS_Pr->SiS_CHPALM = TRUE;
-			else if(temp & EnablePALN) SiS_Pr->SiS_CHPALN = TRUE;
-        	}
-        }
-  }
+		 }
 
-  SiS_Pr->SiS_VBInfo = tempbx;
+              } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* B-DH */
+	         /* This is actually bullshit. The B-DH bridge has cetainly no
+		  * Part4 Index 26, since it has no ability to drive LCD panels
+		  * at all. But as the BIOS does it, we do it, too...
+		  */
+	         if(HwInfo->jChipType == SIS_650) {
+	            if(!(SiS_IsNotM650or651(SiS_Pr,HwInfo))) {
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,0xef);
+	            }
+		    if((!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+		       (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
+	     	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+	            }
+		    SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+		 }
+	      }
 
-  if(HwDeviceExtension->jChipType == SIS_630) {
-       SiS_WhatIsThis(SiS_Pr, SiS_Pr->SiS_VBInfo);
-  }
+	      if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+	         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xef);
+	      }
 
-#ifdef TWDEBUG
-#ifdef LINUX_KERNEL
-  printk(KERN_DEBUG "sisfb: (VBInfo= 0x%04x, SetFlag=0x%04x)\n", 
-      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
-#endif
-#ifdef LINUX_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 3, "(init301: VBInfo=0x%04x, SetFlag=0x%04x)\n", 
-      SiS_Pr->SiS_VBInfo, SiS_Pr->SiS_SetFlag);
-#endif
-#endif
+              if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	         (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		 (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+	         tempah = 0x3f;
+	         if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+	            tempah = 0x7f;
+	            if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+		       tempah = 0xbf;
+                    }
+	         }
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+	      }
 
-#if 0  /* TW: Incomplete! (But does not seem to be required) */
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-     /* TW: From A901/630+301B BIOS */
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
-     }
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-         if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x80)
-	     if( [si] == 3) ModeIdIndex = 0x3f2b;
-	 }
-     }
-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
-     if(ModeNo == 0x13) bp+4 = 0x03;
-  } else {
-     /* From 650/30xLV BIOS: */
-     SiS_SetRegAND(SiS_Pr->SiS_P3d4, 0x31, 0xF7);
-     if(ModeNo == 0x13) bp+4 = 0x03;
-     else bp+4 = ModeNo;
-  }
-#endif
+              if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
 
-  /* TW: 630/301B and 650/301 (not 301LV!) BIOSes do more here, but this seems for DOS mode */
+	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+		    (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		    (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+		    SiS_DisplayOff(SiS_Pr);
+		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+		 } else {
+	            SiS_DisplayOff(SiS_Pr);
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
+		    if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
+		       SiS_DisplayOff(SiS_Pr);
+	               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	               SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	               temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+                       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	               SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
+		    }
+		 }
 
-}
+	      } else {
 
-void
-SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo)
-{
-   unsigned long eax, temp;
-   unsigned short temp1;
+	         if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+		    (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		    (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		    if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+		       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+		       SiS_DisplayOff(SiS_Pr);
+		    }
+		    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+		 } else {
+                    SiS_DisplayOff(SiS_Pr);
+	            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+		 }
 
-   if(!(SiS_Pr->SiS_ChSW)) return;
+		 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
+	         temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
+	         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
 
-#ifndef LINUX_XF86
-   SiS_SetReg4(0xcf8,0x80000874);
-   eax = SiS_GetReg3(0xcfc);
-#else
-   eax = pciReadLong(0x00000800, 0x74);
-#endif
-   eax &= 0xFFFF;
-   temp = eax;
-   eax += 0x3c;
-   temp1 = SiS_GetReg4((USHORT)eax);
-   temp1 &= 0xFEFF;
-   SiS_SetReg5((USHORT)eax, temp1);
-   temp1 = SiS_GetReg4((USHORT)eax);
-   eax = temp;
-   eax += 0x3a;
-   temp1 = SiS_GetReg4((USHORT)eax);
-   temp1 &= 0xFEFF;
-   if(!(myvbinfo & SetCRT2ToTV)) {
-      temp1 |= 0x0100;
-   }
-   SiS_SetReg5((USHORT)eax, temp1);
-   temp1 = SiS_GetReg4((USHORT)eax);
-}
+	      }
 
-void
-SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                   USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempax=0,tempbx=0;
-  USHORT temp1=0,modeflag=0,tempcx=0;
-  USHORT StandTableIndex,CRT1Index;
-#ifdef SIS315H   
-  USHORT ResInfo,DisplayType,temp=0;
-  const  SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr = NULL;
-#endif
+	      if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) &&
+	         (SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+		 (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
 
-  SiS_Pr->SiS_RVBHCMAX  = 1;
-  SiS_Pr->SiS_RVBHCFACT = 1;
+		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    		/* 1.10.8r, 8m */
 
-  if(ModeNo <= 0x13){
+	         tempah = 0x3f;
+	         if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+	            tempah = 0x7f;
+	            if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+		       tempah = 0xbf;
+                    }
+	         }
+	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	StandTableIndex = SiS_GetModePtr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex);
-    	tempax = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[0];
-    	tempbx = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[6];
-	temp1 = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[7];
+		 if(SiS_IsNotM650or651(SiS_Pr,HwInfo)) {   			/* 1.10.8r, 8m */
+	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		 }								/* 1.10.8r, 8m */
 
-  } else {
+	         if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
+	         }
 
-     if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) ) {
-
-#ifdef SIS315H     
-    	temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-			RefreshRateTableIndex,&ResInfo,&DisplayType);
-
-    	if(temp == 0)  return;
-
-    	switch(DisplayType) {
-    		case 0 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1;		break;
-    		case 1 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-    		case 2 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1;         break;
-    		case 3 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_1_H;         break;
-    		case 4 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1_H;        break;
-    		case 5 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_1_H;       break;
-    		case 6 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2;           break;
-    		case 7 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2;          break;
-    		case 8 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2;         break;
-    		case 9 : LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1800x600_2_H;         break;
-    		case 10: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_2_H;        break;
-    		case 11: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x1024_2_H;       break;
-		case 12: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1;           break;
-		case 13: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1XXXxXXX_1_H;         break;
-		case 14: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1;         break;
-		case 15: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_1_H;       break;
-		case 16: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2;         break;
-		case 17: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11400x1050_2_H;       break;
-    		case 18: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UNTSC;               break;
-    		case 19: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1ONTSC;               break;
-    		case 20: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1UPAL;                break;
-    		case 21: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
-    		case 22: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1320x480_1;           break;
-		case 23: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1;          break;
-    		case 24: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_1_H;        break;
-    		case 25: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2;          break;
-    		case 26: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x600_2_H;        break;
-    		case 27: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1;          break;
-    		case 28: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_1_H;        break;
-    		case 29: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2;          break;
-    		case 30: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11152x768_2_H;        break;
-		case 36: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1;         break;
-		case 37: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_1_H;       break;
-		case 38: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2;         break;
-		case 39: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11600x1200_2_H;       break;
-		case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1OPAL;                break;
-		default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
-    	}
-	tempax = (LVDSCRT1Ptr+ResInfo)->CR[0];
-	tempax |= (LVDSCRT1Ptr+ResInfo)->CR[14] << 8;
-	tempax &= 0x03FF;
-    	tempbx = (LVDSCRT1Ptr+ResInfo)->CR[6];
-    	tempcx = (LVDSCRT1Ptr+ResInfo)->CR[13] << 8;
-    	tempcx &= 0x0100;
-    	tempcx <<= 2;
-    	tempbx |= tempcx;
-	temp1  = (LVDSCRT1Ptr+ResInfo)->CR[7];
-#endif	
+	         if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+	            if(!(SiS_CRT2IsLCD(SiS_Pr,HwInfo))) {
+	               if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+		          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+                       }
+                    }
+	         }
 
-    } else {
+	         SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
 
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-#if 0   /* Not any longer */	
-	if(HwDeviceExtension->jChipType < SIS_315H)  CRT1Index &= 0x3F;
-#endif	
-	tempax = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[0];
-	tempax |= SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14] << 8;
-        tempax &= 0x03FF;
-    	tempbx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[6];
-    	tempcx = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13] << 8;
-    	tempcx &= 0x0100;
-    	tempcx <<= 2;
-    	tempbx |= tempcx;
-	temp1  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+  	      } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
 
-    }
+	         if(HwInfo->jChipType == SIS_650) {
+		    if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+		       (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
+		       if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
+		          (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
+			  SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	     	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+			  SiS_PanelDelay(SiS_Pr, HwInfo, 4);
+	               }
+		    }
+		 }
 
-  }
-
-  if(temp1 & 0x01) tempbx |= 0x0100;
-  if(temp1 & 0x20) tempbx |= 0x0200;
-  
-  tempax += 5;
-
-  /* Charx8Dot is no more used (and assumed), so we set it */
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-      modeflag |= Charx8Dot;
-  }
-
-  if(modeflag & Charx8Dot) tempax *= 8;
-  else                     tempax *= 9;
-
-  /* TW: From 650/30xLV 1.10.6s */
-  if(modeflag & HalfDCLK)  tempax <<= 1;
-
-  SiS_Pr->SiS_VGAHT = SiS_Pr->SiS_HT = tempax;
-  tempbx++;
-  SiS_Pr->SiS_VGAVT = SiS_Pr->SiS_VT = tempbx;
-}
-
-void
-SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-{
-  if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2f,0x01);
-  else
-    	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01);
-}
-
-void
-SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-{
-  if(HwDeviceExtension->jChipType >= SIS_315H)
-    	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2F,0xFE);
-  else
-     	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x24,0xFE);
-}
-
-void
-SiS_EnableCRT2(SiS_Private *SiS_Pr)
-{
-  SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
-}
-
-/* Checked against all BIOSes */
-void
-SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT tempah,pushax=0,modenum;
-#endif
-  USHORT temp=0;
-  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
-
-  if (SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-
-      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ===== TW: For 30xB/LV ===== */
-
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-
-#ifdef SIS300	   /* 300 series */
-
-           if(HwDeviceExtension->jChipType == SIS_300) {  /* New for 300+301LV */
-
-	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-	         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-		    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		 }
-	      }
-	      if(SiS_Is301B(SiS_Pr,BaseAddr)) {
-	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
-	         SiS_ShortDelay(SiS_Pr,1);
-	      }
-	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-	      SiS_DisplayOff(SiS_Pr);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	      if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
-	          (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
-	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
-	      }
-
-	   } else {
-
-	      if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-	         SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-	      }
-	      if(SiS_Is301B(SiS_Pr,BaseAddr)) {
-	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0x3f);
-	         SiS_ShortDelay(SiS_Pr,1);
-	      }
-	      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-	      SiS_DisplayOff(SiS_Pr);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
-	      if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
-	          (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
-	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-                 SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
-	      }
-	   }
-
-#endif  /* SIS300 */
-
-        } else {
-
-#ifdef SIS315H	   /* 310/325 series */
-
-           if(IS_SIS650740) {		/* 650, 740 */
-
-#if 0
-	      if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-#endif
-
-	      modenum = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-
-              if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	      
-	         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-		 
-		 if( (modenum <= 0x13) ||
-		     (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		     (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-	         }
-		 SiS_DDC2Delay(SiS_Pr,0xff00);
-		 SiS_DDC2Delay(SiS_Pr,0x6000);
-		 SiS_DDC2Delay(SiS_Pr,0x8000);
-
-	         SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-
-                 pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-		 
-		 if(IS_SIS740) {
-		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-		 }
-
-	         SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		 
-		 if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            tempah = 0xef;
-	            if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	               tempah = 0xf7;
-                    }
-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
-	         }
-
-              }
-
-              if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-	         tempah = 0x3f;
-	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	            tempah = 0x7f;
-	            if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		       tempah = 0xbf;
-                    }
-	         }
-	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-	      }
-
-              if((SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	         ((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13))) {
-
-	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-		    SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-		    SiS_DisplayOff(SiS_Pr);
-		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-		 } else {
-	            SiS_DisplayOff(SiS_Pr);
-	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-		    if((SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && (modenum <= 0x13)) {
-		       SiS_DisplayOff(SiS_Pr);
-	               SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	               SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	               temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	               SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	               SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+	      } else if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	                (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+			(SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+
+	         if(HwInfo->jChipType == SIS_650) {
+		    if(!(SiS_IsNotM650or651(SiS_Pr,HwInfo))) {
+	               tempah = 0xef;
+	               if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+		          if(modenum > 0x13) {
+	                     tempah = 0xf7;
+			  }
+                       }
+	               SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x4c,tempah);
 		    }
-		 }
-
-	      } else {
-
-	         if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-		    if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		       SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-		       SiS_DisplayOff(SiS_Pr);
+		    if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		       (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		       if((SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+		          (!(SiS_IsDualEdge(SiS_Pr,HwInfo)))) {
+		          if((!(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo))) ||
+		             (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo)))) {
+			     SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	     	             SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+			     SiS_PanelDelay(SiS_Pr, HwInfo, 4);
+	                  }
+		       }
 		    }
-		    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-		    SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-		    temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	            SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
-		 } else {
-                    SiS_DisplayOff(SiS_Pr);
-	            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	            SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	            temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	            SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	            SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
 		 }
 
 	      }
 
-	      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-
-		 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,~0x10);    /* 1.10.8r */
-		 
-	         tempah = 0x3f;
-	         if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	            tempah = 0x7f;
-	            if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		       tempah = 0xbf;
-                    }
-	         }
-	         SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-
-		 if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {   /* 1.10.8r */
-	            SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		 }								/* 1.10.8r */
-
-	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-	         }
-
-	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	               if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		          SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
-                       }
-                    }
-	         }
-
-	         SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-
-  	      }
-
-#if 0
-          } else if(IS_SIS740) {	/* 740 */
-	  
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {   /* 30xLV */
-	     
-	        if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-		    (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	     	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-	        }
-		
-		SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-
-                pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-		
-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-
-	        SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		
-		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		   SiS_DisplayOff(SiS_Pr);
-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1E,0xDF);
-		} else {
-		   SiS_DisplayOff(SiS_Pr);
-	           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-	           temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	           SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	           SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
-		}
-		
-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
-		SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0xEF);  /* (from 650) */
-		
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		
-		if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xdf);
-	        }
-		
-		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	              if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	                 if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		            SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
-                         }
-                      }
-	           }
-		}
-	        SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	     
-	     } else {	/* (301,) 301B */
-	  
-	        if(SiS_Is301B(SiS_Pr,BaseAddr)) {
-	           SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,0x3F);
-	        }
-	     
-	        SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
-	        SiS_DisplayOff(SiS_Pr);
-	        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
-
-	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-                SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
-	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
-		
-	     }
-#endif	  
 	  } else {			/* 315, 330 - all bridge types */
 
-	     if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	     if(SiS_Is301B(SiS_Pr)) {
 	        tempah = 0x3f;
-	        if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	        if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
 	           tempah = 0x7f;
-	           if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	           if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
 		      tempah = 0xbf;
                    }
 	        }
 	        SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1F,tempah);
-	        if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	        if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
 	           SiS_DisplayOff(SiS_Pr);
 		   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 	        }
 	     }
-	     if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
-	         (!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+	     if( (!(SiS_Is301B(SiS_Pr))) ||
+	         (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
 
- 	 	if( (!(SiS_Is301B(SiS_Pr,BaseAddr))) ||
-		    (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ) {
+ 	 	if( (!(SiS_Is301B(SiS_Pr))) ||
+		    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ) {
 
 	           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);
 	           SiS_DisplayOff(SiS_Pr);
@@ -5180,10 +3919,10 @@
 
                 SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-	        temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+	        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
 	        SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+	        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
 
 	     }
 
@@ -5193,69 +3932,74 @@
 
 	}
 
-      } else {     /* ============ TW: For 301 ================ */
+      } else {     /* ============ For 301 ================ */
 
-        if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-	    }
+        if(HwInfo->jChipType < SIS_315H) {
+           if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+	   }
 	}
 
         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xDF);           /* disable VB */
         SiS_DisplayOff(SiS_Pr);
 
-        if(HwDeviceExtension->jChipType >= SIS_315H) {
-            SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+        if(HwInfo->jChipType >= SIS_315H) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
 	}
 
         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);                /* disable lock mode */
 
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-            temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
+	if(HwInfo->jChipType >= SIS_315H) {
+            temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x10);
 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
-	    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x00,temp);
+	    SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,temp);
 	} else {
             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);            /* disable CRT2 */
+	    if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+	        (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
+		SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	    }
 	}
 
       }
 
-  } else {     /* ============ TW: For LVDS =============*/
+  } else {     /* ============ For LVDS =============*/
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
 
 #ifdef SIS300	/* 300 series */
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-	    SiS_SetCH700x(SiS_Pr,0x090E);
+	   SiS_SetCH700x(SiS_Pr,0x090E);
 	}
 
-	if(HwDeviceExtension->jChipType == SIS_730) {
-	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
-	      SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+	if(HwInfo->jChipType == SIS_730) {
+	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+	      SiS_WaitVBRetrace(SiS_Pr,HwInfo);
 	   }
-	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	   if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
 	      SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	      SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+	      SiS_PanelDelay(SiS_Pr, HwInfo, 3);
 	   }
 	} else {
-	   if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
+	   if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x08)) {
 
-	      if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-  
-  	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
+	      if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
 
-                     SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+  	         if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
 
-		     if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
-		         SiS_DisplayOff(SiS_Pr);
-	             }
+                    SiS_WaitVBRetrace(SiS_Pr,HwInfo);
 
-	             SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-	             SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-                  }
+		    if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x06) & 0x1c)) {
+		       SiS_DisplayOff(SiS_Pr);
+	            }
+
+	            SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	            SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+                 }
               }
 	   }
 	}
@@ -5265,118 +4009,134 @@
 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
+	SiS_UnLockCRT2(SiS_Pr,HwInfo);
 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80);
 	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40);
 
-	if( (!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ||
-	              (!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) ) {
-		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	if( (!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ||
+	    (!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) ) {
+	   SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
 	}
 
 #endif  /* SIS300 */
 
     } else {
 
-#ifdef SIS315H	/* 310/325 series */
+#ifdef SIS315H	/* 315 series */
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-		temp = SiS_GetCH701x(SiS_Pr,0x61);
-		if(temp < 1) {
-		   SiS_SetCH701x(SiS_Pr,0xac76);
-		   SiS_SetCH701x(SiS_Pr,0x0066);
-		}
-		
-		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-			SiS_SetCH701x(SiS_Pr,0x3e49);
-		} else if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-			SiS_SetCH701x(SiS_Pr,0x3e49);
-		}
-		
-		if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr);
-		} else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-			SiS_Chrontel701xBLOff(SiS_Pr);
-			SiS_Chrontel701xOff(SiS_Pr);
-		}
-		
+
+	   if(HwInfo->jChipType == SIS_740) {
+	      temp = SiS_GetCH701x(SiS_Pr,0x61);
+	      if(temp < 1) {
+	         SiS_SetCH701x(SiS_Pr,0xac76);
+	         SiS_SetCH701x(SiS_Pr,0x0066);
+	      }
+
+	      if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	          (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
+	  	 SiS_SetCH701x(SiS_Pr,0x3e49);
+	      }
+	   }
+
+	   if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	       (SiS_IsVAMode(SiS_Pr,HwInfo)) ) {
+	      SiS_Chrontel701xBLOff(SiS_Pr);
+	      SiS_Chrontel701xOff(SiS_Pr,HwInfo);
+	   }
+
+	   if(HwInfo->jChipType != SIS_740) {
+	      if( (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	          (SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) ) {
+	   	 SiS_SetCH701x(SiS_Pr,0x0149);
+  	      }
+	   }
+
 	}
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
-		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
+	   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x08);
+	   SiS_PanelDelay(SiS_Pr, HwInfo, 3);
 	}
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_DisplayOff(SiS_Pr);
-	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_DisplayOff(SiS_Pr);
-	} else if(!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_DisplayOff(SiS_Pr);
+	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
+	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	    (!(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo))) ) {
+	   SiS_DisplayOff(SiS_Pr);
 	}
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
-	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
+	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x00,0x80);
+	}
+
+	if(HwInfo->jChipType == SIS_740) {
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
 	}
 
 	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x32,0xDF);
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
-	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
+	if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
+	    (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+	    (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+	   SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x1E,0xDF);
 	}
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-	        if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
-		}
-	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	   if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	      if(HwInfo->jChipType == SIS_550) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xbf);
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xef);
+	      }
+	   }
+	} else {
+	   if(HwInfo->jChipType == SIS_740) {
+	      if(SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) {
+	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	      }
+	   } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x1e,0xdf);
+	   }
 	}
 
 	if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-	    	if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff);
-		} else {
-			SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
-		}
+	   if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+	      /* SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xff); */
+	   } else {
+	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xfb);
+	   }
 	}
 
-	SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+	SiS_UnLockCRT2(SiS_Pr,HwInfo);
 
-	if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
-	} else if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
-	} else if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-		SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
+	if(HwInfo->jChipType == SIS_550) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x01,0x80); /* DirectDVD PAL?*/
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x02,0x40); /* VB clock / 4 ? */
+	} else if( (SiS_Pr->SiS_IF_DEF_CH70xx == 0)   ||
+	           (!(SiS_IsDualEdge(SiS_Pr,HwInfo))) ||
+		   (!(SiS_IsVAMode(SiS_Pr,HwInfo))) ) {
+	   SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 	}
 
-#if 0  /* TW: BIOS code makes no sense */
-       if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-		  /* Nothing there! */
-		}
-           }
+#if 0  /* BIOS code makes no sense */
+       if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+          if(!(SiS_IsDualEdge(SiS_Pr,HwInfo))) {
+	     if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+		/* Nothing there! */
+	     }
+          }
        }
 #endif
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-		if(SiS_CRT2IsLCD(SiS_Pr, BaseAddr,HwDeviceExtension)) {
-			if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-				SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-				SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
-			}
-		}
+	  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+		SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+		SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xFB,0x04);
+	     }
+	  }
        }
 
 #endif  /* SIS315H */
@@ -5387,44 +4147,51 @@
 
 }
 
-/* TW: Checked against all BIOSes */
+/*********************************************/
+/*            ENABLE VIDEO BRIDGE            */
+/*********************************************/
+
+/* NEVER use any variables (VBInfo), this will be called
+ * from outside the context of modeswitch!
+ * MUST call getVBType before calling this
+ */
 void
-SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp=0,tempah;
 #ifdef SIS315H
   USHORT temp1,pushax=0;
   BOOLEAN delaylong = FALSE;
 #endif
-  UCHAR *ROMAddr = HwDeviceExtension->pjVirtualRomBase;
+
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* TW: ====== For 301B et al  ====== */
+    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {   /* ====== For 301B et al  ====== */
 
-      if(HwDeviceExtension->jChipType < SIS_315H) {
+      if(HwInfo->jChipType < SIS_315H) {
 
 #ifdef SIS300     /* 300 series */
 
-         if(HwDeviceExtension->jChipType == SIS_300) {
+         if(HwInfo->jChipType == SIS_300) {
 
-	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 
+	    if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
 	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-	          if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
-	             SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+	          if(!(SiS_CR36BIOSWord23d(SiS_Pr, HwInfo))) {
+	             SiS_PanelDelay(SiS_Pr, HwInfo, 0);
 	          }
 	       }
 	    }
-	    temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+	    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
             if(SiS_BridgeInSlave(SiS_Pr)) {
-               tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
                if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
             }
-            SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+            SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 	    SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
-	    if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	    if(SiS_Is301B(SiS_Pr)) {
                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
 	       SiS_DisplayOn(SiS_Pr);
 	    } else {
@@ -5432,14 +4199,14 @@
 	       SiS_DisplayOn(SiS_Pr);
 	       SiS_VBLongWait(SiS_Pr);
 	    }
-	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-		  if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-		     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-		           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+	    if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+		  if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+		     if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+		           SiS_PanelDelay(SiS_Pr, HwInfo, 1);
                      }
-		     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) { 
-		         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
+		     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+		         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
 	 	     }
 		  }
                }
@@ -5448,41 +4215,41 @@
 	 } else {
 
 	    if((SiS_Pr->SiS_VBType & VB_NoLCD) &&
-	       (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
+	       (SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
 	       /* This is only for LCD output on 301B-DH via LVDS */
 	       SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
-	       if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
-	          SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
+	       if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 0);
 	       }
 	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);   /* Enable CRT2 */
 /*	       DoSomeThingPCI_On(SiS_Pr) */
                SiS_DisplayOn(SiS_Pr);
-	       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+	       SiS_UnLockCRT2(SiS_Pr,HwInfo);
 	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
 	       if(SiS_BridgeInSlave(SiS_Pr)) {
       		  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
       	       } else {
       		  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
                }
-	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-	           if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-		       if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-		           SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
+	       if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+	           if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+		       if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+		           SiS_PanelDelay(SiS_Pr, HwInfo, 1);
                        }
-		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
+		       SiS_WaitVBRetrace(SiS_Pr,HwInfo);
                        SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF7,0x00);
                    }
 	       }
             } else {
-	       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
+	       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;             /* lock mode */
                if(SiS_BridgeInSlave(SiS_Pr)) {
-                  tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
+                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
                   if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
                }
-               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);
 	       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);        /* enable VB processor */
-	       if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	       if(SiS_Is301B(SiS_Pr)) {
                   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
 	          SiS_DisplayOn(SiS_Pr);
 	       } else {
@@ -5497,284 +4264,353 @@
 
       } else {
 
-#ifdef SIS315H    /* 310/325 series */
+#ifdef SIS315H    /* 315 series */
 
-	 if(IS_SIS650740) {		/* 650 */
-
-#if 0
-	    if(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00) != 1) return;	/* From 1.10.7w */
-#endif
+	 if(IS_SIS550650740660) {		/* 550, 650, 740, 660 */
 
 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    
-	       SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);  /* 1.10.7u */
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);    /* 1.10.7u */
+
+	       if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x1f,0xef);  /* 1.10.7u */
+#ifdef SET_EMI
+		  if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);    /* 1.10.7u */
+		  }
+#endif
+	       }
 
 	       if(!(IS_SIS740)) {
-                  if(!(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+                  if(!(SiS_IsNotM650or651(SiS_Pr,HwInfo))) {
 	             tempah = 0x10;
-	             if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	                tempah = 0x08;
-                     }
-	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		     if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
+			   if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
+			      tempah = 0x08;
+			   } else {
+			      tempah = 0x18;
+			   }
+			}
+			SiS_SetReg(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		     } else {
+	                if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	                   tempah = 0x08;
+                        }
+			SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		     }
 	          }
 	       }
 
-	       SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-	       SiS_DisplayOff(SiS_Pr);
-	       pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-	       if(IS_SIS740) {
-	          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+	       if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          SiS_SetRegByte(SiS_Pr->SiS_P3c6,0x00);
+	          SiS_DisplayOff(SiS_Pr);
+	          pushax = SiS_GetReg(SiS_Pr->SiS_P3c4,0x06);
+	          if(IS_SIS740) {
+	             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
+	          }
 	       }
 
-	       if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	           (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-		      SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
-		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-	              SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 2);
-	           }
+	       if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	           (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+                  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+		     if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+		        (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+		        SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+		     }
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+	             SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 2);
+	          }
 	       }
 
-	       if(!(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
-                  SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		  delaylong = TRUE;
+               if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          if(!(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x40)) {
+                     SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+		     delaylong = TRUE;
+		  }
 	       }
 
-	    }
-
-	    if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-               temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	       if(SiS_BridgeInSlave(SiS_Pr)) {
-                  tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-               }
-               SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	    } else if(SiS_Pr->SiS_VBType & VB_NoLCD) {
 
-	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
-	       
-	       if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-		  temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
-		  if(!(temp & 0x80)) {
-		     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+	       if(HwInfo->jChipType == SIS_650) {
+	          if(!(SiS_IsNotM650or651(SiS_Pr,HwInfo))) {
+	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,0x10);
+	          }
+		  if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+		      (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+		     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+		     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
 		  }
-	       } else {
-	          SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
 	       }
-	    }
 
-	    if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
+  	    } else if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+
+	       if(HwInfo->jChipType == SIS_650) {
+		  if(!(SiS_IsNotM650or651(SiS_Pr,HwInfo))) {
+	             tempah = 0x10;
+		     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {
+		        tempah = 0x18;
+		        if((SiS_GetReg(SiS_Pr->SiS_Part2Port,0x00) & 0x0f) == 0x0c) {
+			   tempah = 0x08;
+			}
+		     }
+	             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x4c,tempah);
+		  }
+	       }
+
+	    }
+
+	    if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+               temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	       if(SiS_BridgeInSlave(SiS_Pr)) {
+                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+                  if(!(tempah & SetCRT2ToRAMDAC)) {
+		     if((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		        (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+		        if(!(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04)) temp |= 0x20;
+		     } else temp |= 0x20;
+		  }
+               }
+               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
+
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+
+	       if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	          (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+		  (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+		  temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
+		  if(!(temp & 0x80)) {
+		     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+		  }
+	       } else {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	       }
+	    }
+
+	    if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x20);
 	    }
 
 	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
 
-	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
-	       temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2e);
+	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	       (SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+	       (SiS_Pr->SiS_CustomT == CUT_CLEVO1400)) {
+	       temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2e);
 	       if(!(temp & 0x80)) {
 		  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
 	       }
 	    }
 
 	    tempah = 0xc0;
-	    if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+	    if(SiS_IsDualEdge(SiS_Pr, HwInfo)) {
 	       tempah = 0x80;
-	       if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
+	       if(!(SiS_IsVAMode(SiS_Pr, HwInfo))) {
 	          tempah = 0x40;
                }
 	    }
             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-	    if(SiS_Pr->SiS_VBType & VB_SIS301B302B) {
+	    if((SiS_Pr->SiS_VBType & VB_SIS301B302B) ||
+	       (((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) ||
+	         (SiS_Pr->SiS_CustomT == CUT_CLEVO1400))     &&
+	        (!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))))) {
                SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
 	    }
 
 	    if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);	/* All this from 1.10.7u */
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);  
-	       SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
-	       
-	       SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	    
-	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);  /* 1.10.8r */
 
-	       SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+	       if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
+#ifdef SET_EMI
+	          if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);	  /* All this from 1.10.7u */
+		  }
+#endif
+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
+#ifdef SET_EMI
+		  if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	             SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
+		  }
+#endif
+	       }
 
-	       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	          if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	              ((SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) ) {
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    if(delaylong) {
-			SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    }
-                    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-	         }
-	      }
+	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
 
-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	      SiS_DisplayOn(SiS_Pr);
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
+#ifdef SET_EMI
+	          if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,0x08);
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,0x10);
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,0x4d);
+		     if((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x02) {
+		        SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,0x0d);
+	                SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,0x70);
+	                SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,0x6b);
+		     }
+		     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+		  }
+#endif
 
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      }
-#if 0
-              SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x0c);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x20);
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x31,0x05);   /* 1.10.8r: 0x0d */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x32,0x60);   /* 1.10.8r: 0x70 */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x33,0x00);   /* 1.10.8r: 0x40 */
-	      SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10); 
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40); 
-#endif	      
+	       } else if(SiS_Pr->SiS_CustomT != CUT_CLEVO1400) {
 
-	  }
+#ifdef SET_EMI
+	          if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,0x12);
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,0xd0);
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,0x6b);
+	             if((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) == 0x02) {  /* Acer */
+	                SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,0x0d);
+	                SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,0x70);
+	                SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,0x40);
+		        if(((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) != 0x30)) {  /* Acer */
+		           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x31,0x05);
+	                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x32,0x60);
+	                   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x33,0x33);  /* 00 */
+		        }
+	             }
+	             SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	             if((SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) != 0x03) {
+	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+	             }
+		  }
+#endif
+	       }
 
-#if 0
-         } else if(IS_SIS740) {		/* 740 */
-	 
-	   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {  /* 30xLV */
-	   
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0x00);
-	      SiS_DisplayOff(SiS_Pr);
-	      pushax = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x06);
-	      SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x06,0xE3);
-	      
-	      if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	          (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-                   if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-		      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-	              SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 3);
-		   }
-	      }
-	      
-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	         if(SiS_BridgeInSlave(SiS_Pr)) {
-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-                 }
-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	       if((SiS_Pr->SiS_CustomT != CUT_COMPAQ1280) &&
+	          (SiS_Pr->SiS_CustomT != CUT_CLEVO1400)) {
+	          SiS_PanelDelay(SiS_Pr, HwInfo, 2);
+	       }
 
-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);  	
-		 SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 2);
-	      }
-	      
-	      if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	         SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	      }
-	      
-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0x10);  /* (taken from 650 1.10.8r) */
-	      SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-	      
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-	             (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x40) {
-		       SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-		    }
-		    SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xfe,0x01);
-		    SiS_SetPanelDelayLoop(SiS_Pr,ROMAddr, HwDeviceExtension, 3, 10);
-		    SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-	         }
-              }
-	      
-	      SiS_SetReg1(SiS_Pr->SiS_P3c4,0x06,pushax);
-	      SiS_DisplayOn(SiS_Pr);
-	      SiS_SetReg3(SiS_Pr->SiS_P3c6,0xff);
-	      
-	      if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      }
-	   
-	   } else {	/* (301), 301B */
-	 
-	      if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	         temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	         if(SiS_BridgeInSlave(SiS_Pr)) {
-                    tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                    if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-                 }
-                 SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	       SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1f,0x10);
 
-	         SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+	       if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
 
-	         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-                 if(!(temp & 0x80))
-                    SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-              }
+	          if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	              (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+		     SiS_DisplayOn(SiS_Pr);
+		     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+		     SiS_WaitVBRetrace(SiS_Pr, HwInfo);
+		     SiS_PanelDelay(SiS_Pr, HwInfo, 3);
+#ifdef SET_EMI
+		     if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	                SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x30,0x40);
+		     }
+#endif
+		     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+	  	     }
+		  }
 
-	      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+	       } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1400) {
 
-	      if(SiS_Is301B(SiS_Pr,BaseAddr)) { 
-	         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0);
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
-	      } else {
-	         SiS_VBLongWait(SiS_Pr);
-                 SiS_DisplayOn(SiS_Pr);
-	         SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
-                 SiS_VBLongWait(SiS_Pr);
-	      }
-	      
-	   }
+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+	             if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
+	                 (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+		        SiS_DisplayOn(SiS_Pr);
+		        SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+		        SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+		     }
+		  }
+
+	       } else {
+
+	          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2e,0x80);
+
+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+	             if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	                 ((SiS_CRT2IsLCD(SiS_Pr, HwInfo))) ) {
+		        SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+		        if(delaylong) {
+			   SiS_PanelDelayLoop(SiS_Pr, HwInfo, 3, 10);
+		        }
+                        SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+	             }
+	          }
+
+	          SiS_SetReg(SiS_Pr->SiS_P3c4,0x06,pushax);
+	          SiS_DisplayOn(SiS_Pr);
+	          SiS_SetRegByte(SiS_Pr->SiS_P3c6,0xff);
+
+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+	             SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	          }
+
+	       }
+
+#if 0
+	       /* RDirectLCDN */
+	       if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
+	           (SiS_IsDualEdge(SiS_Pr, HwInfo)) ) {
+	          tempah = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
+	          SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
+		  SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+	          SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7f);
+	          SiS_SetReg(SiS_Pr->SiS_Part4Port,0x23,tempah);
+	       }
 #endif
-	  
+
+	    } if(SiS_Pr->SiS_VBType & VB_NoLCD) {
+
+	       if(HwInfo->jChipType == SIS_650) {
+	          if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+		     if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+		         (SiS_CRT2IsLCD(SiS_Pr, HwInfo)) ) {
+			SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+		        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+		     }
+		  }
+	       }
+
+  	    }
+
 	 } else {			/* 315, 330 */
 
-	   if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	      temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
-	      if(SiS_BridgeInSlave(SiS_Pr)) {
-                 tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-                 if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
-              }
-              SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+	    if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+	       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;
+	       if(SiS_BridgeInSlave(SiS_Pr)) {
+                  tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+                  if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+               }
+               SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
-	      SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
+	       SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                   /* enable CRT2 */
 
-	      temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-              if(!(temp & 0x80))
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-           }
+	       temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+               if(!(temp & 0x80))
+                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+            }
 
-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
+	    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1f,0x20);
 
-	   if(SiS_Is301B(SiS_Pr,BaseAddr)) {
+	    if(SiS_Is301B(SiS_Pr)) {
 
-	      temp=SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-              if (!(temp & 0x80))
-                 SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
-
-	      tempah = 0xc0;
-	      if(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	         tempah = 0x80;
-	         if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-	            tempah = 0x40;
-                 }
-	      }
-              SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
+	       temp=SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+               if(!(temp & 0x80))
+                  SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+
+	       tempah = 0xc0;
+	       if(SiS_IsDualEdge(SiS_Pr,HwInfo)) {
+	          tempah = 0x80;
+	          if(!(SiS_IsVAMode(SiS_Pr,HwInfo))) {
+	             tempah = 0x40;
+                  }
+	       }
+               SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x1F,tempah);
 
-	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
 
-	   } else {
-	   
-	      SiS_VBLongWait(SiS_Pr);
-              SiS_DisplayOn(SiS_Pr);
-	      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
-              SiS_VBLongWait(SiS_Pr);
+	    } else {
 
-	   }
+	       SiS_VBLongWait(SiS_Pr);
+               SiS_DisplayOn(SiS_Pr);
+	       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7F);
+               SiS_VBLongWait(SiS_Pr);
+
+	    }
 
 	 }   /* 315, 330 */
 
@@ -5782,100 +4618,102 @@
 
       }
 
-    } else {	/* ============  TW: For 301 ================ */
+    } else {	/* ============  For 301 ================ */
 
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x0B);
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
-	    }
+       if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+	  }
        }
 
-       temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x32) & 0xDF;          /* lock mode */
        if(SiS_BridgeInSlave(SiS_Pr)) {
-         tempah = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-         if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
+          tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x30);
+          if(!(tempah & SetCRT2ToRAMDAC))  temp |= 0x20;
        }
-       SiS_SetReg1(SiS_Pr->SiS_P3c4,0x32,temp);
+       SiS_SetReg(SiS_Pr->SiS_P3c4,0x32,temp);
 
        SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x1E,0x20);                  /* enable CRT2 */
 
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
-         temp = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-         if(!(temp & 0x80))
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
+       if(HwInfo->jChipType >= SIS_315H) {
+          temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+          if(!(temp & 0x80)) {
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);         /* BVBDOENABLE=1 */
+	  }
        }
 
        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x00,0x1F,0x20);     /* enable VB processor */
 
        SiS_VBLongWait(SiS_Pr);
        SiS_DisplayOn(SiS_Pr);
-       if(HwDeviceExtension->jChipType >= SIS_315H) {
-           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       if(HwInfo->jChipType >= SIS_315H) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
        }
        SiS_VBLongWait(SiS_Pr);
 
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-            if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-                SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x11,0xF0,0x03);
-	    }
+       if(HwInfo->jChipType < SIS_315H) {
+          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+             SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+	  }
        }
 
     }
 
-  } else {   /* =================== TW: For LVDS ================== */
+  } else {   /* =================== For LVDS ================== */
 
-    if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(HwInfo->jChipType < SIS_315H) {
 
 #ifdef SIS300    /* 300 series */
 
-      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-         if(HwDeviceExtension->jChipType == SIS_730) {
-	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-	 }
-         SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
-	 if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwDeviceExtension))) {
-	    SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 0);
-	 }
-      }
+       if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+          if(HwInfo->jChipType == SIS_730) {
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+	  }
+          SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	  if(!(SiS_CR36BIOSWord23d(SiS_Pr,HwInfo))) {
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+	  }
+       }
 
-      SiS_EnableCRT2(SiS_Pr);
-      SiS_DisplayOn(SiS_Pr);
-      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
-      SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
-      if(SiS_BridgeInSlave(SiS_Pr)) {
-      	SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
-      } else {
-      	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
-      }
+       SiS_EnableCRT2(SiS_Pr);
+       SiS_DisplayOn(SiS_Pr);
+       SiS_UnLockCRT2(SiS_Pr,HwInfo);
+       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x02,0xBF);
+       if(SiS_BridgeInSlave(SiS_Pr)) {
+      	  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x01,0x1F);
+       } else {
+      	  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0x1F,0x40);
+       }
 
-      if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
-        if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-	        SiS_SetCH700x(SiS_Pr,0x0B0E);
-        }
-      }
+       if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+          if(!(SiS_CRT2IsLCD(SiS_Pr, HwInfo))) {
+	     SiS_WaitVBRetrace(SiS_Pr, HwInfo);
+	     SiS_SetCH700x(SiS_Pr,0x0B0E);
+          }
+       }
 
-      if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-          if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
-              if(!(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
-	          if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwDeviceExtension))) {
-			SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-        		SiS_SetPanelDelay(SiS_Pr,ROMAddr, HwDeviceExtension, 1);
-		  }
-		  SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-                  SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
-              }
+       if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+          if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x13) & 0x40)) {
+             if(!(SiS_GetReg(SiS_Pr->SiS_P3c4,0x16) & 0x10)) {
+	        if(!(SiS_CR36BIOSWord23b(SiS_Pr,HwInfo))) {
+	 	   SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+        	   SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+	        }
+	        SiS_WaitVBRetrace(SiS_Pr, HwInfo);
+                SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+             }
 	  }
-      }
+       }
 
 #endif  /* SIS300 */
 
     } else {
 
-#ifdef SIS315H    /* 310/325 series */
+#ifdef SIS315H    /* 315 series */
 
 #if 0  /* BIOS code makes no sense */
        if(SiS_IsVAMode()) {
@@ -5885,14 +4723,14 @@
 #endif
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-	    if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	     	SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
-	        SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 0);
-            }
+	  if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	     SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xFB);
+	     SiS_PanelDelay(SiS_Pr, HwInfo, 0);
+          }
        }
 
        SiS_EnableCRT2(SiS_Pr);
-       SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension, BaseAddr);
+       SiS_UnLockCRT2(SiS_Pr,HwInfo);
 
        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0xf7);
 
@@ -5902,72 +4740,72 @@
 	  SiS_Chrontel701xBLOff(SiS_Pr);
        }
 
-       SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
-       
-#ifdef NEWCH701x
-       if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-           if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension,BaseAddr)) {
+       if(HwInfo->jChipType != SIS_550) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2e,0x7f);
+       }
+
+       if(HwInfo->jChipType == SIS_740) {
+          if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+             if(SiS_IsLCDOrLCDA(SiS_Pr, HwInfo)) {
 	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	   }
+	     }
+	  }
        }
-#endif       
 
-       temp1 = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x2E);
-       if (!(temp1 & 0x80))
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+       temp1 = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x2E);
+       if(!(temp1 & 0x80)) {
+          SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2E,0x80);
+       }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-           if(temp) {
-	       SiS_Chrontel701xBLOn(SiS_Pr);
-	   }
+          if(temp) {
+	     SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
+	  }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-           if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-	   	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
-	   }
-       } 
-#ifndef NEWCH701x       
-         else if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+          if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+	     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+	     if(HwInfo->jChipType == SIS_550) {
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x40);
+		SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x10);
+	     }
+	  }
+       } else if(SiS_IsVAMode(SiS_Pr,HwInfo)) {
+          if(HwInfo->jChipType != SIS_740) {
+             SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x20);
+	  }
        }
-#endif       
 
-       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-           SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
+       if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+          SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x00,0x7f);
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-
-       		if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           		SiS_Chrontel701xOn(SiS_Pr,HwDeviceExtension, BaseAddr);
-         	}
-
-         	if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
-         	} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-           		SiS_ChrontelDoSomething1(SiS_Pr,HwDeviceExtension, BaseAddr);
-        	}
-
+       	  if(SiS_IsTVOrYPbPrOrScart(SiS_Pr,HwInfo)) {
+             SiS_Chrontel701xOn(SiS_Pr,HwInfo);
+          }
+          if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	      (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
+             SiS_ChrontelDoSomething1(SiS_Pr,HwInfo);
+          }
        }
 
        if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-       	 	if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
- 	   		if(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	            		SiS_Chrontel701xBLOn(SiS_Pr);
-	            		SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
-           		} else if(SiS_IsLCDOrLCDA(SiS_Pr,HwDeviceExtension, BaseAddr))  {
-       				SiS_Chrontel701xBLOn(SiS_Pr);
-       				SiS_ChrontelDoSomething4(SiS_Pr,HwDeviceExtension, BaseAddr);
-	   		}
-       		}
+       	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+ 	     if( (SiS_IsVAMode(SiS_Pr,HwInfo)) ||
+	         (SiS_IsLCDOrLCDA(SiS_Pr,HwInfo)) ) {
+	     	SiS_Chrontel701xBLOn(SiS_Pr, HwInfo);
+	     	SiS_ChrontelInitTVVSync(SiS_Pr,HwInfo);
+             }
+       	  }
        } else if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-       		if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-			if(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) {
-				SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, 1);
-				SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
-			}
-		}
+       	  if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo))) {
+	     if(SiS_CRT2IsLCD(SiS_Pr, HwInfo)) {
+		SiS_PanelDelay(SiS_Pr, HwInfo, 1);
+		SiS_SetRegAND(SiS_Pr->SiS_P3c4,0x11,0xF7);
+	     }
+	  }
        }
 
 #endif  /* SIS315H */
@@ -5978,1000 +4816,2391 @@
 
 }
 
-void
-SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*         SET PART 1 REGISTER GROUP         */
+/*********************************************/
+
+/********** Set CRT2 OFFSET / PITCH **********/
+static void
+SiS_SetCRT2Offset(SiS_Private *SiS_Pr,USHORT ModeNo,
+                  USHORT ModeIdIndex ,USHORT RefreshRateTableIndex,
+	          PSIS_HW_INFO HwInfo)
 {
-  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+  USHORT offset;
+  UCHAR temp;
 
-  /* TW: Switch on LCD backlight on SiS30xLV */
-  if( (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ||
-      (SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension)) ) {
-    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
-	SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
-	SiS_WaitVBRetrace(SiS_Pr,HwDeviceExtension);
-    }
-    if(!(SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
-        SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
-    }
-  }
-}
+  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) return;
 
-void
-SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT  BaseAddr = (USHORT)HwDeviceExtension->ulIOAddress;
+  offset = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                         HwInfo);
 
-  /* TW: Switch off LCD backlight on SiS30xLV */
-  if( (!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) ||
-      (SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr)) ) {
-	 SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFE,0x00);
-  }
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) offset >>= 1;
 
-  if(!(SiS_IsVAMode(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-      if(!(SiS_CRT2IsLCD(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-          if(!(SiS_IsDualEdge(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-  	      SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x26,0xFD,0x00);
-          }
-      }
-  }
+  temp = (UCHAR)(offset & 0xFF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,temp);
+  temp = (UCHAR)((offset & 0xFF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,temp);
+  temp = (UCHAR)(((offset >> 3) & 0xFF) + 1);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,temp);
 }
 
-BOOLEAN
-SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/************* Set CRT2 Sync *************/
+static void
+SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT RefreshRateTableIndex,
+                PSIS_HW_INFO HwInfo)
 {
-  USHORT temp,temp1;
-  UCHAR *ROMAddr;
+  USHORT tempah=0,tempbl,infoflag,flag;
+
+  flag = 0;
+  tempbl = 0xC0;
 
-  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-     temp >>= 4;
-     temp = 1 << temp;
-     temp1 = (ROMAddr[0x23c] << 8) | ROMAddr[0x23b];
-     if(temp1 & temp) return(1);
-     else return(0);
+  if(SiS_Pr->UseCustomMode) {
+     infoflag = SiS_Pr->CInfoFlag;
   } else {
-     return(0);
+     infoflag = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
   }
-}
 
-BOOLEAN
-SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT temp,temp1;
-  UCHAR *ROMAddr;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* LVDS */
 
-  if((ROMAddr = (UCHAR *)HwDeviceExtension->pjVirtualRomBase) && SiS_Pr->SiS_UseROM) {
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xff;
-     temp >>= 4;
-     temp = 1 << temp;
-     temp1 = (ROMAddr[0x23e] << 8) | ROMAddr[0x23d];
-     if(temp1 & temp) return(1);
-     else return(0);
-  } else {
-     return(0);
-  }
-}
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       tempah = 0;
+    } else if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) && (SiS_Pr->SiS_LCDInfo & LCDSync)) {
+       tempah = SiS_Pr->SiS_LCDInfo;
+    } else tempah = infoflag >> 8;
 
-void
-SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                      USHORT DelayTime, USHORT DelayLoop)
-{
-   int i;
-   for(i=0; i<DelayLoop; i++) {
-      SiS_SetPanelDelay(SiS_Pr, ROMAddr, HwDeviceExtension, DelayTime);
-   }
-}		     
+    tempah &= 0xC0;
 
-void
-SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                  USHORT DelayTime)
-{
-  USHORT PanelID, DelayIndex, Delay;
-#ifdef SIS300
-  USHORT temp;
-#endif
+    tempah |= 0x20;
+    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+          (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+	  tempah |= 0xc0;
+       }
+    }
 
-#ifdef SIS300
+    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       if(HwInfo->jChipType >= SIS_315H) {
+          tempah >>= 3;
+          SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xE7,tempah);
+       }
+    } else {
+       SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
+    }
 
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 300 series, LVDS */
+  } else {
 
-	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
+     if(HwInfo->jChipType < SIS_315H) {
 
-	  DelayIndex = PanelID >> 4;
+#ifdef SIS300  /* ---- 300 series --- */
 
-	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
-              Delay = 3;
-          } else {
-              if(DelayTime >= 2) DelayTime -= 2;
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {			/* 630 - 301B(-DH) */
 
-              if(!(DelayTime & 0x01)) {
-       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
-              } else {
-       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
-              }
-	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                  if(ROMAddr[0x220] & 0x40) {
-                      if(!(DelayTime & 0x01)) {
-	    	          Delay = (USHORT)ROMAddr[0x225];
-                      } else {
-	    	          Delay = (USHORT)ROMAddr[0x226];
-                      }
-                  }
-              }
-          }
-	  SiS_ShortDelay(SiS_Pr,Delay);
+            if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+               tempah = SiS_Pr->SiS_LCDInfo;
+	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+                  flag = 1;
+               }
+            }
+            if(flag != 1) tempah = infoflag >> 8;
+            tempah &= 0xC0;
 
-      } else {							/* 300 series, 301(B) */
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
 
-	  PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-	  temp = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x18);
-          if(!(temp & 0x10))  PanelID = 0x12;
+#if 0
+            if (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+	       	/* BIOS does something here @@@ */
+            }
+#endif
 
-          DelayIndex = PanelID >> 4;
+ 	    tempah &= 0x3f;
+  	    tempah |= tempbl;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-	  if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
-              Delay = 3;
-          } else {
-              if(DelayTime >= 2) DelayTime -= 2;
+         } else {							/* 630 - 301 */
 
-              if(!(DelayTime & 0x01)) {
-       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
-              } else {
-       		  Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
-              }
-	      if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                  if(ROMAddr[0x220] & 0x40) {
-                      if(!(DelayTime & 0x01)) {
-	    	          Delay = (USHORT)ROMAddr[0x225];
-                      } else {
-	    	          Delay = (USHORT)ROMAddr[0x226];
-                      }
-                  }
-              }
-          }
-	  SiS_ShortDelay(SiS_Pr,Delay);
+            tempah = infoflag >> 8;
+            tempah &= 0xC0;
+            tempah |= 0x20;
+	    if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-      }
+         }
 
-#endif  /* SIS300 */
+#endif /* SIS300 */
 
-   } else {
+      } else {
 
-      if(HwDeviceExtension->jChipType == SIS_330) return;
+#ifdef SIS315H  /* ------- 315 series ------ */
 
-#ifdef SIS315H
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {	  		/* 315 - 30xLV */
 
-      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {			/* 310/325 series, LVDS */
+	    if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+	       tempah = infoflag >> 8;
+	       if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	          tempah = SiS_Pr->SiS_LCDInfo;
+	       }
+	    } else {
+               tempah = SiS_GetReg(SiS_Pr->SiS_P3d4,0x37);
+	    }
+	    tempah &= 0xC0;
 
-          if(SiS_Pr->SiS_IF_DEF_CH70xx == 0) {
-              PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-	      DelayIndex = PanelID >> 4;
-	      if((DelayTime >= 2) && ((PanelID & 0x0f) == 1))  {
-                 Delay = 3;
-              } else {
-                 if(DelayTime >= 2) DelayTime -= 2;
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-                 if(!(DelayTime & 0x01)) {
-       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[0];
-                 } else {
-       		     Delay = SiS_Pr->SiS_PanelDelayTblLVDS[DelayIndex].timer[1];
-                 }
-	         if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
-                    if(ROMAddr[0x13c] & 0x40) {
-                        if(!(DelayTime & 0x01)) {
-	    	           Delay = (USHORT)ROMAddr[0x17e];
-                        } else {
-	    	           Delay = (USHORT)ROMAddr[0x17f];
-                        }
-                    }
-                 }
-              }
-	      SiS_ShortDelay(SiS_Pr,Delay);
-	  }
+         } else {							/* 315 - 301, 301B */
 
-      } else {							/* 310/325 series, 301(B) */
+            tempah = infoflag >> 8;
+	    if(!SiS_Pr->UseCustomMode) {
+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+	          if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	             tempah = SiS_Pr->SiS_LCDInfo;
+	          }
+	       }
+	    }
+	    tempah &= 0xC0;
 
-          PanelID = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-	  DelayIndex = PanelID >> 4;
-          if(!(DelayTime & 0x01)) {
-       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[0];
-          } else {
-       		Delay = SiS_Pr->SiS_PanelDelayTbl[DelayIndex].timer[1];
-          }
-	  SiS_DDC2Delay(SiS_Pr, Delay * 4);
+            tempah |= 0x20;
+            if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) tempah |= 0x10;
+
+#if 0
+            if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+		/* BIOS does something here @@@ */
+            }
+#endif
 
-      }
+	    if(SiS_Pr->SiS_VBType & VB_NoLCD) {			/* TEST, imitate BIOS bug */
+	       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	          tempah |= 0xc0;
+	       }
+	    }
+            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0x0F,tempah);
 
-#endif /* SIS315H */
+         }
 
+#endif  /* SIS315H */
+      }
    }
-
-}
-
-void
-SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay)
-{
-  while(delay--) {
-    SiS_GenericDelay(SiS_Pr,0x19df);
-  }
 }
 
-void
-SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay)
+/******** Set CRT2 FIFO on 300/630/730 *******/
+#ifdef SIS300
+static void
+SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr,USHORT ModeNo,
+                    PSIS_HW_INFO HwInfo)
 {
-  while(delay--) {
-      SiS_GenericDelay(SiS_Pr,0x42);
-  }
-}
+  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  USHORT temp,index;
+  USHORT modeidindex,refreshratetableindex;
+  USHORT VCLK=0,MCLK,colorth=0,data2=0;
+  USHORT tempal, tempah, tempbx, tempcl, tempax;
+  USHORT CRT1ModeNo,CRT2ModeNo;
+  USHORT SelectRate_backup;
+  ULONG  data,eax;
+  const UCHAR  LatencyFactor[] = {
+  	97, 88, 86, 79, 77, 00,       /*; 64  bit    BQ=2   */
+        00, 87, 85, 78, 76, 54,       /*; 64  bit    BQ=1   */
+        97, 88, 86, 79, 77, 00,       /*; 128 bit    BQ=2   */
+        00, 79, 77, 70, 68, 48,       /*; 128 bit    BQ=1   */
+        80, 72, 69, 63, 61, 00,       /*; 64  bit    BQ=2   */
+        00, 70, 68, 61, 59, 37,       /*; 64  bit    BQ=1   */
+        86, 77, 75, 68, 66, 00,       /*; 128 bit    BQ=2   */
+        00, 68, 66, 59, 57, 37        /*; 128 bit    BQ=1   */
+  };
+  const UCHAR  LatencyFactor730[] = {
+         69, 63, 61,
+	 86, 79, 77,
+	103, 96, 94,
+	120,113,111,
+	137,130,128,    /* <-- last entry, data below */
+	137,130,128,	/* to avoid using illegal values */
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+	137,130,128,
+  };
+  const UCHAR ThLowB[]   = {
+  	81, 4, 72, 6, 88, 8,120,12,
+        55, 4, 54, 6, 66, 8, 90,12,
+        42, 4, 45, 6, 55, 8, 75,12
+  };
+  const UCHAR ThTiming[] = {
+  	1, 2, 2, 3, 0, 1, 1, 2
+  };
 
-void
-SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay)
-{
-  USHORT temp,flag;
+  SelectRate_backup = SiS_Pr->SiS_SelectCRT2Rate;
 
-  flag = SiS_GetReg3(0x61) & 0x10;
+  if(!SiS_Pr->CRT1UsesCustomMode) {
 
-  while(delay) {
-      temp = SiS_GetReg3(0x61) & 0x10;
-      if(temp == flag) continue;
-      flag = temp;
-      delay--;
-  }
-}
+     CRT1ModeNo = SiS_Pr->SiS_CRT1Mode;                                 	/* get CRT1 ModeNo */
+     SiS_SearchModeID(SiS_Pr, &CRT1ModeNo, &modeidindex);
+     SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+     SiS_Pr->SiS_SelectCRT2Rate = 0;
+     refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT1ModeNo, modeidindex, HwInfo);
 
-BOOLEAN
-SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr)
-{
-  USHORT flag;
+     if(CRT1ModeNo >= 0x13) {
+        index = SiS_Pr->SiS_RefIndex[refreshratetableindex].Ext_CRTVCLK;
+        index &= 0x3F;
+        VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;				/* Get VCLK */
+
+	colorth = SiS_GetColorDepth(SiS_Pr,CRT1ModeNo,modeidindex); 	/* Get colordepth */
+        colorth >>= 1;
+        if(!colorth) colorth++;
+     }
 
-  flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x01);
-  if(flag >= 0x0B0) return(1);
-  else return(0);
-}
+  } else {
 
-BOOLEAN
-SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+     CRT1ModeNo = 0xfe;
+     VCLK = SiS_Pr->CSRClock_CRT1;						/* Get VCLK */
+     data2 = (SiS_Pr->CModeFlag_CRT1 & ModeInfoFlag) - 2;
+     switch(data2) {								/* Get color depth */
+        case 0 : colorth = 1; break;
+        case 1 : colorth = 1; break;
+        case 2 : colorth = 2; break;
+        case 3 : colorth = 2; break;
+        case 4 : colorth = 3; break;
+        case 5 : colorth = 4; break;
+        default: colorth = 2;
+     }
 
-  if(HwDeviceExtension->jChipType == SIS_730) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x13);
-     if(flag & 0x20) return(1);
   }
-  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-  if(flag & 0x20) return(1);
-  else return(0);
-}
-
-BOOLEAN
-SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
-
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     if((HwDeviceExtension->jChipType != SIS_650) || (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f) & 0xf0)) {
-        flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-        if(flag & EnableDualEdge) return(1);
-        else return(0);
-     } else return(0);
-  } else
-#endif
-     return(0);
-}
-
-BOOLEAN
-SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if((flag & EnableDualEdge) && (flag & SetToLCDA))   return(1);
-#if 0 /* Not done in 650/30xLV 1.10.6s, but in 650/301LV */
-     else if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(flag) return(1);
-       else     return(0);   			         
-     }
-#endif
-     else
-       return(0);
-  } else
-#endif
-     return(0);
- }
+  if(CRT1ModeNo >= 0x13) {
+    if(HwInfo->jChipType == SIS_300) {
+       index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x3A);
+    } else {
+       index = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1A);
+    }
+    index &= 0x07;
+    MCLK = SiS_Pr->SiS_MCLKData_0[index].CLOCK;				/* Get MCLK */
 
-BOOLEAN
-SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+    data2 = (colorth * VCLK) / MCLK;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x79);
-     if(flag & 0x10)  return(1);
-     else             return(0);
-  } else
-#endif
-     return(0);
- }
+    temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+    temp = ((temp & 0x00FF) >> 6) << 1;
+    if(temp == 0) temp = 1;
+    temp <<= 2;
+    temp &= 0xff;
 
-#if 0
-BOOLEAN
-SiS_Is315E(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+    data2 = temp - data2;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
-     if(flag & 0x10)  return(1);
-     else      	      return(0);
-  } else
-#endif
-     return(0);
-}
-#endif
+    if((28 * 16) % data2) {
+      	data2 = (28 * 16) / data2;
+      	data2++;
+    } else {
+      	data2 = (28 * 16) / data2;
+    }
 
-BOOLEAN
-SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+    if(HwInfo->jChipType == SIS_300) {
 
-  if(HwDeviceExtension->jChipType == SIS_650) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x5f);
-     flag &= 0xF0;
-     if((flag == 0xb0) || (flag == 0x90)) return 0;
-     else return 1;
-  } else
-#endif
-    return 1;
-}
+	tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x18);
+	tempah &= 0x62;
+	tempah >>= 1;
+	tempal = tempah;
+	tempah >>= 3;
+	tempal |= tempah;
+	tempal &= 0x07;
+	tempcl = ThTiming[tempal];
+	tempbx = SiS_GetReg(SiS_Pr->SiS_P3c4,0x16);
+	tempbx >>= 6;
+	tempah = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+	tempah >>= 4;
+	tempah &= 0x0c;
+	tempbx |= tempah;
+	tempbx <<= 1;
+	tempal = ThLowB[tempbx + 1];
+	tempal *= tempcl;
+	tempal += ThLowB[tempbx];
+	data = tempal;
 
-BOOLEAN
-SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+    } else if(HwInfo->jChipType == SIS_730) {
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableLVDSHiVision)  return(1);  /* = YPrPb = 0x08 */
-     else      	                    return(0);
-  } else
+#ifndef LINUX_XF86
+       SiS_SetRegLong(0xcf8,0x80000050);
+       eax = SiS_GetRegLong(0xcfc);
+#else
+       eax = pciReadLong(0x00000000, 0x50);
 #endif
-     return(0);
-}
+       tempal = (USHORT)(eax >> 8);
+       tempal &= 0x06;
+       tempal <<= 5;
 
-BOOLEAN
-SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-#ifdef SIS315H
-  USHORT flag;
+#ifndef LINUX_XF86
+       SiS_SetRegLong(0xcf8,0x800000A0);
+       eax = SiS_GetRegLong(0xcfc);
+#else
+       eax = pciReadLong(0x00000000, 0xA0);
+#endif
+       temp = (USHORT)(eax >> 28);
+       temp &= 0x0F;
+       tempal |= temp;
+
+       tempbx = tempal;   /* BIOS BUG (2.04.5d, 2.04.6a use ah here, which is unset!) */
+       tempbx = 0;        /* -- do it like the BIOS anyway... */
+       tempax = tempbx;
+       tempbx &= 0xc0;
+       tempbx >>= 6;
+       tempax &= 0x0f;
+       tempax *= 3;
+       tempbx += tempax;
+
+       data = LatencyFactor730[tempbx];
+       data += 15;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
+
+    } else {
+
+       index = 0;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(temp & 0x0080) index += 12;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableLVDSScart)     return(1);  /* = Scart = 0x04 */
-     else      	                    return(0);
-  } else
+#ifndef LINUX_XF86
+       SiS_SetRegLong(0xcf8,0x800000A0);
+       eax = SiS_GetRegLong(0xcfc);
+#else
+       /* We use pci functions X offers. We use tag 0, because
+        * we want to read/write to the host bridge (which is always
+        * 00:00.0 on 630, 730 and 540), not the VGA device.
+        */
+       eax = pciReadLong(0x00000000, 0xA0);
 #endif
-     return(0);
-}
+       temp = (USHORT)(eax >> 24);
+       if(!(temp&0x01)) index += 24;
 
-BOOLEAN
-SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-  USHORT flag;
+#ifndef LINUX_XF86
+       SiS_SetRegLong(0xcf8,0x80000050);
+       eax = SiS_GetRegLong(0xcfc);
+#else
+       eax = pciReadLong(0x00000000, 0x50);
+#endif
+       temp=(USHORT)(eax >> 24);
+       if(temp & 0x01) index += 6;
 
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToTV)        return(1);
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & EnableLVDSHiVision) return(1);  /* = YPrPb = 0x08 */
-     if(flag & EnableLVDSScart)    return(1);  /* = Scart = 0x04- TW inserted */
-     else                          return(0);
-  } else
-#endif
-  {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToTV) return(1);
-  }
-  return(0);
-}
+       temp = (temp & 0x0F) >> 1;
+       index += temp;
 
-BOOLEAN
-SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
-{
-  USHORT flag;
+       data = LatencyFactor[index];
+       data += 15;
+       temp = SiS_GetReg(SiS_Pr->SiS_P3c4,0x14);
+       if(!(temp & 0x80)) data += 5;
+    }
 
-#ifdef SIS315H
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-     if(flag & SetCRT2ToLCD) return(1);
-     flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-     if(flag & SetToLCDA)    return(1);
-     else                    return(0);
-  } else
-#endif
-  {
-   flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-   if(flag & SetCRT2ToLCD)   return(1);
-  }
-  return(0);
+    data += data2;				/* CRT1 Request Period */
 
-}
+    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-BOOLEAN
-SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr)
-{
-  USHORT flag;
+    if(!SiS_Pr->UseCustomMode) {
 
-  flag = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x30);
-  if(flag & 0x20) return(0);
-  else            return(1);
-}
+       CRT2ModeNo = ModeNo;
+       SiS_SearchModeID(SiS_Pr, &CRT2ModeNo, &modeidindex);
 
-BOOLEAN
-SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+       refreshratetableindex = SiS_GetRatePtr(SiS_Pr, CRT2ModeNo, modeidindex, HwInfo);
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     return(0);
-  } else {
-     flag = SiS_GetReg1(SiS_Pr->SiS_Part4Port,0x00);
-     if((flag == 1) || (flag == 2)) return(0);
-     else return(1);
-  }
-}
+       index = SiS_GetVCLK2Ptr(SiS_Pr,CRT2ModeNo,modeidindex,
+                               refreshratetableindex,HwInfo);
+       VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK;                         	/* Get VCLK  */
 
-BOOLEAN
-SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT flag;
+       if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	     if(ROMAddr[0x220] & 0x01) {
+                VCLK = ROMAddr[0x229] | (ROMAddr[0x22a] << 8);
+	     }
+          }
+       }
 
-  if(!(SiS_BridgeIsOn(SiS_Pr,BaseAddr,HwDeviceExtension))) {
-    flag = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00);
-    if(HwDeviceExtension->jChipType < SIS_315H) {
-      /* 300 series (630/301B 2.04.5a) */
-      flag &= 0xa0;
-      if((flag == 0x80) || (flag == 0x20)) return 0;
-      else	                           return 1;
     } else {
-      /* 310/325 series (650/30xLV 1.10.6s) */
-      flag &= 0x50;
-      if((flag == 0x40) || (flag == 0x10)) return 0;
-      else                                 return 1;
+
+       CRT2ModeNo = 0xfe;
+       VCLK = SiS_Pr->CSRClock;							/* Get VCLK */
+
     }
-  }
-  return 1;
-}
 
-BOOLEAN
-SiS_BridgeInSlave(SiS_Private *SiS_Pr)
-{
-  USHORT flag1;
+    colorth = SiS_GetColorDepth(SiS_Pr,CRT2ModeNo,modeidindex);   	/* Get colordepth */
+    colorth >>= 1;
+    if(!colorth) colorth++;
 
-  flag1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31);
-  if(flag1 & (SetInSlaveMode >> 8)) return 1;
-  else return 0;
-}
+    data = data * VCLK * colorth;
+    if(data % (MCLK << 4)) {
+      	data = data / (MCLK << 4);
+      	data++;
+    } else {
+      	data = data / (MCLK << 4);
+    }
 
-void
-SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-#ifdef SIS315H
-  USHORT temp;
-#endif
+    if(data <= 6) data = 6;
+    if(data > 0x14) data = 0x14;
 
-  /* Note: This variable is only used on 30xLV systems.
-     CR38 has a different meaning on LVDS/CH7019 systems.
-   */
+    temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x01);
+    if(HwInfo->jChipType == SIS_300) {
+       if(data <= 0x0f) temp = (temp & (~0x1F)) | 0x13;
+       else             temp = (temp & (~0x1F)) | 0x16;
+       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+       		temp = (temp & (~0x1F)) | 0x13;
+       }
+    } else {
+       if( ( (HwInfo->jChipType == SIS_630) ||
+             (HwInfo->jChipType == SIS_730) )  &&
+           (HwInfo->jChipRevision >= 0x30) ) /* 630s or 730(s?) */
+      {
+	  temp = (temp & (~0x1F)) | 0x1b;
+      } else {
+	  temp = (temp & (~0x1F)) | 0x16;
+      }
+    }
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x01,0xe0,temp);
+
+    if( (HwInfo->jChipType == SIS_630) &&
+        (HwInfo->jChipRevision >= 0x30) ) /* 630s, NOT 730 */
+    {
+   	if(data > 0x13) data = 0x13;
+    }
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,0xe0,data);
+
+  } else {  /* If mode <= 0x13, we just restore everything */
+
+    SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+    SiS_Pr->SiS_SelectCRT2Rate = SelectRate_backup;
 
-  SiS_Pr->SiS_HiVision = 0;
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-        if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-           temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
-	   temp &= 0x38;
-	   SiS_Pr->SiS_HiVision = (temp >> 3);
-	}
-     }
-#endif /* SIS315H */
   }
 }
+#endif
 
-BOOLEAN
-SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                  USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/**** Set CRT2 FIFO on 315/330 series ****/
+#ifdef SIS315H
+static void
+SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr)
 {
-  USHORT temp,modeflag,resinfo=0;
-  const unsigned char SiS300SeriesLCDRes[] =
-         { 0, 1, 2, 3, 7, 4, 5, 8,
-	   0, 0, 0, 0, 0, 0, 0, 0 };
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x01,0x3B);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x02,~0x3F,0x04);
+}
+#endif
 
-  SiS_Pr->SiS_LCDResInfo = 0;
-  SiS_Pr->SiS_LCDTypeInfo = 0;
-  SiS_Pr->SiS_LCDInfo = 0;
+/*************** Set LCD-A ***************/
+#ifdef SIS315H
+static void
+SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                   PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+{
+  USHORT modeflag,resinfo;
+  USHORT push1,push2,tempax,tempbx,tempcx,temp;
+  ULONG tempeax=0,tempebx,tempecx,tempvcfact;
 
-  if(SiS_Pr->UseCustomMode) {
-     modeflag = SiS_Pr->CModeFlag;
+  /* This is not supported with LCDA */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
+  if(IS_SIS330) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* Xabre 1.01.03 */
+  } else if(IS_SIS740) {
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 740/LVDS */
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 740/LVDS */
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x03);
+     } else {
+        SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x10);			/* 740/301LV, 301BDH */
+     }
   } else {
-     if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {					/* 650/LVDS */
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,0xfb,0x04);      	/* 650/LVDS */
+	SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x2D,0x00);			/* 650/LVDS 1.10.07 */
      } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+        SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x2D,0x0f);			/* 650/30xLv 1.10.6s */
      }
   }
 
-  if(!(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))   return 0;
-
-  if(!(SiS_Pr->SiS_VBInfo & (SetSimuScanMode | SwitchToCRT2))) return 0;
-
-  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-
-  /* FSTN: Fake CR36 (TypeInfo 2, ResInfo SiS_Panel320x480) */
-  if(SiS_Pr->SiS_IF_DEF_FSTN) {
-   	temp = 0x20 | SiS_Pr->SiS_Panel320x480;
-   	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,temp);
-  }
-
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-  	SiS_Pr->SiS_LCDTypeInfo = temp >> 4;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-        SiS_Pr->SiS_LCDTypeInfo = (temp & 0x0F) - 1;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
-  temp &= 0x0f;
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-      /* TW: Translate 300 series LCDRes to 310/325 series for unified usage */
-      temp = SiS300SeriesLCDRes[temp];
-  }
-  SiS_Pr->SiS_LCDResInfo = temp;
 
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
-       	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel320x480;
-  }
+  tempax = SiS_Pr->SiS_LCDHDES;
+  tempbx = SiS_Pr->SiS_HDE;
+  tempcx = SiS_Pr->SiS_HT;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMin301)
-		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMin301;
-  } else {
-    	if(SiS_Pr->SiS_LCDResInfo < SiS_Pr->SiS_PanelMinLVDS)
-		SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_PanelMinLVDS;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+     tempbx = SiS_Pr->PanelXRes;
   }
+  tempcx -= tempbx;                        	            	/* HT-HDE  */
+  push1 = tempax;
+  tempax += tempbx;	                                    	/* lcdhdee  */
+  tempbx = SiS_Pr->SiS_HT;
+  if(tempax >= tempbx)	tempax -= tempbx;
 
-  if(SiS_Pr->SiS_LCDResInfo > SiS_Pr->SiS_PanelMax)
-  	SiS_Pr->SiS_LCDResInfo = SiS_Pr->SiS_Panel1024x768;
+  push2 = tempax;						/* push lcdhdee  */
 
-  temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37);
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
-        /* TW: Fake LVDS bridge for FSTN */
-      	temp = 0x04;
-      	SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,temp);
-  }
-  SiS_Pr->SiS_LCDInfo = temp;
-  
-  if(!(SiS_Pr->UsePanelScaler))        SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-  else if(SiS_Pr->UsePanelScaler == 1) SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
+  tempcx >>= 2;
 
-  /* TW: Inserted entire 315-block from 650/LVDS/30xLV BIOSes */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		 if(ModeNo == 0x3a || ModeNo == 0x4d || ModeNo == 0x65) {
-		     /* Bridge does not scale to 1280x1024 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-	     }
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-	         if(ModeNo == 0x7c || ModeNo == 0x7d || ModeNo == 0x7e) {
-		     /* TW: Bridge does not scale to 1280x960 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-		 if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
-		     /* TW: Bridge does not scale to 640x400 */
-		     SiS_Pr->SiS_LCDInfo |= DontExpandLCD;
-		 }
-	     }
-	     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-	         if(ModeNo == 0x2f || ModeNo == 0x5d || ModeNo == 0x5e) {
-		     /* TW: Most panels can't scale to 640x400 */
-		     SiS_Pr->SiS_LCDInfo &= ~DontExpandLCD;
-		 }
-	     }
-	 }
+  /* 650/30xLV 1.10.6s, 740/LVDS */
+  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x28;
+ 	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  tempcx = 0x18;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x30;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x40;
+	else                                                          tempcx = 0x30;
      }
-     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x01) {
-         SiS_Pr->SiS_LCDInfo &= 0xFFEF;    
-	 SiS_Pr->SiS_LCDInfo |= LCDPass11;
+  }
+
+  tempcx += tempax;  	                                  	/* lcdhrs  */
+  if(tempcx >= tempbx) tempcx -= tempbx;
+                                                           	/* v ah,cl  */
+  tempax = tempcx;
+  tempax >>= 3;   	                                     	/* BPLHRS */
+  temp = tempax & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);                 	/* Part1_14h  */
+
+  temp += 10;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   temp += 6;
+	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	      temp++;
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+	         temp += 7;
+		 if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+		    temp -= 10;
+		 }
+	      }
+	   }
+	}
      }
-#endif
+  }
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x07) << 5);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);                         /* Part1_15h  */
+
+  tempbx = push2;                                          	/* lcdhdee  */
+  tempcx = push1;                                          	/* lcdhdes  */
+  temp = (tempcx & 0x00FF);
+  temp &= 0x07;                                  		/* BPLHDESKEW  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                         /* Part1_1Ah  */
+
+  tempcx >>= 3;   	                                     	/* BPLHDES */
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);                         /* Part1_16h  */
+
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     if(tempbx & 0x07) tempbx += 8;
+  }
+  tempbx >>= 3;                                        		/* BPLHDEE  */
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);                        	/* Part1_17h  */
+
+  tempcx = SiS_Pr->SiS_VGAVT;
+  tempbx = SiS_Pr->SiS_VGAVDE;
+  tempcx -= tempbx; 	                                   	/* GAVT-VGAVDE  */
+  tempbx = SiS_Pr->SiS_LCDVDES;                                	/* VGAVDES  */
+  push1 = tempbx;
+  if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+     tempax = SiS_Pr->PanelYRes;
   } else {
-#ifdef SIS300
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-           if(!(ROMAddr[0x235] & 0x02)) {
-	      SiS_Pr->SiS_LCDInfo &= 0xEF;
-	   }
-        }
-     } else {
-        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	   if((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo == 0x10))) {
-               SiS_Pr->SiS_LCDInfo &= 0xEF;
-	   }
+     tempax = SiS_Pr->SiS_VGAVDE;
+  }
+
+  tempbx += tempax;
+  tempax = SiS_Pr->SiS_VT;                                    	/* VT  */
+  if(tempbx >= tempax)  tempbx -= tempax;
+
+  push2 = tempbx;
+
+  tempcx >>= 2;
+
+  /* 650/30xLV 1.10.6s, 740/LVDS */
+  if( ((SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) ||
+      ((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 1;
+   	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 3;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 3;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 1;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 1;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 1;
+	else                                                           tempcx = 0x0057;
+     }
+  }
+
+  tempbx += tempcx;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+     tempbx++;                                                	/* BPLVRS  */
+  }
+  if(tempbx >= tempax)   tempbx -= tempax;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);                             /* Part1_18h  */
+
+  tempcx >>= 3;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 3;
+   	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)   tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 5;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 2;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 2;
 	}
      }
+  }
+  tempcx += tempbx;
+  tempcx++;                                                	/* BPLVRE  */
+  temp = tempcx & 0x00FF;
+  temp &= 0x0F;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);
+  } else {
+     /* 650/30xLV 1.10.6s, Xabre */
+     temp |= 0xC0;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,temp);             /* Part1_19h  */
+  }
+
+  temp = (tempbx & 0xFF00) >> 8;
+  temp &= 0x07;
+  temp <<= 3;  		                               		/* BPLDESKEW =0 */
+  tempbx = SiS_Pr->SiS_VGAVDE;
+  if(tempbx != SiS_Pr->SiS_VDE)              temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)    temp |= 0x40;
+  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) temp |= 0x80;
+     }
+  } else {
+     /* Don't check Part1Port,0x00 -> not even being set if LCDA! */
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)  temp |= 0x80;
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x07,temp);            /* Part1_1Ah */
+
+  tempbx = push2;                                      		/* BPLVDEE  */
+  tempcx = push1;                                      		/* NPLVDES */
+  push1 = (USHORT)(tempeax & 0xFFFF);
+
+  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+        if(resinfo == SIS_RI_800x600) tempcx++;
+     }
+  }
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+     tempbx = SiS_Pr->SiS_VGAVDE;
+     tempcx = tempbx;
+     tempbx--;
+  }
+
+  temp = (tempbx & 0xFF00) >> 8;
+  temp &= 0x07;
+  temp <<= 3;
+  temp = temp | (((tempcx & 0xFF00) >> 8) & 0x07);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);                          /* Part1_1Dh */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);                          /* Part1_1Ch  */
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);                          /* Part1_1Bh  */
+
+  tempecx = SiS_Pr->SiS_VGAVT;
+  tempebx = SiS_Pr->SiS_VDE;
+  tempeax = SiS_Pr->SiS_VGAVDE;
+  tempecx -= tempeax;    	                             	/* VGAVT-VGAVDE  */
+  tempeax <<= 18;
+  temp = (USHORT)(tempeax % tempebx);
+  tempeax = tempeax / tempebx;
+  if(temp)  tempeax++;
+  tempebx = tempeax;                                        	/* BPLVCFACT  */
+  tempvcfact = tempeax;
+  temp = (USHORT)(tempebx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);
+
+  temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);
+
+  temp = (USHORT)((tempebx & 0x00030000) >> 16);
+  if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);
+
+  tempecx = SiS_Pr->SiS_VGAHDE;
+  tempebx = SiS_Pr->SiS_HDE;
+  tempeax = tempecx;
+  tempeax <<= 16;
+  temp = tempeax % tempebx;
+  tempeax = tempeax / tempebx;
+  if(temp) tempeax++;
+  if(tempebx == tempecx)  tempeax = 0xFFFF;
+  tempecx = tempeax;
+  tempeax = SiS_Pr->SiS_VGAHDE;
+  tempeax <<= 16;
+  tempeax = tempeax / tempecx;
+  tempecx <<= 16;
+  tempeax--;
+  tempecx = tempecx | (tempeax & 0xFFFF);
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);                          /* Part1_1Fh  */
+
+  tempeax = SiS_Pr->SiS_VGAVDE;
+  tempeax <<= 18;
+  tempeax = tempeax / tempvcfact;
+  tempbx = (USHORT)(tempeax & 0x0FFFF);
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)  tempbx = 1;
+
+  temp = ((tempbx & 0xFF00) >> 8) << 3;
+  temp = temp | (USHORT)(((tempecx & 0x0000FF00) >> 8) & 0x07);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);                         /* Part1_20h */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);                         /* Part1_21h */
+
+  tempecx >>= 16;   	                                  	/* BPLHCFACT  */
+  if(modeflag & HalfDCLK) tempecx >>= 1;
+  temp = (USHORT)((tempecx & 0x0000FF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);                         /* Part1_22h */
+
+  temp=(USHORT)(tempecx & 0x000000FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);
+
+#if 0
+  /* Missing code (calles int 2f) (650/302LV 1.10.6s; 1.10.7w doesn't do this) */
+  if(xxx()) {
+      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0e,0xda);
+  }
 #endif
+
+  /* Only for LVDS and 301LV/302LV */
+  if((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (SiS_Pr->SiS_VBInfo & VB_SIS301LV302LV)) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1e,0x20);
   }
-  
-  /* TW: With Trumpion, always Expanding */
-  if(SiS_Pr->SiS_IF_DEF_TRUMPION != 0){
-       SiS_Pr->SiS_LCDInfo &= (~DontExpandLCD);
+}
+#endif  /* SIS 315 */
+
+static USHORT
+SiS_GetVGAHT2(SiS_Private *SiS_Pr)
+{
+  ULONG tempax,tempbx;
+
+  tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
+  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
+  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
+  return((USHORT) tempax);
+}
+
+/******* Set Part 1 / SiS bridge *********/
+static void
+SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex,
+                  PSIS_HW_INFO HwInfo,USHORT RefreshRateTableIndex)
+{
+  USHORT  push1,push2;
+  USHORT  tempax,tempbx,tempcx,temp;
+  USHORT  resinfo,modeflag;
+  unsigned char p1_7, p1_8;
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
+    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
 
-  if(!((HwDeviceExtension->jChipType < SIS_315H) && (SiS_Pr->SiS_SetFlag & SetDOSMode))) {
+  /* The following is only done if bridge is in slave mode: */
 
-     if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-	   if(ModeNo > 0x13) {
-	      if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-                 if((resinfo == 7) || (resinfo == 3)) {
-                    SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-		 }
-              }
-           }
-        }
-	if(ModeNo == 0x12) {
-	   if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-	      SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
+  tempax = 0xFFFF;
+  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempax = SiS_GetVGAHT2(SiS_Pr);
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)  modeflag |= Charx8Dot;
+
+  if(modeflag & Charx8Dot) tempcx = 0x08;
+  else                     tempcx = 0x09;
+
+  if(tempax >= SiS_Pr->SiS_VGAHT) tempax = SiS_Pr->SiS_VGAHT;
+
+  if(modeflag & HalfDCLK) tempax >>= 1;
+
+  tempax = (tempax / tempcx) - 5;
+  tempbx = tempax & 0x00FF;
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0xff);                 /* set MAX HT */
+
+  tempax = SiS_Pr->SiS_VGAHDE;                                 	/* 0x04 Horizontal Display End */
+  if(modeflag & HalfDCLK) tempax >>= 1;
+  tempax = (tempax / tempcx) - 1;
+  tempbx |= ((tempax & 0x00FF) << 8);
+  temp = tempax & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,temp);
+
+  temp = (tempbx & 0xFF00) >> 8;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+        temp += 2;
+     }
+  }
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(SiS_Pr->SiS_HiVision == 3) {
+        if(resinfo == SIS_RI_800x600) temp -= 2;
+     }
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x05,temp);                 /* 0x05 Horizontal Display Start */
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x06,0x03);                 /* 0x06 Horizontal Blank end     */
+
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+     temp = (tempbx & 0x00FF) - 1;
+     if(!(modeflag & HalfDCLK)) {
+        temp -= 6;
+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+           temp -= 2;
+           if(ModeNo > 0x13) temp -= 10;
+        }
+     }
+  } else {
+     tempcx = tempbx & 0x00FF;
+     tempbx = (tempbx & 0xFF00) >> 8;
+     tempcx = (tempcx + tempbx) >> 1;
+     temp = (tempcx & 0x00FF) + 2;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        temp--;
+        if(!(modeflag & HalfDCLK)) {
+           if((modeflag & Charx8Dot)) {
+              temp += 4;
+              if(SiS_Pr->SiS_VGAHDE >= 800) temp -= 6;
+              if(HwInfo->jChipType >= SIS_315H) {
+	         if(SiS_Pr->SiS_VGAHDE == 800) temp += 2;
+              }
+           }
+        }
+     } else {
+        if(!(modeflag & HalfDCLK)) {
+           temp -= 4;
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960) {
+              if(SiS_Pr->SiS_VGAHDE >= 800) {
+                 temp -= 7;
+	         if(HwInfo->jChipType < SIS_315H) {
+	            /* 650/301LV(x) does not do this, 630/301B, 300/301LV do */
+                    if(SiS_Pr->SiS_ModeType == ModeEGA) {
+                       if(SiS_Pr->SiS_VGAVDE == 1024) {
+                          temp += 15;
+                          if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
+		  	     temp += 7;
+                       }
+                    }
+	         }
+                 if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                    if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) temp += 28;
+                 }
+              }
+           }
+        }
+     }
+  }
+
+  p1_7 = temp;
+  p1_8 = 0x00;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        if(ModeNo <= 0x01) {
+	   p1_7 = 0x2a;
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_8 = 0x61;
+	   else 	      			p1_8 = 0x41;
+	} else if(SiS_Pr->SiS_ModeType == ModeText) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) p1_7 = 0x54;
+	   else 	    			p1_7 = 0x55;
+	   p1_8 = 0x00;
+	} else if(ModeNo <= 0x13) {
+	   if(modeflag & HalfDCLK) {
+	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		 p1_7 = 0x30;
+		 p1_8 = 0x03;
+	      } else {
+	 	 p1_7 = 0x2f;
+		 p1_8 = 0x02;
+	      }
+	   } else {
+	      p1_7 = 0x5b;
+	      p1_8 = 0x03;
+	   }
+	} else if( ((HwInfo->jChipType >= SIS_315H) &&
+	            ((ModeNo == 0x50) || (ModeNo = 0x56) || (ModeNo = 0x53))) ||
+	           ((HwInfo->jChipType < SIS_315H) &&
+		    (resinfo == SIS_RI_320x200 || resinfo == SIS_RI_320x240)) ) {
+	   if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+	      p1_7 = 0x30,
+	      p1_8 = 0x03;
+	   } else {
+	      p1_7 = 0x2f;
+	      p1_8 = 0x03;
+	   }
+        }
+     }
+  }
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+     if(SiS_Pr->SiS_HiVision & 0x03) {
+	p1_7 = 0xb2;
+	if(SiS_Pr->SiS_HiVision & 0x02) {
+	   p1_7 = 0xab;
+	}
+     }
+  }
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x07,p1_7);			/* 0x07 Horizontal Retrace Start */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,p1_8);			/* 0x08 Horizontal Retrace End   */
+
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x03);                	/* 0x18 SR08 (FIFO Threshold?)   */
+
+  SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x19,0xF0);
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x09,0xFF);                	/* 0x09 Set Max VT    */
+
+  tempcx = 0x121;
+  tempbx = SiS_Pr->SiS_VGAVDE;                               	/* 0x0E Vertical Display End */
+  if     (tempbx == 357) tempbx = 350;
+  else if(tempbx == 360) tempbx = 350;
+  else if(tempbx == 375) tempbx = 350;
+  else if(tempbx == 405) tempbx = 400;
+  else if(tempbx == 420) tempbx = 400;
+  else if(tempbx == 525) tempbx = 480;
+  push2 = tempbx;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+      	if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+           if     (tempbx == 350) tempbx += 5;
+           else if(tempbx == 480) tempbx += 5;
+      	}
+     }
+  }
+  tempbx -= 2;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);        		/* 0x10 vertical Blank Start */
+
+  tempbx = push2;
+  tempbx--;
+  temp = tempbx & 0x00FF;
+#if 0
+  /* Missing code from 630/301B 2.04.5a and 650/302LV 1.10.6s (calles int 2f) */
+  if(xxx()) {
+      if(temp == 0xdf) temp = 0xda;
+  }
+#endif
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);
+
+  if(tempbx & 0x0100)  tempcx |= 0x0002;
+
+  tempax = 0x000B;
+  if(modeflag & DoubleScanMode) tempax |= 0x8000;
+
+  if(tempbx & 0x0200)  tempcx |= 0x0040;
+
+  temp = (tempax & 0xFF00) >> 8;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);
+
+  if(tempbx & 0x0400)  tempcx |= 0x0600;
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,0x00);                	/* 0x11 Vertical Blank End */
+
+  tempax = (SiS_Pr->SiS_VGAVT - tempbx) >> 2;
+
+  if((ModeNo > 0x13) || (HwInfo->jChipType < SIS_315H)) {
+     if(resinfo != SIS_RI_1280x1024) {
+	tempbx += (tempax << 1);
+     }
+  } else if(HwInfo->jChipType >= SIS_315H) {
+     if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1400x1050) {
+	tempbx += (tempax << 1);
+     }
+  }
+
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
+     (SiS_Pr->SiS_HiVision == 3)) {
+     tempbx -= 10;
+  } else {
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+	   if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+              tempbx += 40;
+	      if(HwInfo->jChipType >= SIS_315H) {
+	         if(SiS_Pr->SiS_VGAHDE == 800) tempbx += 10;
+	      }
+      	   }
+	}
+     }
+  }
+  tempax >>= 2;
+  tempax++;
+  tempax += tempbx;
+  push1 = tempax;
+  if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+     if(tempbx <= 513)  {
+     	if(tempax >= 513) tempbx = 513;
+     }
+  }
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);			/* 0x0C Vertical Retrace Start */
+
+  tempbx--;
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);
+
+  if(tempbx & 0x0100) tempcx |= 0x0008;
+
+  if(tempbx & 0x0200) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x0B,0x20);
+  }
+  tempbx++;
+
+  if(tempbx & 0x0100) tempcx |= 0x0004;
+  if(tempbx & 0x0200) tempcx |= 0x0080;
+  if(tempbx & 0x0400) {
+     if(SiS_Pr->SiS_VBType & VB_SIS301) tempcx |= 0x0800;
+     else                               tempcx |= 0x0C00;
+  }
+
+  tempbx = push1;
+  temp = tempbx & 0x000F;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);        		/* 0x0D vertical Retrace End */
+
+  if(tempbx & 0x0010) tempcx |= 0x2000;
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);              	/* 0x0A CR07 */
+
+  temp = (tempcx & 0xFF00) >> 8;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);              	/* 0x17 SR0A */
+
+  tempax = modeflag;
+  temp = (tempax & 0xFF00) >> 8;
+  temp = (temp >> 1) & 0x09;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301)) {
+     /* Only use 8 dot clock */
+     temp |= 0x01;
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);              	/* 0x16 SR01 */
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,0x00);              	/* 0x0F CR14 */
+
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,0x00);              	/* 0x12 CR17 */
+
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+     if(IS_SIS650) {
+        /* 650/30xLV 1.10.6s */
+        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+	   temp = 0x80;
+	}
+     } else temp = 0x80;
+  } else temp = 0x00;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);                	/* 0x1A SR0E */
+
+}
+
+/*********** Set Part 1 / LVDS ***********/
+static void
+SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+ 		   PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+{
+  USHORT modeflag, resinfo;
+  USHORT push1, push2, tempax, tempbx, tempcx, temp;
+#ifdef SIS315H
+  USHORT pushcx;
+#endif
+  ULONG  tempeax=0, tempebx, tempecx, tempvcfact=0;
+
+  /* This is not supported on LVDS */
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  } else {
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+  }
+
+  /* Set up Panel Link */
+
+  /* 1. Horizontal setup */
+
+  tempax = SiS_Pr->SiS_LCDHDES;
+
+  if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) &&
+         (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ) {
+  	   tempax -= 8;
+     }
+  }
+
+  tempcx = SiS_Pr->SiS_HT;    				  /* Horiz. Total */
+
+  tempbx = SiS_Pr->SiS_HDE;                               /* Horiz. Display End */
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+     SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+     tempbx >>= 1;
+  }
+
+  if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+	   tempbx = SiS_Pr->PanelXRes;
+	} else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   tempbx = SiS_Pr->PanelXRes;
+	   if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+	      tempbx = 800;
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	         tempbx = 1024;
+	      }
+	   }
+        }
+     }
+  }
+  tempcx = (tempcx - tempbx) >> 2;		 /* HT-HDE / 4 */
+
+  push1 = tempax;
+
+  tempax += tempbx;
+
+  if(tempax >= SiS_Pr->SiS_HT) tempax -= SiS_Pr->SiS_HT;
+
+  push2 = tempax;
+
+  if((!SiS_Pr->SiS_IF_DEF_FSTN) &&
+     (!SiS_Pr->SiS_IF_DEF_DSTN) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
+     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+     if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+     	      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)        tempcx = 0x0028;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)  tempcx = 0x0018;
+     	      else if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) ) {
+	  	   if(HwInfo->jChipType < SIS_315H) {
+		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+		         tempcx = 0x0017;
+#ifdef TWNEWPANEL
+			 tempcx = 0x0018;
+#endif
+		      } else {
+		         tempcx = 0x0017;  /* A901; sometimes 0x0018; */
+		      }
+		   } else {
+		      tempcx = 0x0018;
+		   }
+	      }
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0028;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0030;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0030;
+	      else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0040;
+	   }
+        }
+     }
+  }
+
+  tempcx += tempax;                              /* lcdhrs  */
+  if(tempcx >= SiS_Pr->SiS_HT) tempcx -= SiS_Pr->SiS_HT;
+
+  tempax = tempcx >> 3;                          /* BPLHRS */
+  temp = tempax & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,temp);		 /* Part1_14h; Panel Link Horizontal Retrace Start  */
+
+  if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
+     temp = (tempax & 0x00FF) + 2;
+  } else {
+     temp = (tempax & 0x00FF) + 10;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if((!SiS_Pr->SiS_IF_DEF_DSTN) &&
+	   (!SiS_Pr->SiS_IF_DEF_FSTN) &&
+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+	   (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
+	   (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	      temp += 6;
+              if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	         temp++;
+	         if(HwInfo->jChipType >= SIS_315H) {
+	            if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
+	               temp += 7;
+		       if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
+		          temp -= 0x14;
+			  if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x768) {
+			     temp -= 10;
+			  }
+		       }
+	            }
+	         }
+	      }
+           }
+        }
+     }
+  }
+
+  temp &= 0x1F;
+  temp |= ((tempcx & 0x0007) << 5);
+#if 0
+  if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0x20;       /* WRONG? BIOS loads cl, not ah */
+#endif
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,temp);    	 /* Part1_15h; Panel Link Horizontal Retrace End/Skew */
+
+  tempbx = push2;
+  tempcx = push1;                                /* lcdhdes  */
+
+  temp = (tempcx & 0x0007);                      /* BPLHDESKEW  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1A,temp);   	 /* Part1_1Ah; Panel Link Vertical Retrace Start (2:0) */
+
+  tempcx >>= 3;                                  /* BPLHDES */
+  temp = (tempcx & 0x00FF);
+#if 0 /* Not 550 FSTN */
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(ModeNo == 0x5b) temp--; */
+  }
+#endif
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,temp);    	 /* Part1_16h; Panel Link Horizontal Display Enable Start  */
+
+  if((HwInfo->jChipType < SIS_315H) ||
+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if(tempbx & 0x07) tempbx += 8;
+  }
+  tempbx >>= 3;                                  /* BPLHDEE  */
+  temp = tempbx & 0x00FF;
+#if 0 /* Not 550 FSTN */
+  if(HwInfo->jChipType >= SIS_315H) {
+     if(ModeNo == 0x5b) temp--;
+  }
+#endif
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,temp);   	 /* Part1_17h; Panel Link Horizontal Display Enable End  */
+
+  /* 2. Vertical setup */
+
+  if(HwInfo->jChipType < SIS_315H) {
+     tempcx = SiS_Pr->SiS_VGAVT;
+     tempbx = SiS_Pr->SiS_VGAVDE;
+     if((SiS_Pr->SiS_CustomT != CUT_BARCO1366) && (SiS_Pr->SiS_CustomT != CUT_BARCO1024)) {
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+           if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	      tempbx = SiS_Pr->PanelYRes;
+           }
+	}
+     }
+     tempcx -= tempbx;
+
+  } else {
+
+     tempcx = SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE;           /* VGAVT-VGAVDE  */
+
+  }
+
+  tempbx = SiS_Pr->SiS_LCDVDES;	   		 	 	/* VGAVDES  */
+  push1 = tempbx;
+
+  tempax = SiS_Pr->SiS_VGAVDE;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+     if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+           tempax = 600;
+	   if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel800x600) {
+	      tempax = 768;
+	   }
+	}
+     } else if( (SiS_Pr->SiS_IF_DEF_TRUMPION == 0)   &&
+                (!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+                ((SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) ||
+	         (SiS_Pr->SiS_IF_DEF_FSTN) ||
+	         (SiS_Pr->SiS_IF_DEF_DSTN)) ) {
+	tempax = SiS_Pr->PanelYRes;
+     }
+  }
+
+  tempbx += tempax;
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+
+  push2 = tempbx;
+
+  tempcx >>= 1;
+
+  if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) &&
+     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
+     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) {
+	tempcx = 0x0017;
+     } else if(!(SiS_Pr->SiS_LCDInfo & LCDPass11)) {
+        if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0003;
+  	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)) tempcx = 0x0003;
+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0001;
+           else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0001;
+	   else 							  tempcx = 0x0057;
+        } else  {
+     	   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)         tempcx = 0x0001;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0001;
+     	   else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) ||
+	           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)) {
+		   if(HwInfo->jChipType < SIS_315H) {
+		      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+			    tempcx = 0x0002;
+#ifdef TWNEWPANEL
+			    tempcx = 0x0003;
+#endif
+		      } else {
+		            tempcx = 0x0002;   /* A901; sometimes 0x0003; */
+		      }
+		   } else tempcx = 0x0003;
+           }
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)  tempcx = 0x0003;
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempcx = 0x0001;
+     	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) tempcx = 0x0001;
+	   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempcx = 0x0001;
+     	   else 							 tempcx = 0x0057;
+	}
+     }
+  }
+
+  tempbx += tempcx;			 	/* BPLVRS  */
+
+  if((HwInfo->jChipType < SIS_315H) ||
+     (SiS_Pr->SiS_IF_DEF_FSTN) ||
+     (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     tempbx++;
+  }
+
+  if(tempbx >= SiS_Pr->SiS_VT) tempbx -= SiS_Pr->SiS_VT;
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);       	 /* Part1_18h; Panel Link Vertical Retrace Start  */
+
+  tempcx >>= 3;
+
+  if((!(SiS_Pr->SiS_LCDInfo & LCDPass11)) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1366) &&
+     (SiS_Pr->SiS_CustomT != CUT_BARCO1024) &&
+     (SiS_Pr->SiS_CustomT != CUT_PANEL848)) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        if( (HwInfo->jChipType < SIS_315H) &&
+            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) )     tempcx = 0x0001;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2)  tempcx = 0x0002;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3)  tempcx = 0x0002;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)    tempcx = 0x0003;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)   tempcx = 0x0005;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)   tempcx = 0x0005;
+	else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768)   tempcx = 0x0011;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)  tempcx = 0x0005;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)  tempcx = 0x0002;
+        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)  tempcx = 0x0011;
+        else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  {
+     		if(HwInfo->jChipType < SIS_315H) {
+		        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+				tempcx = 0x0004;
+#ifdef TWNEWPANEL
+				tempcx = 0x0005;
+#endif
+		        } else {
+				tempcx = 0x0004;   /* A901; Other BIOS sets 0x0005; */
+			}
+		} else {
+			tempcx = 0x0005;
+		}
+        }
+     }
+  }
+
+  tempcx = tempcx + tempbx + 1;                  /* BPLVRE  */
+  temp = tempcx & 0x000F;
+  if(SiS_Pr->SiS_IF_DEF_FSTN ||
+     SiS_Pr->SiS_IF_DEF_DSTN ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+     (SiS_Pr->SiS_CustomT == CUT_PANEL848)) {
+     temp |= 0x30;
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xf0,temp); /* Part1_19h; Panel Link Vertical Retrace End (3:0); Misc.  */
+
+  temp = ((tempbx & 0x0700) >> 8) << 3;          /* BPLDESKEW =0 */
+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+     if(SiS_Pr->SiS_HDE != 640) {
+        if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)   temp |= 0x40;
+     }
+  } else if(SiS_Pr->SiS_VGAVDE != SiS_Pr->SiS_VDE)  temp |= 0x40;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA)           temp |= 0x40;
+  if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+     if(HwInfo->jChipType >= SIS_315H) {
+        if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {
+           temp |= 0x80;
+        }
+     } else {
+	if( (HwInfo->jChipType == SIS_630) ||
+	    (HwInfo->jChipType == SIS_730) ) {
+	   if(HwInfo->jChipRevision >= 0x30) {
+	      temp |= 0x80;
+	   }
+	}
+     }
+  }
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1A,0x87,temp);  /* Part1_1Ah; Panel Link Control Signal (7:3); Vertical Retrace Start (2:0) */
+
+  if (HwInfo->jChipType < SIS_315H) {
+
+#ifdef SIS300      /* 300 series */
+
+        tempeax = SiS_Pr->SiS_VGAVDE << 6;
+        temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+        tempeax = tempeax / (ULONG)SiS_Pr->SiS_VDE;
+        if(temp != 0) tempeax++;
+        tempebx = tempeax;                         /* BPLVCFACT  */
+
+  	if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+	   tempebx = 0x003F;
+	}
+
+  	temp = (USHORT)(tempebx & 0x00FF);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,temp);      /* Part1_1Eh; Panel Link Vertical Scaling Factor */
+
+#endif /* SIS300 */
+
+  } else {
+
+#ifdef SIS315H  /* 315 series */
+
+        if(HwInfo->jChipType == SIS_740) {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1E,0x03);
+        } else {
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1E,0x23);
+	}
+
+	tempeax = SiS_Pr->SiS_VGAVDE << 18;
+    	temp = (USHORT)(tempeax % (ULONG)SiS_Pr->SiS_VDE);
+    	tempeax = tempeax / SiS_Pr->SiS_VDE;
+    	if(temp != 0) tempeax++;
+    	tempebx = tempeax;                         /* BPLVCFACT  */
+        tempvcfact = tempeax;
+    	temp = (USHORT)(tempebx & 0x00FF);
+    	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,temp);      /* Part1_37h; Panel Link Vertical Scaling Factor */
+    	temp = (USHORT)((tempebx & 0x00FF00) >> 8);
+    	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,temp);      /* Part1_36h; Panel Link Vertical Scaling Factor */
+    	temp = (USHORT)((tempebx & 0x00030000) >> 16);
+	temp &= 0x03;
+    	if(SiS_Pr->SiS_VDE == SiS_Pr->SiS_VGAVDE) temp |= 0x04;
+    	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,temp);      /* Part1_35h; Panel Link Vertical Scaling Factor */
+
+#endif /* SIS315H */
+
+  }
+
+  tempbx = push2;                                  /* BPLVDEE  */
+  tempcx = push1;
+
+  push1 = temp;
+
+  if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+   	if(!SiS_Pr->SiS_IF_DEF_FSTN && !SiS_Pr->SiS_IF_DEF_DSTN) {
+		if(HwInfo->jChipType < SIS_315H) {
+			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
+      				if(resinfo == SIS_RI_1024x600) tempcx++;
+				if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+					if(resinfo == SIS_RI_800x600) tempcx++;
+		    		}
+			} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+      				if(resinfo == SIS_RI_800x600)  tempcx++;
+				if(resinfo == SIS_RI_1024x768) tempcx++; /* Doesnt make sense anyway... */
+			} else  if(resinfo == SIS_RI_1024x768) tempcx++;
+		} else {
+			if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
+      				if(resinfo == SIS_RI_800x600)  tempcx++;
+			}
+		}
+	}
+  }
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) {
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        tempcx = SiS_Pr->SiS_VGAVDE;
+        tempbx = SiS_Pr->SiS_VGAVDE - 1;
+     }
+  }
+
+  temp = ((tempbx & 0x0700) >> 8) << 3;
+  temp |= ((tempcx & 0x0700) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1D,temp);     	/* Part1_1Dh; Vertical Display Overflow; Control Signal */
+
+  temp = tempbx & 0x00FF;
+  /* if(SiS_Pr->SiS_IF_DEF_FSTN) temp++;  */
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1C,temp);      	/* Part1_1Ch; Panel Link Vertical Display Enable End  */
+
+  temp = tempcx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1B,temp);      	/* Part1_1Bh; Panel Link Vertical Display Enable Start  */
+
+  /* 3. Additional horizontal setup (scaling, etc) */
+
+  tempecx = SiS_Pr->SiS_VGAHDE;
+  if(HwInfo->jChipType >= SIS_315H) {
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        if(modeflag & HalfDCLK) tempecx >>= 1;
+     }
+  }
+  tempebx = SiS_Pr->SiS_HDE;
+  if(tempecx == tempebx) tempeax = 0xFFFF;
+  else {
+     tempeax = tempecx;
+     tempeax <<= 16;
+     temp = (USHORT)(tempeax % tempebx);
+     tempeax = tempeax / tempebx;
+     if(HwInfo->jChipType >= SIS_315H) {
+        if(temp) tempeax++;
+     }
+  }
+  tempecx = tempeax;
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     tempeax = SiS_Pr->SiS_VGAHDE;
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) {
+        if(modeflag & HalfDCLK) tempeax >>= 1;
+     }
+     tempeax <<= 16;
+     tempeax = (tempeax / tempecx) - 1;
+  } else {
+     tempeax = ((SiS_Pr->SiS_VGAHT << 16) / tempecx) - 1;
+  }
+  tempecx <<= 16;
+  tempecx |= (tempeax & 0xFFFF);
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1F,temp);  	 /* Part1_1Fh; Panel Link DDA Operational Number in each horiz. line */
+
+  tempbx = SiS_Pr->SiS_VDE;
+  if(HwInfo->jChipType >= SIS_315H) {
+     tempeax = (SiS_Pr->SiS_VGAVDE << 18) / tempvcfact;
+     tempbx = (USHORT)(tempeax & 0x0FFFF);
+  } else {
+     tempeax = SiS_Pr->SiS_VGAVDE << 6;
+     tempbx = push1 & 0x3f;
+     if(tempbx == 0) tempbx = 64;
+     tempeax /= tempbx;
+     tempbx = (USHORT)(tempeax & 0x0FFFF);
+  }
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) tempbx--;
+  if(SiS_Pr->SiS_SetFlag & EnableLVDSDDA) {
+     if((!SiS_Pr->SiS_IF_DEF_FSTN) && (!SiS_Pr->SiS_IF_DEF_DSTN)) tempbx = 1;
+     else if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480)  tempbx = 1;
+  }
+
+  temp = ((tempbx & 0xFF00) >> 8) << 3;
+  temp |= (USHORT)((tempecx & 0x0700) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x20,temp);  	/* Part1_20h; Overflow register */
+
+  temp = tempbx & 0x00FF;
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x21,temp);  	/* Part1_21h; Panel Link Vertical Accumulator Register */
+
+  tempecx >>= 16;                               /* BPLHCFACT  */
+  if((HwInfo->jChipType < SIS_315H) || (SiS_Pr->SiS_IF_DEF_FSTN) || (SiS_Pr->SiS_IF_DEF_DSTN)) {
+     if(modeflag & HalfDCLK) tempecx >>= 1;
+  }
+  temp = (USHORT)((tempecx & 0xFF00) >> 8);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x22,temp);     	/* Part1_22h; Panel Link Horizontal Scaling Factor High */
+
+  temp = (USHORT)(tempecx & 0x00FF);
+  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x23,temp);         /* Part1_22h; Panel Link Horizontal Scaling Factor Low */
+
+  /* 630/301B and 630/LVDS do something for 640x480 panels here */
+
+#ifdef SIS315H
+  if(SiS_Pr->SiS_IF_DEF_FSTN || SiS_Pr->SiS_IF_DEF_DSTN) {
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x25,0x00);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x26,0x00);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x27,0x00);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x28,0x87);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x29,0x5A);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2A,0x4B);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x007,0x03);
+     tempax = SiS_Pr->SiS_HDE;                       		/* Blps = lcdhdee(lcdhdes+HDE) + 64 */
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax += 64;
+     temp = tempax & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x35,~0x078,temp);
+     tempax += 32;		                     		/* Blpe=lBlps+32 */
+     temp = tempax & 0x00FF;
+     if(SiS_Pr->SiS_IF_DEF_FSTN) temp = 0;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3A,0x00);        	/* Bflml=0 */
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x007,0x00);
+
+     tempax = SiS_Pr->SiS_VDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax >>= 1;
+     temp = tempax & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3B,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x038,temp);
+
+     tempeax = SiS_Pr->SiS_HDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempeax >>= 1;
+     tempeax <<= 2;                       			/* BDxFIFOSTOP = (HDE*4)/128 */
+     tempebx = 128;
+     temp = (USHORT)(tempeax % tempebx);
+     tempeax = tempeax / tempebx;
+     if(temp) tempeax++;
+     temp = (USHORT)(tempeax & 0x003F);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x45,~0x0FF,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3F,0x00);         	/* BDxWadrst0 */
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3E,0x00);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3D,0x10);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x040,0x00);
+
+     tempax = SiS_Pr->SiS_HDE;
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempax >>= 4;                        			/* BDxWadroff = HDE*4/8/8 */
+     pushcx = tempax;
+     temp = tempax & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,temp);
+     temp = ((tempax & 0xFF00) >> 8) << 3;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x44,~0x0F8,temp);
+
+     tempax = SiS_Pr->SiS_VDE;                             	/* BDxWadrst1 = BDxWadrst0 + BDxWadroff * VDE */
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_2 ||
+        SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480_3) tempax >>= 1;
+     tempeax = (tempax * pushcx);
+     tempebx = 0x00100000 + tempeax;
+     temp = (USHORT)tempebx & 0x000000FF;
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,temp);
+     temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,temp);
+     temp = (USHORT)((tempebx & 0x00FF0000) >> 16);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,temp);
+     temp = (USHORT)(((tempebx & 0x01000000) >> 24) << 7);
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x3C,~0x080,temp);
+
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x03);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x03,0x50);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x04,0x00);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2F,0x01);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0x38);
+
+     if(SiS_Pr->SiS_IF_DEF_FSTN) {
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2b,0x02);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2c,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x35,0x0c);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x36,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x37,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x38,0x80);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x39,0xA0);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3a,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3b,0xf0);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3c,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3d,0x10);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3e,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x3f,0x00);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x40,0x10);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x41,0x25);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x42,0x80);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x43,0x14);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x44,0x03);
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x45,0x0a);
+     }
+  }
+#endif  /* SIS315H */
+
+}
+
+/************** Set Part 1 ***************/
+static void
+SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo, USHORT RefreshRateTableIndex)
+{
+  UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+  USHORT  temp=0, tempax=0, tempbx=0, tempcx=0;
+  USHORT  pushbx=0, CRT1Index=0;
+#ifdef SIS315H
+  USHORT  tempbl=0;
+#endif
+  USHORT  modeflag, resinfo=0;
+
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+     if(SiS_Pr->UseCustomMode) {
+	modeflag = SiS_Pr->CModeFlag;
+     } else {
+    	CRT1Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+
+#ifdef SIS315H
+     SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+     SiS_SetGroup1_LCDA(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+#endif
+
+  } else {
+
+     if( (HwInfo->jChipType >= SIS_315H) &&
+         (SiS_Pr->SiS_IF_DEF_LVDS == 1) &&
+	 (SiS_Pr->SiS_VBInfo & SetInSlaveMode) ) {
+
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
+     } else {
+
+        SiS_SetCRT2Offset(SiS_Pr, ModeNo, ModeIdIndex,
+      		          RefreshRateTableIndex, HwInfo);
+
+        if (HwInfo->jChipType < SIS_315H ) {
+#ifdef SIS300
+    	      SiS_SetCRT2FIFO_300(SiS_Pr, ModeNo, HwInfo);
+#endif
+        } else {
+#ifdef SIS315H
+              SiS_SetCRT2FIFO_310(SiS_Pr);
+#endif
+	}
+
+        SiS_SetCRT2Sync(SiS_Pr, ModeNo, RefreshRateTableIndex, HwInfo);
+
+	/* 1. Horizontal setup */
+
+        if (HwInfo->jChipType < SIS_315H ) {
+
+#ifdef SIS300   /* ------------- 300 series --------------*/
+
+    		temp = (SiS_Pr->SiS_VGAHT - 1) & 0x0FF;   			/* BTVGA2HT 0x08,0x09 */
+    		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                   /* CRT2 Horizontal Total */
+
+    		temp = (((SiS_Pr->SiS_VGAHT - 1) & 0xFF00) >> 8) << 4;
+    		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0f,temp);          /* CRT2 Horizontal Total Overflow [7:4] */
+
+    		temp = (SiS_Pr->SiS_VGAHDE + 12) & 0x0FF;                       /* BTVGA2HDEE 0x0A,0x0C */
+    		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                   /* CRT2 Horizontal Display Enable End */
+
+    		pushbx = SiS_Pr->SiS_VGAHDE + 12;                               /* bx  BTVGA@HRS 0x0B,0x0C */
+    		tempcx = (SiS_Pr->SiS_VGAHT - SiS_Pr->SiS_VGAHDE) >> 2;
+    		tempbx = pushbx + tempcx;
+    		tempcx <<= 1;
+    		tempcx += tempbx;
+
+    		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+		   if(SiS_Pr->UseCustomMode) {
+		      tempbx = SiS_Pr->CHSyncStart + 12;
+		      tempcx = SiS_Pr->CHSyncEnd + 12;
+		   }
+
+      		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+		      unsigned char cr4, cr14, cr5, cr15;
+		      if(SiS_Pr->UseCustomMode) {
+		         cr4  = SiS_Pr->CCRT1CRTC[4];
+			 cr14 = SiS_Pr->CCRT1CRTC[14];
+			 cr5  = SiS_Pr->CCRT1CRTC[5];
+			 cr15 = SiS_Pr->CCRT1CRTC[15];
+		      } else {
+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+		      }
+        	      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 1) << 3;
+        	      tempcx = (((cr5 & 0x1F) | ((cr15 & 0x04) << (6-2))) - 1) << 3;
+      		   }
+
+    		   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+        	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)){
+      			 tempbx = 1040;
+      			 tempcx = 1042;
+      		      }
+    		   }
+	        }
+
+    		temp = tempbx & 0x00FF;
+    		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                   /* CRT2 Horizontal Retrace Start */
+#endif /* SIS300 */
+
+ 	} else {
+
+#ifdef SIS315H  /* ------------------- 315/330 series --------------- */
+
+	        tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HT 0x08,0x09 */
+		if(modeflag & HalfDCLK) {
+		    if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+		          tempax = SiS_Pr->SiS_VGAHDE >> 1;
+			  tempcx = SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE + tempax;
+			  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+			      tempcx = SiS_Pr->SiS_HT - tempax;
+			  }
+		    } else {
+			  tempcx >>= 1;
+		    }
+		}
+		tempcx--;
+
+		temp = tempcx & 0xff;
+		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x08,temp);                  /* CRT2 Horizontal Total */
+
+		temp = ((tempcx & 0xff00) >> 8) << 4;
+		SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x09,0x0F,temp);         /* CRT2 Horizontal Total Overflow [7:4] */
+
+		tempcx = SiS_Pr->SiS_VGAHT;				       /* BTVGA2HDEE 0x0A,0x0C */
+		tempbx = SiS_Pr->SiS_VGAHDE;
+		tempcx -= tempbx;
+		tempcx >>= 2;
+		if(modeflag & HalfDCLK) {
+		   tempbx >>= 1;
+		   tempcx >>= 1;
+		}
+		tempbx += 16;
+
+		temp = tempbx & 0xff;
+		SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0A,temp);                  /* CRT2 Horizontal Display Enable End */
+
+		pushbx = tempbx;
+		tempcx >>= 1;
+		tempbx += tempcx;
+		tempcx += tempbx;
+
+		if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+		   if(SiS_Pr->UseCustomMode) {
+		      tempbx = SiS_Pr->CHSyncStart + 16;
+		      tempcx = SiS_Pr->CHSyncEnd + 16;
+		      tempax = SiS_Pr->SiS_VGAHT;
+		      if(modeflag & HalfDCLK) tempax >>= 1;
+		      tempax--;
+		      if(tempcx > tempax)  tempcx = tempax;
+		   }
+
+             	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+		      unsigned char cr4, cr14, cr5, cr15;
+		      if(SiS_Pr->UseCustomMode) {
+		         cr4  = SiS_Pr->CCRT1CRTC[4];
+			 cr14 = SiS_Pr->CCRT1CRTC[14];
+			 cr5  = SiS_Pr->CCRT1CRTC[5];
+			 cr15 = SiS_Pr->CCRT1CRTC[15];
+		      } else {
+		         cr4  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[4];
+			 cr14 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[14];
+			 cr5  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[5];
+			 cr15 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[15];
+		      }
+                      tempbx = ((cr4 | ((cr14 & 0xC0) << 2)) - 3) << 3; 		/* (VGAHRS-3)*8 */
+                      tempcx = (((cr5 & 0x1f) | ((cr15 & 0x04) << (5-2))) - 3) << 3; 	/* (VGAHRE-3)*8 */
+		      tempcx &= 0x00FF;
+		      tempcx |= (tempbx & 0xFF00);
+                      tempbx += 16;
+                      tempcx += 16;
+		      tempax = SiS_Pr->SiS_VGAHT;
+		      if(modeflag & HalfDCLK) tempax >>= 1;
+		      tempax--;
+		      if(tempcx > tempax)  tempcx = tempax;
+             	   }
+         	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+		      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+		         if(resinfo == SIS_RI_1024x768) {
+      		 	    tempbx = 1040;
+      		 	    tempcx = 1042;
+      	     	         }
+		      }
+         	   }
+#if 0
+		   /* Makes no sense, but is in 650/30xLV 1.10.6s */
+         	   if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (resinfo == SIS_RI_1024x768)){
+		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
+             	         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+      		 	    tempbx = 1040;
+      		 	    tempcx = 1042;
+      	     	         }
+		      }
+         	   }
+#endif
+                }
+
+		temp = tempbx & 0xff;
+	 	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0B,temp);                 /* CRT2 Horizontal Retrace Start */
+#endif  /* SIS315H */
+
+     	}  /* 315/330 series */
+
+  	/* The following is done for all bridge/chip types/series */
+
+  	tempax = tempbx & 0xFF00;
+  	tempbx = pushbx;
+  	tempbx = (tempbx & 0x00FF) | ((tempbx & 0xFF00) << 4);
+  	tempax |= (tempbx & 0xFF00);
+  	temp = (tempax & 0xFF00) >> 8;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0C,temp);                        /* Overflow */
+
+  	temp = tempcx & 0x00FF;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0D,temp);                        /* CRT2 Horizontal Retrace End */
+
+  	/* 2. Vertical setup */
+
+  	tempcx = SiS_Pr->SiS_VGAVT - 1;
+  	temp = tempcx & 0x00FF;
+
+        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+	   if(HwInfo->jChipType < SIS_315H) {
+	      if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	         if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSVIDEO | SetCRT2ToAVIDEO)) {
+	            temp--;
+	         }
+              }
+	   } else {
+ 	      temp--;
+           }
+        } else if(HwInfo->jChipType >= SIS_315H) {
+	   /* 650/30xLV 1.10.6s */
+	   temp--;
+	}
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0E,temp);                        /* CRT2 Vertical Total */
+
+  	tempbx = SiS_Pr->SiS_VGAVDE - 1;
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x0F,temp);                        /* CRT2 Vertical Display Enable End */
+
+  	temp = ((tempbx & 0xFF00) << 3) >> 8;
+  	temp |= ((tempcx & 0xFF00) >> 8);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x12,temp);                        /* Overflow (and HWCursor Test Mode) */
+
+	/* 650/LVDS (1.10.07), 650/30xLV (1.10.6s) */
+	if(HwInfo->jChipType >= SIS_315H) {
+           tempbx++;
+   	   tempax = tempbx;
+	   tempcx++;
+	   tempcx -= tempax;
+	   tempcx >>= 2;
+	   tempbx += tempcx;
+	   if(tempcx < 4) tempcx = 4;
+	   tempcx >>= 2;
+	   tempcx += tempbx;
+	   tempcx++;
+	} else {
+	   /* 300 series, LVDS/301B: */
+  	   tempbx = (SiS_Pr->SiS_VGAVT + SiS_Pr->SiS_VGAVDE) >> 1;                 /*  BTVGA2VRS     0x10,0x11   */
+  	   tempcx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) >> 4) + tempbx + 1;  /*  BTVGA2VRE     0x11        */
+	}
+
+  	if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+	   if(SiS_Pr->UseCustomMode) {
+	      tempbx = SiS_Pr->CVSyncStart;
+	      tempcx = (tempcx & 0xFF00) | (SiS_Pr->CVSyncEnd & 0x00FF);
+	   }
+
+    	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {
+	      unsigned char cr8, cr7, cr13, cr9;
+	      if(SiS_Pr->UseCustomMode) {
+	         cr8  = SiS_Pr->CCRT1CRTC[8];
+		 cr7  = SiS_Pr->CCRT1CRTC[7];
+		 cr13 = SiS_Pr->CCRT1CRTC[13];
+		 cr9  = SiS_Pr->CCRT1CRTC[9];
+	      } else {
+	         cr8  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[8];
+		 cr7  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[7];
+		 cr13 = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[13];
+		 cr9  = SiS_Pr->SiS_CRT1Table[CRT1Index].CR[9];
+	      }
+      	      tempbx = cr8;
+      	      if(cr7 & 0x04)  tempbx |= 0x0100;
+      	      if(cr7 & 0x80)  tempbx |= 0x0200;
+      	      if(cr13 & 0x08) tempbx |= 0x0400;
+      	      tempcx = (tempcx & 0xFF00) | (cr9 & 0x00FF);
+    	   }
+  	}
+  	temp = tempbx & 0x00FF;
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x10,temp);           /* CRT2 Vertical Retrace Start */
+
+  	temp = ((tempbx & 0xFF00) >> 8) << 4;
+  	temp |= (tempcx & 0x000F);
+  	SiS_SetReg(SiS_Pr->SiS_Part1Port,0x11,temp);           /* CRT2 Vert. Retrace End; Overflow; "Enable CRTC Check" */
+
+  	/* 3. Panel compensation delay */
+
+  	if(HwInfo->jChipType < SIS_315H) {
+
+#ifdef SIS300  /* ---------- 300 series -------------- */
+
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+	        temp = 0x20;
+
+		if(HwInfo->jChipType == SIS_300) {
+		   temp = 0x10;
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+		}
+		if(SiS_Pr->SiS_VBType & VB_SIS301) {
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+		}
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)     temp = 0x24;
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)       temp = 0x2c;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) 		temp = 0x08;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+      		   if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) 	temp = 0x2c;
+      		   else 					temp = 0x20;
+    	        }
+		if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+		    if(ROMAddr[0x220] & 0x80) {
+		        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV-SetCRT2ToHiVisionTV))
+				temp = ROMAddr[0x221];
+			else if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)
+				temp = ROMAddr[0x222];
+		        else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)
+				temp = ROMAddr[0x223];
+			else
+				temp = ROMAddr[0x224];
+			temp &= 0x3c;
+		    }
+		}
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		   if(HwInfo->pdc) {
+			temp = HwInfo->pdc & 0x3c;
+		   }
+		}
+	   } else {
+	        temp = 0x20;
+		if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
+		   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) temp = 0x04;
+		}
+		if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+		    if(ROMAddr[0x220] & 0x80) {
+		        temp = ROMAddr[0x220] & 0x3c;
+		    }
+		}
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+		   if(HwInfo->pdc) {
+		      temp = HwInfo->pdc & 0x3c;
+		   }
+		}
+	   }
+
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x13,~0x03C,temp);         /* Panel Link Delay Compensation; (Software Command Reset; Power Saving) */
+
+#endif  /* SIS300 */
+
+  	} else {
+
+#ifdef SIS315H   /* --------------- 315/330 series ---------------*/
+
+	   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+                temp = 0x10;
+                if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  temp = 0x2c;
+    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x20;
+    	        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960)  temp = 0x24;
+		if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom)    temp = 0x2c;
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+		   temp = 0x08;
+		   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+		      switch(SiS_Pr->SiS_HiVision) {
+		      case 2:
+		      case 1:
+		      case 0:
+		         temp = 0x08;
+			 break;
+		      default:
+      		         if(SiS_Pr->SiS_VBInfo & SetInSlaveMode)  temp = 0x2c;
+      		         else 					  temp = 0x20;
+		      }
+    	           }
+		}
+		if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+		   tempbl = 0x00;
+		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+		      if(HwInfo->jChipType < SIS_330) {
+		         if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
+		      } else {
+		         if(ROMAddr[0x1bc] & 0x80) tempbl = 0xf0;
+		      }
+		   }
+		} else {  /* LV (550/301LV checks ROM byte, other LV BIOSes do not) */
+		   tempbl = 0xF0;
+		}
+		if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {
+		   if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+		      if(HwInfo->pdc) {
+		         temp = HwInfo->pdc;
+		         tempbl = 0;
+		      }
+		   }
+		}
+	   } else {
+	        if(HwInfo->jChipType == SIS_740) {
+		   temp = 0x03;
+	        } else {
+		   temp = 0x00;
+		}
+		if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) temp = 0x0a;
+		tempbl = 0xF0;
+		if(HwInfo->jChipType == SIS_650) {
+		   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+		      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) tempbl = 0x0F;
+		   }
+		}
+
+		if(SiS_Pr->SiS_IF_DEF_DSTN || SiS_Pr->SiS_IF_DEF_FSTN) {
+		   temp = 0x08;
+		   tempbl = 0;
+		   if((ROMAddr) && (SiS_Pr->SiS_UseROM)) {
+		      if(ROMAddr[0x13c] & 0x80) tempbl = 0xf0;
+		   }
+		}
 	   }
-	}
-     }
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,tempbl,temp);	    /* Panel Link Delay Compensation */
 
-     if(modeflag & HalfDCLK) {
-        if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
-           if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-	      if(!(((SiS_Pr->SiS_IF_DEF_LVDS == 1) || (HwDeviceExtension->jChipType < SIS_315H)) &&
-	                                      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480))) {
-                 if(ModeNo > 0x13) {
-                    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-                       if(resinfo == 4) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 512x384  */
-                    } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) {
-                       if(resinfo == 3) SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;     /* 400x300  */
-                    }
-                 }
-	      } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-           } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-        } else SiS_Pr->SiS_SetFlag |= EnableLVDSDDA;
-     }
+    	   tempax = 0;
+    	   if (modeflag & DoubleScanMode) tempax |= 0x80;
+    	   if (modeflag & HalfDCLK)       tempax |= 0x40;
+    	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2C,0x3f,tempax);
 
-  }
+#endif  /* SIS315H */
 
-  if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-    	if(SiS_Pr->SiS_VBInfo & SetNotSimuMode) {
-      		SiS_Pr->SiS_SetFlag |= LCDVESATiming;
-    	}
-  } else {
-    	SiS_Pr->SiS_SetFlag |= LCDVESATiming;
-  }
+  	}
 
-#ifdef SIS315H
-  /* TW: 650/30xLV 1.10.6s */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-    if(SiS_Pr->SiS_VBType & (VB_SIS302B | VB_SIS302LV)) {
-      /* Enable 302B/302LV dual link mode */
-      /* (302B is a theory - not in any BIOS */
-      temp = 0x00;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) temp = 0x04;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) temp = 0x04;
-      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) temp = 0x04;
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,temp);
-    } else if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-      SiS_SetReg1(SiS_Pr->SiS_P3d4,0x39,0x00);
-    }
-  }
-#endif
+     }  /* Slavemode */
 
-#ifdef LINUX_KERNEL
-#ifdef TWDEBUG
-  printk(KERN_DEBUG "sisfb: (LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x)\n",
-	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo);
-#endif
-#endif
-#ifdef LINUX_XF86
-  xf86DrvMsgVerb(0, X_PROBED, 3, 
-  	"(init301: LCDInfo=0x%04x LCDResInfo=0x%02x LCDTypeInfo=0x%02x SetFlag=0x%04x)\n",
-	SiS_Pr->SiS_LCDInfo, SiS_Pr->SiS_LCDResInfo, SiS_Pr->SiS_LCDTypeInfo, SiS_Pr->SiS_SetFlag);
-#endif
+     if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
 
-  return 1;
-}
+        /* For 301BDH with LCD, we set up the Panel Link */
+        if( (SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) ) {
 
-void
-SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  return;
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x30,0x21);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x31,0x41);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x28);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x33,0x22);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,0x43);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x36,0x01);  */
-  /*SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,0x00);  */
-}
+	    SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
+	                       HwInfo, RefreshRateTableIndex);
 
-void
-SiS_LongWait(SiS_Private *SiS_Pr)
-{
-  USHORT i;
+        } else if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
 
-  i = SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1F);
+    	    SiS_SetGroup1_301(SiS_Pr, ModeNo, ModeIdIndex,
+	                      HwInfo, RefreshRateTableIndex);
+        }
 
-  if(!(i & 0xC0)) {
-    for(i=0; i<0xFFFF; i++) {
-       if(!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
-         break;
-    }
-    for(i=0; i<0xFFFF; i++) {
-       if((SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08))
-         break;
-    }
-  }
-}
+     } else {
 
-void
-SiS_VBLongWait(SiS_Private *SiS_Pr)
-{
-  if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-    SiS_VBWait(SiS_Pr);
-  } else {
-    SiS_LongWait(SiS_Pr);
-  }
-  return;
-}
+        if(HwInfo->jChipType < SIS_315H) {
 
-void
-SiS_VBWait(SiS_Private *SiS_Pr)
-{
-  USHORT tempal,temp,i,j;
+	   SiS_SetGroup1_LVDS(SiS_Pr, ModeNo, ModeIdIndex,
+	                        HwInfo, RefreshRateTableIndex);
+	} else {
 
-  temp = 0;
-  for(i=0; i<3; i++) {
-    for(j=0; j<100; j++) {
-       tempal = SiS_GetReg2(SiS_Pr->SiS_P3da);
-       if(temp & 0x01) {
-          if((tempal & 0x08))  continue;
-          if(!(tempal & 0x08)) break;
-       } else {
-          if(!(tempal & 0x08)) continue;
-          if((tempal & 0x08))  break;
-       }
-    }
-    temp ^= 0x01;
-  }
-}
+	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+              if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+    	          SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
+	                              HwInfo,RefreshRateTableIndex);
+              }
+	   } else {
+	      SiS_SetGroup1_LVDS(SiS_Pr, ModeNo,ModeIdIndex,
+	                         HwInfo,RefreshRateTableIndex);
+	   }
+
+	}
 
-void
-SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-#ifdef SIS300
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x20)) return;
-     }
-     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x80)) {
-        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
-     } else {
-        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
-     }
-#endif
-  } else {
-#ifdef SIS315H
-     if(!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x40)) {
-        SiS_WaitRetrace1(SiS_Pr,HwDeviceExtension);
-     } else {
-        SiS_WaitRetrace2(SiS_Pr,HwDeviceExtension);
      }
-#endif
-  }
+  } /* LCDA */
 }
 
-void
-SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT watchdog;
-#ifdef SIS300
-  USHORT i;
-#endif
+/*********************************************/
+/*         SET PART 2 REGISTER GROUP         */
+/*********************************************/
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
 #ifdef SIS315H
-     if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-     watchdog = 65535;
-     while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
-     watchdog = 65535;
-     while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
-#endif
-  } else {
-#ifdef SIS300
-#if 0  /* TW: Not done in A901 BIOS */
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-        if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-     }
-#endif
-     for(i=0; i<10; i++) {
-        watchdog = 65535;
-        while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
-	if(watchdog) break;
-     }
-     for(i=0; i<10; i++) {
-        watchdog = 65535;
-        while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
-	if(watchdog) break;
-     }
-#endif
-  }
-}
-
-void
-SiS_WaitRetraceDDC(SiS_Private *SiS_Pr)
+static void
+SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+		    USHORT RefreshRateTableIndex,USHORT *CRT2Index,
+		    USHORT *ResIndex,PSIS_HW_INFO HwInfo)
 {
-  USHORT watchdog;
+  USHORT tempbx,tempal;
 
-  if(SiS_GetReg1(SiS_Pr->SiS_P3c4,0x1f) & 0xc0) return;
-  watchdog = 65535;
-  while( (SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08) && --watchdog);
-  watchdog = 65535;
-  while( (!(SiS_GetReg2(SiS_Pr->SiS_P3da) & 0x08)) && --watchdog);
-}
+  if(ModeNo <= 0x13)
+      	tempal = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  else
+      	tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
 
-void
-SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT watchdog;
-#ifdef SIS300
-  USHORT i;
-#endif
+  tempbx = SiS_Pr->SiS_LCDResInfo;
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-     watchdog = 65535;
-     while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02) && --watchdog);
-     watchdog = 65535;
-     while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x30) & 0x02)) && --watchdog);
-#endif
-  } else {
-#ifdef SIS300
-     for(i=0; i<10; i++) {
-        watchdog = 65535;
-	while( (SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02) && --watchdog);
-	if(watchdog) break;
+  if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx += 16;
+  else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx += 32;
+
+  if(SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        tempbx = 100;
+        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 101;
+  	else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 102;
      }
-     for(i=0; i<10; i++) {
-        watchdog = 65535;
-	while( (!(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x25) & 0x02)) && --watchdog);
-	if(watchdog) break;
+  } else if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+           tempbx = 103;
+           if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)      tempbx = 104;
+  	   else if(SiS_Pr->SiS_SetFlag & LCDVESATiming) tempbx = 105;
+	}
      }
-#endif
   }
-}
 
-/* =========== Set and Get register routines ========== */
+  *CRT2Index = tempbx;
+  *ResIndex = tempal & 0x3F;
+}
+#endif
 
-void
-SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR)
+#ifdef SIS300
+/* For ECS A907. Highly preliminary. */
+static void
+SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+    		    USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
+		    USHORT ModeNo)
 {
-  USHORT temp;
+  USHORT crt2crtc, resindex;
+  int    i,j;
+  const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
 
-  temp = SiS_GetReg1(Port,Index);    
-  temp = (temp & (DataAND)) | DataOR;
-  SiS_SetReg1(Port,Index,temp);
-}
+  if(HwInfo->jChipType != SIS_300) return;
+  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  if(SiS_Pr->UseCustomMode) return;
 
-void
-SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND)
-{
-  USHORT temp;
+  if(ModeNo <= 0x13) {
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+     crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+  }
 
-  temp = SiS_GetReg1(Port,Index);    
-  temp &= DataAND;
-  SiS_SetReg1(Port,Index,temp);
-}
+  resindex = crt2crtc & 0x3F;
+  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
 
-void SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR)
-{
-  USHORT temp;
+  /* The BIOS code (1.16.51) is obviously a fragment! */
+  if(ModeNo > 0x13) {
+     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
+     resindex = 4;
+  }
 
-  temp = SiS_GetReg1(Port,Index);    
-  temp |= DataOR;
-  SiS_SetReg1(Port,Index,temp);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
+  for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  for(j = 0x1c; j <= 0x1d; i++, j++ ) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  for(j = 0x1f; j <= 0x21; i++, j++ ) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
 }
+#endif
 
-/* ========================================================= */
+#ifdef SIS315H
+static void
+SiS_SetTVSpecial(SiS_Private *SiS_Pr, USHORT ModeNo)
+{
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+           if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1d,0x07);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x20,0x17);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,0x8b);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x22,0x73);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,0x53);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,0x13);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x25,0x40);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x26,0x34);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,0xf4);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x28,0x63);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x29,0xbb);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2c,0x58);   /* 48 */
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2e,0x73);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,0xda);   /* de */
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0x13);
+	      if((SiS_GetReg(SiS_Pr->SiS_P3d4,0x38)) & 0x40) {
+	         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x14);
+	      } else {
+	         SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x15);
+	      }
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1b);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,0x72);
+           }
+        } else {
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x21);
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x5a);
+	}
+     } else {
+     }
+  }
+}
+#endif
 
-/* TW: Set 301 TV Encoder (and some LCD relevant) registers */
-void
-SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr, USHORT ModeNo,
-              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/* Set 301 TV Encoder (and some LCD relevant) registers */
+static void
+SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
+	      PSIS_HW_INFO HwInfo)
 {
   USHORT      i, j, tempax, tempbx, tempcx, temp, temp1;
   USHORT      push1, push2;
   const       UCHAR *PhasePoint;
   const       UCHAR *TimingPoint;
-#ifdef SIS315H   
+#ifdef SIS315H
   const       SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
   USHORT      resindex, CRT2Index;
-#endif  
+#endif
   USHORT      modeflag, resinfo, crt2crtc;
-  ULONG       longtemp, tempeax, tempebx, temp2, tempecx;
+  ULONG       longtemp, tempeax;
+#ifdef SIS300
   const UCHAR atable[] = {
                  0xc3,0x9e,0xc3,0x9e,0x02,0x02,0x02,
 	         0xab,0x87,0xab,0x9e,0xe7,0x02,0x02
   };
+#endif
 
 #ifdef SIS315H   
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-     /* TW: 650/30xLV 1.10.6s: (Is at end of SetGroup2!) */
-     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);
-	   temp = 1;
-	   if(ModeNo <= 0x13) temp = 3;
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
-	}
-     }
-     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-           if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-           }
-         }
-       }
-     }
-     return;
-  }
-#endif  
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
+#endif
 
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;      /* si+St_ResInfo */
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;     /* si+Ext_ResInfo */
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+	crt2crtc = 0;
+     } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
     	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
     	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+     }
   }
 
   tempcx = SiS_Pr->SiS_VBInfo;
@@ -6984,96 +7213,95 @@
   temp |= ((tempbx & 0x00FF) >> 3);
   temp ^= 0x0C;
 
-  /* TW: From 1.10.7w (no vb check there; don't care - this only disables SVIDEO and CVBS signal) */
-  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-  	temp |= 0x0c;
-  }
+  /* Disables SVIDEO and CVBS signal */
+  if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+     temp |= 0x0c;
+  }
+
+  PhasePoint  = SiS_Pr->SiS_PALPhase;
+  TimingPoint = SiS_Pr->SiS_PALTiming;
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
+
+     temp ^= 0x01;
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
+        if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+           if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
+           else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
+        }
+     } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
+
+     if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
 
-  PhasePoint  = SiS_Pr->SiS_PALPhase;
-  TimingPoint = SiS_Pr->SiS_PALTiming;
-  
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {          
-  
-    temp ^= 0x01;
-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      TimingPoint = SiS_Pr->SiS_HiTVSt2Timing;
-      if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-        if(modeflag & Charx8Dot) TimingPoint = SiS_Pr->SiS_HiTVSt1Timing;
-        else TimingPoint = SiS_Pr->SiS_HiTVTextTiming;
-      }
-    } else TimingPoint = SiS_Pr->SiS_HiTVExtTiming;
-    
-    if(SiS_Pr->SiS_HiVision & 0x03) temp &= 0xfe;
-    
   } else {
-  
-    if(SiS_Pr->SiS_VBInfo & SetPALTV){
 
-      TimingPoint = SiS_Pr->SiS_PALTiming;
-      PhasePoint  = SiS_Pr->SiS_PALPhase;
+     if(SiS_Pr->SiS_VBInfo & SetPALTV){
 
-      if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-          ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-	    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-         PhasePoint = SiS_Pr->SiS_PALPhase2;
-      }
+        TimingPoint = SiS_Pr->SiS_PALTiming;
+        PhasePoint  = SiS_Pr->SiS_PALPhase;
 
-    } else {
+        if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+            ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+           PhasePoint = SiS_Pr->SiS_PALPhase2;
+        }
+
+     } else {
 
         temp |= 0x10;
-	TimingPoint = SiS_Pr->SiS_NTSCTiming;
-	PhasePoint  = SiS_Pr->SiS_NTSCPhase;
+        TimingPoint = SiS_Pr->SiS_NTSCTiming;
+        PhasePoint  = SiS_Pr->SiS_NTSCPhase;
 
-        if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
+        if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
 	    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
 	      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-        	PhasePoint = SiS_Pr->SiS_NTSCPhase2;
+           PhasePoint = SiS_Pr->SiS_NTSCPhase2;
         }
 
-    }
-    
+     }
+
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x00,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x00,temp);
 
   temp = 0;
-  if((HwDeviceExtension->jChipType == SIS_630)||
-     (HwDeviceExtension->jChipType == SIS_730)) {
+  if((HwInfo->jChipType == SIS_630)||
+     (HwInfo->jChipType == SIS_730)) {
      temp = 0x35;
   }
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  if(HwInfo->jChipType >= SIS_315H) {
      temp = 0x38;
   }
   if(temp) {
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-          temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,temp);
-          if(temp1 & EnablePALM) {	/* 0x40 */
-              	PhasePoint = SiS_Pr->SiS_PALMPhase;
-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-	           PhasePoint = SiS_Pr->SiS_PALMPhase2;
-		}
-	  }
-          if(temp1 & EnablePALN) {	/* 0x80 */
-               	PhasePoint = SiS_Pr->SiS_PALNPhase;
-		if( (SiS_Pr->SiS_VBType & VB_SIS301B302B) &&
-		    ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
-		      (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
-	           PhasePoint = SiS_Pr->SiS_PALNPhase2;
-		}
-	  }
-      }
-    }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,temp);
+           if(temp1 & EnablePALM) {	/* 0x40 */
+              PhasePoint = SiS_Pr->SiS_PALMPhase;
+	      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	         PhasePoint = SiS_Pr->SiS_PALMPhase2;
+	      }
+	   }
+           if(temp1 & EnablePALN) {	/* 0x80 */
+              PhasePoint = SiS_Pr->SiS_PALNPhase;
+	      if( (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) &&
+		  ( (!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) ||
+		    (SiS_Pr->SiS_SetFlag & TVSimuMode) ) ) {
+	         PhasePoint = SiS_Pr->SiS_PALNPhase2;
+	      }
+	   }
+        }
+     }
   }
 
 #ifdef SIS315H
-  /* TW: 650/301LV BIOS */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  if(HwInfo->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {  
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
            if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-              if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
+              if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
 	         PhasePoint = SiS_Pr->SiS_SpecialPhase;
 	      }
            }
@@ -7083,38 +7311,38 @@
 #endif
 
   for(i=0x31, j=0; i<=0x34; i++, j++) {
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,PhasePoint[j]);
   }
 
   for(i=0x01, j=0; i<=0x2D; i++, j++) {
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
   for(i=0x39; i<=0x45; i++, j++) {
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,TimingPoint[j]);
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(!(SiS_Pr->SiS_ModeType & 0x07))
+     if(HwInfo->jChipType >= SIS_315H) {
+        if(!(SiS_Pr->SiS_ModeType & 0x07))
+           SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
+     } else {
         SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-    } else {
-      SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x3A,0x1F);
-    }
+     }
   }
 
   SiS_SetRegOR(SiS_Pr->SiS_Part2Port,0x0A,SiS_Pr->SiS_NewFlickerMode);
 
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x35,SiS_Pr->SiS_RY1COE);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x36,SiS_Pr->SiS_RY2COE);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x37,SiS_Pr->SiS_RY3COE);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x38,SiS_Pr->SiS_RY4COE);
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-      if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
-      else tempax = 440;
+     if(SiS_Pr->SiS_HiVision == 3) tempax = 950;
+     else tempax = 440;
   } else {
-    if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
-    else tempax = 440;
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) tempax = 520;
+     else tempax = 440;
   }
 
   if( ( ( (!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) || (SiS_Pr->SiS_HiVision == 3) ) && (SiS_Pr->SiS_VDE <= tempax) ) ||
@@ -7127,25 +7355,25 @@
 
      temp = (tempax & 0xFF00) >> 8;
      temp += (USHORT)TimingPoint[0];
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
      temp = (tempax & 0xFF00) >> 8;
      temp += (USHORT)TimingPoint[1];
-     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
 
      if( (SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
-        (SiS_Pr->SiS_HiVision != 3) &&
-        (SiS_Pr->SiS_VGAHDE >= 1024) ) {
+         (SiS_Pr->SiS_HiVision != 3) &&
+         (SiS_Pr->SiS_VGAHDE >= 1024) ) {
         if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x19);
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x52);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x19);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x52);
         } else {
-           if(HwDeviceExtension->jChipType >= SIS_315H) {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x17);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x1d);
+           if(HwInfo->jChipType >= SIS_315H) {
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x17);
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x1d);
 	   } else {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x0b);
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x11);
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x0b);
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x11);
 	   }
         }
      }
@@ -7154,11 +7382,9 @@
 
   tempcx = SiS_Pr->SiS_HT;
 
-  /* TW: 650/30xLV 1.10.6s */
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-      	   tempcx >>= 1;
-      }
+  /* 650/30xLV 1.10.6s */
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+     tempcx >>= 1;
   }
 
   tempcx--;
@@ -7166,7 +7392,7 @@
         tempcx--;
   }
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1B,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1B,temp);
   temp = (tempcx & 0xFF00) >> 8;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0xF0,temp);
 
@@ -7181,7 +7407,7 @@
   tempcx += 7;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-       tempcx -= 4;
+     tempcx -= 4;
   }
   temp = (tempcx & 0x00FF) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x22,0x0F,temp);
@@ -7192,7 +7418,7 @@
   push2 = tempbx;
 
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x24,temp);
   temp = ((tempbx & 0xFF00) >> 8) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0F,temp);
 
@@ -7201,8 +7427,8 @@
   tempbx += 8;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-    tempbx -= 4;
-    tempcx = tempbx;
+     tempbx -= 4;
+     tempcx = tempbx;
   }
   temp = (tempbx & 0x00FF) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x29,0x0F,temp);
@@ -7210,7 +7436,7 @@
   j += 2;
   tempcx += ((TimingPoint[j] | ((TimingPoint[j+1]) << 8)));
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x27,temp);
   temp = ((tempcx & 0xFF00) >> 8) << 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x28,0x0F,temp);
 
@@ -7231,363 +7457,333 @@
 
   tempcx -= 11;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) {
-    tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
-    tempcx = tempax;
+     tempax = SiS_GetVGAHT2(SiS_Pr) - 1;
+     tempcx = tempax;
   }
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2E,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2E,temp);
 
   tempbx = SiS_Pr->SiS_VDE;
   if(SiS_Pr->SiS_VGAVDE == 360) tempbx = 746;
   if(SiS_Pr->SiS_VGAVDE == 375) tempbx = 746;
   if(SiS_Pr->SiS_VGAVDE == 405) tempbx = 853;
-  if(HwDeviceExtension->jChipType < SIS_315H) {
-  	if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
+  if(HwInfo->jChipType < SIS_315H) {
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) tempbx >>= 1;
   } else {
-	if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-	   tempbx >>= 1;
-	   if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-	      if(ModeNo <= 0x13) {
-	         if(crt2crtc == 1) {
-	            tempbx++;
-                 }
-	      }
-	   } else {
-              if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-	         if(crt2crtc == 4)   /* TW: BIOS calls GetRatePtrCRT2 here - does not make sense */
-                    if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
-	      }
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+	tempbx >>= 1;
+	if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+	   if(ModeNo <= 0x13) {
+	      if(crt2crtc == 1) {
+	         tempbx++;
+              }
 	   }
-        }
+	} else {
+           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	      if(crt2crtc == 4)   /* BIOS calls GetRatePtrCRT2 here - does not make sense */
+                 if(SiS_Pr->SiS_ModeType <= 3) tempbx++;
+	   }
+	}
+     }
   }
   tempbx -= 2;
   temp = tempbx & 0x00FF;
   if((SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
      (SiS_Pr->SiS_HiVision == 3)) {
-    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-      if(ModeNo == 0x2f) temp++;
-    }
+     if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+        if((ModeNo == 0x2f) || (ModeNo == 0x5d) || (ModeNo == 0x5e)) temp++;
+     }
   }
-  /* TW: From 1.10.7w - doesn't make sense */
+  /* From 1.10.7w - doesn't make sense */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
         if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
 	   if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {   /* SetFlag?? */
-	       if(ModeNo == 0x03) temp++;
+	      if(ModeNo == 0x03) temp++;
 	   }
 	}
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2F,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2F,temp);
 
   tempax = (tempcx & 0xFF00) | (tempax & 0x00FF);
   tempbx = ((tempbx & 0xFF00) << 6) | (tempbx & 0x00FF);
   tempax |= (tempbx & 0xFF00);
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwInfo->jChipType < SIS_315H) {
      if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) {
-        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {		/* TW: New from 630/301B (II) BIOS */
+        if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSCART)) {
            tempax |= 0x1000;
            if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
         }
      }
   } else {
      /* TODO Check this with other BIOSes */
-     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV)) && 
-        (SiS_Pr->SiS_HiVision == 3)) {
+     if((!(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV))
+         /* && (SiS_Pr->SiS_HiVision == 3) */ ) {
 	tempax |= 0x1000;
         if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToSVIDEO))  tempax |= 0x2000;
      }
   }
   temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,temp);
 
-  /* TW: 650/30xLV 1.10.6s */
-  if(HwDeviceExtension->jChipType > SIS_315H) {
+  if(HwInfo->jChipType > SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if( (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
             (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) ) {
-            SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
+           SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x10,0x60);
         }
      }
   }
-  
+
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
      if(SiS_Pr->SiS_HiVision != 3) {
 	for(i=0, j=0; i<=0x2d; i++, j++) {
-	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
+	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
 	}
 	for(i=0x39; i<=0x45; i++, j++) {
-	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
+	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS_HiVisionTable[SiS_Pr->SiS_HiVision][j]);
 	}
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {     
-    tempbx = SiS_Pr->SiS_VDE;
-    if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-         tempbx >>= 1;
-    }
-    tempbx -= 3;
-    tempbx &= 0x03ff;
-    temp = ((tempbx & 0xFF00) >> 8) << 5;
-    temp |= 0x18;
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x46,temp);
-    temp = tempbx & 0x00FF;
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x47,temp);	/* tv gatingno */
-    if(HwDeviceExtension->jChipType >= SIS_315H) {	/* TW: 650/30xLV 1.10.6s */
-       if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-          tempax = 0;
-          if(SiS_Pr->SiS_HiVision & 0x03) {
-	     tempax = 0x3000;
-	     if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
-	  }
-	  temp = (tempax & 0xFF00) >> 8;
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4d,temp);
-       }
-    }
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     tempbx = SiS_Pr->SiS_VDE;
+     if((SiS_Pr->SiS_VBInfo & SetCRT2ToTV) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
+        tempbx >>= 1;
+     }
+     tempbx -= 3;
+     tempbx &= 0x03ff;
+     temp = ((tempbx & 0xFF00) >> 8) << 5;
+     temp |= 0x18;
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x46,temp);
+     temp = tempbx & 0x00FF;
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x47,temp);
+     if(HwInfo->jChipType >= SIS_315H) {
+        if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+           tempax = 0;
+           if(SiS_Pr->SiS_HiVision & 0x03) {
+ 	      tempax = 0x3000;
+	      if(SiS_Pr->SiS_HiVision & 0x01) tempax = 0x5000;
+	   }
+	   temp = (tempax & 0xFF00) >> 8;
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4d,temp);
+        }
+     }
   }
 
   tempbx &= 0x00FF;
   if(!(modeflag & HalfDCLK)) {
-    tempcx = SiS_Pr->SiS_VGAHDE;
-    if(tempcx >= SiS_Pr->SiS_HDE) {
-      tempbx |= 0x2000;
-      tempax &= 0x00FF;
-    }
+     if(SiS_Pr->SiS_VGAHDE >= SiS_Pr->SiS_HDE) {
+        tempbx |= 0x2000;
+        tempax &= 0x00FF;
+     }
   }
 
   tempcx = 0x0101;
-/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /*301b- TW: BIOS BUG? */
+/*if(SiS_Pr->SiS_VBInfo & (SetPALTV | SetCRT2ToTV)) {  */ /* BIOS BUG? */
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) {
-    if(!(SiS_Pr->SiS_HiVision & 0x03)) {
-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
-        if((!(modeflag & HalfDCLK)) || (HwDeviceExtension->jChipType < SIS_315H)) {   /* TW: This check not in 630/301B */
-          tempcx = 0x1920;
-          if(SiS_Pr->SiS_VGAHDE >= 1280) {
-            tempcx = 0x1420;
-            tempbx &= 0xDFFF;
-          }
+     if(!(SiS_Pr->SiS_HiVision & 0x03)) {
+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
+           if((!(modeflag & HalfDCLK)) || (HwInfo->jChipType < SIS_315H)) {
+              tempcx = 0x1920;
+              if(SiS_Pr->SiS_VGAHDE >= 1280) {
+                 tempcx = 0x1420;
+                 tempbx &= 0xDFFF;
+              }
+           }
         }
-      }
-    }
+     }
   }
 
   if(!(tempbx & 0x2000)) {
-    if(modeflag & HalfDCLK) {
-         tempcx = (tempcx & 0xFF00) | (((tempcx & 0x00FF) << 1) & 0xff);
-    }
-    push1 = tempbx;
-    tempeax = SiS_Pr->SiS_VGAHDE;
-    tempebx = (tempcx & 0xFF00) >> 8;
-    longtemp = tempeax * tempebx;
-    tempecx = tempcx & 0x00FF;
-    longtemp /= tempecx;
-    longtemp <<= 0x0d;
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     if(modeflag & HalfDCLK) {
+        tempcx = (tempcx & 0xFF00) | ((tempcx << 1) & 0x00FF);
+     }
+     longtemp = (SiS_Pr->SiS_VGAHDE * ((tempcx & 0xFF00) >> 8)) / (tempcx & 0x00FF);
+     longtemp <<= 13;
+     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
      	longtemp <<= 3;
-    }
-    tempecx = SiS_Pr->SiS_HDE;
-    temp2 = longtemp % tempecx;
-    tempeax = longtemp / tempecx;
-    if(temp2 != 0) tempeax++;
-    tempax = (USHORT)tempeax;
-    tempbx = push1;
-    tempcx = (tempcx & 0xff00) | (((tempax & 0xFF00) >> 8) >> 5);
-    tempbx |= (tempax & 0x1F00);
-    tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
+     }
+     tempeax = longtemp / SiS_Pr->SiS_HDE;
+     if(longtemp % SiS_Pr->SiS_HDE) tempeax++;
+     tempax = (USHORT)tempeax;
+     tempcx = (tempcx & 0xFF00) | ((tempax & 0xFF00) >> (8 + 5));
+     tempbx |= (tempax & 0x1F00);
+     tempax = ((tempax & 0x00FF) << 8) | (tempax & 0x00FF);
   }
 
   temp = (tempax & 0xFF00) >> 8;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x44,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x44,temp);
   temp = (tempbx & 0xFF00) >> 8;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x45,0xC0,temp);
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-       temp = tempcx & 0x00FF;
-       if(tempbx & 0x2000) temp = 0;
-       temp |= 0x18;
-       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
-       if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-             tempbx = 0x0382;  
-             tempcx = 0x007e;  
-       } else {
-             tempbx = 0x0369;  
-             tempcx = 0x0061;  
-       }
-       temp = (tempbx & 0x00FF) ;
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4B,temp);
-       temp = (tempcx & 0x00FF) ;
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4C,temp);
-       tempbx &= 0x03FF;
-       temp = (tempcx & 0xFF00) >> 8;
-       temp = (temp & 0x0003) << 2;
-       temp |= (tempbx >> 8);
-       if(HwDeviceExtension->jChipType < SIS_315H) {
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x4D,temp);
-       } else {
-          SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
-       }
+     temp = tempcx & 0x00FF;
+     if(tempbx & 0x2000) temp = 0;
+     temp |= 0x18;
+     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x46,0xE0,temp);
+
+     if(SiS_Pr->SiS_VBInfo & SetPALTV) {
+        tempbx = 0x0382;
+        tempcx = 0x007e;
+     } else {
+        tempbx = 0x0369;
+        tempcx = 0x0061;
+     }
+     temp = (tempbx & 0x00FF) ;
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4B,temp);
+     temp = (tempcx & 0x00FF) ;
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4C,temp);
+     temp = (tempcx & 0x0300) >> (8 - 2);
+     temp |= ((tempbx >> 8) & 0x03);
+     if(HwInfo->jChipType < SIS_315H) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x4D,temp);
+     } else {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x4D,0xF0,temp);
+     }
 
-       temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x43);
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
+     temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x43);
+     SiS_SetReg(SiS_Pr->SiS_Part2Port,0x43,(USHORT)(temp - 3));
   }
 
   temp = 0;
-  if((HwDeviceExtension->jChipType == SIS_630) ||
-     (HwDeviceExtension->jChipType == SIS_730)) {
+  if((HwInfo->jChipType == SIS_630) ||
+     (HwInfo->jChipType == SIS_730)) {
      temp = 0x35;
-  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+  } else if(HwInfo->jChipType >= SIS_315H) {
      temp = 0x38;
   }
   if(temp) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-               if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
-                     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
-                     temp = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
-                     SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
-               }
-          }
-      }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           if(SiS_GetReg(SiS_Pr->SiS_P3d4,temp) & EnablePALM) {  /* 0x40 */
+              SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x00,0xEF);
+              temp = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
+              SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp - 1);
+           }
+        }
+     }
+  }
+
+  if(HwInfo->jChipType >= SIS_315H) {
+     if((SiS_Pr->SiS_VBType & VB_SIS301B302B) && (!(SiS_Pr->SiS_VBType & VB_NoLCD))) {
+        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+        }
+     }
   }
 
+#if 0  /* Old: Why HiVision? */
   if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) &&
       (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
-    if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,0x00);
-    }
+     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,0x00);
+     }
   }
+#endif
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwInfo->jChipType < SIS_315H) {
+#ifdef SIS300
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-     	SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
-			    RefreshRateTableIndex, BaseAddr, ModeNo);
+     	SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
+			    RefreshRateTableIndex, ModeNo);
 	return;
      }
+#endif
   } else {
-     /* TW: !!! The following is a duplicate, done for LCDA as well (see above) */
+#ifdef SIS315H
+     /* !!! The following is a duplicate, done for LCDA as well (see above) */
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    
-         if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-           if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-             if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-               SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1c,0xa7);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1d,0x07);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1e,0xf2);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1f,0x6e);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x20,0x17);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,0x8b);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x22,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,0x53);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x24,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x25,0x40);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x26,0x34);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x27,0xf4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x28,0x63);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x29,0xbb);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2a,0xcc);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2b,0x7a);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2c,0x58);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2d,0xe4);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2e,0x73);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,0xda);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0x13);
-	       SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x43,0x72);
-	     }
-           }
-         }
-       }
-       return;
+        SiS_SetTVSpecial(SiS_Pr, ModeNo);
+        return;
      }
+#endif
   }
 
-  /* TW: From here: Part2 LCD setup */
+  /* From here: Part2 LCD setup */
 
   tempbx = SiS_Pr->SiS_HDE;
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-      /* TW: 650/30xLV 1.10.6s */
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
-  }
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
   tempbx--;			         	/* RHACTE=HDE-1 */
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2C,temp);
-  temp = (tempbx & 0xFF00) >> 8;
-  temp <<= 4;
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2C,temp);
+  temp = (tempbx & 0xFF00) >> 4;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x2B,0x0F,temp);
 
   temp = 0x01;
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-    if(SiS_Pr->SiS_ModeType == ModeEGA) {
-      if(SiS_Pr->SiS_VGAHDE >= 1024) {
-        temp = 0x02;
-	if(HwDeviceExtension->jChipType >= SIS_315H) {
-           if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-             temp = 0x01;
+     if(SiS_Pr->SiS_ModeType == ModeEGA) {
+        if(SiS_Pr->SiS_VGAHDE >= 1024) {
+           temp = 0x02;
+	   if(HwInfo->jChipType >= SIS_315H) {
+              if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
+                 temp = 0x01;
+	      }
 	   }
-	}
-      }
-    }
+        }
+     }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0B,temp);
-
-  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO=(VDE-1)&0xFF */
-  push1 = tempbx;
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0B,temp);
 
+  tempbx = SiS_Pr->SiS_VDE;         		/* RTVACTEO = VDE - 1 */
+  /* push1 = tempbx; */
   tempbx--;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x03,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x03,temp);
   temp = ((tempbx & 0xFF00) >> 8) & 0x07;
   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x0C,0xF8,temp);
 
   tempcx = SiS_Pr->SiS_VT;
-  push2 = tempcx;
-
+  /* push2 = tempcx; */
   tempcx--;
-  temp = tempcx & 0x00FF;  			 /* RVTVT=VT-1 */
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x19,temp);
+  temp = tempcx & 0x00FF;  			 /* RVTVT = VT - 1 */
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x19,temp);
 
   temp = (tempcx & 0xFF00) >> 8;
   temp <<= 5;
-  
+
   /* Enable dithering; newer versions only do this for 32bpp mode */
-  if((HwDeviceExtension->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-    if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
-  } else if(HwDeviceExtension->jChipType < SIS_315H) {
-    if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp |= 0x10;
-    else {
-      if(SiS_Pr->SiS_LCDInfo & LCDSync)       /* TW: 630/301 BIOS checks this */
-         temp |= 0x10;
-    }
+  if((HwInfo->jChipType == SIS_300) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
+     if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) temp |= 0x10;
+  } else if(HwInfo->jChipType < SIS_315H) {
+     temp |= 0x10;
   } else {
-      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-         /* TW: 650/30xLV 1.10.6s */
-         if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
-            if(SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
-      	       temp |= 0x10;
-	    }
-         }
-      } else {
-         temp |= 0x10;
-      }
+     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+        if(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit) {
+           if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00) & 0x01) {  /* 32bpp mode? */
+              temp |= 0x10;
+	   }
+        }
+     } else {
+        temp |= 0x10;
+     }
   }
 
   /* 630/301 does not do all this */
   if((SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-     if((HwDeviceExtension->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-        /* TW: 650/30xLV 1.10.6s */
-        temp |= (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x37) >> 6);
-	temp |= 0x08;   					/* From 1.10.7w */
-	if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
+     if((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+	if(((SiS_Pr->SiS_CustomT == CUT_COMPAQ1280) &&
+	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024)) ||
+	   ((SiS_Pr->SiS_CustomT == CUT_CLEVO1400) &&
+	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050))) {
+#ifdef SIS315H
+	   if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	      temp |= (SiS_Pr->SiS_LCDInfo >> 6);
+	   }
+#endif
+	} else {
+           temp |= (SiS_GetReg(SiS_Pr->SiS_P3d4,0x37) >> 6);
+	   temp |= 0x08;   						/* From 1.10.7w */
+	   if(!(SiS_Pr->SiS_LCDInfo & LCDRGB18Bit)) temp |= 0x04; 	/* From 1.10.7w */
+	}
      } else {
-        tempbx = (tempbx & 0xFF00) | (SiS_Pr->SiS_LCDInfo & 0x0FF);
-        if(tempbx & LCDSync) {
-           tempbx &= 0xFFE0;
-           tempbx = (tempbx & 0xFF00) | ((tempbx & 0x00FF) >> 6);
-           temp |= (tempbx & 0x00FF);
-        }
+        if(SiS_Pr->SiS_LCDInfo & LCDSync) {
+	   temp |= (SiS_Pr->SiS_LCDInfo >> 6);
+	}
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1A,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1A,temp);
 
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x09,0xF0);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x0A,0xF0);
@@ -7595,24 +7791,22 @@
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x17,0xFB);
   SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x18,0xDF);
 
-  /* 1280x960, 1280x1024 and 1600x1200 data invalid/missing in tables, use old calculation */
-  if((HwDeviceExtension->jChipType >= SIS_315H)             && 
-     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)                &&  
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) &&
-     (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x960)) {
+  if((HwInfo->jChipType >= SIS_315H)         &&
+     (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)            &&
+     ((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)  ||
+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+      (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) ) {
      
-#ifdef SIS315H 							/* ------------- 310/325/330 series ------------ */
+#ifdef SIS315H 							/* ------------- 315/330 series ------------ */
 
-      /* TW: Inserted this entire section from 650/301LV(x) BIOS */
-      
       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) results
        * in a black bar in modes < 1024; if the panel is non-expanding, the bridge
        * scales all modes to 1024. All modes in both variants (exp/non-exp) work.
        */
 
-      SiS_GetCRT2Part2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                         &CRT2Index,&resindex);
+      SiS_GetCRT2Part2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                          &CRT2Index, &resindex, HwInfo);
 
       switch(CRT2Index) {
         case Panel_1024x768      : CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;  break;  /* "Normal" */
@@ -7627,21 +7821,27 @@
         case Panel_1280x1024 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1280x1024_3; break;
 	case Panel_1400x1050 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1400x1050_3; break;
 	case Panel_1600x1200 + 32: CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1600x1200_3; break;
+	case 100:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_1; break;  /* Custom */
+	case 101:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_2; break;
+	case 102:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Compaq1280x1024_3; break;
+	case 103:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_1; break;    /* Custom */
+	case 104:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_2; break;
+	case 105:		   CRT2Part2Ptr = (SiS_Part2PortTblStruct *)SiS310_CRT2Part2_Clevo1024x768_3; break;
 	default:                   CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_3;  break;
       }
 
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
       for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
       for(j = 0x1c; j <= 0x1d; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
       for(j = 0x1f; j <= 0x21; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
       }
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
+      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
       SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
 
       if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
@@ -7651,27 +7851,25 @@
 	     temp++;
 	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp += 2;
 	  }
-	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xb3);
-	}
-	if(SiS_Pr->SiS_VGAVDE == 420) {
+	  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+	  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xb3);
+	} else if(SiS_Pr->SiS_VGAVDE == 420) {
 	  temp = 0x4d;
 	  if(SiS_Pr->SiS_ModeType <= ModeVGA) {
 	     temp++;
 	     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) temp++;
 	  }
-	  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
+	  SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
 	}
      }
 
-     /* TW: 650/30xLV 1.10.6s: */
      /* !!! This is a duplicate, done for LCDA as well - see above */
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
 	   SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1a,0xfc,0x03);   /* Not done in 1.10.7w */
 	   temp = 1;
 	   if(ModeNo <= 0x13) temp = 3;
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x0b,temp);
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,0x0b,temp);
 	}
      }
 #endif
@@ -7679,273 +7877,248 @@
   } else {   /* ------ 300 series and other bridges, other LCD resolutions ------ */
 
       /* Using this on the 301B with an auto-expanding 1024 panel (CR37=1) makes
-       * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding, 
+       * the panel scale at modes < 1024 (no black bars); if the panel is non-expanding,
        * the bridge scales all modes to 1024.
        * !!! Malfunction at 640x480 and 640x400 when panel is auto-expanding - black screen !!!
        */
-  
+
+    /* cx = VT - 1 */
+
     tempcx++;
-    
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)       tempbx =  768;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) tempbx = 1024;
-    else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) tempbx = 1200;
-    else if(SiS_Pr->SiS_VDE != 1024) 				  tempbx =  960;
-    else            						  tempbx = 1024;
-    
-#if 0  /* old */
-    tempbx = 768;
-    if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1024x768) {
-      tempbx = 1024;
-      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024) {
-         tempbx = 1200;
-         if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1600x1200) {
-            if(tempbx != SiS_Pr->SiS_VDE) {
-               tempbx = 960;
-            }
-         }
-      }
-    }
-#endif
-    
+
+    tempbx = SiS_Pr->PanelYRes;
+
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
-      tempbx = SiS_Pr->SiS_VDE - 1;
-      tempcx--;
+       tempbx = SiS_Pr->SiS_VDE - 1;
+       tempcx--;
     }
-    
+
     tempax = 1;
     if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {
-      if(tempbx != SiS_Pr->SiS_VDE) {
-        tempax = tempbx;
-/*	if(SiS_Pr->SiS_VGAVDE == 525) tempax += 60;   in 650/301B BIOS */
-        if(tempax < SiS_Pr->SiS_VDE) {
-          tempax = 0;
-          tempcx = 0;
-        } else {
-          tempax -= SiS_Pr->SiS_VDE;
-        }
-        tempax >>= 1;
-      }
-      tempcx -= tempax; /* lcdvdes */
-      tempbx -= tempax; /* lcdvdee */
-    } else {
-      tempax >>= 1;
-      tempcx -= tempax; /* lcdvdes */
-      tempbx -= tempax; /* lcdvdee */
+       if(tempbx != SiS_Pr->SiS_VDE) {
+          tempax = tempbx;
+          if(tempax < SiS_Pr->SiS_VDE) {
+             tempax = 0;
+             tempcx = 0;
+          } else {
+             tempax -= SiS_Pr->SiS_VDE;
+          }
+          tempax >>= 1;
+       }
+       tempcx -= tempax; /* lcdvdes */
+       tempbx -= tempax; /* lcdvdee */
     }
-    
+#if 0  /* meaningless: 1 / 2 = 0... */
+    else {
+       tempax >>= 1;
+       tempcx -= tempax; /* lcdvdes */
+       tempbx -= tempax; /* lcdvdee */
+    }
+#endif
+
+    /* Non-expanding: lcdvdees = tempcx = VT-1; lcdvdee = tempbx = VDE-1 */
+
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdvds 0x%x lcdvde 0x%x\n", tempcx, tempbx);
-#endif    
+    xf86DrvMsg(0, X_INFO, "lcdvdes 0x%x lcdvdee 0x%x\n", tempcx, tempbx);
+#endif
 
     temp = tempcx & 0x00FF;   				/* RVEQ1EQ=lcdvdes */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,temp);
     temp = tempbx & 0x00FF;   				/* RVEQ2EQ=lcdvdee */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,temp);
 
     temp = ((tempbx & 0xFF00) >> 8) << 3;
     temp |= ((tempcx & 0xFF00) >> 8);
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,temp);
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,temp);
 
-    tempbx = push2;
-    tempax = push1;
-    tempcx = tempbx;
-    tempcx -= tempax;
-    tempcx >>= 4;
+    tempbx = SiS_Pr->SiS_VT;    /* push2; */
+    tempax = SiS_Pr->SiS_VDE;   /* push1; */
+    tempcx = (tempbx - tempax) >> 4;
     tempbx += tempax;
     tempbx >>= 1;
     if(SiS_Pr->SiS_LCDInfo & DontExpandLCD)  tempbx -= 10;
-    
+
+    /* non-expanding: lcdvrs = tempbx = ((VT + VDE) / 2) - 10 */
+
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CVSyncStart;
+    }
+
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "lcdvrs 0x%x\n", tempbx);
 #endif
 
-    temp = tempbx & 0x00FF;   				/* RTVACTEE=lcdvrs */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
+    temp = tempbx & 0x00FF;   				/* RTVACTEE = lcdvrs */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
 
     temp = ((tempbx & 0xFF00) >> 8) << 4;
     tempbx += (tempcx + 1);
     temp |= (tempbx & 0x000F);
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-    /* TW: Code from 630/301B (I+II) BIOS */
-
-    if( ( ( (HwDeviceExtension->jChipType == SIS_630) ||
-            (HwDeviceExtension->jChipType == SIS_730) ) &&
-          (HwDeviceExtension->jChipRevision > 2) )  &&
-        (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
-        (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
-        (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-            if(ModeNo == 0x13) {
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xB9);
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0xCC);
-              SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xA6);
-            } else {
-              if((crt2crtc & 0x3F) == 4) {
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x2B);
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x13);
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,0xE5);
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x05,0x08);
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xE2);
-              }
-            }
+    if(SiS_Pr->UseCustomMode) {
+       temp &= 0xf0;
+       temp |= (SiS_Pr->CVSyncEnd & 0x0f);
     }
 
-    /* TW: Inserted missing code from 630/301B BIOS;
-     *     Strangely, this is done in all 650 BIOSes as
-     *     well (although LCDTypeInfo is not used there
-     *     in the same way as on 300 series)
-     */
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdvre[3:0] 0x%x\n", (temp & 0x0f));
+#endif
 
-    if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
-         crt2crtc &= 0x1f;
-         tempcx = 0;
-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-           if (SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-              tempcx += 7;
-           }
-         }
-         tempcx += crt2crtc;
-         if (crt2crtc >= 4) {
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x06,0xff);
-         }
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,temp);
 
-         if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
-           if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-             if(crt2crtc == 4) {
-                SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x01,0x28);
+    /* Code from 630/301B (I+II) BIOS */
+
+    if(!SiS_Pr->UseCustomMode) {
+       if( ( ( (HwInfo->jChipType == SIS_630) ||
+               (HwInfo->jChipType == SIS_730) ) &&
+             (HwInfo->jChipRevision > 2) )  &&
+           (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) &&
+           (!(SiS_Pr->SiS_SetFlag & LCDVESATiming))  &&
+           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
+          if(ModeNo == 0x13) {
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xB9);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0xCC);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xA6);
+          } else {
+             if((crt2crtc & 0x3F) == 4) {
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x2B);
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x13);
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,0xE5);
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x05,0x08);
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xE2);
              }
-           }
-         }
-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x02,0x18);
-         SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+          }
+       }
+    }
+
+#ifdef SIS300
+    if(HwInfo->jChipType < SIS_315H) {
+       if(!SiS_Pr->UseCustomMode) {
+          if(SiS_Pr->SiS_LCDTypeInfo == 0x0c) {
+             crt2crtc &= 0x1f;
+             tempcx = 0;
+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                   tempcx += 7;
+                }
+             }
+             tempcx += crt2crtc;
+             if(crt2crtc >= 4) {
+                SiS_SetReg(SiS_Pr->SiS_Part2Port,0x06,0xff);
+             }
+
+             if(!(SiS_Pr->SiS_VBInfo & SetNotSimuMode)) {
+                if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+                   if(crt2crtc == 4) {
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x01,0x28);
+                   }
+                }
+             }
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x02,0x18);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,atable[tempcx]);
+          }
+       }
     }
+#endif
 
-    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT-HDE)>>2     */
+    tempcx = (SiS_Pr->SiS_HT - SiS_Pr->SiS_HDE) >> 2;     /* (HT - HDE) >> 2 */
     tempbx = SiS_Pr->SiS_HDE + 7;            		  /* lcdhdee         */
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         tempbx += 2;
+       tempbx += 2;
     }
     push1 = tempbx;
+
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhde 0x%x\n", tempbx);
-#endif    
-    temp = tempbx & 0x00FF;    			          /* RHEQPLE=lcdhdee */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,temp);
+    xf86DrvMsg(0, X_INFO, "lcdhdee 0x%x\n", tempbx);
+#endif
+
+    temp = tempbx & 0x00FF;    			          /* RHEQPLE = lcdhdee */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x23,temp);
     temp = (tempbx & 0xFF00) >> 8;
     SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0xF0,temp);
 
     temp = 7;
     if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-         temp += 2;
+       temp += 2;
     }
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE=lcdhdes[7:0] */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1F,temp);  	  /* RHBLKE = lcdhdes[7:0] */
     SiS_SetRegAND(SiS_Pr->SiS_Part2Port,0x20,0x0F);	  /* lcdhdes [11:8] */
 
     tempbx += tempcx;
     push2 = tempbx;
-#ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
-#endif
-    temp = tempbx & 0x00FF;            		          /* RHBURSTS=lcdhrs */
-    if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-       if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) { 
-          if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CHSyncStart + 7;
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+          tempbx += 2;
        }
     }
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x1C,temp);
-    temp = ((tempbx & 0xFF00) >> 8) << 4;
-    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
 
-    tempbx = push2;
-    tempcx <<= 1;
-    tempbx += tempcx;
 #ifdef TWDEBUG
-    xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
-#endif    
-    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S=lcdhre */
-    SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x21,temp);
-
-    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
-      if(SiS_Pr->SiS_VGAVDE == 525) {
-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
-    	   temp=0xC6;
-        else
-       	   temp=0xC3;
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x30,0xB3);
-      } else if(SiS_Pr->SiS_VGAVDE == 420) {
-        if(SiS_Pr->SiS_ModeType <= ModeVGA)
-	   temp=0x4F;
-        else
-       	   temp=0x4D;   
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x2f,temp);
-      }
-    }
-    SiS_Set300Part2Regs(SiS_Pr, HwDeviceExtension, ModeIdIndex,
-                        RefreshRateTableIndex, BaseAddr, ModeNo);
-
-  } /* HwDeviceExtension */
-}
-
-USHORT
-SiS_GetVGAHT2(SiS_Private *SiS_Pr)
-{
-  ULONG tempax,tempbx;
+    xf86DrvMsg(0, X_INFO, "lcdhrs 0x%x\n", tempbx);
+#endif
 
-  tempbx = ((SiS_Pr->SiS_VGAVT - SiS_Pr->SiS_VGAVDE) * SiS_Pr->SiS_RVBHCMAX) & 0xFFFF;
-  tempax = (SiS_Pr->SiS_VT - SiS_Pr->SiS_VDE) * SiS_Pr->SiS_RVBHCFACT;
-  tempax = (tempax * SiS_Pr->SiS_HT) / tempbx;
-  return((USHORT) tempax);
-}
+    temp = tempbx & 0x00FF;            		          /* RHBURSTS = lcdhrs */
+    if(!SiS_Pr->UseCustomMode) {
+       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+          if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) {
+             if(SiS_Pr->SiS_HDE == 1280) temp = 0x47;
+          }
+       }
+    }
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x1C,temp);
+    temp = (tempbx & 0x0F00) >> 4;
+    SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x1D,0x0F,temp);
 
-/* TW: New from 300/301LV BIOS 1.16.51 for ECS A907. Seems highly preliminary. */
-void
-SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-    			USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-			USHORT BaseAddr, USHORT ModeNo)
-{
-  USHORT crt2crtc, resindex;
-  int    i,j;
-  const  SiS_Part2PortTblStruct *CRT2Part2Ptr = NULL;
+    tempbx = push2;
+    tempcx <<= 1;
+    tempbx += tempcx;
 
-  if(HwDeviceExtension->jChipType != SIS_300) return;
-  if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+    if(SiS_Pr->UseCustomMode) {
+       tempbx = SiS_Pr->CHSyncEnd + 7;
+       if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+          tempbx += 2;
+       }
+    }
 
-  if(ModeNo<=0x13) {
-    	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-    	crt2crtc = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
+#ifdef TWDEBUG
+    xf86DrvMsg(0, X_INFO, "lcdhre 0x%x\n", tempbx);
+#endif
 
-  resindex = crt2crtc & 0x3F;
-  if(SiS_Pr->SiS_SetFlag & LCDVESATiming) CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-  else                                    CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_2;
+    temp = tempbx & 0x00FF;            		          /* RHSYEXP2S = lcdhre */
+    SiS_SetReg(SiS_Pr->SiS_Part2Port,0x21,temp);
 
-  /* TW: The BIOS code (1.16.51) is obviously a fragment! */
-  if(ModeNo > 0x13) {
-     CRT2Part2Ptr = SiS_Pr->SiS_CRT2Part2_1024x768_1;
-     resindex = 4;
-  }
+    if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) {
+       if(SiS_Pr->SiS_VGAVDE == 525) {
+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
+    	     temp=0xC6;
+          else
+       	     temp=0xC3;
+          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x30,0xB3);
+       } else if(SiS_Pr->SiS_VGAVDE == 420) {
+          if(SiS_Pr->SiS_ModeType <= ModeVGA)
+	     temp=0x4F;
+          else
+       	     temp=0x4D;
+          SiS_SetReg(SiS_Pr->SiS_Part2Port,0x2f,temp);
+       }
+    }
+#ifdef SIS300
+    SiS_Set300Part2Regs(SiS_Pr, HwInfo, ModeIdIndex,
+                        RefreshRateTableIndex, ModeNo);
+#endif
 
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,(CRT2Part2Ptr+resindex)->CR[0]);
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x02,0x80,(CRT2Part2Ptr+resindex)->CR[1]);
-  for(i = 2, j = 0x04; j <= 0x06; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
-  }
-  for(j = 0x1c; j <= 0x1d; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
-  }
-  for(j = 0x1f; j <= 0x21; i++, j++ ) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,j,(CRT2Part2Ptr+resindex)->CR[i]);
-  }
-  SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x23,(CRT2Part2Ptr+resindex)->CR[10]);
-  SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x25,0x0f,(CRT2Part2Ptr+resindex)->CR[11]);
+  } /* HwInfo */
 }
 
-/* TW: Set 301 Macrovision(tm) registers */
-void
-SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*         SET PART 3 REGISTER GROUP         */
+/*********************************************/
+
+static void
+SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
   USHORT i;
@@ -7954,88 +8127,152 @@
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) return;
 
-  if(ModeNo<=0x13)
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-  else
+  if(ModeNo<=0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+  } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     }
+  }
+
+#ifndef SIS_CP
+  SiS_SetReg(SiS_Pr->SiS_Part3Port,0x00,0x00);
+#endif
 
-  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x00,0x00);
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP
+#endif
 
   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-    SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+     SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
   } else {
-    if(HwDeviceExtension->jChipType >= SIS_315H) {
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF5);
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xB7);
-    } else {
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xF6);
-      SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xBf);
-    }
+     if(HwInfo->jChipType >= SIS_315H) {
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF5);
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xB7);
+     } else {
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xF6);
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xBf);
+     }
   }
 
   temp = 0;
-  if((HwDeviceExtension->jChipType == SIS_630)||
-     (HwDeviceExtension->jChipType == SIS_730)) {
+  if((HwInfo->jChipType == SIS_630)||
+     (HwInfo->jChipType == SIS_730)) {
      temp = 0x35;
-  } else if(HwDeviceExtension->jChipType >= SIS_315H) {
+  } else if(HwInfo->jChipType >= SIS_315H) {
      temp = 0x38;
   }
   if(temp) {
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-          if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-              if(SiS_GetReg1(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x13,0xFA);
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x14,0xC8);
-                  SiS_SetReg1(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
-              }
-          }
-      }
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+        if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+           if(SiS_GetReg(SiS_Pr->SiS_P3d4,temp) & EnablePALM){  /* 0x40 */
+              SiS_SetReg(SiS_Pr->SiS_Part3Port,0x13,0xFA);
+              SiS_SetReg(SiS_Pr->SiS_Part3Port,0x14,0xC8);
+              SiS_SetReg(SiS_Pr->SiS_Part3Port,0x3D,0xA8);
+           }
+        }
+     }
   }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-    tempdi = SiS_Pr->SiS_HiTVGroup3Data;
-    if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-      tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
-      if(!(modeflag & Charx8Dot)) {
-        tempdi = SiS_Pr->SiS_HiTVGroup3Text;
-      }
-    }
-    if(SiS_Pr->SiS_HiVision & 0x03) {
-       tempdi = SiS_HiTVGroup3_1;
-       if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
-    }
-    for(i=0; i<=0x3E; i++){
-       SiS_SetReg1(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
-    }
+     tempdi = SiS_Pr->SiS_HiTVGroup3Data;
+     if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
+        tempdi = SiS_Pr->SiS_HiTVGroup3Simu;
+        if(!(modeflag & Charx8Dot)) {
+           tempdi = SiS_Pr->SiS_HiTVGroup3Text;
+        }
+     }
+     if(SiS_Pr->SiS_HiVision & 0x03) {
+        tempdi = SiS_HiTVGroup3_1;
+        if(SiS_Pr->SiS_HiVision & 0x02) tempdi = SiS_HiTVGroup3_2;
+     }
+     for(i=0; i<=0x3E; i++){
+        SiS_SetReg(SiS_Pr->SiS_Part3Port,i,tempdi[i]);
+     }
   }
 
-  return;
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP2
+#endif
+
 }
 
-/* TW: Set 301 VGA2 registers */
-void
-SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-              USHORT ModeIdIndex,USHORT RefreshRateTableIndex,
-	      PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*         SET PART 4 REGISTER GROUP         */
+/*********************************************/
+
+static void
+SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                 USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+{
+  USHORT vclkindex;
+  USHORT temp, reg1, reg2;
+
+  if(SiS_Pr->UseCustomMode) {
+     reg1 = SiS_Pr->CSR2B;
+     reg2 = SiS_Pr->CSR2C;
+  } else {
+     vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                                 HwInfo);
+     reg1 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
+     reg2 = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
+  }
+
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0A,reg1);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0B,reg2);
+     if(HwInfo->jChipType >= SIS_315H) {
+	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
+                 if((ModeNo == 0x64) || (ModeNo == 0x4a) || (ModeNo == 0x38)) {
+		    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0a,0x57);
+		    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0b,0x46);
+		    SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
+                 }
+              }
+           }
+	}
+     }
+  } else {
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0A,0x01);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0B,reg2);
+     SiS_SetReg(SiS_Pr->SiS_Part4Port,0x0A,reg1);
+  }
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x12,0x00);
+  temp = 0x08;
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) temp |= 0x20;
+  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,temp);
+}
+
+/* Set 301 VGA2 registers */
+static void
+SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+  	      USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
   USHORT tempax,tempcx,tempbx,modeflag,temp,temp2,resinfo;
   ULONG tempebx,tempeax,templong;
 
-
-  if(ModeNo<=0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo <= 0x13) {
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
+     if(SiS_Pr->UseCustomMode) {
+        modeflag = SiS_Pr->CModeFlag;
+	resinfo = 0;
+     } else {
     	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     }
   }
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-      /* TW: From 650/302LV 1.10.6s (not for 300/301LV - no LCDA on this combination) */
+  if(HwInfo->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
         if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-           SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+           SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
         }
      }
   }
@@ -8046,34 +8283,38 @@
       }
   }
 
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
+  if(HwInfo->jChipType >= SIS_315H) {
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	   /* TW: From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
-  	   /* TW: This is a duplicate; done at the end, too */
-	   if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-		SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-	   }
-	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	   SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	   /* From 650/301LV (any, incl. 1.10.6s, 1.10.7w) */
+  	   /* This is a duplicate; done at the end, too */
+	   if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+	      SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	   }
+#ifdef SET_EMI
+	   if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	   }
+#endif
 	}
    	return;
      }
   }
 
   temp = SiS_Pr->SiS_RVBHCFACT;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x13,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x13,temp);
 
   tempbx = SiS_Pr->SiS_RVBHCMAX;
   temp = tempbx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x14,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x14,temp);
 
   temp2 = (((tempbx & 0xFF00) >> 8) << 7) & 0x00ff;
 
   tempcx = SiS_Pr->SiS_VGAHT - 1;
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x16,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x16,temp);
 
   temp = (((tempcx & 0xFF00) >> 8) << 3) & 0x00ff;
   temp2 |= temp;
@@ -8082,48 +8323,41 @@
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV))  tempcx -= 5;
 
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x17,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x17,temp);
 
   temp = temp2 | ((tempcx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x15,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x15,temp);
 
   tempbx = SiS_Pr->SiS_VGAHDE;
   if(modeflag & HalfDCLK)  tempbx >>= 1;
 
-  /* TW: New for 650/301LV and 630/301B */
   temp = 0xA0;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) {
-       temp = 0;
-       if(tempbx > 800) {
-          temp = 0xA0;
-          if(tempbx != 1024) {
-             temp = 0xC0;
-             if(tempbx != 1280) temp = 0;
-	  }
-       }
-  } else
-    if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-      if(tempbx <= 800) {
-         temp = 0x80;
-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-            temp = 0;
-            if(tempbx > 800) temp = 0x60;
-         }
-      }
+     temp = 0;
+     if(tempbx > 800) {
+        temp = 0xA0;
+        if(tempbx != 1024) {
+           temp = 0xC0;
+           if(tempbx != 1280) temp = 0;
+	}
+     }
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+     if(tempbx <= 800) {
+        temp = 0x80;
+     }
   } else {
-      temp = 0x80;
-      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-            temp = 0;
-            if(tempbx > 800) temp = 0x60;
-      }
+     temp = 0x80;
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+        temp = 0;
+        if(tempbx > 800) temp = 0x60;
+     }
   }
   if(SiS_Pr->SiS_HiVision & 0x03) {
         temp = 0;
 	if(SiS_Pr->SiS_VGAHDE == 1024) temp = 0x20;
   }
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-  	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) temp = 0;
-  }
+
+  if(SiS_IsDualLink(SiS_Pr, HwInfo)) temp = 0;
 
   if(SiS_Pr->SiS_VBType & VB_SIS301) {
      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)
@@ -8140,14 +8374,14 @@
 
   tempcx = SiS_Pr->SiS_RVBHRS;
   temp = tempcx & 0x00FF;
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x18,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x18,temp);
 
   tempeax = SiS_Pr->SiS_VGAVDE;
   tempcx |= 0x4000;
-  if(tempeax <= tempebx){
-    tempcx ^= 0x4000;
+  if(tempeax <= tempebx) {
+     tempcx ^= 0x4000;
   } else {
-    tempeax -= tempebx;
+     tempeax -= tempebx;
   }
 
   templong = (tempeax * 256 * 1024) % tempebx;
@@ -8156,446 +8390,159 @@
   if(templong != 0) tempebx++;
 
   temp = (USHORT)(tempebx & 0x000000FF);
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1B,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1B,temp);
   temp = (USHORT)((tempebx & 0x0000FF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1A,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1A,temp);
 
   tempbx = (USHORT)(tempebx >> 16);
   temp = tempbx & 0x00FF;
   temp <<= 4;
   temp |= ((tempcx & 0xFF00) >> 8);
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x19,temp);
+  SiS_SetReg(SiS_Pr->SiS_Part4Port,0x19,temp);
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
 
-         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1C,0x28);
+         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1C,0x28);
 	 tempbx = 0;
          tempax = SiS_Pr->SiS_VGAHDE;
          if(modeflag & HalfDCLK) tempax >>= 1;
          if((SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) || (SiS_Pr->SiS_HiVision & 0x03)) {
-	     if(HwDeviceExtension->jChipType >= SIS_315H) {
-	         if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempax >>= 1;
-		 else if(tempax > 800) tempax -= 800;
-	     } else {
-                 if(tempax > 800) tempax -= 800;
-             }
+	    if(HwInfo->jChipType >= SIS_315H) {
+	       if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempax >>= 1;
+	       else if(tempax > 800) tempax -= 800;
+	    } else {
+               if(tempax > 800) tempax -= 800;
+            }
          }
 
 /*       if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV | SetPALTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {  */
  	 if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) && (!(SiS_Pr->SiS_HiVision & 0x03))) {
-           if(tempax > 800) {
-	      tempbx = 8;
-              if(tempax == 1024)
-	        tempax *= 25;
-              else
-	        tempax *= 20;
-
-	      temp = tempax % 32;
-	      tempax /= 32;
-	      tempax--;
-	      if (temp!=0) tempax++;
-           }
+            if(tempax > 800) {
+	       tempbx = 8;
+               if(tempax == 1024)
+	          tempax *= 25;
+               else
+	          tempax *= 20;
+
+	       temp = tempax % 32;
+	       tempax /= 32;
+	       tempax--;
+	       if (temp!=0) tempax++;
+            }
          }
 	 tempax--;
          temp = (tempax & 0xFF00) >> 8;
          temp &= 0x03;
-	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {		/* From 1.10.7w */
-	 	if(ModeNo > 0x13) {			/* From 1.10.7w */
-			if(resinfo == 8) tempax = 0x1f;	/* From 1.10.7w */
-		}					/* From 1.10.7w */
-	 }						/* From 1.10.7w */
-	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
+	 if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* From 1.10.7w */
+	    if(ModeNo > 0x13) {					/* From 1.10.7w */
+	       if(resinfo == SIS_RI_1024x768) tempax = 0x1f;	/* From 1.10.7w */
+	    }							/* From 1.10.7w */
+	 }							/* From 1.10.7w */
+	 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1D,tempax & 0x00FF);
 	 temp <<= 4;
 	 temp |= tempbx;
-	 SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1E,temp);
+	 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x1E,temp);
 
 	 if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    if(IS_SIS650740) {
-	        temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
-	    } else {
-	        temp = 0x0036;
-	    }
-	 } else {
-	     temp = 0x0036;
-	 }
-         if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
-	                               (!(SiS_Pr->SiS_HiVision & 0x03))) {
-		temp |= 0x01;
-	        if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
-	          if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
-  	                  temp &= 0xFE;
-		}
-         }
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
-
-	 tempbx = SiS_Pr->SiS_HT;
-	 if(HwDeviceExtension->jChipType >= SIS_315H) {
-	 	if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) tempbx >>= 1;
-	 }
-         tempbx >>= 1;
-	 tempbx -= 2;
-         temp = ((tempbx & 0x0700) >> 8) << 3;
-         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
-         temp = tempbx & 0x00FF;
-         SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x22,temp);
-	 
-         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-               SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x24,0x0e);
-	    }
-	 }
-
-	 if(HwDeviceExtension->jChipType >= SIS_315H) {
-	     /* TW: 650/LV BIOS does this for all bridge types - assumingly wrong */
-	     /* 315, 330, 650+301B BIOS don't do this at all */
-             /* TW: This is a duplicate; done for LCDA as well (see above) */
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	        if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x39) & 0x04) {
-		   SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
-	        }
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-	     }
-         } else if(HwDeviceExtension->jChipType == SIS_300) {
-	     /* TW: 300/301LV BIOS does this for all bridge types - assumingly wrong */
-	     if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-	     }
-	 }
-
-  }  /* 301B */
-
-  SiS_SetCRT2VCLK(SiS_Pr,BaseAddr,ROMAddr,ModeNo,ModeIdIndex,
-                  RefreshRateTableIndex,HwDeviceExtension);
-}
-
-
-void
-SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                 USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT vclkindex;
-  USHORT tempah;
-
-  vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                              HwDeviceExtension);
-
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
-     if(HwDeviceExtension->jChipType >= SIS_315H) {
-	if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-           if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-	      if(!(SiS_Pr->SiS_VBInfo & SetPALTV)) {
-                 if((ModeNo == 0x4a) || (ModeNo == 0x38)) {
-		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0a,0x57);
-		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0b,0x46);
-		    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x1f,0xf6);
-                 }
-              }
-           }
-	}
-     }
-  } else {	
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,0x01);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_B;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0B,tempah);
-     tempah = SiS_Pr->SiS_VBVCLKData[vclkindex].Part4_A;
-     SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x0A,tempah);
-  }
-  SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x12,0x00);
-  tempah = 0x08;
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) tempah |= 0x20;
-  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x12,tempah);
-}
-
-USHORT
-SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempbx;
-  const USHORT LCDXlat0VCLK[4]    = {VCLK40, VCLK40, VCLK40, VCLK40};
-  const USHORT LVDSXlat1VCLK[4]   = {VCLK40, VCLK40, VCLK40, VCLK40};
-#ifdef SIS300
-  const USHORT LCDXlat1VCLK300[4] = {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  const USHORT LCDXlat2VCLK300[4] = {VCLK108_2,VCLK108_2,VCLK108_2,VCLK108_2};
-  const USHORT LVDSXlat2VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-  const USHORT LVDSXlat3VCLK300[4]= {VCLK65,   VCLK65,   VCLK65,   VCLK65};
-#endif
-#ifdef SIS315H
-  const USHORT LCDXlat1VCLK310[4] = {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  const USHORT LCDXlat2VCLK310[4] = {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-  const USHORT LVDSXlat2VCLK310[4]= {VCLK65+2,   VCLK65+2,   VCLK65+2,   VCLK65+2};
-  const USHORT LVDSXlat3VCLK310[4]= {VCLK108_2+5,VCLK108_2+5,VCLK108_2+5,VCLK108_2+5};
-#endif
-  USHORT CRT2Index,VCLKIndex=0;
-  USHORT modeflag,resinfo;
-  const UCHAR *CHTVVCLKPtr=NULL;
-  const USHORT *LCDXlatVCLK1 = NULL;
-  const USHORT *LCDXlatVCLK2 = NULL;
-  const USHORT *LVDSXlatVCLK2 = NULL;
-  const USHORT *LVDSXlatVCLK3 = NULL;
-
-  if(HwDeviceExtension->jChipType >= SIS_315H) {
-#ifdef SIS315H
-		LCDXlatVCLK1 = LCDXlat1VCLK310;
-		LCDXlatVCLK2 = LCDXlat2VCLK310;
-		LVDSXlatVCLK2 = LVDSXlat2VCLK310;
-		LVDSXlatVCLK3 = LVDSXlat3VCLK310;
-#endif
-  } else {
-#ifdef SIS300
-		LCDXlatVCLK1 = LCDXlat1VCLK300;
-		LCDXlatVCLK2 = LCDXlat2VCLK300;
-		LVDSXlatVCLK2 = LVDSXlat2VCLK300;
-		LVDSXlatVCLK3 = LVDSXlat3VCLK300;
-#endif
-  }
-
-  if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-    	CRT2Index = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
-  } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-    	CRT2Index = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
-  }
-
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {    /* 30x/B/LV */
-
-     if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {
-
-        CRT2Index >>= 6;
-        if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)){      /*  LCD */
-            if(HwDeviceExtension->jChipType < SIS_315H) {
-	       if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600)
-	    		VCLKIndex = LCDXlat0VCLK[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
-	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
-	    		VCLKIndex = LCDXlatVCLK1[CRT2Index];
-	       else
-	    		VCLKIndex = LCDXlatVCLK2[CRT2Index];
+	    if(IS_SIS550650740660) {
+	       temp = 0x0026;  /* 1.10.7w; 1.10.8r; needs corresponding code in Dis/EnableBridge! */
 	    } else {
-               /* TW: 330, 650/301LV BIOS does not check expanding, 315 does  */
-	       if( (HwDeviceExtension->jChipType > SIS_315PRO) ||
-	           (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) ) {
-      	          if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-		     VCLKIndex = 0x19;
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-		     VCLKIndex = 0x19;
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-		     VCLKIndex = 0x21;
-		  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-		     VCLKIndex = LCDXlatVCLK1[CRT2Index];
-                  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x960) {
-		     VCLKIndex = 0x45;  /* TW: in VBVCLK table */
-		     if(resinfo == 0x09) VCLKIndex++;
-	          } else {
-		     VCLKIndex = LCDXlatVCLK2[CRT2Index];
-      	          }
-	       } else {
-                   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));  /*  Port 3cch */
-         	   VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-        	   if(ModeNo > 0x13) {
-          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-        	   }
-		   if(ModeNo <= 0x13) {  /* TW: 315 BIOS */
-		      if(SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC == 1) VCLKIndex = 0x42;
-		   }
-		   if(VCLKIndex == 0) VCLKIndex = 0x41;
-		   if(VCLKIndex == 1) VCLKIndex = 0x43;
-		   if(VCLKIndex == 4) VCLKIndex = 0x44;
-	       }
-	    }
-        } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {                 /*  TV */
-        	if( (SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) && 
-		    (!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) ) {
-          		if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = HiTVVCLKDIV2;
-     			else                                  VCLKIndex = HiTVVCLK;
-          		if(SiS_Pr->SiS_SetFlag & TVSimuMode) {
-            			if(modeflag & Charx8Dot)      VCLKIndex = HiTVSimuVCLK;
-            			else 			      VCLKIndex = HiTVTextVCLK;
-          		}
-        	} else {
-       			if(SiS_Pr->SiS_SetFlag & RPLLDIV2XO)  VCLKIndex = TVVCLKDIV2;
-            		else         		              VCLKIndex = TVVCLK;
-          	}
-		if(HwDeviceExtension->jChipType >= SIS_315H) {
-              		VCLKIndex += 25;
-  		}
-        } else {         					/* RAMDAC2 */
-        	VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-        	VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-        	if(ModeNo > 0x13) {
-          		VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-			if(HwDeviceExtension->jChipType < SIS_315H) {
-          			VCLKIndex &= 0x3f;
-				if( (HwDeviceExtension->jChipType == SIS_630) &&
-				    (HwDeviceExtension->jChipRevision >= 0x30)) {
-				     if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
-				}
-			}
-        	}
-        }
-
-    } else {   /* If not programming CRT2 */
-
-        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-        VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-        if(ModeNo > 0x13) {
-             VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-	     if(HwDeviceExtension->jChipType < SIS_315H) {
-                VCLKIndex &= 0x3f;
-		if( (HwDeviceExtension->jChipType != SIS_630) &&
-		    (HwDeviceExtension->jChipType != SIS_300) ) {
-		   if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
-		}
-	     }
-        }
-    }
-
-  } else {       /*   LVDS  */
-
-    	VCLKIndex = CRT2Index;
-
-	if(SiS_Pr->SiS_SetFlag & ProgrammingCRT2) {  /* programming CRT2 */
-
-	   if( (SiS_Pr->SiS_IF_DEF_CH70xx != 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
-
-		VCLKIndex &= 0x1f;
-        	tempbx = 0;
-		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-        	if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-			tempbx += 2;
-			if(SiS_Pr->SiS_CHSOverScan) tempbx = 8;
-			if(SiS_Pr->SiS_CHPALM) {
-				tempbx = 4;
-				if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-			} else if(SiS_Pr->SiS_CHPALN) {
-				tempbx = 6;
-				if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx += 1;
-			}
-		}
-       		switch(tempbx) {
-          	   case  0: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUNTSC;  break;
-         	   case  1: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKONTSC;  break;
-                   case  2: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPAL;   break;
-                   case  3: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
-		   case  4: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALM;  break;
-         	   case  5: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALM;  break;
-                   case  6: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKUPALN;  break;
-                   case  7: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPALN;  break;
-		   case  8: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKSOPAL;  break;
-		   default: CHTVVCLKPtr = SiS_Pr->SiS_CHTVVCLKOPAL;   break;
-        	}
-        	VCLKIndex = CHTVVCLKPtr[VCLKIndex];
-
-	   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-
-	        VCLKIndex >>= 6;
-     		if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel800x600) ||
-		   (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480))
-     			VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-     		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768)
-     			VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600)
-                        VCLKIndex = LVDSXlatVCLK2[VCLKIndex];
-		else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768)
-                        VCLKIndex = LVDSXlatVCLK2[VCLKIndex];			
-     		else    VCLKIndex = LVDSXlatVCLK3[VCLKIndex];
-
-	   } else {
-
-	        VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-                VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-                if(ModeNo > 0x13) {
-                     VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-		     if(HwDeviceExtension->jChipType < SIS_315H) {
-    		        VCLKIndex &= 0x3F;
-                     }
-		     if( (HwDeviceExtension->jChipType == SIS_630) &&
-                         (HwDeviceExtension->jChipRevision >= 0x30) ) {
-		         	if(VCLKIndex == 0x14) VCLKIndex = 0x2e;
-		     }
-	        }
-	   }
+	       temp = 0x0036;
+	    }
+	 } else {
+	    temp = 0x0036;
+	 }
+         if((SiS_Pr->SiS_VBInfo & (SetCRT2ToTV - SetCRT2ToHiVisionTV)) &&
+	    (!(SiS_Pr->SiS_HiVision & 0x03))) {
+	    temp |= 0x01;
+	    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+	       if(!(SiS_Pr->SiS_SetFlag & TVSimuMode))
+  	          temp &= 0xFE;
+	    }
+         }
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x1F,0xC0,temp);
 
-	} else {  /* if not programming CRT2 */
+	 tempbx = SiS_Pr->SiS_HT;
+	 if(SiS_IsDualLink(SiS_Pr, HwInfo)) tempbx >>= 1;
+         tempbx >>= 1;
+	 tempbx -= 2;
+         temp = ((tempbx & 0x0700) >> 8) << 3;
+         SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x21,0xC0,temp);
+         temp = tempbx & 0x00FF;
+         SiS_SetReg(SiS_Pr->SiS_Part4Port,0x22,temp);
 
-	   VCLKIndex = (UCHAR)SiS_GetReg2((USHORT)(SiS_Pr->SiS_P3ca+0x02));
-           VCLKIndex = ((VCLKIndex >> 2) & 0x03);
-           if(ModeNo > 0x13) {
-              VCLKIndex = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-              if(HwDeviceExtension->jChipType < SIS_315H) {
-	         VCLKIndex &= 0x3F;
-	         if( (HwDeviceExtension->jChipType != SIS_630) &&
-		     (HwDeviceExtension->jChipType != SIS_300) ) {
-		        if(VCLKIndex == 0x1b) VCLKIndex = 0x35;
-	         }
-#if 0		 
-		 if(HwDeviceExtension->jChipType == SIS_730) {
-		    if(VCLKIndex == 0x0b) VCLKIndex = 0x40;   /* 1024x768-70 */
-		    if(VCLKIndex == 0x0d) VCLKIndex = 0x41;   /* 1024x768-75 */ 
-		 }
-#endif		 
-	      }
-	   }
+         if(SiS_Pr->SiS_VBType & VB_SIS301LV302LV) {
+	    if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
+               SiS_SetReg(SiS_Pr->SiS_Part4Port,0x24,0x0e);
+	       /* LCD-too-dark-error-source, see FinalizeLCD() */
+	    }
+	    if(HwInfo->jChipType >= SIS_315H) {
+	       if(SiS_IsDualLink(SiS_Pr, HwInfo)) {
+		  SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x27,0x2c);
+	       }
+	    }
+#ifdef SET_EMI
+	    if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	       SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	    }
+#endif
+	 }
 
-	}
+  }  /* 301B */
 
-  }
-#ifdef TWDEBUG
-  xf86DrvMsg(0, X_INFO, "VCLKIndex %d (0x%x)\n", VCLKIndex, VCLKIndex);
-#endif
-  return (VCLKIndex);
+  SiS_SetCRT2VCLK(SiS_Pr, ModeNo, ModeIdIndex,
+                  RefreshRateTableIndex,HwInfo);
 }
 
-/* TW: Set 301 Palette address port registers */
-/* TW: Checked against 650/301LV BIOS */
-void
-SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr,
-              UCHAR *ROMAddr, USHORT ModeNo, USHORT ModeIdIndex)
+/*********************************************/
+/*         SET PART 5 REGISTER GROUP         */
+/*********************************************/
+
+/* Set 301 Palette address port registers */
+static void
+SiS_SetGroup5(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+              PSIS_HW_INFO HwInfo)
 {
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)  return;
 
-  if(SiS_Pr->SiS_ModeType == ModeVGA){
+  if(SiS_Pr->SiS_ModeType == ModeVGA) {
      if(!(SiS_Pr->SiS_VBInfo & (SetInSlaveMode | LoadDACFlag))){
         SiS_EnableCRT2(SiS_Pr);
-        SiS_LoadDAC(SiS_Pr,HwDeviceExtension,ROMAddr,ModeNo,ModeIdIndex);
+        SiS_LoadDAC(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
      }
   }
 }
 
-void
-SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
+/*********************************************/
+/*     MODIFY CRT1 GROUP FOR SLAVE MODE      */
+/*********************************************/
+
+static void
+SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
 {
-  USHORT temp,tempah,i,modeflag,j;
-  USHORT ResInfo,DisplayType;
+  USHORT tempah,i,modeflag,j;
+  USHORT ResIndex,DisplayType;
   const SiS_LVDSCRT1DataStruct *LVDSCRT1Ptr=NULL;
 
   if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
   }
 
-  temp = SiS_GetLVDSCRT1Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,RefreshRateTableIndex,
-                            &ResInfo,&DisplayType);
+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+     (SiS_Pr->SiS_CustomT == CUT_BARCO1024) ||
+     (SiS_Pr->SiS_CustomT == CUT_PANEL848))
+     return;
 
-  if(temp == 0) return;
+  if(!(SiS_GetLVDSCRT1Ptr(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex,
+                          &ResIndex, &DisplayType))) return;
 
-  if(HwDeviceExtension->jChipType < SIS_315H) {
+  if(HwInfo->jChipType < SIS_315H) {
      if(SiS_Pr->SiS_SetFlag & SetDOSMode) return;
   }
 
@@ -8639,216 +8586,121 @@
     case 41: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_1_H;        break;
     case 42: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2;          break;
     case 43: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11280x768_2_H;        break;
+    case 50: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1;           break;
+    case 51: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_1_H;         break;
+    case 52: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2;           break;
+    case 53: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_2_H;         break;
+    case 54: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3;           break;
+    case 55: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT1640x480_3_H;         break;
     case 99: LVDSCRT1Ptr = SiS_Pr->SiS_CHTVCRT1SOPAL;               break;
     default: LVDSCRT1Ptr = SiS_Pr->SiS_LVDSCRT11024x768_1;          break;
   }
 
   SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);                        /*unlock cr0-7  */
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[0];
-  SiS_SetReg1(SiS_Pr->SiS_P3d4,0x00,tempah);
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[0];
+  SiS_SetReg(SiS_Pr->SiS_P3d4,0x00,tempah);
 
   for(i=0x02,j=1;i<=0x05;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x06,j=5;i<=0x07;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x10,j=7;i<=0x11;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x15,j=9;i<=0x16;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,i,tempah);
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+    SiS_SetReg(SiS_Pr->SiS_P3d4,i,tempah);
   }
   for(i=0x0A,j=11;i<=0x0C;i++,j++){
-    tempah = (LVDSCRT1Ptr+ResInfo)->CR[j];
-    SiS_SetReg1(SiS_Pr->SiS_P3c4,i,tempah);
+    tempah = (LVDSCRT1Ptr + ResIndex)->CR[j];
+    SiS_SetReg(SiS_Pr->SiS_P3c4,i,tempah);
   }
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
   tempah &= 0xE0;
-  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);     
+  SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x0E,0x1f,tempah);
 
-  tempah = (LVDSCRT1Ptr+ResInfo)->CR[14];
+  tempah = (LVDSCRT1Ptr + ResIndex)->CR[14];
   tempah &= 0x01;
   tempah <<= 5;
   if(modeflag & DoubleScanMode)  tempah |= 0x080;
   SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x09,~0x020,tempah);
 
-  /* TW: 650/LVDS BIOS - doesn't make sense */
+  /* 650/LVDS BIOS - doesn't make sense */
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
      if(modeflag & HalfDCLK)
         SiS_SetRegAND(SiS_Pr->SiS_P3d4,0x11,0x7f);
   }
 }
 
-BOOLEAN
-SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		   USHORT RefreshRateTableIndex,USHORT *ResInfo,
-		   USHORT *DisplayType)
- {
-  USHORT tempbx,modeflag=0;
-  USHORT Flag,CRT2CRTC;
+/*********************************************/
+/*              SET CRT2 ECLK                */
+/*********************************************/
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
-        if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
-     }
-  } else {
-     if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) return 0;
-  }
+static void
+SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+           USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo)
+{
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT clkbase, vclkindex=0;
+  UCHAR  sr2b, sr2c;
 
-  if(ModeNo <= 0x13) {
-    	modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
-    	CRT2CRTC = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
+	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
+        if((SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK & 0x3f) == 2) {
+	   RefreshRateTableIndex--;
+	}
+	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex, HwInfo);
+	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
   } else {
-    	modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-    	CRT2CRTC = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr, ModeNo, ModeIdIndex,
+                                    RefreshRateTableIndex, HwInfo);
   }
 
-  Flag = 1;
-  tempbx = 0;
-  if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
-     if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
-        Flag = 0;
-        tempbx = 18;
-        if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
-        if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-      	   tempbx += 2;
-	   if(SiS_Pr->SiS_CHSOverScan) tempbx = 99;
-	   if(SiS_Pr->SiS_CHPALM) {
-	      tempbx = 18;  /* PALM uses NTSC data */
-	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
-	   } else if(SiS_Pr->SiS_CHPALN) {
-	      tempbx = 20;  /* PALN uses PAL data  */
-	      if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) tempbx++;
-	   }
-        }
-     }
-  }
-  if(Flag) {
-     tempbx = SiS_Pr->SiS_LCDResInfo;
-     tempbx -= SiS_Pr->SiS_PanelMinLVDS;
-     if(SiS_Pr->SiS_LCDResInfo <= SiS_Pr->SiS_Panel1280x1024) {
-        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 6;
-        if(modeflag & HalfDCLK) tempbx += 3;
-     } else {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-           tempbx = 14;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x600) {
-           tempbx = 23;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1152x768) {
-           tempbx = 27;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-           tempbx = 36;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-        } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x768) {
-           tempbx = 40;
-	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 2;
-	   if(modeflag & HalfDCLK) tempbx++;
-        }
-     }
-     if(SiS_Pr->SiS_LCDInfo & LCDPass11) {
-        tempbx = 12;
-	if(modeflag & HalfDCLK) tempbx++;
-     }
-  }
-  if(SiS_Pr->SiS_IF_DEF_FSTN){
-     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel320x480){
-        tempbx = 22;
+  sr2b = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
+  sr2c = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
+
+  if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) || (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+     if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+	if(ROMAddr[0x220] & 0x01) {
+           sr2b = ROMAddr[0x227];
+	   sr2c = ROMAddr[0x228];
+	}
      }
   }
-  *ResInfo = CRT2CRTC & 0x3F;
-  *DisplayType = tempbx;
-  return 1;
-}
 
-void
-SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension)
-{
-  USHORT tempah,tempal,pushax;
-  USHORT vclkindex=0;
-    
-  if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel640x480) || (SiS_Pr->SiS_IF_DEF_TRUMPION == 1)) {
-	SiS_Pr->SiS_SetFlag &= (~ProgrammingCRT2);
-        tempal = SiS_Pr->SiS_RefIndex[RefreshRateTableIndex].Ext_CRTVCLK;
-    	tempal &= 0x3F;
-	if(tempal == 2) RefreshRateTableIndex--;
-	vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                               RefreshRateTableIndex,HwDeviceExtension);
-	SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
-  } else {
-        vclkindex = SiS_GetVCLK2Ptr(SiS_Pr,ROMAddr,ModeNo,ModeIdIndex,
-                               RefreshRateTableIndex,HwDeviceExtension);
-  }
-  
-  tempal = 0x02B;
+  clkbase = 0x02B;
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA)) {
      if(!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) {
-    	tempal += 3;
+    	clkbase += 3;
      }
   }
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x05,0x86);
-  pushax = tempal;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x20);
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x10);
-  tempal = pushax;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,0x31,0x00);
-  tempal = pushax;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2B;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  tempal++;
-  tempah = SiS_Pr->SiS_VCLKData[vclkindex].SR2C;
-  SiS_SetReg1(SiS_Pr->SiS_P3c4,tempal,tempah);
-  return;
-}
-
-#if 0  /* TW: Not used */
-void
-SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr)
-{
-  USHORT  temp;
 
-  if(SiS_Pr->SiS_IF_DEF_LVDS==0) {
-    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x40);
-    SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x10,0x80);
-    temp=(UCHAR)SiS_GetReg1(SiS_Pr->SiS_P3c4,0x16);
-    temp &= 0xC3;
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x35,temp);
-  } else {
-    SiS_SetReg1(SiS_Pr->SiS_P3d4,0x32,0x02);
-    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x02,0x00);
-  }
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x05,0x86);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x20);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x10);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,0x31,0x00);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase,sr2b);
+  SiS_SetReg(SiS_Pr->SiS_P3c4,clkbase+1,sr2c);
 }
-#endif
 
-/* TW: Start of Chrontel 70xx functions ---------------------- */
+/*********************************************/
+/*           SET UP CHRONTEL CHIPS           */
+/*********************************************/
 
-/* Set-up the Chrontel Registers */
-void
-SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
+static void
+SiS_SetCHTVReg(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
                USHORT RefreshRateTableIndex)
 {
   USHORT temp, tempbx, tempcl;
@@ -8864,7 +8716,9 @@
   if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
   if(SiS_Pr->SiS_VBInfo & SetPALTV) {
   	TVType += 2;
-	if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+	if(SiS_Pr->SiS_ModeType > ModeVGA) {
+	   if(SiS_Pr->SiS_CHSOverScan) TVType = 8;
+	}
 	if(SiS_Pr->SiS_CHPALM) {
 		TVType = 4;
 		if(SiS_Pr->SiS_VBInfo & SetCHTVOverScan) TVType += 1;
@@ -8890,44 +8744,44 @@
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
 
 #ifdef SIS300
-  
-     /* Chrontel 7005 - I assume that it does not come with a 310/325 series chip */
 
-     /* TW: We don't support modes >800x600 */
+     /* Chrontel 7005 - I assume that it does not come with a 315 series chip */
+
+     /* We don't support modes >800x600 */
      if (resindex > 5) return;
 
      if(SiS_Pr->SiS_VBInfo & SetPALTV) {
-    	SiS_SetCH700x(SiS_Pr,0x4304);   /* TW: 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(SiS_Pr,0x6909);	/* TW: Black level for PAL (105)*/
+    	SiS_SetCH700x(SiS_Pr,0x4304);   /* 0x40=76uA (PAL); 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x6909);	/* Black level for PAL (105)*/
      } else {
-    	SiS_SetCH700x(SiS_Pr,0x0304);   /* TW: upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
-    	SiS_SetCH700x(SiS_Pr,0x7109);	/* TW: Black level for NTSC (113)*/
+    	SiS_SetCH700x(SiS_Pr,0x0304);   /* upper nibble=71uA (NTSC), 0x03=15bit non-multi RGB*/
+    	SiS_SetCH700x(SiS_Pr,0x7109);	/* Black level for NTSC (113)*/
      }
 
      temp = CHTVRegData[resindex].Reg[0];
-     tempbx=((temp&0x00FF)<<8)|0x00;	/* TW: Mode register */
+     tempbx=((temp&0x00FF)<<8)|0x00;	/* Mode register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[1];
-     tempbx=((temp&0x00FF)<<8)|0x07;	/* TW: Start active video register */
+     tempbx=((temp&0x00FF)<<8)|0x07;	/* Start active video register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[2];
-     tempbx=((temp&0x00FF)<<8)|0x08;	/* TW: Position overflow register */
+     tempbx=((temp&0x00FF)<<8)|0x08;	/* Position overflow register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[3];
-     tempbx=((temp&0x00FF)<<8)|0x0A;	/* TW: Horiz Position register */
+     tempbx=((temp&0x00FF)<<8)|0x0A;	/* Horiz Position register */
      SiS_SetCH700x(SiS_Pr,tempbx);
      temp = CHTVRegData[resindex].Reg[4];
-     tempbx=((temp&0x00FF)<<8)|0x0B;	/* TW: Vertical Position register */
+     tempbx=((temp&0x00FF)<<8)|0x0B;	/* Vertical Position register */
      SiS_SetCH700x(SiS_Pr,tempbx);
 
-     /* TW: Set minimum flicker filter for Luma channel (SR1-0=00),
+     /* Set minimum flicker filter for Luma channel (SR1-0=00),
                 minimum text enhancement (S3-2=10),
    	        maximum flicker filter for Chroma channel (S5-4=10)
 	        =00101000=0x28 (When reading, S1-0->S3-2, and S3-2->S1-0!)
       */
      SiS_SetCH700x(SiS_Pr,0x2801);
 
-     /* TW: Set video bandwidth
+     /* Set video bandwidth
             High bandwith Luma composite video filter(S0=1)
             low bandwith Luma S-video filter (S2-1=00)
 	    disable peak filter in S-video channel (S3=0)
@@ -8936,22 +8790,24 @@
      */
      SiS_SetCH700x(SiS_Pr,0xb103);       /* old: 3103 */
 
-     /* TW: Register 0x3D does not exist in non-macrovision register map
+     /* Register 0x3D does not exist in non-macrovision register map
             (Maybe this is a macrovision register?)
       */
-     /* SiS_SetCH70xx(SiS_Pr,0x003D); */
+#ifndef SIS_CP
+     SiS_SetCH70xx(SiS_Pr,0x003D);
+#endif
 
-     /* TW: Register 0x10 only contains 1 writable bit (S0) for sensing,
+     /* Register 0x10 only contains 1 writable bit (S0) for sensing,
             all other bits a read-only. Macrovision?
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x0010,0x1F);
 
-     /* TW: Register 0x11 only contains 3 writable bits (S0-S2) for
+     /* Register 0x11 only contains 3 writable bits (S0-S2) for
             contrast enhancement (set to 010 -> gain 1 Yout = 17/16*(Yin-30) )
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x0211,0xF8);
 
-     /* TW: Clear DSEN
+     /* Clear DSEN
       */
      SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xEF);
 
@@ -8960,41 +8816,41 @@
          if(resindex == 0x04) {   			/* 640x480 overscan: Mode 16 */
       	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);   	/* loop filter off */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on, no need to set FSCI */
-         } else {
-           if(resindex == 0x05) {    			/* 800x600 overscan: Mode 23 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);     /* Loop filter on for mode 23 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);     /* ACIV off, need to set FSCI */
-           }
+         } else  if(resindex == 0x05) {    		/* 800x600 overscan: Mode 23 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);	/* 0x18-0x1f: FSCI 469,762,048 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0C19,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001A,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001B,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001C,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001D,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001E,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x001F,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0120,0xEF);       /* Loop filter on for mode 23 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);       /* ACIV off, need to set FSCI */
          }
        } else {
          if(resindex == 0x04) {     			 /* ----- 640x480 underscan; Mode 17 */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
-         } else {
-           if(resindex == 0x05) {   			 /* ----- 800x600 underscan: Mode 24 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);     /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);	 /* FSCI for mode 24 is 428,554,851 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x031C,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0a1D,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x031F,0xF0);
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);     /* loop filter off for mode 24 */
-             SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);	 /* ACIV off, need to set FSCI */
-           }
+         } else if(resindex == 0x05) {   		 /* ----- 800x600 underscan: Mode 24 */
+#if 0
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0118,0xF0);       /* (FSCI was 0x1f1c71c7 - this is for mode 22) */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0919,0xF0);	 /* FSCI for mode 24 is 428,554,851 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x081A,0xF0);       /* 198b3a63 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0b1B,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x041C,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x011D,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x061E,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x051F,0xF0);
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF);       /* loop filter off for mode 24 */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0021,0xFE);	 /* ACIV off, need to set FSCI */
+#endif     /* All alternatives wrong (datasheet wrong?), don't use FSCI */
+	   SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	 /* loop filter off */
+           SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);
          }
        }
      } else {				/* ---- PAL ---- */
-           /* TW: We don't play around with FSCI in PAL mode */
+           /* We don't play around with FSCI in PAL mode */
          if (resindex == 0x04) {
            SiS_SetCH70xxANDOR(SiS_Pr,0x0020,0xEF); 	/* loop filter off */
            SiS_SetCH70xxANDOR(SiS_Pr,0x0121,0xFE);      /* ACIV on */
@@ -9012,7 +8868,7 @@
 
 #ifdef SIS315H
 
-     /* TW: We don't support modes >1024x768 */
+     /* We don't support modes >1024x768 */
      if (resindex > 6) return;
 
      temp = CHTVRegData[resindex].Reg[0];
@@ -9078,30 +8934,31 @@
      temp = CHTVRegData[resindex].Reg[15];
      tempbx=((temp & 0x00FF) <<8 ) | 0x10;
      SiS_SetCH701x(SiS_Pr,tempbx);
-     
+
 #endif	/* 315 */
 
   }
-}
 
-/* TW: Chrontel 701x functions ================================= */
+#ifdef SIS_CP
+  SIS_CP_INIT301_CP3
+#endif
+
+}
 
 void
-SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr)
+SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-#ifndef NEWCH701x
   USHORT temp;
-#endif  
 
-  /* TW: Enable Chrontel 7019 LCD panel backlight */
+  /* Enable Chrontel 7019 LCD panel backlight */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef NEWCH701x
+     if(HwInfo->jChipType == SIS_740) {
         SiS_SetCH701x(SiS_Pr,0x6566);
-#else  
+     } else {
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp |= 0x20;
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-#endif	
+     }
   }
 }
 
@@ -9110,7 +8967,7 @@
 {
   USHORT temp;
 
-  /* TW: Disable Chrontel 7019 LCD panel backlight */
+  /* Disable Chrontel 7019 LCD panel backlight */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
         temp = SiS_GetCH701x(SiS_Pr,0x66);
         temp &= 0xDF;
@@ -9118,47 +8975,94 @@
   }
 }
 
-#ifdef SIS315H  /* -------- 310/325 series only --------- */
+#ifdef SIS315H  /* ----------- 315 series only ---------- */
 
-void
-SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+static void
+SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-#ifdef NEWCH701x  
-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                        0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 }; 
-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 			
-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,         
-                        0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 }; 
-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
-#else
-  UCHAR regtable[]  = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
-                        0x72, 0x73, 0x74, 0x76, 0x78, 0x7d };
-  UCHAR table1024[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
-                        0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 }; 
-  UCHAR table1280[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
-   			0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 }; 			
-  UCHAR table1400[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,   
-                        0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 }; 
-  UCHAR table1600[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
-  			0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
-#endif			
+  UCHAR regtable[]      = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
+  UCHAR table1024_740[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
+  UCHAR table1400_740[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
+  UCHAR asus1024_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+  UCHAR asus1400_740[]  = { 0x19, 0x6e, 0x01, 0x19, 0x09 };
+  UCHAR table1024_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR table1400_650[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
+  UCHAR *tableptr = NULL;
+  int i;
+
+  /* Set up Power up/down timing */
+
+  if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1024_740;
+        else    			          tableptr = table1024_740;
+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) tableptr = asus1400_740;
+        else					  tableptr = table1400_740;
+     } else return;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_650;
+     } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
+               (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
+	       (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
+        tableptr = table1400_650;
+     } else return;
+  }
+
+  for(i=0; i<5; i++) {
+     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
+  }
+}
+
+static void
+SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  UCHAR regtable[]      = { 0x1c, 0x5f, 0x64, 0x6f, 0x70, 0x71,
+                            0x72, 0x73, 0x74, 0x76, 0x78, 0x7d, 0x66 };
+  UCHAR table1024_740[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                            0xa3, 0xc8, 0xc7, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1280_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   			    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1400_740[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+                            0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02, 0x44 };
+  UCHAR table1600_740[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a, 0x44 };
+  UCHAR table1024_650[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xed,
+                            0xa3, 0xc8, 0xc7, 0xac, 0x60, 0x02 };
+  UCHAR table1280_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xe3,
+   		   	    0xad, 0xdb, 0xf6, 0xac, 0xe0, 0x02 };
+  UCHAR table1400_650[] = { 0x60, 0x03, 0x11, 0x00, 0x40, 0xef,
+                            0xad, 0xdb, 0xf6, 0xac, 0x60, 0x02 };
+  UCHAR table1600_650[] = { 0x60, 0x04, 0x11, 0x00, 0x40, 0xe3,
+  			    0xad, 0xde, 0xf6, 0xac, 0x60, 0x1a };
   UCHAR *tableptr = NULL;
   USHORT tempbh;
   int i;
 
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-     tableptr = table1024;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
-     tableptr = table1280;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-     tableptr = table1400;
-  } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
-     tableptr = table1600;
-  } else return;
+  if(HwInfo->jChipType == SIS_740) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        tableptr = table1280_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+        tableptr = table1400_740;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+        tableptr = table1600_740;
+     } else return;
+  } else {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        tableptr = table1024_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        tableptr = table1280_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
+        tableptr = table1400_650;
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) {
+        tableptr = table1600_650;
+     } else return;
+  }
 
   tempbh = SiS_GetCH701x(SiS_Pr,0x74);
   if((tempbh == 0xf6) || (tempbh == 0xc7)) {
@@ -9169,268 +9073,254 @@
         if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) return;
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
      } else if(tempbh == 0xde) {
-        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) return;
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) return;
      }
   }
-#ifdef NEWCH701x     /* New from 740/LVDS: */    
-  for(i=0; i<0x0d; i++) {	
-#else
-  for(i=0; i<0x0c; i++) {
-#endif  
+
+  if(HwInfo->jChipType == SIS_740) {
+     tempbh = 0x0d;
+  } else {
+     tempbh = 0x0c;
+  }
+  for(i = 0; i < tempbh; i++) {
      SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
   }
-  SiS_ChrontelPowerSequencing(SiS_Pr);
+  SiS_ChrontelPowerSequencing(SiS_Pr,HwInfo);
   tempbh = SiS_GetCH701x(SiS_Pr,0x1e);
   tempbh |= 0xc0;
   SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1e);
-  
-#ifdef NEWCH701x     /* 740/LVDS: */
-  tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
-  tempbh &= 0xfb;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
-  SiS_SetReg1(SiS_Pr->SiS_Part1Port, 0x2d, 0x03);
-  tempbh = SiS_GetCH701x(SiS_Pr,0x64);
-  tempbh |= 0x40;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
-  tempbh = SiS_GetCH701x(SiS_Pr,0x03);
-  tempbh &= 0x3f;
-  SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
-#endif  /* End 740/LVDS */
+
+  if(HwInfo->jChipType == SIS_740) {
+     tempbh = SiS_GetCH701x(SiS_Pr,0x1c);
+     tempbh &= 0xfb;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x1c);
+     SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+     tempbh = SiS_GetCH701x(SiS_Pr,0x64);
+     tempbh |= 0x40;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x64);
+     tempbh = SiS_GetCH701x(SiS_Pr,0x03);
+     tempbh &= 0x3f;
+     SiS_SetCH701x(SiS_Pr,(tempbh << 8) | 0x03);
+  }
 }
 
-void
-SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr)
+static void
+SiS_ChrontelResetVSync(SiS_Private *SiS_Pr)
 {
-  UCHAR regtable[]  = { 0x67, 0x68, 0x69, 0x6a, 0x6b };
-#ifdef NEWCH701x  
-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x01 };
-  UCHAR table1400[] = { 0x01, 0x6e, 0x01, 0x01, 0x01 };
-#else
-  UCHAR table1024[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-  UCHAR table1400[] = { 0x01, 0x02, 0x01, 0x01, 0x02 };
-#endif  
-  UCHAR *tableptr = NULL;
-  int i;
+     unsigned char temp, temp1;
 
-  /* Set up Power up/down timing */
-  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-     tableptr = table1024;
-  } else if((SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) ||
-            (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) ||
-	    (SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200)) {
-     tableptr = table1400;
-  } else return;
-  
-  for(i=0; i<5; i++) {
-     SiS_SetCH701x(SiS_Pr,(tableptr[i] << 8) | regtable[i]);
-  }
+     temp1 = SiS_GetCH701x(SiS_Pr,0x49);
+     SiS_SetCH701x(SiS_Pr,0x3e49);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
+     temp &= 0x7f;	/* Use external VSYNC */
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+     SiS_LongDelay(SiS_Pr,3);
+     temp = SiS_GetCH701x(SiS_Pr,0x47);
+     temp |= 0x80;	/* Use internal VSYNC */
+     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+     SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
 }
 
 void
-SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr)
+SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
 
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
-#ifdef NEWCH701x
-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
-     temp |= 0x04;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-#endif 
-     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+     if(HwInfo->jChipType == SIS_740) {
+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
+        temp |= 0x04;	/* Invert XCLK phase */
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+     }
+     if(SiS_IsYPbPr(SiS_Pr, HwInfo)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
-	temp |= 0x80;	/* TW: Enable YPrPb (HDTV) */
+	temp |= 0x80;	/* Enable YPrPb (HDTV) */
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
-     if(SiS_IsChScart(SiS_Pr,HwDeviceExtension, BaseAddr)) {
+     if(SiS_IsChScart(SiS_Pr, HwInfo)) {
         temp = SiS_GetCH701x(SiS_Pr,0x01);
 	temp &= 0x3f;
-	temp |= 0xc0;	/* TW: Enable SCART + CVBS */
+	temp |= 0xc0;	/* Enable SCART + CVBS */
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x01);
      }
-#ifdef NEWCH701x
-     SiS_ChrontelDoSomething5(SiS_Pr);
-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
-#else      
-     SiS_SetCH701x(SiS_Pr,0x2049);   			/* TW: Enable TV path */
-     temp = SiS_GetCH701x(SiS_Pr,0x49);
-     if(SiS_IsYPbPr(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-        temp = SiS_GetCH701x(SiS_Pr,0x73);
-	temp |= 0x60;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+     if(HwInfo->jChipType == SIS_740) {
+        SiS_ChrontelResetVSync(SiS_Pr);
+        SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
+     } else {
+        SiS_SetCH701x(SiS_Pr,0x2049);   /* Enable TV path */
+        temp = SiS_GetCH701x(SiS_Pr,0x49);
+        if(SiS_IsYPbPr(SiS_Pr,HwInfo)) {
+           temp = SiS_GetCH701x(SiS_Pr,0x73);
+	   temp |= 0x60;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x73);
+        }
+        temp = SiS_GetCH701x(SiS_Pr,0x47);
+        temp &= 0x7f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
+        SiS_LongDelay(SiS_Pr,2);
+        temp = SiS_GetCH701x(SiS_Pr,0x47);
+        temp |= 0x80;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
      }
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp &= 0x7f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-     SiS_LongDelay(SiS_Pr,2);
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp |= 0x80;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-#endif     
   }
 }
 
 void
-SiS_Chrontel701xOff(SiS_Private *SiS_Pr)
+SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT temp;
 
+  /* Complete power down of LVDS */
   if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+     if(HwInfo->jChipType == SIS_740) {
+        SiS_LongDelay(SiS_Pr,1);
+	SiS_GenericDelay(SiS_Pr,0x16ff);
+	SiS_SetCH701x(SiS_Pr,0xac76);
+	SiS_SetCH701x(SiS_Pr,0x0066);
+     } else {
         SiS_LongDelay(SiS_Pr,2);
-	/* TW: Complete power down of LVDS */
 	temp = SiS_GetCH701x(SiS_Pr,0x76);
 	temp &= 0xfc;
 	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
 	SiS_SetCH701x(SiS_Pr,0x0066);
+     }
   }
 }
 
-#ifdef NEWCH701x
-void
-SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr)
-{
-     unsigned char temp, temp1;
-     
-     temp1 = SiS_GetCH701x(SiS_Pr,0x49);
-     SiS_SetCH701x(SiS_Pr,0x3e49);
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp &= 0x7f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-     SiS_LongDelay(SiS_Pr,3);
-     temp = SiS_GetCH701x(SiS_Pr,0x47);
-     temp |= 0x80;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);
-     SiS_SetCH701x(SiS_Pr,(temp1 << 8) | 0x49);
-}
-#endif
-
-void
-SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+static void
+SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-#ifdef NEWCH701x
      USHORT temp;
-     
-     /* 740/LVDS: */
-     temp = SiS_GetCH701x(SiS_Pr,0x4a);
-     temp &= 0x01;
-     if(!(temp)) {
-     
-        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	   temp = SiS_GetCH701x(SiS_Pr,0x49);
-	   SiS_SetCH701x(SiS_Pr,0x3e49);
-	}
-	/* TW: Reset Chrontel 7019 datapath */
+
+     if(HwInfo->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x4a);  /* Version ID */
+        temp &= 0x01;
+        if(!temp) {
+
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+	      temp = SiS_GetCH701x(SiS_Pr,0x49);
+	      SiS_SetCH701x(SiS_Pr,0x3e49);
+	   }
+	   /* Reset Chrontel 7019 datapath */
+           SiS_SetCH701x(SiS_Pr,0x1048);
+           SiS_LongDelay(SiS_Pr,1);
+           SiS_SetCH701x(SiS_Pr,0x1848);
+
+	   if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
+	      SiS_ChrontelResetVSync(SiS_Pr);
+	      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
+	   }
+
+        } else {
+
+	   /* Clear/set/clear GPIO */
+           temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp &= 0xef;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp |= 0x10;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x5c);
+	   temp &= 0xef;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
+	   temp = SiS_GetCH701x(SiS_Pr,0x61);
+	   if(!temp) {
+	      SiS_SetCH701xForLCD(SiS_Pr, HwInfo);
+	   }
+        }
+
+     } else { /* 650 */
+        /* Reset Chrontel 7019 datapath */
         SiS_SetCH701x(SiS_Pr,0x1048);
         SiS_LongDelay(SiS_Pr,1);
         SiS_SetCH701x(SiS_Pr,0x1848);
-	
-	if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	   SiS_ChrontelDoSomething5(SiS_Pr);
-	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x49);
-	}    
-     } else {
-     
-        temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp &= 0xef;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp |= 0x10;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x5c);
-	temp &= 0xef;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x5c);
-	temp = SiS_GetCH701x(SiS_Pr,0x61);
-	if(!temp) {
-	   SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
-	}
-     }
-#else /* pre 740/LVDS code */     
-     /* TW: Reset Chrontel 7019 datapath */
-     SiS_SetCH701x(SiS_Pr,0x1048);
-     SiS_LongDelay(SiS_Pr,1);
-     SiS_SetCH701x(SiS_Pr,0x1848);
-#endif     
+     }
 }
 
 void
-SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
-#ifdef NEWCH701x
-     if(!(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr))) {
-        SiS_ChrontelDoSomething5(SiS_Pr);
-     }
-#else
      USHORT temp;
 
-     SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
-     temp = SiS_GetCH701x(SiS_Pr,0x49);
-     temp &= 1;
-     if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
-	temp = SiS_GetCH701x(SiS_Pr,0x47);
-	temp &= 0x70;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
-	SiS_LongDelay(SiS_Pr,3);
-	temp = SiS_GetCH701x(SiS_Pr,0x47);
-	temp |= 0x80;
-	SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
+     if(HwInfo->jChipType == SIS_740) {
+
+        if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwInfo)) {
+           SiS_ChrontelResetVSync(SiS_Pr);
+        }
+
+     } else {
+
+        SiS_SetCH701x(SiS_Pr,0xaf76);  /* Power up LVDS block */
+        temp = SiS_GetCH701x(SiS_Pr,0x49);
+        temp &= 1;
+        if(temp != 1) {  /* TV block powered? (0 = yes, 1 = no) */
+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
+	   temp &= 0x70;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* enable VSYNC */
+	   SiS_LongDelay(SiS_Pr,3);
+	   temp = SiS_GetCH701x(SiS_Pr,0x47);
+	   temp |= 0x80;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x47);  /* disable VSYNC */
+        }
+
      }
-#endif     
 }
 
-void
-SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                         USHORT BaseAddr)
+static void
+SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_INFO HwInfo)
 {
-#ifdef NEWCH701x
-     USHORT temp;
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x61);
-     if(temp < 1) {
-          temp++;
-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-     }
-     SiS_SetCH701x(SiS_Pr,0x4566);
-     SiS_SetCH701x(SiS_Pr,0xaf76);
-     SiS_LongDelay(SiS_Pr,1);
-     SiS_GenericDelay(SiS_Pr,0x16ff);
-
-#else
      USHORT temp,temp1;
-     
-     temp1 = 0;
-     temp = SiS_GetCH701x(SiS_Pr,0x61);
-     if(temp < 2) {
-          temp++;
-	  SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
-	  temp1 = 1;
-     }
-     SiS_SetCH701x(SiS_Pr,0xac76);
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     temp |= 0x5f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-     if(ModeNo > 0x13) {
-         if(SiS_WeHaveBacklightCtrl(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-	    SiS_GenericDelay(SiS_Pr,0x3ff);
-	 } else {
-	    SiS_GenericDelay(SiS_Pr,0x2ff);
-	 }
-     } else {
-         if(!temp1)
-	    SiS_GenericDelay(SiS_Pr,0x2ff);
+
+     if(HwInfo->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x61);
+        if(temp < 1) {
+           temp++;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+        }
+        SiS_SetCH701x(SiS_Pr,0x4566);  /* Panel power on */
+        SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on */
+        SiS_LongDelay(SiS_Pr,1);
+        SiS_GenericDelay(SiS_Pr,0x16ff);
+
+     } else {  /* 650 */
+
+        temp1 = 0;
+        temp = SiS_GetCH701x(SiS_Pr,0x61);
+        if(temp < 2) {
+           temp++;
+	   SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x61);
+	   temp1 = 1;
+        }
+        SiS_SetCH701x(SiS_Pr,0xac76);
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp |= 0x5f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+        if(ModeNo > 0x13) {
+           if(SiS_WeHaveBacklightCtrl(SiS_Pr, HwInfo)) {
+	      SiS_GenericDelay(SiS_Pr,0x3ff);
+	   } else {
+	      SiS_GenericDelay(SiS_Pr,0x2ff);
+	   }
+        } else {
+           if(!temp1)
+	      SiS_GenericDelay(SiS_Pr,0x2ff);
+        }
+        temp = SiS_GetCH701x(SiS_Pr,0x76);
+        temp |= 0x03;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
+        temp = SiS_GetCH701x(SiS_Pr,0x66);
+        temp &= 0x7f;
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
+        SiS_LongDelay(SiS_Pr,1);
+
      }
-     temp = SiS_GetCH701x(SiS_Pr,0x76);
-     temp |= 0x03;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     temp &= 0x7f;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x66);
-     SiS_LongDelay(SiS_Pr,1);
-#endif     
 }
 
-void
-SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr)
+static void
+SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp,tempcl,tempch;
 
@@ -9440,43 +9330,43 @@
 
      do {
        temp = SiS_GetCH701x(SiS_Pr,0x66);
-       temp &= 0x04;
+       temp &= 0x04;  /* PLL stable? -> bail out */
        if(temp == 0x04) break;
-       
-#ifdef NEWCH701x
-       SiS_SetCH701x(SiS_Pr,0xac76);    /* 740/LVDS */
-#endif       
 
-       SiS_SetCH701xForLCD(SiS_Pr,HwDeviceExtension,BaseAddr);
+       if(HwInfo->jChipType == SIS_740) {
+          /* Power down LVDS output, PLL normal operation */
+          SiS_SetCH701x(SiS_Pr,0xac76);
+       }
+
+       SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
 
        if(tempcl == 0) {
            if(tempch == 3) break;
-	   SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
+	   SiS_ChrontelResetDB(SiS_Pr,HwInfo);
 	   tempcl = 3;
 	   tempch++;
        }
        tempcl--;
        temp = SiS_GetCH701x(SiS_Pr,0x76);
-       temp &= 0xfb;
+       temp &= 0xfb;  /* Reset PLL */
        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
        SiS_LongDelay(SiS_Pr,2);
        temp = SiS_GetCH701x(SiS_Pr,0x76);
-       temp |= 0x04;
+       temp |= 0x04;  /* PLL normal operation */
        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x76);
-#ifdef NEWCH701x
-       SiS_SetCH701x(SiS_Pr,0xe078);
-#else       
-       SiS_SetCH701x(SiS_Pr,0x6078);
-#endif       
+       if(HwInfo->jChipType == SIS_740) {
+          SiS_SetCH701x(SiS_Pr,0xe078);	/* PLL loop filter */
+       } else {
+          SiS_SetCH701x(SiS_Pr,0x6078);
+       }
        SiS_LongDelay(SiS_Pr,2);
     } while(0);
 
-    SiS_SetCH701x(SiS_Pr,0x0077);
+    SiS_SetCH701x(SiS_Pr,0x0077);  /* MV? */
 }
 
 void
-SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                         USHORT BaseAddr)
+SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
      USHORT temp;
 
@@ -9484,280 +9374,464 @@
      temp |= 0x80;	/* Set datapath 1 to TV   */
      temp &= 0xbf;	/* Set datapath 2 to LVDS */
      SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-     
-#ifdef NEWCH701x   /* 740/LVDS: */
 
-     temp = SiS_GetCH701x(SiS_Pr,0x1c);
-     temp &= 0xfb;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
-     
-     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2d,0x03);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x64);
-     temp |= 0x40;
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x03);
-     temp &= 0x3f;	
-     SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
-     
-     temp = SiS_GetCH701x(SiS_Pr,0x66);
-     if(temp != 0x45) {
-        SiS_ChrontelResetDB(SiS_Pr,HwDeviceExtension,BaseAddr);
-        SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
-	temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
-     }     
+     if(HwInfo->jChipType == SIS_740) {
+
+        temp = SiS_GetCH701x(SiS_Pr,0x1c);
+        temp &= 0xfb;	/* Normal XCLK phase */
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x1c);
+
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2d,0x03);
+
+        temp = SiS_GetCH701x(SiS_Pr,0x64);
+        temp |= 0x40;	/* ? Bit not defined */
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x64);
+
+        temp = SiS_GetCH701x(SiS_Pr,0x03);
+        temp &= 0x3f;	/* D1 input to both LVDS and TV */
+        SiS_SetCH701x(SiS_Pr,(temp << 8) | 0x03);
+
+	if(SiS_Pr->SiS_CustomT == CUT_ASUSL3000D) {
+	   SiS_SetCH701x(SiS_Pr,0x4063); /* LVDS off */
+	   SiS_LongDelay(SiS_Pr, 1);
+	   SiS_SetCH701x(SiS_Pr,0x0063); /* LVDS on */
+	   SiS_ChrontelResetDB(SiS_Pr, HwInfo);
+	   SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
+	   SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+	} else {
+           temp = SiS_GetCH701x(SiS_Pr,0x66);
+           if(temp != 0x45) {
+              SiS_ChrontelResetDB(SiS_Pr, HwInfo);
+              SiS_ChrontelDoSomething2(SiS_Pr, HwInfo);
+              SiS_ChrontelDoSomething3(SiS_Pr, 0, HwInfo);
+           }
+	}
+
+     } else { /* 650 */
 
-#else  /* pre-740/LVDS: */     
+        SiS_ChrontelResetDB(SiS_Pr,HwInfo);
+        SiS_ChrontelDoSomething2(SiS_Pr,HwInfo);
+        temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x34);
+        SiS_ChrontelDoSomething3(SiS_Pr,temp,HwInfo);
+        SiS_SetCH701x(SiS_Pr,0xaf76);  /* All power on, LVDS normal operation */
 
-     SiS_ChrontelResetDB(SiS_Pr);
+     }
 
-     SiS_ChrontelDoSomething2(SiS_Pr,HwDeviceExtension,BaseAddr);
+}
+#endif  /* 315 series  */
 
-     temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x34);
-     SiS_ChrontelDoSomething3(SiS_Pr,temp,HwDeviceExtension,BaseAddr);
+/*********************************************/
+/*      MAIN: SET CRT2 REGISTER GROUP        */
+/*********************************************/
 
-     SiS_SetCH701x(SiS_Pr,0xaf76);
-     
-#endif  /* End of pre-740/LVDS */
+BOOLEAN
+SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
+{
+#ifdef SIS300
+   UCHAR  *ROMAddr  = HwInfo->pjVirtualRomBase;
+#endif
+   USHORT ModeIdIndex, RefreshRateTableIndex;
+#if 0
+   USHORT temp;
+#endif
+
+   SiS_Pr->SiS_SetFlag |= ProgrammingCRT2;
+
+   if(!SiS_Pr->UseCustomMode) {
+      SiS_SearchModeID(SiS_Pr, &ModeNo, &ModeIdIndex);
+   } else {
+      ModeIdIndex = 0;
+   }
+
+   /* Used for shifting CR33 */
+   SiS_Pr->SiS_SelectCRT2Rate = 4;
+
+   SiS_UnLockCRT2(SiS_Pr, HwInfo);
+
+   RefreshRateTableIndex = SiS_GetRatePtr(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+
+   SiS_SaveCRT2Info(SiS_Pr,ModeNo);
+
+   if(SiS_LowModeTest(SiS_Pr, ModeNo, HwInfo)) {
+      SiS_DisableBridge(SiS_Pr,HwInfo);
+      if((SiS_Pr->SiS_IF_DEF_LVDS == 1) && (HwInfo->jChipType == SIS_730)) {
+         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x00,0x80);
+      }
+      SiS_SetCRT2ModeRegs(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+   }
+
+   if(SiS_Pr->SiS_VBInfo & DisableCRT2Display) {
+#if 0
+      /* RDirectLCDN */
+      if( (SiS_IsVAMode(SiS_Pr, HwInfo)) ||
+          (SiS_IsDualEdge(SiS_Pr, HwInfo)) ) {
+         temp = SiS_GetReg(SiS_Pr->SiS_Part4Port,0x23);
+         SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x23,0x80);
+	 SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x23,0x7f);
+	 SiS_SetReg(SiS_Pr->SiS_Part4Port,0x23,temp);
+      }
+#endif
+      SiS_LockCRT2(SiS_Pr, HwInfo);
+      SiS_DisplayOn(SiS_Pr);
+      return TRUE;
+   }
+
+   SiS_GetCRT2Data(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+
+   /* Set up Panel Link for LVDS, 301BDH and 650/30xLV(for LCDA) */
+   if( (SiS_Pr->SiS_IF_DEF_LVDS == 1) ||
+       ((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) ||
+       ((HwInfo->jChipType >= SIS_315H) && (SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) ) {
+   	SiS_GetLVDSDesData(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+   } else {
+        SiS_Pr->SiS_LCDHDES = SiS_Pr->SiS_LCDVDES = 0;
+   }
+
+#ifdef LINUX_XF86
+#ifdef TWDEBUG
+  xf86DrvMsg(0, X_INFO, "(init301: LCDHDES 0x%03x LCDVDES 0x%03x)\n", SiS_Pr->SiS_LCDHDES, SiS_Pr->SiS_LCDVDES);
+  xf86DrvMsg(0, X_INFO, "(init301: HDE     0x%03x VDE     0x%03x)\n", SiS_Pr->SiS_HDE, SiS_Pr->SiS_VDE);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHDE  0x%03x VGAVDE  0x%03x)\n", SiS_Pr->SiS_VGAHDE, SiS_Pr->SiS_VGAVDE);
+  xf86DrvMsg(0, X_INFO, "(init301: HT      0x%03x VT      0x%03x)\n", SiS_Pr->SiS_HT, SiS_Pr->SiS_VT);
+  xf86DrvMsg(0, X_INFO, "(init301: VGAHT   0x%03x VGAVT   0x%03x)\n", SiS_Pr->SiS_VGAHT, SiS_Pr->SiS_VGAVT);
+#endif
+#endif
+
+   if(SiS_LowModeTest(SiS_Pr, ModeNo, HwInfo)) {
+      SiS_SetGroup1(SiS_Pr, ModeNo, ModeIdIndex, HwInfo, RefreshRateTableIndex);
+   }
+
+   if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
+
+        if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+
+	   SiS_SetGroup2(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+      	   SiS_SetGroup3(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+      	   SiS_SetGroup4(SiS_Pr, ModeNo, ModeIdIndex, RefreshRateTableIndex, HwInfo);
+      	   SiS_SetGroup5(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+
+	   /* For 301BDH (Panel link initialization): */
+	   if((SiS_Pr->SiS_VBType & VB_NoLCD) && (SiS_Pr->SiS_VBInfo & SetCRT2ToLCD)) {
+	      if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+		 if(!((SiS_Pr->SiS_SetFlag & SetDOSMode) && ((ModeNo == 0x03) || (ModeNo = 0x10)))) {
+		    if(SiS_Pr->SiS_VBInfo & SetInSlaveMode) {
+		       SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
+		                       RefreshRateTableIndex,HwInfo);
+		    }
+                 }
+	      }
+	      SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
+		              RefreshRateTableIndex,HwInfo);
+	   }
+        }
+
+   } else {
+
+        if(SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel640x480) {
+	   if(SiS_Pr->SiS_IF_DEF_TRUMPION == 0) {
+    	      SiS_ModCRT1CRTC(SiS_Pr,ModeNo,ModeIdIndex,
+	                      RefreshRateTableIndex,HwInfo);
+	   }
+	}
+
+        SiS_SetCRT2ECLK(SiS_Pr,ModeNo,ModeIdIndex,
+	                RefreshRateTableIndex,HwInfo);
+
+	if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+     	   if(SiS_Pr->SiS_IF_DEF_CH70xx != 0) {
+	      if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+	         if(SiS_Pr->SiS_IF_DEF_CH70xx == 2) {
+#ifdef SIS315H
+		    SiS_SetCH701xForLCD(SiS_Pr,HwInfo);
+#endif
+		 }
+	      }
+	      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+       		 SiS_SetCHTVReg(SiS_Pr,ModeNo,ModeIdIndex,
+		               RefreshRateTableIndex);
+	      }
+     	   }
+	}
+
+   }
+
+#ifdef SIS300
+   if(HwInfo->jChipType < SIS_315H) {
+      if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+	 if(SiS_Pr->SiS_UseOEM) {
+	    if((SiS_Pr->SiS_UseROM) && ROMAddr && (SiS_Pr->SiS_UseOEM == -1)) {
+	       if((ROMAddr[0x233] == 0x12) && (ROMAddr[0x234] == 0x34)) {
+	          SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
+	       			    RefreshRateTableIndex);
+	       }
+	    } else {
+       	       SiS_OEM300Setting(SiS_Pr,HwInfo,ModeNo,ModeIdIndex,
+	       			 RefreshRateTableIndex);
+	    }
+	 }
+	 if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+            if((SiS_Pr->SiS_CustomT == CUT_BARCO1366) ||
+	       (SiS_Pr->SiS_CustomT == CUT_BARCO1024)) {
+	       SetOEMLCDData2(SiS_Pr, HwInfo, ModeNo, ModeIdIndex,RefreshRateTableIndex);
+	    }
+            if(HwInfo->jChipType == SIS_730) {
+               SiS_DisplayOn(SiS_Pr);
+	    }
+         }
+      }
+      if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+          if(HwInfo->jChipType != SIS_730) {
+             SiS_DisplayOn(SiS_Pr);
+	  }
+      }
+   }
+#endif
+
+#ifdef SIS315H
+   if(HwInfo->jChipType >= SIS_315H) {
+      if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+	 SiS_FinalizeLCD(SiS_Pr, ModeNo, ModeIdIndex, HwInfo);
+         if(SiS_Pr->SiS_UseOEM) {
+            SiS_OEM310Setting(SiS_Pr, HwInfo, ModeNo, ModeIdIndex);
+         }
+         SiS_CRT2AutoThreshold(SiS_Pr);
+      }
+   }
+#endif
+
+   if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+      SiS_EnableBridge(SiS_Pr, HwInfo);
+   }
+
+   SiS_DisplayOn(SiS_Pr);
+
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) {
+      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
+	 /* Disable LCD panel when using TV */
+	 SiS_SetRegOR(SiS_Pr->SiS_P3c4,0x11,0x0C);
+      } else {
+	 /* Disable TV when using LCD */
+	 SiS_SetCH70xxANDOR(SiS_Pr,0x010E,0xF8);
+      }
+   }
+
+   if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+      SiS_LockCRT2(SiS_Pr,HwInfo);
+   }
+
+   return TRUE;
 }
 
-#endif  /* 310/325 series --------------------------------- */
 
-/* TW: End of Chrontel 701x functions ==================================== */
+/*********************************************/
+/*     ENABLE/DISABLE LCD BACKLIGHT (SIS)    */
+/*********************************************/
+
+void
+SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  /* Switch on LCD backlight on SiS30xLV */
+  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x02)) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x02);
+     SiS_WaitVBRetrace(SiS_Pr,HwInfo);
+  }
+  if(!(SiS_GetReg(SiS_Pr->SiS_Part4Port,0x26) & 0x01)) {
+     SiS_SetRegOR(SiS_Pr->SiS_Part4Port,0x26,0x01);
+  }
+}
+
+void
+SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
+{
+  /* Switch off LCD backlight on SiS30xLV */
+  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFE);
+  SiS_SetRegAND(SiS_Pr->SiS_Part4Port,0x26,0xFD);
+}
 
-/* TW: Generic Read/write routines for Chrontel ========================== */
+/*********************************************/
+/*          DDC RELATED FUNCTIONS            */
+/*********************************************/
 
-/* TW: The Chrontel is connected to the 630/730 via
+/* The Chrontel 700x is connected to the 630/730 via
  * the 630/730's DDC/I2C port.
  *
- * On 630(S)T chipset, the index changed from 0x11 to 0x0a,
- * possibly for working around the DDC problems
+ * On 630(S)T chipset, the index changed from 0x11 to
+ * 0x0a, possibly for working around the DDC problems
  */
 
-void
-SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+static BOOLEAN
+SiS_SetChReg(SiS_Private *SiS_Pr, USHORT tempbx, USHORT myor)
 {
-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-      SiS_SetCH700x(SiS_Pr,tempbx);
-   else
-      SiS_SetCH701x(SiS_Pr,tempbx);
+  USHORT tempah,temp,i;
+
+  for(i=0; i<20; i++) {				/* Do 20 attempts to write */
+     if(i) {
+        SiS_SetStop(SiS_Pr);
+	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+     }
+     if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+     if(temp) continue;				/*    (ERROR: no ack) */
+     tempah = tempbx & 0x00FF;			/* Write RAB */
+     tempah |= myor;                            /* (700x: set bit 7, see datasheet) */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+     if(temp) continue;				/*    (ERROR: no ack) */
+     tempah = (tempbx & 0xFF00) >> 8;
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write data */
+     if(temp) continue;				/*    (ERROR: no ack) */
+     if(SiS_SetStop(SiS_Pr)) continue;		/* Set stop condition */
+     SiS_Pr->SiS_ChrontelInit = 1;
+     return TRUE;
+  }
+  return FALSE;
 }
 
-/* TW: Write to Chrontel 700x */
+/* Write to Chrontel 700x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
 SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
+  SiS_Pr->SiS_DDC_DataShift = 0x00;
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
 
   if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x11;		   /* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_Pr->SiS_DDC_Data  = 0x02;                 /* Bitmask in IndexReg for Data */
-     SiS_Pr->SiS_DDC_Clk   = 0x01;                 /* Bitmask in IndexReg for Clk */
-     SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	   /* TW: DAB (Device Address Byte) */
-  }
-
-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-    /* SiS_SetSwitchDDC2(SiS_Pr); */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    tempah = tempbx & 0x00FF;			/* TW: Write RAB */
-    tempah |= 0x80;                             /* TW: (set bit 7, see datasheet) */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    tempah = (tempbx & 0xFF00) >> 8;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
-    SiS_Pr->SiS_ChrontelInit = 1;
-    return;
+     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
+     SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
   }
 
-  /* TW: For 630ST */
-  if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 7 = SC;  Bit 6 = SD */
+  if( (!(SiS_SetChReg(SiS_Pr, tempbx, 0x80))) &&
+      (!(SiS_Pr->SiS_ChrontelInit)) ) {
+     SiS_Pr->SiS_DDC_Index = 0x0a;		/* Bit 7 = SC;  Bit 6 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
-     SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
 
-     for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-       /* SiS_SetSwitchDDC2(SiS_Pr); */
-       if (SiS_SetStart(SiS_Pr)) continue;	/* TW: Set start condition */
-       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
-       tempah = tempbx & 0x00FF;		/* TW: Write RAB */
-       tempah |= 0x80;                          /* TW: (set bit 7, see datasheet) */
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
-       tempah = (tempbx & 0xFF00) >> 8;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-       if(temp) continue;			/* TW:    (ERROR: no ack) */
-       if(SiS_SetStop(SiS_Pr)) continue;	/* TW: Set stop condition */
-       SiS_Pr->SiS_ChrontelInit = 1;
-       return;
-    }
+     SiS_SetChReg(SiS_Pr, tempbx, 0x80);
   }
 }
 
-/* TW: Write to Chrontel 701x */
+/* Write to Chrontel 701x */
 /* Parameter is [Data (S15-S8) | Register no (S7-S0)] */
 void
 SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
-
-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
   SiS_Pr->SiS_DDC_DataShift = 0x00;
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* TW: DAB (Device Address Byte) */
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  		/* DAB (Device Address Byte) */
 
-  for(i=0;i<10;i++) {	/* TW: Do only 10 attempts to write */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    tempah = tempbx & 0x00FF;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write RAB */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    tempah = (tempbx & 0xFF00) >> 8;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write data */
-    if(temp) continue;				/* TW:    (ERROR: no ack) */
-    if(SiS_SetStop(SiS_Pr)) continue;		/* TW: Set stop condition */
-    return;
-  }
+  SiS_SetChReg(SiS_Pr, tempbx, 0);
 }
 
-/* TW: Read from Chrontel 70xx */
-/* Parameter is [Register no (S7-S0)] */
-USHORT
-SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+void
+SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-   if (SiS_Pr->SiS_IF_DEF_CH70xx == 1)
-      return(SiS_GetCH700x(SiS_Pr,tempbx));
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+      SiS_SetCH700x(SiS_Pr,tempbx);
    else
-      return(SiS_GetCH701x(SiS_Pr,tempbx));
+      SiS_SetCH701x(SiS_Pr,tempbx);
+}
+
+static USHORT
+SiS_GetChReg(SiS_Private *SiS_Pr, USHORT myor)
+{
+  USHORT tempah,temp,i;
+
+  for(i=0; i<20; i++) {				/* Do 20 attempts to read */
+     if(i) {
+        SiS_SetStop(SiS_Pr);
+	SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
+     }
+     if(SiS_SetStart(SiS_Pr)) continue;		/* Set start condition */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr;
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* Write DAB (S0=0=write) */
+     if(temp) continue;				/*        (ERROR: no ack) */
+     tempah = SiS_Pr->SiS_DDC_ReadAddr | myor;	/* Write RAB (700x: | 0x80) */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
+     if(temp) continue;				/*        (ERROR: no ack) */
+     if (SiS_SetStart(SiS_Pr)) continue;	/* Re-start */
+     tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01;/* DAB | 0x01 = Read */
+     temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* DAB (S0=1=read) */
+     if(temp) continue;				/*        (ERROR: no ack) */
+     tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* Read byte */
+     if(SiS_SetStop(SiS_Pr)) continue;		/* Stop condition */
+     SiS_Pr->SiS_ChrontelInit = 1;
+     return(tempah);
+  }
+  return 0xFFFF;
 }
 
-/* TW: Read from Chrontel 700x */
+/* Read from Chrontel 700x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
 SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
+  USHORT result;
+
+  SiS_Pr->SiS_DDC_DataShift = 0x00;
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
 
   if(!(SiS_Pr->SiS_ChrontelInit)) {
-     SiS_Pr->SiS_DDC_Index = 0x11;		/* TW: Bit 0 = SC;  Bit 1 = SD */
+     SiS_Pr->SiS_DDC_Index = 0x11;		/* Bit 0 = SC;  Bit 1 = SD */
      SiS_Pr->SiS_DDC_Data  = 0x02;              /* Bitmask in IndexReg for Data */
      SiS_Pr->SiS_DDC_Clk   = 0x01;              /* Bitmask in IndexReg for Clk */
-     SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
   }
 
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-  for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-    /* SiS_SetSwitchDDC2(SiS_Pr); */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-    if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
-    SiS_Pr->SiS_ChrontelInit = 1;
-    return(tempah);
-  }
-
-  /* TW: For 630ST */
-  if(!SiS_Pr->SiS_ChrontelInit) {
-     SiS_Pr->SiS_DDC_Index = 0x0a;		/* TW: Bit 0 = SC;  Bit 1 = SD */
-     SiS_Pr->SiS_DDC_Data  = 0x80;              /* Bitmask in IndexReg for Data */
-     SiS_Pr->SiS_DDC_Clk   = 0x40;              /* Bitmask in IndexReg for Clk */
-     SiS_Pr->SiS_DDC_DataShift = 0x00;
-     SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;  	/* TW: DAB (Device Address Byte) */
+  if( ((result = SiS_GetChReg(SiS_Pr,0x80)) == 0xFFFF) &&
+      (!SiS_Pr->SiS_ChrontelInit) ) {
 
-     for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-       /* SiS_SetSwitchDDC2(SiS_Pr); */
-       if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-       tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: Write DAB (S0=0=write) */
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       tempah = SiS_Pr->SiS_DDC_ReadAddr | 0x80;	/* TW: Write RAB | 0x80 */
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-       tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; 	/* DAB | 0x01 = Read */
-       temp = SiS_WriteDDC2Data(SiS_Pr,tempah);		/* TW: DAB (S0=1=read) */
-       if(temp) continue;				/* TW:        (ERROR: no ack) */
-       tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-       if (SiS_SetStop(SiS_Pr)) continue;		/* TW: Stop condition */
-       SiS_Pr->SiS_ChrontelInit = 1;
-       return(tempah);
-     }
+     SiS_Pr->SiS_DDC_Index = 0x0a;
+     SiS_Pr->SiS_DDC_Data  = 0x80;
+     SiS_Pr->SiS_DDC_Clk   = 0x40;
+
+     result = SiS_GetChReg(SiS_Pr,0x80);
   }
-  return(0xFFFF);
+  return(result);
 }
 
-/* TW: Read from Chrontel 701x */
+/* Read from Chrontel 701x */
 /* Parameter is [Register no (S7-S0)] */
 USHORT
 SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx)
 {
-  USHORT tempah,temp,i;
-
-  SiS_Pr->SiS_DDC_Index = 0x11;			/* TW: Bit 0 = SC;  Bit 1 = SD */
+  SiS_Pr->SiS_DDC_Index = 0x11;			/* Bit 0 = SC;  Bit 1 = SD */
   SiS_Pr->SiS_DDC_Data  = 0x08;                 /* Bitmask in IndexReg for Data */
   SiS_Pr->SiS_DDC_Clk   = 0x04;                 /* Bitmask in IndexReg for Clk */
   SiS_Pr->SiS_DDC_DataShift = 0x00;
-  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* TW: DAB */
+  SiS_Pr->SiS_DDC_DeviceAddr = 0xEA;		/* DAB */
+
   SiS_Pr->SiS_DDC_ReadAddr = tempbx;
 
-   for(i=0;i<20;i++) {	/* TW: Do only 20 attempts to read */
-    if(SiS_SetStart(SiS_Pr)) continue;		/* TW: Set start condition */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr;
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: Write DAB (S0=0=write) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_Pr->SiS_DDC_ReadAddr;		/* TW: Write RAB */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    if (SiS_SetStart(SiS_Pr)) continue;		/* TW: Re-start */
-    tempah = SiS_Pr->SiS_DDC_DeviceAddr | 0x01; /* DAB | 0x01 = Read */
-    temp = SiS_WriteDDC2Data(SiS_Pr,tempah);	/* TW: DAB (S0=1=read) */
-    if(temp) continue;				/* TW:        (ERROR: no ack) */
-    tempah = SiS_ReadDDC2Data(SiS_Pr,tempah);	/* TW: Read byte */
-    SiS_SetStop(SiS_Pr);			/* TW: Stop condition */
-    return(tempah);
-   }
-  return 0xFFFF;
+  return(SiS_GetChReg(SiS_Pr,0));
 }
 
-#ifdef LINUX_XF86
-/* TW: Our own DDC functions */
+/* Read from Chrontel 70xx */
+/* Parameter is [Register no (S7-S0)] */
+USHORT
+SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx)
+{
+   if(SiS_Pr->SiS_IF_DEF_CH70xx == 1)
+      return(SiS_GetCH700x(SiS_Pr, tempbx));
+   else
+      return(SiS_GetCH701x(SiS_Pr, tempbx));
+}
+
+/* Our own DDC functions */
 USHORT
-SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype,
-		BOOLEAN checkcr32)
+SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32)
 {
      unsigned char ddcdtype[] = { 0xa0, 0xa0, 0xa0, 0xa2, 0xa6 };
      unsigned char flag, cr32;
      USHORT        temp = 0, myadaptnum = adaptnum;
 
      if(adaptnum != 0) {
-        if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0xFFFF;
-	if((pSiS->VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
+        if(!(VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0xFFFF;
+	if((VBFlags & VB_30xBDH) && (adaptnum == 1)) return 0xFFFF;
      }	
      
      /* adapternum for SiS bridges: 0 = CRT1, 1 = LCD, 2 = VGA2 */
@@ -9770,9 +9844,10 @@
      SiS_Pr->SiS_DDC_Index = 0x11;
      flag = 0xff;
 
-     cr32 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x32);
-  
-     if(pSiS->VBFlags & VB_SISBRIDGE) {
+     cr32 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x32);
+
+#if 0
+     if(VBFlags & VB_SISBRIDGE) {
 	if(myadaptnum == 0) {
 	   if(!(cr32 & 0x20)) {
 	      myadaptnum = 2;
@@ -9785,18 +9860,19 @@
 	   }
         }
      }
+#endif
 
-     if(pSiS->VGAEngine == SIS_300_VGA) {		/* 300 series */
+     if(VGAEngine == SIS_300_VGA) {		/* 300 series */
 	
         if(myadaptnum != 0) {
 	   flag = 0;
-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	   if(VBFlags & VB_SISBRIDGE) {
 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
 	   }
         }
 
-	if(!(pSiS->VBFlags & VB_301)) {
+	if(!(VBFlags & VB_301)) {
 	   if((cr32 & 0x80) && (checkcr32)) {
               if(myadaptnum >= 1) {
 	         if(!(cr32 & 0x08)) {
@@ -9810,11 +9886,11 @@
 	temp = 4 - (myadaptnum * 2);
 	if(flag) temp = 0;
 
-     } else {						/* 310/325/330 series */
+     } else {						/* 315/330 series */
 
      	/* here we simplify: 0 = CRT1, 1 = CRT2 (VGA, LCD) */
 	
-	if(pSiS->VBFlags & VB_SISBRIDGE) {
+	if(VBFlags & VB_SISBRIDGE) {
 	   if(myadaptnum == 2) {
 	      myadaptnum = 1;
            }
@@ -9822,7 +9898,7 @@
 
         if(myadaptnum == 1) {
      	   flag = 0;
-	   if(pSiS->VBFlags & VB_SISBRIDGE) {
+	   if(VBFlags & VB_SISBRIDGE) {
 	      SiS_Pr->SiS_DDC_Port = SiS_Pr->SiS_Part4Port;
               SiS_Pr->SiS_DDC_Index = 0x0f;
 	   }
@@ -9840,7 +9916,7 @@
         temp = myadaptnum;
         if(myadaptnum == 1) {
            temp = 0;
-	   if(pSiS->VBFlags & VB_LVDS) flag = 0xff;
+	   if(VBFlags & VB_LVDS) flag = 0xff;
         }
 
 	if(flag) temp = 0;
@@ -9852,7 +9928,7 @@
 #ifdef TWDEBUG
     xf86DrvMsg(0, X_INFO, "DDC Port %x Index %x Shift %d\n",
     		SiS_Pr->SiS_DDC_Port, SiS_Pr->SiS_DDC_Index, temp);
-#endif	 
+#endif
     
     return 0;
 }
@@ -9862,15 +9938,9 @@
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_DeviceAddr)) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "WriteDAB 1 failed\n");
-#endif	 
   	return 0xFFFF;
    }
    if(SiS_WriteDDC2Data(SiS_Pr, SiS_Pr->SiS_DDC_SecAddr)) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "WriteDAB 2 failed\n");
-#endif	 
    	return 0xFFFF;
    }
    return(0);
@@ -9881,9 +9951,6 @@
 {
    if(SiS_SetStart(SiS_Pr)) return 0xFFFF;
    if(SiS_WriteDDC2Data(SiS_Pr, (SiS_Pr->SiS_DDC_DeviceAddr | 0x01))) {
-#ifdef TWDEBUG
-        xf86DrvMsg(0, X_INFO, "PrepareReadDDC 1 failed\n");
-#endif	 
    	return 0xFFFF;
    }
    return(0);
@@ -9922,8 +9989,8 @@
     if(SiS_PrepareDDC(SiS_Pr)) {
          SiS_SetStop(SiS_Pr);
 #ifdef TWDEBUG
-	 xf86DrvMsg(0, X_INFO, "DoProbeDDC 1 failed at PrepareDDC\n");
-#endif	 
+         xf86DrvMsg(0, X_INFO, "Probe: Prepare failed\n");
+#endif
          return(0xFFFF);
     }
     mask = 0xf0;
@@ -9937,6 +10004,9 @@
        } else {
            failed = TRUE;
 	   ret = 0xFFFF;
+#ifdef TWDEBUG
+           xf86DrvMsg(0, X_INFO, "Probe: Read 1 failed\n");
+#endif
        }
     }
     if(failed == FALSE) {
@@ -9946,6 +10016,9 @@
        if(temp == value) ret = 0;
        else {
           ret = 0xFFFF;
+#ifdef TWDEBUG
+          xf86DrvMsg(0, X_INFO, "Probe: Read 2 failed\n");
+#endif
           if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
              if(temp == 0x30) ret = 0;
           }
@@ -9972,7 +10045,7 @@
 }
 
 USHORT
-SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer)
+SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer)
 {
    USHORT flag, length, i;
    unsigned char chksum,gotcha;
@@ -10004,28 +10077,7 @@
    return(flag);
 }
 
-USHORT
-SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer)
-{
-   USHORT i=0, flag=0;
-
-   length--;
-   
-   SiS_SetSwitchDDC2(SiS_Pr);
-   if(!(SiS_PrepareDDC(SiS_Pr))) {
-      for(i=0; i<length; i++) {
-         buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
-         SiS_SendACK(SiS_Pr, 0);
-      }
-      buffer[i] = (unsigned char)SiS_ReadDDC2Data(SiS_Pr, 0);
-      SiS_SendACK(SiS_Pr, 1);
-   } else flag = 0xFFFF;
-   
-   SiS_SetStop(SiS_Pr);
-   return(0);
-}
-
-/* TW: Our private DDC function
+/* Our private DDC functions
 
    It complies somewhat with the corresponding VESA function
    in arguments and return values.
@@ -10036,7 +10088,7 @@
 
    Arguments:
        adaptnum: 0=CRT1, 1=LCD, 2=VGA2
-                 CRT2 DDC is only supported on SiS301, 301B (non-DH version), 302B.
+                 CRT2 DDC is only supported on SiS301, 301B, 302B.
        DDCdatatype: 0=Probe, 1=EDID, 2=EDID+VDIF, 3=EDID V2 (P&D), 4=EDID V2 (FPDI-2)
        buffer: ptr to 256 data bytes which will be filled with read data.
 
@@ -10046,43 +10098,74 @@
 
  */
 USHORT
-SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
-              USHORT DDCdatatype, unsigned char *buffer)
+SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer)
 {
+   unsigned char sr1f,cr17=1;
+   USHORT result;
+
    if(adaptnum > 2) return 0xFFFF;
    if(DDCdatatype > 4) return 0xFFFF;
-   if((!(pSiS->VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+   if((!(VBFlags & VB_VIDEOBRIDGE)) && (adaptnum > 0)) return 0xFFFF;
+   if(SiS_InitDDCRegs(SiS_Pr, VBFlags, VGAEngine, adaptnum, DDCdatatype, TRUE) == 0xFFFF) return 0xFFFF;
+
+   sr1f = SiS_GetReg(SiS_Pr->SiS_P3c4,0x1f);
+   SiS_SetRegANDOR(SiS_Pr->SiS_P3c4,0x1f,0x3f,0x04);
+   if(VGAEngine == SIS_300_VGA) {
+      cr17 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x17) & 0x80;
+      if(!cr17) {
+         SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x17,0x80);
+         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x01);
+         SiS_SetReg(SiS_Pr->SiS_P3c4,0x00,0x03);
+      }
+   }
+   if((sr1f) || (!cr17)) {
+      SiS_WaitRetrace1(SiS_Pr);
+      SiS_WaitRetrace1(SiS_Pr);
+      SiS_WaitRetrace1(SiS_Pr);
+      SiS_WaitRetrace1(SiS_Pr);
+   }
+
    if(DDCdatatype == 0) {
-       return(SiS_ProbeDDC(SiS_Pr));
+      result = SiS_ProbeDDC(SiS_Pr);
    } else {
-       return(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer));
+      result = SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer);
    }
+   SiS_SetReg(SiS_Pr->SiS_P3c4,0x1f,sr1f);
+   if(VGAEngine == SIS_300_VGA) {
+      SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x17,0x7f,cr17);
+   }
+   return result;
 }
 
+#ifdef LINUX_XF86
 /* Sense the LCD parameters (CR36, CR37) via DDC */
 /* SiS30x(B) only */
 USHORT
 SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
 {
-   USHORT DDCdatatype, paneltype, flag, xres, yres;
+   USHORT DDCdatatype, paneltype, flag, xres=0, yres=0;
    USHORT index, myindex, lumsize, numcodes;
    unsigned char cr37=0, seekcode;
    BOOLEAN checkexpand = FALSE;
    int retry, i;
    unsigned char buffer[256];
-   
-   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+
+   for(i=0; i<7; i++) SiS_Pr->CP_DataValid[i] = FALSE;
+   SiS_Pr->CP_HaveCustomData = FALSE;
+   SiS_Pr->CP_MaxX = SiS_Pr->CP_MaxY = SiS_Pr->CP_MaxClock = 0;
+
+   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
    if(pSiS->VBFlags & VB_30xBDH) return 0;
   
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0;
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 1, 0, FALSE) == 0xFFFF) return 0;
    
    SiS_Pr->SiS_DDC_SecAddr = 0x00;
    
    /* Probe supported DA's */
    flag = SiS_ProbeDDC(SiS_Pr);
 #ifdef TWDEBUG   
-   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+   xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
    	"CRT2 DDC capabilities 0x%x\n", flag);
 #endif	
    if(flag & 0x10) {
@@ -10099,7 +10182,7 @@
    /* Read the entire EDID */
    retry = 2;
    do {
-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
@@ -10132,7 +10215,7 @@
       }
       
       if((buffer[0x18] & 0x18) != 0x08) {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED, 
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
 	 	"CRT2: Attached display is not of RGB but of %s type (0x%02x)\n", 
 		((buffer[0x18] & 0x18) == 0x00) ? "monochrome/greyscale" :
 		  ( ((buffer[0x18] & 0x18) == 0x10) ? "non-RGB multicolor" : 
@@ -10140,103 +10223,227 @@
 		buffer[0x18]);
 	 return 0;
       }
-      
-      /* Now analyze the first Detailed Timing Block and hope
-       * that the preferred timing mode is stored there.
-       */	
-      xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
-      yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+      /* Now analyze the first Detailed Timing Block and see
+       * if the preferred timing mode is stored there. If so,
+       * check if this is a standard panel for which we already
+       * know the timing.
+       */
+
+      paneltype = Panel_Custom;
       checkexpand = FALSE;
-      switch(xres) {
-         case 800:
-	     if(yres == 600) {
-	     	paneltype = Panel310_800x600;
-	     	checkexpand = TRUE;
-	     }
-	     break;
-         case 1024:
-	     if(yres == 768) {
-	     	paneltype = Panel310_1024x768;
-	     	checkexpand = FALSE;    /* expand causes error at 640x480, should otherwise be TRUE; */
-	     }
-	     break;
-	 case 1280:
-	     if(yres == 960) {
-	        if(pSiS->VGAEngine == SIS_300_VGA) {
-		   paneltype = Panel300_1280x960;
-		} else {
-		   paneltype = Panel310_1280x960; 
-		}
-	     } else if(yres == 1024) {
-	     	paneltype = Panel310_1280x1024;  
-		checkexpand = TRUE;
-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
+
+      if(buffer[0x18] & 0x02) {
+
+         xres = buffer[0x38] | ((buffer[0x3a] & 0xf0) << 4);
+         yres = buffer[0x3b] | ((buffer[0x3d] & 0xf0) << 4);
+
+	 SiS_Pr->CP_PreferredX = xres;
+	 SiS_Pr->CP_PreferredY = yres;
+
+         switch(xres) {
+            case 800:
+	        if(yres == 600) {
+	     	   paneltype = Panel_800x600;
+	     	   checkexpand = TRUE;
+	        }
+	        break;
+            case 1024:
 	        if(yres == 768) {
-	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
-		   checkexpand = TRUE;	
-	        }	
-	     }
-	     break;
-	 case 1400:
-	     if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 1050) {
-	           paneltype = Panel310_1400x1050;
-		   checkexpand = TRUE; 
-	        } 
-	     }
-      	     break;
-	 case 1600:
-	     if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 1200) {
-	           paneltype = Panel310_1600x1200;
+	     	   paneltype = Panel_1024x768;
+	     	   checkexpand = TRUE;
+	        }
+	        break;
+	    case 1280:
+	        if(yres == 1024) {
+	     	   paneltype = Panel_1280x1024;
 		   checkexpand = TRUE;
-	        } 
-	     }
-      	     break;
+	        } else if(yres == 960) {
+	           if(pSiS->VGAEngine == SIS_300_VGA) {
+		      paneltype = Panel300_1280x960;
+		   } else {
+		      paneltype = Panel310_1280x960;
+		   }
+	        } else if(yres == 768) {
+	       	   paneltype = Panel_1280x768;
+		   checkexpand = FALSE;
+		   cr37 |= 0x10;
+	        }
+	        break;
+	    case 1400:
+	        if(pSiS->VGAEngine == SIS_315_VGA) {
+	           if(yres == 1050) {
+	              paneltype = Panel310_1400x1050;
+		      checkexpand = TRUE;
+	           }
+	        }
+      	        break;
+#if 0	    /* Treat this as custom, as we have no valid timing data yet */
+	    case 1600:
+	        if(pSiS->VGAEngine == SIS_315_VGA) {
+	           if(yres == 1200) {
+	              paneltype = Panel310_1600x1200;
+		      checkexpand = TRUE;
+	           }
+	        }
+      	        break;
+#endif
+         }
+
+	 if(paneltype != Panel_Custom) {
+	    if((buffer[0x47] & 0x18) == 0x18) {
+	       cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
+	    } else {
+	       /* What now? There is no digital separate output timing... */
+	       xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
+	    }
+	 }
+
       }
 
-      if(buffer[0x18] & 0x02) {
-         /* If the preferred timing mode is stored in the first
-	  * detailed timing block, we now can extract the sync
-	  * polarisation information as well. This only works
-	  * if the Flags indicate a digital separate output.
-	  */
-	  if((buffer[0x47] & 0x18) == 0x18) {
-	     cr37 |= ((((buffer[0x47] & 0x06) ^ 0x06) << 5) | 0x20);
-	  } else {
-	     /* What now? There is no digital separate output timing... */
-	     xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	     	"CRT2: Unable to retrieve Sync polarity information\n");
-	  }
-	  
-      } else {
-         /* If the preferred timing mode is *not* stored in the first
-	  * detailed timing block, we need to guess the resolution
-	  * from the supported Established Timings and assume the
-	  * default sync polarity
-	  */
+      /* If we still don't know what panel this is, we take it
+       * as a custom panel and derive the timing data from the
+       * detailed timing blocks
+       */
+      if(paneltype == Panel_Custom) {
+
+         BOOLEAN havesync = FALSE;
+	 int i, temp, base = 0x36;
+	 unsigned long estpack;
+	 unsigned short estx[] = {
+	 	720, 720, 640, 640, 640, 640, 800, 800,
+		800, 800, 832,1024,1024,1024,1024,1280,
+		1152
+	 };
+	 unsigned short esty[] = {
+	 	400, 400, 480, 480, 480, 480, 600, 600,
+		600, 600, 624, 768, 768, 768, 768,1024,
+		870
+	 };
+
 	 paneltype = 0;
-	 if(buffer[0x24] & 0x01) { 	
-	 	paneltype = Panel310_1280x1024;
-		checkexpand = TRUE;
-		cr37 |= 0x20;
-	 } else if(buffer[0x24] & 0x0e) {
-	 	paneltype = Panel310_1024x768;
-		cr37 |= 0xe0;
-		checkexpand = FALSE;		/* Bug at 640x480 */
-	 } else if(buffer[0x23] & 0x01) {
-	 	paneltype = Panel310_800x600;
-		cr37 |= 0xe0;
-		checkexpand = TRUE;
-         }
+
+	 /* Find the maximum resolution */
+
+	 /* 1. From Established timings */
+	 estpack = (buffer[0x23] << 9) | (buffer[0x24] << 1) | ((buffer[0x25] >> 7) & 0x01);
+	 for(i=16; i>=0; i--) {
+	     if(estpack & (1 << i)) {
+	        if(estx[16 - i] > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = estx[16 - i];
+		if(esty[16 - i] > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = esty[16 - i];
+	     }
+	 }
+
+	 /* 2. From Standard Timings */
+	 for(i=0x26; i < 0x36; i+=2) {
+	    if((buffer[i] != 0x01) && (buffer[i+1] != 0x01)) {
+	       temp = (buffer[i] + 31) * 8;
+	       if(temp > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = temp;
+	       switch((buffer[i+1] & 0xc0) >> 6) {
+	       case 0x03: temp = temp * 9 / 16; break;
+	       case 0x02: temp = temp * 4 / 5;  break;
+	       case 0x01: temp = temp * 3 / 4;  break;
+	       }
+	       if(temp > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = temp;
+	    }
+	 }
+
+	 /* Now extract the Detailed Timings and convert them into modes */
+
+         for(i = 0; i < 4; i++, base += 18) {
+
+	    /* Is this a detailed timing block or a monitor descriptor? */
+	    if(buffer[base] || buffer[base+1] || buffer[base+2]) {
+
+      	       xres = buffer[base+2] | ((buffer[base+4] & 0xf0) << 4);
+               yres = buffer[base+5] | ((buffer[base+7] & 0xf0) << 4);
+
+	       SiS_Pr->CP_HDisplay[i] = xres;
+	       SiS_Pr->CP_HSyncStart[i] = xres + (buffer[base+8] | ((buffer[base+11] & 0xc0) << 2));
+               SiS_Pr->CP_HSyncEnd[i]   = SiS_Pr->CP_HSyncStart[i] + (buffer[base+9] | ((buffer[base+11] & 0x30) << 4));
+	       SiS_Pr->CP_HTotal[i] = xres + (buffer[base+3] | ((buffer[base+4] & 0x0f) << 8));
+	       SiS_Pr->CP_HBlankStart[i] = xres + 1;
+	       SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
+
+	       SiS_Pr->CP_VDisplay[i] = yres;
+               SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[base+10] & 0xf0) >> 4) | ((buffer[base+11] & 0x0c) << 2));
+               SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[base+10] & 0x0f) | ((buffer[base+11] & 0x03) << 4));
+	       SiS_Pr->CP_VTotal[i] = yres + (buffer[base+6] | ((buffer[base+7] & 0x0f) << 8));
+	       SiS_Pr->CP_VBlankStart[i] = yres + 1;
+	       SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
+
+	       SiS_Pr->CP_Clock[i] = (buffer[base] | (buffer[base+1] << 8)) * 10;
+
+	       SiS_Pr->CP_DataValid[i] = TRUE;
+
+	       /* Sort out invalid timings, interlace and too high clocks */
+	       if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
+	          (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
+	          (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
+	          (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
+	          (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
+	          (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
+	          (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
+	          (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
+	          (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
+	          ( ((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162000)) ||
+		    ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108000)) ) ||
+		  (buffer[base+17] & 0x80)) {
+
+	          SiS_Pr->CP_DataValid[i] = FALSE;
+
+	       } else {
+
+	          paneltype = Panel_Custom;
+
+		  SiS_Pr->CP_HaveCustomData = TRUE;
+
+		  if(xres > SiS_Pr->CP_MaxX) SiS_Pr->CP_MaxX = xres;
+	          if(yres > SiS_Pr->CP_MaxY) SiS_Pr->CP_MaxY = yres;
+		  if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+
+		  SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
+		  SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
+
+	          /* We must assume the panel can scale, since we have
+	           * no scaling data
+		   */
+	          checkexpand = FALSE;
+	          cr37 |= 0x10;
+
+	          /* Extract the sync polarisation information. This only works
+	           * if the Flags indicate a digital separate output.
+	           */
+	          if((buffer[base+17] & 0x18) == 0x18) {
+		     SiS_Pr->CP_HSync_P[i] = (buffer[base+17] & 0x02) ? TRUE : FALSE;
+		     SiS_Pr->CP_VSync_P[i] = (buffer[base+17] & 0x04) ? TRUE : FALSE;
+		     SiS_Pr->CP_SyncValid[i] = TRUE;
+		     if(!havesync) {
+	                cr37 |= ((((buffer[base+17] & 0x06) ^ 0x06) << 5) | 0x20);
+			havesync = TRUE;
+	   	     }
+	          } else {
+		     SiS_Pr->CP_SyncValid[i] = FALSE;
+		  }
+	       }
+            }
+	 }
+	 if(!havesync) {
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	       	   "CRT2: Unable to retrieve Sync polarity information\n");
+   	 }
       }
-      
-      if(checkexpand) {
-         /* If any of the Established low-res modes is supported, the 
+
+      if(paneltype && checkexpand) {
+         /* If any of the Established low-res modes is supported, the
 	  * panel can scale automatically. For 800x600 panels, we only 
 	  * check the even lower ones.
 	  */
-	 if(paneltype == Panel310_800x600) {
+	 if(paneltype == Panel_800x600) {
 	    if(buffer[0x23] & 0xfc) cr37 |= 0x10;
 	 } else {
             if(buffer[0x23])	    cr37 |= 0x10;
@@ -10262,20 +10469,31 @@
 		buffer[0x41]);
 	 return 0;
       }
-   
-      xres = buffer[0x76] | (buffer[0x77] << 8);
-      yres = buffer[0x78] | (buffer[0x79] << 8);
+
+      paneltype = Panel_Custom;
+      SiS_Pr->CP_MaxX = xres = buffer[0x76] | (buffer[0x77] << 8);
+      SiS_Pr->CP_MaxY = yres = buffer[0x78] | (buffer[0x79] << 8);
       switch(xres) {
          case 800:
 	     if(yres == 600) {
-	     	paneltype = Panel310_800x600;
+	     	paneltype = Panel_800x600;
 	     	checkexpand = TRUE;
 	     }
 	     break;
          case 1024:
 	     if(yres == 768) {
-	     	paneltype = Panel310_1024x768;
-	     	checkexpand = FALSE;			/* Bug at 640x480; we do the scaling ourselves */
+	     	paneltype = Panel_1024x768;
+	     	checkexpand = TRUE;
+	     }
+	     break;
+	 case 1152:
+	     if(yres == 768) {
+	        if(pSiS->VGAEngine == SIS_300_VGA) {
+		   paneltype = Panel300_1152x768;
+		} else {
+		   paneltype = Panel310_1152x768;
+		}
+	     	checkexpand = TRUE;
 	     }
 	     break;
 	 case 1280:
@@ -10286,45 +10504,46 @@
 		   paneltype = Panel300_1280x960;
 		}
 	     } else if(yres == 1024) {
-	     	paneltype = Panel310_1280x1024;  
+	     	paneltype = Panel_1280x1024;
 		checkexpand = TRUE;
-	     } else if(pSiS->VGAEngine == SIS_315_VGA) {
-	        if(yres == 768) {
-	       	   paneltype = Panel310_1280x768; 	/* Panel size 1280x768 not supported yet */
-		   checkexpand = TRUE;
-	        }
-	     } 
+	     } else if(yres == 768) {
+	        paneltype = Panel_1280x768;
+		checkexpand = FALSE;
+		cr37 |= 0x10;
+	     }
 	     break;
 	 case 1400:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(yres == 1050) {
 	           paneltype = Panel310_1400x1050;
 		   checkexpand = TRUE;
-	        } 
+	        }
 	     }
       	     break;
+#if 0    /* Treat this one as custom since we have no timing data yet */
 	 case 1600:
 	     if(pSiS->VGAEngine == SIS_315_VGA) {
 	        if(yres == 1200) {
 	           paneltype = Panel310_1600x1200;
 		   checkexpand = TRUE;
-	        } 
+	        }
 	     }
       	     break;
+#endif
       }
-                 
+
       /* Determine if RGB18 or RGB24 */
       if(index) {
          if((buffer[index] == 0x20) || (buffer[index] == 0x34)) {
 	    cr37 |= 0x01;
 	 }
       }
-      
+
       if(checkexpand) {
          /* TODO - for now, we let the panel scale */
 	 cr37 |= 0x10;
       }
-     
+
       /* Now seek 4-Byte Timing codes and extract sync pol info */
       index = 0x80;
       if(buffer[0x7e] & 0x20) {			    /* skip Luminance Table (if provided) */
@@ -10346,32 +10565,122 @@
 	 if(buffer[myindex] == seekcode) {
 	    cr37 |= ((((buffer[myindex + 1] & 0x0c) ^ 0x0c) << 4) | 0x20);
 	 } else {
-	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	    	"CRT2: Unable to retrieve Sync polarity information\n");    
+	    xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	        "CRT2: Unable to retrieve Sync polarity information\n");
 	 }
       } else {
-         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING, 
-	    	"CRT2: Unable to retrieve Sync polarity information\n");
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_WARNING,
+	     "CRT2: Unable to retrieve Sync polarity information\n");
+      }
+
+      /* Now seek the detailed timing descriptions for custom panels */
+      if(paneltype == Panel_Custom) {
+         index += (numcodes * 4);
+	 numcodes = buffer[0x7f] & 0x07;
+	 for(i=0; i<numcodes; i++) {
+	    xres = buffer[index+2] | ((buffer[index+4] & 0xf0) << 4);
+            yres = buffer[index+5] | ((buffer[index+7] & 0xf0) << 4);
+
+	    SiS_Pr->CP_HDisplay[i] = xres;
+	    SiS_Pr->CP_HSyncStart[i] = xres + (buffer[index+8] | ((buffer[index+11] & 0xc0) << 2));
+            SiS_Pr->CP_HSyncEnd[i] = SiS_Pr->CP_HSyncStart[i] + (buffer[index+9] | ((buffer[index+11] & 0x30) << 4));
+	    SiS_Pr->CP_HTotal[i] = xres + (buffer[index+3] | ((buffer[index+4] & 0x0f) << 8));
+	    SiS_Pr->CP_HBlankStart[i] = xres + 1;
+	    SiS_Pr->CP_HBlankEnd[i] = SiS_Pr->CP_HTotal[i];
+
+	    SiS_Pr->CP_VDisplay[i] = yres;
+            SiS_Pr->CP_VSyncStart[i] = yres + (((buffer[index+10] & 0xf0) >> 4) | ((buffer[index+11] & 0x0c) << 2));
+            SiS_Pr->CP_VSyncEnd[i] = SiS_Pr->CP_VSyncStart[i] + ((buffer[index+10] & 0x0f) | ((buffer[index+11] & 0x03) << 4));
+	    SiS_Pr->CP_VTotal[i] = yres + (buffer[index+6] | ((buffer[index+7] & 0x0f) << 8));
+	    SiS_Pr->CP_VBlankStart[i] = yres + 1;
+	    SiS_Pr->CP_VBlankEnd[i] = SiS_Pr->CP_VTotal[i];
+
+	    SiS_Pr->CP_Clock[i] = (buffer[index] | (buffer[index+1] << 8)) * 10;
+
+	    SiS_Pr->CP_DataValid[i] = TRUE;
+
+	    if((SiS_Pr->CP_HDisplay[i] > SiS_Pr->CP_HSyncStart[i])  ||
+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HSyncEnd[i])   ||
+	       (SiS_Pr->CP_HDisplay[i] >= SiS_Pr->CP_HTotal[i])     ||
+	       (SiS_Pr->CP_HSyncStart[i] >= SiS_Pr->CP_HSyncEnd[i]) ||
+	       (SiS_Pr->CP_HSyncStart[i] > SiS_Pr->CP_HTotal[i])    ||
+	       (SiS_Pr->CP_HSyncEnd[i] > SiS_Pr->CP_HTotal[i])      ||
+	       (SiS_Pr->CP_VDisplay[i] > SiS_Pr->CP_VSyncStart[i])  ||
+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VSyncEnd[i])   ||
+	       (SiS_Pr->CP_VDisplay[i] >= SiS_Pr->CP_VTotal[i])     ||
+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VSyncEnd[i])  ||
+	       (SiS_Pr->CP_VSyncStart[i] > SiS_Pr->CP_VTotal[i])    ||
+	       (SiS_Pr->CP_VSyncEnd[i] > SiS_Pr->CP_VTotal[i])      ||
+	       ( ((pSiS->VBFlags & VB_301C) && (SiS_Pr->CP_Clock[i] > 162000)) ||
+		 ((!(pSiS->VBFlags & VB_301C)) && (SiS_Pr->CP_Clock[i] > 108000)) ) ||
+	       (buffer[index + 17] & 0x80)) {
+
+	       SiS_Pr->CP_DataValid[i] = FALSE;
+
+	    } else {
+
+	       SiS_Pr->CP_HaveCustomData = TRUE;
+
+	       if(SiS_Pr->CP_Clock[i] > SiS_Pr->CP_MaxClock) SiS_Pr->CP_MaxClock = SiS_Pr->CP_Clock[i];
+
+	       SiS_Pr->CP_HSync_P[i] = (buffer[index + 17] & 0x02) ? TRUE : FALSE;
+	       SiS_Pr->CP_VSync_P[i] = (buffer[index + 17] & 0x04) ? TRUE : FALSE;
+	       SiS_Pr->CP_SyncValid[i] = TRUE;
+
+	       SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
+	       SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
+
+	       /* We must assume the panel can scale, since we have
+	        * no scaling data
+    	        */
+	       cr37 |= 0x10;
+
+	    }
+	 }
+
       }
 
       break;
-     
+
    }
-   
+
    /* 1280x960 panels are always RGB24, unable to scale and use
     * high active sync polarity
     */
    if(pSiS->VGAEngine == SIS_315_VGA) {
-      if(paneltype == Panel310_1280x960) cr37 &= 0x0e; 
+      if(paneltype == Panel310_1280x960) cr37 &= 0x0e;
    } else {
-      if(paneltype == Panel300_1280x960) cr37 &= 0x0e; 
+      if(paneltype == Panel300_1280x960) cr37 &= 0x0e;
    }
-   
+
+   for(i = 0; i < 7; i++) {
+      if(SiS_Pr->CP_DataValid[i]) {
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+            "Non-standard LCD timing data no. %d:\n", i);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	    "   HDisplay %d HSync %d HSyncEnd %d HTotal %d\n",
+	    SiS_Pr->CP_HDisplay[i], SiS_Pr->CP_HSyncStart[i],
+	    SiS_Pr->CP_HSyncEnd[i], SiS_Pr->CP_HTotal[i]);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+            "   VDisplay %d VSync %d VSyncEnd %d VTotal %d\n",
+            SiS_Pr->CP_VDisplay[i], SiS_Pr->CP_VSyncStart[i],
+   	    SiS_Pr->CP_VSyncEnd[i], SiS_Pr->CP_VTotal[i]);
+         xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	    "   Pixel clock: %3.3fMhz\n", (float)SiS_Pr->CP_Clock[i] / 1000);
+	 xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
+	    "   To use this, add \"%dx%d\" to the list of Modes in the Screen section\n",
+	    SiS_Pr->CP_HDisplay[i],
+	    SiS_Pr->CP_VDisplay[i]);
+      }
+   }
+
    if(paneltype) {
+       if(!SiS_Pr->CP_PreferredX) SiS_Pr->CP_PreferredX = SiS_Pr->CP_MaxX;
+       if(!SiS_Pr->CP_PreferredY) SiS_Pr->CP_PreferredY = SiS_Pr->CP_MaxY;
        cr37 &= 0xf1;
        cr37 |= 0x02;    /* SiS301 */
        SiS_SetRegANDOR(SiS_Pr->SiS_P3d4,0x36,0xf0,paneltype);
-       SiS_SetReg1(SiS_Pr->SiS_P3d4,0x37,cr37);
+       SiS_SetReg(SiS_Pr->SiS_P3d4,0x37,cr37);
        SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x08);
 #ifdef TWDEBUG       
        xf86DrvMsgVerb(pSiS->pScrn->scrnIndex, X_PROBED, 3, 
@@ -10389,10 +10698,10 @@
    int retry;
    unsigned char buffer[256];
 
-   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_302B))) return 0;
+   if(!(pSiS->VBFlags & (VB_301|VB_301B|VB_301C|VB_302B))) return 0;
 /* if(pSiS->VBFlags & VB_30xBDH) return 0;  */
    
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 2, 0, FALSE) == 0xFFFF) return 0;
+   if(SiS_InitDDCRegs(SiS_Pr, pSiS->VBFlags, pSiS->VGAEngine, 2, 0, FALSE) == 0xFFFF) return 0;
    
    SiS_Pr->SiS_DDC_SecAddr = 0x00;
    
@@ -10408,7 +10717,7 @@
       SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
       DDCdatatype = 1;
    } else {
-   	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
+   	xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO,
 		"Do DDC answer\n");
    	return 0;				/* no DDC support (or no device attached) */
    }
@@ -10416,7 +10725,7 @@
    /* Read the entire EDID */
    retry = 2;
    do {
-      if(SiS_ReadDDC(SiS_Pr, pSiS, DDCdatatype, buffer)) {
+      if(SiS_ReadDDC(SiS_Pr, DDCdatatype, buffer)) {
          xf86DrvMsg(pSiS->pScrn->scrnIndex, X_INFO, 
 	 	"CRT2: DDC read failed (attempt %d), %s\n", 
 		(3-retry), (retry == 1) ? "giving up" : "retrying");
@@ -10435,6 +10744,8 @@
 	  	"CRT2: Attached display expects digital input\n");
       	  return 0;  	
       }
+      SiS_Pr->CP_Vendor = buffer[9] | (buffer[8] << 8);
+      SiS_Pr->CP_Product = buffer[10] | (buffer[11] << 8);
       foundcrt = TRUE;
       break;
    case 3:
@@ -10443,311 +10754,104 @@
           ((buffer[0x41] & 0x0f) != 0x02) &&
 	  ((buffer[0x41] & 0xf0) != 0x10) &&
 	  ((buffer[0x41] & 0xf0) != 0x20) ) {
-	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
-	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
-		buffer[0x41]);
-	  return 0;
-      }
-      foundcrt = TRUE;
-      break;	  
-   }
-   
-   if(foundcrt) {
-       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
-   }
-   return(0);
-}
-
-#if 0
-   /* ----- */
-USHORT
-SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS)
-{
-   USHORT DDCdatatype, paneltype, flag;
-   unsigned char cr36=0, cr37=0;
-   unsigned char tempal, tempah, tempbl, tempbh;
-   USHORT tempax, tempbx, tempcx, push1, push2, push3;
-   unsigned char addresstable[] = { 0x00, 0x22, 0x30, 0x40 };
-   int i;
-   unsigned char buffer[256];
-   
-   if(pSiS->VGAEngine != SIS_315_VGA) return 0xFFFF;
-   if(!(pSiS->VBFlags & (VB_301B|VB_302B))) return 0xFFFF;
-   
-   if(SiS_InitDDCRegs(SiS_Pr, pSiS, 1, 0, FALSE) == 0xFFFF) return 0xFFFF;   
-   
-   flag = SiS_ProbeDDC(SiS_Pr);
-   if(flag & 0x02) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;	/* EDID V1 */
-      DDCdatatype = 1;
-      SiS_Pr->SiS_DDC_SecAddr = 0x3a;
-   } else if(flag & 0x08) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa2;	/* EDID V2 (P&D-D Monitor) */
-      DDCdatatype = 3;
-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
-   } else if(flag & 0x10) {
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa6;	/* EDID V2 (FP) */
-      DDCdatatype = 4;
-      SiS_Pr->SiS_DDC_SecAddr = 0x76;
-   } else return 0xFFFF;
-   
-   
-   SiS_ReadLCDDDC(SiS_Pr, 4, buffer);
-   tempbl = buffer[0];  /* 3a - 76 */
-   tempbh = buffer[1];  /* 3b - 77 */
-   
-   if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
-   
-      /* Read and analyze EDID V1 (res) */
-   
-      tempah = 0x02;				/* 1024x768 by default */
-      tempbl &= 0xf0;
-      if(tempbl != 0x40) {			
-         tempah = 0x03;				/* 1280x1024 by default */
-	 if(tempbl == 0x50) {
-	    if(!tempbh) {
-	       tempbh = buffer[3] & 0xf0;
-	       if(tempbh == 0x30) {
-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-		   tempbl = buffer[0];  /* 0x23 */
-		   tempbh = buffer[1];  /* 0x24 */
-		   if(tempbl) cr37 |= 0x10;
-		   tempah = 0x0a;		/* 1280x768 */
-	       }
-	       if(tempbh == 0x40) {
-	           SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      		   SiS_Pr->SiS_DDC_SecAddr = 0x23;
-		   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-		   tempbl = buffer[0];  /* 0x23 */
-		   tempbh = buffer[1];  /* 0x24 */
-		   if(tempbl) cr37 |= 0x10;
-		   tempah = 0x03;		/* 1280x1024 */
-	       }
-	       tempbh = 0x00;
-	    }
-	 }
-	 if(tempbh == 0x00) goto cr36ready;
-	 tempah = 0x07;				/* 1280x960 */
-	 if(tempbh == 0xc0) goto cr36ready;
-      }
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      SiS_Pr->SiS_DDC_SecAddr = 0x18;		/* feature support */
-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-      tempbl = buffer[0];
-      tempbh = buffer[1];
-      if(tempbl & 0x02) goto cr36ready;
-      SiS_Pr->SiS_DDC_DeviceAddr = 0xa0;
-      SiS_Pr->SiS_DDC_SecAddr = 0x23;		/* Established Timings */
-      SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-      tempbl = buffer[0];
-      tempbh = buffer[1];
-      tempah = 0x03;
-      if(!(tempbh & 0x01)) tempah = 0x02;
-      if(!tempbl) cr37 |= 0x10;
-      
-  } else {
-  
-      /* Read and analyze EDID V2 (res) */
-      
-      tempah = 0x02;
-      tempbx = tempbl | (tempbh << 8);
-      if(tempbx != 1024) tempah = 0x03;
-      
-  }     
-
-cr36ready:
-  cr36 = tempah;      
-  
-  if(SiS_Pr->SiS_DDC_DeviceAddr == 0xa0) {
-  
-     /* Read and analyze EDID V1 (pol) */
-  
-     SiS_Pr->SiS_DDC_SecAddr = 0x47;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempah = buffer[0];
-     tempah &= 0x06;
-     tempah ^= 0x06;
-     tempah <<= 5;
-     tempah |= 0x20;
-     cr37 &= 0x1f;
-     cr37 |= tempah;
-     if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
-     
-  } else {
-  
-     /* Read and analyze EDID V2 (depth, pol) */
-  
-     push1 = tempah;
-     SiS_Pr->SiS_DDC_SecAddr = 0x45;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempah = 0x01;
-     if((buffer[0] != 0x20) && (buffer[0] != 0x34)) {   /* RGB18 or 24? */
-        tempah = 0x00;
-     }
-     cr37 &= 0xfe;
-     cr37 |= tempah;
-     
-     SiS_Pr->SiS_DDC_SecAddr = 0x7e;
-     SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-     tempax = (USHORT)(buffer[0] | (buffer[1] << 8));
-     push2 = tempax;
-     tempax &= 0x0003;
-     tempax *= 0x1b;
-     push3 = tempax;
-     tempax = (USHORT)buffer[0];
-     tempax &= 0x001c;
-     tempax >>= 2;
-     tempax *= 8;
-     tempbx = push3;
-     tempbx += tempax;
-     if(buffer[0] & 0x20) {		/* Luminance table provided? */
-        SiS_Pr->SiS_DDC_SecAddr = 0x80;
-	SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-	tempax = buffer[0] | (buffer[1] << 8);
-	tempax &= 0x1f;
-	if(buffer[0] & 0x70) tempax <<= 1;
-	tempax++;	
-	tempbx += tempax;        	/* yes -> skip it */
-     }
-     tempcx = push2;
-     tempax = push1 << 8;
-     tempbx = (tempbx & 0xff00) | (((tempbx & 0x00ff) + 0x80) & 0x00ff);
-     if(tempcx & 0xf800) {
-        tempal = addresstable[((tempax & 0xff00) >> 8)];
-	tempcx &= 0xf8ff;
-	tempcx >>= 11;
-	for(i=0; i<tempcx; i++) {
-	   SiS_Pr->SiS_DDC_SecAddr = (tempbx & 0x00ff);
-	   SiS_ReadLCDDDC(SiS_Pr, 2, buffer);
-	   tempbx += 0x04;
-	   if(buffer[0] == tempal) break;
-	}
-	tempah = buffer[1];
-	tempah &= 0x0c;
-	tempah ^= 0x0c;
-	tempah <<= 4;
-	tempah |= 0x20;
-        cr37 &= 0x1f;
-        cr37 |= tempah;
-	if((cr36 & 0x07) == 0x07) cr37 &= 0x0e;
-     }
-  }
-  xf86DrvMsg(0, X_INFO, "DDC: cr36 = 0x%02x, cr37 = 0x%02x\n", cr36, cr37);
-  return 0;
-}
-#endif
-
-/* TW: Generic I2C functions (compliant to i2c library) */
-
-#if 0
-USHORT
-SiS_I2C_GetByte(SiS_Private *SiS_Pr)
-{
-   return(SiS_ReadDDC2Data(SiS_Pr,0));
-}
-
-Bool
-SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data)
-{
-   if(SiS_WriteDDC2Data(SiS_Pr,data)) return FALSE;
-   return TRUE;
-}
-
-Bool
-SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr)
-{
-   if(SiS_SetStart(SiS_Pr)) return FALSE;
-   if(SiS_WriteDDC2Data(SiS_Pr,addr)) return FALSE;
-   return TRUE;
-}
+	  xf86DrvMsg(pSiS->pScrn->scrnIndex, X_PROBED,
+	     	"CRT2: Attached display does not support analog input (0x%02x)\n",
+		buffer[0x41]);
+	  return 0;
+      }
+      SiS_Pr->CP_Vendor = buffer[2] | (buffer[1] << 8);
+      SiS_Pr->CP_Product = buffer[3] | (buffer[4] << 8);
+      foundcrt = TRUE;
+      break;
+   }
 
-void
-SiS_I2C_Stop(SiS_Private *SiS_Pr)
-{
-   SiS_SetStop(SiS_Pr);
+   if(foundcrt) {
+       SiS_SetRegOR(SiS_Pr->SiS_P3d4,0x32,0x10);
+   }
+   return(0);
 }
-#endif
 
 #endif
 
 void
 SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh)
 {
-  USHORT tempal,tempah,tempbl;
+  USHORT tempbl;
 
-  tempal = tempax & 0x00FF;
-  tempah =(tempax >> 8) & 0x00FF;
-  tempbl = SiS_GetCH70xx(SiS_Pr,tempal);
-  tempbl = (((tempbl & tempbh) | tempah) << 8 | tempal);
+  tempbl = SiS_GetCH70xx(SiS_Pr,(tempax & 0x00FF));
+  tempbl = (((tempbl & tempbh) << 8) | tempax);
   SiS_SetCH70xx(SiS_Pr,tempbl);
 }
 
-/* TW: Generic I2C functions for Chrontel --------- */
+/* Generic I2C functions for Chrontel & DDC --------- */
 
 void
 SiS_SetSwitchDDC2(SiS_Private *SiS_Pr)
 {
   SiS_SetSCLKHigh(SiS_Pr);
-  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
-  SiS_WaitRetraceDDC(SiS_Pr);
+  SiS_WaitRetrace1(SiS_Pr);
 
   SiS_SetSCLKLow(SiS_Pr);
-  /* SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAY); */
-  SiS_WaitRetraceDDC(SiS_Pr);
+  SiS_WaitRetrace1(SiS_Pr);
+}
+
+USHORT
+SiS_ReadDDC1Bit(SiS_Private *SiS_Pr)
+{
+   SiS_WaitRetrace1(SiS_Pr);
+   return((SiS_GetReg(SiS_Pr->SiS_P3c4,0x11) & 0x02) >> 1);
 }
 
-/* TW: Set I2C start condition */
-/* TW: This is done by a SD high-to-low transition while SC is high */
+/* Set I2C start condition */
+/* This is done by a SD high-to-low transition while SC is high */
 USHORT
 SiS_SetStart(SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low)  */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low)  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* TW: SD->high */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);             /* SD->high */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* TW: SD->low = start condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
+                  ~SiS_Pr->SiS_DDC_Data,0x00);                             /* SD->low = start condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
   return 0;
 }
 
-/* TW: Set I2C stop condition */
-/* TW: This is done by a SD low-to-high transition while SC is high */
+/* Set I2C stop condition */
+/* This is done by a SD low-to-high transition while SC is high */
 USHORT
 SiS_SetStop(SiS_Private *SiS_Pr)
 {
-  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->low) */
+  if(SiS_SetSCLKLow(SiS_Pr)) return 0xFFFF;			           /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* TW: SD->low   */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: SC->high  */
+                  ~SiS_Pr->SiS_DDC_Data,0x00);          		   /* SD->low   */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* SC->high  */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* TW: SD->high = stop condition */
-  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* TW: (SC->high) */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);  	   /* SD->high = stop condition */
+  if(SiS_SetSCLKHigh(SiS_Pr)) return 0xFFFF;			           /* (SC->high) */
   return 0;
 }
 
-/* TW: Write 8 bits of data */
+/* Write 8 bits of data */
 USHORT
 SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax)
 {
   USHORT i,flag,temp;
 
-  flag=0x80;
-  for(i=0;i<8;i++) {
-    SiS_SetSCLKLow(SiS_Pr);				                      /* TW: SC->low */
+  flag = 0x80;
+  for(i=0; i<8; i++) {
+    SiS_SetSCLKLow(SiS_Pr);				                      /* SC->low */
     if(tempax & flag) {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* TW: Write bit (1) to SD */
+                      ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);            /* Write bit (1) to SD */
     } else {
       SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* TW: Write bit (0) to SD */
+                      ~SiS_Pr->SiS_DDC_Data,0x00);                            /* Write bit (0) to SD */
     }
-    SiS_SetSCLKHigh(SiS_Pr);				                      /* TW: SC->high */
+    SiS_SetSCLKHigh(SiS_Pr);				                      /* SC->high */
     flag >>= 1;
   }
-  temp = SiS_CheckACK(SiS_Pr);				                      /* TW: Check acknowledge */
+  temp = SiS_CheckACK(SiS_Pr);				                      /* Check acknowledge */
   return(temp);
 }
 
@@ -10763,7 +10867,7 @@
     SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
                     ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);
     SiS_SetSCLKHigh(SiS_Pr);
-    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
     if(temp & SiS_Pr->SiS_DDC_Data) getdata |= 0x01;
   }
   return(getdata);
@@ -10781,68 +10885,59 @@
 USHORT
 SiS_SetSCLKHigh(SiS_Private *SiS_Pr)
 {
-  USHORT temp,watchdog=1000;
+  USHORT temp, watchdog=1000;
 
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
                   ~SiS_Pr->SiS_DDC_Clk,SiS_Pr->SiS_DDC_Clk);  	/* SetSCLKHigh()  */
   do {
-    temp = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
+    temp = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);
   } while((!(temp & SiS_Pr->SiS_DDC_Clk)) && --watchdog);
   if (!watchdog) {
 #ifdef TWDEBUG
         xf86DrvMsg(0, X_INFO, "SetClkHigh failed\n");
-#endif	   
+#endif
   	return 0xFFFF;
   }
   SiS_DDC2Delay(SiS_Pr,SiS_I2CDELAYSHORT);
   return 0;
 }
 
-void
-SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime)
-{
-  USHORT i;
-
-  for(i=0; i<delaytime; i++) {
-    SiS_GetReg1(SiS_Pr->SiS_P3c4,0x05);
-  }
-}
-
-/* TW: Check I2C acknowledge */
+/* Check I2C acknowledge */
 /* Returns 0 if ack ok, non-0 if ack not ok */
 USHORT
 SiS_CheckACK(SiS_Private *SiS_Pr)
 {
   USHORT tempah;
 
-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: (SC->low) */
+  SiS_SetSCLKLow(SiS_Pr);				           /* (SC->low) */
   SiS_SetRegANDOR(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index,
-                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* TW: (SD->high) */
-  SiS_SetSCLKHigh(SiS_Pr);				           /* TW: SC->high = clock impulse for ack */
-  tempah = SiS_GetReg1(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* TW: Read SD */
-  SiS_SetSCLKLow(SiS_Pr);				           /* TW: SC->low = end of clock impulse */
-  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* TW: Ack OK if bit = 0 */
+                  ~SiS_Pr->SiS_DDC_Data,SiS_Pr->SiS_DDC_Data);     /* (SD->high) */
+  SiS_SetSCLKHigh(SiS_Pr);				           /* SC->high = clock impulse for ack */
+  tempah = SiS_GetReg(SiS_Pr->SiS_DDC_Port,SiS_Pr->SiS_DDC_Index);/* Read SD */
+  SiS_SetSCLKLow(SiS_Pr);				           /* SC->low = end of clock impulse */
+  if(tempah & SiS_Pr->SiS_DDC_Data) return(1);			   /* Ack OK if bit = 0 */
   else return(0);
 }
 
-/* TW: End of I2C functions ----------------------- */
+/* End of I2C functions ----------------------- */
 
 
-/* =============== SiS 310/325/330 O.E.M. ================= */
+/* =============== SiS 315/330 O.E.M. ================= */
 
 #ifdef SIS315H
 
 static USHORT
-GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+GetRAMDACromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT romptr;
 
-  if(HwDeviceExtension->jChipType < SIS_330) {
-     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);  
+  if(HwInfo->jChipType < SIS_330) {
+     romptr = ROMAddr[0x128] | (ROMAddr[0x129] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
         romptr = ROMAddr[0x12a] | (ROMAddr[0x12b] << 8);
   } else {
-     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);  
+     romptr = ROMAddr[0x1a8] | (ROMAddr[0x1a9] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301B302B)
         romptr = ROMAddr[0x1aa] | (ROMAddr[0x1ab] << 8);
   }
@@ -10850,16 +10945,17 @@
 }
 
 static USHORT
-GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+GetLCDromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT romptr;
 
-  if(HwDeviceExtension->jChipType < SIS_330) {
-     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);  
+  if(HwInfo->jChipType < SIS_330) {
+     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
   } else {
-     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);  
+     romptr = ROMAddr[0x1a0] | (ROMAddr[0x1a1] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x1a2] | (ROMAddr[0x1a3] << 8);
   }
@@ -10867,11 +10963,12 @@
 }
 
 static USHORT
-GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr)
+GetTVromptr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT romptr;
 
-  if(HwDeviceExtension->jChipType < SIS_330) {
+  if(HwInfo->jChipType < SIS_330) {
      romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)
         romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
@@ -10884,10 +10981,22 @@
 }
 
 static USHORT
-GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr)
+GetLCDPtrIndexBIOS(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
   USHORT index;
-  
+
+  if((IS_SIS650) && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+     if(!(SiS_IsNotM650or651(SiS_Pr, HwInfo))) {
+        if((index = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0)) {
+	   index >>= 4;
+	   index *= 3;
+	   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
+           else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
+           return index;
+	}
+     }
+  }
+
   index = SiS_Pr->SiS_LCDResInfo & 0x0F;
   if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050)      index -= 5;
   else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1600x1200) index -= 6;
@@ -10895,7 +11004,6 @@
   index *= 3;
   if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) index += 2;
   else if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) index++;
-
   return index;
 }
 
@@ -10913,17 +11021,7 @@
   return index;
 }
 
-/*
----------------------------------------------------------
-       GetTVPtrIndex()
-          return       0 : NTSC Enhanced/Standard
-                       1 : NTSC Standard TVSimuMode
-                       2 : PAL Enhanced/Standard
-                       3 : PAL Standard TVSimuMode
-                       4 : HiVision Enhanced/Standard
-                       5 : HiVision Standard TVSimuMode
----------------------------------------------------------
-*/
+
 static USHORT
 GetTVPtrIndex(SiS_Private *SiS_Pr)
 {
@@ -10942,15 +11040,18 @@
 }
 
 static void
-SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             UCHAR *ROMAddr, USHORT ModeNo)
+SetDelayComp(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo)
 {
-  USHORT delay,index,myindex,temp,romptr=0;
-  
-  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* VGA */
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
+  USHORT delay=0,index,myindex,temp,romptr=0;
+  BOOLEAN dochiptest = TRUE;
+
+  /* Find delay (from ROM, internal tables, PCI subsystem) */
+
+  if(SiS_Pr->SiS_VBInfo & SetCRT2ToRAMDAC) {			/* ------------ VGA */
      
      if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-        romptr = GetRAMDACromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+        romptr = GetRAMDACromptr(SiS_Pr, HwInfo);
 	if(!romptr) return;
 	delay = ROMAddr[romptr];
      } else {
@@ -10960,7 +11061,7 @@
 	      delay = 0x0a;
 	   } else if(IS_SIS740) {
 	      delay = 0x00;
-	   } else if(HwDeviceExtension->jChipType < SIS_330) {
+	   } else if(HwInfo->jChipType < SIS_330) {
 	      delay = 0x0c;
 	   } else {
 	      delay = 0x0c;
@@ -10969,112 +11070,215 @@
         if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
            delay = 0x00;
      }
-  
-  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {		/* LCD */
-  
-     index = GetLCDPtrIndexBIOS(SiS_Pr);
-     myindex = GetLCDPtrIndex(SiS_Pr);
-     
-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) { 	/* 650+30xLV */
-       if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-#if 0	     /* Always use the second pointer on 650; some BIOSes */
-             /* still carry old 301 data at the first location    */  
-	     romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8); 
-	     if(SiS_Pr->SiS_VBType & VB_SIS302LV) 
-#endif		
-	        romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
-	     if(!romptr) return;
-	     delay = ROMAddr[(romptr + index)];
-	  } else {
-             delay = SiS310_LCDDelayCompensation_650301B[myindex];   
-#if 0	     
+
+  } else if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD|SetCRT2ToLCDA)) {  /* ----------	LCD/LCDA */
+
+     BOOLEAN gotitfrompci = FALSE;
+
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+
+     /* Could we detect a PDC for LCD? If yes, use it */
+
+     if(HwInfo->pdc) {
+        if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	   SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2d,0x0f,((HwInfo->pdc & 0x0f) << 4));
+	}
+        return;
+     }
+
+     /* This is a piece of typical SiS crap: They code the OEM LCD
+      * delay into the code, at none defined place in the BIOS.
+      * We now have to start doing a PCI subsystem check here.
+      */
+
+     switch(SiS_Pr->SiS_CustomT) {
+     case CUT_COMPAQ1280:
+     case CUT_COMPAQ12802:
+	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+	   gotitfrompci = TRUE;
+	   dochiptest = FALSE;
+	   delay = 0x03;
+	}
+	break;
+     case CUT_CLEVO1400:
+     case CUT_CLEVO14002:
+	/* if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) { */
+	   gotitfrompci = TRUE;
+	   dochiptest = FALSE;
+	   delay = 0x02;
+	/* } */
+	break;
+     case CUT_CLEVO1024:
+     case CUT_CLEVO10242:
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	   gotitfrompci = TRUE;
+	   dochiptest = FALSE;
+	   delay = 0x33;
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
+	   delay &= 0x0f;
+	}
+	break;
+     }
+
+     /* Could we find it through the PCI ID? If no, use ROM or table */
+
+     if(!gotitfrompci) {
+
+        index = GetLCDPtrIndexBIOS(SiS_Pr, HwInfo);
+        myindex = GetLCDPtrIndex(SiS_Pr);
+
+        if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
+
+           if(SiS_IsNotM650or651(SiS_Pr, HwInfo)) {
+
+              if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+#if 0	         /* Always use the second pointer on 650; some BIOSes */
+                 /* still carry old 301 data at the first location    */
+	         romptr = ROMAddr[0x120] | (ROMAddr[0x121] << 8);
+	         if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+#endif
+	            romptr = ROMAddr[0x122] | (ROMAddr[0x123] << 8);
+	         if(!romptr) return;
+	         delay = ROMAddr[(romptr + index)];
+	      } else {
+                 delay = SiS310_LCDDelayCompensation_650301B[myindex];
+#if 0
+	         if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	            delay = SiS310_LCDDelayCompensation_650301B[myindex];
+#endif
+	      }
+
+          } else {
+
+             delay = SiS310_LCDDelayCompensation_651301LV[myindex];
 	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-	        delay = SiS310_LCDDelayCompensation_650301B[myindex];
-#endif		
-	  }
-       } else {
-          delay = SiS310_LCDDelayCompensation_651301LV[myindex];     
-	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-	     delay = SiS310_LCDDelayCompensation_651302LV[myindex];  
-       }
-     } else {
-        if((ROMAddr) && SiS_Pr->SiS_UseROM && 				/* 315, 330, 740, 650+301B */
-	   (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) { 
-           romptr = GetLCDromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
+	        delay = SiS310_LCDDelayCompensation_651302LV[myindex];
+
+          }
+
+        } else if((ROMAddr) && SiS_Pr->SiS_UseROM &&
+	          (SiS_Pr->SiS_LCDResInfo != SiS_Pr->SiS_Panel1280x1024)) {
+
+           romptr = GetLCDromptr(SiS_Pr, HwInfo);
 	   if(!romptr) return;
 	   delay = ROMAddr[(romptr + index)];
-        } else {
+
+        } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+
+	   if(IS_SIS650) {
+              delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
+	   } else {
+	      delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
+	   }
+
+	} else {
+
            delay = SiS310_LCDDelayCompensation_301[myindex];
            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-#if 0 	      /* This data is (like the one in the BIOS) wrong. */	   
-	      if(IS_SIS650740) {  /* V */
+#if 0 	      /* This data is (like the one in the BIOS) wrong. */
+	      if(IS_SIS550650740660) {
 	         delay = SiS310_LCDDelayCompensation_650301B[myindex];
 	      } else {
-#endif	      
+#endif
                  delay = SiS310_LCDDelayCompensation_3xx301B[myindex];
-#if 0		 
-	      }
-#endif	      
-	   }
-           if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-	      if(IS_SIS650) {
-                 delay = SiS310_LCDDelayCompensation_LVDS650[myindex];
-	      } else {
-	         delay = SiS310_LCDDelayCompensation_LVDS740[myindex];
+#if 0
 	      }
+#endif
 	   }
+
         }
+
+     }  /* got it from PCI */
+
+     if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0x0F,((delay << 4) & 0xf0));
+	dochiptest = FALSE;
      }
      
-  } else {							/* TV */
-  
+  } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {			/* ------------ TV */
+
      index = GetTVPtrIndex(SiS_Pr);
      
      if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-       if(SiS_IsNotM650or651(SiS_Pr,HwDeviceExtension, BaseAddr)) {
-          if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-#if 0	     /* Always use the second pointer on 650; some BIOSes */
-             /* still carry old 301 data at the first location    */  	  
-             romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
-	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-#endif	     
-	        romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
-	     if(!romptr) return;
-	     delay = ROMAddr[romptr + index];
-	  } else {
-	     delay = SiS310_TVDelayCompensation_301B[index];     
-#if 0	     
-	     if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-	        delay = SiS310_TVDelayCompensation_301B[index];  
+
+        if(SiS_IsNotM650or651(SiS_Pr,HwInfo)) {
+
+           if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+#if 0	      /* Always use the second pointer on 650; some BIOSes */
+              /* still carry old 301 data at the first location    */
+              romptr = ROMAddr[0x114] | (ROMAddr[0x115] << 8);
+	      if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+#endif
+	         romptr = ROMAddr[0x11a] | (ROMAddr[0x11b] << 8);
+	      if(!romptr) return;
+	      delay = ROMAddr[romptr + index];
+
+	   } else {
+
+	      delay = SiS310_TVDelayCompensation_301B[index];
+#if 0
+	      if(SiS_Pr->SiS_VBType & VB_SIS302LV)
+	         delay = SiS310_TVDelayCompensation_301B[index];
 #endif		
-	  }
-       } else {
-          delay = SiS310_TVDelayCompensation_651301LV[index];       
-	  if(SiS_Pr->SiS_VBType & VB_SIS302LV)
-	      delay = SiS310_TVDelayCompensation_651302LV[index];   
-       }
+	   }
+
+        } else {
+
+           switch(SiS_Pr->SiS_CustomT) {
+	   case CUT_COMPAQ1280:
+	   case CUT_COMPAQ12802:
+	   case CUT_CLEVO1400:
+	   case CUT_CLEVO14002:
+	      delay = 0x02;
+	      dochiptest = FALSE;
+	      break;
+	   case CUT_CLEVO1024:
+	   case CUT_CLEVO10242:
+	      delay = 0x03;
+	      dochiptest = FALSE;
+   	      break;
+	   default:
+              delay = SiS310_TVDelayCompensation_651301LV[index];
+	      if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	         delay = SiS310_TVDelayCompensation_651302LV[index];
+	      }
+	   }
+        }
+
+     } else if((ROMAddr) && SiS_Pr->SiS_UseROM) {
+
+        romptr = GetTVromptr(SiS_Pr, HwInfo);
+	if(!romptr) return;
+	delay = ROMAddr[romptr + index];
+
+     } else if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+
+        delay = SiS310_TVDelayCompensation_LVDS[index];
+
      } else {
-       if((ROMAddr) && SiS_Pr->SiS_UseROM) {
-          romptr = GetTVromptr(SiS_Pr, HwDeviceExtension, ROMAddr);
-	  if(!romptr) return;
-	  delay = ROMAddr[romptr + index];
-       } else {
-	    delay = SiS310_TVDelayCompensation_301[index];
-            if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
-	       if(IS_SIS740) 
-	          delay = SiS310_TVDelayCompensation_740301B[index];
-	       else 
-                  delay = SiS310_TVDelayCompensation_301B[index];
-	    }
-            if(SiS_Pr->SiS_IF_DEF_LVDS == 1)
-               delay = SiS310_TVDelayCompensation_LVDS[index];
-       }
+
+	delay = SiS310_TVDelayCompensation_301[index];
+        if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
+	   if(IS_SIS740) {
+	      delay = SiS310_TVDelayCompensation_740301B[index];
+	   } else {
+              delay = SiS310_TVDelayCompensation_301B[index];
+	   }
+	}
+
+     }
+
+     if(SiS_GetReg(SiS_Pr->SiS_Part1Port,0x13) & 0x04) {  /* LCDA */
+	delay &= 0x0f;
+	dochiptest = FALSE;
      }
     
-  }
+  } else return;
+
+  /* Write delay */
 
   if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
+
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
      } else {
@@ -11085,27 +11289,36 @@
            SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
         }
      }
+
   } else {
-     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) {
-        temp = (SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
-        if(temp == 8) {
+
+     if(IS_SIS650 && (SiS_Pr->SiS_VBType & VB_SIS301LV302LV) && dochiptest) {
+
+        temp = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0xf0) >> 4;
+        if(temp == 8) {		/* 1400x1050 BIOS (ECS) */
 	   delay &= 0x0f;
 	   delay |= 0xb0;
         } else if(temp == 6) {
            delay &= 0x0f;
 	   delay |= 0xc0;
+        } else if(temp > 7) {	/* 1280x1024 BIOS (which one?) */
+	   delay = 0x35;
         }
-        SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x2D,delay);  /* index 2D D[3:0] */
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x2D,delay);
+
      } else {
+
         SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x2D,0xF0,delay);
+
      }
   }
 }
 
 static void
-SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+               USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
   temp = GetTVPtrIndex(SiS_Pr);
@@ -11118,7 +11331,7 @@
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x112] | (ROMAddr[0x113] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwInfo->jChipType >= SIS_330) {
         romptr = ROMAddr[0x192] | (ROMAddr[0x193] << 8);
      }
   }
@@ -11135,9 +11348,10 @@
 }
 
 static void
-SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetEdgeEnhance(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+               USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
   temp = GetTVPtrIndex(SiS_Pr);
@@ -11150,7 +11364,7 @@
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x124] | (ROMAddr[0x125] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwInfo->jChipType >= SIS_330) {
         romptr = ROMAddr[0x1a4] | (ROMAddr[0x1a5] << 8);
      }
   }
@@ -11166,9 +11380,10 @@
 }
 
 static void
-SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-           UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+           USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index, temp, i, j;
   UCHAR  OutputSelect = *SiS_Pr->pSiS_OutputSelect;
 
@@ -11185,52 +11400,53 @@
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
     for(i=0x35, j=0; i<=0x38; i++, j++) {
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
     }
     for(i=0x48; i<=0x4A; i++, j++) {
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter2[temp][index][j]);
     }
   } else {
     for(i=0x35, j=0; i<=0x38; i++, j++){
-       SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
+       SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVYFilter1[temp][index][j]);
     }
   }
 
   if(ROMAddr && SiS_Pr->SiS_UseROM) {
   	OutputSelect = ROMAddr[0xf3];
-	if(HwDeviceExtension->jChipType == SIS_330) {
+	if(HwInfo->jChipType >= SIS_330) {
 	    OutputSelect = ROMAddr[0x11b];
 	}
   }
   if(OutputSelect & EnablePALMN) {
-      if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-         temp = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);
+      if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+         temp = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);
          temp &= (EnablePALM | EnablePALN);
          if(temp == EnablePALM) {
               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
                  }
                  for(i=0x48; i<=0x4A; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter2[index][j]);
                  }
               } else {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALMFilter[index][j]);
                  }
               }
          }
+	 /* PALN : Is this data correct? */
          if(temp == EnablePALN) {
               if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
                  }
                  for(i=0x48, j=0; i<=0x4A; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter2[index][j]);
                  }
              } else {
                  for(i=0x35, j=0; i<=0x38; i++, j++) {
-                      SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
+                      SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_PALNFilter[index][j]);
 		 }
              }
          }
@@ -11239,21 +11455,22 @@
 }
 
 static void
-SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-             UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+             USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,temp1,i,j,resinfo,romptr=0;
 
   if(!(SiS_Pr->SiS_VBInfo & SetCRT2ToTV)) return;
 
-  temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
-  temp1 &=  (EnablePALM | EnablePALN);
+  temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x38);        /* if PALM/N not set */
+  temp1 &= (EnablePALM | EnablePALN);
   if(temp1) return;
 
-  if (ModeNo<=0x13) {
-    resinfo =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+  if(ModeNo<=0x13) {
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
   } else {
-    resinfo =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
   }
 
   temp = GetTVPtrIndex(SiS_Pr);
@@ -11262,17 +11479,17 @@
    */
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
-     if(HwDeviceExtension->jChipType == SIS_330) {
+     if(HwInfo->jChipType >= SIS_330) {
         romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
      }
      if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
         romptr = ROMAddr[0x11c] | (ROMAddr[0x11d] << 8);
-	if(HwDeviceExtension->jChipType == SIS_330) {
+	if(HwInfo->jChipType >= SIS_330) {
 	   romptr = ROMAddr[0x19c] | (ROMAddr[0x19d] << 8);
 	}
 	if((SiS_Pr->SiS_VBInfo & SetInSlaveMode) && (!(SiS_Pr->SiS_SetFlag & TVSimuMode))) {
 	   romptr = ROMAddr[0x116] | (ROMAddr[0x117] << 8);
-	   if(HwDeviceExtension->jChipType == SIS_330) {
+	   if(HwInfo->jChipType >= SIS_330) {
               romptr = ROMAddr[0x196] | (ROMAddr[0x197] << 8);
            }
 	}
@@ -11281,267 +11498,320 @@
   if(romptr) {
      romptr += (temp << 2);
      for(j=0, i=0x31; i<=0x34; i++, j++) {
-        SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+        SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
      }
   } else {
      index = temp % 2;
      temp >>= 1;          /* 0:NTSC, 1:PAL, 2:HiTV */
      for(j=0, i=0x31; i<=0x34; i++, j++) {
         if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV))
-	   SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+	   SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
         else if((!(SiS_Pr->SiS_VBInfo & SetInSlaveMode)) || (SiS_Pr->SiS_SetFlag & TVSimuMode))
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr2[temp][index][j]);
         else
-           SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
+           SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS310_TVPhaseIncr1[temp][index][j]);
      }
   }
 
-  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* TW: 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
+  if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {    /* 650/301LV: (VB_SIS301LV | VB_SIS302LV)) */
      if((!(SiS_Pr->SiS_VBInfo & SetPALTV)) && (ModeNo > 0x13)) {
-        if(resinfo == 6) {
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
-	} else if (resinfo == 7) {
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x21);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0xf0);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xf5);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7f);
-	} else if (resinfo == 8) {
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x31,0x1e);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x32,0x8b);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x33,0xfb);
-	      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x34,0x7b);
+        if(resinfo == SIS_RI_640x480) {
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+	} else if (resinfo == SIS_RI_800x600) {
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x21);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0xf0);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xf5);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7f);
+	} else if (resinfo == SIS_RI_1024x768) {
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x31,0x1e);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x32,0x8b);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x33,0xfb);
+	      SiS_SetReg(SiS_Pr->SiS_Part2Port,0x34,0x7b);
 	}
      }
   }
 }
 
 void
-SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT ModeNo,USHORT ModeIdIndex)
 {
-   SetDelayComp(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo);
-   /* TW: The TV functions are not for LVDS */
+   SetDelayComp(SiS_Pr,HwInfo,ModeNo);
+
+   if(SiS_Pr->UseCustomMode) return;
+
    if( (SiS_Pr->SiS_IF_DEF_LVDS == 0) && (SiS_Pr->SiS_VBInfo & SetCRT2ToTV) ) {
-       SetAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       SetPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       SetYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetAntiFlicker(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+       SetPhaseIncr(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
+       SetYFilter(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
        if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) {
-          SetEdgeEnhance(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+          SetEdgeEnhance(SiS_Pr,HwInfo,ModeNo,ModeIdIndex);
        }
    }
 }
 
 /* FinalizeLCD
- * This finalizes some Part1 registers for the very panel used.
+ * This finalizes some CRT2 registers for the very panel used.
  * If we have a backup if these registers, we use it; otherwise
  * we set the register according to most BIOSes. However, this
  * function looks quite different in every BIOS, so you better
  * pray that we have a backup...
  */
 void
-SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                USHORT ModeIdIndex, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                PSIS_HW_INFO HwInfo)
 {
   USHORT tempcl,tempch,tempbl,tempbh,tempbx,tempax,temp;
   USHORT resinfo,modeflag;
 
   if(!(SiS_Pr->SiS_VBType & VB_SIS301LV302LV)) return;
 
+  if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+     if(SiS_Pr->LVDSHL != -1) {
+        SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,SiS_Pr->LVDSHL);
+     }
+  }
+
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+  if(SiS_Pr->UseCustomMode) return;
+
+  switch(SiS_Pr->SiS_CustomT) {
+  case CUT_COMPAQ1280:
+  case CUT_COMPAQ12802:
+  case CUT_CLEVO1400:
+  case CUT_CLEVO14002:
+     return;
+  }
+
   if(ModeNo <= 0x13) {
-	resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
-	modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+     resinfo = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ResInfo;
+     modeflag =  SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
   } else {
-    	resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
-	modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+     resinfo = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_RESINFO;
+     modeflag =  SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+  }
+
+  if(IS_SIS650) {
+     if(!(SiS_GetReg(SiS_Pr->SiS_P3d4, 0x5f) & 0xf0)) {
+        if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+	   SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x02);
+	} else {
+           SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x1e,0x03);
+	}
+     }
+  }
+
+  if(SiS_Pr->SiS_CustomT == CUT_CLEVO1024) {
+     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+        /* Maybe all panels? */
+        if(SiS_Pr->LVDSHL == -1) {
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
+	}
+	return;
+     }
+  }
+
+  if(SiS_Pr->SiS_CustomT == CUT_CLEVO10242) {
+     if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
+        if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	   if(SiS_Pr->LVDSHL == -1) {
+	      /* Maybe all panels? */
+              SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
+	   }
+	   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
+	      tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
+	      if(tempch == 3) {
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
+	      }
+	   }
+	   return;
+	}
+     }
   }
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
      if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-        SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x2a,0x00);
-	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x30,0x00);
-	SiS_SetReg1(SiS_Pr->SiS_Part4Port,0x34,0x10);
-     }
-     tempch = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x36);
-     tempch &= 0xf0;
-     tempch >>= 4;
+#ifdef SET_EMI
+	if(SiS_Pr->SiS_VBType & VB_SIS302LV) {
+	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x2a,0x00);
+	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x30,0x00);
+	   SiS_SetReg(SiS_Pr->SiS_Part4Port,0x34,0x10);
+	}
+#endif
+     } else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1280x1024) {
+        if(SiS_Pr->LVDSHL == -1) {
+           /* Maybe ACER only? */
+           SiS_SetRegANDOR(SiS_Pr->SiS_Part4Port,0x24,0xfc,0x01);
+	}
+     }
+     tempch = SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) >> 4;
      if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	   SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1f,0x76);
-	}
-	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {	
+	   SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1f,0x76);
+	} else if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
+	   if(tempch == 0x03) {
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x25);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x00);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x1b);
+	   }
 	   if((SiS_Pr->Backup == TRUE) && (SiS_Pr->Backup_Mode == ModeNo)) {
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
-	      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
-	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* From 1.10.8w */
-	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x90);
-	       if(ModeNo <= 0x13) {
-	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x11);
-		  if((resinfo == 0) && (resinfo == 2)) return;
-		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x18);
-		  if((resinfo == 1) && (resinfo == 3)) return;
-	       }
-	       SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);
-	       if((ModeNo > 0x13) && (resinfo == 8)) {
-	          SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
-#if 0	       
-	          tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
-		  tempbx--;
-		  temp = tempbx & 0xff;
-		  SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,temp);
-		  temp = (tempbx >> 8) & 0x03;
-		  SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
-#endif		  
-	       }
-	   } else {
-	       if(ModeNo <= 0x13) {
-	          if(ModeNo <= 1) {
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x70);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xff);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
-		  }
-		  if(!(modeflag & HalfDCLK)) {
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,0x20);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x15,0x1a);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x16,0x28);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x17,0x00);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x4c);
-		     SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
-		     if(ModeNo == 0x12) {
-			 switch(tempch) {
-			 case 0:
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x19,0xdc);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1a,0x10);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1c,0x48);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1d,0x12);
-			    break;
-			 case 2:
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,0x95);
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x48);
-			    break;
-			 case 3:
-			    SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x1b,0x95);
-			    break;
-			 }
-		     }
-		  }
-	       }
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,SiS_Pr->Backup_14);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,SiS_Pr->Backup_15);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,SiS_Pr->Backup_16);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,SiS_Pr->Backup_17);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,SiS_Pr->Backup_18);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,SiS_Pr->Backup_19);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,SiS_Pr->Backup_1a);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,SiS_Pr->Backup_1b);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,SiS_Pr->Backup_1c);
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,SiS_Pr->Backup_1d);
+	   } else if(!(SiS_Pr->SiS_LCDInfo & DontExpandLCD)) {	/* 1.10.8w */
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x90);
+	      if(ModeNo <= 0x13) {
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x11);
+		 if((resinfo == 0) || (resinfo == 2)) return;
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x18);
+		 if((resinfo == 1) || (resinfo == 3)) return;
+	      }
+	      SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);
+	      if((ModeNo > 0x13) && (resinfo == SIS_RI_1024x768)) {
+	         SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x02);  /* 1.10.7u */
+#if 0
+	         tempbx = 806;  /* 0x326 */			 /* other older BIOSes */
+		 tempbx--;
+		 temp = tempbx & 0xff;
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,temp);
+		 temp = (tempbx >> 8) & 0x03;
+		 SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1d,0xf8,temp);
+#endif
+	      }
+	   } else if(ModeNo <= 0x13) {
+	      if(ModeNo <= 1) {
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x70);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xff);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+	      }
+	      if(!(modeflag & HalfDCLK)) {
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x14,0x20);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x15,0x1a);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x16,0x28);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x17,0x00);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x4c);
+		 SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+		 if(ModeNo == 0x12) {
+		    switch(tempch) {
+		       case 0:
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x19,0xdc);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1a,0x10);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1c,0x48);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1d,0x12);
+			  break;
+		       case 2:
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,0x95);
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x48);
+			  break;
+		       case 3:
+			  SiS_SetReg(SiS_Pr->SiS_Part1Port,0x1b,0x95);
+			  break;
+		    }
+		 }
+	      }
 	   }
 	}
      } else {
-        tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
+        tempcl = tempbh = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x01);
 	tempcl &= 0x0f;
 	tempbh &= 0x70;
 	tempbh >>= 4;
-	tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
+	tempbl = SiS_GetReg(SiS_Pr->SiS_Part2Port,0x04);
 	tempbx = (tempbh << 8) | tempbl;
 	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
-	   if((resinfo == 8) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
+	   if((resinfo == SIS_RI_1024x768) || (!(SiS_Pr->SiS_LCDInfo & DontExpandLCD))) {
 	      if(SiS_Pr->SiS_SetFlag & LCDVESATiming) {
-	      	tempbx = 770;
+	      	 tempbx = 770;
 	      } else {
-	        if(tempbx > 770) tempbx = 770;
-		if(SiS_Pr->SiS_VGAVDE < 600) {
-		   tempax = 768 - SiS_Pr->SiS_VGAVDE;
-		   tempax >>= 4;  				/* From 1.10.7w; 1.10.6s: 3;  */
-		   if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* From 1.10.7w; 1.10.6s: < 480; >>=1; */
-		   tempbx -= tempax;
-		}
+	         if(tempbx > 770) tempbx = 770;
+		 if(SiS_Pr->SiS_VGAVDE < 600) {
+		    tempax = 768 - SiS_Pr->SiS_VGAVDE;
+		    tempax >>= 4;  				 /* 1.10.7w; 1.10.6s: 3;  */
+		    if(SiS_Pr->SiS_VGAVDE <= 480)  tempax >>= 4; /* 1.10.7w; 1.10.6s: < 480; >>=1; */
+		    tempbx -= tempax;
+		 }
 	      }
 	   } else return;
 	}
-#if 0
-	if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1400x1050) {
-	}
-#endif
 	temp = tempbx & 0xff;
-	SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,temp);
-	temp = (tempbx & 0xff00) >> 8;
-	temp <<= 4;
-	temp |= tempcl;
+	SiS_SetReg(SiS_Pr->SiS_Part2Port,0x04,temp);
+	temp = ((tempbx & 0xff00) >> 4) | tempcl;
 	SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,temp);
      }
   }
 }
 
-#if 0
-/* TW: New and checked from 650/301LV BIOS */
-/* This might clash with newer "FinalizeLCD()" function */
+#endif
+
+
+/*  =================  SiS 300 O.E.M. ================== */
+
+#ifdef SIS300
+
 void
-SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                  UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+               USHORT ModeNo,USHORT ModeIdIndex, USHORT RefTabIndex)
 {
-   USHORT tempbx,tempah,tempbl,tempbh,tempcl;
-
-   if(!(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV)) return;
+  USHORT crt2crtc=0, modeflag, myindex=0;
+  UCHAR  temp;
+  int i;
 
-   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCDA) {
-      SiS_UnLockCRT2(SiS_Pr,HwDeviceExtension,BaseAddr);
-      tempbh = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x1a);
-      tempbh &= 0x38;
-      tempbh >>= 3;
-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x18);
-      tempbx = (tempbh << 8) | tempbl;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempbx -= 0x12;
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x18,tempbx & 0x00ff);
-      tempah = (tempbx & 0xff00) >> 8;
-      tempah &= 0x07;
-      tempah <<= 3;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x1a,0xc7,tempah);
-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x19);
-      tempah &= 0x0f;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah -= 2;
-      tempah &= 0x0f;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,0x19,0xF0,tempah);
-      tempah = SiS_GetReg1(SiS_Pr->SiS_Part1Port,0x14);
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  tempah++;
-      tempah -= 8;
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,0x14,tempah);
-   } else if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-      tempcl = tempbh = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x01);
-      tempbh &= 0x70;
-      tempbh >>= 4;
-      tempbl = SiS_GetReg1(SiS_Pr->SiS_Part2Port,0x04);
-      tempbx = (tempbh << 8) | tempbl;
-      if(SiS_Pr->SiS_LCDTypeInfo == 1)  {
-           tempbx -= 0x1e;
-	   tempcl &= 0x0f;
-	   tempcl -= 4;
-	   tempcl &= 0x0f;
-      }
-      tempbl = tempbx & 0x00ff;
-      tempbh = (tempbx >> 8) & 0x00ff;
-      SiS_SetReg1(SiS_Pr->SiS_Part2Port,0x04,tempbl);
-      tempbh <<= 4;
-      tempbh |= tempcl;
-      SiS_SetRegANDOR(SiS_Pr->SiS_Part2Port,0x01,0x80,tempbh);
-   }
-}
-#endif
+  if(ModeNo <= 0x13) {
+        modeflag = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_ModeFlag;
+	crt2crtc = SiS_Pr->SiS_SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+  } else {
+        modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag;
+	crt2crtc = SiS_Pr->SiS_RefIndex[RefTabIndex].Ext_CRT2CRTC;
+  }
 
-#endif
+  crt2crtc &= 0x3f;
 
+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1024) {
+     SiS_SetRegAND(SiS_Pr->SiS_Part1Port,0x13,0xdf);
+  }
 
-/*  =================  SiS 300 O.E.M. ================== */
+  if(SiS_Pr->SiS_CustomT == CUT_BARCO1366) {
+     if(modeflag & HalfDCLK) myindex = 1;
 
-#ifdef SIS300
+     if(SiS_LowModeTest(SiS_Pr,ModeNo,HwInfo)) {
+        for(i=0; i<7; i++) {
+           if(barco_p1[myindex][crt2crtc][i][0]) {
+	      SiS_SetRegANDOR(SiS_Pr->SiS_Part1Port,
+	                      barco_p1[myindex][crt2crtc][i][0],
+	   	   	      barco_p1[myindex][crt2crtc][i][2],
+			      barco_p1[myindex][crt2crtc][i][1]);
+	   }
+        }
+     }
+     temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x00);
+     if(temp & 0x80) {
+        temp = SiS_GetReg(SiS_Pr->SiS_Part1Port,0x18);
+        temp++;
+        SiS_SetReg(SiS_Pr->SiS_Part1Port,0x18,temp);
+     }
+  }
+}
 
 #if 0   /* Not used */
 static USHORT
-GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension)
+GetRevisionID(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo)
 {
    ULONG temp1;
 #ifndef LINUX_XF86
@@ -11549,9 +11819,9 @@
 #endif
    USHORT temp2 = 0;
 
-   if((HwDeviceExtension->jChipType==SIS_540)||
-      (HwDeviceExtension->jChipType==SIS_630)||
-      (HwDeviceExtension->jChipType==SIS_730)) {
+   if((HwInfo->jChipType==SIS_540)||
+      (HwInfo->jChipType==SIS_630)||
+      (HwInfo->jChipType==SIS_730)) {
 #ifndef LINUX_XF86
      	base = 0x80000008;
      	OutPortLong(base,0xcf8);
@@ -11568,8 +11838,9 @@
 #endif
 
 static USHORT
-GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, UCHAR *ROMAddr, int Flag)
+GetOEMLCDPtr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, int Flag)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT tempbx=0,romptr=0;
   UCHAR customtable300[] = {
   	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
@@ -11580,9 +11851,9 @@
 	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
   };
 
-  if(HwDeviceExtension->jChipType == SIS_300) {
+  if(HwInfo->jChipType == SIS_300) {
 
-    tempbx = SiS_Pr->SiS_LCDResInfo - 2;
+    tempbx = (SiS_GetReg(SiS_Pr->SiS_P3d4,0x36) & 0x0f) - 2;
     if(!(SiS_Pr->SiS_SetFlag & LCDVESATiming)) tempbx += 4;
     if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_Panel1024x768) {
        if(SiS_Pr->SiS_LCDInfo & DontExpandLCD) tempbx += 3;
@@ -11631,31 +11902,37 @@
 }
 
 static void
-SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+               USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
+  if(SiS_Pr->SiS_LCDResInfo == SiS_Pr->SiS_PanelCustom) return;
+
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
      if(!(ROMAddr[0x237] & 0x01)) return;
      if(!(ROMAddr[0x237] & 0x02)) return;
      romptr = ROMAddr[0x24b] | (ROMAddr[0x24c] << 8);
   }
 
-  /* TW: The Panel Compensation Delay should be set according to tables
-   *     here. Unfortunately, various BIOS versions don't case about
-   *     a uniform way using eg. ROM byte 0x220, but use different
-   *     hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
-   *     Thus we don't set this if the user select a custom pdc or if
-   *     we otherwise detected a valid pdc.
+  /* The Panel Compensation Delay should be set according to tables
+   * here. Unfortunately, various BIOS versions don't case about
+   * a uniform way using eg. ROM byte 0x220, but use different
+   * hard coded delays (0x04, 0x20, 0x18) in SetGroup1().
+   * Thus we don't set this if the user select a custom pdc or if
+   * we otherwise detected a valid pdc.
    */
-  if(HwDeviceExtension->pdc) return;
+  if(HwInfo->pdc) return;
 
-  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 0);
+  temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 0);
 
-  index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
+  if(SiS_Pr->UseCustomMode)
+     index = 0;
+  else
+     index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_LCDDelayIndex;
 
-  if(HwDeviceExtension->jChipType != SIS_300) {
+  if(HwInfo->jChipType != SIS_300) {
 	if(romptr) {
 	   romptr += (temp * 2);
 	   romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
@@ -11699,10 +11976,11 @@
 }
 
 static void
-SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-               UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMLCDData(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+              USHORT ModeNo,USHORT ModeIdIndex)
 {
-#if 0  /* TW: Unfinished; VData table missing */
+#if 0  /* Unfinished; Data table missing */
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -11711,21 +11989,21 @@
      /* No rom pointer in BIOS header! */
   }
 
-  temp = GetOEMLCDPtr(SiS_Pr,HwDeviceExtension, ROMAddr, 1);
+  temp = GetOEMLCDPtr(SiS_Pr,HwInfo, 1);
   if(temp = 0xFFFF) return;
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDHIndex;
   for(i=0x14, j=0; i<=0x17; i++, j++) {
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
+      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDHData[temp][index][j]);
   }
   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1a, 0xf8, (SiS300_LCDHData[temp][index][j] & 0x07));
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex]._VB_LCDVIndex;
-  SiS_SetReg1(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
+  SiS_SetReg(SiS_SiS_Part1Port,0x18, SiS300_LCDVData[temp][index][0]);
   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x19, 0xF0, SiS300_LCDVData[temp][index][1]);
   SiS_SetRegANDOR(SiS_SiS_Part1Port,0x1A, 0xC7, (SiS300_LCDVData[temp][index][2] & 0x38));
   for(i=0x1b, j=3; i<=0x1d; i++, j++) {
-      SiS_SetReg1(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
+      SiS_SetReg(SiS_Pr->SiS_Part1Port,i,SiS300_LCDVData[temp][index][j]);
   }
 #endif
 }
@@ -11749,9 +12027,10 @@
 }
 
 static void
-SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMTVDelay(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+              USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -11781,10 +12060,10 @@
 }
 
 static void
-SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-		  USHORT ModeIdIndex)
+SetOEMAntiFlicker(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                  USHORT ModeNo, USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,romptr=0;
 
   if((ROMAddr) && SiS_Pr->SiS_UseROM) {
@@ -11810,9 +12089,10 @@
 }
 
 static void
-SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMPhaseIncr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,i,j,temp,romptr=0;
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToHiVisionTV) return;
@@ -11829,7 +12109,7 @@
 
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
        for(i=0x31, j=0; i<=0x34; i++, j++) {
-          SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
+          SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase2[temp][index][j]);
        }
   } else {
        if(romptr) {
@@ -11837,20 +12117,21 @@
 	  romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
 	  romptr += (index * 4);
           for(i=0x31, j=0; i<=0x34; i++, j++) {
-	     SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+	     SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
 	  }
        } else {
           for(i=0x31, j=0; i<=0x34; i++, j++) {
-             SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
+             SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Phase1[temp][index][j]);
 	  }
        }
   }
 }
 
 static void
-SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-              UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex)
+SetOEMYFilter(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+              USHORT ModeNo,USHORT ModeIdIndex)
 {
+  UCHAR  *ROMAddr = HwInfo->pjVirtualRomBase;
   USHORT index,temp,temp1,i,j,romptr=0;
 
   if(SiS_Pr->SiS_VBInfo & (SetCRT2ToSCART | SetCRT2ToHiVisionTV)) return;
@@ -11865,9 +12146,9 @@
 
   index = SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].VB_TVYFilterIndex;
 
-  if(HwDeviceExtension->jChipType > SIS_300) {
-     if(SiS_GetReg1(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
-       temp1 = SiS_GetReg1(SiS_Pr->SiS_P3d4,0x35);
+  if(HwInfo->jChipType > SIS_300) {
+     if(SiS_GetReg(SiS_Pr->SiS_P3d4,0x31) & 0x01) {
+       temp1 = SiS_GetReg(SiS_Pr->SiS_P3d4,0x35);
        if(temp1 & (EnablePALM | EnablePALN)) {
           temp = 8;
 	  if(!(temp1 & EnablePALM)) temp = 9;
@@ -11876,10 +12157,10 @@
   }
   if(SiS_Pr->SiS_VBType & VB_SIS301BLV302BLV) {
       for(i=0x35, j=0; i<=0x38; i++, j++) {
-       	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
+       	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
       }
       for(i=0x48; i<=0x4A; i++, j++) {
-     	SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
+     	SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter2[temp][index][j]);
       }
   } else {
       if(romptr) {
@@ -11887,40 +12168,66 @@
 	 romptr = ROMAddr[romptr] | (ROMAddr[romptr + 1] << 8);
 	 romptr += (index * 4);
 	 for(i=0x35, j=0; i<=0x38; i++, j++) {
-       	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
+       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,ROMAddr[romptr + j]);
          }
       } else {
          for(i=0x35, j=0; i<=0x38; i++, j++) {
-       	    SiS_SetReg1(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
+       	    SiS_SetReg(SiS_Pr->SiS_Part2Port,i,SiS300_Filter1[temp][index][j]);
          }
       }
   }
 }
 
+static USHORT
+SiS_SearchVBModeID(SiS_Private *SiS_Pr, USHORT *ModeNo)
+{
+   USHORT ModeIdIndex;
+   UCHAR VGAINFO = SiS_Pr->SiS_VGAINFO;
+
+   if(*ModeNo <= 5) *ModeNo |= 1;
+
+   for(ModeIdIndex=0; ; ModeIdIndex++) {
+      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == *ModeNo) break;
+      if(SiS_Pr->SiS_VBModeIDTable[ModeIdIndex].ModeID == 0xFF)    return 0;
+   }
+
+   if(*ModeNo != 0x07) {
+      if(*ModeNo > 0x03) return ModeIdIndex;
+      if(VGAINFO & 0x80) return ModeIdIndex;
+      ModeIdIndex++;
+   }
+
+   if(VGAINFO & 0x10) ModeIdIndex++;   /* 400 lines */
+	                               /* else 350 lines */
+   return ModeIdIndex;
+}
+
 void
-SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-		  USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo)
+SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+		  USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTableIndex)
 {
-  USHORT ModeIdIndex;
+  USHORT OEMModeIdIndex=0;
 
-  ModeIdIndex = SiS_SearchVBModeID(SiS_Pr,ROMAddr,&ModeNo);
-  if(!(ModeIdIndex)) return;
+  if(!SiS_Pr->UseCustomMode) {
+     OEMModeIdIndex = SiS_SearchVBModeID(SiS_Pr,&ModeNo);
+     if(!(OEMModeIdIndex)) return;
+  }
 
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToLCD) {
-       SetOEMLCDDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetOEMLCDDelay(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
        if(SiS_Pr->SiS_IF_DEF_LVDS == 1) {
-            SetOEMLCDData(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+            SetOEMLCDData(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
        }
   }
+  if(SiS_Pr->UseCustomMode) return;
   if(SiS_Pr->SiS_VBInfo & SetCRT2ToTV) {
-       SetOEMTVDelay(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       SetOEMTVDelay(SiS_Pr, HwInfo, ModeNo,OEMModeIdIndex);
        if(SiS_Pr->SiS_IF_DEF_LVDS == 0) {
-       		SetOEMAntiFlicker(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-    		SetOEMPhaseIncr(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
-       		SetOEMYFilter(SiS_Pr,HwDeviceExtension,BaseAddr,ROMAddr,ModeNo,ModeIdIndex);
+       		SetOEMAntiFlicker(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+    		SetOEMPhaseIncr(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
+       		SetOEMYFilter(SiS_Pr, HwInfo, ModeNo, OEMModeIdIndex);
        }
   }
 }
 #endif
-
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/init301.h fbdev-2.6/drivers/video/sis/init301.h
--- linus-2.6/drivers/video/sis/init301.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/init301.h	Thu Oct 16 14:13:41 2003
@@ -1,20 +1,47 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/init301.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+/* $XFree86$ */
+/*
+ * Data and prototypes for init301.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
+
 #ifndef  _INIT301_
 #define  _INIT301_
 
 #include "osdef.h"
+
 #include "initdef.h"
 #include "vgatypes.h"
 #include "vstruct.h"
 
-#ifdef TC
-#include <stdio.h>
-#include <string.h>
-#include <conio.h>
-#include <dos.h>
-#include <stdlib.h>
-#endif
-
 #ifdef LINUX_XF86
 #include "xf86.h"
 #include "xf86Pci.h"
@@ -24,6 +51,9 @@
 #endif
 
 #ifdef LINUX_KERNEL
+#ifdef SIS_CP
+#undef SIS_CP
+#endif
 #include <linux/config.h>
 #include <linux/version.h>
 #include <asm/io.h>
@@ -35,276 +65,8 @@
 #endif
 #endif
 
-#ifdef WIN2000
-#include <stdio.h>
-#include <string.h>
-#include <miniport.h>
-#include "dderror.h"
-#include "devioctl.h"
-#include "miniport.h"
-#include "ntddvdeo.h"
-#include "video.h"
-#include "sisv.h"
-#endif
-
-#if 0
-extern   const USHORT   SiS_MDA_DAC[];
-extern   const USHORT   SiS_CGA_DAC[];
-extern   const USHORT   SiS_EGA_DAC[];
-extern   const USHORT   SiS_VGA_DAC[];
-#endif
-
-extern   BOOLEAN  SiS_SearchVBModeID(SiS_Private *SiS_Pr, UCHAR *RomAddr, USHORT *);
-
-BOOLEAN  SiS_Is301B(SiS_Private *SiS_Pr, USHORT BaseAddr);
-BOOLEAN  SiS_IsNotM650or651(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsDisableCRT2(SiS_Private *SiS_Pr, USHORT BaseAddr);
-BOOLEAN  SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_CRT2IsLCD(SiS_Private *SiS_Pr, USHORT BaseAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetDefCRT2ExtRegs(SiS_Private *SiS_Pr, USHORT BaseAddr);
-USHORT   SiS_GetRatePtrCRT2(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_AdjustCRT2Rate(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT MODEIdIndex,
-                            USHORT RefreshRateTableIndex,USHORT *i,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SaveCRT2Info(SiS_Private *SiS_Pr, USHORT ModeNo);
-void     SiS_GetCRT2Data(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetCRT2DataLVDS(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                             USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#ifdef SIS315H			     
-void     SiS_GetCRT2PtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex);
-#endif
-void     SiS_GetCRT2Part2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		             USHORT RefreshRateTableIndex,USHORT *CRT2Index, USHORT *ResIndex);
-void     SiS_GetCRT2Data301(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_GetCRT2ResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetRAMDAC2DATA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetCRT2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        USHORT RefreshRateTableIndex,USHORT *CRT2Index,USHORT *ResIndex,
-			PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2ModeRegs(SiS_Private *SiS_Pr, USHORT BaseAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                             PSIS_HW_DEVICE_INFO );
-void     SiS_SetHiVision(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetLVDSDesData(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-			    USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2Offset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                           USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetOffset(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_GetColorDepth(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-USHORT   SiS_GetMCLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-USHORT   SiS_CalcDelayVB(SiS_Private *SiS_Pr);
-USHORT   SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2Sync(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetRegANDOR(USHORT Port,USHORT Index,USHORT DataAND,USHORT DataOR);
-void     SiS_SetRegOR(USHORT Port,USHORT Index,USHORT DataOR);
-void     SiS_SetRegAND(USHORT Port,USHORT Index,USHORT DataAND);
-USHORT   SiS_GetVGAHT2(SiS_Private *SiS_Pr);
-void     SiS_Set300Part2Regs(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-    	 		     USHORT ModeIdIndex, USHORT RefreshRateTableIndex,
-			     USHORT BaseAddr, USHORT ModeNo);
-void     SiS_SetGroup2(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup3(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup4(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup5(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                       USHORT ModeIdIndex);
-void     SiS_FinalizeLCD(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCRT2VCLK(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_EnableCRT2(SiS_Private *SiS_Pr);
-void     SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       PSIS_HW_DEVICE_INFO HwDeviceExtension, int checkcrt2mode);
-BOOLEAN  SiS_BridgeIsOn(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-BOOLEAN  SiS_BridgeIsEnable(SiS_Private *SiS_Pr, USHORT BaseAddr,PSIS_HW_DEVICE_INFO);
-BOOLEAN  SiS_BridgeInSlave(SiS_Private *SiS_Pr);
-void     SiS_PresetScratchregister(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetTVSystem(SiS_Private *SiS_Pr);
-void     SiS_LongWait(SiS_Private *SiS_Pr);
-USHORT   SiS_GetQueueConfig(SiS_Private *SiS_Pr);
-void     SiS_VBLongWait(SiS_Private *SiS_Pr);
-USHORT   SiS_GetVCLKLen(SiS_Private *SiS_Pr, UCHAR *ROMAddr);
-void     SiS_WaitVBRetrace(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_WaitRetrace1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_WaitRetrace2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_WaitRetraceDDC(SiS_Private *SiS_Pr);
-void     SiS_SetCRT2ECLK(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_GetLVDSDesPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                           USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex,
-			   PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#ifdef SIS315H			   
-void     SiS_GetLVDSDesPtrA(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            USHORT RefreshRateTableIndex,USHORT *PanelIndex,USHORT *ResIndex);
-#endif			    
-void     SiS_SetTPData(SiS_Private *SiS_Pr);
-void     SiS_WhatIsThis(SiS_Private *SiS_Pr, USHORT myvbinfo);
-void     SiS_ModCRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                         USHORT RefreshRateTableIndex,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetCHTVReg(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        USHORT RefreshRateTableIndex);
-void     SiS_GetCHTVRegPtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                           USHORT RefreshRateTableIndex);
-void     SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
-void     SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
-void     SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
-#ifdef LINUX_XF86
-USHORT   SiS_I2C_GetByte(SiS_Private *SiS_Pr);
-Bool     SiS_I2C_PutByte(SiS_Private *SiS_Pr, USHORT data);
-Bool     SiS_I2C_Address(SiS_Private *SiS_Pr, USHORT addr);
-void     SiS_I2C_Stop(SiS_Private *SiS_Pr);
-#endif
-void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
-void     SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
-USHORT   SiS_SetStart(SiS_Private *SiS_Pr);
-USHORT   SiS_SetStop(SiS_Private *SiS_Pr);
-void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
-USHORT   SiS_SetSCLKLow(SiS_Private *SiS_Pr);
-USHORT   SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
-USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadLCDDDC(SiS_Private *SiS_Pr, USHORT length, unsigned char *buffer);
-#ifdef LINUX_XF86
-USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
-#endif
-#ifdef SIS315H
-void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                           UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-void     SiS_OEMLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                    UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex);
-#endif
-#ifdef SIS300
-void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT BaseAddr,
-                           UCHAR *ROMAddr,USHORT ModeNo);
-#endif
-BOOLEAN  SiS_LowModeStuff(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-
-BOOLEAN  SiS_GetLCDResInfo(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo, USHORT ModeIdIndex,
-                           PSIS_HW_DEVICE_INFO HwDeviceExtension);
-/* void    SiS_CHACRT1CRTC(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                        USHORT RefreshRateTableIndex); */
-
-BOOLEAN  SiS_SetCRT2Group301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SetGroup1(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                       PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-void     SiS_SetGroup1_LVDS(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-#ifdef SIS315H			    
-void     SiS_SetGroup1_LCDA(SiS_Private *SiS_Pr, USHORT  BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                            PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-#endif			    
-void     SiS_SetGroup1_301(SiS_Private *SiS_Pr, USHORT BaseAddr,UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                           PSIS_HW_DEVICE_INFO HwDeviceExtension,USHORT RefreshRateTableIndex);
-#ifdef SIS300
-void     SiS_SetCRT2FIFO_300(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
-#ifdef SIS315H
-void     SiS_SetCRT2FIFO_310(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,
-                             PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_CRT2AutoThreshold(SiS_Private *SiS_Pr, USHORT  BaseAddr);
-#endif
-BOOLEAN  SiS_GetLCDDDCInfo(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT  BaseAddr);
-void     SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO,USHORT BaseAddr);
-void     SiS_SetPanelDelay(SiS_Private *SiS_Pr, UCHAR* ROMAddr,PSIS_HW_DEVICE_INFO,USHORT DelayTime);
-void     SiS_SetPanelDelayLoop(SiS_Private *SiS_Pr, UCHAR *ROMAddr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                               USHORT DelayTime, USHORT DelayLoop);
-void     SiS_ShortDelay(SiS_Private *SiS_Pr, USHORT delay);
-void     SiS_LongDelay(SiS_Private *SiS_Pr, USHORT delay);
-void     SiS_GenericDelay(SiS_Private *SiS_Pr, USHORT delay);
-void     SiS_VBWait(SiS_Private *SiS_Pr);
-
-void     SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-void     SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-
-void     SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr);
-void     SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
-#ifdef SIS315H
-void     SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
-                            USHORT BaseAddr);
-void     SiS_Chrontel701xOff(SiS_Private *SiS_Pr);
-void     SiS_ChrontelResetDB(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething4(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething3(SiS_Private *SiS_Pr, USHORT ModeNo, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething2(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_WeHaveBacklightCtrl(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-void     SiS_ChrontelPowerSequencing(SiS_Private *SiS_Pr);
-void     SiS_SetCH701xForLCD(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-#ifdef NEWCH701x
-void     SiS_ChrontelDoSomething5(SiS_Private *SiS_Pr);
-#endif
-#endif /* 315 */
-#if 0
-BOOLEAN  SiS_IsSomethingCR5F(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-#endif
-BOOLEAN  SiS_IsYPbPr(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsChScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsTVOrYPbPrOrScart(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_IsLCDOrLCDA(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT BaseAddr);
-BOOLEAN  SiS_CR36BIOSWord23b(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_CR36BIOSWord23d(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-BOOLEAN  SiS_IsSR13_CR30(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-
-extern   void     SiS_SetReg1(USHORT, USHORT, USHORT);
-extern   void     SiS_SetReg3(USHORT, USHORT);
-extern   UCHAR    SiS_GetReg1(USHORT, USHORT);
-extern   UCHAR    SiS_GetReg2(USHORT);
-extern   BOOLEAN  SiS_SearchModeID(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT *ModeNo,USHORT *ModeIdIndex);
-extern   BOOLEAN  SiS_GetRatePtr(SiS_Private *SiS_Pr, ULONG, USHORT);
-extern   void     SiS_SetReg4(USHORT, ULONG);
-extern   ULONG    SiS_GetReg3(USHORT);
-extern   void     SiS_SetReg5(USHORT, USHORT);
-extern   USHORT   SiS_GetReg4(USHORT);
-extern   void     SiS_DisplayOff(SiS_Private *SiS_Pr);
-extern   void     SiS_DisplayOn(SiS_Private *SiS_Pr);
-extern   UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, UCHAR *ROMAddr, USHORT ModeNo,USHORT ModeIdIndex);
-extern   BOOLEAN  SiS_GetLCDACRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-		                     USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
-extern   BOOLEAN  SiS_GetLVDSCRT1Ptr(SiS_Private *SiS_Pr, UCHAR *ROMAddr,USHORT ModeNo,USHORT ModeIdIndex,
-                                     USHORT RefreshRateTableIndex,USHORT *ResInfo,USHORT *DisplayType);
-extern   void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO, UCHAR *ROMAddr,USHORT ModeNo,
-                              USHORT ModeIdIndex);
-#ifdef SIS315H
-extern   UCHAR    SiS_Get310DRAMType(SiS_Private *SiS_Pr, UCHAR *ROMAddr,PSIS_HW_DEVICE_INFO HwDeviceExtension);
-#endif
-
-#ifdef LINUX_XF86
-/* DDC functions */
-USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
-USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
-void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
-USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
-USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT DDCdatatype, unsigned char *buffer);
-USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, SISPtr pSiS, USHORT adaptnum,
-                       USHORT DDCdatatype, unsigned char *buffer);
-#endif
-
 const UCHAR SiS_HiVisionTable[3][64] = {
-  { 
+  {
     0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
     0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
     0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
@@ -314,7 +76,7 @@
     0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x53,
     0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
   },
-  { 
+  {
     0x1d, 0x1d, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
     0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
     0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
@@ -324,15 +86,15 @@
     0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x04, 0xf3,
     0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
   },
-  { 
-    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c, 
-    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a, 
-    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f, 
-    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13, 
-    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0, 
-    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40, 
-    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a, 
-    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00 
+  {
+    0x13, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
+    0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
+    0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+    0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x2b, 0x13,
+    0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
+    0x4b, 0x4b, 0x6f, 0x2f, 0x63, 0x92, 0x0f, 0x40,
+    0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x2a,
+    0x00, 0x40, 0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
   }
 };
 
@@ -357,5 +119,110 @@
     0x26, 0x05, 0x01, 0x0f, 0xed, 0x0f, 0x0a, 0x64,
     0x18, 0x1d, 0x23, 0x28, 0x4c, 0xaa, 0x01
 };
+
+
+void	SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_EnableCRT2(SiS_Private *SiS_Pr);
+USHORT	SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
+void	SiS_WaitRetrace1(SiS_Private *SiS_Pr);
+BOOLEAN	SiS_IsDualEdge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+BOOLEAN	SiS_IsVAMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
+void	SiS_GetVBInfo(SiS_Private *SiS_Pr, USHORT ModeNo,
+              USHORT ModeIdIndex,PSIS_HW_INFO HwInfo,
+	      int checkcrt2mode);
+void	SiS_SetHiVision(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo);
+USHORT	SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex,
+                USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo);
+USHORT	SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+void	SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+BOOLEAN	SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo);
+void	SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void	SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+
+void   	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax);
+void   	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT 	SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax);
+void   	SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT 	SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax);
+void   	SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
+#ifdef SIS315H
+void   	SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void   	SiS_Chrontel701xOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void   	SiS_ChrontelInitTVVSync(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void   	SiS_ChrontelDoSomething1(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void   	SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo);
+void   	SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+#endif /* 315 */
+
+USHORT   SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+void     SiS_SetSwitchDDC2(SiS_Private *SiS_Pr);
+USHORT   SiS_SetStart(SiS_Private *SiS_Pr);
+USHORT   SiS_SetStop(SiS_Private *SiS_Pr);
+void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+USHORT   SiS_SetSCLKLow(SiS_Private *SiS_Pr);
+USHORT   SiS_SetSCLKHigh(SiS_Private *SiS_Pr);
+USHORT   SiS_ReadDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_WriteDDC2Data(SiS_Private *SiS_Pr, USHORT tempax);
+USHORT   SiS_CheckACK(SiS_Private *SiS_Pr);
+
+USHORT   SiS_InitDDCRegs(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+                         USHORT adaptnum, USHORT DDCdatatype, BOOLEAN checkcr32);
+USHORT   SiS_WriteDABDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_PrepareReadDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_PrepareDDC(SiS_Private *SiS_Pr);
+void     SiS_SendACK(SiS_Private *SiS_Pr, USHORT yesno);
+USHORT   SiS_DoProbeDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_ProbeDDC(SiS_Private *SiS_Pr);
+USHORT   SiS_ReadDDC(SiS_Private *SiS_Pr, USHORT DDCdatatype, unsigned char *buffer);
+USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+		       USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+#ifdef LINUX_XF86
+USHORT   SiS_SenseLCDDDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+USHORT   SiS_SenseVGA2DDC(SiS_Private *SiS_Pr, SISPtr pSiS);
+#endif
+
+#ifdef SIS315H
+void     SiS_OEM310Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                           USHORT ModeNo,USHORT ModeIdIndex);
+void     SiS_FinalizeLCD(SiS_Private *, USHORT, USHORT, PSIS_HW_INFO);
+#endif
+#ifdef SIS300
+void     SiS_OEM300Setting(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+                           USHORT ModeNo, USHORT ModeIdIndex, USHORT RefTabindex);
+void     SetOEMLCDData2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo,
+			USHORT ModeNo, USHORT ModeIdIndex,USHORT RefTableIndex);
+#endif
+
+extern void     SiS_SetReg(SISIOADDRESS, USHORT, USHORT);
+extern void     SiS_SetRegByte(SISIOADDRESS, USHORT);
+extern void     SiS_SetRegShort(SISIOADDRESS, USHORT);
+extern void     SiS_SetRegLong(SISIOADDRESS, ULONG);
+extern UCHAR    SiS_GetReg(SISIOADDRESS, USHORT);
+extern UCHAR    SiS_GetRegByte(SISIOADDRESS);
+extern USHORT   SiS_GetRegShort(SISIOADDRESS);
+extern ULONG    SiS_GetRegLong(SISIOADDRESS);
+extern void     SiS_SetRegANDOR(SISIOADDRESS Port,USHORT Index,USHORT DataAND,USHORT DataOR);
+extern void     SiS_SetRegOR(SISIOADDRESS Port,USHORT Index,USHORT DataOR);
+extern void     SiS_SetRegAND(SISIOADDRESS Port,USHORT Index,USHORT DataAND);
+
+extern void     SiS_DisplayOff(SiS_Private *SiS_Pr);
+extern void     SiS_DisplayOn(SiS_Private *SiS_Pr);
+extern BOOLEAN  SiS_LowModeTest(SiS_Private *SiS_Pr, USHORT ModeNo,PSIS_HW_INFO HwInfo);
+
+extern BOOLEAN  SiS_SearchModeID(SiS_Private *, USHORT *, USHORT *);
+extern UCHAR    SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo,USHORT ModeIdIndex);
+
+extern USHORT   SiS_GetColorDepth(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex);
+extern USHORT   SiS_GetOffset(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex,
+                              USHORT RefreshRateTableIndex,PSIS_HW_INFO HwInfo);
+
+extern void     SiS_LoadDAC(SiS_Private *SiS_Pr, PSIS_HW_INFO,USHORT ModeNo,
+                            USHORT ModeIdIndex);
+
 
 #endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/initdef.h fbdev-2.6/drivers/video/sis/initdef.h
--- linus-2.6/drivers/video/sis/initdef.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/initdef.h	Thu Oct 16 14:13:41 2003
@@ -1,13 +1,57 @@
 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
-
+/*
+ * Global definitions for init.c and init301.c
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Integrated Systems
+ *
+ */
 
 #ifndef _INITDEF_
 #define _INITDEF_
 
-#define SiS300                  0x0300
-#define SiS540                  0x5300
-#define SiS630                  0x6300
-#define SiS730                  0x6300
+#define IS_SIS330		(HwInfo->jChipType == SIS_330)
+#define IS_SIS550		(HwInfo->jChipType == SIS_550)
+#define IS_SIS650		(HwInfo->jChipType == SIS_650)
+#define IS_SIS740		(HwInfo->jChipType == SIS_740)
+#define IS_SIS651	        (SiS_Pr->SiS_SysFlags & (SF_Is651 | SF_Is652))
+#define IS_SISM650	        (SiS_Pr->SiS_SysFlags & (SF_IsM650 | SF_IsM652 | SF_IsM653))
+#define IS_SIS661		(SiS_Pr->SiS_SysFlags & (SF_Is661 | SF_IsM651))
+#define IS_SIS741		(SiS_Pr->SiS_SysFlags & SF_IsM741)
+#define IS_SIS65x               (IS_SIS651 || IS_SISM650)
+#define IS_SIS661741	        (SiS_Pr->SiS_SysFlags & (SF_Is661 | SF_IsM661 | SF_Is741))
+#define IS_SIS660		(HwInfo->jChipType == SIS_660)
+#define IS_SIS760		(HwInfo->jChipType == SIS_760)
+#define IS_SIS650660            (IS_SIS650 || IS_SIS660)
+#define IS_SIS650740            ((HwInfo->jChipType >= SIS_650) && (HwInfo->jChipType < SIS_330))
+#define IS_SIS650740660         (IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
+#define IS_SIS550650740660      (IS_SIS550 || IS_SIS650 || IS_SIS660 || IS_SIS740 || IS_SIS760)
 
 /* SiS_VBType */
 #define VB_SIS301	      	0x0001
@@ -15,23 +59,36 @@
 #define VB_SIS302B        	0x0004
 #define VB_SIS301LV     	0x0008
 #define VB_SIS302LV     	0x0010
-#define VB_SIS30xLV		VB_SIS301LV
-#define VB_SIS30xNEW		VB_SIS302LV
+#define VB_SIS301C              0x0020
 #define VB_NoLCD        	0x8000
-#define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)
-#define VB_SIS301B302B          (VB_SIS301B|VB_SIS302B)
+#define VB_SIS301BLV302BLV      (VB_SIS301B|VB_SIS301C|VB_SIS302B|VB_SIS301LV|VB_SIS302LV)
+#define VB_SIS301B302B          (VB_SIS301B|VB_SIS301C|VB_SIS302B)
 #define VB_SIS301LV302LV        (VB_SIS301LV|VB_SIS302LV)
+#define VB_SISVB		(VB_SIS301 | VB_SIS301BLV302BLV)
 
-#define IS_SIS650740            ((HwDeviceExtension->jChipType >= SIS_650) && (HwDeviceExtension->jChipType < SIS_330))
-
-#define IS_SIS650		(HwDeviceExtension->jChipType == SIS_650)
-#define IS_SIS740		(HwDeviceExtension->jChipType == SIS_740)
-#define IS_SIS330		(HwDeviceExtension->jChipType == SIS_330)
-#define IS_SIS550		(HwDeviceExtension->jChipType == SIS_550)
-
-#define CRT1Len                 17
-#define LVDSCRT1Len             15
-#define CHTVRegDataLen          5
+/* VBInfo */
+#define SetSimuScanMode         0x0001   /* CR 30 */
+#define SwitchCRT2              0x0002
+#define SetCRT2ToAVIDEO         0x0004
+#define SetCRT2ToSVIDEO         0x0008
+#define SetCRT2ToSCART          0x0010
+#define SetCRT2ToLCD            0x0020
+#define SetCRT2ToRAMDAC         0x0040
+#define SetCRT2ToHiVisionTV     0x0080
+#define SetCRT2ToTV             0x009C   /* alias */
+#define SetNTSCTV               0x0000   /* CR 31 */
+#define SetPALTV                0x0100
+#define SetInSlaveMode          0x0200
+#define SetNotSimuMode          0x0400
+#define SetNotSimuTVMode        0x0400
+#define SetDispDevSwitch        0x0800
+#define LoadDACFlag             0x1000
+#define SetCHTVOverScan  	0x1000  /* TW: Re-defined (from 0x8000) */
+#define DisableCRT2Display      0x2000
+#define CRT2DisplayFlag         0x2000
+#define DriverMode              0x4000
+#define HotKeySwitch            0x8000  /* TW: ? */
+#define SetCRT2ToLCDA           0x8000
 
 /* SiS_ModeType */
 #define ModeText                0x00
@@ -63,7 +120,7 @@
 #define SupportTV               0x0008
 #define SupportHiVisionTV       0x0010
 #define SupportLCD              0x0020
-#define SupportRAMDAC2          0x0040  
+#define SupportRAMDAC2          0x0040
 #define NoSupportTV             0x0070
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
@@ -81,38 +138,28 @@
 #define ECLKindex3              0x0300
 #define ECLKindex4              0x0400
 
-/* VBInfo */
-#define SetSimuScanMode         0x0001   /* CR 30 */
-#define SwitchToCRT2            0x0002
-#define SetCRT2ToAVIDEO         0x0004
-#define SetCRT2ToSVIDEO         0x0008
-#define SetCRT2ToSCART          0x0010
-#define SetCRT2ToLCD            0x0020
-#define SetCRT2ToRAMDAC         0x0040
-#define SetCRT2ToHiVisionTV     0x0080
-#define SetCRT2ToTV             0x009C   /* alias */
-#define SetNTSCTV               0x0000   /* CR 31 */
-#define SetPALTV                0x0100
-#define SetInSlaveMode          0x0200
-#define SetNotSimuMode          0x0400
-#define SetNotSimuTVMode        0x0400
-#define SetDispDevSwitch        0x0800
-#define LoadDACFlag             0x1000
-#define SetCHTVOverScan  	0x1000  /* TW: Re-defined (from 0x8000) */
-#define DisableCRT2Display      0x2000
-#define CRT2DisplayFlag         0x2000
-#define DriverMode              0x4000
-#define HotKeySwitch            0x8000  /* TW: ? */
-#define SetCRT2ToLCDA           0x8000
-
-#define PanelRGB18Bit           0x0100
-#define PanelRGB24Bit           0x0000
+/* SetFlag */
+#define ProgrammingCRT2         0x01
+#define TVSimuMode              0x02
+#define RPLLDIV2XO              0x04
+#define LCDVESATiming           0x08
+#define EnableLVDSDDA           0x10
+#define SetDispDevSwitchFlag    0x20
+#define CheckWinDos             0x40
+#define SetDOSMode              0x80
 
-#define TVOverScan              0x10    /* Bit in CR35 (300 series only) */
-#define TVOverScanShift         4
-#define ClearBufferFlag         0x20
+/* SysFlags */
+#define SF_Is651                0x0001
+#define SF_IsM650               0x0002
+#define SF_Is652		0x0004
+#define SF_IsM652		0x0008
+#define SF_IsM653		0x0010
+#define SF_Is661		0x0020
+#define SF_IsM661		0x0040
+#define SF_Is741		0x0080
+#define SF_Is660		0x8000
 
-/* CR32 (Newer 630, and 310/325 series)
+/* CR32 (Newer 630, and 315 series)
 
    [0]   VB connected with CVBS
    [1]   VB connected with SVHS
@@ -122,8 +169,13 @@
    [5]   CRT1 monitor is connected
    [6]   VB connected with Hi-Vision TV
    [7]   VB connected with DVI combo connector
+*/
 
+/* CR35 (300 series only) */
+#define TVOverScan              0x10
+#define TVOverScanShift         4
 
+/*
    CR37
 
    [0]   Set 24/18 bit (0/1) RGB to LVDS/TMDS transmitter (set by BIOS)
@@ -134,7 +186,7 @@
 	    011   LVDS + Tumpion Zurac
 	    100   LVDS + Chrontel 7005
 	    110   Chrontel 7005
-	  310/325 series
+	  315 series
 	    001   SiS30x (never seen)
 	    010   LVDS
 	    011   LVDS + Chrontel 7019
@@ -163,28 +215,26 @@
 #define LCDSyncBit            0x00e0
 #define LCDSyncShift               6
 
-/* CR38 (310/325 series) */
+/* CR38 (315 series) */
 #define EnableDualEdge 		0x01   
-#define SetToLCDA		0x02   /* LCD channel A (302B/LV and 650+LVDS only) */
+#define SetToLCDA		0x02   /* LCD channel A (302B/30xLV and 650+LVDS only) */
 #define EnableSiSHiVision       0x04   /* HiVision (HDTV) on SiS bridge */
 #define EnableLVDSScart         0x04   /* Scart on Ch7019 (unofficial definition - TW) */
 #define EnableLVDSHiVision      0x08   /* YPbPr color format (480i HDTV); only on 650/Ch7019 systems */
-#define SiSHiVision1            0x10   /* See SetHiVision() */
-#define SiSHiVision2            0x20
+#define EnableHiVision750       0x08   /* Enable 750P HiVision mode (30xLV only) */
+#define EnableHiVision525       0x10   /* Enable 525P HiVision mode (30xLV only) */
+#define SiSHiVision2            0x20   /* ? - |  --- mask 0x38 combinations have different meaning! */
 #define EnablePALM              0x40   /* 1 = Set PALM */
 #define EnablePALN              0x80   /* 1 = Set PALN */
 
-#define SetSCARTOutput          0x01
-#define BoardTVType             0x02
-
 #define EnablePALMN             0x40   /* Romflag: 1 = Allow PALM/PALN */
 
 /* CR39 (650) */
 #define LCDPass1_1		0x01   /* LVDS only; set by driver to pass 1:1 data to LVDS output  */
-#define Enable302LV_DualLink    0x04   /* 30xNEW (302LV) only; set by mode switching function */
+#define Enable302LV_DualLink    0x04   /* 302LV only; set by mode switching function */
 
 
-/* CR79 (310/325 series only)
+/* CR79 (315 series only)
    [3-0] Notify driver
          0001 Mode Switch event (set by BIOS)
 	 0010 Epansion On/Off event
@@ -202,16 +252,6 @@
    [7]   TV UnderScan/OverScan (set by BIOS)
 */
 
-/* SetFlag */
-#define ProgrammingCRT2         0x01
-#define TVSimuMode              0x02
-#define RPLLDIV2XO              0x04
-#define LCDVESATiming           0x08
-#define EnableLVDSDDA           0x10
-#define SetDispDevSwitchFlag    0x20
-#define CheckWinDos             0x40
-#define SetDOSMode              0x80
-
 /* LCDResInfo */
 #define Panel300_800x600        0x01	/* CR36 */
 #define Panel300_1024x768       0x02
@@ -220,7 +260,10 @@
 #define Panel300_640x480        0x05
 #define Panel300_1024x600       0x06
 #define Panel300_1152x768       0x07
-#define Panel300_320x480        0x08 	/* fstn - TW: This is fake, can be any */
+#define Panel300_1280x768       0x0a
+#define Panel300_320x480        0x0e 	/* fstn - TW: This is fake, can be any */
+#define Panel300_Custom		0x0f
+#define Panel300_Barco1366      0x10
 
 #define Panel310_800x600        0x01
 #define Panel310_1024x768       0x02
@@ -231,9 +274,12 @@
 #define Panel310_1280x960       0x07
 #define Panel310_1152x768       0x08	/* LVDS only */
 #define Panel310_1400x1050      0x09
-#define Panel310_1280x768       0x0a    /* LVDS only */
+#define Panel310_1280x768       0x0a
 #define Panel310_1600x1200      0x0b
-#define Panel310_320x480        0x0c    /* fstn - TW: This is fake, can be any */
+#define Panel310_640x480_2      0x0c
+#define Panel310_640x480_3      0x0d
+#define Panel310_320x480        0x0e    /* fstn - TW: This is fake, can be any */
+#define Panel310_Custom		0x0f
 
 #define Panel_800x600           0x01	/* Unified values */
 #define Panel_1024x768          0x02
@@ -246,23 +292,48 @@
 #define Panel_1400x1050         0x09
 #define Panel_1280x768          0x0a    /* LVDS only */
 #define Panel_1600x1200         0x0b
-#define Panel_320x480           0x0c    /* fstn - TW: This is fake, can be any */
+#define Panel_640x480_2		0x0c
+#define Panel_640x480_3		0x0d
+#define Panel_320x480           0x0e    /* fstn - TW: This is fake, can be any */
+#define Panel_Custom		0x0f
+#define Panel_Barco1366         0x10
+#define Panel_848x480		0x11
+
+/* Index in ModeResInfo table */
+#define SIS_RI_320x200 0
+#define SIS_RI_320x240 1
+#define SIS_RI_320x400 2
+#define SIS_RI_400x300 3
+#define SIS_RI_512x384 4
+#define SIS_RI_640x400 5
+#define SIS_RI_640x480 6
+#define SIS_RI_800x600 7
+#define SIS_RI_1024x768 8
+#define SIS_RI_1280x1024 9
+#define SIS_RI_1600x1200 10
+#define SIS_RI_1920x1440 11
+#define SIS_RI_2048x1536 12
+#define SIS_RI_720x480 13
+#define SIS_RI_720x576 14
+#define SIS_RI_1280x960 15
+#define SIS_RI_800x480 16
+#define SIS_RI_1024x576 17
+#define SIS_RI_1280x720 18
+#define SIS_RI_856x480 19
+#define SIS_RI_1280x768 20
+#define SIS_RI_1400x1050 21
+#define SIS_RI_1152x864 22
+#define SIS_RI_848x480 23
+#define SIS_RI_1360x768 24
+#define SIS_RI_1024x600 25
+#define SIS_RI_1152x768 26
+#define SIS_RI_768x576 27
+#define SIS_RI_1360x1024 28
 
-#define ExtChipType             0x0e
-#define ExtChip301              0x02
-#define ExtChipLVDS             0x04
-#define ExtChipTrumpion         0x06
-#define ExtChipCH7005           0x08
-#define ExtChipMitacTV          0x0a    /* TW: Incorrect, 0x0a = Chrontel 7005 only */
-
-#define IsM650                  0x80   	/* TW: CR5F */
-
-#define LCDDataLen              8
-#define HiTVDataLen             12
-#define TVDataLen               16
-#define SetPALTV                0x0100
-#define HalfDCLK                0x1000  /* modeflag */
+/* CR5F */
+#define IsM650                  0x80
 
+/* Timing data */
 #define NTSCHT                  1716
 #define NTSC2HT                 1920
 #define NTSCVT                  525
@@ -275,37 +346,44 @@
 #define ExtHiTVHT               2100
 #define ExtHiTVVT               1125
 
-#define VCLKStartFreq           25
-#define SoftDramType            0x80
+/* Indices in (VB)VCLKData tables */
 
-#define VCLK40                  0x04   /* Index in VCLKData array */
-#define VCLK65                  0x09   /* Index in VCLKData array */
-#define VCLK108_2               0x14   /* Index in VCLKData array */
-#define TVVCLKDIV2              0x21   /* Indices in (VB)VCLKData arrays */
-#define TVVCLK                  0x22
-#define HiTVVCLKDIV2            0x23
-#define HiTVVCLK                0x24
-#define HiTVSimuVCLK            0x25
-#define HiTVTextVCLK            0x26
+#define VCLK28                  0x00   /* Index in VCLKData table (300 and 315) */
+#define VCLK40                  0x04   /* Index in VCLKData table (300 and 315) */
+#define VCLK65_300              0x09   /* Index in VCLKData table (300) */
+#define VCLK108_2_300           0x14   /* Index in VCLKData table (300) */
+#define VCLK81_300		0x3f   /* Index in VCLKData table (300) */
+#define VCLK108_3_300           0x42   /* Index in VCLKData table (300) */
+#define VCLK100_300             0x43   /* Index in VCLKData table (300) */
+#define VCLK34_300              0x3d   /* Index in VCLKData table (300) */
+#define VCLK65_315              0x0b   /* Index in (VB)VCLKData table (315) */
+#define VCLK108_2_315           0x19   /* Index in (VB)VCLKData table (315) */
+#define VCLK81_315		0x5b   /* Index in (VB)VCLKData table (315) */
+#define VCLK162_315             0x21   /* Index in (VB)VCLKData table (315) */
+#define VCLK108_3_315           0x45   /* Index in VBVCLKData table (315) */
+#define VCLK100_315             0x46   /* Index in VBVCLKData table (315) */
+#define VCLK34_315              0x55   /* Index in VBVCLKData table (315) */
+#define VCLK68_315		0x0d
+
+#define TVCLKBASE_300		0x21   /* Indices on TV clocks in VCLKData table (300) */
+#define TVCLKBASE_315	        0x3a   /* Indices on TV clocks in (VB)VCLKData table (315) */
+#define TVVCLKDIV2              0x00   /* Index relative to TVCLKBASE */
+#define TVVCLK                  0x01   /* Index relative to TVCLKBASE */
+#define HiTVVCLKDIV2            0x02   /* Index relative to TVCLKBASE */
+#define HiTVVCLK                0x03   /* Index relative to TVCLKBASE */
+#define HiTVSimuVCLK            0x04   /* Index relative to TVCLKBASE */
+#define HiTVTextVCLK            0x05   /* Index relative to TVCLKBASE */
 
-#define LoadDACFlag             0x1000
-#define AfterLockCRT2           0x4000
-#define SetCRT2ToAVIDEO         0x0004
-#define SetCRT2ToSCART          0x0010
-#define Ext2StructSize          5
+/* ------------------------------ */
 
 #define SetSCARTOutput          0x01
-#define AVIDEOSense             0x01
-#define SVIDEOSense             0x02
-#define SCARTSense              0x04
-#define LCDSense                0x08
-#define Monitor1Sense           0x20
-#define Monitor2Sense           0x10
-#define HiTVSense               0x40
-#define BoardTVType             0x02
+
 #define HotPlugFunction         0x08
+
 #define StStructSize            0x06
 
+#define SIS_VIDEO_CAPTURE       0x00 - 0x30
+#define SIS_VIDEO_PLAYBACK      0x02 - 0x30
 #define SIS_CRT2_PORT_04        0x04 - 0x30
 #define SIS_CRT2_PORT_10        0x10 - 0x30
 #define SIS_CRT2_PORT_12        0x12 - 0x30
@@ -318,6 +396,10 @@
 #define ADR_CHTVVCLKPtr         0x216
 #define ADR_CHTVRegDataPtr      0x218
 
+#define LCDDataLen              8
+#define HiTVDataLen             12
+#define TVDataLen               16
+
 #define LVDSDataLen             6
 #define EnableLVDSDDA           0x10
 #define LVDSDesDataLen          3
@@ -330,8 +412,6 @@
 #define SoftSettingAddr         0x52
 #define ModeSettingAddr         0x53
 
-#define SelectCRT1Rate          0x4
-        
 #define _PanelType00             0x00
 #define _PanelType01             0x08
 #define _PanelType02             0x10
@@ -350,7 +430,8 @@
 #define _PanelType0F             0x78
 
 #define PRIMARY_VGA       	0     /* 1: SiS is primary vga 0:SiS is secondary vga */
-#define BIOSIDCodeAddr          0x235  /* TW: Offsets to ptrs in BIOS image */
+
+#define BIOSIDCodeAddr          0x235  /* Offsets to ptrs in BIOS image */
 #define OEMUtilIDCodeAddr       0x237
 #define VBModeIDTableAddr       0x239
 #define OEMTVPtrAddr            0x241
@@ -393,7 +474,7 @@
 
 /*
   =============================================================
-   			for 310/325 series
+   			  for 315 series
   =============================================================
 */
 #define SoftDRAMType        0x80
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/oem300.h fbdev-2.6/drivers/video/sis/oem300.h
--- linus-2.6/drivers/video/sis/oem300.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/oem300.h	Thu Oct 16 14:13:42 2003
@@ -1,5 +1,37 @@
-
-/* OEM Data for 300 series */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/*
+ * OEM Data for 300 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
 
 const UCHAR SiS300_OEMTVDelay301[8][4] =
 {
@@ -680,325 +712,147 @@
     }
 };
 
-const UCHAR SiS300_LCDHData[24][11][5] = {
+/* Custom data for Barco iQ Pro R300 */
+const UCHAR barco_p1[2][9][7][3] = {
     {
-        {0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-        {0x67,0x11,0x9a,0x56,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x8e,0x18,0x28,0x78,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x4e,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-	{0x67,0x11,0x9a,0x56,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x67,0x91,0x84,0x5e,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x65,0xef,0x83,0x5c,0x00},
-	{0x8a,0x14,0x00,0x80,0x00},
-	{0x8a,0x14,0x00,0x80,0x00}
-    },
-    {
-        {0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x67,0x91,0x84,0x5E,0x00},
-    	{0x65,0xEF,0x83,0x5C,0x00},
-    	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x67,0x91,0x84,0x5E,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x65,0xEF,0x83,0x5C,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
-    },
-    {
-    	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x8E,0x18,0x28,0x78,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x4E,0x18,0x90,0x38,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x67,0x11,0x9A,0x56,0x00},
-	{0x8A,0x14,0x00,0x80,0x00},
-	{0x8A,0x14,0x00,0x80,0x00}
+	{  { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x1e, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x16, 0x00 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x1e, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x11, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x26, 0x00 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x30, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0x00, 0x00 },
+	   { 0x17, 0xa0, 0x00 },
+	   { 0x1a, 0xa0, 0x00 },
+	   { 0x1b, 0x2a, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0x00, 0x00 },
+	   { 0x17, 0xaa, 0x00 },
+	   { 0x1a, 0xa0, 0x00 },
+	   { 0x1b, 0x2a, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   {    0,    0,    0 }
+	}
+    },
+    {
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x19, 0x00 },
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   { 0x16, 0xcf, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe7, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x1e, 0x00 }
+	},
+	{
+	   { 0x16, 0xd1, 0x00 },
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe6, 0x00 },
+	   { 0x1b, 0x11, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x26, 0x00 }
+	},
+	{
+	   { 0x18, 0x00, 0x00 },
+	   { 0x1a, 0xe0, 0x00 },
+	   { 0x1b, 0x26, 0x00 },
+	   { 0x1c, 0xff, 0x00 },
+	   { 0x1d, 0x1c, 0x00 },
+	   { 0x1e, 0x30, 0x00 },
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	},
+	{
+	   {    0,    0,    0 }
+	}
     }
 };
 
-#if 0
-const UCHAR SiS300_LCDVData[24][11][6] = {
-    {
-        {
-    },
-};
-#endif
+
+
+
+
+
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/oem310.h fbdev-2.6/drivers/video/sis/oem310.h
--- linus-2.6/drivers/video/sis/oem310.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/oem310.h	Thu Oct 16 14:13:42 2003
@@ -1,5 +1,37 @@
-
-/* OEM Data for 310/325/330 series */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/oem300.h.c,v 1.0 2001/11/30 12:12:01 eich Exp $ */
+/*
+ * OEM Data for 315/330 series
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Based on code by Silicon Intergrated Systems
+ *
+ */
 
 const UCHAR SiS310_LCDDelayCompensation_301[] =	    	/* 301 */
 {
@@ -100,7 +132,7 @@
 
 const UCHAR SiS310_LCDDelayCompensation_651301LV[] =	  /* M650/651 301LV */
 {
-                 0x33,0x33,0x33,    /*   800x600 (guessed) */
+                 0x33,0x33,0x33,    /*   800x600 (guessed) - new: PanelType, not PanelRes ! */
 		 0x33,0x33,0x33,    /*  1024x768 */
 		 0x33,0x33,0x33,    /* 1280x1024 */
 		 0x33,0x33,0x33,    /*   640x480 (unknown) */
@@ -361,5 +393,146 @@
  }
 };
 
+/* OEM data for Compaq Presario 3045US/Inventec */
+static const SiS_LCDDataStruct  SiS310_ExtCompaq1280x1024Data[] =
+{
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{  211,  60,1024, 501,1688,1066},
+	{  211,  60,1024, 508,1688,1066},
+	{   32,  15,1696, 501,1696,1066},
+	{  212,  75,1024, 621,1696,1066},
+	{    4,   3,1696, 810,1696,1066},
+	{    1,   1,1696,1066,1696,1066}
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_1[] =
+{
+ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x35,0x1B,0xA0,0xC0,0x80,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x3F,0x1B,0xD0,0xF0,0xB0,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x45,0x1C,0x20,0x3F,0xFF,0xB8,0x23,0x0A,0x07,0x14,0x8A,0x12}},
+ {{0x49,0x1C,0x40,0x7F,0xFF,0xAD,0x23,0x0A,0x07,0xF3,0x8A,0x12}},
+ {{0x4C,0x1C,0x18,0x2F,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x48,0x1C,0x15,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}}
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_2[] =
+{
+ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
+ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
+ {{0x2B,0x12,0xD9,0xE5,0xD5,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
+ {{0x22,0x12,0xC0,0xCC,0xBC,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
+ {{0x33,0x13,0x01,0x0D,0xFD,0x2C,0x23,0x98,0x27,0x3E,0x08,0x42}},
+ {{0x3F,0x1B,0x3D,0x49,0x39,0x54,0x23,0xC0,0x27,0x66,0x30,0x42}},
+ {{0x33,0x1B,0x91,0x9D,0x8D,0x8C,0x23,0xF8,0x27,0x9E,0x68,0x42}},
+ {{0x43,0x24,0x11,0x1D,0x0D,0xCC,0x23,0x38,0x37,0xDE,0xA8,0x42}},
+ {{0x43,0x24,0x21,0x29,0x19,0xEA,0x23,0x0A,0x07,0x32,0xC6,0x42}}
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Compaq1280x1024_3[] =
+{
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBD,0x23,0x0A,0x07,0x23,0x8A,0x12}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}},
+ {{0x47,0x1C,0x14,0x29,0xFF,0xBE,0x23,0x0A,0x07,0x26,0x8A,0x42}}
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_1[] =
+{
+ {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x2C,0x12,0x9A,0xAE,0x88,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x38,0x13,0x16,0x0C,0xE6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x38,0x18,0x16,0x00,0x00,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x12,0xC9,0xDC,0xB6,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_2[] =
+{
+  {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
+  {{0x2C,0x12,0x38,0x55,0x2F,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
+  {{0x25,0x12,0x51,0x6E,0x48,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
+  {{0x2C,0x12,0x38,0x55,0x2F,0xE0,0x12,0xB1,0x47,0x30,0x71,0x33}},
+  {{0x2D,0x12,0x79,0x96,0x70,0xCC,0x12,0x89,0x47,0x1C,0x49,0x33}},
+  {{0x29,0x12,0xB5,0xD2,0xAC,0xF4,0x12,0xD9,0x47,0x44,0x99,0x33}},
+  {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+#if 0
+  {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+  {{0x2C,0x12,0x38,0x55,0x2F,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+  {{0x25,0x12,0x51,0x6E,0x48,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+  {{0x2C,0x12,0x38,0x55,0x2F,0xC1,0x35,0xB1,0x47,0xE9,0x71,0x33}},
+  {{0x2D,0x12,0x79,0x96,0x70,0x99,0x35,0x89,0x47,0xC1,0x49,0x33}},
+  {{0x29,0x12,0xB5,0xD2,0xAC,0xE9,0x35,0xD9,0x47,0x11,0x99,0x33}},
+  {{0x36,0x13,0x13,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
+#endif
+};
+
+static const SiS_Part2PortTblStruct SiS310_CRT2Part2_Clevo1024x768_3[] =
+{
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}}, /* Corrected */
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+ {{0x36,0x13,0x13,0x25,0xFF,0x32,0x22,0x0A,0x07,0x82,0x0A,0x12}},
+ {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}},
+ {{0x25,0x13,0xC9,0x25,0xFF,0x59,0x45,0x09,0x07,0xF9,0x09,0x24}}
+};
+
+static const SiS_LVDSDesStruct Clevo1024x768Des_1[] =
+{
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 }
+};
+
+static const SiS_LVDSDesStruct Clevo1024x768Des_2[] =
+{
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1152, 622 },
+  { 1232, 722 },
+  {    0,   0 },
+  {    0, 794 },
+  {    0,   0 }
+};
+
+static const SiS_LVDSDesStruct Uniwill1024x768Des_1[] =
+{
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 0 },
+  { 0, 805 }
+};
+
+static const SiS_LVDSDesStruct Uniwill1024x768Des_2[] =
+{
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1184, 622 },
+  { 1184, 597 },
+  { 1152, 650 },
+  { 1232, 722 },
+  {    0, 805 },
+};
 
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/osdef.h fbdev-2.6/drivers/video/sis/osdef.h
--- linus-2.6/drivers/video/sis/osdef.h	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/osdef.h	Thu Oct 16 14:13:42 2003
@@ -1,79 +1,43 @@
-/* #define WINCE_HEADER */
-/* #define WIN2000 */
-/* #define TC */
+
+/* OS depending defines */
+
+/* The choices are: */
+
 #define LINUX_KERNEL	   /* Kernel framebuffer */
 /* #define LINUX_XF86 */   /* XFree86 */
 
 /**********************************************************************/
-#ifdef LINUX_KERNEL
-	#include <linux/config.h>
-	#include <linux/version.h>
-	#ifdef CONFIG_FB_SIS_300
- 		#define SIS300
-	#endif
-
-	#ifdef CONFIG_FB_SIS_315
-		#define SIS315H
-	#endif
-	#if 1
-		#define SISFBACCEL	/* Include 2D acceleration */
-	#endif
-	#if 1
-		#define SISFB_PAN	/* Include Y-Panning code */
-	#endif
-#else
-/*	#define SIS300*/
-	#define SIS315H
-#endif
-#ifdef LINUX_XF86
-	#define SIS300
-	/* #define SIS315H */ /* TW: done above */
-#endif
+#ifdef LINUX_KERNEL  /* -------------------------- */
+#include <linux/config.h>
+#include <linux/version.h>
 
-/**********************************************************************/
-#ifdef TC
-#endif
-#ifdef WIN2000
-#endif
-#ifdef WINCE_HEADER
-#endif
-#ifdef LINUX_XF86
+#ifdef CONFIG_FB_SIS_300
+#define SIS300
 #endif
-#ifdef LINUX_KERNEL
-#endif
-/**********************************************************************/
-#ifdef TC
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
-#endif
-#ifdef WIN2000
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) MemFill((PVOID) MemoryAddress,(ULONG) MemorySize,(UCHAR) value);
+
+#ifdef CONFIG_FB_SIS_315
+#define SIS315H
 #endif
-#ifdef WINCE_HEADER
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize);
+
+#if 1
+#define SISFBACCEL	/* Include 2D acceleration */
 #endif
-#ifdef LINUX_XF86
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+
 #endif
-#ifdef LINUX_KERNEL
-#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
+
+#ifdef LINUX_XF86 /* ----------------------------- */
+#define SIS300
+#define SIS315H
 #endif
-/**********************************************************************/
 
 /**********************************************************************/
-
-#ifdef TC
-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
-#ifdef WIN2000
-#define SiS_MemoryCopy(Destination,Soruce,Length)  /*VideoPortMoveMemory((PUCHAR)Destination , Soruce,length);*/
-#endif
-#ifdef WINCE_HEADER
-#define SiS_MemoryCopy(Destination,Soruce,Length) memmove(Destination, Soruce, Length);
-#endif
 #ifdef LINUX_XF86
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
 #endif
+
 #ifdef LINUX_KERNEL
+#define SiS_SetMemory(MemoryAddress,MemorySize,value) memset(MemoryAddress, value, MemorySize)
 #define SiS_MemoryCopy(Destination,Soruce,Length) memcpy(Destination,Soruce,Length)
 #endif
 
@@ -104,19 +68,6 @@
 #endif /* InPortLong */
 
 /**********************************************************************/
-/*  TC                                                                */
-/**********************************************************************/
-
-#ifdef TC
-#define OutPortByte(p,v) outp((unsigned short)(p),(unsigned char)(v))
-#define OutPortWord(p,v) outp((unsigned short)(p),(unsigned short)(v))
-#define OutPortLong(p,v) outp((unsigned short)(p),(unsigned long)(v))
-#define InPortByte(p)    inp((unsigned short)(p))
-#define InPortWord(p)    inp((unsigned short)(p))
-#define InPortLong(p)    ((inp((unsigned short)(p+2))<<16) | inp((unsigned short)(p)))
-#endif
-
-/**********************************************************************/
 /*  LINUX XF86                                                        */
 /**********************************************************************/
 
@@ -142,29 +93,4 @@
 #define InPortLong(p)    inl((u16)(p))
 #endif
 
-/**********************************************************************/
-/*  WIN 2000                                                          */
-/**********************************************************************/
-
-#ifdef WIN2000
-#define OutPortByte(p,v) VideoPortWritePortUchar ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) VideoPortWritePortUshort((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) VideoPortWritePortUlong ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    VideoPortReadPortUchar  ((PUCHAR) (p))
-#define InPortWord(p)    VideoPortReadPortUshort ((PUSHORT) (p))
-#define InPortLong(p)    VideoPortReadPortUlong  ((PULONG) (p))
-#endif
 
-
-/**********************************************************************/
-/*  WIN CE                                                            */
-/**********************************************************************/
-
-#ifdef WINCE_HEADER
-#define OutPortByte(p,v) WRITE_PORT_UCHAR ((PUCHAR) (p), (UCHAR) (v))
-#define OutPortWord(p,v) WRITE_PORT_USHORT((PUSHORT) (p), (USHORT) (v))
-#define OutPortLong(p,v) WRITE_PORT_ULONG ((PULONG) (p), (ULONG) (v))
-#define InPortByte(p)    READ_PORT_UCHAR  ((PUCHAR) (p))
-#define InPortWord(p)    READ_PORT_USHORT ((PUSHORT) (p))
-#define InPortLong(p)    READ_PORT_ULONG  ((PULONG) (p))
-#endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/sis_accel.c fbdev-2.6/drivers/video/sis/sis_accel.c
--- linus-2.6/drivers/video/sis/sis_accel.c	Thu Oct 16 14:13:41 2003
+++ fbdev-2.6/drivers/video/sis/sis_accel.c	Thu Oct 16 14:13:42 2003
@@ -1,5 +1,5 @@
 /*
- * SiS 300/630/730/540/315/550/650/740 frame buffer driver
+ * SiS 300/630/730/540/315/550/650/740/330/660 frame buffer driver
  * for Linux kernels 2.4.x and 2.5.x
  *
  * 2D acceleration part
@@ -211,7 +211,7 @@
 	SiS300DoCMD
 }
 
-/* 310/325 series ------------------------------------------------ */
+/* 315 series ---------------------------------------------------- */
 
 static void
 SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
@@ -230,7 +230,7 @@
 		/* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
 	}
 	SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
-	/* TW: The 310/325 series is smart enough to know the direction */
+	/* The 315 series is smart enough to know the direction */
 }
 
 static void
@@ -328,11 +328,13 @@
     }
 }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)  /* --- KERNEL 2.5.34 and later --- */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)  /* --------------- 2.5 --------------- */
 
 int fbcon_sis_sync(struct fb_info *info)
 {
-   if(!sisfb_accel) return 0;
+   if(!ivideo.accel)
+   	return 0;
+
    CRITFLAGS
    if(sisvga_engine == SIS_300_VGA) {
       SiS300Sync();
@@ -352,7 +354,7 @@
    if(!rect->width || !rect->height)
    	return;
 
-   if(!sisfb_accel) {
+   if(!ivideo.accel) {
 	cfb_fillrect(info, rect);
 	return;
    }
@@ -388,7 +390,7 @@
    CRITFLAGS
 
    TWDEBUG("Inside sis_copyarea");
-   if(!sisfb_accel) {
+   if(!ivideo.accel) {
    	cfb_copyarea(info, area);
 	return;
    }
@@ -418,7 +420,7 @@
 
 #endif
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)  /* ------ KERNEL <2.5.34 ------ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)  /* -------------- 2.4 --------------- */
 
 void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
 			    int dsty, int dstx, int height, int width)
@@ -591,38 +593,38 @@
 
 #ifdef FBCON_HAS_CFB8
 struct display_switch fbcon_sis8 = {
-	setup:			fbcon_cfb8_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear8,
-	putc:			fbcon_cfb8_putc,
-	putcs:			fbcon_cfb8_putcs,
-	revc:			fbcon_cfb8_revc,
-	clear_margins:		fbcon_cfb8_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb8_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear8,
+	.putc			= fbcon_cfb8_putc,
+	.putcs			= fbcon_cfb8_putcs,
+	.revc			= fbcon_cfb8_revc,
+	.clear_margins		= fbcon_cfb8_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
 struct display_switch fbcon_sis16 = {
-	setup:			fbcon_cfb16_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear16,
-	putc:			fbcon_cfb16_putc,
-	putcs:			fbcon_cfb16_putcs,
-	revc:			fbcon_sis_revc,
-	clear_margins:		fbcon_cfb16_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb16_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear16,
+	.putc			= fbcon_cfb16_putc,
+	.putcs			= fbcon_cfb16_putcs,
+	.revc			= fbcon_sis_revc,
+	.clear_margins		= fbcon_cfb16_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
 struct display_switch fbcon_sis32 = {
-	setup:			fbcon_cfb32_setup,
-	bmove:			fbcon_sis_bmove,
-	clear:			fbcon_sis_clear32,
-	putc:			fbcon_cfb32_putc,
-	putcs:			fbcon_cfb32_putcs,
-	revc:			fbcon_sis_revc,
-	clear_margins:		fbcon_cfb32_clear_margins,
-	fontwidthmask:		FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+	.setup			= fbcon_cfb32_setup,
+	.bmove			= fbcon_sis_bmove,
+	.clear			= fbcon_sis_clear32,
+	.putc			= fbcon_cfb32_putc,
+	.putcs			= fbcon_cfb32_putcs,
+	.revc			= fbcon_sis_revc,
+	.clear_margins		= fbcon_cfb32_clear_margins,
+	.fontwidthmask		= FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/sis_accel.h fbdev-2.6/drivers/video/sis/sis_accel.h
--- linus-2.6/drivers/video/sis/sis_accel.h	Thu Oct 16 14:13:42 2003
+++ fbdev-2.6/drivers/video/sis/sis_accel.h	Thu Oct 16 14:13:42 2003
@@ -47,7 +47,7 @@
 #define TRAPAZOID_FILL          0x00000005  /* Fill trapezoid */
 #define TRANSPARENT_BITBLT      0x00000006  /* Transparent Blit */
 
-/* Additional engine commands for 310/325 */
+/* Additional engine commands for 315 */
 #define ALPHA_BLEND		0x00000007  /* Alpha blend ? */
 #define A3D_FUNCTION		0x00000008  /* 3D command ? */
 #define	CLEAR_Z_BUFFER		0x00000009  /* ? */
@@ -90,11 +90,11 @@
 #define NO_RESET_COUNTER        0x00400000
 #define NO_LAST_PIXEL           0x00200000
 
-/* Subfunctions for Color/Enhanced Color Expansion (310/325 only) */
+/* Subfunctions for Color/Enhanced Color Expansion (315 only) */
 #define COLOR_TO_MONO		0x00100000
 #define AA_TEXT			0x00200000
 
-/* Some general registers for 310/325 series */
+/* Some general registers for 315 series */
 #define SRC_ADDR		0x8200
 #define SRC_PITCH		0x8204
 #define AGP_BASE		0x8206 /* color-depth dependent value */
@@ -326,7 +326,7 @@
 
 
 
-/* ----------- SiS 310/325 series --------------- */
+/* -------------- SiS 315 series --------------- */
 
 /* Q_STATUS:
    bit 31 = 1: All engines idle and all queues empty
@@ -342,16 +342,27 @@
    bits 7:0:   2D counter 1
 
    Where is the command queue length (current amount of commands the queue
-   can accept) on the 310/325 series? (The current implementation is taken
-   from 300 series and certainly wrong...)
+   can accept) on the 315 series?
 */
 
 /* TW: FIXME: CmdQueLen is... where....? */
+/* We assume a length of 4 bytes per command; since 512K of
+ * of RAM are allocated, the number of commands is easily
+ * calculated (assuming that there is no 3D support yet)
+ * We calculate it very cautiously (128K only) and let the
+ * rest to the (never?)-to-come (?) 3D engine. (The 3D engine
+ * can use a similar technique, using the remaining 384K,
+ * hence a queue overflow is avoided)
+ * UPDATE: This technique causes a terrible system latency
+ * on integrated chipsets. Disable the queue handling for
+ * now.
+ */
 #define SiS310Idle \
   { \
   while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
   while( (MMIO_IN16(ivideo.mmio_vbase, Q_STATUS+2) & 0x8000) != 0x8000){}; \
-  CmdQueLen=MMIO_IN16(ivideo.mmio_vbase, Q_STATUS); \
+  CmdQueLen = 0; \
+  /*CmdQueLen = ((128 * 1024) / 4) - 64; */ \
   }
 
 #define SiS310SetupSRCBase(base) \
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/sis_main.c fbdev-2.6/drivers/video/sis/sis_main.c
--- linus-2.6/drivers/video/sis/sis_main.c	Thu Oct 16 14:13:42 2003
+++ fbdev-2.6/drivers/video/sis/sis_main.c	Thu Oct 16 14:13:42 2003
@@ -1,25 +1,20 @@
 /*
- * SiS 300/630/730/540/315/550/650/740 frame buffer device
- * for Linux kernels 2.4.x and 2.5.x
+ * SiS 300/630/730/540/315/550/650/651/M650/661FX/M661FX/740/741/330/760
+ * frame buffer driver for Linux kernels 2.4.x and 2.5.x
  *
- * Partly based on the VBE 2.0 compliant graphic boards framebuffer driver,
+ * (C) 1999 Silicon Integrated Systems, Inc.
+ * (C) 2001-2003 Thomas Winischhofer, Vienna, Austria.
+ *
+ * Author:   	Thomas Winischhofer <thomas@winischhofer.net>
+ *
+ * Author of code base:
+ *		SiS (www.sis.com.tw)
+ *
+ * See http://www.winischhofer.net/ for more information and updates
+ *
+ * Originally based on the VBE 2.0 compliant graphic boards framebuffer driver,
  * which is (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  *
- * Authors:   	SiS (www.sis.com.tw)
- *		(Various others)
- *		Thomas Winischhofer <thomas@winischhofer.net>:
- *			- SiS Xabre (330) support
- *			- many fixes and enhancements for all chipset series,
- *			- extended bridge handling, TV output for Chrontel 7005
- *                      - 650/LVDS support (for LCD panels up to 1600x1200)
- *                      - 650/740/Chrontel 7019 support
- *                      - 30xB/30xLV LCD, TV and VGA2 support
- *			- memory queue handling enhancements,
- *                      - 2D acceleration and y-panning,
- *                      - portation to 2.5 API
- *			- etc.
- *			(see http://www.winischhofer.net/
- *			for more information and updates)
  */
 
 #include <linux/config.h>
@@ -38,11 +33,15 @@
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/pci.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#include <linux/vmalloc.h>
+#endif
 #include <linux/vt_kern.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
 #include <linux/agp_backend.h>
 #include <linux/types.h>
+#include <asm/uaccess.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 #include <linux/spinlock.h>
@@ -73,9 +72,9 @@
 #include "sis_main.h"
 #include "sis.h"
 
-#if 0
-#ifdef LINUXBIOS
-#include "bios.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#error "This version of sisfb requires at least 2.6.0"
 #endif
 #endif
 
@@ -121,7 +120,7 @@
 /* ------------ Interface for init & mode switching code ------------- */
 
 BOOLEAN
-sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
+sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
 	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
@@ -134,9 +133,19 @@
 
 	if (!init) {
 		init = TRUE;
-		pdev = pci_find_device(PCI_VENDOR_ID_SI, ivideo.chip_id, pdev);
-		if (pdev)
-			valid_pdev = TRUE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
+		pci_for_each_dev(pdev) {
+#else
+		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+#endif
+			DPRINTK("sisfb: Current: 0x%x, target: 0x%x\n",
+			         pdev->device, ivideo.chip_id);
+			if ((pdev->vendor == PCI_VENDOR_ID_SI)
+			           && (pdev->device == ivideo.chip_id)) {
+				valid_pdev = TRUE;
+				break;
+			}
+		}
 	}
 
 	if (!valid_pdev) {
@@ -153,7 +162,7 @@
 	return TRUE;
 }
 
-BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+BOOLEAN sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
 	unsigned long offset, unsigned long set, unsigned long *value)
 {
 	static struct pci_dev *pdev = NULL;
@@ -163,6 +172,7 @@
 	if (!init) {
 		init = TRUE;
 		switch (ivideo.chip) {
+#ifdef CONFIG_FB_SIS_300
 		case SIS_540:
 			nbridge_id = PCI_DEVICE_ID_SI_540;
 			break;
@@ -172,23 +182,42 @@
 		case SIS_730:
 			nbridge_id = PCI_DEVICE_ID_SI_730;
 			break;
+#endif
+#ifdef CONFIG_FB_SIS_315
 		case SIS_550:
 			nbridge_id = PCI_DEVICE_ID_SI_550;
 			break;
 		case SIS_650:
 			nbridge_id = PCI_DEVICE_ID_SI_650;
 			break;
-		case SIS_740:			
+		case SIS_740:
 			nbridge_id = PCI_DEVICE_ID_SI_740;
 			break;
+		case SIS_660:
+			nbridge_id = PCI_DEVICE_ID_SI_660;
+			break;
+		case SIS_760:
+			nbridge_id = PCI_DEVICE_ID_SI_760;
+			break;
+#endif
 		default:
 			nbridge_id = 0;
 			break;
 		}
 
-		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
-		if (pdev)
-			valid_pdev = TRUE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
+		pci_for_each_dev(pdev) {
+#else
+		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+#endif
+			DPRINTK("Current: 0x%x, target: 0x%x\n",
+					pdev->device, ivideo.chip_id);
+			if ((pdev->vendor == PCI_VENDOR_ID_SI)
+					&& (pdev->device == nbridge_id)) {
+				valid_pdev = TRUE;
+				break;
+			}
+		}
 	}
 
 	if (!valid_pdev) {
@@ -207,66 +236,291 @@
 
 /* ------------------ Internal helper routines ----------------- */
 
-static void sisfb_search_mode(const char *name)
+static BOOLEAN sisfb_verify_rate(struct sisfb_monitor *monitor, int mode_idx, int rate_idx, int rate)
 {
-	int i = 0, j = 0;
+	int htotal, vtotal;
+	unsigned int dclock, hsync;
 
-	if(name == NULL) {
-	   printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
-	   sisfb_mode_idx = DEFAULT_MODE;
-	   return;
+	if(!monitor->datavalid) return TRUE;
+
+	if(mode_idx < 0) return FALSE;
+
+	if(rate < (monitor->vmin - 1)) return FALSE;
+	if(rate > (monitor->vmax + 1)) return FALSE;
+
+	if(sisfb_gettotalfrommode(&SiS_Pr, &sishw_ext, sisbios_mode[mode_idx].mode_no,
+	                          &htotal, &vtotal, rate_idx)) {
+		dclock = (htotal * vtotal * rate) / 1000;
+		if(dclock > (monitor->dclockmax + 1000)) return FALSE;
+		hsync = dclock / htotal;
+		if(hsync < (monitor->hmin - 1)) return FALSE;
+		if(hsync > (monitor->hmax + 1)) return FALSE;
+        } else {
+	  	return FALSE;
 	}
-		
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		
-        if (!strcmp(name, sisbios_mode[MODE_INDEX_NONE].name)) {
-	   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
-	   sisfb_mode_idx = DEFAULT_MODE;
-	   return;
+	return TRUE;
+};
+
+static BOOLEAN sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer)
+{
+	int i, j, xres, yres, refresh, index;
+	u32 emodes;
+
+	if(buffer[0] != 0x00 || buffer[1] != 0xff ||
+	   buffer[2] != 0xff || buffer[3] != 0xff ||
+	   buffer[4] != 0xff || buffer[5] != 0xff ||
+	   buffer[6] != 0xff || buffer[7] != 0x00) {
+	   printk(KERN_DEBUG "sisfb: Bad EDID header\n");
+	   return FALSE;
 	}
-#endif		
 
-	while(sisbios_mode[i].mode_no != 0) {
-		if (!strcmp(name, sisbios_mode[i].name)) {
-			sisfb_mode_idx = i;
-			j = 1;
-			break;
-		}
-		i++;
+	if(buffer[0x12] != 0x01) {
+	   printk(KERN_INFO "sisfb: EDID version %d not supported\n",
+	   	buffer[0x12]);
+	   return FALSE;
+	}
+
+	monitor->feature = buffer[0x18];
+
+	if(!buffer[0x14] & 0x80) {
+	   if(!(buffer[0x14] & 0x08)) {
+	      printk(KERN_INFO "sisfb: WARNING: Monitor does not support separate syncs\n");
+	   }
+	}
+
+	if(buffer[0x13] >= 0x01) {
+	   /* EDID V1 rev 1 and 2: Search for monitor descriptor
+	    * to extract ranges
+	    */
+	    j = 0x36;
+	    for(i=0; i<4; i++) {
+	       if(buffer[j]     == 0x00 && buffer[j + 1] == 0x00 &&
+	          buffer[j + 2] == 0x00 && buffer[j + 3] == 0xfd &&
+		  buffer[j + 4] == 0x00) {
+		  monitor->hmin = buffer[j + 7];
+		  monitor->hmax = buffer[j + 8];
+		  monitor->vmin = buffer[j + 5];
+		  monitor->vmax = buffer[j + 6];
+		  monitor->dclockmax = buffer[j + 9] * 10 * 1000;
+		  monitor->datavalid = TRUE;
+		  break;
+	       }
+	       j += 18;
+	    }
+	}
+
+	if(!monitor->datavalid) {
+	   /* Otherwise: Get a range from the list of supported
+	    * Estabished Timings. This is not entirely accurate,
+	    * because fixed frequency monitors are not supported
+	    * that way.
+	    */
+	   monitor->hmin = 65535; monitor->hmax = 0;
+	   monitor->vmin = 65535; monitor->vmax = 0;
+	   monitor->dclockmax = 0;
+	   emodes = buffer[0x23] | (buffer[0x24] << 8) | (buffer[0x25] << 16);
+	   for(i = 0; i < 13; i++) {
+	      if(emodes & sisfb_ddcsmodes[i].mask) {
+	         if(monitor->hmin > sisfb_ddcsmodes[i].h) monitor->hmin = sisfb_ddcsmodes[i].h;
+		 if(monitor->hmax < sisfb_ddcsmodes[i].h) monitor->hmax = sisfb_ddcsmodes[i].h + 1;
+		 if(monitor->vmin > sisfb_ddcsmodes[i].v) monitor->vmin = sisfb_ddcsmodes[i].v;
+		 if(monitor->vmax < sisfb_ddcsmodes[i].v) monitor->vmax = sisfb_ddcsmodes[i].v;
+		 if(monitor->dclockmax < sisfb_ddcsmodes[i].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
+	      }
+	   }
+	   index = 0x26;
+	   for(i = 0; i < 8; i++) {
+	      xres = (buffer[index] + 31) * 8;
+	      switch(buffer[index + 1] & 0xc0) {
+	         case 0xc0: yres = (xres * 9) / 16; break;
+	         case 0x80: yres = (xres * 4) /  5; break;
+	         case 0x40: yres = (xres * 3) /  4; break;
+	         default:   yres = xres;	    break;
+	      }
+	      refresh = (buffer[index + 1] & 0x3f) + 60;
+	      if((xres >= 640) && (yres >= 480)) {
+                 for(j = 0; j < 8; j++) {
+	            if((xres == sisfb_ddcfmodes[j].x) &&
+	               (yres == sisfb_ddcfmodes[j].y) &&
+		       (refresh == sisfb_ddcfmodes[j].v)) {
+		      if(monitor->hmin > sisfb_ddcfmodes[j].h) monitor->hmin = sisfb_ddcfmodes[j].h;
+		      if(monitor->hmax < sisfb_ddcfmodes[j].h) monitor->hmax = sisfb_ddcfmodes[j].h + 1;
+		      if(monitor->vmin > sisfb_ddcsmodes[j].v) monitor->vmin = sisfb_ddcsmodes[j].v;
+		      if(monitor->vmax < sisfb_ddcsmodes[j].v) monitor->vmax = sisfb_ddcsmodes[j].v;
+		      if(monitor->dclockmax < sisfb_ddcsmodes[j].d) monitor->dclockmax = sisfb_ddcsmodes[i].d;
+	            }
+	         }
+	      }
+	      index += 2;
+           }
+	   if((monitor->hmin <= monitor->hmax) && (monitor->vmin <= monitor->vmax)) {
+	      monitor->datavalid = TRUE;
+	   }
+	}
+
+ 	return(monitor->datavalid);
+}
+
+static void sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno)
+{
+	USHORT  temp, i, realcrtno = crtno;
+   	u8      buffer[256];
+
+	monitor->datavalid = FALSE;
+
+	if(crtno) {
+       	   if(ivideo.vbflags & CRT2_LCD)      realcrtno = 1;
+      	   else if(ivideo.vbflags & CRT2_VGA) realcrtno = 2;
+      	   else return;
+   	}
+
+	if((sisfb_crt1off) && (!crtno)) return;
+
+    	temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, realcrtno, 0, &buffer[0]);
+   	if((!temp) || (temp == 0xffff)) {
+      	   printk(KERN_INFO "sisfb: CRT%d DDC probing failed\n", crtno + 1);
+	   return;
+   	} else {
+      	   printk(KERN_INFO "sisfb: CRT%d DDC supported\n", crtno + 1);
+      	   printk(KERN_INFO "sisfb: CRT%d DDC level: %s%s%s%s\n",
+	   	crtno + 1,
+	   	(temp & 0x1a) ? "" : "[none of the supported]",
+	   	(temp & 0x02) ? "2 " : "",
+	   	(temp & 0x08) ? "D&P" : "",
+           	(temp & 0x10) ? "FPDI-2" : "");
+      	   if(temp & 0x02) {
+	      i = 3;  /* Number of retrys */
+	      do {
+	    	 temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine,
+				     realcrtno, 1, &buffer[0]);
+	      } while((temp) && i--);
+              if(!temp) {
+	    	 if(sisfb_interpret_edid(monitor, &buffer[0])) {
+		    printk(KERN_INFO "sisfb: Monitor range H %d-%dKHz, V %d-%dHz, Max. dotclock %dMHz\n",
+		    	monitor->hmin, monitor->hmax, monitor->vmin, monitor->vmax,
+			monitor->dclockmax / 1000);
+		 } else {
+	       	    printk(KERN_INFO "sisfb: CRT%d DDC EDID corrupt\n", crtno + 1);
+	    	 }
+	      } else {
+            	 printk(KERN_INFO "sisfb: CRT%d DDC reading failed\n", crtno + 1);
+	      }
+	   } else {
+	      printk(KERN_INFO "sisfb: VESA D&P and FPDI-2 not supported yet\n");
+	   }
 	}
-	if(!j) printk(KERN_INFO "sisfb: Invalid mode '%s'\n", name);
 }
 
-static void sisfb_search_vesamode(unsigned int vesamode)
+static void sisfb_search_vesamode(unsigned int vesamode, BOOLEAN quiet)
 {
 	int i = 0, j = 0;
 
 	if(vesamode == 0) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		sisfb_mode_idx = MODE_INDEX_NONE;
 #else
-		printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+		if(!quiet)
+		   printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
 		sisfb_mode_idx = DEFAULT_MODE;
-#endif		
+#endif
 		return;
 	}
 
 	vesamode &= 0x1dff;  /* Clean VESA mode number from other flags */
 
+	while(sisbios_mode[i++].mode_no != 0) {
+		if( (sisbios_mode[i-1].vesa_mode_no_1 == vesamode) ||
+		    (sisbios_mode[i-1].vesa_mode_no_2 == vesamode) ) {
+		    if(sisfb_fstn) {
+		       if(sisbios_mode[i-1].mode_no == 0x50 ||
+		          sisbios_mode[i-1].mode_no == 0x56 ||
+		          sisbios_mode[i-1].mode_no == 0x53) continue;
+	            } else {
+		       if(sisbios_mode[i-1].mode_no == 0x5a ||
+		          sisbios_mode[i-1].mode_no == 0x5b) continue;
+		    }
+		    sisfb_mode_idx = i - 1;
+		    j = 1;
+		    break;
+		}
+	}
+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+}
+
+static void sisfb_search_mode(char *name, BOOLEAN quiet)
+{
+	int i = 0;
+	unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0;
+	char strbuf[16], strbuf1[20];
+	char *nameptr = name;
+
+	if(name == NULL) {
+	   if(!quiet)
+	      printk(KERN_ERR "sisfb: Internal error, using default mode.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+        if (!strnicmp(name, sisbios_mode[MODE_INDEX_NONE].name, strlen(name))) {
+	   if(!quiet)
+	      printk(KERN_ERR "sisfb: Mode 'none' not supported anymore. Using default.\n");
+	   sisfb_mode_idx = DEFAULT_MODE;
+	   return;
+	}
+#endif
+	if(strlen(name) <= 19) {
+	   strcpy(strbuf1, name);
+	   for(i=0; i<strlen(strbuf1); i++) {
+	      if(strbuf1[i] < '0' || strbuf1[i] > '9') strbuf1[i] = ' ';
+	   }
+
+	   /* This does some fuzzy mode naming detection */
+	   if(sscanf(strbuf1, "%u %u %u %u", &xres, &yres, &depth, &rate) == 4) {
+	      if((rate <= 32) || (depth > 32)) {
+	         j = rate; rate = depth; depth = j;
+	      }
+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+	      nameptr = strbuf;
+	      ivideo.refresh_rate = sisfb_parm_rate = rate;
+	   } else if(sscanf(strbuf1, "%u %u %u", &xres, &yres, &depth) == 3) {
+	      sprintf(strbuf, "%ux%ux%u", xres, yres, depth);
+	      nameptr = strbuf;
+	   } else {
+	      xres = 0;
+	      if((sscanf(strbuf1, "%u %u", &xres, &yres) == 2) && (xres != 0)) {
+	         sprintf(strbuf, "%ux%ux8", xres, yres);
+	         nameptr = strbuf;
+	      } else {
+	         sisfb_search_vesamode(simple_strtoul(name, NULL, 0), quiet);
+	         return;
+	      }
+	   }
+	}
+
+	i = 0; j = 0;
 	while(sisbios_mode[i].mode_no != 0) {
-		if( (sisbios_mode[i].vesa_mode_no_1 == vesamode) ||
-		    (sisbios_mode[i].vesa_mode_no_2 == vesamode) ) {
-			sisfb_mode_idx = i;
-			j = 1;
-			break;
+		if(!strnicmp(nameptr, sisbios_mode[i++].name, strlen(nameptr))) {
+		   if(sisfb_fstn) {
+		      if(sisbios_mode[i-1].mode_no == 0x50 ||
+		         sisbios_mode[i-1].mode_no == 0x56 ||
+		         sisbios_mode[i-1].mode_no == 0x53) continue;
+	           } else {
+		      if(sisbios_mode[i-1].mode_no == 0x5a ||
+		         sisbios_mode[i-1].mode_no == 0x5b) continue;
+		   }
+		   sisfb_mode_idx = i - 1;
+		   j = 1;
+		   break;
 		}
-		i++;
 	}
-	if(!j) printk(KERN_INFO "sisfb: Invalid VESA mode 0x%x'\n", vesamode);
+	if((!j) && !quiet) printk(KERN_ERR "sisfb: Invalid mode '%s'\n", nameptr);
+
 }
 
-static int sisfb_validate_mode(int myindex)
+static int sisfb_validate_mode(int myindex, unsigned long vbflags)
 {
-   u16 xres, yres;
+   u16 xres, yres, myres;
 
 #ifdef CONFIG_FB_SIS_300
    if(sisvga_engine == SIS_300_VGA) {
@@ -283,8 +537,10 @@
    }
 #endif
 
-   switch (ivideo.disp_state & DISPTYPE_DISP2) {
-     case DISPTYPE_LCD:
+   myres = sisbios_mode[myindex].yres;
+
+   switch (vbflags & VB_DISPTYPE_DISP2) {
+     case CRT2_LCD:
 	switch (sishw_ext.ulCRT2LCDType) {
 	case LCD_640x480:
 		xres =  640; yres =  480;  break;
@@ -306,140 +562,208 @@
 		xres = 1400; yres = 1050;  break;		
 	case LCD_1600x1200:
 		xres = 1600; yres = 1200;  break;
-	case LCD_320x480:				/* TW: FSTN */
+	case LCD_320x480:				/* FSTN (old) */
 		xres =  320; yres =  480;  break;
+	case LCD_640x480_2:				/* FSTN (new) */
+	case LCD_640x480_3:
+		xres =  640; yres =  480;  break;
 	default:
 	        xres =    0; yres =    0;  break;
 	}
-	if(sisbios_mode[myindex].xres > xres) {
-	        return(-1);
+
+	if(SiS_Pr.SiS_CustomT == CUT_BARCO1366) {
+	   	xres = 1360; yres = 1024;
 	}
-        if(sisbios_mode[myindex].yres > yres) {
+
+	if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+	   	xres = 848;  yres =  480;
+	} else {
+	   if(sisbios_mode[myindex].xres > xres) {
+	        return(-1);
+	   }
+           if(myres > yres) {
 	        return(-1);
+	   }
 	}
-	if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
-           (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
-	   (sishw_ext.Is301BDH)) {		   /* 301B-DH */
+
+	if(vbflags & (VB_LVDS | VB_30xBDH)) {
 	   switch (sisbios_mode[myindex].xres) {
+	   	case 320:
+			if((myres != 200) && (myres != 240))
+		          	return(-1);
+			if((myres == 240) || (myres == 480)) {
+			   	if(!sisfb_fstn) {
+				   if(sisbios_mode[myindex].mode_no == 0x5a ||
+				      sisbios_mode[myindex].mode_no == 0x5b)
+					return(-1);
+			        } else {
+				   if(sisbios_mode[myindex].mode_no == 0x50 ||
+				      sisbios_mode[myindex].mode_no == 0x56 ||
+				      sisbios_mode[myindex].mode_no == 0x53)
+					return(-1);
+				}
+			}
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+			break;
+		case 400:
+	       		if(myres != 300) return(-1);
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+	       		break;
 	   	case 512:
-	       		if(sisbios_mode[myindex].yres != 512) return -1;
-			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return -1;
+	       		if(myres != 384) return(-1);
+			if(sishw_ext.ulCRT2LCDType == LCD_1024x600) return(-1);
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
 	       		break;
 	   	case 640:
-		       	if((sisbios_mode[myindex].yres != 400) &&
-	           	   (sisbios_mode[myindex].yres != 480))
+		       	if((myres != 400) && (myres != 480))
 		          	return -1;
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) {
+			   if(myres == 400)
+			 	return(-1);
+			}
 	       		break;
 	   	case 800:
-		       	if(sisbios_mode[myindex].yres != 600) return -1;
+		       	if(myres != 600) return(-1);
+	       		break;
+		case 848:
+		        if(SiS_Pr.SiS_CustomT != CUT_PANEL848) return(-1);
+		       	if(myres != 480) return(-1);
 	       		break;
 	   	case 1024:
-		       	if((sisbios_mode[myindex].yres != 600) &&
-	           	   (sisbios_mode[myindex].yres != 768))
-		          	return -1;
-			if((sisbios_mode[myindex].yres == 600) &&
+		       	if((myres != 600) && (myres != 768))
+		          	return(-1);
+			if((myres == 600) &&
 			   (sishw_ext.ulCRT2LCDType != LCD_1024x600))
-			   	return -1;
+			   	return(-1);
 			break;
 		case 1152:
-			if((sisbios_mode[myindex].yres) != 768) return -1;
-			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return -1;
+			if(myres != 768) return(-1);
+			if(sishw_ext.ulCRT2LCDType != LCD_1152x768) return(-1);
 			break;
 	   	case 1280:
-		   	if((sisbios_mode[myindex].yres != 768) &&
-	           	   (sisbios_mode[myindex].yres != 1024))
-		          	return -1;
-			if((sisbios_mode[myindex].yres == 768) &&
+		   	if((myres != 768) && (myres != 1024))
+		          	return(-1);
+			if((myres == 768) &&
 			   (sishw_ext.ulCRT2LCDType != LCD_1280x768))
-			   	return -1;				
+			   	return(-1);
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
+			break;
+		case 1360:
+			if(SiS_Pr.SiS_CustomT != CUT_BARCO1366) return(-1);
+			if(myres != 1024) return(-1);
 			break;
 	   	case 1400:
-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+		   	if(myres != 1050) return(-1);
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
 			break;
 	   	case 1600:
-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+		   	if(myres != 1200) return(-1);
+			if(SiS_Pr.SiS_CustomT == CUT_PANEL848) return(-1);
 			break;
 	   	default:
-		        return -1;		
+		        return(-1);
 	   }
 	} else {
 	   switch (sisbios_mode[myindex].xres) {
+	   	case 320:
+			if((myres != 200) && (myres != 240))
+		          	return -1;
+			break;
+		case 400:
+	       		if(myres != 300) return(-1);
+	       		break;
 	   	case 512:
-	       		if(sisbios_mode[myindex].yres != 512) return -1;
+	       		if(myres != 384) return(-1);
 	       		break;
 	   	case 640:
-		       	if((sisbios_mode[myindex].yres != 400) &&
-	           	   (sisbios_mode[myindex].yres != 480))
-		          	return -1;
+		       	if((myres != 400) && (myres != 480))
+		          	return(-1);
 	       		break;
 	   	case 800:
-		       	if(sisbios_mode[myindex].yres != 600) return -1;
+		       	if(myres != 600) return(-1);
 	       		break;
 	   	case 1024:
-		       	if(sisbios_mode[myindex].yres != 768) return -1;
+		       	if(myres != 768) return(-1);
 			break;
 	   	case 1280:
-		   	if((sisbios_mode[myindex].yres != 960) &&
-	           	   (sisbios_mode[myindex].yres != 1024))
-		          	return -1;
-			if(sisbios_mode[myindex].yres == 960) {
-			    if(sishw_ext.ulCRT2LCDType == LCD_1400x1050) 
-			   	return -1;
+		   	if((myres != 960) && (myres != 768) && (myres != 1024))
+		          	return(-1);
+			if((myres == 768) || (myres == 960)) {
+			    	if(sishw_ext.ulCRT2LCDType == LCD_1400x1050)
+			   		return(-1);
+			}
+			if(myres == 768) {
+			    	if(sishw_ext.ulCRT2LCDType == LCD_1280x960)
+			   		return(-1);
 			}
 			break;
 	   	case 1400:
-		   	if(sisbios_mode[myindex].yres != 1050) return -1;
+		   	if(myres != 1050) return(-1);
 			break;
 	   	case 1600:
-		   	if(sisbios_mode[myindex].yres != 1200) return -1;
+		   	if(myres != 1200) return(-1);
 			break;
 	   	default:
-		        return -1;		
+		        return(-1);
 	   }
 	}
 	break;
-     case DISPTYPE_TV:
+
+     case CRT2_TV:
 	switch (sisbios_mode[myindex].xres) {
+	case 320:
+		if(vbflags & VB_CHRONTEL) return(-1);
+		if((myres != 200) && (myres != 240))
+		       	return(-1);
+		break;
+	case 400:
+		if(vbflags & VB_CHRONTEL) return(-1);
+		if(myres != 300) return(-1);
+		break;
 	case 512:
+		if((vbflags & VB_CHRONTEL) && (ivideo.chip < SIS_315H))
+			return(-1);
+		if((vbflags & VB_SISBRIDGE) && (vbflags & TV_NTSC))
+		   	return(-1);
+		if(myres != 384) return(-1);
+		break;
 	case 640:
-	case 800:
+		if((myres != 400) && (myres != 480))
+		       	return(-1);
 		break;
 	case 720:
-		if (ivideo.TV_type == TVMODE_NTSC) {
-			if (sisbios_mode[myindex].yres != 480) {
-				return(-1);
-			}
-		} else if (ivideo.TV_type == TVMODE_PAL) {
-			if (sisbios_mode[myindex].yres != 576) {
-				return(-1);
-			}
-		}
-		/* TW: LVDS/CHRONTEL does not support 720 */
-		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
-					ivideo.hasVB == HASVB_CHRONTEL) {
-				return(-1);
-		}
+		if(vbflags & VB_CHRONTEL) return(-1);
+		if((vbflags & TV_NTSC) && (myres != 480))
+			return(-1);
+		if((vbflags & TV_PAL) && (myres != 576))
+			return(-1);
+		break;
+	case 768:
+		if(vbflags & VB_CHRONTEL) return(-1);
+		if(!(vbflags & TV_PAL)) return(-1);
+		if(myres != 576) return(-1);
+		break;
+	case 800:
+		if(myres != 600) return(-1);
 		break;
 	case 1024:
-		if (ivideo.TV_type == TVMODE_NTSC) {
-			if(sisbios_mode[myindex].bpp == 32) {
-			       return(-1);
-			}
-		}
-		/* TW: LVDS/CHRONTEL only supports < 800 (1024 on 650/Ch7019)*/
-		if (ivideo.hasVB == HASVB_LVDS_CHRONTEL ||
-					ivideo.hasVB == HASVB_CHRONTEL) {
-		    if(ivideo.chip < SIS_315H) {
+		if(vbflags & VB_301) return(-1);
+		if(vbflags & VB_CHRONTEL) {
+		    	if(ivideo.chip < SIS_315H) {
 				return(-1);
-		    }
+		    	}
 		}
 		break;
 	default:
 		return(-1);
 	}
 	break;
-     case DISPTYPE_CRT2:	
-        if(sisbios_mode[myindex].xres > 1280) return -1;
+
+     case CRT2_VGA:
+        if(sisbios_mode[myindex].xres > 1600) return(-1);
+	if(!(vbflags & (VB_301B|VB_301C|VB_302B))) {
+	   if(sisbios_mode[myindex].xres > 1400) return(-1);
+	}
 	break;	
      }
      return(myindex);
@@ -453,15 +777,20 @@
 		return;
 
 	while(sis_crt2type[i].type_no != -1) {
-		if (!strcmp(name, sis_crt2type[i].name)) {
+		if (!strnicmp(name, sis_crt2type[i].name, strlen(sis_crt2type[i].name))) {
 			sisfb_crt2type = sis_crt2type[i].type_no;
 			sisfb_tvplug = sis_crt2type[i].tvplug_no;
+			sisfb_dstn = (sis_crt2type[i].flags & FL_550_DSTN) ? 1 : 0;
+			sisfb_fstn = (sis_crt2type[i].flags & FL_550_FSTN) ? 1 : 0;
 			break;
 		}
 		i++;
 	}
 	if(sisfb_crt2type < 0)
-		printk(KERN_INFO "sisfb: Invalid CRT2 type: %s\n", name);
+		printk(KERN_ERR "sisfb: Invalid CRT2 type: %s\n", name);
+        if(ivideo.chip != SIS_550) {
+	   sisfb_dstn = sisfb_fstn = 0;
+	}
 }
 
 static void sisfb_search_queuemode(const char *name)
@@ -472,23 +801,23 @@
 		return;
 
 	while (sis_queuemode[i].type_no != -1) {
-		if (!strcmp(name, sis_queuemode[i].name)) {
+		if (!strnicmp(name, sis_queuemode[i].name, strlen(sis_queuemode[i].name))) {
 			sisfb_queuemode = sis_queuemode[i].type_no;
 			break;
 		}
 		i++;
 	}
 	if (sisfb_queuemode < 0)
-		printk(KERN_INFO "sisfb: Invalid queuemode type: %s\n", name);
+		printk(KERN_ERR "sisfb: Invalid queuemode type: %s\n", name);
 }
 
-static u8 sisfb_search_refresh_rate(unsigned int rate)
+static u8 sisfb_search_refresh_rate(unsigned int rate, int mode_idx)
 {
 	u16 xres, yres;
 	int i = 0;
 
-	xres = sisbios_mode[sisfb_mode_idx].xres;
-	yres = sisbios_mode[sisfb_mode_idx].yres;
+	xres = sisbios_mode[mode_idx].xres;
+	yres = sisbios_mode[mode_idx].yres;
 
 	sisfb_rate_idx = 0;
 	while ((sisfb_vrate[i].idx != 0) && (sisfb_vrate[i].xres <= xres)) {
@@ -536,45 +865,100 @@
 		return;
 
 	while (sis_tvtype[i].type_no != -1) {
-		if (!strcmp(name, sis_tvtype[i].name)) {
-			sisfb_tvmode = sis_tvtype[i].type_no;
+		if (!strnicmp(name, sis_tvtype[i].name, strlen(sis_tvtype[i].name))) {
+			ivideo.vbflags |= sis_tvtype[i].type_no;
 			break;
 		}
 		i++;
 	}
 }
 
+static void sisfb_search_specialtiming(const char *name)
+{
+	int i = 0;
+	BOOLEAN found = FALSE;
+
+	if(name == NULL)
+		return;
+
+	if(!strnicmp(name, "none", 4)) {
+	        SiS_Pr.SiS_CustomT = CUT_FORCENONE;
+		printk(KERN_DEBUG "sisfb: Special timing disabled\n");
+	} else {
+	   while(mycustomttable[i].chipID != 0) {
+	      if(!strnicmp(name,mycustomttable[i].optionName, strlen(mycustomttable[i].optionName))) {
+		 SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+		 found = TRUE;
+		 printk(KERN_INFO "sisfb: Special timing for %s %s forced\n",
+		 mycustomttable[i].vendorName, mycustomttable[i].cardName);
+		 break;
+	      }
+	      i++;
+	   }
+	   if(!found) {
+	      printk(KERN_WARNING "sisfb: Invalid SpecialTiming parameter, valid are:");
+	      printk(KERN_WARNING "\t\"none\" (to disable special timings)\n");
+	      i = 0;
+	      while(mycustomttable[i].chipID != 0) {
+		 printk(KERN_WARNING "\t\"%s\" (for %s %s)\n",
+		     mycustomttable[i].optionName,
+		     mycustomttable[i].vendorName,
+		     mycustomttable[i].cardName);
+		 i++;
+	      }
+           }
+ 	}
+}
+
 static BOOLEAN sisfb_bridgeisslave(void)
 {
-   unsigned char usScratchP1_00;
+   unsigned char P1_00;
 
-   if(ivideo.hasVB == HASVB_NONE) return FALSE;
+   if(!(ivideo.vbflags & VB_VIDEOBRIDGE)) return FALSE;
 
-   inSISIDXREG(SISPART1,0x00,usScratchP1_00);
-   if( ((sisvga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) ||
-       ((sisvga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10) ) {
+   inSISIDXREG(SISPART1,0x00,P1_00);
+   if( ((sisvga_engine == SIS_300_VGA) && (P1_00 & 0xa0) == 0x20) ||
+       ((sisvga_engine == SIS_315_VGA) && (P1_00 & 0x50) == 0x10) ) {
 	   return TRUE;
    } else {
            return FALSE;
    }
 }
 
-static BOOLEAN sisfbcheckvretracecrt1(void)
+static BOOLEAN sisfballowretracecrt1(void)
 {
    unsigned char temp;
 
    inSISIDXREG(SISCR,0x17,temp);
    if(!(temp & 0x80)) return FALSE;
-   
-   if(sisvga_engine == SIS_315_VGA) {
-      inSISIDXREG(SISSR,0x1f,temp);
-      if(temp & 0xc0) return FALSE;
-   }
+
+   inSISIDXREG(SISSR,0x1f,temp);
+   if(temp & 0xc0) return FALSE;
+
+   return TRUE;
+}
+
+static BOOLEAN sisfbcheckvretracecrt1(void)
+{
+
+   if(!sisfballowretracecrt1()) return FALSE;
 
    if(inSISREG(SISINPSTAT) & 0x08) return TRUE;
    else 			   return FALSE;
 }
 
+static void sisfbwaitretracecrt1(void)
+{
+   int watchdog;
+
+   if(!sisfballowretracecrt1()) return;
+
+   watchdog = 65536;
+   while((!(inSISREG(SISINPSTAT) & 0x08)) && --watchdog);
+   watchdog = 65536;
+   while((inSISREG(SISINPSTAT) & 0x08) && --watchdog);
+}
+
 static BOOLEAN sisfbcheckvretracecrt2(void)
 {
    unsigned char temp, reg;
@@ -595,9 +979,9 @@
    else 	   return TRUE;
 }
 
-static BOOLEAN sisfb_CheckVBRetrace(void) 
+static BOOLEAN sisfb_CheckVBRetrace(void)
 {
-   if(ivideo.disp_state & DISPTYPE_DISP2) {
+   if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
       if(sisfb_bridgeisslave()) {
          return(sisfbcheckvretracecrt1());
       } else {
@@ -607,60 +991,195 @@
    return(sisfbcheckvretracecrt1());
 }
 
+static int sisfb_myblank(int blank)
+{
+   u8 sr01, sr11, sr1f, cr63=0, p2_0, p1_13;
+   BOOLEAN backlight = TRUE;
+
+   switch(blank) {
+   case 0:	/* on */
+      sr01  = 0x00;
+      sr11  = 0x00;
+      sr1f  = 0x00;
+      cr63  = 0x00;
+      p2_0  = 0x20;
+      p1_13 = 0x00;
+      backlight = TRUE;
+      break;
+   case 1:	/* blank */
+      sr01  = 0x20;
+      sr11  = 0x00;
+      sr1f  = 0x00;
+      cr63  = 0x00;
+      p2_0  = 0x20;
+      p1_13 = 0x00;
+      backlight = TRUE;
+      break;
+   case 2:	/* no vsync */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0x80;
+      cr63  = 0x40;
+      p2_0  = 0x40;
+      p1_13 = 0x80;
+      backlight = FALSE;
+      break;
+   case 3:	/* no hsync */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0x40;
+      cr63  = 0x40;
+      p2_0  = 0x80;
+      p1_13 = 0x40;
+      backlight = FALSE;
+      break;
+   case 4:	/* off */
+      sr01  = 0x20;
+      sr11  = 0x08;
+      sr1f  = 0xc0;
+      cr63  = 0x40;
+      p2_0  = 0xc0;
+      p1_13 = 0xc0;
+      backlight = FALSE;
+      break;
+   default:
+      return 1;
+   }
+
+   if(ivideo.currentvbflags & VB_DISPTYPE_CRT1) {
+
+      setSISIDXREG(SISSR, 0x01, ~0x20, sr01);
+
+      if( (!sisfb_thismonitor.datavalid) ||
+          ((sisfb_thismonitor.datavalid) &&
+           (sisfb_thismonitor.feature & 0xe0))) {
+
+	 if(sisvga_engine == SIS_315_VGA) {
+	    setSISIDXREG(SISCR, 0x63, 0xbf, cr63);
+	 }
+
+	 setSISIDXREG(SISSR, 0x1f, 0x3f, sr1f);
+      }
+
+   }
+
+   if(ivideo.currentvbflags & CRT2_LCD) {
+
+      if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+	 if(backlight) {
+	    SiS_SiS30xBLOn(&SiS_Pr, &sishw_ext);
+	 } else {
+	    SiS_SiS30xBLOff(&SiS_Pr, &sishw_ext);
+	 }
+      } else if(sisvga_engine == SIS_315_VGA) {
+	 if(ivideo.vbflags & VB_CHRONTEL) {
+	    if(backlight) {
+	       SiS_Chrontel701xBLOn(&SiS_Pr,&sishw_ext);
+	    } else {
+	       SiS_Chrontel701xBLOff(&SiS_Pr);
+	    }
+	 }
+      }
+
+      if(((sisvga_engine == SIS_300_VGA) &&
+          (ivideo.vbflags & (VB_301|VB_30xBDH|VB_LVDS))) ||
+         ((sisvga_engine == SIS_315_VGA) &&
+          ((ivideo.vbflags & (VB_LVDS | VB_CHRONTEL)) == VB_LVDS))) {
+          setSISIDXREG(SISSR, 0x11, ~0x0c, sr11);
+      }
+
+      if(sisvga_engine == SIS_300_VGA) {
+         if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
+            (!(ivideo.vbflags & VB_30xBDH))) {
+	    setSISIDXREG(SISPART1, 0x13, 0x3f, p1_13);
+	 }
+      } else if(sisvga_engine == SIS_315_VGA) {
+         if((ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) &&
+            (!(ivideo.vbflags & VB_30xBDH))) {
+	    setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+	 }
+      }
+
+   } else if(ivideo.currentvbflags & CRT2_VGA) {
+
+      if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) {
+         setSISIDXREG(SISPART2, 0x00, 0x1f, p2_0);
+      }
+
+   }
+
+   return(0);
+}
+
 /* ----------- FBDev related routines for all series ----------- */
 
+static void sisfb_set_vparms(void)
+{
+   switch(ivideo.video_bpp) {
+   case 8:
+       	ivideo.DstColor = 0x0000;
+	ivideo.SiS310_AccelDepth = 0x00000000;
+	ivideo.video_cmap_len = 256;
+       	break;
+   case 16:
+       	ivideo.DstColor = 0x8000;
+       	ivideo.SiS310_AccelDepth = 0x00010000;
+	ivideo.video_cmap_len = 16;
+       	break;
+   case 32:
+       	ivideo.DstColor = 0xC000;
+	ivideo.SiS310_AccelDepth = 0x00020000;
+	ivideo.video_cmap_len = 16;
+       	break;
+   default:
+ 	ivideo.video_cmap_len = 16;
+	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
+	ivideo.accel = 0;
+	break;
+   }
+}
+
 static int sisfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		      struct fb_info *info)
 {
-	unsigned int htotal =
-		var->left_margin + var->xres + var->right_margin +
-		var->hsync_len;
-	unsigned int vtotal = 0; 
-	double drate = 0, hrate = 0;
+	unsigned int htotal = 0, vtotal = 0;
+	unsigned int drate = 0, hrate = 0;
 	int found_mode = 0;
 	int old_mode;
-	unsigned char reg;
+	u32 pixclock;
 
-	TWDEBUG("Inside do_set_var");
-	
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-	inSISIDXREG(SISCR,0x34,reg);
-	if(reg & 0x80) {
-	   printk(KERN_INFO "sisfb: Cannot change display mode, X server is active\n");
-	   return -EBUSY;
-	}
-#endif	
+	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
+
+	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
+
+	pixclock = var->pixclock;
 
 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
-		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;
+		vtotal += var->yres;
 		vtotal <<= 1;
 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;
+		vtotal += var->yres;
 		vtotal <<= 2;
 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
-		         var->vsync_len; 
-	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;
+		vtotal += var->yres;
+		vtotal <<= 1;
+	} else 	vtotal += var->yres;
 
 	if(!(htotal) || !(vtotal)) {
 		DPRINTK("sisfb: Invalid 'var' information\n");
 		return -EINVAL;
 	}
 
-	if(var->pixclock && htotal && vtotal) {
-	   drate = 1E12 / var->pixclock;
-	   hrate = drate / htotal;
-	   ivideo.refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
+	if(pixclock && htotal && vtotal) {
+	   drate = 1000000000 / pixclock;
+	   hrate = (drate * 1000) / htotal;
+	   ivideo.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
 	} else ivideo.refresh_rate = 60;
 
-	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
-	if((var->xres == 1024) && (var->yres == 600)) ivideo.refresh_rate = 60;
-
+#if 0
 	printk(KERN_DEBUG "sisfb: Change mode to %dx%dx%d-%dHz\n",
 		var->xres,var->yres,var->bits_per_pixel,ivideo.refresh_rate);
+#endif
 
 	old_mode = sisfb_mode_idx;
 	sisfb_mode_idx = 0;
@@ -678,7 +1197,7 @@
 	}
 
 	if(found_mode)
-		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
+		sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
 	else
 		sisfb_mode_idx = -1;
 
@@ -689,12 +1208,21 @@
 		return -EINVAL;
 	}
 
-	if(sisfb_search_refresh_rate(ivideo.refresh_rate) == 0) {
+	if(sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx) == 0) {
 		sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
 		ivideo.refresh_rate = 60;
 	}
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	if(sisfb_thismonitor.datavalid) {
+	   if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
+	                         sisfb_rate_idx, ivideo.refresh_rate)) {
+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+	   }
+	}
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	if(((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) && isactive) {
 #else
 	if(isactive) {
@@ -707,15 +1235,7 @@
 		}
 
 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
-		sisfb_post_setmode();
-
-		DPRINTK("sisfb: Set new mode: %dx%dx%d-%d \n",
-			sisbios_mode[sisfb_mode_idx].xres,
-			sisbios_mode[sisfb_mode_idx].yres,
-			sisbios_mode[sisfb_mode_idx].bpp,
-			ivideo.refresh_rate);
-
+
 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
@@ -725,54 +1245,39 @@
 		if(sisfb_accel) {
 		   ivideo.accel = (var->accel_flags & FB_ACCELF_TEXT) ? -1 : 0;
 		}
-		switch(ivideo.video_bpp) {
-        	case 8:
-            		ivideo.DstColor = 0x0000;
-	    		ivideo.SiS310_AccelDepth = 0x00000000;
-			ivideo.video_cmap_len = 256;
-            		break;
-        	case 16:
-            		ivideo.DstColor = 0x8000;
-            		ivideo.SiS310_AccelDepth = 0x00010000;
-			ivideo.video_cmap_len = 16;
-            		break;
-        	case 32:
-            		ivideo.DstColor = 0xC000;
-	    		ivideo.SiS310_AccelDepth = 0x00020000;
-			ivideo.video_cmap_len = 16;
-            		break;
-		default:
-			ivideo.video_cmap_len = 16;
-		        printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
-			ivideo.accel = 0;
-			break;
-    		}
+
+		sisfb_set_vparms();
+
+		ivideo.current_width = ivideo.video_width;
+		ivideo.current_height = ivideo.video_height;
+		ivideo.current_bpp = ivideo.video_bpp;
+		ivideo.current_htotal = htotal;
+		ivideo.current_vtotal = vtotal;
+		ivideo.current_pixclock = var->pixclock;
+		ivideo.current_refresh_rate = ivideo.refresh_rate;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+                sisfb_lastrates[sisfb_mode_no] = ivideo.refresh_rate;
+#endif
+
+		sisfb_post_setmode();
 
 	}
-	TWDEBUG("End of do_set_var");
 	return 0;
 }
 
-#ifdef SISFB_PAN
 static int sisfb_pan_var(struct fb_var_screeninfo *var)
 {
 	unsigned int base;
 
-	TWDEBUG("Inside pan_var");
-	
 	if (var->xoffset > (var->xres_virtual - var->xres)) {
-	        printk(KERN_INFO "Pan: xo: %d xv %d xr %d\n",
-			var->xoffset, var->xres_virtual, var->xres);
 		return -EINVAL;
 	}
 	if(var->yoffset > (var->yres_virtual - var->yres)) {
-		printk(KERN_INFO "Pan: yo: %d yv %d yr %d\n",
-			var->yoffset, var->yres_virtual, var->yres);
 		return -EINVAL;
-	}
-
-        base = var->yoffset * var->xres_virtual + var->xoffset;
-
+	}
+
+	base = var->yoffset * var->xres_virtual + var->xoffset;
+
         /* calculate base bpp dep. */
         switch(var->bits_per_pixel) {
         case 16:
@@ -794,7 +1299,7 @@
 	if(sisvga_engine == SIS_315_VGA) {
 		setSISIDXREG(SISSR, 0x37, 0xFE, (base >> 24) & 0x01);
 	}
-        if(ivideo.disp_state & DISPTYPE_DISP2) {
+        if(ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
         	outSISIDXREG(SISPART1, 0x06, (base & 0xFF));
         	outSISIDXREG(SISPART1, 0x05, ((base >> 8) & 0xFF));
@@ -803,10 +1308,8 @@
 			setSISIDXREG(SISPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
 		}
         }
-	TWDEBUG("End of pan_var");
 	return 0;
 }
-#endif
 
 static void sisfb_bpp_to_var(struct fb_var_screeninfo *var)
 {
@@ -843,22 +1346,24 @@
 
 void sis_dispinfo(struct ap_data *rec)
 {
-	rec->minfo.bpp    = ivideo.video_bpp;
-	rec->minfo.xres   = ivideo.video_width;
-	rec->minfo.yres   = ivideo.video_height;
-	rec->minfo.v_xres = ivideo.video_vwidth;
-	rec->minfo.v_yres = ivideo.video_vheight;
-	rec->minfo.org_x  = ivideo.org_x;
-	rec->minfo.org_y  = ivideo.org_y;
-	rec->minfo.vrate  = ivideo.refresh_rate;
-	rec->iobase       = ivideo.vga_base - 0x30;
-	rec->mem_size     = ivideo.video_size;
-	rec->disp_state   = ivideo.disp_state; 
-	rec->version      = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL; 
-	rec->hasVB        = ivideo.hasVB; 
-	rec->TV_type      = ivideo.TV_type; 
-	rec->TV_plug      = ivideo.TV_plug; 
-	rec->chip         = ivideo.chip;
+	rec->minfo.bpp      = ivideo.video_bpp;
+	rec->minfo.xres     = ivideo.video_width;
+	rec->minfo.yres     = ivideo.video_height;
+	rec->minfo.v_xres   = ivideo.video_vwidth;
+	rec->minfo.v_yres   = ivideo.video_vheight;
+	rec->minfo.org_x    = ivideo.org_x;
+	rec->minfo.org_y    = ivideo.org_y;
+	rec->minfo.vrate    = ivideo.refresh_rate;
+	rec->iobase         = ivideo.vga_base - 0x30;
+	rec->mem_size       = ivideo.video_size;
+	rec->disp_state     = ivideo.disp_state;
+	rec->version        = (VER_MAJOR << 24) | (VER_MINOR << 16) | VER_LEVEL;
+	rec->hasVB          = ivideo.hasVB;
+	rec->TV_type        = ivideo.TV_type;
+	rec->TV_plug        = ivideo.TV_plug;
+	rec->chip           = ivideo.chip;
+	rec->vbflags	    = ivideo.vbflags;
+	rec->currentvbflags = ivideo.currentvbflags;
 }
 
 /* ------------ FBDev related routines for 2.4 series ----------- */
@@ -871,15 +1376,14 @@
 	u16 HRE, HBE, HRS, HBS, HDE, HT;
 	u8  sr_data, cr_data, cr_data2, cr_data3, mr_data;
 	int A, B, C, D, E, F, temp;
-	double hrate, drate;
+	unsigned int hrate, drate;
 
-	TWDEBUG("Inside crtc_to_var");
 	inSISIDXREG(SISSR, IND_SIS_COLOR_MODE, sr_data);
 
-	if (sr_data & SIS_INTERLACED_MODE)
-		var->vmode = FB_VMODE_INTERLACED;
+	if(sr_data & SIS_INTERLACED_MODE)
+	   var->vmode = FB_VMODE_INTERLACED;
 	else
-		var->vmode = FB_VMODE_NONINTERLACED;
+	   var->vmode = FB_VMODE_NONINTERLACED;
 
 	switch ((sr_data & 0x1C) >> 2) {
 	   case SIS_8BPP_COLOR_MODE:
@@ -921,6 +1425,8 @@
 
 	inSISIDXREG(SISCR, 0x09, cr_data3);
 
+	if(cr_data3 & 0x80) var->vmode = FB_VMODE_DOUBLE;
+
 	VBS = (cr_data & 0xff) | ((u16) (cr_data2 & 0x08) << 5) |
 	      ((u16) (cr_data3 & 0x20) << 4) | ((u16) (sr_data & 0x04) << 8);
 
@@ -939,26 +1445,22 @@
 	D = B - F - C;
 
         var->yres = E;
-#ifndef SISFB_PAN
-	var->yres_virtual = E;
-#endif
-	/* TW: We have to report the physical dimension to the console! */
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		var->yres <<= 1;
-#ifndef SISFB_PAN
-		var->yres_virtual <<= 1;
-#endif
-	} else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-		var->yres >>= 1;
-#ifndef SISFB_PAN
-		var->yres_virtual >>= 1;
-#endif
-	}
-
 	var->upper_margin = D;
 	var->lower_margin = F;
 	var->vsync_len = C;
 
+	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+	   var->yres <<= 1;
+	   var->upper_margin <<= 1;
+	   var->lower_margin <<= 1;
+	   var->vsync_len <<= 1;
+	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+	   var->yres >>= 1;
+	   var->upper_margin >>= 1;
+	   var->lower_margin >>= 1;
+	   var->vsync_len >>= 1;
+	}
+
 	inSISIDXREG(SISSR, 0x0b, sr_data);
 
 	inSISIDXREG(SISCR, 0x00, cr_data);
@@ -999,44 +1501,54 @@
 	D = B - F - C;
 
 	var->xres = var->xres_virtual = E * 8;
-	var->left_margin = D * 8;
-	var->right_margin = F * 8;
-	var->hsync_len = C * 8;
 
+	if((var->xres == 320) &&
+	   (var->yres == 200 || var->yres == 240)) {
+		/* Terrible hack, but the correct CRTC data for
+	  	 * these modes only produces a black screen...
+	  	 */
+       		var->left_margin = (400 - 376);
+       		var->right_margin = (328 - 320);
+       		var->hsync_len = (376 - 328);
+	} else {
+	   	var->left_margin = D * 8;
+	   	var->right_margin = F * 8;
+	   	var->hsync_len = C * 8;
+	}
 	var->activate = FB_ACTIVATE_NOW;
 
 	var->sync = 0;
 
 	mr_data = inSISREG(SISMISCR);
-	if (mr_data & 0x80)
-		var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
+	if(mr_data & 0x80)
+	   var->sync &= ~FB_SYNC_VERT_HIGH_ACT;
 	else
-		var->sync |= FB_SYNC_VERT_HIGH_ACT;
+	   var->sync |= FB_SYNC_VERT_HIGH_ACT;
 
-	if (mr_data & 0x40)
-		var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
+	if(mr_data & 0x40)
+	   var->sync &= ~FB_SYNC_HOR_HIGH_ACT;
 	else
-		var->sync |= FB_SYNC_HOR_HIGH_ACT;
+	   var->sync |= FB_SYNC_HOR_HIGH_ACT;
 
 	VT += 2;
 	VT <<= 1;
 	HT = (HT + 5) * 8;
 
-	hrate = (double) ivideo.refresh_rate * (double) VT / 2;
-	drate = hrate * HT;
-	var->pixclock = (u32) (1E12 / drate);
+	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+	   VT <<= 1;
+	}
+	hrate = ivideo.refresh_rate * VT / 2;
+	drate = (hrate * HT) / 1000;
+	var->pixclock = (u32) (1000000000 / drate);
 
-#ifdef SISFB_PAN
 	if(sisfb_ypan) {
-	    var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
-	    if(var->yres_virtual <= var->yres) {
-	        var->yres_virtual = var->yres;
-	    }
+	   var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
+	   if(var->yres_virtual <= var->yres) {
+	      var->yres_virtual = var->yres;
+	   }
 	} else
-#endif
 	   var->yres_virtual = var->yres;
 
-        TWDEBUG("end of crtc_to_var");
 }
 
 static int sis_getcolreg(unsigned regno, unsigned *red, unsigned *green, unsigned *blue,
@@ -1069,7 +1581,7 @@
 		outSISREG(SISDACD, (red >> 10));
 		outSISREG(SISDACD, (green >> 10));
 		outSISREG(SISDACD, (blue >> 10));
-		if (ivideo.disp_state & DISPTYPE_DISP2) {
+		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
 		        outSISREG(SISDAC2A, regno);
 			outSISREG(SISDAC2D, (red >> 8));
 			outSISREG(SISDAC2D, (green >> 8));
@@ -1118,7 +1630,7 @@
 	display->ywrapstep = fix.ywrapstep;
 	display->line_length = fix.line_length;
 	display->next_line = fix.line_length;
-	display->can_soft_blank = 0;
+	display->can_soft_blank = 1;
 	display->inverse = sisfb_inverse;
 	display->var = *var;
 
@@ -1162,17 +1674,12 @@
 	display->dispsw = &sisfb_sw;
 	restore_flags(flags);
 
-#ifdef SISFB_PAN
-        if((ivideo.accel) && (sisfb_ypan)) {
-  	    /* display->scrollmode = SCROLL_YPAN; - not defined */
+        if(sisfb_ypan) {
+  	    /* display->scrollmode = 0;  */
 	} else {
 	    display->scrollmode = SCROLL_YREDRAW;
 	    sisfb_sw.bmove = fbcon_redraw_bmove;
 	}
-#else
-	display->scrollmode = SCROLL_YREDRAW;
-	sisfb_sw.bmove = fbcon_redraw_bmove;
-#endif
 }
 
 static void sisfb_do_install_cmap(int con, struct fb_info *info)
@@ -1191,17 +1698,16 @@
 static int sisfb_get_var(struct fb_var_screeninfo *var, int con,
 			 struct fb_info *info)
 {
-	TWDEBUG("inside get_var");
 	if(con == -1)
 		memcpy(var, &default_var, sizeof(struct fb_var_screeninfo));
 	else
 		*var = fb_display[con].var;
 
- 	/* For FSTN, DSTN */
-	if (var->xres == 320 && var->yres == 480)
+	if(sisfb_fstn) {
+	   if (var->xres == 320 && var->yres == 480)
 		var->yres = 240;
-		
-	TWDEBUG("end of get_var");
+        }
+
 	return 0;
 }
 
@@ -1211,8 +1717,6 @@
 	int err;
 	unsigned int cols, rows;
 
-	TWDEBUG("inside set_var");
-
 	fb_display[con].var.activate = FB_ACTIVATE_NOW;
         if(sisfb_do_set_var(var, con == currcon, info)) {
 		sisfb_crtc_to_var(var);
@@ -1233,16 +1737,17 @@
 
 	cols = sisbios_mode[sisfb_mode_idx].cols;
 	rows = sisbios_mode[sisfb_mode_idx].rows;
-	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
+#if 0
+	/* Why was this called here? */
+ 	vc_resize_con(rows, cols, fb_display[con].conp->vc_num);
+#endif
 
-	TWDEBUG("end of set_var");
 	return 0;
 }
 
 static int sisfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
 			  struct fb_info *info)
 {
-	TWDEBUG("inside get_cmap");
         if (con == currcon)
 		return fb_get_cmap(cmap, kspc, sis_getcolreg, info);
 
@@ -1251,7 +1756,6 @@
 	else
 		fb_copy_cmap(fb_default_cmap(ivideo.video_cmap_len), cmap, kspc ? 0 : 2);
 
-	TWDEBUG("end of get_cmap");
 	return 0;
 }
 
@@ -1260,7 +1764,6 @@
 {
 	int err;
 
-	TWDEBUG("inside set_cmap");
 	if (!fb_display[con].cmap.len) {
 		err = fb_alloc_cmap(&fb_display[con].cmap, ivideo.video_cmap_len, 0);
 		if (err)
@@ -1272,17 +1775,15 @@
 
 	else
 		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-	TWDEBUG("end of set_cmap");
+
 	return 0;
 }
 
-#ifdef SISFB_PAN
 static int sisfb_pan_display(struct fb_var_screeninfo *var, int con,
 			     struct fb_info* info)
 {
 	int err;
-	
-	TWDEBUG("inside pan_display");
+
 	if (var->vmode & FB_VMODE_YWRAP) {
 		if (var->yoffset < 0 || var->yoffset >= fb_display[con].var.yres_virtual || var->xoffset)
 			return -EINVAL;
@@ -1303,10 +1804,8 @@
 	else
 		fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
 
-	TWDEBUG("end of pan_display");
 	return 0;
 }
-#endif
 
 static int sisfb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma)
@@ -1316,7 +1815,6 @@
 	unsigned long off;
 	u32 len, mmio_off;
 
-	TWDEBUG("inside mmap");
 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
 
 	off = vma->vm_pgoff << PAGE_SHIFT;
@@ -1351,11 +1849,11 @@
 	if (boot_cpu_data.x86 > 3)
 		pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
 #endif
+        /* RedHat requires vma as the first paramater to the following call */
 	if (io_remap_page_range(vma->vm_start, off, vma->vm_end - vma->vm_start,
 				vma->vm_page_prot))
 		return -EAGAIN;
 
-        TWDEBUG("end of mmap");
 	return 0;
 }
 
@@ -1368,7 +1866,6 @@
 	u8 *gbuf = gly->gmask;
 	int size;
 
-	TWDEBUG("Inside get_glyph");
 	gly->fontheight = fontheight(p);
 	gly->fontwidth = fontwidth(p);
 	widthb = (fontwidth(p) + 7) / 8;
@@ -1382,16 +1879,11 @@
 	size = fontheight(p) * widthb;
 	memcpy(gbuf, cdat, size);
 	gly->ngmask = size;
-	TWDEBUG("End of get_glyph");
 }
 
 static int sisfb_update_var(int con, struct fb_info *info)
 {
-#ifdef SISFB_PAN
         return(sisfb_pan_var(&fb_display[con].var));
-#else
-	return 0;
-#endif	
 }
 
 static int sisfb_switch(int con, struct fb_info *info)
@@ -1428,127 +1920,7 @@
 
 static void sisfb_blank(int blank, struct fb_info *info)
 {
-	u8 reg;
-
-	inSISIDXREG(SISCR, 0x17, reg);
-
-	if(blank > 0)
-		reg &= 0x7f;
-	else
-		reg |= 0x80;
-
-        outSISIDXREG(SISCR, 0x17, reg);		
-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
-	printk(KERN_DEBUG "sisfb_blank() called (%d)\n", blank);
-}
-
-
-static int sisfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, int con,
-		       struct fb_info *info)
-{
-	TWDEBUG("inside ioctl");
-	switch (cmd) {
-	   case FBIO_ALLOC:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		sis_malloc((struct sis_memreq *) arg);
-		break;
-	   case FBIO_FREE:
-		if (!capable(CAP_SYS_RAWIO))
-			return -EPERM;
-		sis_free(*(unsigned long *) arg);
-		break;
-	   case FBIOGET_GLYPH:
-                sis_get_glyph(info,(SIS_GLYINFO *) arg);
-		break;	
-	   case FBIOGET_HWCINFO:
-		{
-			unsigned long *hwc_offset = (unsigned long *) arg;
-
-			if (sisfb_caps & HW_CURSOR_CAP)
-				*hwc_offset = sisfb_hwcursor_vbase -
-				    (unsigned long) ivideo.video_vbase;
-			else
-				*hwc_offset = 0;
-
-			break;
-		}
-	   case FBIOPUT_MODEINFO:
-		{
-			struct mode_info *x = (struct mode_info *)arg;
-
-			ivideo.video_bpp        = x->bpp;
-			ivideo.video_width      = x->xres;
-			ivideo.video_height     = x->yres;
-			ivideo.video_vwidth     = x->v_xres;
-			ivideo.video_vheight    = x->v_yres;
-			ivideo.org_x            = x->org_x;
-			ivideo.org_y            = x->org_y;
-			ivideo.refresh_rate     = x->vrate;
-			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
-			switch(ivideo.video_bpp) {
-        		case 8:
-            			ivideo.DstColor = 0x0000;
-	    			ivideo.SiS310_AccelDepth = 0x00000000;
-				ivideo.video_cmap_len = 256;
-            			break;
-        		case 16:
-            			ivideo.DstColor = 0x8000;
-            			ivideo.SiS310_AccelDepth = 0x00010000;
-				ivideo.video_cmap_len = 16;
-            			break;
-        		case 32:
-            			ivideo.DstColor = 0xC000;
-	    			ivideo.SiS310_AccelDepth = 0x00020000;
-				ivideo.video_cmap_len = 16;
-            			break;
-			default:
-				ivideo.video_cmap_len = 16;
-		       	 	printk(KERN_ERR "sisfb: Unsupported depth %d", ivideo.video_bpp);
-				ivideo.accel = 0;
-				break;
-    			}
-
-			break;
-		}
-	   case FBIOGET_DISPINFO:
-		sis_dispinfo((struct ap_data *)arg);
-		break;
-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
-	        {
-			sisfb_info *x = (sisfb_info *)arg;
-
-			x->sisfb_id = SISFB_ID;
-			x->sisfb_version = VER_MAJOR;
-			x->sisfb_revision = VER_MINOR;
-			x->sisfb_patchlevel = VER_LEVEL;
-			x->chip_id = ivideo.chip_id;
-			x->memory = ivideo.video_size / 1024;
-			x->heapstart = ivideo.heapstart / 1024;
-			x->fbvidmode = sisfb_mode_no;
-			x->sisfb_caps = sisfb_caps;
-			x->sisfb_tqlen = 512; /* yet unused */
-			x->sisfb_pcibus = ivideo.pcibus;
-			x->sisfb_pcislot = ivideo.pcislot;
-			x->sisfb_pcifunc = ivideo.pcifunc;
-			x->sisfb_lcdpdc = sisfb_detectedpdc;
-			x->sisfb_lcda = sisfb_detectedlcda;
-	                break;
-		}
-	   case SISFB_GET_VBRSTATUS:
-	        {
-			unsigned long *vbrstatus = (unsigned long *) arg;
-			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
-			else		           *vbrstatus = 0;
-		}
-	   default:
-		return -EINVAL;
-	}
-	TWDEBUG("end of ioctl");
-	return 0;
-
+	sisfb_myblank(blank);
 }
 #endif
 
@@ -1575,11 +1947,9 @@
 		rc = 256;	
 		break;
 	case 16:
-		rc = 16;	
-		break;		
 	case 32:
 		rc = 16;
-		break;	
+		break;
 	}
 	return rc;
 }
@@ -1596,7 +1966,7 @@
 		outSISREG(SISDACD, (red >> 10));
 		outSISREG(SISDACD, (green >> 10));
 		outSISREG(SISDACD, (blue >> 10));
-		if (ivideo.disp_state & DISPTYPE_DISP2) {
+		if (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
 		        outSISREG(SISDAC2A, regno);
 			outSISREG(SISDAC2D, (red >> 8));
 			outSISREG(SISDAC2D, (green >> 8));
@@ -1622,63 +1992,52 @@
 {
 	int err;
 
-	TWDEBUG("inside set_par");
         if((err = sisfb_do_set_var(&info->var, 1, info)))
 		return err;
 
 	sisfb_get_fix(&info->fix, info->currcon, info);
 
-	TWDEBUG("end of set_par");
 	return 0;
 }
 
 static int sisfb_check_var(struct fb_var_screeninfo *var,
                            struct fb_info *info)
 {
-	unsigned int htotal =
-		var->left_margin + var->xres + var->right_margin +
-		var->hsync_len;
-	unsigned int vtotal = 0;
-	double drate = 0, hrate = 0;
+	unsigned int htotal = 0, vtotal = 0, myrateindex = 0;
+	unsigned int drate = 0, hrate = 0;
 	int found_mode = 0;
 	int refresh_rate, search_idx;
+	BOOLEAN recalc_clock = FALSE;
+	u32 pixclock;
 
-	TWDEBUG("Inside check_var");
+	htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
+
+	vtotal = var->upper_margin + var->lower_margin + var->vsync_len;
+
+	pixclock = var->pixclock;
 
 	if((var->vmode & FB_VMODE_MASK) == FB_VMODE_NONINTERLACED) {
-		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;   
+		vtotal += var->yres;
 		vtotal <<= 1;
 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-		vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;   
+		vtotal += var->yres;
 		vtotal <<= 2;
 	} else if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		vtotal = var->upper_margin + (var->yres/2) + var->lower_margin +
-		         var->vsync_len;   
-	} else 	vtotal = var->upper_margin + var->yres + var->lower_margin +
-		         var->vsync_len;
+		vtotal += var->yres;
+		vtotal <<= 1;
+	} else 	vtotal += var->yres;
 
 	if(!(htotal) || !(vtotal)) {
 		SISFAIL("sisfb: no valid timing data");
 	}
 
-	if((var->pixclock) && (htotal)) {
-	   drate = 1E12 / var->pixclock;
-	   hrate = drate / htotal;
-	   refresh_rate = (unsigned int) (hrate / vtotal * 2 + 0.5);
-	} else refresh_rate = 60;
-
-	/* TW: Calculation wrong for 1024x600 - force it to 60Hz */
-	if((var->xres == 1024) && (var->yres == 600)) refresh_rate = 60;
-
 	search_idx = 0;
 	while( (sisbios_mode[search_idx].mode_no != 0) &&
 	       (sisbios_mode[search_idx].xres <= var->xres) ) {
 		if( (sisbios_mode[search_idx].xres == var->xres) &&
 		    (sisbios_mode[search_idx].yres == var->yres) &&
 		    (sisbios_mode[search_idx].bpp == var->bits_per_pixel)) {
-		        if(sisfb_validate_mode(search_idx) > 0) {
+		        if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
 			   found_mode = 1;
 			   break;
 			}
@@ -1687,38 +2046,95 @@
 	}
 
 	if(!found_mode) {
-	
-		printk(KERN_ERR "sisfb: %dx%dx%d is no valid mode\n", 
-			var->xres, var->yres, var->bits_per_pixel);
-			
+
                 search_idx = 0;
 		while(sisbios_mode[search_idx].mode_no != 0) {
-		       
 		   if( (var->xres <= sisbios_mode[search_idx].xres) &&
-		       (var->yres <= sisbios_mode[search_idx].yres) && 
+		       (var->yres <= sisbios_mode[search_idx].yres) &&
 		       (var->bits_per_pixel == sisbios_mode[search_idx].bpp) ) {
-		          if(sisfb_validate_mode(search_idx) > 0) {
+		          if(sisfb_validate_mode(search_idx, ivideo.currentvbflags) > 0) {
 			     found_mode = 1;
 			     break;
 			  }
 		   }
 		   search_idx++;
-	        }			
+	        }
 		if(found_mode) {
+			printk(KERN_DEBUG "sisfb: Adapted from %dx%dx%d to %dx%dx%d\n",
+		   		var->xres, var->yres, var->bits_per_pixel,
+				sisbios_mode[search_idx].xres,
+				sisbios_mode[search_idx].yres,
+				var->bits_per_pixel);
 			var->xres = sisbios_mode[search_idx].xres;
 		      	var->yres = sisbios_mode[search_idx].yres;
-		      	printk(KERN_DEBUG "sisfb: Adapted to mode %dx%dx%d\n",
-		   		var->xres, var->yres, var->bits_per_pixel);
-		   
+
+
 		} else {
-		   	printk(KERN_ERR "sisfb: Failed to find similar mode to %dx%dx%d\n", 
+		   	printk(KERN_ERR "sisfb: Failed to find supported mode near %dx%dx%d\n",
 				var->xres, var->yres, var->bits_per_pixel);
 		   	return -EINVAL;
 		}
 	}
 
-	/* TW: TODO: Check the refresh rate */		
-	
+	if( ((ivideo.vbflags & VB_LVDS) ||			/* Slave modes on LVDS and 301B-DH */
+	     ((ivideo.vbflags & VB_30xBDH) && (ivideo.currentvbflags & CRT2_LCD))) &&
+	    (var->bits_per_pixel == 8) ) {
+	    	refresh_rate = 60;
+		recalc_clock = TRUE;
+	} else if( (ivideo.current_htotal == htotal) &&		/* x=x & y=y & c=c -> assume depth change */
+	    	   (ivideo.current_vtotal == vtotal) &&
+	    	   (ivideo.current_pixclock == pixclock) ) {
+		drate = 1000000000 / pixclock;
+	        hrate = (drate * 1000) / htotal;
+	        refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+	} else if( ( (ivideo.current_htotal != htotal) ||	/* x!=x | y!=y & c=c -> invalid pixclock */
+	    	     (ivideo.current_vtotal != vtotal) ) &&
+	    	   (ivideo.current_pixclock == var->pixclock) ) {
+		if(sisfb_lastrates[sisbios_mode[search_idx].mode_no]) {
+			refresh_rate = sisfb_lastrates[sisbios_mode[search_idx].mode_no];
+		} else if(sisfb_parm_rate != -1) {
+			refresh_rate = sisfb_parm_rate;
+		} else {
+			refresh_rate = 60;
+		}
+		recalc_clock = TRUE;
+	} else if((pixclock) && (htotal) && (vtotal)) {
+		drate = 1000000000 / pixclock;
+	   	hrate = (drate * 1000) / htotal;
+	   	ivideo.refresh_rate = (unsigned int) (hrate * 2 / vtotal);
+	} else if(ivideo.current_refresh_rate) {
+		refresh_rate = ivideo.current_refresh_rate;
+		recalc_clock = TRUE;
+	} else {
+		refresh_rate = 60;
+		recalc_clock = TRUE;
+	}
+
+	myrateindex = sisfb_search_refresh_rate(refresh_rate, search_idx);
+
+	/* Eventually recalculate timing and clock */
+	if(recalc_clock) {
+	   if(!myrateindex) myrateindex = sisbios_mode[search_idx].rate_idx;
+	   var->pixclock = (u32) (1000000000 / sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
+						sisbios_mode[search_idx].mode_no, myrateindex));
+	   sisfb_mode_rate_to_ddata(&SiS_Pr, &sishw_ext,
+		 			sisbios_mode[search_idx].mode_no, myrateindex,
+		 			&var->left_margin, &var->right_margin,
+		 			&var->upper_margin, &var->lower_margin,
+		 			&var->hsync_len, &var->vsync_len,
+		 			&var->sync, &var->vmode);
+	   if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		var->pixclock <<= 1;
+	   }
+	}
+
+	if(sisfb_thismonitor.datavalid) {
+	   if(!sisfb_verify_rate(&sisfb_thismonitor, search_idx,
+	                         myrateindex, refresh_rate)) {
+	      printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+	   }
+	}
+
 	/* Adapt RGB settings */
 	sisfb_bpp_to_var(var);	
 	
@@ -1731,18 +2147,20 @@
 	/* Horiz-panning not supported */
 	if(var->xres != var->xres_virtual)
 		var->xres_virtual = var->xres;
-
-	if(!sisfb_ypan) {
-		if(var->yres != var->yres_virtual)
-			var->yres_virtual = var->yres;
-	} else {
+
+	if(sisfb_ypan) {
 	   /* TW: Now patch yres_virtual if we use panning */
 	   /* *** May I do this? *** */
 	   var->yres_virtual = ivideo.heapstart / (var->xres * (var->bits_per_pixel >> 3));
-	    if(var->yres_virtual <= var->yres) {
+	   if(var->yres_virtual <= var->yres) {
 	    	/* TW: Paranoia check */
 	        var->yres_virtual = var->yres;
-	    }
+	   }
+	} else {
+	   if(var->yres != var->yres_virtual)
+		var->yres_virtual = var->yres;
+	   var->xoffset = 0;
+	   var->yoffset = 0;
 	}
 	
 	/* Truncate offsets to maximum if too high */
@@ -1757,28 +2175,25 @@
 	    var->green.msb_right =
 	    var->blue.msb_right =
 	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;		
-		
-	TWDEBUG("end of check_var");
+
 	return 0;
 }
 
-#ifdef SISFB_PAN
 static int sisfb_pan_display(struct fb_var_screeninfo *var,
 			     struct fb_info* info)
 {
 	int err;
-	
-	TWDEBUG("inside pan_display");
-	
+
 	if (var->xoffset > (var->xres_virtual - var->xres))
 		return -EINVAL;
 	if (var->yoffset > (var->yres_virtual - var->yres))
 		return -EINVAL;
 
 	if (var->vmode & FB_VMODE_YWRAP) {
-		if (var->yoffset < 0
-		    || var->yoffset >= info->var.yres_virtual
-		    || var->xoffset) return -EINVAL;
+		if (var->yoffset < 0 ||
+		    var->yoffset >= info->var.yres_virtual ||
+		    var->xoffset)
+		    	return -EINVAL;
 	} else {
 		if (var->xoffset + info->var.xres > info->var.xres_virtual ||
 		    var->yoffset + info->var.yres > info->var.yres_virtual)
@@ -1794,10 +2209,8 @@
 	else
 		info->var.vmode &= ~FB_VMODE_YWRAP;
 
-	TWDEBUG("end of pan_display");
 	return 0;
 }
-#endif
 
 static int sisfb_mmap(struct fb_info *info, struct file *file,
 		      struct vm_area_struct *vma)
@@ -1806,7 +2219,6 @@
 	unsigned long off;
 	u32 len, mmio_off;
 
-	TWDEBUG("inside mmap");
 	if(vma->vm_pgoff > (~0UL >> PAGE_SHIFT))  return -EINVAL;
 
 	off = vma->vm_pgoff << PAGE_SHIFT;
@@ -1844,188 +2256,194 @@
 				vma->vm_page_prot))
 		return -EAGAIN;
 
-        TWDEBUG("end of mmap");
 	return 0;
 }
 
 static int sisfb_blank(int blank, struct fb_info *info)
 {
-	u8 reg;
+	return(sisfb_myblank(blank));
+}
 
-	inSISIDXREG(SISCR, 0x17, reg);
+#endif
 
-	if(blank > 0)
-		reg &= 0x7f;
-	else
-		reg |= 0x80;
+/* ----------- FBDev related routines for all series ---------- */
 
-        outSISIDXREG(SISCR, 0x17, reg);		
-	outSISIDXREG(SISSR, 0x00, 0x01);    /* Synchronous Reset */
-	outSISIDXREG(SISSR, 0x00, 0x03);    /* End Reset */
-        return(0);
-}
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static int sisfb_ioctl(struct inode *inode, struct file *file,
+		       unsigned int cmd, unsigned long arg,
+		       struct fb_info *info)
+#else
 static int sisfb_ioctl(struct inode *inode, struct file *file,
-		       unsigned int cmd, unsigned long arg, 
+		       unsigned int cmd, unsigned long arg, int con,
 		       struct fb_info *info)
+#endif
 {
-	TWDEBUG("inside ioctl");
+	struct sis_memreq sismemreq;
+	struct ap_data sisapdata;
+	unsigned long sismembase = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	SIS_GLYINFO sisglyinfo;
+#endif
+
 	switch (cmd) {
 	   case FBIO_ALLOC:
-		if (!capable(CAP_SYS_RAWIO))
+		if(!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_malloc((struct sis_memreq *) arg);
+		if(copy_from_user(&sismemreq, (void *)arg, sizeof(sismemreq)))
+		   	return -EFAULT;
+        	sis_malloc(&sismemreq);
+		if(copy_to_user((void *)arg, &sismemreq, sizeof(sismemreq))) {
+			sis_free(sismemreq.offset);
+		    	return -EFAULT;
+		}
 		break;
 	   case FBIO_FREE:
-		if (!capable(CAP_SYS_RAWIO))
+		if(!capable(CAP_SYS_RAWIO))
 			return -EPERM;
-		sis_free(*(unsigned long *) arg);
+		if(get_user(sismembase, (unsigned long *) arg))
+			return -EFAULT;
+		sis_free(sismembase);
 		break;
-	   case FBIOGET_HWCINFO:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	   case FBIOGET_GLYPH:
+	        if(copy_from_user(&sisglyinfo, (void *)arg, sizeof(sisglyinfo)))
+			return -EFAULT;
+                sis_get_glyph(info, &sisglyinfo);
+		break;
+	   case FBIOPUT_MODEINFO:
 		{
-			unsigned long *hwc_offset = (unsigned long *) arg;
+			struct mode_info x;
 
-			if (sisfb_caps & HW_CURSOR_CAP)
-				*hwc_offset = sisfb_hwcursor_vbase -
-				    (unsigned long) ivideo.video_vbase;
-			else
-				*hwc_offset = 0;
+			if(copy_from_user(&x, (void *)arg, sizeof(x)))
+				return -EFAULT;
 
+			ivideo.video_bpp        = x.bpp;
+			ivideo.video_width      = x.xres;
+			ivideo.video_height     = x.yres;
+			ivideo.video_vwidth     = x.v_xres;
+			ivideo.video_vheight    = x.v_yres;
+			ivideo.org_x            = x.org_x;
+			ivideo.org_y            = x.org_y;
+			ivideo.refresh_rate     = x.vrate;
+			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
+			sisfb_set_vparms();
 			break;
 		}
-	   case FBIOPUT_MODEINFO:
+#endif
+	   case FBIOGET_HWCINFO:
 		{
-			struct mode_info *x = (struct mode_info *)arg;
+			unsigned long myhwcoffset = 0;
 
-			ivideo.video_bpp        = x->bpp;
-			ivideo.video_width      = x->xres;
-			ivideo.video_height     = x->yres;
-			ivideo.video_vwidth     = x->v_xres;
-			ivideo.video_vheight    = x->v_yres;
-			ivideo.org_x            = x->org_x;
-			ivideo.org_y            = x->org_y;
-			ivideo.refresh_rate     = x->vrate;
-			ivideo.video_linelength = ivideo.video_vwidth * (ivideo.video_bpp >> 3);
-			switch(ivideo.video_bpp) {
-        		case 8:
-            			ivideo.DstColor = 0x0000;
-	    			ivideo.SiS310_AccelDepth = 0x00000000;
-				ivideo.video_cmap_len = 256;
-            			break;
-        		case 16:
-            			ivideo.DstColor = 0x8000;
-            			ivideo.SiS310_AccelDepth = 0x00010000;
-				ivideo.video_cmap_len = 16;
-            			break;
-        		case 32:
-            			ivideo.DstColor = 0xC000;
-	    			ivideo.SiS310_AccelDepth = 0x00020000;
-				ivideo.video_cmap_len = 16;
-            			break;
-			default:
-				ivideo.video_cmap_len = 16;
-		       	 	printk(KERN_ERR "sisfb: Unsupported accel depth %d", ivideo.video_bpp);
-				ivideo.accel = 0;
-				break;
-    			}
+			if(sisfb_caps & HW_CURSOR_CAP)
+				myhwcoffset = sisfb_hwcursor_vbase -
+				    (unsigned long) ivideo.video_vbase;
+
+			return put_user(myhwcoffset, (unsigned long *)arg);
 
 			break;
 		}
 	   case FBIOGET_DISPINFO:
-		sis_dispinfo((struct ap_data *)arg);
+	   	sis_dispinfo(&sisapdata);
+		if(copy_to_user((void *)arg, &sisapdata, sizeof(sisapdata)))
+			return -EFAULT;
 		break;
-	   case SISFB_GET_INFO:  /* TW: New for communication with X driver */
+	   case SISFB_GET_INFO:  /* For communication with X driver */
 	        {
-			sisfb_info *x = (sisfb_info *)arg;
+			sisfb_info x;
 
-			x->sisfb_id = SISFB_ID;
-			x->sisfb_version = VER_MAJOR;
-			x->sisfb_revision = VER_MINOR;
-			x->sisfb_patchlevel = VER_LEVEL;
-			x->chip_id = ivideo.chip_id;
-			x->memory = ivideo.video_size / 1024;
-			x->heapstart = ivideo.heapstart / 1024;
-			x->fbvidmode = sisfb_mode_no;
-			x->sisfb_caps = sisfb_caps;
-			x->sisfb_tqlen = 512; /* yet unused */
-			x->sisfb_pcibus = ivideo.pcibus;
-			x->sisfb_pcislot = ivideo.pcislot;
-			x->sisfb_pcifunc = ivideo.pcifunc;
-			x->sisfb_lcdpdc = sisfb_detectedpdc;
-			x->sisfb_lcda = sisfb_detectedlcda;
+			x.sisfb_id = SISFB_ID;
+			x.sisfb_version = VER_MAJOR;
+			x.sisfb_revision = VER_MINOR;
+			x.sisfb_patchlevel = VER_LEVEL;
+			x.chip_id = ivideo.chip_id;
+			x.memory = ivideo.video_size / 1024;
+			x.heapstart = ivideo.heapstart / 1024;
+			x.fbvidmode = sisfb_mode_no;
+			x.sisfb_caps = sisfb_caps;
+			x.sisfb_tqlen = 512; /* yet fixed */
+			x.sisfb_pcibus = ivideo.pcibus;
+			x.sisfb_pcislot = ivideo.pcislot;
+			x.sisfb_pcifunc = ivideo.pcifunc;
+			x.sisfb_lcdpdc = sisfb_detectedpdc;
+			x.sisfb_lcda = sisfb_detectedlcda;
+			x.sisfb_vbflags = ivideo.vbflags;
+			x.sisfb_currentvbflags = ivideo.currentvbflags;
+			x.sisfb_scalelcd = SiS_Pr.UsePanelScaler;
+			x.sisfb_specialtiming = SiS_Pr.SiS_CustomT;
+			if(copy_to_user((void *)arg, &x, sizeof(x)))
+				return -EFAULT;
 	                break;
 		}
 	   case SISFB_GET_VBRSTATUS:
 	        {
-			unsigned long *vbrstatus = (unsigned long *) arg;
-			if(sisfb_CheckVBRetrace()) *vbrstatus = 1;
-			else		           *vbrstatus = 0;
+			if(sisfb_CheckVBRetrace())
+				return put_user(1UL, (unsigned long *) arg);
+			else
+				return put_user(0UL, (unsigned long *) arg);
+			break;
 		}
 	   default:
 		return -EINVAL;
 	}
-	TWDEBUG("end of ioctl");
 	return 0;
-
 }
 
-#endif
-
-/* ----------- FBDev related routines for all series ---------- */
 
 static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
 			 struct fb_info *info)
 {
-	TWDEBUG("inside get_fix");
 	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-	strcpy(fix->id, sis_fb_info.modename);
+	strcpy(fix->id, sis_fb_info->modename);
 #else
 	strcpy(fix->id, myid);
 #endif	
 
 	fix->smem_start = ivideo.video_base;
 
-        /* TW */
         if((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-	    if (ivideo.video_size > 0x1000000) {
-	        fix->smem_len = 0xc00000;
-	    } else if (ivideo.video_size > 0x800000)
-		fix->smem_len = 0x800000;
-	    else
-		fix->smem_len = 0x400000;
+	    if(sisvga_engine == SIS_300_VGA) {
+	       if(ivideo.video_size > 0x1000000) {
+	          	fix->smem_len = 0xc00000;
+	       } else if(ivideo.video_size > 0x800000)
+		  	fix->smem_len = 0x800000;
+	       else
+		  	fix->smem_len = 0x400000;
+            } else {
+	       	fix->smem_len = ivideo.video_size - 0x100000;
+	    }
         } else
 		fix->smem_len = sisfb_mem * 1024;
 
-	fix->type        = video_type;
+	fix->type        = FB_TYPE_PACKED_PIXELS;
 	fix->type_aux    = 0;
 	if(ivideo.video_bpp == 8)
 		fix->visual = FB_VISUAL_PSEUDOCOLOR;
 	else
 		fix->visual = FB_VISUAL_TRUECOLOR;
 	fix->xpanstep    = 0;
-#ifdef SISFB_PAN
+
         if(sisfb_ypan) 	 fix->ypanstep = 1;
-#endif
+
 	fix->ywrapstep   = 0;
 	fix->line_length = ivideo.video_linelength;
 	fix->mmio_start  = ivideo.mmio_base;
 	fix->mmio_len    = sisfb_mmio_size;
 	if(sisvga_engine == SIS_300_VGA) 
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR;
-	else if(ivideo.chip == SIS_330)
+	else if((ivideo.chip == SIS_330) || (ivideo.chip == SIS_660) || (ivideo.chip == SIS_760))
 	   fix->accel    = FB_ACCEL_SIS_XABRE;
-	else 
+	else
 	   fix->accel    = FB_ACCEL_SIS_GLAMOUR_2;
-	
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	fix->reserved[0] = ivideo.video_size & 0xFFFF;
 	fix->reserved[1] = (ivideo.video_size >> 16) & 0xFFFF;
 	fix->reserved[2] = sisfb_caps;
-#endif	
+#endif
 
-	TWDEBUG("end of get_fix");
 	return 0;
 }
 
@@ -2033,17 +2451,15 @@
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static struct fb_ops sisfb_ops = {
-	owner:		THIS_MODULE,
-	fb_get_fix:	sisfb_get_fix,
-	fb_get_var:	sisfb_get_var,
-	fb_set_var:	sisfb_set_var,
-	fb_get_cmap:	sisfb_get_cmap,
-	fb_set_cmap:	sisfb_set_cmap,
-#ifdef SISFB_PAN
-        fb_pan_display:	sisfb_pan_display,
-#endif
-	fb_ioctl:	sisfb_ioctl,
-	fb_mmap:	sisfb_mmap,
+	.owner		= THIS_MODULE,
+	.fb_get_fix	= sisfb_get_fix,
+	.fb_get_var	= sisfb_get_var,
+	.fb_set_var	= sisfb_set_var,
+	.fb_get_cmap	= sisfb_get_cmap,
+	.fb_set_cmap	= sisfb_set_cmap,
+        .fb_pan_display = sisfb_pan_display,
+	.fb_ioctl	= sisfb_ioctl,
+	.fb_mmap	= sisfb_mmap,
 };
 #endif
 
@@ -2056,9 +2472,7 @@
 	.fb_check_var = sisfb_check_var,
 	.fb_set_par   = sisfb_set_par,
 	.fb_setcolreg = sisfb_setcolreg,
-#ifdef SISFB_PAN
         .fb_pan_display = sisfb_pan_display,
-#endif	
         .fb_blank     = sisfb_blank,
 	.fb_fillrect  = fbcon_sis_fillrect,
 	.fb_copyarea  = fbcon_sis_copyarea,
@@ -2094,271 +2508,77 @@
 		break;
 	   default:
 		nbridge_id = 0;
-		break;
-	}
-
-	if (nbridge_id == 0) {  /* 300 */
-
-	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);
-		ivideo.video_size =
-		        ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);
-
-	} else {		/* 540, 630, 730 */
-
-		pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
-		if (pdev) {
-			pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
-			pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-			ivideo.video_size = (unsigned int)(1 << (pci_data+21));
-			pdev_valid = 1;
-
-			reg = SIS_DATA_BUS_64 << 6;
-			switch (pci_data) {
-			   case BRI_DRAM_SIZE_2MB:
-				reg |= SIS_DRAM_SIZE_2MB;
-				break;
-			   case BRI_DRAM_SIZE_4MB:
-				reg |= SIS_DRAM_SIZE_4MB;
-				break;
-			   case BRI_DRAM_SIZE_8MB:
-				reg |= SIS_DRAM_SIZE_8MB;
-				break;
-			   case BRI_DRAM_SIZE_16MB:
-				reg |= SIS_DRAM_SIZE_16MB;
-				break;
-			   case BRI_DRAM_SIZE_32MB:
-				reg |= SIS_DRAM_SIZE_32MB;
-				break;
-			   case BRI_DRAM_SIZE_64MB:
-				reg |= SIS_DRAM_SIZE_64MB;
-				break;
-			}
-			outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-		}
-	
-		if (!pdev_valid)  return -1;
-	}
-	return 0;
-}
-
-static void sisfb_detect_VB_connect_300()
-{
-	u8 sr16, sr17, cr32, temp;
-
-	ivideo.TV_plug = ivideo.TV_type = 0;
-
-        switch(ivideo.hasVB) {
-	  case HASVB_LVDS_CHRONTEL:
-	  case HASVB_CHRONTEL:
-	     SiS_SenseCh();
-	     break;
-	  case HASVB_301:
-	  case HASVB_302:
-	     SiS_Sense30x();
-	     break;
-	}
-
-	inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
-        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
-
-	if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
-
-		if ((sr17 & 0x01) && !sisfb_crt1off)
-			sisfb_crt1off = 0;
-		else {
-			if (sr17 & 0x0E)
-				sisfb_crt1off = 1;
-			else
-				sisfb_crt1off = 0;
-		}
-
-		if (sisfb_crt2type != -1)
-			/* TW: override detected CRT2 type */
-			ivideo.disp_state = sisfb_crt2type;
-                else if (sr17 & 0x04)
-			ivideo.disp_state = DISPTYPE_TV;			
-		else if (sr17 & 0x02)
-			ivideo.disp_state = DISPTYPE_LCD;			
-		else if (sr17 & 0x08 )
-			ivideo.disp_state = DISPTYPE_CRT2;
-		else
-			ivideo.disp_state = 0;
-
-		if(sisfb_tvplug != -1)
-			/* PR/TW: override detected TV type */
-			ivideo.TV_plug = sisfb_tvplug;
-		else if (sr17 & 0x20)
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		else if (sr17 & 0x10)
-			ivideo.TV_plug = TVPLUG_COMPOSITE;
-
-		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
-		if (sr16 & 0x20)
-			ivideo.TV_type = TVMODE_PAL;
-		else
-			ivideo.TV_type = TVMODE_NTSC;
-
-	} else {
-
-		if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
-			sisfb_crt1off = 0;
-		else {
-			if (cr32 & 0x5F)
-				sisfb_crt1off = 1;
-			else
-				sisfb_crt1off = 0;
-		}
-
-		if (sisfb_crt2type != -1)
-			/* TW: override detected CRT2 type */
-			ivideo.disp_state = sisfb_crt2type;
-		else if (cr32 & SIS_VB_TV)
-			ivideo.disp_state = DISPTYPE_TV;
-		else if (cr32 & SIS_VB_LCD)
-			ivideo.disp_state = DISPTYPE_LCD;
-		else if (cr32 & SIS_VB_CRT2)
-			ivideo.disp_state = DISPTYPE_CRT2;
-		else
-			ivideo.disp_state = 0;
-
-		/* TW: Detect TV plug & type */
-		if(sisfb_tvplug != -1)
-			/* PR/TW: override with option */
-		        ivideo.TV_plug = sisfb_tvplug;
-		else if (cr32 & SIS_VB_HIVISION) {
-			ivideo.TV_type = TVMODE_HIVISION;
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		}
-		else if (cr32 & SIS_VB_SVIDEO)
-			ivideo.TV_plug = TVPLUG_SVIDEO;
-		else if (cr32 & SIS_VB_COMPOSITE)
-			ivideo.TV_plug = TVPLUG_COMPOSITE;
-		else if (cr32 & SIS_VB_SCART)
-			ivideo.TV_plug = TVPLUG_SCART;
-
-		if (ivideo.TV_type == 0) {
-		        inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
-			if (temp & 0x01)
-				ivideo.TV_type = TVMODE_PAL;
-			else
-				ivideo.TV_type = TVMODE_NTSC;
-		}
-
-	}
-
-	/* TW: Copy forceCRT1 option to CRT1off if option is given */
-    	if (sisfb_forcecrt1 != -1) {
-    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
-		else                sisfb_crt1off = 1;
-    	}
-}
-
-static void sisfb_get_VB_type_300(void)
-{
-	u8 reg;
-
-	if(ivideo.chip != SIS_300) {
-		if(!sisfb_has_VB_300()) {
-		        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
-			switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-			   case SIS_EXTERNAL_CHIP_LVDS:
-				ivideo.hasVB = HASVB_LVDS;
-				break;
-			   case SIS_EXTERNAL_CHIP_TRUMPION:
-				ivideo.hasVB = HASVB_TRUMPION;
-				break;
-			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
-				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-				break;
-			   case SIS_EXTERNAL_CHIP_CHRONTEL:
-				ivideo.hasVB = HASVB_CHRONTEL;
-				break;
-			   default:
-				break;
-			}
-		}
-	} else {
-		sisfb_has_VB_300();
-	}
-}
-
-static int sisfb_has_VB_300(void)
-{
-	u8 vb_chipid;
-
-	inSISIDXREG(SISPART4, 0x00, vb_chipid);
-	switch (vb_chipid) {
-	   case 0x01:
-		ivideo.hasVB = HASVB_301;
-		break;
-	   case 0x02:
-		ivideo.hasVB = HASVB_302;
-		break;
-	   default:
-		ivideo.hasVB = HASVB_NONE;
-		return FALSE;
+		break;
 	}
-	return TRUE;
-
-}
-
-#endif  /* CONFIG_FB_SIS_300 */
-
-
-#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330 */
 
-static int sisfb_get_dram_size_315(void)
-{
-	struct pci_dev *pdev = NULL;
-	int pdev_valid = 0;
-	u8  pci_data;
-	u8  reg = 0;
+	if (nbridge_id == 0) {  /* 300 */
 
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
+	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE,reg);
+		ivideo.video_size =
+		        ((unsigned int) ((reg & SIS_DRAM_SIZE_MASK) + 1) << 20);
 
-#ifdef LINUXBIOS
+	} else {		/* 540, 630, 730 */
 
-		while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev)) != NULL) {
-			if ((pdev->device == PCI_DEVICE_ID_SI_550) ||
-			     (pdev->device == PCI_DEVICE_ID_SI_650) ||
-			     (pdev->device == PCI_DEVICE_ID_SI_740)) {
-				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
-				                     &pci_data);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
+		pci_for_each_dev(pdev) {
+#else
+		while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+#endif
+			if ((pdev->vendor == PCI_VENDOR_ID_SI)
+				       && (pdev->device == nbridge_id)) {
+				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS, &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
-				ivideo.video_size = (unsigned int)(1 << (pci_data + 21));
+				ivideo.video_size = (unsigned int)(1 << (pci_data+21));
 				pdev_valid = 1;
-
-				/* TW: Initialize SR14 "by hand" */
-				inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
-				reg &= 0xC0;
+
+				reg = SIS_DATA_BUS_64 << 6;
 				switch (pci_data) {
+				   case BRI_DRAM_SIZE_2MB:
+					reg |= SIS_DRAM_SIZE_2MB;
+					break;
 				   case BRI_DRAM_SIZE_4MB:
-					reg |= SIS550_DRAM_SIZE_4MB;
+					reg |= SIS_DRAM_SIZE_4MB;
 					break;
 				   case BRI_DRAM_SIZE_8MB:
-					reg |= SIS550_DRAM_SIZE_8MB;
+					reg |= SIS_DRAM_SIZE_8MB;
 					break;
 				   case BRI_DRAM_SIZE_16MB:
-					reg |= SIS550_DRAM_SIZE_16MB;
+					reg |= SIS_DRAM_SIZE_16MB;
 					break;
 				   case BRI_DRAM_SIZE_32MB:
-					reg |= SIS550_DRAM_SIZE_32MB;
+					reg |= SIS_DRAM_SIZE_32MB;
 					break;
 				   case BRI_DRAM_SIZE_64MB:
-					reg |= SIS550_DRAM_SIZE_64MB;
+					reg |= SIS_DRAM_SIZE_64MB;
 					break;
 				}
-
-			        /* TODO: set Dual channel and bus width bits here */
-
 				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 				break;
 			}  
-		}
+		}
 	
 		if (!pdev_valid)  return -1;
+	}
+	return 0;
+}
 
-#else
+#endif  /* CONFIG_FB_SIS_300 */
+
+
+#ifdef CONFIG_FB_SIS_315    /* for SiS 315/550/650/740/330/660/760 */
+
+static int sisfb_get_dram_size_315(void)
+{
+	struct pci_dev *pdev = NULL;
+	int pdev_valid = 0;
+	u8  pci_data;
+	u8  reg = 0;
+
+	if (ivideo.chip == SIS_550 ||
+	    ivideo.chip == SIS_650 ||
+	    ivideo.chip == SIS_740 ||
+	    ivideo.chip == SIS_660 ||
+	    ivideo.chip == SIS_760) {
 
                 inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 		switch (reg & SIS550_DRAM_SIZE_MASK) {
@@ -2381,16 +2601,24 @@
 		   case SIS550_DRAM_SIZE_256MB:
 			ivideo.video_size = 0x10000000;	break;
 		   default:
-		        /* TW: Some 550 BIOSes don't seem to initialize SR14 correctly (if at all),
-			 *     do it the hard way ourselves in this case. Unfortunately, we don't
-			 *     support 24, 48, 96 and other "odd" amounts here.
+		        /* Some 550 BIOSes don't seem to initialize SR14 correctly (if at all),
+			 * do it the hard way ourselves in this case. Unfortunately, we don't
+			 * support 24, 48, 96 and other "odd" amounts here.
 			 */
 		        printk(KERN_INFO
 			       "sisfb: Warning: Could not determine memory size, "
 			       "now reading from PCI config\n");
 			pdev_valid = 0;
 
-			while ((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550, pdev)) != NULL) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
+			pci_for_each_dev(pdev) {
+#else
+			while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+#endif
+
+			   if ( (pdev->vendor == PCI_VENDOR_ID_SI)
+			         && (pdev->device == PCI_DEVICE_ID_SI_550) ) {
+
 				pci_read_config_byte(pdev, IND_BRI_DRAM_STATUS,
 				                     &pci_data);
 				pci_data = (pci_data & BRI_DRAM_SIZE_MASK) >> 4;
@@ -2415,6 +2643,7 @@
 					return -1;
 				}
 				outSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
+			   }
 			}
 			if (!pdev_valid) {
 				printk(KERN_INFO "sisfb: Total confusion - No SiS PCI VGA device found?!\n");
@@ -2422,10 +2651,10 @@
 			}
 			return 0;
 		}
-#endif
+
 		return 0;
 
-	} else {	/* 315 */
+	} else {	/* 315, 330 */
 
 	        inSISIDXREG(SISSR, IND_SIS_DRAM_SIZE, reg);
 		switch ((reg & SIS315_DRAM_SIZE_MASK) >> 4) {
@@ -2456,9 +2685,9 @@
 		
 		reg &= SIS315_DUAL_CHANNEL_MASK;
 		reg >>= 2;
-		
+
 		if(ivideo.chip == SIS_330) {
-		
+
 		   if(reg) ivideo.video_size <<= 1;
 		
 		} else {
@@ -2470,7 +2699,7 @@
 		      case SIS315_DUAL_CHANNEL_1_RANK:
 			   ivideo.video_size <<= 1;
 			   break;
-		      case SIS315_ASYM_DDR:		/* TW: DDR asymentric */
+		      case SIS315_ASYM_DDR:		/* TW: DDR asymetric */
 			   ivideo.video_size += (ivideo.video_size/2);
 			   break;
 		   }
@@ -2483,259 +2712,475 @@
 	
 }
 
-static void sisfb_detect_VB_connect_315(void)
+#endif   /* CONFIG_FB_SIS_315 */
+
+
+/* -------------- video bridge detection --------------- */
+
+static void sisfb_detect_VB_connect()
 {
-	u8 cr32, temp=0;
+	u8 sr16, sr17, cr32, temp;
+
+	if(sisvga_engine == SIS_300_VGA) {
+
+		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_17, sr17);
+
+		if ((sr17 & 0x0F) && (ivideo.chip != SIS_300)) {
+
+			/* Old BIOSes store the detected CRT2 type in SR17
+		 	 * instead of CR32. However, since our detection
+			 * routines store their results to CR32, we now copy
+			 * the remaining bits (for LCD and VGA) to CR32 for
+			 * unified usage.
+			 * SR17[0] CRT1    [1] LCD     [2] TV    [3] VGA2
+			 *     [4] AVIDEO  [5] SVIDEO
+			 */
+
+#if 0
+			if (sr17 & 0x01) orSISIDXREG(SISCR, 0x32, SIS_CRT1);
+			else		 andSISIDXREG(SISCR, 0x32, ~SIS_CRT1);
 
-	ivideo.TV_plug = ivideo.TV_type = 0;
+			if (sr17 & 0x02) orSISIDXREG(SISCR, 0x32, SIS_VB_LCD);
+			else		 andSISIDXREG(SISCR, 0x32, ~SIS_VB_LCD);
 
-        switch(ivideo.hasVB) {
-	  case HASVB_LVDS_CHRONTEL:
-	  case HASVB_CHRONTEL:
-	     SiS_SenseCh();
-	     break;
-	  case HASVB_301:
-	  case HASVB_302:
-	     SiS_Sense30x();
-	     break;
-	}
+			/* no HiVision and no DVI connector here */
+			andSISIDXREG(SISCR, 0x32, ~0xc0);
+#endif
+
+			/* PAL/NTSC is stored on SR16 on such machines */
+			if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
+		   		inSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_16, sr16);
+				if (sr16 & 0x20)
+					ivideo.vbflags |= TV_PAL;
+				else
+					ivideo.vbflags |= TV_NTSC;
+			}
 
+		}
+
+	}
+
 	inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR32, cr32);
 
-	if ((cr32 & SIS_CRT1) && !sisfb_crt1off)
+	if (cr32 & SIS_CRT1)
 		sisfb_crt1off = 0;
 	else {
-		if (cr32 & 0x5F)   
+		if (cr32 & 0x5F)
 			sisfb_crt1off = 1;
 		else
 			sisfb_crt1off = 0;
 	}
 
-	if (sisfb_crt2type != -1)
-		/* TW: Override with option */
-		ivideo.disp_state = sisfb_crt2type;
-	else if (cr32 & SIS_VB_TV)
-		ivideo.disp_state = DISPTYPE_TV;		
-	else if (cr32 & SIS_VB_LCD)
-		ivideo.disp_state = DISPTYPE_LCD;		
-	else if (cr32 & SIS_VB_CRT2)
-		ivideo.disp_state = DISPTYPE_CRT2;
-	else
-		ivideo.disp_state = 0;
+	ivideo.vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA);
 
+	if (cr32 & SIS_VB_TV)
+		ivideo.vbflags |= CRT2_TV;
+	if (cr32 & SIS_VB_LCD)
+		ivideo.vbflags |= CRT2_LCD;
+	if (cr32 & SIS_VB_CRT2)
+		ivideo.vbflags |= CRT2_VGA;
+
+	/* TW: Detect/set TV plug & type */
 	if(sisfb_tvplug != -1)
-		/* PR/TW: Override with option */
-	        ivideo.TV_plug = sisfb_tvplug;
-	else if (cr32 & SIS_VB_HIVISION) {
-		ivideo.TV_type = TVMODE_HIVISION;
-		ivideo.TV_plug = TVPLUG_SVIDEO;
-	}
+	        ivideo.vbflags |= sisfb_tvplug;
+	if (cr32 & SIS_VB_HIVISION)
+		ivideo.vbflags |= (TV_HIVISION | TV_SVIDEO);
 	else if (cr32 & SIS_VB_SVIDEO)
-		ivideo.TV_plug = TVPLUG_SVIDEO;
+		ivideo.vbflags |= TV_SVIDEO;
 	else if (cr32 & SIS_VB_COMPOSITE)
-		ivideo.TV_plug = TVPLUG_COMPOSITE;
+		ivideo.vbflags |= TV_AVIDEO;
 	else if (cr32 & SIS_VB_SCART)
-		ivideo.TV_plug = TVPLUG_SCART;
-
-	if(ivideo.TV_type == 0) {
-	    /* TW: PAL/NTSC changed for 650 */
-	    if((ivideo.chip <= SIS_315PRO) || (ivideo.chip >= SIS_330)) {
-
-                inSISIDXREG(SISCR, 0x38, temp);
-		if(temp & 0x10)
-			ivideo.TV_type = TVMODE_PAL;
-		else
-			ivideo.TV_type = TVMODE_NTSC;
+		ivideo.vbflags |= TV_SCART;
+
+	if (!(ivideo.vbflags & (TV_PAL | TV_NTSC))) {
+		if(sisvga_engine == SIS_300_VGA) {
+	        	inSISIDXREG(SISSR, IND_SIS_POWER_ON_TRAP, temp);
+			if (temp & 0x01)
+				ivideo.vbflags |= TV_PAL;
+			else
+				ivideo.vbflags |= TV_NTSC;
+		} else if((ivideo.chip <= SIS_315PRO) || (ivideo.chip == SIS_330)) {
 
-	    } else {
+                	inSISIDXREG(SISCR, 0x38, temp);
+			if(temp & 0x10)
+				ivideo.vbflags |= TV_PAL;
+			else
+				ivideo.vbflags |= TV_NTSC;
+
+	    	} else {
 
-	        inSISIDXREG(SISCR, 0x79, temp);
-		if(temp & 0x20)
-			ivideo.TV_type = TVMODE_PAL;
-		else
-			ivideo.TV_type = TVMODE_NTSC;
-	    }
+	        	inSISIDXREG(SISCR, 0x79, temp);
+			if(temp & 0x20)
+				ivideo.vbflags |= TV_PAL;
+			else
+				ivideo.vbflags |= TV_NTSC;
+	    	}
 	}
 
 	/* TW: Copy forceCRT1 option to CRT1off if option is given */
     	if (sisfb_forcecrt1 != -1) {
-    		if (sisfb_forcecrt1) sisfb_crt1off = 0;
-		else   	             sisfb_crt1off = 1;
+    		if(sisfb_forcecrt1) sisfb_crt1off = 0;
+		else                sisfb_crt1off = 1;
     	}
-}
 
-static void sisfb_get_VB_type_315(void)
-{
-	u8 reg;
-
-	if (!sisfb_has_VB_315()) {
-	        inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
-		switch ((reg & SIS_EXTERNAL_CHIP_MASK) >> 1) {
-	 	   case SIS310_EXTERNAL_CHIP_LVDS:
-			ivideo.hasVB = HASVB_LVDS;
-			break;
-		   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-			ivideo.hasVB = HASVB_LVDS_CHRONTEL;
-			break;
-		   default:
-			break;
-		}
-	}
 }
 
-
-static int sisfb_has_VB_315(void)
+static void sisfb_get_VB_type(void)
 {
 	u8 vb_chipid;
+	u8 reg;
+	char stdstr[]    = "sisfb: Detected";
+	char bridgestr[] = "video bridge";
+	char lvdsstr[]   = "LVDS transmitter";
+  	char chrstr[]    = "Chrontel TV encoder";
+
+	ivideo.hasVB = HASVB_NONE;
+	sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
+	sishw_ext.Is301BDH = FALSE;
+	sishw_ext.usExternalChip = 0;
 
 	inSISIDXREG(SISPART4, 0x00, vb_chipid);
 	switch (vb_chipid) {
 	   case 0x01:
 		ivideo.hasVB = HASVB_301;
+		inSISIDXREG(SISPART4, 0x01, reg);
+		if(reg < 0xb0) {
+			ivideo.vbflags |= VB_301;
+			sishw_ext.ujVBChipID = VB_CHIP_301;
+			printk(KERN_INFO "%s SiS301 %s\n", stdstr, bridgestr);
+		} else if(reg < 0xc0) {
+		 	ivideo.vbflags |= VB_301B;
+			sishw_ext.ujVBChipID = VB_CHIP_301B;
+			printk(KERN_INFO "%s SiS301B %s\n", stdstr, bridgestr);
+		} else if(reg < 0xd0) {
+		 	ivideo.vbflags |= VB_301C;
+			sishw_ext.ujVBChipID = VB_CHIP_301C;
+			printk(KERN_INFO "%s SiS301C %s\n", stdstr, bridgestr);
+		} else if(reg < 0xe0) {
+			ivideo.vbflags |= VB_301LV;
+			sishw_ext.ujVBChipID = VB_CHIP_301LV;
+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
+		} else if(reg <= 0xe1) {
+			ivideo.vbflags |= VB_302LV;
+			sishw_ext.ujVBChipID = VB_CHIP_302LV;
+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
+		}
 		break;
 	   case 0x02:
 		ivideo.hasVB = HASVB_302;
+		inSISIDXREG(SISPART4, 0x01, reg);
+		if(reg < 0xd0) {
+			ivideo.vbflags |= VB_302B;
+			sishw_ext.ujVBChipID = VB_CHIP_302B;
+			printk(KERN_INFO "%s SiS302B %s\n", stdstr, bridgestr);
+		} else if(reg < 0xe0) {
+		 	ivideo.vbflags |= VB_301LV;
+			sishw_ext.ujVBChipID = VB_CHIP_301LV;
+			printk(KERN_INFO "%s SiS301LV %s\n", stdstr, bridgestr);
+		} else if(reg <= 0xe1) {
+			ivideo.vbflags |= VB_302LV;
+			sishw_ext.ujVBChipID = VB_CHIP_302LV;
+			printk(KERN_INFO "%s SiS302LV %s\n", stdstr, bridgestr);
+		}
 		break;
-	   default:
-		ivideo.hasVB = HASVB_NONE;
-		return FALSE;
 	}
-	return TRUE;
-}
 
-#endif   /* CONFIG_FB_SIS_315 */
+	if(ivideo.vbflags & (VB_301B | VB_302B)) {
+		inSISIDXREG(SISPART4,0x23,reg);
+		if(!(reg & 0x02)) {
+			sishw_ext.Is301BDH = TRUE;
+			ivideo.vbflags |= VB_30xBDH;
+			printk(KERN_INFO "This %s does not support LCD output\n", bridgestr);
+		}
+	}
+
+	if((!(ivideo.vbflags & VB_VIDEOBRIDGE)) && (ivideo.chip != SIS_300)) {
+		inSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR37, reg);
+		reg &= SIS_EXTERNAL_CHIP_MASK;
+		reg >>= 1;
+		if(sisvga_engine == SIS_300_VGA) {
+			switch (reg) {
+			   case SIS_EXTERNAL_CHIP_LVDS:
+				ivideo.hasVB = HASVB_LVDS;
+				ivideo.vbflags |= VB_LVDS;
+				sishw_ext.usExternalChip = 0x01;
+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+				break;
+			   case SIS_EXTERNAL_CHIP_TRUMPION:
+				ivideo.hasVB = HASVB_TRUMPION;
+				sishw_ext.usExternalChip = 0x02;
+				printk(KERN_INFO "%s Trumpion LCD scaler\n", stdstr);
+				break;
+			   case SIS_EXTERNAL_CHIP_CHRONTEL:
+				ivideo.hasVB = HASVB_CHRONTEL;
+				ivideo.vbflags |= VB_CHRONTEL;
+				sishw_ext.usExternalChip = 0x04;
+				printk(KERN_INFO "%s %s\n", stdstr, chrstr);
+				break;
+			   case SIS_EXTERNAL_CHIP_LVDS_CHRONTEL:
+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
+				sishw_ext.usExternalChip = 0x05;
+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+				break;
+			}
+		} else {
+			switch (reg) {
+	 	   	   case SIS310_EXTERNAL_CHIP_LVDS:
+				ivideo.hasVB = HASVB_LVDS;
+				ivideo.vbflags |= VB_LVDS;
+				sishw_ext.usExternalChip = 0x01;
+				printk(KERN_INFO "%s %s\n", stdstr, lvdsstr);
+				break;
+		   	   case SIS310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+				ivideo.hasVB = HASVB_LVDS_CHRONTEL;
+				ivideo.vbflags |= (VB_LVDS | VB_CHRONTEL);
+				sishw_ext.usExternalChip = 0x05;
+				printk(KERN_INFO "%s %s and %s\n", stdstr, lvdsstr, chrstr);
+				break;
+			}
+		}
+
+	}
+
+	if(ivideo.vbflags & VB_SISBRIDGE) {
+		SiS_Sense30x();
+	} else if(ivideo.vbflags & VB_CHRONTEL) {
+		SiS_SenseCh();
+	}
+
+}
 
 /* ------------------ Sensing routines ------------------ */
 
-/* TW: Determine and detect attached devices on SiS30x */
+static BOOLEAN
+sisfb_test_DDC1(void)
+{
+    unsigned short old;
+    int count = 48;
+
+    old = SiS_ReadDDC1Bit(&SiS_Pr);
+    do {
+       if(old != SiS_ReadDDC1Bit(&SiS_Pr)) break;
+    } while(count--);
+    return (count == -1) ? FALSE : TRUE;
+}
+
+static void
+sisfb_sense_crt1(void)
+{
+    unsigned char SR1F, CR63=0, CR17;
+    unsigned short temp = 0xffff;
+    int i;
+    BOOLEAN mustwait = FALSE;
+
+    inSISIDXREG(SISSR,0x1F,SR1F);
+    orSISIDXREG(SISSR,0x1F,0x04);
+    andSISIDXREG(SISSR,0x1F,0x3F);
+    if(SR1F & 0xc0) mustwait = TRUE;
+
+    if(sisvga_engine == SIS_315_VGA) {
+       inSISIDXREG(SISCR,0x63,CR63);
+       CR63 &= 0x40;
+       andSISIDXREG(SISCR,0x63,0xBF);
+    }
+
+    inSISIDXREG(SISCR,0x17,CR17);
+    CR17 &= 0x80;
+    if(!CR17) {
+       orSISIDXREG(SISCR,0x17,0x80);
+       mustwait = TRUE;
+       outSISIDXREG(SISSR, 0x00, 0x01);
+       outSISIDXREG(SISSR, 0x00, 0x03);
+    }
+
+    if(mustwait) {
+       for(i=0; i < 10; i++) sisfbwaitretracecrt1();
+    }
+
+    i = 3;
+    do {
+       temp = SiS_HandleDDC(&SiS_Pr, ivideo.vbflags, sisvga_engine, 0, 0, NULL);
+    } while(((temp == 0) || (temp == 0xffff)) && i--);
+
+    if((temp == 0) || (temp == 0xffff)) {
+       if(sisfb_test_DDC1()) temp = 1;
+    }
+
+    if((temp) && (temp != 0xffff)) {
+       orSISIDXREG(SISCR,0x32,0x20);
+    }
+
+    if(sisvga_engine == SIS_315_VGA) {
+       setSISIDXREG(SISCR,0x63,0xBF,CR63);
+    }
+
+    setSISIDXREG(SISCR,0x17,0x7F,CR17);
+
+    outSISIDXREG(SISSR,0x1F,SR1F);
+}
+
+/* Determine and detect attached devices on SiS30x */
 int
 SISDoSense(int tempbl, int tempbh, int tempcl, int tempch)
 {
-    int temp,i;
+    int temp;
 
     outSISIDXREG(SISPART4,0x11,tempbl);
     temp = tempbh | tempcl;
     setSISIDXREG(SISPART4,0x10,0xe0,temp);
-    for(i=0; i<10; i++) SiS_LongWait(&SiS_Pr);
+    SiS_DDC2Delay(&SiS_Pr, 0x1000);
     tempch &= 0x7f;
     inSISIDXREG(SISPART4,0x03,temp);
     temp ^= 0x0e;
     temp &= tempch;
-    return(temp);
+    return((temp == tempch));
 }
 
 void
 SiS_Sense30x(void)
 {
-  u8 backupP4_0d;
-  u8 testsvhs_tempbl, testsvhs_tempbh;
-  u8 testsvhs_tempcl, testsvhs_tempch;
-  u8 testcvbs_tempbl, testcvbs_tempbh;
-  u8 testcvbs_tempcl, testcvbs_tempch;
-  u8 testvga2_tempbl, testvga2_tempbh;
-  u8 testvga2_tempcl, testvga2_tempch;
-  int myflag, result;
+  u8 backupP4_0d,backupP2_00;
+  u8 svhs_bl, svhs_bh;
+  u8 svhs_cl, svhs_ch;
+  u8 cvbs_bl, cvbs_bh;
+  u8 cvbs_cl, cvbs_ch;
+  u8 vga2_bl, vga2_bh;
+  u8 vga2_cl, vga2_ch;
+  int myflag, result, haveresult, i, j;
+  char stdstr[] = "sisfb: Detected";
+  char tvstr[]  = "TV connected to";
 
   inSISIDXREG(SISPART4,0x0d,backupP4_0d);
   outSISIDXREG(SISPART4,0x0d,(backupP4_0d | 0x04));
 
+  inSISIDXREG(SISPART2,0x00,backupP2_00);
+  outSISIDXREG(SISPART2,0x00,(backupP2_00 | 0x1c));
+
   if(sisvga_engine == SIS_300_VGA) {
 
-  	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
-	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
-	   (sishw_ext.ujVBChipID != VB_CHIP_302) ) {
-	   testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-	   testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-	   testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
+	if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV)) {
+	   	vga2_bh = 0x01; vga2_bl = 0x90;
+	   	svhs_bh = 0x01; svhs_bl = 0x6b;
+	   	cvbs_bh = 0x01; cvbs_bl = 0x74;
+	} else {
+		vga2_bh = 0x00; vga2_bl = 0xd1;
+        	svhs_bh = 0x00; svhs_bl = 0xb9;
+		cvbs_bh = 0x00; cvbs_bl = 0xb3;
 	}
 	inSISIDXREG(SISPART4,0x01,myflag);
 	if(myflag & 0x04) {
-	   testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
-	   testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
-	   testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
-	}
-	testvga2_tempch = 0x0e;	testvga2_tempcl = 0x08;
-	testsvhs_tempch = 0x06;	testsvhs_tempcl = 0x04;
-	testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+	   vga2_bh = 0x00; vga2_bl = 0xfd;
+	   svhs_bh = 0x00; svhs_bl = 0xdd;
+	   cvbs_bh = 0x00; cvbs_bl = 0xee;
+	}
+	vga2_ch = 0x0e;	vga2_cl = 0x08;
+	svhs_ch = 0x04;	svhs_cl = 0x04;
+	cvbs_ch = 0x08; cvbs_cl = 0x04;
+	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+	   	vga2_bh = 0x00; vga2_bl = 0x00;
+	   	vga2_ch = 0x00; vga2_cl = 0x00;
+	 }
 	if(ivideo.chip == SIS_300) {
 	   inSISIDXREG(SISSR,0x3b,myflag);
 	   if(!(myflag & 0x01)) {
-	      testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-	      testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
+	      	vga2_bh = 0x00; vga2_bl = 0x00;
+	      	vga2_ch = 0x00; vga2_cl = 0x00;
 	   }
 	}
 
   } else {
 
-	testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1;
-        testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9;
-	testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3;
-	if((sishw_ext.ujVBChipID != VB_CHIP_301) &&
-	   (sishw_ext.ujVBChipID != VB_CHIP_302)) {
-	      testvga2_tempbh = 0x01; testvga2_tempbl = 0x90;
-	      testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b;
-	      testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74;
-	      if(sishw_ext.ujVBChipID == VB_CHIP_301LV ||
-	         sishw_ext.ujVBChipID == VB_CHIP_302LV) {
-	         testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-	         testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00;
-	         testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00;
-	      }
+	if(ivideo.vbflags & (VB_301B|VB_301C|VB_302B)) {
+		vga2_bh = 0x01; vga2_bl = 0x90;
+		svhs_bh = 0x01; svhs_bl = 0x6b;
+		cvbs_bh = 0x01; cvbs_bl = 0x74;
+	} else if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+	      	vga2_bh = 0x00; vga2_bl = 0x00;
+	      	svhs_bh = 0x02; svhs_bl = 0x00;
+	      	cvbs_bh = 0x01; cvbs_bl = 0x00;
+	} else {
+		vga2_bh = 0x00; vga2_bl = 0xd1;
+        	svhs_bh = 0x00; svhs_bl = 0xb9;
+		cvbs_bh = 0x00; cvbs_bl = 0xb3;
 	}
-	if(sishw_ext.ujVBChipID != VB_CHIP_301LV &&
-	   sishw_ext.ujVBChipID != VB_CHIP_302LV) {
+	if(ivideo.vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) {
 	   inSISIDXREG(SISPART4,0x01,myflag);
 	   if(myflag & 0x04) {
-	      testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd;
-	      testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd;
-	      testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee;
+	      vga2_bh = 0x00; vga2_bl = 0xfd;
+	      svhs_bh = 0x00; svhs_bl = 0xdd;
+	      cvbs_bh = 0x00; cvbs_bl = 0xee;
 	   }
 	}
-	if((sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
-	   (sishw_ext.ujVBChipID == VB_CHIP_302LV) ) {
-	   testvga2_tempbh = 0x00; testvga2_tempbl = 0x00;
-	   testvga2_tempch = 0x00; testvga2_tempcl = 0x00;
-	   testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08;
-	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08;
+	if(ivideo.vbflags & (VB_301LV|VB_302LV)) {
+	   vga2_bh = 0x00; vga2_bl = 0x00;
+	   vga2_ch = 0x00; vga2_cl = 0x00;
+	   svhs_ch = 0x04; svhs_cl = 0x08;
+	   cvbs_ch = 0x08; cvbs_cl = 0x08;
 	} else {
-	   testvga2_tempch = 0x0e; testvga2_tempcl = 0x08;
-	   testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04;
-	   testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04;
+	   vga2_ch = 0x0e; vga2_cl = 0x08;
+	   svhs_ch = 0x04; svhs_cl = 0x04;
+	   cvbs_ch = 0x08; cvbs_cl = 0x04;
 	}
     } 
 
-    if(testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) {
-        result = SISDoSense(testvga2_tempbl, testvga2_tempbh,
-                            testvga2_tempcl, testvga2_tempch);
- 	if(result) {
-        	printk(KERN_INFO "sisfb: Detected secondary VGA connection\n");
-		orSISIDXREG(SISCR, 0x32, 0x10);
-	}
+    if(vga2_ch || vga2_cl || vga2_bh || vga2_bl) {
+       haveresult = 0;
+       for(j = 0; j < 10; j++) {
+          result = 0;
+          for(i = 0; i < 3; i++) {
+             if(SISDoSense(vga2_bl, vga2_bh, vga2_cl, vga2_ch))
+	        result++;
+          }
+	  if((result == 0) || (result >= 2)) break;
+       }
+       if(result) {
+          printk(KERN_INFO "%s secondary VGA connection\n", stdstr);
+	  orSISIDXREG(SISCR, 0x32, 0x10);
+       } else {
+	  andSISIDXREG(SISCR, 0x32, ~0x10);
+       }
+    }
+
+    haveresult = 0;
+    for(j = 0; j < 10; j++) {
+       result = 0;
+       for(i = 0; i < 3; i++) {
+          if(SISDoSense(svhs_bl, svhs_bh, svhs_cl, svhs_ch))
+	        result++;
+       }
+       if((result == 0) || (result >= 2)) break;
     }
-    
-    result = SISDoSense(testsvhs_tempbl, testsvhs_tempbh,
-                        testsvhs_tempcl, testsvhs_tempch);
     if(result) {
-        printk(KERN_INFO "sisfb: Detected TV connected to SVHS output\n");
-        /* TW: So we can be sure that there IS a SVHS output */
-	ivideo.TV_plug = TVPLUG_SVIDEO;
+        printk(KERN_INFO "%s %s SVIDEO output\n", stdstr, tvstr);
+	ivideo.vbflags |= TV_SVIDEO;
 	orSISIDXREG(SISCR, 0x32, 0x02);
+	andSISIDXREG(SISCR, 0x32, ~0x05);
     }
 
     if(!result) {
-        result = SISDoSense(testcvbs_tempbl, testcvbs_tempbh,
-	                    testcvbs_tempcl, testcvbs_tempch);
+
+	haveresult = 0;
+       	for(j = 0; j < 10; j++) {
+           result = 0;
+           for(i = 0; i < 3; i++) {
+              if(SISDoSense(cvbs_bl, cvbs_bh, cvbs_cl, cvbs_ch))
+	        result++;
+           }
+           if((result == 0) || (result >= 2)) break;
+        }
 	if(result) {
-	    printk(KERN_INFO "sisfb: Detected TV connected to CVBS output\n");
-	    /* TW: So we can be sure that there IS a CVBS output */
-	    ivideo.TV_plug = TVPLUG_COMPOSITE;
+	    printk(KERN_INFO "%s %s COMPOSITE output\n", stdstr, tvstr);
+	    ivideo.vbflags |= TV_AVIDEO;
 	    orSISIDXREG(SISCR, 0x32, 0x01);
+	    andSISIDXREG(SISCR, 0x32, ~0x06);
+	} else {
+	    andSISIDXREG(SISCR, 0x32, ~0x07);
 	}
     }
     SISDoSense(0, 0, 0, 0);
 
+    outSISIDXREG(SISPART2,0x00,backupP2_00);
     outSISIDXREG(SISPART4,0x0d,backupP4_0d);
 }
 
@@ -2744,51 +3189,84 @@
 SiS_SenseCh(void)
 {
 
-   u8 temp1;
-#ifdef CONFIG_FB_SIS_315
-   u8 temp2;
+   u8 temp1, temp2;
+#ifdef CONFIG_FB_SIS_300
+   unsigned char test[3];
+   int i;
 #endif
+   char stdstr[] = "sisfb: Chrontel: Detected TV connected to";
 
    if(ivideo.chip < SIS_315H) {
 
 #ifdef CONFIG_FB_SIS_300
-       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* TW: Chrontel 7005 */
+       SiS_Pr.SiS_IF_DEF_CH70xx = 1;		/* Chrontel 700x */
+       SiS_SetChrontelGPIO(&SiS_Pr, 0x9c);	/* Set general purpose IO for Chrontel communication */
+       SiS_DDC2Delay(&SiS_Pr, 1000);
        temp1 = SiS_GetCH700x(&SiS_Pr, 0x25);
-       if ((temp1 >= 50) && (temp1 <= 100)) {
-	   /* TW: Read power status */
+       /* TW: See Chrontel TB31 for explanation */
+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x0e);
+       if(((temp2 & 0x07) == 0x01) || (temp2 & 0x04)) {
+	  SiS_SetCH700x(&SiS_Pr, 0x0b0e);
+	  SiS_DDC2Delay(&SiS_Pr, 300);
+       }
+       temp2 = SiS_GetCH700x(&SiS_Pr, 0x25);
+       if(temp2 != temp1) temp1 = temp2;
+
+       if((temp1 >= 0x22) && (temp1 <= 0x50)) {
+	   /* Read power status */
 	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x0e);
 	   if((temp1 & 0x03) != 0x03) {
-     	        /* TW: Power all outputs */
-		SiS_SetCH70xxANDOR(&SiS_Pr, 0x030E,0xF8);
+     	        /* Power all outputs */
+		SiS_SetCH700x(&SiS_Pr, 0x0B0E);
+		SiS_DDC2Delay(&SiS_Pr, 300);
 	   }
-	   /* TW: Sense connected TV devices */
-	   SiS_SetCH700x(&SiS_Pr, 0x0110);
-	   SiS_SetCH700x(&SiS_Pr, 0x0010);
-	   temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
-	   if(!(temp1 & 0x08)) {
-		printk(KERN_INFO
-		   "sisfb: Chrontel: Detected TV connected to SVHS output\n");
-		/* TW: So we can be sure that there IS a SVHS output */
-		ivideo.TV_plug = TVPLUG_SVIDEO;
+	   /* Sense connected TV devices */
+	   for(i = 0; i < 3; i++) {
+	       SiS_SetCH700x(&SiS_Pr, 0x0110);
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	       SiS_SetCH700x(&SiS_Pr, 0x0010);
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	       temp1 = SiS_GetCH700x(&SiS_Pr, 0x10);
+	       if(!(temp1 & 0x08))       test[i] = 0x02;
+	       else if(!(temp1 & 0x02))  test[i] = 0x01;
+	       else                      test[i] = 0;
+	       SiS_DDC2Delay(&SiS_Pr, 0x96);
+	   }
+
+	   if(test[0] == test[1])      temp1 = test[0];
+	   else if(test[0] == test[2]) temp1 = test[0];
+	   else if(test[1] == test[2]) temp1 = test[1];
+	   else {
+	   	printk(KERN_INFO
+			"sisfb: TV detection unreliable - test results varied\n");
+		temp1 = test[2];
+	   }
+	   if(temp1 == 0x02) {
+		printk(KERN_INFO "%s SVIDEO output\n", stdstr);
+		ivideo.vbflags |= TV_SVIDEO;
 		orSISIDXREG(SISCR, 0x32, 0x02);
-	   } else if (!(temp1 & 0x02)) {
-		printk(KERN_INFO
-		   "sisfb: Chrontel: Detected TV connected to CVBS output\n");
-		/* TW: So we can be sure that there IS a CVBS output */
-		ivideo.TV_plug = TVPLUG_COMPOSITE;
+		andSISIDXREG(SISCR, 0x32, ~0x05);
+	   } else if (temp1 == 0x01) {
+		printk(KERN_INFO "%s CVBS output\n", stdstr);
+		ivideo.vbflags |= TV_AVIDEO;
 		orSISIDXREG(SISCR, 0x32, 0x01);
+		andSISIDXREG(SISCR, 0x32, ~0x06);
 	   } else {
  		SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+		andSISIDXREG(SISCR, 0x32, ~0x07);
 	   }
        } else if(temp1 == 0) {
 	  SiS_SetCH70xxANDOR(&SiS_Pr, 0x010E,0xF8);
+	  andSISIDXREG(SISCR, 0x32, ~0x07);
        }
+       /* Set general purpose IO for Chrontel communication */
+       SiS_SetChrontelGPIO(&SiS_Pr, 0x00);
 #endif
 
    } else {
 
 #ifdef CONFIG_FB_SIS_315
-	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* TW: Chrontel 7019 */
+	SiS_Pr.SiS_IF_DEF_CH70xx = 2;		/* Chrontel 7019 */
         temp1 = SiS_GetCH701x(&SiS_Pr, 0x49);
 	SiS_SetCH701x(&SiS_Pr, 0x2049);
 	SiS_DDC2Delay(&SiS_Pr, 0x96);
@@ -2808,22 +3286,24 @@
 	if( (temp1 & 0x01) && (temp1 & 0x02) ) temp1 = 0x04;
 	switch(temp1) {
 	case 0x01:
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to CVBS output\n");
-	     ivideo.TV_plug = TVPLUG_COMPOSITE;
+	     printk(KERN_INFO "%s CVBS output\n", stdstr);
+	     ivideo.vbflags |= TV_AVIDEO;
 	     orSISIDXREG(SISCR, 0x32, 0x01);
+	     andSISIDXREG(SISCR, 0x32, ~0x06);
              break;
 	case 0x02:
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to SVHS output\n");
-	     ivideo.TV_plug = TVPLUG_SVIDEO;
+	     printk(KERN_INFO "%s SVIDEO output\n", stdstr);
+	     ivideo.vbflags |= TV_SVIDEO;
 	     orSISIDXREG(SISCR, 0x32, 0x02);
+	     andSISIDXREG(SISCR, 0x32, ~0x05);
              break;
 	case 0x04:
-	     /* TW: This should not happen */
-	     printk(KERN_INFO
-		"sisfb: Chrontel: Detected TV connected to SCART output\n");
+	     printk(KERN_INFO "%s SCART output\n", stdstr);
+	     orSISIDXREG(SISCR, 0x32, 0x04);
+	     andSISIDXREG(SISCR, 0x32, ~0x03);
              break;
+	default:
+	     andSISIDXREG(SISCR, 0x32, ~0x07);
 	}
 #endif
 
@@ -2845,8 +3325,13 @@
 	unsigned long *write_port = 0;
 	SIS_CMDTYPE    cmd_type;
 #ifndef AGPOFF
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 	struct agp_kern_info  *agp_info;
 	struct agp_memory     *agp;
+#else
+	agp_kern_info  *agp_info;
+	agp_memory     *agp;
+#endif
 	u32            agp_phys;
 #endif
 #endif
@@ -2860,14 +3345,21 @@
  *     in XF86Config-4.
  *     The heap start can also be specified by parameter "mem" when starting the sisfb
  *     driver. sisfb mem=1024 lets heap starts at 1MB, etc.
+ *
+ *     On the 315 and Xabre series, the default is a 1MB heap since DRI is not
+ *     supported there.
  */
      if ((!sisfb_mem) || (sisfb_mem > (ivideo.video_size/1024))) {
-        if (ivideo.video_size > 0x1000000) {
+        if(sisvga_engine == SIS_300_VGA) {
+           if (ivideo.video_size > 0x1000000) {
 	        ivideo.heapstart = 0xc00000;
-	} else if (ivideo.video_size > 0x800000) {
+	   } else if (ivideo.video_size > 0x800000) {
 	        ivideo.heapstart = 0x800000;
-	} else {
+	   } else {
 		ivideo.heapstart = 0x400000;
+	   }
+	} else {
+	   ivideo.heapstart = ivideo.video_size - 0x100000;
 	}
      } else {
            ivideo.heapstart = sisfb_mem * 1024;
@@ -2883,7 +3375,7 @@
 #ifdef CONFIG_FB_SIS_315
      if (sisvga_engine == SIS_315_VGA) {
         /* TW: Now initialize the 310 series' command queue mode.
-	 * On 310/325, there are three queue modes available which
+	 * On 315, there are three queue modes available which
 	 * are chosen by setting bits 7:5 in SR26:
 	 * 1. MMIO queue mode (bit 5, 0x20). The hardware will keep
 	 *    track of the queue, the FIFO, command parsing and so
@@ -2923,8 +3415,13 @@
 
 #ifndef AGPOFF
 	if (sisfb_queuemode == AGP_CMD_QUEUE) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 		agp_info = vmalloc(sizeof(*agp_info));
 		memset((void*)agp_info, 0x00, sizeof(*agp_info));
+#else
+		agp_info = vmalloc(sizeof(agp_kern_info));
+		memset((void*)agp_info, 0x00, sizeof(agp_kern_info));
+#endif
 		agp_copy_info(agp_info);
 
 		agp_backend_acquire();
@@ -3025,10 +3522,6 @@
 		break;
 
 	   default:  /* MMIO */
-	   	/* TW: This previously only wrote SIS_MMIO_CMD_ENABLE
-		 * to IND_SIS_CMDQUEUE_SET. I doubt that this is
-		 * enough. Reserve memory in any way.
-		 */
 	   	sisfb_heap_end -= COMMAND_QUEUE_AREA_SIZE;
 		sisfb_heap_size -= COMMAND_QUEUE_AREA_SIZE;
 
@@ -3037,7 +3530,7 @@
 
 		*write_port = *read_port;
 
-		/* TW: Set Auto_Correction bit */
+		/* Set Auto_Correction bit */
 		temp |= (SIS_MMIO_CMD_ENABLE | SIS_CMD_AUTO_CORR);
 		outSISIDXREG(SISSR, IND_SIS_CMDQUEUE_SET, temp);
 
@@ -3333,7 +3826,6 @@
 		req->offset = poh->offset;
 		req->size = poh->size;
 	}
-
 }
 
 void sis_free(unsigned long base)
@@ -3352,35 +3844,70 @@
 
 static void sisfb_pre_setmode(void)
 {
-	u8 cr30 = 0, cr31 = 0;
+	u8 cr30 = 0, cr31 = 0, cr33 = 0;
+
+	ivideo.currentvbflags &= (VB_VIDEOBRIDGE | VB_DISPTYPE_DISP2);
 
 	inSISIDXREG(SISCR, 0x31, cr31);
 	cr31 &= ~0x60;
+	cr31 |= 0x04;
+
+	cr33 = sisfb_rate_idx & 0x0F;
 
-	switch (ivideo.disp_state & DISPTYPE_DISP2) {
-	   case DISPTYPE_CRT2:
-		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= SIS_DRIVER_MODE;
-		break;
-	   case DISPTYPE_LCD:
-		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= SIS_DRIVER_MODE;
-		break;
-	   case DISPTYPE_TV:
-		if (ivideo.TV_type == TVMODE_HIVISION)
+	SiS_SetEnableDstn(&SiS_Pr, FALSE);
+	SiS_SetEnableFstn(&SiS_Pr, FALSE);
+
+	switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+	   case CRT2_TV:
+		ivideo.disp_state = DISPTYPE_TV;
+		if (ivideo.vbflags & TV_HIVISION) {
 			cr30 = (SIS_VB_OUTPUT_HIVISION | SIS_SIMULTANEOUS_VIEW_ENABLE);
-		else if (ivideo.TV_plug == TVPLUG_SVIDEO)
+			ivideo.currentvbflags |= (TV_HIVISION | TV_SVIDEO);
+			ivideo.TV_type = TVMODE_HIVISION;
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		} else if (ivideo.vbflags & TV_SVIDEO) {
 			cr30 = (SIS_VB_OUTPUT_SVIDEO | SIS_SIMULTANEOUS_VIEW_ENABLE);
-		else if (ivideo.TV_plug == TVPLUG_COMPOSITE)
+			ivideo.currentvbflags |= TV_SVIDEO;
+			ivideo.TV_plug = TVPLUG_SVIDEO;
+		} else if (ivideo.vbflags & TV_AVIDEO) {
 			cr30 = (SIS_VB_OUTPUT_COMPOSITE | SIS_SIMULTANEOUS_VIEW_ENABLE);
-		else if (ivideo.TV_plug == TVPLUG_SCART)
+			ivideo.currentvbflags |= TV_AVIDEO;
+			ivideo.TV_plug = TVPLUG_COMPOSITE;
+		} else if (ivideo.vbflags & TV_SCART) {
 			cr30 = (SIS_VB_OUTPUT_SCART | SIS_SIMULTANEOUS_VIEW_ENABLE);
+			ivideo.currentvbflags |= TV_SCART;
+			ivideo.TV_plug = TVPLUG_SCART;
+		}
 		cr31 |= SIS_DRIVER_MODE;
 
-	        if (sisfb_tvmode == 1 || ivideo.TV_type == TVMODE_PAL)
-			cr31 |= 0x01;
-                else
-                        cr31 &= ~0x01;
+		if(!(ivideo.vbflags & TV_HIVISION)) {
+	        	if (ivideo.vbflags & TV_PAL) {
+		 		cr31 |= 0x01;
+				ivideo.currentvbflags |= TV_PAL;
+				ivideo.TV_type = TVMODE_PAL;
+                	} else {
+		       		cr31 &= ~0x01;
+				ivideo.currentvbflags |= TV_NTSC;
+				ivideo.TV_type = TVMODE_NTSC;
+			}
+		}
+		break;
+	   case CRT2_LCD:
+		ivideo.disp_state = DISPTYPE_LCD;
+		cr30  = (SIS_VB_OUTPUT_LCD | SIS_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= SIS_DRIVER_MODE;
+		SiS_SetEnableDstn(&SiS_Pr, sisfb_dstn);
+	        SiS_SetEnableFstn(&SiS_Pr, sisfb_fstn);
+		break;
+	   case CRT2_VGA:
+		ivideo.disp_state = DISPTYPE_CRT2;
+		cr30 = (SIS_VB_OUTPUT_CRT2 | SIS_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= SIS_DRIVER_MODE;
+		if(sisfb_nocrt2rate) {
+			cr33 |= (sisbios_mode[sisfb_mode_idx].rate_idx << 4);
+		} else {
+			cr33 |= ((sisfb_rate_idx & 0x0F) << 4);
+		}
 		break;
 	   default:	/* disable CRT2 */
 		cr30 = 0x00;
@@ -3389,8 +3916,14 @@
 
 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR30, cr30);
 	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR31, cr31);
+	outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, cr33);
 
-        outSISIDXREG(SISCR, IND_SIS_SCRATCH_REG_CR33, (sisfb_rate_idx & 0x0F));
+#ifdef CONFIG_FB_SIS_315
+        if(sisvga_engine == SIS_315_VGA) {
+	   /* Clear LCDA and PAL-N/M bits */
+	   andSISIDXREG(SISCR,0x38,~0xc3);
+	}
+#endif
 
 	if(ivideo.accel) sisfb_syncaccel();
 
@@ -3400,67 +3933,90 @@
 static void sisfb_post_setmode(void)
 {
 	u8 reg;
+	BOOLEAN crt1isoff = FALSE;
+#ifdef CONFIG_FB_SIS_315
+	u8 reg1;
+#endif
+#ifdef CONFIG_FB_SIS_300
 	BOOLEAN doit = TRUE;
-#if 0	/* TW: Wrong: Is not in MMIO space, but in RAM */
-	/* Backup mode number to MMIO space */
-	if(ivideo.mmio_vbase) {
-	  *(volatile u8 *)(((u8*)ivideo.mmio_vbase) + 0x449) = (unsigned char)sisfb_mode_no;
-	}
-#endif	
-
-	if (ivideo.video_bpp == 8) {
-		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
-		if ((ivideo.hasVB == HASVB_LVDS) || (ivideo.hasVB == HASVB_LVDS_CHRONTEL)) {
-			doit = FALSE;
-		}
-		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
-		if ( (sishw_ext.Is301BDH) && (ivideo.disp_state & DISPTYPE_LCD) ) {
-	        	doit = FALSE;
-	        }
-	}
-
-	/* TW: We can't switch off CRT1 if bridge is in slave mode */
-	if(ivideo.hasVB != HASVB_NONE) {
-		inSISIDXREG(SISPART1, 0x00, reg);
+#endif
+	/* We can't switch off CRT1 if bridge is in slave mode */
+	if(ivideo.vbflags & VB_VIDEOBRIDGE) {
+#ifdef CONFIG_FB_SIS_300
 		if(sisvga_engine == SIS_300_VGA) {
+			inSISIDXREG(SISPART1, 0x00, reg);
 			if((reg & 0xa0) == 0x20) {
 				doit = FALSE;
 			}
 		}
-		if(sisvga_engine == SIS_315_VGA) {
-			if((reg & 0x50) == 0x10) {
-				doit = FALSE;
-			}
-		}
+#endif
 	} else sisfb_crt1off = 0;
 
-	inSISIDXREG(SISCR, 0x17, reg);
-	if((sisfb_crt1off) && (doit))
-		reg &= ~0x80;
-	else 	      
-		reg |= 0x80;
-	outSISIDXREG(SISCR, 0x17, reg);
+	if(sisvga_engine == SIS_300_VGA) {
+
+#ifdef CONFIG_FB_SIS_300
+	   if((sisfb_crt1off) && (doit)) {
+	        crt1isoff = TRUE;
+		reg = 0x00;
+	   } else {
+	        crt1isoff = FALSE;
+		reg = 0x80;
+	   }
+	   setSISIDXREG(SISCR, 0x17, 0x7f, reg);
+#endif
+
+	} else {
+
+#ifdef CONFIG_FB_SIS_315
+	   if(sisfb_crt1off) {
+	        crt1isoff = TRUE;
+		reg  = 0x40;
+		reg1 = 0xc0;
+	   } else {
+	        crt1isoff = FALSE;
+		reg  = 0x00;
+		reg1 = 0x00;
+
+	   }
+	   setSISIDXREG(SISCR, 0x63, ~0x40, reg);
+	   setSISIDXREG(SISSR, 0x1f, ~0xc0, reg1);
+#endif
 
-        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
+	}
 
-	if((ivideo.disp_state & DISPTYPE_TV) && (ivideo.hasVB == HASVB_301)) {
+	if(crt1isoff) {
+	   ivideo.currentvbflags &= ~VB_DISPTYPE_CRT1;
+	   ivideo.currentvbflags |= VB_SINGLE_MODE;
+	   ivideo.disp_state |= DISPMODE_SINGLE;
+	} else {
+	   ivideo.currentvbflags |= VB_DISPTYPE_CRT1;
+	   ivideo.disp_state |= DISPTYPE_CRT1;
+	   if(ivideo.currentvbflags & VB_DISPTYPE_CRT2) {
+	  	ivideo.currentvbflags |= VB_MIRROR_MODE;
+		ivideo.disp_state |= DISPMODE_MIRROR;
+	   } else {
+	 	ivideo.currentvbflags |= VB_SINGLE_MODE;
+		ivideo.disp_state |= DISPMODE_SINGLE;
+	   }
+	}
 
-	   inSISIDXREG(SISPART4, 0x01, reg);
+        andSISIDXREG(SISSR, IND_SIS_RAMDAC_CONTROL, ~0x04);
 
-	   if(reg < 0xB0) {        	/* Set filter for SiS301 */
+	if((ivideo.currentvbflags & CRT2_TV) && (ivideo.vbflags & VB_301)) {  /* Set filter for SiS301 */
 
 		switch (ivideo.video_width) {
 		   case 320:
-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 4 : 12;
+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 4 : 12;
 			break;
 		   case 640:
-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 5 : 13;
+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 5 : 13;
 			break;
 		   case 720:
-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 6 : 14;
+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 6 : 14;
 			break;
+		   case 400:
 		   case 800:
-			filter_tb = (ivideo.TV_type == TVMODE_NTSC) ? 7 : 15;
+			filter_tb = (ivideo.vbflags & TV_NTSC) ? 7 : 15;
 			break;
 		   default:
 			filter = -1;
@@ -3469,15 +4025,15 @@
 
 		orSISIDXREG(SISPART1, sisfb_CRT2_write_enable, 0x01);
 
-		if(ivideo.TV_type == TVMODE_NTSC) {
+		if(ivideo.vbflags & TV_NTSC) {
 
 		        andSISIDXREG(SISPART2, 0x3a, 0x1f);
 
-			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+			if (ivideo.vbflags & TV_SVIDEO) {
 
 			        andSISIDXREG(SISPART2, 0x30, 0xdf);
 
-			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+			} else if (ivideo.vbflags & TV_AVIDEO) {
 
 			        orSISIDXREG(SISPART2, 0x30, 0x20);
 
@@ -3494,6 +4050,7 @@
 					outSISIDXREG(SISPART2, 0x37, 0x22);
 					outSISIDXREG(SISPART2, 0x38, 0x08);
 					break;
+				case 400:
 				case 800:
 					outSISIDXREG(SISPART2, 0x35, 0xEB);
 					outSISIDXREG(SISPART2, 0x36, 0x15);
@@ -3503,15 +4060,15 @@
 				}
 			}
 
-		} else if(ivideo.TV_type == TVMODE_PAL) {
+		} else if(ivideo.vbflags & TV_PAL) {
 
 			andSISIDXREG(SISPART2, 0x3A, 0x1F);
 
-			if (ivideo.TV_plug == TVPLUG_SVIDEO) {
+			if (ivideo.vbflags & TV_SVIDEO) {
 
 			        andSISIDXREG(SISPART2, 0x30, 0xDF);
 
-			} else if (ivideo.TV_plug == TVPLUG_COMPOSITE) {
+			} else if (ivideo.vbflags & TV_AVIDEO) {
 
 			        orSISIDXREG(SISPART2, 0x30, 0x20);
 
@@ -3528,6 +4085,7 @@
 					outSISIDXREG(SISPART2, 0x37, 0x1D);
 					outSISIDXREG(SISPART2, 0x38, 0x20);
 					break;
+				case 400:
 				case 800:
 					outSISIDXREG(SISPART2, 0x35, 0xFC);
 					outSISIDXREG(SISPART2, 0x36, 0xFB);
@@ -3538,8 +4096,8 @@
 			}
 		}
 
-		if ((filter >= 0) && (filter <=7)) {
-			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter, 
+		if ((filter >= 0) && (filter <= 7)) {
+			DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
 				sis_TV_filter[filter_tb].filter[filter][0],
 				sis_TV_filter[filter_tb].filter[filter][1],
 				sis_TV_filter[filter_tb].filter[filter][2],
@@ -3550,8 +4108,6 @@
 			outSISIDXREG(SISPART2, 0x37, (sis_TV_filter[filter_tb].filter[filter][2]));
 			outSISIDXREG(SISPART2, 0x38, (sis_TV_filter[filter_tb].filter[filter][3]));
 		}
-
-	     }
 	  
 	}
 
@@ -3563,12 +4119,15 @@
 	char *this_opt;
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	sis_fb_info.fontname[0] = '\0';
-#endif	
+	sisfb_fontname[0] = '\0';
+#endif
 
 	ivideo.refresh_rate = 0;
+	SiS_Pr.SiS_CustomT = CUT_NONE;
+	SiS_Pr.UsePanelScaler = -1;
+	SiS_Pr.LVDSHL = -1;
 
-        printk(KERN_INFO "sisfb: Options %s\n", options);
+        printk(KERN_DEBUG "sisfb: Options %s\n", options);
 
 	if (!options || !*options)
 		return 0;
@@ -3577,72 +4136,78 @@
 
 		if (!*this_opt)	continue;
 
-		if (!strncmp(this_opt, "mode:", 5)) {
-			sisfb_search_mode(this_opt + 5);
-		} else if (!strncmp(this_opt, "vesa:", 5)) {
-			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)			
-		} else if (!strcmp(this_opt, "inverse")) {
+		if (!strnicmp(this_opt, "mode:", 5)) {
+			sisfb_search_mode(this_opt + 5, FALSE);
+		} else if (!strnicmp(this_opt, "vesa:", 5)) {
+			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0), FALSE);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+		} else if (!strnicmp(this_opt, "inverse", 7)) {
 			sisfb_inverse = 1;
 			/* fb_invert_cmaps(); */
-		} else if (!strncmp(this_opt, "font:", 5)) {
-			strcpy(sis_fb_info.fontname, this_opt + 5);
-#endif			
-		} else if (!strncmp(this_opt, "mode:", 5)) {
-			sisfb_search_mode(this_opt + 5);
-		} else if (!strncmp(this_opt, "vesa:", 5)) {
-			sisfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
-		} else if (!strncmp(this_opt, "vrate:", 6)) {
+		} else if (!strnicmp(this_opt, "font:", 5)) {
+			strncpy(sisfb_fontname, this_opt + 5, sizeof(sisfb_fontname) - 1);
+			sisfb_fontname[sizeof(sisfb_fontname) - 1] = '\0';
+#endif
+		} else if (!strnicmp(this_opt, "vrate:", 6)) {
 			ivideo.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
-		} else if (!strncmp(this_opt, "rate:", 5)) {
+			sisfb_parm_rate = ivideo.refresh_rate;
+		} else if (!strnicmp(this_opt, "rate:", 5)) {
 			ivideo.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
-		} else if (!strncmp(this_opt, "off", 3)) {
+			sisfb_parm_rate = ivideo.refresh_rate;
+		} else if (!strnicmp(this_opt, "off", 3)) {
 			sisfb_off = 1;
-		} else if (!strncmp(this_opt, "crt1off", 7)) {
+		} else if (!strnicmp(this_opt, "crt1off", 7)) {
 			sisfb_crt1off = 1;
-		} else if (!strncmp(this_opt, "filter:", 7)) {
+		} else if (!strnicmp(this_opt, "filter:", 7)) {
 			filter = (int)simple_strtoul(this_opt + 7, NULL, 0);
-		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
+		} else if (!strnicmp(this_opt, "forcecrt2type:", 14)) {
 			sisfb_search_crt2type(this_opt + 14);
-		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
+		} else if (!strnicmp(this_opt, "forcecrt1:", 10)) {
 			sisfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
-                } else if (!strncmp(this_opt, "tvmode:",7)) {
+                } else if (!strnicmp(this_opt, "tvmode:",7)) {
 		        sisfb_search_tvstd(this_opt + 7);
-                } else if (!strncmp(this_opt, "tvstandard:",11)) {
+                } else if (!strnicmp(this_opt, "tvstandard:",11)) {
 			sisfb_search_tvstd(this_opt + 7);
-                } else if (!strncmp(this_opt, "mem:",4)) {
+                } else if (!strnicmp(this_opt, "mem:",4)) {
 		        sisfb_mem = simple_strtoul(this_opt + 4, NULL, 0);
-                } else if (!strncmp(this_opt, "dstn", 4)) {
-			enable_dstn = 1;
-			/* TW: DSTN overrules forcecrt2type */
-			sisfb_crt2type = DISPTYPE_LCD;
-		} else if (!strncmp(this_opt, "queuemode:", 10)) {
+		} else if (!strnicmp(this_opt, "queuemode:", 10)) {
 			sisfb_search_queuemode(this_opt + 10);
-		} else if (!strncmp(this_opt, "pdc:", 4)) {
+		} else if (!strnicmp(this_opt, "pdc:", 4)) {
 		        sisfb_pdc = simple_strtoul(this_opt + 4, NULL, 0);
-		        if(sisfb_pdc & ~0x3c) {
-			   printk(KERN_INFO "sisfb: Illegal pdc parameter\n");
-			   sisfb_pdc = 0;
-		        }
-		} else if (!strncmp(this_opt, "noaccel", 7)) {
+		} else if (!strnicmp(this_opt, "noaccel", 7)) {
 			sisfb_accel = 0;
-		} else if (!strncmp(this_opt, "noypan", 6)) {
+		} else if (!strnicmp(this_opt, "noypan", 6)) {
 		        sisfb_ypan = 0;
-		} else if (!strncmp(this_opt, "userom:", 7)) {
+		} else if (!strnicmp(this_opt, "userom:", 7)) {
 			sisfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
-		} else if (!strncmp(this_opt, "useoem:", 7)) {
+		} else if (!strnicmp(this_opt, "useoem:", 7)) {
 			sisfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0);
+		} else if (!strnicmp(this_opt, "nocrt2rate", 10)) {
+			sisfb_nocrt2rate = 1;
+	 	} else if (!strnicmp(this_opt, "scalelcd:", 9)) {
+		        unsigned long temp = 2;
+		        temp = simple_strtoul(this_opt + 9, NULL, 0);
+		        if((temp == 0) || (temp == 1)) {
+			   SiS_Pr.UsePanelScaler = temp ^ 1;
+		        }
+		} else if (!strnicmp(this_opt, "specialtiming:", 14)) {
+			sisfb_search_specialtiming(this_opt + 14);
+		} else if (!strnicmp(this_opt, "lvdshl:", 7)) {
+		        unsigned long temp = 4;
+		        temp = simple_strtoul(this_opt + 7, NULL, 0);
+		        if((temp >= 0) && (temp <= 3)) {
+			   SiS_Pr.LVDSHL = temp;
+		        }
+		} else if(this_opt[0] >= '0' && this_opt[0] <= '9') {
+			sisfb_search_mode(this_opt, TRUE);
 		} else {
 			printk(KERN_INFO "sisfb: Invalid option %s\n", this_opt);
 		}
 
 		/* TW: Acceleration only with MMIO mode */
 		if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
-			sisfb_ypan = 0;
 			sisfb_accel = 0;
 		}
-		/* TW: Panning only with acceleration */
-		if(sisfb_accel == 0) sisfb_ypan = 0;
 
 	}
 	return 0;
@@ -3661,14 +4226,14 @@
         char *sis_sig_300[4] = {
           "300", "540", "630", "730"
         };
-        char *sis_sig_310[7] = {
-          "315", "315", "315", "5315", "6325", "6325", "Xabre"
+        char *sis_sig_310[9] = {
+          "315", "315", "315", "5315", "6325", "6325", "Xabre", "6330", "6330"
         };
 	ushort sis_nums_300[4] = {
 	  SIS_300, SIS_540, SIS_630, SIS_730
 	};
-	unsigned short sis_nums_310[7] = {
-	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330
+	unsigned short sis_nums_310[9] = {
+	  SIS_315PRO, SIS_315H, SIS_315, SIS_550, SIS_650, SIS_740, SIS_330, SIS_660, SIS_760
 	};
 
         for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) {
@@ -3705,7 +4270,7 @@
                     }
                 }
 		if(stage != 4) {
-                   for(i = 0;(i < 7) && (stage != 4); i++) {
+                   for(i = 0;(i < 9) && (stage != 4); i++) {
                       if(strncmp(sis_sig_310[i], rom, strlen(sis_sig_310[i])) == 0) {
 		          if(sis_nums_310[i] == ivideo.chip) {
                              stage = 4;
@@ -3735,11 +4300,9 @@
 	int pdev_valid = 0;
 	u32 reg32;
 	u16 reg16;
-	u8  reg, reg1;
+	u8  reg;
 
-	/* outb(0x77, 0x80); */  /* What is this? */
-
-#if 0 	
+#if 0
 	/* for DOC VB */
 	sisfb_set_reg4(0xcf8,0x800000e0);
 	reg32 = sisfb_get_reg3(0xcfc);
@@ -3751,24 +4314,39 @@
 	if (sisfb_off)
 		return -ENXIO;
 
-	if (enable_dstn)
-		SiS_SetEnableDstn(&SiS_Pr);
-		
 	sisfb_registered = 0;
+	sisfb_thismonitor.datavalid = FALSE;
+
+	memset(&sishw_ext, 0, sizeof(sishw_ext));
 
-	memset(&sis_fb_info, 0, sizeof(sis_fb_info));
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+        memset(&sisfb_lastrates[0], 0, 128);
+#endif
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 	memset(&sis_disp, 0, sizeof(sis_disp));
-#endif	
+#endif
 
-	while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74)
+	pci_for_each_dev(pdev) {
+#else
+	while((pdev = pci_find_device(PCI_VENDOR_ID_SI, PCI_ANY_ID, pdev))) {
+#endif
 		for (b = sisdev_list; b->vendor; b++) {
 			if ((b->vendor == pdev->vendor)
 			    && (b->device == pdev->device)) {
 				pdev_valid = 1;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
-				strcpy(sis_fb_info.modename, b->name);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+				sis_fb_info = framebuffer_alloc(0, &pdev->dev);
+#else
+				sis_fb_info = kmalloc(sizeof(*sis_fb_info), GFP_KERNEL);
+#endif
+				if(!sis_fb_info) return -ENOMEM;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+				memset(sis_fb_info, 0, sizeof(*sis_fb_info));
+#endif
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, b->name);
 #else				
 				strcpy(myid, b->name);
 #endif				
@@ -3804,18 +4382,17 @@
 		break;
 	   case PCI_DEVICE_ID_SI_630_VGA:
 		{
+			ivideo.chip = SIS_630;
 			sisfb_set_reg4(0xCF8, 0x80000000);
 			reg32 = sisfb_get_reg3(0xCFC);
 			if(reg32 == 0x07301039) {
 				ivideo.chip = SIS_730;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
-				strcpy(sis_fb_info.modename, "SIS 730");
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 730");
 #else
 				strcpy(myid, "SIS 730");
-#endif				
-			} else
-				ivideo.chip = SIS_630;
-
+#endif
+			}
 			sisvga_engine = SIS_300_VGA;
 			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_300 * 2;
 			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_300;
@@ -3860,11 +4437,11 @@
 			reg32 = sisfb_get_reg3(0xCFC);
 			if(reg32 == 0x07401039) {
 				ivideo.chip = SIS_740;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)				
-				strcpy(sis_fb_info.modename, "SIS 740");
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 740");
 #else
-				strcpy(myid, "SIS 740");				
-#endif				
+				strcpy(myid, "SIS 740");
+#endif
 			}
 			sisvga_engine = SIS_315_VGA;
 			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
@@ -3877,8 +4454,27 @@
 		sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
 		sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
 		break;
+	   case PCI_DEVICE_ID_SI_660_VGA:
+	   	{
+			ivideo.chip = SIS_660;
+			sisfb_set_reg4(0xCF8, 0x80000000);
+			reg32 = sisfb_get_reg3(0xCFC);
+			if(reg32 == 0x07601039) {
+				ivideo.chip = SIS_760;
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)
+				strcpy(sis_fb_info->modename, "SIS 760");
+#else
+				strcpy(myid, "SIS 760");
+#endif
+			}
+			sisvga_engine = SIS_315_VGA;
+			sisfb_hwcursor_size = HW_CURSOR_AREA_SIZE_315 * 2;
+			sisfb_CRT2_write_enable = IND_SIS_CRT2_WRITE_ENABLE_315;
+			break;
+		}
 #endif
            default:
+	   	kfree(sis_fb_info);
 	        return -ENODEV;
 	}
 	sishw_ext.jChipType = ivideo.chip;
@@ -3890,73 +4486,56 @@
 
 	ivideo.video_base = pci_resource_start(pdev, 0);
 	ivideo.mmio_base = pci_resource_start(pdev, 1);
-	sishw_ext.ulIOAddress = (unsigned short) ivideo.vga_base =
-	    (unsigned short) SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
+	sishw_ext.ulIOAddress = SiS_Pr.RelIO = pci_resource_start(pdev, 2) + 0x30;
+	ivideo.vga_base = (unsigned short) sishw_ext.ulIOAddress;
 
 	sisfb_mmio_size =  pci_resource_len(pdev, 1);
 
 	if(!sisvga_enabled) {
-		if (pci_enable_device(pdev))   return -EIO;
+	   if(pci_enable_device(pdev)) {
+	      kfree(sis_fb_info);
+	      return -EIO;
+	   }
 	}
 
 	SiS_Pr.SiS_Backup70xx = 0xff;
         SiS_Pr.SiS_CHOverScan = -1;
         SiS_Pr.SiS_ChSW = FALSE;
 	SiS_Pr.SiS_UseLCDA = FALSE;
-	SiS_Pr.UsePanelScaler = -1;
-	SiSRegInit(&SiS_Pr, (USHORT)sishw_ext.ulIOAddress);
+	SiSRegInit(&SiS_Pr, sishw_ext.ulIOAddress);
 
 #ifdef CONFIG_FB_SIS_300
-	/* TW: Find PCI systems for Chrontel/ISA bridge manipulation */
+	/* TW: Find PCI systems for Chrontel/GPIO communication setup */
 	if(ivideo.chip == SIS_630) {
-	  int i=0;
-          do {
-	    if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
-	       mychswtable[i].subsysCard   == ivideo.subsysdevice) {
-		SiS_Pr.SiS_ChSW = TRUE;
-            }
-            i++;
-          } while(mychswtable[i].subsysVendor != 0);
+	   int i=0;
+           do {
+	      if(mychswtable[i].subsysVendor == ivideo.subsysvendor &&
+	         mychswtable[i].subsysCard   == ivideo.subsysdevice) {
+		 SiS_Pr.SiS_ChSW = TRUE;
+		 printk(KERN_DEBUG "sisfb: Identified [%s %s] requiring Chrontel/GPIO setup\n",
+		        mychswtable[i].vendorName, mychswtable[i].cardName);
+		 break;
+              }
+              i++;
+           } while(mychswtable[i].subsysVendor != 0);
 	}
 #endif
 
         outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		
-#ifdef MODULE	
+#ifdef MODULE
 	inSISIDXREG(SISCR,0x34,reg);
-	if(reg & 0x80) {
+	if((reg & 0x80) && (reg != 0xff)) {
 	   if((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF) {
 	      printk(KERN_INFO "sisfb: Cannot initialize display mode, X server is active\n");
+	      kfree(sis_fb_info);
 	      return -EBUSY;
 	   }
 	}
 #endif	
 #endif
 
-#ifdef LINUXBIOS  /* -------------------------------- */
-
-#ifdef CONFIG_FB_SIS_300
-	if (sisvga_engine == SIS_300_VGA) {
-	        outSISIDXREG(SISSR, 0x28, 0x37);
-
-                outSISIDXREG(SISSR, 0x29, 0x61);
-
-                orSISIDXREG(SISSR, IND_SIS_SCRATCH_REG_1A, SIS_SCRATCH_REG_1A_MASK);
-	}
-#endif
-#ifdef CONFIG_FB_SIS_315
-	if (ivideo.chip == SIS_550 || ivideo.chip == SIS_650 || ivideo.chip == SIS_740) {
-	        outSISIDXREG(SISSR, 0x28, 0x5a);
-
-                outSISIDXREG(SISSR, 0x29, 0x64);
-
-                outSISIDXREG(SISCR, 0x3a, 0x00);
-	}
-#endif		
-
-#endif /* LinuxBIOS  -------------------------------- */
-
 	if (sisvga_engine == SIS_315_VGA) {
 		switch (ivideo.chip) {
 		   case SIS_315H:
@@ -3967,6 +4546,8 @@
 		   case SIS_550:
 		   case SIS_650:
 		   case SIS_740:
+		   case SIS_660:
+		   case SIS_760:
 			sishw_ext.bIntegratedMMEnabled = TRUE;
 			break;
 		   default:
@@ -3984,7 +4565,6 @@
 		}
 	}
 
-	sishw_ext.pDevice = NULL;
 	if(sisfb_userom) {
 	    sishw_ext.pjVirtualRomBase = sis_find_rom();
 	    if(sishw_ext.pjVirtualRomBase) {
@@ -4000,23 +4580,74 @@
 	    sishw_ext.UseROM = FALSE;
 	    printk(KERN_INFO "sisfb: Video ROM usage disabled\n");
 	}
-	sishw_ext.pjCustomizedROMImage = NULL;
 	sishw_ext.bSkipDramSizing = 0;
 	sishw_ext.pQueryVGAConfigSpace = &sisfb_query_VGA_config_space;
 	sishw_ext.pQueryNorthBridgeSpace = &sisfb_query_north_bridge_space;
-	strcpy(sishw_ext.szVBIOSVer, "0.84");
 
-	/* TW: Mode numbers for 1280x960 are different for 300 and 310/325 series */
+        /* Find systems for special custom timing */
+	if(SiS_Pr.SiS_CustomT == CUT_NONE) {
+	   int i=0, j;
+	   unsigned char *biosver = NULL;
+           unsigned char *biosdate = NULL;
+	   BOOLEAN footprint;
+	   unsigned long chksum = 0;
+
+	   if(sishw_ext.UseROM) {
+	      biosver = sishw_ext.pjVirtualRomBase + 0x06;
+	      biosdate = sishw_ext.pjVirtualRomBase + 0x2c;
+              for(i=0; i<32768; i++) chksum += sishw_ext.pjVirtualRomBase[i];
+	   }
+
+	   i=0;
+           do {
+	      if( (mycustomttable[i].chipID == ivideo.chip) &&
+	          ((!strlen(mycustomttable[i].biosversion)) ||
+		   (sishw_ext.UseROM &&
+		   (!strncmp(mycustomttable[i].biosversion, biosver, strlen(mycustomttable[i].biosversion))))) &&
+	          ((!strlen(mycustomttable[i].biosdate)) ||
+		   (sishw_ext.UseROM &&
+		   (!strncmp(mycustomttable[i].biosdate, biosdate, strlen(mycustomttable[i].biosdate))))) &&
+		  ((!mycustomttable[i].bioschksum) ||
+		   (sishw_ext.UseROM &&
+	           (mycustomttable[i].bioschksum == chksum)))	&&
+		  (mycustomttable[i].pcisubsysvendor == ivideo.subsysvendor) &&
+		  (mycustomttable[i].pcisubsyscard == ivideo.subsysdevice) ) {
+		 footprint = TRUE;
+	         for(j=0; j<5; j++) {
+	            if(mycustomttable[i].biosFootprintAddr[j]) {
+		       if(sishw_ext.UseROM) {
+	                  if(sishw_ext.pjVirtualRomBase[mycustomttable[i].biosFootprintAddr[j]] !=
+		      		mycustomttable[i].biosFootprintData[j])
+		          footprint = FALSE;
+		       } else footprint = FALSE;
+		    }
+	         }
+	         if(footprint) {
+	 	    SiS_Pr.SiS_CustomT = mycustomttable[i].SpecialID;
+		    printk(KERN_DEBUG "sisfb: Identified [%s %s], special timing applies\n",
+		        mycustomttable[i].vendorName,
+			mycustomttable[i].cardName);
+	            break;
+                 }
+	      }
+              i++;
+           } while(mycustomttable[i].chipID);
+	}
+
+#ifdef CONFIG_FB_SIS_300
+	/* Mode numbers for 1280x768 are different for 300 and 315 series */
 	if(sisvga_engine == SIS_300_VGA) {
-		sisbios_mode[MODEINDEX_1280x960].mode_no = 0x6e;
-		sisbios_mode[MODEINDEX_1280x960+1].mode_no = 0x6f;
-		sisbios_mode[MODEINDEX_1280x960+2].mode_no = 0x7b;
-		sisbios_mode[MODEINDEX_1280x960+3].mode_no = 0x7b;
+		sisbios_mode[MODEINDEX_1280x768].mode_no = 0x55;
+		sisbios_mode[MODEINDEX_1280x768+1].mode_no = 0x5a;
+		sisbios_mode[MODEINDEX_1280x768+2].mode_no = 0x5b;
+		sisbios_mode[MODEINDEX_1280x768+3].mode_no = 0x5b;
 	}
+#endif
 
 	sishw_ext.pSR = vmalloc(sizeof(SIS_DSReg) * SR_BUFFER_SIZE);
 	if (sishw_ext.pSR == NULL) {
 		printk(KERN_ERR "sisfb: Fatal error: Allocating SRReg space failed.\n");
+		kfree(sis_fb_info);
 		return -ENODEV;
 	}
 	sishw_ext.pSR[0].jIdx = sishw_ext.pSR[0].jVal = 0xFF;
@@ -4025,6 +4656,7 @@
 	if (sishw_ext.pCR == NULL) {
 	        vfree(sishw_ext.pSR);
 		printk(KERN_ERR "sisfb: Fatal error: Allocating CRReg space failed.\n");
+		kfree(sis_fb_info);
 		return -ENODEV;
 	}
 	sishw_ext.pCR[0].jIdx = sishw_ext.pCR[0].jVal = 0xFF;
@@ -4036,29 +4668,14 @@
 			sishw_ext.pjVideoMemoryAddress
 				= ioremap(ivideo.video_base, 0x4000000);
 			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
-#ifdef LINUXBIOS		/* TW: SiSInit now for LinuxBIOS only */	        
-				SiSInit(&SiS_Pr, &sishw_ext);
-#endif
-				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-			}
-		}
-#ifdef LINUXBIOS
-		else {
-			sishw_ext.pjVideoMemoryAddress
-				= ioremap(ivideo.video_base, 0x4000000);
-			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) {
-				SiSInit(&SiS_Pr, &sishw_ext);
 				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 			}
 		}
-		if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
-		        orSISIDXREG(SISSR, 0x07, 0x10);
-		}
-#endif
 		if(sisfb_get_dram_size_300()) {
 		        vfree(sishw_ext.pSR);
 			vfree(sishw_ext.pCR);
 			printk(KERN_ERR "sisfb: Fatal error: Unable to determine RAM size\n");
+			kfree(sis_fb_info);
 			return -ENODEV;
 		}
 	}
@@ -4071,32 +4688,7 @@
 			sishw_ext.pjVideoMemoryAddress 
 				= ioremap(ivideo.video_base, 0x8000000);
 			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
-#ifdef LINUXBIOS
-			        /* TW: SISInit is now for LINUXBIOS only */
-				SiSInit(&SiS_Pr, &sishw_ext);
-#endif
-
-				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
-				sishw_ext.bSkipDramSizing = TRUE;
-				sishw_ext.pSR[0].jIdx = 0x13;
-				sishw_ext.pSR[1].jIdx = 0x14;
-				sishw_ext.pSR[2].jIdx = 0xFF;
-				inSISIDXREG(SISSR, 0x13, sishw_ext.pSR[0].jVal);
-				inSISIDXREG(SISSR, 0x14, sishw_ext.pSR[1].jVal);
-				sishw_ext.pSR[2].jVal = 0xFF;
-			}
-		}
-#ifdef LINUXBIOS
-		else {
-			sishw_ext.pjVideoMemoryAddress
-				= ioremap(ivideo.video_base, 0x8000000);
-			if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
-
-				SiSInit(&SiS_Pr, &sishw_ext);
-
 				outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
-
 				sishw_ext.bSkipDramSizing = TRUE;
 				sishw_ext.pSR[0].jIdx = 0x13;
 				sishw_ext.pSR[1].jIdx = 0x14;
@@ -4106,11 +4698,11 @@
 				sishw_ext.pSR[2].jVal = 0xFF;
 			}
 		}
-#endif
-		if (sisfb_get_dram_size_315()) {
+		if(sisfb_get_dram_size_315()) {
 			vfree(sishw_ext.pSR);
 			vfree(sishw_ext.pCR);
 			printk(KERN_INFO "sisfb: Fatal error: Unable to determine RAM size.\n");
+			kfree(sis_fb_info);
 			return -ENODEV;
 		}
 	}
@@ -4128,6 +4720,7 @@
 
 	sishw_ext.ulVideoMemorySize = ivideo.video_size;
 
+	if(sisvga_engine == SIS_300_VGA) sisfb_pdc &= 0x3c;
 	if(sisfb_pdc) {
 	    sishw_ext.pdc = sisfb_pdc;
 	} else {
@@ -4139,6 +4732,7 @@
 		printk(KERN_ERR "sisfb: Is there another framebuffer driver active?\n");
 		vfree(sishw_ext.pSR);
 		vfree(sishw_ext.pCR);
+		kfree(sis_fb_info);
 		return -ENODEV;
 	}
 
@@ -4147,6 +4741,7 @@
 		release_mem_region(ivideo.video_base, ivideo.video_size);
 		vfree(sishw_ext.pSR);
 		vfree(sishw_ext.pCR);
+		kfree(sis_fb_info);
 		return -ENODEV;
 	}
 
@@ -4167,131 +4762,64 @@
 	}
 
 	ivideo.mtrr = (unsigned int) 0;
+
+	ivideo.vbflags = 0;
 
 	if((sisfb_mode_idx < 0) || ((sisbios_mode[sisfb_mode_idx].mode_no) != 0xFF)) { 
-
-#ifdef CONFIG_FB_SIS_300
-		if (sisvga_engine == SIS_300_VGA) {
-			sisfb_get_VB_type_300();
-		}
-#endif
-
-#ifdef CONFIG_FB_SIS_315
-		if (sisvga_engine == SIS_315_VGA) {
-			sisfb_get_VB_type_315();
-		}
-#endif
-
+
 		sishw_ext.ujVBChipID = VB_CHIP_UNKNOWN;
 		sishw_ext.Is301BDH = FALSE;
 		sishw_ext.usExternalChip = 0;
 
-		switch (ivideo.hasVB) {
-
-		case HASVB_301:
-		        inSISIDXREG(SISPART4, 0x01, reg);
-			if (reg >= 0xE0) {
-				sishw_ext.ujVBChipID = VB_CHIP_302LV;
-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
-	  		} else if (reg >= 0xD0) {
-				sishw_ext.ujVBChipID = VB_CHIP_301LV;
-				printk(KERN_INFO "sisfb: SiS301LV bridge detected (revision 0x%02x)\n",reg);
-	  		} else if (reg >= 0xB0) {
-				sishw_ext.ujVBChipID = VB_CHIP_301B;
-				inSISIDXREG(SISPART4,0x23,reg1);
-				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
-				printk(KERN_INFO "sisfb: SiS301B%s bridge detected (revision 0x%02x)\n",
-					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
-			} else {
-				sishw_ext.ujVBChipID = VB_CHIP_301;
-				printk(KERN_INFO "sisfb: SiS301 bridge detected\n");
-			}
-			break;
-		case HASVB_302:
-		        inSISIDXREG(SISPART4, 0x01, reg);
-			if (reg >= 0xE0) {
-				sishw_ext.ujVBChipID = VB_CHIP_302LV;
-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
-	  		} else if (reg >= 0xD0) {
-				sishw_ext.ujVBChipID = VB_CHIP_301LV;
-				printk(KERN_INFO "sisfb: SiS302LV bridge detected (revision 0x%02x)\n",reg);
-	  		} else if (reg >= 0xB0) {
-				inSISIDXREG(SISPART4,0x23,reg1);
-				if(!(reg1 & 0x02)) sishw_ext.Is301BDH = TRUE;
-			        sishw_ext.ujVBChipID = VB_CHIP_302B;
-				printk(KERN_INFO "sisfb: SiS302B%s bridge detected (revision 0x%02x)\n",
-					(sishw_ext.Is301BDH ? "-DH" : ""), reg);
-			} else {
-			        sishw_ext.ujVBChipID = VB_CHIP_302;
-				printk(KERN_INFO "sisfb: SiS302 bridge detected\n");
-			}
-			break;
-		case HASVB_LVDS:
-			sishw_ext.usExternalChip = 0x1;
-			printk(KERN_INFO "sisfb: LVDS transmitter detected\n");
-			break;
-		case HASVB_TRUMPION:
-			sishw_ext.usExternalChip = 0x2;
-			printk(KERN_INFO "sisfb: Trumpion Zurac LVDS scaler detected\n");
-			break;
-		case HASVB_CHRONTEL:
-			sishw_ext.usExternalChip = 0x4;
-			printk(KERN_INFO "sisfb: Chrontel TV encoder detected\n");
-			break;
-		case HASVB_LVDS_CHRONTEL:
-			sishw_ext.usExternalChip = 0x5;
-			printk(KERN_INFO "sisfb: LVDS transmitter and Chrontel TV encoder detected\n");
-			break;
-		default:
-			printk(KERN_INFO "sisfb: No or unknown bridge type detected\n");
-			break;
-		}
-
-		if (ivideo.hasVB != HASVB_NONE) {
-#ifdef CONFIG_FB_SIS_300
-		      if (sisvga_engine == SIS_300_VGA) {
-				sisfb_detect_VB_connect_300();
-                      }
-#endif
-#ifdef CONFIG_FB_SIS_315
-		      if (sisvga_engine == SIS_315_VGA) {
-				sisfb_detect_VB_connect_315();
-                      }
-#endif
+		sisfb_sense_crt1();
+
+		sisfb_get_VB_type();
+
+		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
+			sisfb_detect_VB_connect();
 		}
-
-		if (ivideo.disp_state & DISPTYPE_DISP2) {
-			if (sisfb_crt1off)
-				ivideo.disp_state |= DISPMODE_SINGLE;
-			else
-				ivideo.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
-		} else {
-			ivideo.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
+
+		ivideo.currentvbflags = ivideo.vbflags & VB_VIDEOBRIDGE;
+
+		if(ivideo.vbflags & VB_VIDEOBRIDGE) {
+		   if(sisfb_crt2type != -1) {
+		      if((sisfb_crt2type == CRT2_LCD) && (ivideo.vbflags & CRT2_LCD)) {
+		         ivideo.currentvbflags |= CRT2_LCD;
+		      } else if(sisfb_crt2type != CRT2_LCD) {
+		         ivideo.currentvbflags |= sisfb_crt2type;
+		      }
+		   } else {
+		      /* Chrontel 700x TV detection often unreliable, therefore use a
+		       * different default order on such machines
+		       */
+		      if((sisvga_engine == SIS_300_VGA) && (ivideo.vbflags & VB_CHRONTEL)) {
+		         if(ivideo.vbflags & CRT2_LCD)      ivideo.currentvbflags |= CRT2_LCD;
+		         else if(ivideo.vbflags & CRT2_TV)  ivideo.currentvbflags |= CRT2_TV;
+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+		      } else {
+		         if(ivideo.vbflags & CRT2_TV)       ivideo.currentvbflags |= CRT2_TV;
+		         else if(ivideo.vbflags & CRT2_LCD) ivideo.currentvbflags |= CRT2_LCD;
+		         else if(ivideo.vbflags & CRT2_VGA) ivideo.currentvbflags |= CRT2_VGA;
+		      }
+		   }
 		}
 
-		if (ivideo.disp_state & DISPTYPE_LCD) {
-		    if (!enable_dstn) {
-		        inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
-			reg &= 0x0f;
-			if (sisvga_engine == SIS_300_VGA) {
-			    sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
-			} else {
-			    sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
-			}
-		    } else {
-		        /* TW: FSTN/DSTN */
-			sishw_ext.ulCRT2LCDType = LCD_320x480;
-		    }
+		if(ivideo.vbflags & CRT2_LCD) {
+		   inSISIDXREG(SISCR, IND_SIS_LCD_PANEL, reg);
+		   reg &= 0x0f;
+		   if(sisvga_engine == SIS_300_VGA) {
+		      sishw_ext.ulCRT2LCDType = sis300paneltype[reg];
+		   } else {
+		      sishw_ext.ulCRT2LCDType = sis310paneltype[reg];
+		   }
 		}
 		
 		sisfb_detectedpdc = 0;
-#ifndef LINUXBIOS
+
 #ifdef CONFIG_FB_SIS_300
                 /* TW: Save the current PanelDelayCompensation if the LCD is currently used */
 		if(sisvga_engine == SIS_300_VGA) {
-	          if((sishw_ext.usExternalChip == 0x01) ||   /* LVDS */
-		     (sishw_ext.usExternalChip == 0x05) ||   /* LVDS+Chrontel */
-		     (sishw_ext.Is301BDH)) {		     /* 301B-DH */
+	          if(ivideo.vbflags & (VB_LVDS | VB_30xBDH)) {
 		       int tmp;
 		       inSISIDXREG(SISCR,0x30,tmp);
 		       if(tmp & 0x20) {
@@ -4314,60 +4842,85 @@
 	          }
 		}
 #endif
-#endif
+
 	        sisfb_detectedlcda = 0xff;
-#ifndef LINUXBIOS
+
 #ifdef CONFIG_FB_SIS_315
-                /* TW: Try to find about LCDA */
+
 		if(sisvga_engine == SIS_315_VGA) {
-	          if((sishw_ext.ujVBChipID == VB_CHIP_302B) ||
-		     (sishw_ext.ujVBChipID == VB_CHIP_301LV) ||
-		     (sishw_ext.ujVBChipID == VB_CHIP_302LV)) {
-		       int tmp;
-		       inSISIDXREG(SISCR,0x34,tmp);
-		       if(tmp <= 0x13) {	
-		          /* Currently on LCDA? (Some BIOSes leave CR38) */
-		          inSISIDXREG(SISCR,0x38,tmp);
-			  if((tmp & 0x03) == 0x03) {
-			     SiS_Pr.SiS_UseLCDA = TRUE;
-			  } else {
-			     /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
-			     inSISIDXREG(SISCR,0x35,tmp);
-			     if(tmp & 0x01) {
-			        SiS_Pr.SiS_UseLCDA = TRUE;
-			     } else {
-			        /* Currently on LCD? If so, we can find out 
-				   by peeking the mode register 
-				 */
-			        inSISIDXREG(SISCR,0x30,tmp);
-			        if(tmp & 0x20) {
-			           inSISIDXREG(SISPART1,0x13,tmp);
-				   if(tmp & 0x04) {
-				      SiS_Pr.SiS_UseLCDA = TRUE;
-				   }
-			        }
-			     }
-			  }
-		       } 
-		       if(SiS_Pr.SiS_UseLCDA) {
-		          sisfb_detectedlcda = 0x03;
-		          printk(KERN_INFO
-			         "sisfb: Bridge uses LCDA for low resolution and text modes\n");
-		       }
+		   /* Save PDC */
+		   if(ivideo.vbflags & (VB_301LV | VB_302LV)) {
+		      int tmp;
+		      inSISIDXREG(SISCR,0x30,tmp);
+		      if(tmp & 0x20) {
+		         /* Currently on LCD? If yes, read current pdc */
+		         inSISIDXREG(SISPART1,0x2D,sisfb_detectedpdc);
+			 if(sishw_ext.pdc == 0) {
+			    /* Let option override detection */
+			    sishw_ext.pdc = sisfb_detectedpdc;
+			 }
+			 printk(KERN_INFO
+			        "sisfb: Detected LCD PanelDelayCompensation %d\n",
+  			         sisfb_detectedpdc);
+		      }
+		      if((sishw_ext.pdc) && (sishw_ext.pdc != sisfb_detectedpdc)) {
+		         printk(KERN_INFO
+			         "sisfb: Using LCD PanelDelayCompensation %d\n",
+				 sishw_ext.pdc);
+		      }
+		   }
+
+		   /* Try to find about LCDA */
+		   if(ivideo.vbflags & (VB_302B | VB_301LV | VB_302LV)) {
+		      int tmp;
+		      inSISIDXREG(SISCR,0x34,tmp);
+		      if((tmp <= 0x13) || (tmp == 0xff)) {
+		         /* Currently on LCDA? (Some BIOSes leave CR38) */
+		         inSISIDXREG(SISCR,0x38,tmp);
+			 if((tmp & 0x03) == 0x03)  SiS_Pr.SiS_UseLCDA = TRUE;
+			 else {
+			    /* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
+			    inSISIDXREG(SISCR,0x35,tmp);
+			    if(tmp & 0x01) SiS_Pr.SiS_UseLCDA = TRUE;
+			    else {
+			       /* Currently on LCD? If so, we can find out
+			        * by peeking the mode register
+				*/
+			       inSISIDXREG(SISCR,0x30,tmp);
+			       if(tmp & 0x20) {
+			          inSISIDXREG(SISPART1,0x13,tmp);
+				  if(tmp & 0x04) SiS_Pr.SiS_UseLCDA = TRUE;
+			       }
+			    }
+			 }
+		      }
+		      if(SiS_Pr.SiS_UseLCDA) {
+		         sisfb_detectedlcda = 0x03;
+		         printk(KERN_DEBUG
+			        "sisfb: Bridge uses LCDA for low resolution and text modes\n");
+		      }
 	          }
 		}
 #endif
-#endif
+
+		if (!sisfb_crt1off) {
+		   	sisfb_handle_ddc(&sisfb_thismonitor, 0);
+		} else {
+		   	if ((ivideo.vbflags & (VB_301|VB_301B|VB_301C|VB_302B)) &&
+		      	    (ivideo.vbflags & (CRT2_VGA | CRT2_LCD))) {
+		      		sisfb_handle_ddc(&sisfb_thismonitor, 1);
+		   	}
+		}
 
 		if (sisfb_mode_idx >= 0)
-			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx);
+			sisfb_mode_idx = sisfb_validate_mode(sisfb_mode_idx, ivideo.currentvbflags);
 
 		if (sisfb_mode_idx < 0) {
-			switch (ivideo.disp_state & DISPTYPE_DISP2) {
-			   case DISPTYPE_LCD:
+			switch (ivideo.currentvbflags & VB_DISPTYPE_DISP2) {
+			   case CRT2_LCD:
 				sisfb_mode_idx = DEFAULT_LCDMODE;
 				break;
-			   case DISPTYPE_TV:
+			   case CRT2_TV:
 				sisfb_mode_idx = DEFAULT_TVMODE;
 				break;
 			   default:
@@ -4379,39 +4932,27 @@
 		sisfb_mode_no = sisbios_mode[sisfb_mode_idx].mode_no;
 
 		if (ivideo.refresh_rate != 0)
-			sisfb_search_refresh_rate(ivideo.refresh_rate);
+			sisfb_search_refresh_rate(ivideo.refresh_rate, sisfb_mode_idx);
 
 		if (sisfb_rate_idx == 0) {
 			sisfb_rate_idx = sisbios_mode[sisfb_mode_idx].rate_idx;
 			ivideo.refresh_rate = 60;
 		}
 
+		if (sisfb_thismonitor.datavalid) {
+			if(!sisfb_verify_rate(&sisfb_thismonitor, sisfb_mode_idx,
+			                      sisfb_rate_idx, ivideo.refresh_rate)) {
+				printk(KERN_INFO "sisfb: WARNING: Refresh rate exceeds monitor specs!\n");
+			}
+		}
+
 		ivideo.video_bpp = sisbios_mode[sisfb_mode_idx].bpp;
 		ivideo.video_vwidth = ivideo.video_width = sisbios_mode[sisfb_mode_idx].xres;
 		ivideo.video_vheight = ivideo.video_height = sisbios_mode[sisfb_mode_idx].yres;
 		ivideo.org_x = ivideo.org_y = 0;
 		ivideo.video_linelength = ivideo.video_width * (ivideo.video_bpp >> 3);
-		switch(ivideo.video_bpp) {
-        	case 8:
-            		ivideo.DstColor = 0x0000;
-	    		ivideo.SiS310_AccelDepth = 0x00000000;
-			ivideo.video_cmap_len = 256;
-            		break;
-        	case 16:
-            		ivideo.DstColor = 0x8000;
-            		ivideo.SiS310_AccelDepth = 0x00010000;
-			ivideo.video_cmap_len = 16;
-            		break;
-        	case 32:
-            		ivideo.DstColor = 0xC000;
-	    		ivideo.SiS310_AccelDepth = 0x00020000;
-			ivideo.video_cmap_len = 16;
-            		break;
-		default:
-			ivideo.video_cmap_len = 16;
-		        printk(KERN_INFO "sisfb: Unsupported depth %d", ivideo.video_bpp);
-			break;
-    		}
+
+		sisfb_set_vparms();
 		
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 
@@ -4424,30 +4965,54 @@
 		sisfb_pre_setmode();
 
 		if (SiSSetMode(&SiS_Pr, &sishw_ext, sisfb_mode_no) == 0) {
-			printk(KERN_ERR "sisfb: Setting mode[0x%x] failed, using default mode\n", 
+			printk(KERN_ERR "sisfb: Fatal error: Setting mode[0x%x] failed\n",
 				sisfb_mode_no);
-			return -1;
+			vfree(sishw_ext.pSR);
+			vfree(sishw_ext.pCR);
+			release_mem_region(ivideo.video_base, ivideo.video_size);
+			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+			kfree(sis_fb_info);
+			return -EINVAL;
 		}
 
 		outSISIDXREG(SISSR, IND_SIS_PASSWORD, SIS_PASSWORD);
 
 		sisfb_post_setmode();
+
+		ivideo.accel = 0;
+		if(sisfb_accel) {
+		   ivideo.accel = -1;
+		   default_var.accel_flags |= FB_ACCELF_TEXT;
+		   sisfb_initaccel();
+		}
 
 		sisfb_crtc_to_var(&default_var);
 		
+		sis_fb_info->node = -1;
+		sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
+		sis_fb_info->blank = &sisfb_blank;
+		sis_fb_info->fbops = &sisfb_ops;
+		sis_fb_info->switch_con = &sisfb_switch;
+		sis_fb_info->updatevar = &sisfb_update_var;
+		sis_fb_info->changevar = NULL;
+		sis_fb_info->disp = &sis_disp;
+		strcpy(sis_fb_info->fontname, sisfb_fontname);
+
+		sisfb_set_disp(-1, &default_var, sis_fb_info);
+
 #else		/* --------- For 2.5: Setup a somewhat sane default var ------------ */
 
 		printk(KERN_INFO "sisfb: Default mode is %dx%dx%d (%dHz)\n",
 	       		ivideo.video_width, ivideo.video_height, ivideo.video_bpp,
 			ivideo.refresh_rate);
-			
+
 		default_var.xres = default_var.xres_virtual = ivideo.video_width;
 		default_var.yres = default_var.yres_virtual = ivideo.video_height;
 		default_var.bits_per_pixel = ivideo.video_bpp;
-		
+
 		sisfb_bpp_to_var(&default_var);
 		
-		default_var.pixclock = (u32) (1E12 /
+		default_var.pixclock = (u32) (1000000000 /
 				sisfb_mode_rate_to_dclock(&SiS_Pr, &sishw_ext,
 						sisfb_mode_no, sisfb_rate_idx));
 						
@@ -4457,28 +5022,10 @@
 			 &default_var.upper_margin, &default_var.lower_margin,
 			 &default_var.hsync_len, &default_var.vsync_len,
 			 &default_var.sync, &default_var.vmode)) {
-			 
-		   if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
-		      default_var.yres <<= 1;
-		      default_var.yres_virtual <<= 1;
-		   } else if((default_var.vmode	& FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
-		      default_var.pixclock >>= 1;
-		      default_var.yres >>= 1;
-		      default_var.yres_virtual >>= 1;
-		   }
-		   
+			if((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+				default_var.pixclock <<= 1;
+	   		}
 	        }
-#ifdef SISFB_PAN
-		if(sisfb_ypan) {
-	    		default_var.yres_virtual = 
-				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
-	    		if(default_var.yres_virtual <= default_var.yres) {
-	        		default_var.yres_virtual = default_var.yres;
-	    		}
-		} 
-#endif
-		
-#endif
 
 		ivideo.accel = 0;
 		if(sisfb_accel) {
@@ -4486,33 +5033,30 @@
 		   default_var.accel_flags |= FB_ACCELF_TEXT;
 		   sisfb_initaccel();
 		}
+
+		if(sisfb_ypan) {
+	    		default_var.yres_virtual =
+				ivideo.heapstart / (default_var.xres * (default_var.bits_per_pixel >> 3));
+	    		if(default_var.yres_virtual <= default_var.yres) {
+	        		default_var.yres_virtual = default_var.yres;
+	    		}
+		}
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)		/* ---- 2.4 series init ---- */
-		sis_fb_info.node = -1;
-		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
-		sis_fb_info.blank = &sisfb_blank;
-		sis_fb_info.fbops = &sisfb_ops;
-		sis_fb_info.switch_con = &sisfb_switch;
-		sis_fb_info.updatevar = &sisfb_update_var;
-		sis_fb_info.changevar = NULL;
-		sis_fb_info.disp = &sis_disp;
-			
-		sisfb_set_disp(-1, &default_var, &sis_fb_info);
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)		/* ---- 2.5 series init ---- */
-		sis_fb_info.flags = FBINFO_FLAG_DEFAULT;
-		sis_fb_info.var = default_var;
-		sis_fb_info.fix = sisfb_fix;
-		sis_fb_info.par = &ivideo;
-		sis_fb_info.screen_base = ivideo.video_vbase;
-		sis_fb_info.fbops = &sisfb_ops;
-		sisfb_get_fix(&sis_fb_info.fix, -1, &sis_fb_info);
-		sis_fb_info.pseudo_palette = pseudo_palette;
+		sis_fb_info->flags = FBINFO_FLAG_DEFAULT;
+		sis_fb_info->var = default_var;
+		sis_fb_info->fix = sisfb_fix;
+		sis_fb_info->par = &ivideo;
+		sis_fb_info->screen_base = ivideo.video_vbase;
+		sis_fb_info->fbops = &sisfb_ops;
+		sis_fb_info->class_dev.dev = &pdev->dev;
+		sisfb_get_fix(&sis_fb_info->fix, -1, sis_fb_info);
+		sis_fb_info->pseudo_palette = pseudo_palette;
 		
-		fb_alloc_cmap(&sis_fb_info.cmap, 256 , 0);
+		fb_alloc_cmap(&sis_fb_info->cmap, 256 , 0);
 #endif
 
+		printk(KERN_INFO "sisfb: Initial vbflags 0x%lx\n", ivideo.vbflags);
+
 #ifdef CONFIG_MTRR
 		ivideo.mtrr = mtrr_add((unsigned int) ivideo.video_base,
 				(unsigned int) ivideo.video_size,
@@ -4520,20 +5064,29 @@
 		if(ivideo.mtrr) {
 			printk(KERN_INFO "sisfb: Added MTRRs\n");
 		}
+
 #endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		vc_resize_con(1, 1, 0);
 #endif
 
-		TWDEBUG("Before calling register_framebuffer");
-		
-		if(register_framebuffer(&sis_fb_info) < 0)
+		if(register_framebuffer(sis_fb_info) < 0) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+			vfree(sishw_ext.pSR);
+			vfree(sishw_ext.pCR);
+			release_mem_region(ivideo.video_base, ivideo.video_size);
+			release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
+#endif
+			printk(KERN_ERR "sisfb: Fatal error: Failed to register framebuffer\n");
+			kfree(sis_fb_info);
 			return -EINVAL;
-			
+		}
+
 		sisfb_registered = 1;			
 
 		printk(KERN_INFO "sisfb: Installed SISFB_GET_INFO ioctl (%x)\n", SISFB_GET_INFO);
+		printk(KERN_INFO "sisfb: Installed SISFB_GET_VBRSTATUS ioctl (%x)\n", SISFB_GET_VBRSTATUS);
 		
 		printk(KERN_INFO "sisfb: 2D acceleration is %s, scrolling mode %s\n",
 		     sisfb_accel ? "enabled" : "disabled",
@@ -4541,15 +5094,17 @@
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-	       		GET_FB_IDX(sis_fb_info.node), sis_fb_info.modename, VER_MAJOR, VER_MINOR,
+	       		GET_FB_IDX(sis_fb_info->node), sis_fb_info->modename, VER_MAJOR, VER_MINOR,
 	       		VER_LEVEL);		     
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-	       		sis_fb_info.node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);			     
+	       		sis_fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 #endif
 
+		printk(KERN_INFO "sisfb: (C) 2001-2003 Thomas Winischhofer. All rights reserved.\n");
+
 	}	/* TW: if mode = "none" */
 	return 0;
 }
@@ -4562,7 +5117,6 @@
 static unsigned int rate = 0;
 static unsigned int crt1off = 1;
 static unsigned int mem = 0;
-static unsigned int dstn = 0;
 static char         *forcecrt2type = NULL;
 static int          forcecrt1 = -1;
 static char         *queuemode = NULL;
@@ -4575,25 +5129,34 @@
 static int          userom = 1;
 static int          useoem = -1;
 static char         *tvstandard = NULL;
+static int	    nocrt2rate = 0;
+static int          scalelcd = -1;
+static char	    *specialtiming = NULL;
+static int	    lvdshl = -1;
 
-MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/740/330 framebuffer driver");
+MODULE_DESCRIPTION("SiS 300/540/630/730/315/550/650/651/661/740/741/330/760 framebuffer driver");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SiS; Thomas Winischhofer <thomas@winischhofer.net>; Various others");
+MODULE_AUTHOR("Thomas Winischhofer <thomas@winischhofer.net>; SiS; Various others");
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode,
        "\nSelects the desired display mode in the format [X]x[Y]x[Depth], eg.\n"
-         "800x600x16 (default: none if sisfb is a module; this leaves the\n"
-	 "console untouched and the driver will only do the video memory\n"
-	 "management for eg. DRM/DRI; 800x600x8 if sisfb is in the kernel)");
+         "1024x768x16. Other formats supported include XxY-Depth and\n"
+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+	 "number, it will be interpreted as a VESA mode number. (default: none if\n"
+	 "sisfb is a module; this leaves the console untouched and the driver will\n"
+	 "only do the video memory management for eg. DRM/DRI; 800x600x8 if sisfb\n"
+	 "is in the kernel)");
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
 MODULE_PARM(mode, "s");
 MODULE_PARM_DESC(mode,
-       "\nSelects the desired default display mode in the format [X]x[Y]x[Depth],\n"
-         "eg. 1024x768x16 (default: 800x600x8)");
-#endif	 
+       "\nSelects the desired default display mode in the format XxYxDepth,\n"
+         "eg. 1024x768x16. Other formats supported include XxY-Depth and\n"
+	 "XxY-Depth@Rate. If the parameter is only one (decimal or hexadecimal)\n"
+	 "number, it will be interpreted as a VESA mode number. (default: 800x600x8)");
+#endif
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 MODULE_PARM(vesa, "i");
@@ -4603,17 +5166,18 @@
 	 "and the driver will only do the video memory management for eg. DRM/DRI;\n"
 	 "0x0103 if sisfb is in the kernel)");
 #endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)	 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 MODULE_PARM(vesa, "i");
 MODULE_PARM_DESC(vesa,
        "\nSelects the desired default display mode by VESA defined mode number, eg.\n"
          "0x117 (default: 0x0103)");
-#endif	 
+#endif
 
 MODULE_PARM(rate, "i");
 MODULE_PARM_DESC(rate,
 	"\nSelects the desired vertical refresh rate for CRT1 (external VGA) in Hz.\n"
-	"(default: 60)");
+	  "If the mode is specified in the format XxY-Depth@Rate, this parameter\n"
+	  "will be ignored (default: 60)");
 
 MODULE_PARM(crt1off,   "i");
 MODULE_PARM_DESC(crt1off,
@@ -4624,14 +5188,9 @@
 	"\nSelects TV flicker filter type (only for systems with a SiS301 video bridge).\n"
 	  "(Possible values 0-7, default: [no filter])");
 
-MODULE_PARM(dstn,   "i");
-MODULE_PARM_DESC(dstn,
-	"\nSelects DSTN/FSTN display mode for SiS550. This sets CRT2 type to LCD and\n"
-	  "overrides forcecrt2type setting. (1=ON, 0=OFF) (default: 0)");
-
 MODULE_PARM(queuemode,   "s");
 MODULE_PARM_DESC(queuemode,
-	"\nSelects the queue mode on 315/550/650/740/330. Possible choices are AGP, VRAM or\n"
+	"\nSelects the queue mode on 315/550/650/740/330/760. Possible choices are AGP, VRAM,\n"
   	  "MMIO. AGP is only available if the kernel has AGP support. The queue mode is\n"
 	  "important to programs using the 2D/3D accelerator of the SiS chip. The modes\n"
 	  "require a totally different way of programming the engines. If any mode than\n"
@@ -4642,11 +5201,12 @@
 MODULE_PARM(mem,    "i");
 MODULE_PARM_DESC(mem,
 	"\nDetermines the beginning of the video memory heap in KB. This heap is used\n"
-	  "for video RAM management for eg. DRM/DRI. The default depends on the amount\n"
-	  "of video RAM available. If 8MB of video RAM or less is available, the heap\n"
-	  "starts at 4096KB, if between 8 and 16MB are available at 8192KB, otherwise\n"
-	  "at 12288KB. The value is to be specified without 'KB' and should match\n"
-	  "the MaxXFBMem setting for XFree 4.x (x>=2).");
+	  "for video RAM management for eg. DRM/DRI. On 300 series, the default depends\n"
+	  "on the amount of video RAM available. If 8MB of video RAM or less is available,\n"
+	  "the heap starts at 4096KB, if between 8 and 16MB are available at 8192KB,\n"
+	  "otherwise at 12288KB. On 315 and Xabre series, the heap is 1MB by default. The\n"
+	  "value is to be specified without 'KB' and should match the MaxXFBMem setting for\n"
+	  "XFree 4.x (x>=2).");
 
 MODULE_PARM(forcecrt2type, "s");
 MODULE_PARM_DESC(forcecrt2type,
@@ -4664,65 +5224,90 @@
 
 MODULE_PARM(pdc, "i");
 MODULE_PARM_DESC(pdc,
-        "\n(300 series only) This is for manually selecting the LCD panel delay\n"
-	  "compensation. The driver should detect this correctly in most cases; however,\n"
-	  "sometimes this is not possible. If you see 'small waves' on the LCD, try\n"
-	  "setting this to 4, 32 or 24. If the problem persists, try other values\n"
-	  "between 4 and 60 in steps of 4. (default: [autodetected])");
+        "\nThis is for manually selecting the LCD panel delay compensation. The driver\n"
+	  "should detect this correctly in most cases; however, sometimes this is not\n"
+	  "possible. If you see 'small waves' on the LCD, try setting this to 4, 32 or 24\n"
+	  "on a 300 series chipset; 3 or 51 on a 315 series chipset. If the problem persists,\n"
+	  "try other values (on 300 series: between 4 and 60 in steps of 4; on 315 series:\n"
+	  "and value from 0 to 255). (default: [autodetected])");
 
 MODULE_PARM(noaccel, "i");
 MODULE_PARM_DESC(noaccel,
         "\nIf set to anything other than 0, 2D acceleration and y-panning will be\n"
-	"disabled. (default: 0)");
+	  "disabled. (default: 0)");
 
 MODULE_PARM(noypan, "i");
 MODULE_PARM_DESC(noypan,
         "\nIf set to anything other than 0, y-panning will be disabled and scrolling\n"
-	"will be performed by redrawing the screen. This required 2D acceleration, so\n"
-	"if the option noaccel is set, y-panning will be disabled. (default: 0)");
+ 	  "will be performed by redrawing the screen. (default: 0)");
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
 MODULE_PARM(inverse, "i");
 MODULE_PARM_DESC(inverse,
         "\nSetting this to anything but 0 should invert the display colors, but this\n"
-	"does not seem to work. (default: 0)");
+	  "does not seem to work. (default: 0)");
 #endif	
 
 MODULE_PARM(userom, "i");
 MODULE_PARM_DESC(userom,
         "\nSetting this to 0 keeps sisfb from using the video BIOS data which is needed\n"
-	"for some LCD and TV setup. (default: 1)");
+	  "for some LCD and TV setup. (default: 1)");
 
 MODULE_PARM(useoem, "i");
 MODULE_PARM_DESC(useoem,
         "\nSetting this to 0 keeps sisfb from using its internel OEM data for some LCD\n"
-	"panels and TV connector types. (default: auto)");
+	  "panels and TV connector types. (default: [auto])");
 
 MODULE_PARM(tvstandard, "s");
 MODULE_PARM_DESC(tvstandard,
 	"\nThis allows overriding the BIOS default for the TV standard. Valid choices are\n"
-	"pal and ntsc. (default: auto)");
+	  "pal and ntsc. (default: [auto])");
+
+MODULE_PARM(nocrt2rate, "i");
+MODULE_PARM_DESC(nocrt2rate,
+	"\nSetting this to 1 will force the driver to use the default refresh rate for\n"
+	  "CRT2 if CRT2 type is VGA. (default: 0, use same rate as CRT1)");
+
+MODULE_PARM(scalelcd, "i");
+MODULE_PARM_DESC(scalelcd,
+	"\nSetting this to 1 will force the driver to scale the LCD image to the panel's\n"
+	  "native resolution. Setting it to 0 will disable scaling; if the panel can scale\n"
+	  "by itself, it will probably do this, otherwise you will see a black bar around\n"
+	  "the screen image. Default: [autodetect if panel can scale]");
+
+MODULE_PARM(specialtiming, "s");
+
+MODULE_PARM(lvdshl, "i");
+
 
 int init_module(void)
 {
 	int err;
-	
+
+	SiS_Pr.UsePanelScaler = -1;
+	SiS_Pr.SiS_CustomT = CUT_NONE;
+	SiS_Pr.LVDSHL = -1;
+
+	ivideo.refresh_rate = sisfb_parm_rate = rate;
+
+	if((scalelcd == 0) || (scalelcd == 1)) {
+	   SiS_Pr.UsePanelScaler = scalelcd ^ 1;
+	}
+
 	if(mode)
-		sisfb_search_mode(mode);
+		sisfb_search_mode(mode, FALSE);
 	else if(vesa != -1)
-		sisfb_search_vesamode(vesa);
-	else  
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
+		sisfb_search_vesamode(vesa, FALSE);
+	else
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 		/* For 2.4, set mode=none if no mode is given  */
 		sisfb_mode_idx = MODE_INDEX_NONE;
 #endif
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-		/* For 2.5, we don't need this "mode=none" stuff anymore */	
+		/* For 2.5, we don't need this "mode=none" stuff anymore */
 		sisfb_mode_idx = DEFAULT_MODE;
 #endif
 
-	ivideo.refresh_rate = rate;
-
 	if(forcecrt2type)
 		sisfb_search_crt2type(forcecrt2type);
 
@@ -4745,12 +5330,10 @@
 
 	if(noypan == 1)       sisfb_ypan = 0;
 	else if(noypan == 0)  sisfb_ypan = 1;
-
-	/* TW: Panning only with acceleration */
-	if(sisfb_accel == 0)  sisfb_ypan = 0;
 	
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 	if(inverse)           sisfb_inverse = 1;
+	sisfb_fontname[0] = '\0';
 #endif
 
 	if(mem)		      sisfb_mem = mem;
@@ -4759,24 +5342,21 @@
 
 	sisfb_useoem = useoem;
 
-	enable_dstn = dstn;
-
-	/* TW: DSTN overrules forcecrt2type */
-	if (enable_dstn)      sisfb_crt2type = DISPTYPE_LCD;
-
 	if (queuemode)        sisfb_search_queuemode(queuemode);
 	
-	/* TW: If other queuemode than MMIO, disable 2D accel and ypan */
+	/* If other queuemode than MMIO, disable 2D accel and ypan */
 	if((sisfb_queuemode != -1) && (sisfb_queuemode != MMIO_CMD)) {
 	        sisfb_accel = 0;
-		sisfb_ypan = 0;
 	}
 
-        if(pdc) {
-	   if(!(pdc & ~0x3c)) {
-	        sisfb_pdc = pdc & 0x3c;
-	   }
-	}
+        if(pdc) sisfb_pdc = pdc & 0x3c;
+
+	sisfb_nocrt2rate = nocrt2rate;
+
+	if(specialtiming)
+		sisfb_search_specialtiming(specialtiming);
+
+	if((lvdshl >= 0) && (lvdshl <= 3)) SiS_Pr.LVDSHL = lvdshl;
 
 	if((err = sisfb_init()) < 0) return err;
 
@@ -4785,10 +5365,10 @@
 
 void cleanup_module(void)
 {
-	/* TW: Release mem regions */
+	/* Release mem regions */
 	release_mem_region(ivideo.video_base, ivideo.video_size);
 	release_mem_region(ivideo.mmio_base, sisfb_mmio_size);
-	
+
 #ifdef CONFIG_MTRR
 	/* TW: Release MTRR region */
 	if(ivideo.mtrr) {
@@ -4800,13 +5380,24 @@
 
 	/* Unregister the framebuffer */
 	if(sisfb_registered) {
-		unregister_framebuffer(&sis_fb_info);
+		unregister_framebuffer(sis_fb_info);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+		framebuffer_release(sis_fb_info);
+#else
+		kfree(sis_fb_info);
+#endif
 	}
-	
+
 	if(sishw_ext.pSR) vfree(sishw_ext.pSR);
 	if(sishw_ext.pCR) vfree(sishw_ext.pCR);
 	
-	/* TODO: Restore the initial mode */
+	/* TODO: Restore the initial mode
+	 * This sounds easy but is as good as impossible
+	 * on many machines with SiS chip and video bridge
+	 * since text modes are always set up differently
+	 * from machine to machine. Depends on the type
+	 * of integration between chipset and bridge.
+	 */
 	
 	printk(KERN_INFO "sisfb: Module unloaded\n");
 }
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/sis_main.h fbdev-2.6/drivers/video/sis/sis_main.h
--- linus-2.6/drivers/video/sis/sis_main.h	Thu Oct 16 14:13:42 2003
+++ fbdev-2.6/drivers/video/sis/sis_main.h	Thu Oct 16 14:13:42 2003
@@ -1,24 +1,21 @@
 #ifndef _SISFB_MAIN
 #define _SISFB_MAIN
 
-/* Comments and changes marked with "TW" by Thomas Winischhofer <thomas@winischhofer.net> */
-
 #include "vstruct.h"
 
 /* ------------------- Constant Definitions ------------------------- */
 
-#undef LINUXBIOS   /* turn this on when compiling for LINUXBIOS */
 #define AGPOFF     /* default is turn off AGP */
 
 #define SISFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
 
 #define VER_MAJOR                 1
 #define VER_MINOR                 6
-#define VER_LEVEL                 1
+#define VER_LEVEL                 21
 
 #include "sis.h"
 
-/* TW: To be included in pci_ids.h */
+/* To be included in pci_ids.h */
 #ifndef PCI_DEVICE_ID_SI_650_VGA
 #define PCI_DEVICE_ID_SI_650_VGA  0x6325
 #endif
@@ -31,13 +28,22 @@
 #ifndef PCI_DEVICE_ID_SI_330
 #define PCI_DEVICE_ID_SI_330      0x0330
 #endif
+#ifndef PCI_DEVICE_ID_SI_660
+#define PCI_DEVICE_ID_SI_660      0x0660
+#endif
+#ifndef PCI_DEVICE_ID_SI_660_VGA
+#define PCI_DEVICE_ID_SI_660_VGA  0x6330
+#endif
+#ifndef PCI_DEVICE_ID_SI_760
+#define PCI_DEVICE_ID_SI_760      0x0760
+#endif
 
 /* To be included in fb.h */
 #ifndef FB_ACCEL_SIS_GLAMOUR_2
-#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 740		*/
+#define FB_ACCEL_SIS_GLAMOUR_2  40	/* SiS 315, 650, 661, 740		*/
 #endif
 #ifndef FB_ACCEL_SIS_XABRE
-#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre")		*/
+#define FB_ACCEL_SIS_XABRE      41	/* SiS 330 ("Xabre"), 660, 760 (DOA)	*/
 #endif
 
 #define MAX_ROM_SCAN              0x10000
@@ -53,13 +59,12 @@
 #define TURBO_QUEUE_AREA_SIZE     0x80000 /* 512K */
 #endif
 
-/* For 315 series */
+/* For 315/Xabre series */
 #ifdef CONFIG_FB_SIS_315
 #define COMMAND_QUEUE_AREA_SIZE   0x80000 /* 512K */
 #define COMMAND_QUEUE_THRESHOLD   0x1F
 #endif
 
-/* TW */
 #define HW_CURSOR_AREA_SIZE_315   0x4000  /* 16K */
 #define HW_CURSOR_AREA_SIZE_300   0x1000  /* 4K */
 
@@ -95,7 +100,9 @@
 #define SISDAC2A                  SISPART5
 #define SISDAC2D                  (SISPART5 + 1)
 #define SISMISCR                  (SiS_Pr.RelIO + 0x1c)
-#define SISINPSTAT		  (SiS_Pr.RelIO + 0x2a)  
+#define SISMISCW                  SiS_Pr.SiS_P3c2
+#define SISINPSTAT		  (SiS_Pr.RelIO + 0x2a)
+#define SISPEL			  SiS_Pr.SiS_P3c6
 
 #define IND_SIS_PASSWORD          0x05  /* SRs */
 #define IND_SIS_COLOR_MODE        0x06
@@ -236,8 +243,8 @@
 #define BRI_DRAM_SIZE_32MB        0x04
 #define BRI_DRAM_SIZE_64MB        0x05
 
-#define HW_DEVICE_EXTENSION	  SIS_HW_DEVICE_INFO
-#define PHW_DEVICE_EXTENSION      PSIS_HW_DEVICE_INFO
+#define HW_DEVICE_EXTENSION	  SIS_HW_INFO
+#define PHW_DEVICE_EXTENSION      PSIS_HW_INFO
 
 #define SR_BUFFER_SIZE            5
 #define CR_BUFFER_SIZE            5
@@ -281,50 +288,48 @@
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
-static struct fb_info sis_fb_info;
-
-static int    video_type = FB_TYPE_PACKED_PIXELS;
+static struct fb_info *sis_fb_info;
 
 static struct fb_var_screeninfo default_var = {
-	.xres		= 0,
-	.yres		= 0,
-	.xres_virtual	= 0,
-	.yres_virtual	= 0,
-	.xoffset	= 0,
-	.yoffset	= 0,
-	.bits_per_pixel	= 0,
-	.grayscale	= 0,
-	.red		= {0, 8, 0},
-	.green		= {0, 8, 0},
-	.blue		= {0, 8, 0},
-	.transp		= {0, 0, 0},
-	.nonstd		= 0,
-	.activate	= FB_ACTIVATE_NOW,
-	.height		= -1,
-	.width		= -1,
-	.accel_flags	= 0,
-	.pixclock	= 0,
-	.left_margin	= 0,
-	.right_margin	= 0,
-	.upper_margin	= 0,
-	.lower_margin	= 0,
-	.hsync_len	= 0,
-	.vsync_len	= 0,
-	.sync		= 0,
-	.vmode		= FB_VMODE_NONINTERLACED,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)	
-	.reserved	= {0, 0, 0, 0, 0, 0}
-#endif	
+	.xres            = 0,
+	.yres            = 0,
+	.xres_virtual    = 0,
+	.yres_virtual    = 0,
+	.xoffset         = 0,
+	.yoffset         = 0,
+	.bits_per_pixel  = 0,
+	.grayscale       = 0,
+	.red             = {0, 8, 0},
+	.green           = {0, 8, 0},
+	.blue            = {0, 8, 0},
+	.transp          = {0, 0, 0},
+	.nonstd          = 0,
+	.activate        = FB_ACTIVATE_NOW,
+	.height          = -1,
+	.width           = -1,
+	.accel_flags     = 0,
+	.pixclock        = 0,
+	.left_margin     = 0,
+	.right_margin    = 0,
+	.upper_margin    = 0,
+	.lower_margin    = 0,
+	.hsync_len       = 0,
+	.vsync_len       = 0,
+	.sync            = 0,
+	.vmode           = FB_VMODE_NONINTERLACED,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+	.reserved        = {0, 0, 0, 0, 0, 0}
+#endif
 };
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 static struct fb_fix_screeninfo sisfb_fix = {
 	.id		= "SiS",
 	.type		= FB_TYPE_PACKED_PIXELS,
-	.xpanstep	= 1,
+	.xpanstep	= 0,
 	.ypanstep	= 1,
 };
-static char myid[20];
+static char myid[40];
 static u32 pseudo_palette[17];
 #endif
 
@@ -347,62 +352,54 @@
 } sis_fbcon_cmap;
 
 static int sisfb_inverse = 0;
+static int currcon = 0;
 #endif
 
-/* display status */
+/* global flags */
 static int sisfb_off = 0;
 static int sisfb_crt1off = 0;
 static int sisfb_forcecrt1 = -1;
 static int sisvga_enabled = 0;
 static int sisfb_userom = 1;
 static int sisfb_useoem = -1;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-static int currcon = 0;
-#endif
-
-/* global flags */
-static int sisfb_registered;
-static int sisfb_tvmode = 0;
+static int sisfb_parm_rate = -1;
+static int sisfb_registered = 0;
 static int sisfb_mem = 0;
 static int sisfb_pdc = 0;
-static int enable_dstn = 0;
 static int sisfb_ypan = -1;
+static int sisfb_nocrt2rate = 0;
+static int sisfb_dstn = 0;
+static int sisfb_fstn = 0;
 
 VGA_ENGINE sisvga_engine = UNKNOWN_VGA;
 int 	   sisfb_accel = -1;
 
-/* TW: These are to adapted according to VGA_ENGINE type */
+/* These are to adapted according to VGA_ENGINE type */
 static int sisfb_hwcursor_size = 0;
 static int sisfb_CRT2_write_enable = 0;
 
-int sisfb_crt2type  = -1;	/* TW: CRT2 type (for overriding autodetection) */
-int sisfb_tvplug    = -1;	/* PR: Tv plug type (for overriding autodetection) */
+int sisfb_crt2type  = -1;	/* CRT2 type (for overriding autodetection) */
+int sisfb_tvplug    = -1;	/* Tv plug type (for overriding autodetection) */
 
-int sisfb_queuemode = -1; 	/* TW: Use MMIO queue mode by default (310/325 series only) */
+int sisfb_queuemode = -1; 	/* Use MMIO queue mode by default (315 series only) */
 
 unsigned char sisfb_detectedpdc = 0;
 
 unsigned char sisfb_detectedlcda = 0xff;
 
-/* data for sis components */
+/* data for sis hardware ("par") */
 struct video_info ivideo;
 
-/* TW: For ioctl SISFB_GET_INFO */
+/* For ioctl SISFB_GET_INFO */
 sisfb_info sisfbinfo;
 
-/* TW: Hardware extension; contains data on hardware */
-HW_DEVICE_EXTENSION sishw_ext = {
-	NULL, NULL, FALSE, NULL, NULL,
-	0, 0, 0, 0, 0, 0, 0, 0, 0,
-	NULL, NULL, NULL, NULL,
-	{0, 0, 0, 0},
-	0
-};
+/* Hardware info; contains data on hardware */
+SIS_HW_INFO sishw_ext;
 
-/* TW: SiS private structure */
+/* SiS private structure */
 SiS_Private  SiS_Pr;
 
-/* card parameters */
+/* Card parameters */
 static unsigned long sisfb_mmio_size = 0;
 static u8            sisfb_caps = 0;
 
@@ -412,7 +409,7 @@
 	VM_CMD_QUEUE,
 } SIS_CMDTYPE;
 
-/* Supported SiS Chips list */
+/* List of supported chips */
 static struct board {
 	u16 vendor, device;
 	const char *name;
@@ -424,16 +421,19 @@
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315,     "SIS 315"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_315PRO,  "SIS 315PRO"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_550_VGA, "SIS 550 VGA"},
-	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 650/M650/651/740 VGA"},
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_650_VGA, "SIS 65x/M65x/66xFX/M66xFX/74x VGA"},
 	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_330,     "SIS 330"},
+#if 0
+	{PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_660_VGA, "SIS 660/M660/760/M760 VGA"},
+#endif
 	{0, 0, NULL}
 };
 
 #define MD_SIS300 1
 #define MD_SIS315 2
 
-/* mode table */
-/* NOT const - will be patched for 1280x960 mode number chaos reasons */
+/* Mode table */
+/* NOT const - will be patched for 1280x768 mode number chaos reasons */
 struct _sisbios_mode {
 	char name[15];
 	u8 mode_no;
@@ -447,14 +447,33 @@
 	u16 rows;
 	u8  chipset;
 } sisbios_mode[] = {
-#define MODE_INDEX_NONE           0  /* TW: index for mode=none */
-	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},  /* TW: for mode "none" */
-	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,           MD_SIS315},
-	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
-	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
+#define MODE_INDEX_NONE           0  /* index for mode=none */
+	{"none",         0xff, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_SIS300|MD_SIS315},
+	{"320x200x8",    0x59, 0x0138, 0x0000,  320,  200,  8, 1,  40, 12, MD_SIS300|MD_SIS315},
+	{"320x200x16",   0x41, 0x010e, 0x0000,  320,  200, 16, 1,  40, 12, MD_SIS300|MD_SIS315},
+	{"320x200x24",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
+	{"320x200x32",   0x4f, 0x0000, 0x0000,  320,  200, 32, 1,  40, 12, MD_SIS300|MD_SIS315},
+	{"320x240x8",    0x50, 0x0132, 0x0000,  320,  240,  8, 1,  40, 15, MD_SIS300|MD_SIS315},
+	{"320x240x16",   0x56, 0x0135, 0x0000,  320,  240, 16, 1,  40, 15, MD_SIS300|MD_SIS315},
+	{"320x240x24",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
+	{"320x240x32",   0x53, 0x0000, 0x0000,  320,  240, 32, 1,  40, 15, MD_SIS300|MD_SIS315},
+	{"320x240x8",    0x5a, 0x0132, 0x0000,  320,  480,  8, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"320x240x16",   0x5b, 0x0135, 0x0000,  320,  480, 16, 1,  40, 30,           MD_SIS315},  /* TW: FSTN */
+	{"400x300x8",    0x51, 0x0133, 0x0000,  400,  300,  8, 1,  50, 18, MD_SIS300|MD_SIS315},
+	{"400x300x16",   0x57, 0x0136, 0x0000,  400,  300, 16, 1,  50, 18, MD_SIS300|MD_SIS315},
+	{"400x300x24",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
+	{"400x300x32",   0x54, 0x0000, 0x0000,  400,  300, 32, 1,  50, 18, MD_SIS300|MD_SIS315},
+	{"512x384x8",    0x52, 0x0000, 0x0000,  512,  384,  8, 1,  64, 24, MD_SIS300|MD_SIS315},
+	{"512x384x16",   0x58, 0x0000, 0x0000,  512,  384, 16, 1,  64, 24, MD_SIS300|MD_SIS315},
+	{"512x384x24",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
+	{"512x384x32",   0x5c, 0x0000, 0x0000,  512,  384, 32, 1,  64, 24, MD_SIS300|MD_SIS315},
+	{"640x400x8",    0x2f, 0x0000, 0x0000,  640,  400,  8, 1,  80, 25, MD_SIS300|MD_SIS315},
+	{"640x400x16",   0x5d, 0x0000, 0x0000,  640,  400, 16, 1,  80, 25, MD_SIS300|MD_SIS315},
+	{"640x400x24",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
+	{"640x400x32",   0x5e, 0x0000, 0x0000,  640,  400, 32, 1,  80, 25, MD_SIS300|MD_SIS315},
+	{"640x480x8",    0x2e, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_SIS300|MD_SIS315},
 	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_SIS300|MD_SIS315},
-	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},  /* TW: That's for people who mix up color- and fb depth */
+	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
 	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_SIS300|MD_SIS315},
 	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_SIS300|MD_SIS315},
 	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_SIS300|MD_SIS315},
@@ -464,63 +483,87 @@
 	{"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_SIS300|MD_SIS315},
 	{"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
 	{"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_SIS300|MD_SIS315},
+	{"768x576x8",    0x5f, 0x0000, 0x0000,  768,  576,  8, 1,  96, 36, MD_SIS300|MD_SIS315},
+	{"768x576x16",   0x60, 0x0000, 0x0000,  768,  576, 16, 1,  96, 36, MD_SIS300|MD_SIS315},
+	{"768x576x24",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
+	{"768x576x32",   0x61, 0x0000, 0x0000,  768,  576, 32, 1,  96, 36, MD_SIS300|MD_SIS315},
 	{"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_SIS300|MD_SIS315},
 	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_SIS300|MD_SIS315},
 	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
 	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_SIS300|MD_SIS315},
-#define DEFAULT_MODE              20 /* TW: index for 800x600x8 */
-#define DEFAULT_LCDMODE           20 /* TW: index for 800x600x8 */
-#define DEFAULT_TVMODE            20 /* TW: index for 800x600x8 */
+#define DEFAULT_MODE              43 /* index for 800x600x8 */
+#define DEFAULT_LCDMODE           43 /* index for 800x600x8 */
+#define DEFAULT_TVMODE            43 /* index for 800x600x8 */
 	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 2, 100, 37, MD_SIS300|MD_SIS315},
 	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 2, 100, 37, MD_SIS300|MD_SIS315},
 	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
 	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 2, 100, 37, MD_SIS300|MD_SIS315},
+	{"848x480x8",    0x39, 0x0000, 0x0000,  848,  480,  8, 2, 106, 30, MD_SIS300|MD_SIS315},
+	{"848x480x16",   0x3b, 0x0000, 0x0000,  848,  480, 16, 2, 106, 30, MD_SIS300|MD_SIS315},
+	{"848x480x24",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+	{"848x480x32",   0x3e, 0x0000, 0x0000,  848,  480, 32, 2, 106, 30, MD_SIS300|MD_SIS315},
+	{"856x480x8",    0x3f, 0x0000, 0x0000,  856,  480,  8, 2, 107, 30, MD_SIS300|MD_SIS315},
+	{"856x480x16",   0x42, 0x0000, 0x0000,  856,  480, 16, 2, 107, 30, MD_SIS300|MD_SIS315},
+	{"856x480x24",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
+	{"856x480x32",   0x45, 0x0000, 0x0000,  856,  480, 32, 2, 107, 30, MD_SIS300|MD_SIS315},
 	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
 	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_SIS300|MD_SIS315},
-	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },  /* TW: 300 series only */
+	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_SIS300          },
 	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_SIS300          },
 	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
 	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_SIS300          },
 	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 2, 128, 48, MD_SIS300|MD_SIS315},
-	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
+	{"1024x768x16",  0x4a, 0x0117, 0x0117, 1024,  768, 16, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
 	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 2, 128, 48, MD_SIS300|MD_SIS315},
-	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },  /* TW: 300 series only */
+	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_SIS300          },
 	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_SIS300          },
 	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
 	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_SIS300          },
+	{"1152x864x8",   0x29, 0x0000, 0x0000, 1152,  864,  8, 1, 144, 54, MD_SIS300|MD_SIS315},
+	{"1152x864x16",  0x2a, 0x0000, 0x0000, 1152,  864, 16, 1, 144, 54, MD_SIS300|MD_SIS315},
+	{"1152x864x24",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
+	{"1152x864x32",  0x2b, 0x0000, 0x0000, 1152,  864, 32, 1, 144, 54, MD_SIS300|MD_SIS315},
 	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
 	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_SIS300|MD_SIS315},
-	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_SIS315},  /* TW: 310/325 series only */
-	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_SIS315},
-	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
-	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_SIS315},
-#define MODEINDEX_1280x960 48
-	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},  /* TW: Modenumbers being patched */
-	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
-	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
-	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
-	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
+#define MODEINDEX_1280x768 79
+	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48, MD_SIS300|MD_SIS315},
+	{"1280x960x8",   0x7c, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x960x16",  0x7d, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x960x24",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x960x32",  0x7e, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_SIS300|MD_SIS315},
+	{"1280x1024x8",  0x3a, 0x0107, 0x0107, 1280, 1024,  8, 2, 160, 64, MD_SIS300|MD_SIS315},
+	{"1280x1024x16", 0x4d, 0x011a, 0x011a, 1280, 1024, 16, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
 	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 2, 160, 64, MD_SIS300|MD_SIS315},
-	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},  /* TW: 310/325 series only */
+	{"1360x768x8",   0x48, 0x0000, 0x0000, 1360,  768,  8, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x16",  0x4b, 0x0000, 0x0000, 1360,  768, 16, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x24",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x768x32",  0x4e, 0x0000, 0x0000, 1360,  768, 32, 1, 170, 48, MD_SIS300|MD_SIS315},
+	{"1360x1024x8",  0x67, 0x0000, 0x0000, 1360, 1024,  8, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x16", 0x6f, 0x0000, 0x0000, 1360, 1024, 16, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x24", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+	{"1360x1024x32", 0x72, 0x0000, 0x0000, 1360, 1024, 32, 1, 170, 64, MD_SIS300          },
+	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
 	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_SIS315},
-	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
-	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1600x1200x8",  0x3c, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_SIS300|MD_SIS315},
+	{"1600x1200x16", 0x3d, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_SIS300|MD_SIS315},
 	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_SIS300|MD_SIS315},
-	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
-	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},  /* TW: 310/325 series only */
+	{"1920x1440x24", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"1920x1440x32", 0x6b, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_SIS300|MD_SIS315},
+	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
 	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_SIS315},
@@ -536,39 +579,38 @@
 u8  sisfb_mode_no  = 0;
 u8  sisfb_rate_idx = 0;
 
-/* TW: CR36 evaluation */
+/* CR36 evaluation */
 const USHORT sis300paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768,
-      LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+      LCD_1280x960,  LCD_640x480,   LCD_1024x600,  LCD_1152x768,
+      LCD_1024x768,  LCD_1024x768,  LCD_1024x768,  LCD_1024x768,
+      LCD_1024x768,  LCD_1024x768,  LCD_320x480,   LCD_1024x768 };
 
 const USHORT sis310paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
-      LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
-      LCD_320x480,   LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+    { LCD_UNKNOWN,   LCD_800x600,   LCD_1024x768,  LCD_1280x1024,
+      LCD_640x480,   LCD_1024x600,  LCD_1152x864,  LCD_1280x960,
+      LCD_1152x768,  LCD_1400x1050, LCD_1280x768,  LCD_1600x1200,
+      LCD_640x480_2, LCD_640x480_3, LCD_320x480,   LCD_1024x768 };
+
+#define FL_550_DSTN 0x01
+#define FL_550_FSTN 0x02
 
 static const struct _sis_crt2type {
 	char name[10];
 	int type_no;
 	int tvplug_no;
+	unsigned short flags;
 } sis_crt2type[] = {
-	{"NONE", 	0, 		-1},
-	{"LCD",  	DISPTYPE_LCD, 	-1},
-	{"TV",   	DISPTYPE_TV, 	-1},
-	{"VGA",  	DISPTYPE_CRT2, 	-1},
-	{"SVIDEO", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
-	{"COMPOSITE", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
-	{"SCART", 	DISPTYPE_TV, 	TVPLUG_SCART},
-	{"none", 	0, 		-1},
-	{"lcd",  	DISPTYPE_LCD, 	-1},
-	{"tv",   	DISPTYPE_TV, 	-1},
-	{"vga",  	DISPTYPE_CRT2, 	-1},
-	{"svideo", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
-	{"composite", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
-	{"scart", 	DISPTYPE_TV, 	TVPLUG_SCART},
-	{"\0",  	-1, 		-1}
+	{"NONE", 	0, 		-1,        0},
+	{"LCD",  	CRT2_LCD, 	-1,        0},
+	{"TV",   	CRT2_TV, 	-1,        0},
+	{"VGA",  	CRT2_VGA, 	-1,        0},
+	{"SVIDEO", 	CRT2_TV, 	TV_SVIDEO, 0},
+	{"COMPOSITE", 	CRT2_TV, 	TV_AVIDEO, 0},
+	{"SCART", 	CRT2_TV, 	TV_SCART,  0},
+	{"DSTN",        CRT2_LCD,       -1,        FL_550_DSTN},
+	{"FSTN",        CRT2_LCD,       -1,        FL_550_FSTN},
+	{"\0",  	-1, 		-1,        0}
 };
 
 /* Queue mode selection for 310 series */
@@ -579,9 +621,6 @@
 	{"AGP",  	AGP_CMD_QUEUE},
 	{"VRAM", 	VM_CMD_QUEUE},
 	{"MMIO", 	MMIO_CMD},
-	{"agp",  	AGP_CMD_QUEUE},
-	{"vram", 	VM_CMD_QUEUE},
-	{"mmio", 	MMIO_CMD},
 	{"\0",   	-1}
 };
 
@@ -590,10 +629,8 @@
 	char name[6];
 	int type_no;
 } sis_tvtype[] = {
-	{"PAL",  	1},
-	{"NTSC", 	2},
-	{"pal", 	1},
-	{"ntsc",  	2},
+	{"PAL",  	TV_PAL},
+	{"NTSC", 	TV_NTSC},
 	{"\0",   	-1}
 };
 
@@ -602,33 +639,103 @@
 	u16 xres;
 	u16 yres;
 	u16 refresh;
+	BOOLEAN SiS730valid32bpp;
 } sisfb_vrate[] = {
-	{1,  640,  480, 60}, {2,  640,  480,  72}, {3, 640,   480,  75}, {4,  640, 480,  85},
-	{5,  640,  480,100}, {6,  640,  480, 120}, {7, 640,   480, 160}, {8,  640, 480, 200},
-	{1,  720,  480, 60},
-	{1,  720,  576, 58},
-	{1,  800,  480, 60}, {2,  800,  480,  75}, {3, 800,   480,  85},
-	{1,  800,  600, 56}, {2,  800,  600,  60}, {3, 800,   600,  72}, {4,  800, 600,  75},
-	{5,  800,  600, 85}, {6,  800,  600, 100}, {7, 800,   600, 120}, {8,  800, 600, 160},
-	{1, 1024,  768, 43}, {2, 1024,  768,  60}, {3, 1024,  768,  70}, {4, 1024, 768,  75},
-	{5, 1024,  768, 85}, {6, 1024,  768, 100}, {7, 1024,  768, 120},
-	{1, 1024,  576, 60}, {2, 1024,  576,  75}, {3, 1024,  576,  85},
-	{1, 1024,  600, 60},
-	{1, 1152,  768, 60},
-	{1, 1280,  720, 60}, {2, 1280,  720,  75}, {3, 1280,  720,  85},
-	{1, 1280,  768, 60},
-	{1, 1280, 1024, 43}, {2, 1280, 1024,  60}, {3, 1280, 1024,  75}, {4, 1280, 1024,  85},
-	{1, 1280,  960, 70},
-	{1, 1400, 1050, 60},
-	{1, 1600, 1200, 60}, {2, 1600, 1200,  65}, {3, 1600, 1200,  70}, {4, 1600, 1200,  75},
-	{5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
-	{1, 1920, 1440, 60}, {2, 1920, 1440,  65}, {3, 1920, 1440,  70}, {4, 1920, 1440,  75},
-	{5, 1920, 1440, 85}, {6, 1920, 1440, 100},
-	{1, 2048, 1536, 60}, {2, 2048, 1536,  65}, {3, 2048, 1536,  70}, {4, 2048, 1536,  75},
-	{5, 2048, 1536, 85},
-	{0, 0, 0, 0}
+	{1,  320,  200,  70,  TRUE},
+	{1,  320,  240,  60,  TRUE},
+	{1,  320,  480,  60,  TRUE},
+	{1,  400,  300,  60,  TRUE},
+	{1,  512,  384,  60,  TRUE},
+	{1,  640,  400,  72,  TRUE},
+	{1,  640,  480,  60,  TRUE}, {2,  640,  480,  72,  TRUE}, {3,  640,  480,  75,  TRUE},
+	{4,  640,  480,  85,  TRUE}, {5,  640,  480, 100,  TRUE}, {6,  640,  480, 120,  TRUE},
+	{7,  640,  480, 160,  TRUE}, {8,  640,  480, 200,  TRUE},
+	{1,  720,  480,  60,  TRUE},
+	{1,  720,  576,  58,  TRUE},
+	{1,  768,  576,  58,  TRUE},
+	{1,  800,  480,  60,  TRUE}, {2,  800,  480,  75,  TRUE}, {3,  800,  480,  85,  TRUE},
+	{1,  800,  600,  56,  TRUE}, {2,  800,  600,  60,  TRUE}, {3,  800,  600,  72,  TRUE},
+	{4,  800,  600,  75,  TRUE}, {5,  800,  600,  85,  TRUE}, {6,  800,  600, 105,  TRUE},
+	{7,  800,  600, 120,  TRUE}, {8,  800,  600, 160,  TRUE},
+	{1,  848,  480,  39,  TRUE}, {2,  848,  480,  60,  TRUE},
+	{1,  856,  480,  39,  TRUE}, {2,  856,  480,  60,  TRUE},
+	{1, 1024,  576,  60,  TRUE}, {2, 1024,  576,  75,  TRUE}, {3, 1024,  576,  85,  TRUE},
+	{1, 1024,  600,  60,  TRUE},
+	{1, 1024,  768,  43,  TRUE}, {2, 1024,  768,  60,  TRUE}, {3, 1024,  768,  70, FALSE},
+	{4, 1024,  768,  75, FALSE}, {5, 1024,  768,  85,  TRUE}, {6, 1024,  768, 100,  TRUE},
+	{7, 1024,  768, 120,  TRUE},
+	{1, 1152,  768,  60,  TRUE},
+	{1, 1152,  864,  75,  TRUE}, {2, 1152,  864,  84,  TRUE},
+	{1, 1280,  720,  60,  TRUE}, {2, 1280,  720,  75,  TRUE}, {3, 1280,  720,  85,  TRUE},
+	{1, 1280,  768,  60,  TRUE},
+	{1, 1280,  960,  60,  TRUE}, {2, 1280,  960,  85,  TRUE},
+	{1, 1280, 1024,  43,  TRUE}, {2, 1280, 1024,  60,  TRUE}, {3, 1280, 1024,  75,  TRUE},
+	{4, 1280, 1024,  85,  TRUE},
+	{1, 1360,  768,  60,  TRUE},
+	{1, 1360, 1024,  59,  TRUE},
+	{1, 1400, 1050,  60,  TRUE}, {2, 1400, 1050,  75,  TRUE},
+	{1, 1600, 1200,  60,  TRUE}, {2, 1600, 1200,  65,  TRUE}, {3, 1600, 1200,  70,  TRUE},
+	{4, 1600, 1200,  75,  TRUE}, {5, 1600, 1200,  85,  TRUE}, {6, 1600, 1200, 100,  TRUE},
+	{7, 1600, 1200, 120,  TRUE},
+	{1, 1920, 1440,  60,  TRUE}, {2, 1920, 1440,  65,  TRUE}, {3, 1920, 1440,  70,  TRUE},
+	{4, 1920, 1440,  75,  TRUE}, {5, 1920, 1440,  85,  TRUE}, {6, 1920, 1440, 100,  TRUE},
+	{1, 2048, 1536,  60,  TRUE}, {2, 2048, 1536,  65,  TRUE}, {3, 2048, 1536,  70,  TRUE},
+	{4, 2048, 1536,  75,  TRUE}, {5, 2048, 1536,  85,  TRUE},
+	{0,    0,    0,   0, FALSE}
+};
+
+static struct sisfb_monitor {
+	u16 hmin;
+	u16 hmax;
+	u16 vmin;
+	u16 vmax;
+	u32 dclockmax;
+	u8  feature;
+	BOOLEAN datavalid;
+} sisfb_thismonitor;
+
+static const struct _sisfbddcsmodes {
+	u32 mask;
+	u16 h;
+	u16 v;
+	u32 d;
+} sisfb_ddcsmodes[] = {
+	{ 0x10000, 67, 75, 108000},
+	{ 0x08000, 48, 72,  50000},
+	{ 0x04000, 46, 75,  49500},
+	{ 0x01000, 35, 43,  44900},
+	{ 0x00800, 48, 60,  65000},
+	{ 0x00400, 56, 70,  75000},
+	{ 0x00200, 60, 75,  78800},
+	{ 0x00100, 80, 75, 135000},
+	{ 0x00020, 31, 60,  25200},
+	{ 0x00008, 38, 72,  31500},
+	{ 0x00004, 37, 75,  31500},
+	{ 0x00002, 35, 56,  36000},
+	{ 0x00001, 38, 60,  40000}
 };
 
+static const struct _sisfbddcfmodes {
+	u16 x;
+	u16 y;
+	u16 v;
+	u16 h;
+	u32 d;
+} sisfb_ddcfmodes[] = {
+       { 1280, 1024, 85, 92, 157500},
+       { 1600, 1200, 60, 75, 162000},
+       { 1600, 1200, 65, 82, 175500},
+       { 1600, 1200, 70, 88, 189000},
+       { 1600, 1200, 75, 94, 202500},
+       { 1600, 1200, 85, 107,229500},
+       { 1920, 1440, 60, 90, 234000},
+       { 1920, 1440, 75, 113,297000}
+};
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+static u8 sisfb_lastrates[128];
+#endif
+
 static const struct _chswtable {
     int subsysVendor;
     int subsysCard;
@@ -636,9 +743,96 @@
     char *cardName;
 } mychswtable[] = {
         { 0x1631, 0x1002, "Mitachi", "0x1002" },
+	{ 0x1071, 0x7521, "Mitac"  , "7521P"  },
 	{ 0,      0,      ""       , ""       }
 };
 
+static const struct _customttable {
+    unsigned short chipID;
+    char *biosversion;
+    char *biosdate;
+    unsigned long bioschksum;
+    unsigned short biosFootprintAddr[5];
+    unsigned char biosFootprintData[5];
+    unsigned short pcisubsysvendor;
+    unsigned short pcisubsyscard;
+    char *vendorName;
+    char *cardName;
+    unsigned long SpecialID;
+    char *optionName;
+} mycustomttable[] = {
+        { SIS_630, "2.00.07", "09/27/2002-13:38:25",
+	  0x3240A8,
+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
+	  {  0x01,  0xe3,  0x9a,  0x6a,  0x00 },
+	  0x1039, 0x6300,
+	  "Barco", "iQ R200L/300/400", CUT_BARCO1366, "BARCO1366"
+	},
+	{ SIS_630, "2.00.07", "09/27/2002-13:38:25",
+	  0x323FBD,
+	  { 0x220, 0x227, 0x228, 0x229, 0x22a },
+	  {  0x00,  0x5a,  0x64,  0x41,  0x00 },
+	  0x1039, 0x6300,
+	  "Barco", "iQ G200L/300/400/500", CUT_BARCO1024, "BARCO1024"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x0e11, 0x083c,
+	  "Inventec (Compaq)", "3017cl/3045US", CUT_COMPAQ12802, "COMPAQ1280"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0x00c, 0, 0, 0, 0 },
+	  { 'e'  , 0, 0, 0, 0 },
+	  0x1558, 0x0287,
+	  "Clevo", "L285/L287 (Version 1)", CUT_CLEVO1024, "CLEVO1024"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0x00c, 0, 0, 0, 0 },
+	  { 'y'  , 0, 0, 0, 0 },
+	  0x1558, 0x0287,
+	  "Clevo", "L285/L287 (Version 2)", CUT_CLEVO10242, "CLEVO10242"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1558, 0x0400,
+	  "Clevo", "D400S/D410S/D400H/D410H", CUT_CLEVO1400, "CLEVO400"
+	},
+	{ SIS_650, "", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1734, 0x101f,
+	  "Uniwill", "N243S9", CUT_UNIWILL1024, "UNIWILL1024"
+	},
+	{ SIS_740, "1.11.27a", "",
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0x1043, 0x1612,
+	  "Asus", "L3000D/L3500D", CUT_ASUSL3000D, "ASUSLVDS1024"
+	},
+	{ 4321, "", "",			/* This is hopefully NEVER autodetected */
+	  0,
+	  { 0, 0, 0, 0, 0 },
+	  { 0, 0, 0, 0, 0 },
+	  0, 0,
+	  "Generic", "LVDS/Parallel 848x480", CUT_PANEL848, "PANEL848x480"
+	},
+	{ 0, "", "",
+	  0,
+	  { 0, 0, 0, 0 },
+	  { 0, 0, 0, 0 },
+	  0, 0,
+	  "", "", CUT_NONE, ""
+	}
+};
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 /* Offscreen layout */
 typedef struct _SIS_GLYINFO {
@@ -648,6 +842,8 @@
 	u8 gmask[72];
 	int ngmask;
 } SIS_GLYINFO;
+
+static char sisfb_fontname[40];
 #endif
 
 typedef struct _SIS_OH {
@@ -677,7 +873,6 @@
 static unsigned long sisfb_heap_size;
 static SIS_HEAP      sisfb_heap;
 
-// Eden Chen
 static const struct _sis_TV_filter {
 	u8 filter[9][4];
 } sis_TV_filter[] = {
@@ -697,7 +892,7 @@
 	   {0xF8,0xF4,0x18,0x38},
 	   {0xFC,0xFB,0x14,0x2A},
 	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18}, 
+	   {0x00,0x04,0x10,0x18},
 	   {0xFF,0xFF,0xFF,0xFF} }},
 	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_2 */
 	   {0xF5,0xEE,0x1B,0x44},
@@ -717,7 +912,7 @@
 	   {0xF9,0x0A,0x17,0x0C},
 	   {0x00,0x07,0x10,0x12}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 */
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 - 320 */
 	   {0x00,0xE0,0x10,0x60},
 	   {0x00,0xEE,0x10,0x44},
 	   {0x00,0xF4,0x10,0x38},
@@ -726,7 +921,7 @@
 	   {0x00,0x00,0x10,0x20},
 	   {0x00,0x04,0x10,0x18}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 */
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 - 640 */
 	   {0xF5,0xEE,0x1B,0x44},
 	   {0xF8,0xF4,0x18,0x38},
 	   {0xEB,0x04,0x25,0x18},
@@ -735,7 +930,7 @@
 	   {0xFA,0x06,0x16,0x14},
 	   {0x00,0x04,0x10,0x18}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 */
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 - 720 */
 	   {0xEB,0x04,0x25,0x18},
 	   {0xE7,0x0E,0x29,0x04},
 	   {0xEE,0x0C,0x22,0x08},
@@ -744,7 +939,7 @@
 	   {0xFC,0x0A,0x14,0x0C},
 	   {0x00,0x08,0x10,0x10}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 */
+	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 - 800 */
 	   {0xEC,0x02,0x24,0x1C},
 	   {0xF2,0x04,0x1E,0x18},
 	   {0xEB,0x15,0x25,0xF6},
@@ -789,7 +984,7 @@
 	   {0xFB,0x04,0x15,0x18},
 	   {0x00,0x06,0x10,0x14}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_4 */
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_4 - 320 */
 	   {0x00,0xE0,0x10,0x60},
 	   {0x00,0xEE,0x10,0x44},
 	   {0x00,0xF4,0x10,0x38},
@@ -798,7 +993,7 @@
 	   {0x00,0x00,0x10,0x20},
 	   {0x00,0x04,0x10,0x18}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_5 */
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_5 - 640 */
 	   {0xF5,0xEE,0x1B,0x44},
 	   {0xF8,0xF4,0x18,0x38},
 	   {0xF1,0xF7,0x1F,0x32},
@@ -807,7 +1002,7 @@
 	   {0xFB,0x01,0x15,0x1E},
 	   {0x00,0x04,0x10,0x18}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_6 */
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_6 - 720 */
 	   {0xF5,0xEE,0x1B,0x2A},
 	   {0xEE,0xFE,0x22,0x24},
 	   {0xF3,0x00,0x1D,0x20},
@@ -816,7 +1011,7 @@
 	   {0xFB,0x04,0x15,0x18},
 	   {0x00,0x06,0x10,0x14}, 
 	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_7 */
+	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_7 - 800 */
 	   {0xF5,0xEE,0x1B,0x44},
 	   {0xF8,0xF4,0x18,0x38},
 	   {0xFC,0xFB,0x14,0x2A},
@@ -829,9 +1024,8 @@
 
 static int           filter = -1;
 static unsigned char filter_tb;
-//~Eden Chen
 
-/* ---------------------- Routine prototypes ------------------------- */
+/* ---------------------- Prototypes ------------------------- */
 
 /* Interface used by the world */
 #ifndef MODULE
@@ -894,10 +1088,6 @@
                                    const struct fb_fillrect *rect);
 extern void     fbcon_sis_copyarea(struct fb_info *info, 
                                    const struct fb_copyarea *area);
-#if 0				   
-extern void     cfb_imageblit(struct fb_info *info, 
-                              const struct fb_image *image);
-#endif			      
 extern int      fbcon_sis_sync(struct fb_info *info);
 static int      sisfb_ioctl(struct inode *inode, 
 	 		    struct file *file,
@@ -905,14 +1095,14 @@
 			    unsigned long arg, 
 		       	    struct fb_info *info);
 extern int	sisfb_mode_rate_to_dclock(SiS_Private *SiS_Pr, 
-			      PSIS_HW_DEVICE_INFO HwDeviceExtension,
+			      PSIS_HW_INFO HwDeviceExtension,
 			      unsigned char modeno, unsigned char rateindex);	
-extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension,
+extern int      sisfb_mode_rate_to_ddata(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
 			 unsigned char modeno, unsigned char rateindex,
 			 unsigned int *left_margin, unsigned int *right_margin, 
 			 unsigned int *upper_margin, unsigned int *lower_margin,
 			 unsigned int *hsync_len, unsigned int *vsync_len,
-			 unsigned int *sync, unsigned int *vmode);			      		    			      
+			 unsigned int *sync, unsigned int *vmode);
 #endif
 			
 static int      sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
@@ -923,9 +1113,9 @@
 extern void     sisfb_syncaccel(void);
 
 /* Internal general routines */
-static void     sisfb_search_mode(const char *name);
-static int      sisfb_validate_mode(int modeindex);
-static u8       sisfb_search_refresh_rate(unsigned int rate);
+static void     sisfb_search_mode(char *name, BOOLEAN quiet);
+static int      sisfb_validate_mode(int modeindex, unsigned long vbflags);
+static u8       sisfb_search_refresh_rate(unsigned int rate, int index);
 static int      sisfb_setcolreg(unsigned regno, unsigned red, unsigned green,
 			unsigned blue, unsigned transp,
 			struct fb_info *fb_info);
@@ -939,6 +1129,11 @@
 static BOOLEAN  sisfbcheckvretracecrt2(void);
 static BOOLEAN  sisfbcheckvretracecrt1(void);
 static BOOLEAN  sisfb_bridgeisslave(void);
+static void     sisfb_detect_VB_connect(void);
+static void     sisfb_get_VB_type(void);
+
+static void     sisfb_handle_ddc(struct sisfb_monitor *monitor, int crtno);
+static BOOLEAN  sisfb_interpret_edid(struct sisfb_monitor *monitor, unsigned char *buffer);
 
 /* SiS-specific Export functions */
 void            sis_dispinfo(struct ap_data *rec);
@@ -952,15 +1147,9 @@
 /* Chipset-dependent internal routines */
 #ifdef CONFIG_FB_SIS_300
 static int      sisfb_get_dram_size_300(void);
-static void     sisfb_detect_VB_connect_300(void);
-static void     sisfb_get_VB_type_300(void);
-static int      sisfb_has_VB_300(void);
 #endif
 #ifdef CONFIG_FB_SIS_315
 static int      sisfb_get_dram_size_315(void);
-static void     sisfb_detect_VB_connect_315(void);
-static void     sisfb_get_VB_type_315(void);
-static int      sisfb_has_VB_315(void);
 #endif
 
 /* Internal heap routines */
@@ -973,30 +1162,40 @@
 static void     sisfb_free_node(SIS_OH *poh);
 
 /* Internal routines to access PCI configuration space */
-BOOLEAN         sisfb_query_VGA_config_space(PSIS_HW_DEVICE_INFO psishw_ext,
+BOOLEAN         sisfb_query_VGA_config_space(PSIS_HW_INFO psishw_ext,
 	          	unsigned long offset, unsigned long set, unsigned long *value);
-BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_DEVICE_INFO psishw_ext,
+BOOLEAN         sisfb_query_north_bridge_space(PSIS_HW_INFO psishw_ext,
 	         	unsigned long offset, unsigned long set, unsigned long *value);
 
+/* Sensing routines */
+void            SiS_Sense30x(void);
+int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
+void            SiS_SenseCh(void);
 
 /* Routines from init.c/init301.c */
-extern void 	SiSRegInit(SiS_Private *SiS_Pr, USHORT BaseAddr);
-extern BOOLEAN  SiSInit(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension);
-extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_DEVICE_INFO HwDeviceExtension, USHORT ModeNo);
-extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr);
-extern void     SiS_LongWait(SiS_Private *SiS_Pr);
+extern void 	SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr);
+extern BOOLEAN  SiSSetMode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo, USHORT ModeNo);
+extern void     SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable);
+extern void     SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable);
+
+extern BOOLEAN  sisfb_gettotalfrommode(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceExtension,
+		       unsigned char modeno, int *htotal, int *vtotal, unsigned char rateindex);
 
-/* TW: Chrontel TV functions */
+/* Chrontel TV functions */
 extern USHORT 	SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void 	SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern USHORT 	SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void 	SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx);
 extern void     SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh);
 extern void     SiS_DDC2Delay(SiS_Private *SiS_Pr, USHORT delaytime);
+extern void     SiS_SetChrontelGPIO(SiS_Private *SiS_Pr, USHORT myvbinfo);
+extern USHORT   SiS_HandleDDC(SiS_Private *SiS_Pr, unsigned long VBFlags, int VGAEngine,
+		              USHORT adaptnum, USHORT DDCdatatype, unsigned char *buffer);
+extern USHORT   SiS_ReadDDC1Bit(SiS_Private *SiS_Pr);
+extern void 	SiS_Chrontel701xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
+extern void 	SiS_Chrontel701xBLOff(SiS_Private *SiS_Pr);
+extern void 	SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
+extern void 	SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwDeviceInfo);
 
-/* TW: Sensing routines */
-void            SiS_Sense30x(void);
-int             SISDoSense(int tempbl, int tempbh, int tempcl, int tempch);
-void            SiS_SenseCh(void);			
 			
 #endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/vgatypes.h fbdev-2.6/drivers/video/sis/vgatypes.h
--- linus-2.6/drivers/video/sis/vgatypes.h	Thu Oct 16 14:13:42 2003
+++ fbdev-2.6/drivers/video/sis/vgatypes.h	Thu Oct 16 14:13:42 2003
@@ -1,18 +1,48 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vgatypes.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/*
+ * General type definitions for universal mode switching modules
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *		Silicon Integrated Systems
+ *
+ */
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
 #ifdef LINUX_XF86
+#include "xf86Version.h"
 #include "xf86Pci.h"
 #endif
 
-#ifdef LINUX_KERNEL  /* TW: We don't want the X driver to depend on kernel source */
+#ifdef LINUX_KERNEL  /* We don't want the X driver to depend on kernel source */
 #include <linux/ioctl.h>
 #endif
 
-#ifndef TC
-#define far
-#endif
-
 #ifndef FALSE
 #define FALSE   0
 #endif
@@ -49,47 +79,34 @@
 typedef unsigned long ULONG;
 #endif
 
-#ifndef PUCHAR
-typedef UCHAR far *PUCHAR;
-#endif
-
-#ifndef PUSHORT
-typedef USHORT far *PUSHORT;
-#endif
-
-#ifndef PULONG
-typedef ULONG far *PULONG;
-#endif
-
-#ifndef PVOID
-typedef void far *PVOID;
-#endif
-#ifndef VOID
-typedef void VOID;
-#endif
-
 #ifndef BOOLEAN
 typedef UCHAR BOOLEAN;
 #endif
 
-#ifndef WINCE_HEADER
 #ifndef bool
 typedef UCHAR bool;
 #endif
-#endif /*WINCE_HEADER*/
 
-#ifndef VBIOS_VER_MAX_LENGTH
-#define VBIOS_VER_MAX_LENGTH         4
+#ifdef LINUX_KERNEL
+typedef unsigned long SISIOADDRESS;
+#endif
+
+#ifdef LINUX_XF86
+#if XF86_VERSION_CURRENT < XF86_VERSION_NUMERIC(4,2,0,0,0)
+typedef unsigned long IOADDRESS;
+typedef unsigned long SISIOADDRESS;
+#else
+typedef IOADDRESS SISIOADDRESS;
+#endif
 #endif
 
-#ifndef LINUX_KERNEL   /* For kernel, this is defined in sisfb.h */
-#ifndef WIN2000
+#ifndef LINUX_KERNEL   /* For the linux kernel, this is defined in sisfb.h */
 #ifndef SIS_CHIP_TYPE
 typedef enum _SIS_CHIP_TYPE {
     SIS_VGALegacy = 0,
 #ifdef LINUX_XF86
-    SIS_530,	/* TW */
-    SIS_OLD,	/* TW */
+    SIS_530,
+    SIS_OLD,
 #endif
     SIS_300,
     SIS_630,
@@ -101,30 +118,29 @@
     SIS_550,
     SIS_650,
     SIS_740,
-    SIS_330, 
+    SIS_330,
+    SIS_660,
+    SIS_760,
     MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 #endif
 #endif
-#endif
 
-#ifndef WIN2000
 #ifndef SIS_VB_CHIP_TYPE
 typedef enum _SIS_VB_CHIP_TYPE {
     VB_CHIP_Legacy = 0,
     VB_CHIP_301,
-    VB_CHIP_301B,      
+    VB_CHIP_301B,
     VB_CHIP_301LV,
     VB_CHIP_302,
     VB_CHIP_302B,
     VB_CHIP_302LV,
+    VB_CHIP_301C,
     VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
     MAX_VB_CHIP
 } SIS_VB_CHIP_TYPE;
 #endif
-#endif
 
-#ifndef WIN2000
 #ifndef SIS_LCD_TYPE
 typedef enum _SIS_LCD_TYPE {
     LCD_INVALID = 0,
@@ -136,18 +152,20 @@
     LCD_1600x1200,
     LCD_1920x1440,
     LCD_2048x1536,
-    LCD_320x480,       /* TW: FSTN */
+    LCD_320x480,       /* FSTN, DSTN */
     LCD_1400x1050,
     LCD_1152x864,
     LCD_1152x768,
     LCD_1280x768,
     LCD_1024x600,
+    LCD_640x480_2,     /* FSTN, DSTN */
+    LCD_640x480_3,     /* FSTN, DSTN */
+    LCD_848x480,
+    LCD_CUSTOM,
     LCD_UNKNOWN
 } SIS_LCD_TYPE;
 #endif
-#endif
 
-#ifndef WIN2000 /* mark by Paul, Move definition to sisv.h*/
 #ifndef PSIS_DSReg
 typedef struct _SIS_DSReg
 {
@@ -156,36 +174,27 @@
 } SIS_DSReg, *PSIS_DSReg;
 #endif
 
-#ifndef SIS_HW_DEVICE_INFO
-
-typedef struct _SIS_HW_DEVICE_INFO  SIS_HW_DEVICE_INFO, *PSIS_HW_DEVICE_INFO;
+#ifndef SIS_HW_INFO
 
-typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_DEVICE_INFO, ULONG, ULONG, ULONG *);
+typedef struct _SIS_HW_INFO  SIS_HW_INFO, *PSIS_HW_INFO;
 
+typedef BOOLEAN (*PSIS_QUERYSPACE)   (PSIS_HW_INFO, ULONG, ULONG, ULONG *);
 
-struct _SIS_HW_DEVICE_INFO
+struct _SIS_HW_INFO
 {
-    PVOID  pDevice;              /* The pointer to the physical device data structure
-                                    in each OS or NULL for unused. */
-    UCHAR  *pjVirtualRomBase;    /* base virtual address of VBIOS ROM Space */
-                                 /* or base virtual address of ROM image file. */
-                                 /* if NULL, then read from pjROMImage; */
-                                 /* Note:ROM image file is the file of VBIOS ROM */
+#ifdef LINUX_XF86
+    PCITAG PciTag;		 /* PCI Tag */
+#endif
 
-    BOOLEAN UseROM;		 /* TW: Use the ROM image if provided */
- 
-    UCHAR  *pjCustomizedROMImage;/* base virtual address of ROM image file. */
-                                 /* wincE:ROM image file is the file for OEM */
-                                 /*       customized table */
-                                 /* Linux: not used */
-                                 /* NT   : not used  */
-                                 /* Note : pjCustomizedROMImage=NULL if no ROM image file */
+    UCHAR  *pjVirtualRomBase;    /* ROM image */
+
+    BOOLEAN UseROM;		 /* Use the ROM image if provided */
 
     UCHAR  *pjVideoMemoryAddress;/* base virtual memory address */
                                  /* of Linear VGA memory */
 
     ULONG  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
-    ULONG  ulIOAddress;          /* base I/O address of VGA ports (0x3B0) */
+    SISIOADDRESS ulIOAddress;    /* base I/O address of VGA ports (0x3B0) */
     UCHAR  jChipType;            /* Used to Identify SiS Graphics Chip */
                                  /* defined in the data structure type  */
                                  /* "SIS_CHIP_TYPE" */
@@ -194,20 +203,12 @@
     UCHAR  ujVBChipID;           /* the ID of video bridge */
                                  /* defined in the data structure type */
                                  /* "SIS_VB_CHIP_TYPE" */
+#ifdef LINUX_KERNEL
+    BOOLEAN Is301BDH;
+#endif
 
-    USHORT usExternalChip;       /* NO VB or other video bridge(not  */
+    USHORT usExternalChip;       /* NO VB or other video bridge (other than  */
                                  /* SiS video bridge) */
-                                 /* if ujVBChipID = VB_CHIP_UNKNOWN, */
-                                 /* then bit0=1 : LVDS,bit1=1 : trumpion, */
-                                 /* bit2=1 : CH7005 & no video bridge if */
-                                 /* usExternalChip = 0. */
-                                 /* Note: CR37[3:1]: */
-                                 /*             001:SiS 301 */
-                                 /*             010:LVDS */
-                                 /*             011:Trumpion LVDS Scaling Chip */
-                                 /*             100:LVDS(LCD-out)+Chrontel 7005 */
-                                 /*             101:Single Chrontel 7005 */
-				 /* TW: This has changed on 310/325 series! */
 
     ULONG  ulCRT2LCDType;        /* defined in the data structure type */
                                  /* "SIS_LCD_TYPE" */
@@ -215,6 +216,8 @@
     BOOLEAN bIntegratedMMEnabled;/* supporting integration MM enable */
                                       
     BOOLEAN bSkipDramSizing;     /* True: Skip video memory sizing. */
+
+#ifdef LINUX_KERNEL
     PSIS_DSReg  pSR;             /* restore SR registers in initial function. */
                                  /* end data :(idx, val) =  (FF, FF). */
                                  /* Note : restore SR registers if  */
@@ -224,6 +227,7 @@
                                  /* end data :(idx, val) =  (FF, FF) */
                                  /* Note : restore cR registers if  */
                                  /* bSkipDramSizing = TRUE */
+#endif
 
     PSIS_QUERYSPACE  pQueryVGAConfigSpace; /* Get/Set VGA Configuration  */
                                            /* space */
@@ -231,31 +235,19 @@
     PSIS_QUERYSPACE  pQueryNorthBridgeSpace;/* Get/Set North Bridge  */
                                             /* space  */
 
-    UCHAR  szVBIOSVer[VBIOS_VER_MAX_LENGTH];
-
-    UCHAR  pdc;			/* TW: PanelDelayCompensation */
-    
-#ifdef LINUX_KERNEL
-    BOOLEAN Is301BDH;
-#endif        
-
-#ifdef LINUX_XF86
-    PCITAG PciTag;		/* PCI Tag for Linux XF86 */
-#endif
+    UCHAR  pdc;			/* PanelDelayCompensation */
 };
 #endif
-#endif 
 
-
-/* TW: Addtional IOCTL for communication sisfb <> X driver        */
-/*     If changing this, sisfb.h must also be changed (for sisfb) */
+/* Addtional IOCTL for communication sisfb <> X driver        */
+/* If changing this, sisfb.h must also be changed (for sisfb) */
 
 #ifdef LINUX_XF86  /* We don't want the X driver to depend on the kernel source */
 
-/* TW: ioctl for identifying and giving some info (esp. memory heap start) */
+/* ioctl for identifying and giving some info (esp. memory heap start) */
 #define SISFB_GET_INFO    0x80046ef8  /* Wow, what a terrible hack... */
 
-/* TW: Structure argument for SISFB_GET_INFO ioctl  */
+/* Structure argument for SISFB_GET_INFO ioctl  */
 typedef struct _SISFB_INFO sisfb_info, *psisfb_info;
 
 struct _SISFB_INFO {
@@ -284,86 +276,15 @@
 	
 	unsigned char sisfb_lcda;
 
-	char reserved[235]; 		/* for future use */
-};
-#endif
+	unsigned long sisfb_vbflags;
+	unsigned long sisfb_currentvbflags;
 
-#ifndef WIN2000
-#ifndef WINCE_HEADER
-#ifndef BUS_DATA_TYPE
-typedef enum _BUS_DATA_TYPE {
-    ConfigurationSpaceUndefined = -1,
-    Cmos,
-    EisaConfiguration,
-    Pos,
-    CbusConfiguration,
-    PCIConfiguration,
-    VMEConfiguration,
-    NuBusConfiguration,
-    PCMCIAConfiguration,
-    MPIConfiguration,
-    MPSAConfiguration,
-    PNPISAConfiguration,
-    MaximumBusDataType
-} BUS_DATA_TYPE, *PBUS_DATA_TYPE;
-#endif
-#endif /* WINCE_HEADER */
-
-#ifndef PCI_TYPE0_ADDRESSES
-#define PCI_TYPE0_ADDRESSES             6
-#endif
-
-#ifndef PCI_TYPE1_ADDRESSES
-#define PCI_TYPE1_ADDRESSES             2
-#endif
-
-#ifndef WINCE_HEADER
-#ifndef PCI_COMMON_CONFIG
-typedef struct _PCI_COMMON_CONFIG {
-    USHORT  VendorID;                   /* (ro)                 */
-    USHORT  DeviceID;                   /* (ro)                 */
-    USHORT  Command;                    /* Device control       */
-    USHORT  Status;
-    UCHAR   RevisionID;                 /* (ro)                 */
-    UCHAR   ProgIf;                     /* (ro)                 */
-    UCHAR   SubClass;                   /* (ro)                 */
-    UCHAR   BaseClass;                  /* (ro)                 */
-    UCHAR   CacheLineSize;              /* (ro+)                */
-    UCHAR   LatencyTimer;               /* (ro+)                */
-    UCHAR   HeaderType;                 /* (ro)                 */
-    UCHAR   BIST;                       /* Built in self test   */
-
-    union {
-        struct _PCI_HEADER_TYPE_0 {
-            ULONG   BaseAddresses[PCI_TYPE0_ADDRESSES];
-            ULONG   CIS;
-            USHORT  SubVendorID;
-            USHORT  SubSystemID;
-            ULONG   ROMBaseAddress;
-            ULONG   Reserved2[2];
-
-            UCHAR   InterruptLine;      /*                    */
-            UCHAR   InterruptPin;       /* (ro)               */
-            UCHAR   MinimumGrant;       /* (ro)               */
-            UCHAR   MaximumLatency;     /* (ro)               */
-        } type0;
-
-
-    } u;
-
-    UCHAR   DeviceSpecific[192];
-
-} PCI_COMMON_CONFIG, *PPCI_COMMON_CONFIG;
-#endif
-#endif /* WINCE_HEADER */
+	int sisfb_scalelcd;
+	unsigned long sisfb_specialtiming;
 
-#ifndef FIELD_OFFSET
-#define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
+	char reserved[219]; 		/* for future use */
+};
 #endif
 
-#ifndef PCI_COMMON_HDR_LENGTH
-#define PCI_COMMON_HDR_LENGTH (FIELD_OFFSET (PCI_COMMON_CONFIG, DeviceSpecific))
-#endif
 #endif
 
-#endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sis/vstruct.h fbdev-2.6/drivers/video/sis/vstruct.h
--- linus-2.6/drivers/video/sis/vstruct.h	Thu Oct 16 14:13:42 2003
+++ fbdev-2.6/drivers/video/sis/vstruct.h	Thu Oct 16 14:13:42 2003
@@ -1,3 +1,37 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/vstruct.h,v 1.0 2001/06/15 21:23:00 dawes Exp $ */
+/*
+ * General structure definitions for universal mode switching modules
+ *
+ * Copyright 2002, 2003 by Thomas Winischhofer, Vienna, Austria
+ *
+ * If distributed as part of the linux kernel, the contents of this file
+ * is entirely covered by the GPL.
+ *
+ * Otherwise, the following terms apply:
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holder not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  The copyright holder makes no representations
+ * about the suitability of this software for any purpose.  It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: 	Thomas Winischhofer <thomas@winischhofer.net>
+ *              Silicon Integrated Systems
+ *
+ */
+
 #ifdef _INIT_
 #define EXTERN
 #else
@@ -58,7 +92,6 @@
 	UCHAR  CR[15];
 } SiS_LVDSCRT1DataStruct;
 
-/*add for LCDA*/
 typedef struct _SiS_LCDACRT1DataStruct
 {
 	UCHAR  CR[17];
@@ -111,9 +144,7 @@
 	UCHAR  Ext_ModeID;
 	USHORT Ext_ModeFlag;
 	USHORT Ext_ModeInfo;
-	USHORT Ext_Point;
 	USHORT Ext_VESAID;
-	UCHAR  Ext_VESAMEMSize;
 	UCHAR  Ext_RESINFO;
 	UCHAR  VB_ExtTVFlickerIndex;
 	UCHAR  VB_ExtTVEdgeIndex;
@@ -130,7 +161,6 @@
 	UCHAR  ModeID;
 	USHORT XRes;
 	USHORT YRes;
-	USHORT ROM_OFFSET;
 } SiS_Ext2Struct;
 
 typedef struct _SiS_Part2PortTblStruct
@@ -183,40 +213,64 @@
 
 typedef UCHAR DRAM4Type[4];
 
+/* Defines for SiS_Customt */
+#define CUT_NONE         0
+#define CUT_FORCENONE    1
+#define CUT_BARCO1366    2
+#define CUT_BARCO1024    3
+#define CUT_COMPAQ1280   4
+#define CUT_COMPAQ12802  5
+#define CUT_PANEL848     6
+#define CUT_CLEVO1024    7
+#define CUT_CLEVO10242   8
+#define CUT_CLEVO1400    9
+#define CUT_CLEVO14002  10
+#define CUT_UNIWILL1024 11
+#define CUT_ASUSL3000D  12
+
 typedef struct _SiS_Private
 {
 #ifdef LINUX_KERNEL
-        USHORT RelIO;
+        SISIOADDRESS RelIO;
 #endif
-	USHORT SiS_P3c4;
-	USHORT SiS_P3d4;
-	USHORT SiS_P3c0;
-	USHORT SiS_P3ce;
-	USHORT SiS_P3c2;
-	USHORT SiS_P3ca;
-	USHORT SiS_P3c6;
-	USHORT SiS_P3c7;
-	USHORT SiS_P3c8;
-	USHORT SiS_P3c9;
-	USHORT SiS_P3da;
-	USHORT SiS_Part1Port;
-	USHORT SiS_Part2Port;
-	USHORT SiS_Part3Port;
-	USHORT SiS_Part4Port;
-	USHORT SiS_Part5Port;
+	SISIOADDRESS SiS_P3c4;
+	SISIOADDRESS SiS_P3d4;
+	SISIOADDRESS SiS_P3c0;
+	SISIOADDRESS SiS_P3ce;
+	SISIOADDRESS SiS_P3c2;
+	SISIOADDRESS SiS_P3ca;
+	SISIOADDRESS SiS_P3c6;
+	SISIOADDRESS SiS_P3c7;
+	SISIOADDRESS SiS_P3c8;
+	SISIOADDRESS SiS_P3c9;
+	SISIOADDRESS SiS_P3cb;
+	SISIOADDRESS SiS_P3cd;
+	SISIOADDRESS SiS_P3da;
+	SISIOADDRESS SiS_Part1Port;
+	SISIOADDRESS SiS_Part2Port;
+	SISIOADDRESS SiS_Part3Port;
+	SISIOADDRESS SiS_Part4Port;
+	SISIOADDRESS SiS_Part5Port;
+	SISIOADDRESS SiS_VidCapt;
+	SISIOADDRESS SiS_VidPlay;
 	USHORT SiS_IF_DEF_LVDS;
 	USHORT SiS_IF_DEF_TRUMPION;
 	USHORT SiS_IF_DEF_DSTN;
 	USHORT SiS_IF_DEF_FSTN;
 	USHORT SiS_IF_DEF_CH70xx;
 	USHORT SiS_IF_DEF_HiVision;
+	USHORT SiS_SysFlags;
 	UCHAR  SiS_VGAINFO;
+#ifndef LINUX_KERNEL
+        USHORT SiS_CP1, SiS_CP2, SiS_CP3, SiS_CP4;
+#endif
 	BOOLEAN SiS_UseROM;
 	int    SiS_CHOverScan;
 	BOOLEAN SiS_CHSOverScan;
 	BOOLEAN SiS_ChSW;
 	BOOLEAN SiS_UseLCDA;
 	int    SiS_UseOEM;
+	ULONG  SiS_CustomT;
 	USHORT SiS_Backup70xx;
 	USHORT SiS_CRT1Mode;
 	USHORT SiS_flag_clearbuffer;
@@ -270,15 +324,18 @@
 	USHORT SiS_Panel1280x768;
 	USHORT SiS_Panel1024x600;
 	USHORT SiS_Panel640x480;
+	USHORT SiS_Panel640x480_2;
+	USHORT SiS_Panel640x480_3;
 	USHORT SiS_Panel1152x864;
+	USHORT SiS_PanelCustom;
+	USHORT SiS_PanelBarco1366;
 	USHORT SiS_PanelMax;
 	USHORT SiS_PanelMinLVDS;
 	USHORT SiS_PanelMin301;
 	USHORT SiS_ChrontelInit;
 	
-	/* Pointers: */
 	const SiS_StStruct          *SiS_SModeIDTable;
-	const SiS_StandTableStruct  *SiS_StandTable;
+	SiS_StandTableStruct        *SiS_StandTable;
 	const SiS_ExtStruct         *SiS_EModeIDTable;
 	const SiS_Ext2Struct        *SiS_RefIndex;
 	const SiS_VBModeStruct      *SiS_VBModeIDTable;
@@ -316,7 +373,7 @@
 	const USHORT *pSiS_RGBSenseData;
 	const USHORT *pSiS_VideoSenseData;
 	const USHORT *pSiS_YCSenseData;
-	const USHORT *pSiS_RGBSenseData2; /*301b*/
+	const USHORT *pSiS_RGBSenseData2;
 	const USHORT *pSiS_VideoSenseData2;
 	const USHORT *pSiS_YCSenseData2;
 #endif
@@ -340,15 +397,18 @@
 	const SiS_LCDDataStruct  *SiS_LCD1280x960Data;
 	const SiS_LCDDataStruct  *SiS_NoScaleData1400x1050;
 	const SiS_LCDDataStruct  *SiS_NoScaleData1600x1200;
+	const SiS_LCDDataStruct  *SiS_NoScaleData1280x768;
 	const SiS_LCDDataStruct  *SiS_StLCD1400x1050Data;
 	const SiS_LCDDataStruct  *SiS_StLCD1600x1200Data;
+	const SiS_LCDDataStruct  *SiS_StLCD1280x768Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1400x1050Data;
 	const SiS_LCDDataStruct  *SiS_ExtLCD1600x1200Data;
+	const SiS_LCDDataStruct  *SiS_ExtLCD1280x768Data;
+	const SiS_LCDDataStruct  *SiS_NoScaleData;
 	const SiS_TVDataStruct   *SiS_StPALData;
 	const SiS_TVDataStruct   *SiS_ExtPALData;
 	const SiS_TVDataStruct   *SiS_StNTSCData;
 	const SiS_TVDataStruct   *SiS_ExtNTSCData;
-/*	const SiS_TVDataStruct   *SiS_St1HiTVData;  */
 	const SiS_TVDataStruct   *SiS_St2HiTVData;
 	const SiS_TVDataStruct   *SiS_ExtHiTVData;
 	const UCHAR *SiS_NTSCTiming;
@@ -381,12 +441,23 @@
 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_1;
 	const SiS_LVDSDataStruct  *SiS_LVDS1152x768Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS640x480Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDS320x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1024x768Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1024x768Data_2;
+	const SiS_LVDSDataStruct  *SiS_LCDA1280x1024Data_1;
+	const SiS_LVDSDataStruct  *SiS_LCDA1280x1024Data_2;
 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_1;
 	const SiS_LVDSDataStruct  *SiS_LCDA1400x1050Data_2;
 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_1;
 	const SiS_LVDSDataStruct  *SiS_LCDA1600x1200Data_2;
 	const SiS_LVDSDataStruct  *SiS_LVDSXXXxXXXData_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1366Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDSBARCO1024Data_2;
+	const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_1;
+	const SiS_LVDSDataStruct  *SiS_LVDS848x480Data_2;
 	const SiS_LVDSDataStruct  *SiS_CHTVUNTSCData;
 	const SiS_LVDSDataStruct  *SiS_CHTVONTSCData;
 	const SiS_LVDSDataStruct  *SiS_CHTVUPALData;
@@ -478,6 +549,12 @@
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT11600x1200_2_H;
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1;
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1XXXxXXX_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_1_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_2_H;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3;
+	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1640x480_3_H;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UNTSC;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1ONTSC;
 	const SiS_LVDSCRT1DataStruct  *SiS_CHTVCRT1UPAL;
@@ -486,28 +563,23 @@
 
 	const SiS_LVDSCRT1DataStruct  *SiS_LVDSCRT1320x480_1;
 
-	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1;
-	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_1_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_1_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_1_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_1_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_1_H;
-	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2;
-	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT1800x600_2_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11024x768_2_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11280x1024_2_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11400x1050_2_H;
 	const SiS_LCDACRT1DataStruct  *SiS_LCDACRT11600x1200_2_H;
 
-	/* TW: New for 650/301LV */
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1024x768_1;
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1280x1024_1;
 	const SiS_Part2PortTblStruct *SiS_CRT2Part2_1400x1050_1;
@@ -539,6 +611,9 @@
 	const UCHAR *SiS_CHTVVCLKUPALN;
 	const UCHAR *SiS_CHTVVCLKOPALN;
 	const UCHAR *SiS_CHTVVCLKSOPAL;
+
+	USHORT  PanelXRes;
+	USHORT  PanelYRes;
 	
 	BOOLEAN UseCustomMode;
 	BOOLEAN CRT1UsesCustomMode;
@@ -560,10 +635,15 @@
 	UCHAR   CSR2B;
 	UCHAR   CSR2C;
 	USHORT  CSRClock;
+	USHORT  CSRClock_CRT1;
 	USHORT  CModeFlag;
+	USHORT  CModeFlag_CRT1;
 	USHORT  CInfoFlag;
+
 	BOOLEAN SiS_CHPALM;
 	BOOLEAN SiS_CHPALN;
+
+	int	LVDSHL;
 	
 	BOOLEAN Backup;
 	UCHAR Backup_Mode;
@@ -578,7 +658,21 @@
 	UCHAR Backup_1c;
 	UCHAR Backup_1d;
 	
-	int    UsePanelScaler;
+	int     UsePanelScaler;
+
+	USHORT  CP_Vendor, CP_Product;
+	BOOLEAN CP_HaveCustomData;
+	int     CP_PreferredX, CP_PreferredY;
+	int	CP_MaxX, CP_MaxY, CP_MaxClock;
+	int     CP_HDisplay[7], CP_VDisplay[7];	/* For Custom LCD panel dimensions */
+    	int     CP_HTotal[7], CP_VTotal[7];
+    	int     CP_HSyncStart[7], CP_VSyncStart[7];
+    	int     CP_HSyncEnd[7], CP_VSyncEnd[7];
+	int     CP_HBlankStart[7], CP_VBlankStart[7];
+	int     CP_HBlankEnd[7], CP_VBlankEnd[7];
+    	int     CP_Clock[7];
+	BOOLEAN CP_DataValid[7];
+	BOOLEAN CP_HSync_P[7], CP_VSync_P[7], CP_SyncValid[7];
 } SiS_Private;
 
 #endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/skeletonfb.c fbdev-2.6/drivers/video/skeletonfb.c
--- linus-2.6/drivers/video/skeletonfb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/skeletonfb.c	Thu Oct 16 14:13:32 2003
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
  *
- *  Modified to new api Jan 2001 by James Simmons (jsimmons@transvirtual.com)
+ *  Modified to new api Jan 2001 by James Simmons (jsimmons@infradead.org)
  *
  *  Created 28 Dec 1997 by Geert Uytterhoeven
  *
@@ -469,15 +469,71 @@
 int xxxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
 /*
- *      @set: 	Which fields we are altering in struct fb_cursor 
+ *      @set: 	 Which fields we are altering in struct fb_cursor
  *	@enable: Disable or enable the cursor 
- *      @rop: 	The bit operation we want to do. 
- *      @mask:  This is the cursor mask bitmap. 
- *      @dest:  A image of the area we are going to display the cursor.
- *		Used internally by the driver.	 
- *      @hot:	The hot spot. 
- *	@image:	The actual data for the cursor image.
- */
+ *      @rop: 	 The bit operation we want to do.
+ *      @hot:	 The hot spot.
+ *	@image:	 The actual data for the cursor image.
+ *      @mask:   This is the cursor mask bitmap.
+ */
+
+   /* Disable hardware cursor. We don't want to display the cursor
+      while changing it. Note we use the enable and rop fields in
+      struct fb_cursor that is apart of struct fb_info. Not the
+      cursor data passed in from userland. */
+
+   if (cursor->set & FB_CUR_SETHOT) {
+	info->cursor.hot = cursor->hot;
+   	/* Set the hardware cursor's hot spot  */
+   }
+
+   if (cursor->set & FB_CUR_SETPOS) {
+	info->cursor.image.dx = cursor->image.dx;
+	info->cursor.image.dy = cursor->image.dy;
+   	/* Set the hardware cursor's position */
+   }
+
+   if (cursor->set & FB_CUR_SETSIZE) {
+	info->cursor.image.height = cursor->image.height;
+	info->cursor.image.width = cursor->image.width;
+   	/* Set the hardware cursor's size */
+   }
+
+   if (cursor->set & FB_CUR_SETCMAP) {
+	if (cursor->image.depth == 1) {
+		info->cursor.image.fg_color = cursor->image.fg_color;
+		info->cursor.image.bg_color = cursor->image.bg_color;
+	} else {
+		if (cursor->image.cmap.len)
+			fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
+	}
+	info->curosr.image.depth = cursor->image.depth;
+
+   	/* Set the hardware cursor's color map */
+   }
+
+   /*
+    * Set the cursor shape. The two pieces needed to create
+    * the final image is mask and image.data. The mask is
+    * combined with image.data according to the rop field.
+    */
+   if (cursor->set & FB_CUR_SETSHAPE) {
+ 	switch (info->cursor.rop) {
+	case ROP_XOR:
+		/* ... */
+		break;
+	case ROP_COPY:
+	default:
+		/* ... */
+		break;
+   	}
+	/* ... */
+   }
+
+   if (info->cursor.enable) {
+	/* Now we turn the hardware cursor on */
+   }
+   return 0;
 }
 
 /**
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/softcursor.c fbdev-2.6/drivers/video/softcursor.c
--- linus-2.6/drivers/video/softcursor.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/softcursor.c	Thu Oct 16 14:13:32 2003
@@ -17,13 +17,35 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+#if BITS_PER_LONG == 32
+#define FB_WRITEL fb_writel
+#define FB_READL  fb_readl
+#else
+#define FB_WRITEL fb_writeq
+#define FB_READL  fb_readq
+#endif
+
 int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
 {
-	unsigned int scan_align = info->pixmap.scan_align - 1;
-	unsigned int buf_align = info->pixmap.buf_align - 1;
-	unsigned int i, size, dsize, s_pitch, d_pitch;
-	u8 *dst, src[64];
+	unsigned int scan_align = info->sprite.scan_align - 1;
+	u8 *addr = info->sprite.addr, *dst;
+	unsigned int size, i, j;
+	unsigned long *save;
+
+	if (cursor->image.height > 32 || cursor->image.width > 32)
+		return -ENXIO;
 
+	if (cursor->set & FB_CUR_SETCMAP) {
+		if (cursor->image.depth == 1) {
+			info->cursor.image.bg_color = cursor->image.bg_color;
+			info->cursor.image.fg_color = cursor->image.fg_color;
+		} else {
+			if (cursor->image.cmap.len)
+				fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
+		}
+		info->cursor.image.depth = cursor->image.depth;
+	}
+
 	if (cursor->set & FB_CUR_SETSIZE) {
 		info->cursor.image.height = cursor->image.height;
 		info->cursor.image.width = cursor->image.width;
@@ -36,46 +58,48 @@
 
 	if (cursor->set & FB_CUR_SETHOT)
 		info->cursor.hot = cursor->hot;
-	
-	if (cursor->set & FB_CUR_SETCMAP) {
-		if (cursor->image.depth == 1) {
-			info->cursor.image.bg_color = cursor->image.bg_color;
-			info->cursor.image.fg_color = cursor->image.fg_color;
-		} else {
-			if (cursor->image.cmap.len)
-				fb_copy_cmap(&cursor->image.cmap, &info->cursor.image.cmap, 0);
-		}
-		info->cursor.image.depth = cursor->image.depth;
-	}	
 
-	s_pitch = (info->cursor.image.width + 7) >> 3;
-	dsize = s_pitch * info->cursor.image.height;
-	d_pitch = (s_pitch + scan_align) & ~scan_align;
-	size = d_pitch * info->cursor.image.height + buf_align;
-	size &= ~buf_align;
-	dst = info->pixmap.addr + fb_get_buffer_offset(info, size);
-
-	if (info->cursor.enable) {
-		switch (info->cursor.rop) {
-		case ROP_XOR:
-			for (i = 0; i < dsize; i++)
-				src[i] = cursor->image.data[i] ^ info->cursor.mask[i]; 
-			break;
-		case ROP_COPY:
-		default:
-			for (i = 0; i < dsize; i++)
-				src[i] = cursor->image.data[i] & info->cursor.mask[i];
-			break;
+	if (cursor->set & FB_CUR_SETSHAPE)
+		load_cursor_image(info);
+
+	if (!cursor->enable || (info->cursor.enable && (cursor->set & FB_CUR_SETPOS))) {
+		// Draw saved area
+		i = (info->cursor.image.width * info->var.bits_per_pixel + 7) >> 3;
+		size = (i + scan_align) & ~scan_align;
+		i = (info->cursor.image.dx * info->var.bits_per_pixel >> 3);
+		dst = info->screen_base + info->cursor.image.dy * info->fix.line_length + i;
+
+		save = (unsigned long *) addr + info->sprite.size/2;
+		for (i = 0; i < 32; i++) {
+			unsigned long *dst0 = (unsigned long *) dst;
+			for (j = 0; j < size; j++) {
+				FB_WRITEL(FB_READL(save++), dst0++);
+			}
+			dst += info->fix.line_length;
 		}
-	} else 
-		memcpy(src, cursor->image.data, dsize);
-	
-	move_buf_aligned(info, dst, src, d_pitch, s_pitch, info->cursor.image.height);
-	info->cursor.image.data = dst;
+	}
 	
-	info->fbops->fb_imageblit(info, &info->cursor.image);
-	atomic_dec(&info->pixmap.count);
-	smp_mb__after_atomic_dec();
+	if (!info->cursor.enable || (cursor->set & FB_CUR_SETPOS)) {
+		// Save the area under the cursor
+		i = (info->cursor.image.width * info->var.bits_per_pixel + 7) >> 3;
+		size = (i + scan_align) & ~scan_align;
+		i = (info->cursor.image.dx * info->var.bits_per_pixel >> 3);
+		dst = info->screen_base + info->cursor.image.dy * info->fix.line_length + i;
+
+		save = (unsigned long *) addr + info->sprite.size/2;
+		for (i = 0; i < 32; i++) {
+			unsigned long *dst0 = (unsigned long *) dst;
+			for (j = 0; j < size; j++) {
+				FB_WRITEL(FB_READL(dst0++), save++);
+			}
+			dst += info->fix.line_length;
+		}
+	}
+
+	if (cursor->enable) {
+		info->cursor.image.data = addr;
+		info->fbops->fb_imageblit(info, &info->cursor.image);
+	}
 	return 0;
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/sstfb.c fbdev-2.6/drivers/video/sstfb.c
--- linus-2.6/drivers/video/sstfb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/sstfb.c	Thu Oct 16 14:13:32 2003
@@ -1475,8 +1475,8 @@
 
 	info->flags	= FBINFO_FLAG_DEFAULT;
 	info->fbops	= &sstfb_ops;
-	info->currcon	= -1;
 	info->pseudo_palette = &all->pseudo_palette;
+	info->class_dev.dev	= &pdev->dev;
 
 	fix->type	= FB_TYPE_PACKED_PIXELS;
 	fix->visual	= FB_VISUAL_TRUECOLOR;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/stifb.c fbdev-2.6/drivers/video/stifb.c
--- linus-2.6/drivers/video/stifb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/stifb.c	Thu Oct 16 14:13:32 2003
@@ -1282,7 +1282,6 @@
 	info->fbops = &stifb_ops;
 	info->screen_base = (void*) REGION_BASE(fb,1);
 	info->flags = FBINFO_FLAG_DEFAULT;
-	info->currcon = -1;
 
 	/* This has to been done !!! */
 	fb_alloc_cmap(&info->cmap, 256, 0);
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/tcx.c fbdev-2.6/drivers/video/tcx.c
--- linus-2.6/drivers/video/tcx.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/tcx.c	Thu Oct 16 14:13:32 2003
@@ -121,6 +121,7 @@
 	int			lowdepth;
 
 	struct sbus_dev		*sdev;
+	struct fb_info		*info;
 	struct list_head	list;
 };
 
@@ -300,60 +301,57 @@
 	info->fix.accel = FB_ACCEL_SUN_TCX;
 }
 
-struct all_info {
-	struct fb_info info;
-	struct tcx_par par;
-	struct list_head list;
-};
 static LIST_HEAD(tcx_list);
 
 static void tcx_init_one(struct sbus_dev *sdev)
 {
-	struct all_info *all;
+	struct fb_info *info;
+	struct tcx_par *par;
 	int linebytes, i;
 
-	all = kmalloc(sizeof(*all), GFP_KERNEL);
-	if (!all) {
+	info = framebuffer_alloc(sizeof(*par), NULL);
+	if (!info) {
 		printk(KERN_ERR "tcx: Cannot allocate memory.\n");
 		return;
 	}
-	memset(all, 0, sizeof(*all));
+	par = info->par;
+	par->info = info;
 
-	INIT_LIST_HEAD(&all->list);
+	INIT_LIST_HEAD(&par->list);
 
-	spin_lock_init(&all->par.lock);
-	all->par.sdev = sdev;
+	spin_lock_init(&par->lock);
+	par->sdev = sdev;
 
-	all->par.lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
+	par->lowdepth = prom_getbool(sdev->prom_node, "tcx-8-bit");
 
-	sbusfb_fill_var(&all->info.var, sdev->prom_node, 8);
+	sbusfb_fill_var(&info->var, sdev->prom_node, 8);
 
 	linebytes = prom_getintdefault(sdev->prom_node, "linebytes",
-				       all->info.var.xres);
-	all->par.fbsize = PAGE_ALIGN(linebytes * all->info.var.yres);
+				       info->var.xres);
+	par->fbsize = PAGE_ALIGN(linebytes * info->var.yres);
 
-	all->par.tec = (struct tcx_tec *)
+	par->tec = (struct tcx_tec *)
 		sbus_ioremap(&sdev->resource[7], 0,
 			     sizeof(struct tcx_tec), "tcx tec");
-	all->par.thc = (struct tcx_thc *)
+	par->thc = (struct tcx_thc *)
 		sbus_ioremap(&sdev->resource[9], 0,
 			     sizeof(struct tcx_thc), "tcx thc");
-	all->par.bt = (struct bt_regs *)
+	par->bt = (struct bt_regs *)
 		sbus_ioremap(&sdev->resource[8], 0,
 			     sizeof(struct bt_regs), "tcx dac");
-	memcpy(&all->par.mmap_map, &__tcx_mmap_map, sizeof(all->par.mmap_map));
-	if (!all->par.lowdepth) {
-		all->par.cplane = (volatile u32 *)
+	memcpy(&par->mmap_map, &__tcx_mmap_map, sizeof(par->mmap_map));
+	if (!par->lowdepth) {
+		par->cplane = (volatile u32 *)
 			sbus_ioremap(&sdev->resource[4], 0,
-				     all->par.fbsize * sizeof(u32), "tcx cplane");
+				     par->fbsize * sizeof(u32), "tcx cplane");
 	} else {
-		all->par.mmap_map[1].size = SBUS_MMAP_EMPTY;
-		all->par.mmap_map[4].size = SBUS_MMAP_EMPTY;
-		all->par.mmap_map[5].size = SBUS_MMAP_EMPTY;
-		all->par.mmap_map[6].size = SBUS_MMAP_EMPTY;
+		par->mmap_map[1].size = SBUS_MMAP_EMPTY;
+		par->mmap_map[4].size = SBUS_MMAP_EMPTY;
+		par->mmap_map[5].size = SBUS_MMAP_EMPTY;
+		par->mmap_map[6].size = SBUS_MMAP_EMPTY;
 	}
 
-	all->par.physbase = 0;
+	par->physbase = 0;
 	for (i = 0; i < TCX_MMAP_ENTRIES; i++) {
 		int j;
 
@@ -370,58 +368,56 @@
 			j = i;
 			break;
 		};
-		all->par.mmap_map[i].poff = sdev->reg_addrs[j].phys_addr;
+		par->mmap_map[i].poff = sdev->reg_addrs[j].phys_addr;
 	}
 
-	all->info.flags = FBINFO_FLAG_DEFAULT;
-	all->info.fbops = &tcx_ops;
+	info->flags = FBINFO_FLAG_DEFAULT;
+	info->fbops = &tcx_ops;
 #ifdef CONFIG_SPARC32
-	all->info.screen_base = (char *)
+	info->screen_base = (char *)
 		prom_getintdefault(sdev->prom_node, "address", 0);
 #endif
-	if (!all->info.screen_base)
-		all->info.screen_base = (char *)
+	if (!info->screen_base)
+		info->screen_base = (char *)
 			sbus_ioremap(&sdev->resource[0], 0,
-				     all->par.fbsize, "tcx ram");
-	all->info.currcon = -1;
-	all->info.par = &all->par;
+				     par->fbsize, "tcx ram");
 
 	/* Initialize brooktree DAC. */
-	sbus_writel(0x04 << 24, &all->par.bt->addr);         /* color planes */
-	sbus_writel(0xff << 24, &all->par.bt->control);
-	sbus_writel(0x05 << 24, &all->par.bt->addr);
-	sbus_writel(0x00 << 24, &all->par.bt->control);
-	sbus_writel(0x06 << 24, &all->par.bt->addr);         /* overlay plane */
-	sbus_writel(0x73 << 24, &all->par.bt->control);
-	sbus_writel(0x07 << 24, &all->par.bt->addr);
-	sbus_writel(0x00 << 24, &all->par.bt->control);
+	sbus_writel(0x04 << 24, &par->bt->addr);         /* color planes */
+	sbus_writel(0xff << 24, &par->bt->control);
+	sbus_writel(0x05 << 24, &par->bt->addr);
+	sbus_writel(0x00 << 24, &par->bt->control);
+	sbus_writel(0x06 << 24, &par->bt->addr);         /* overlay plane */
+	sbus_writel(0x73 << 24, &par->bt->control);
+	sbus_writel(0x07 << 24, &par->bt->addr);
+	sbus_writel(0x00 << 24, &par->bt->control);
 
-	tcx_reset(&all->info);
+	tcx_reset(info);
 
-	tcx_blank(0, &all->info);
+	tcx_blank(0, info);
 
-	if (fb_alloc_cmap(&all->info.cmap, 256, 0)) {
+	if (fb_alloc_cmap(&info->cmap, 256, 0)) {
 		printk(KERN_ERR "tcx: Could not allocate color map.\n");
-		kfree(all);
+		kfree(info);
 		return;
 	}
 
-	tcx_init_fix(&all->info, linebytes);
+	tcx_init_fix(info, linebytes);
 
-	if (register_framebuffer(&all->info) < 0) {
+	if (register_framebuffer(info) < 0) {
 		printk(KERN_ERR "tcx: Could not register framebuffer.\n");
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		fb_dealloc_cmap(&info->cmap);
+		kfree(info);
 		return;
 	}
 
-	list_add(&all->list, &tcx_list);
+	list_add(&par->list, &tcx_list);
 
 	printk("tcx: %s at %lx:%lx, %s\n",
 	       sdev->prom_name,
 	       (long) sdev->reg_addrs[0].which_io,
 	       (long) sdev->reg_addrs[0].phys_addr,
-	       all->par.lowdepth ? "8-bit only" : "24-bit depth");
+	       par->lowdepth ? "8-bit only" : "24-bit depth");
 }
 
 int __init tcx_init(void)
@@ -442,11 +438,12 @@
 	struct list_head *pos, *tmp;
 
 	list_for_each_safe(pos, tmp, &tcx_list) {
-		struct all_info *all = list_entry(pos, typeof(*all), list);
+		struct tcx_par *par = list_entry(pos, typeof(*par), list);
+
+		unregister_framebuffer(par->info);
+		fb_dealloc_cmap(&par->info->cmap);
 
-		unregister_framebuffer(&all->info);
-		fb_dealloc_cmap(&all->info.cmap);
-		kfree(all);
+		framebuffer_release(par->info);
 	}
 }
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/tdfxfb.c fbdev-2.6/drivers/video/tdfxfb.c
--- linus-2.6/drivers/video/tdfxfb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/tdfxfb.c	Thu Oct 16 14:13:32 2003
@@ -508,8 +508,10 @@
 		return -EINVAL;
 	}
 
-	/* fixme: does Voodoo3 support interlace? Banshee doesn't */
-	if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+	/* Banshee doesn't support interlace, but Voodoo4/5 and probably Voodoo3 do. */
+	/* no direct information about device id now? use max_pixclock for this... */
+	if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) &&
+			(par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
 		DPRINTK("interlace not supported\n");
 		return -EINVAL;
 	}
@@ -616,10 +618,17 @@
 	hbs = hd;
 	hbe = ht;
 
-	vbs = vd = info->var.yres - 1;
-	vs  = vd + info->var.lower_margin;
-	ve  = vs + info->var.vsync_len;
-	vbe = vt = ve + info->var.upper_margin - 1;
+	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		vbs = vd = (info->var.yres << 1) - 1;
+		vs  = vd + (info->var.lower_margin << 1);
+		ve  = vs + (info->var.vsync_len << 1);
+		vbe = vt = ve + (info->var.upper_margin << 1) - 1;
+	} else {
+		vbs = vd = info->var.yres - 1;
+		vs  = vd + info->var.lower_margin;
+		ve  = vs + info->var.vsync_len;
+		vbe = vt = ve + info->var.upper_margin - 1;
+	}
   
 	/* this is all pretty standard VGA register stuffing */
 	reg.misc[0x00] = 0x0f | 
@@ -742,8 +751,16 @@
 	reg.gfxpll = do_calc_pll(..., &fout);
 #endif
 
-	reg.screensize = info->var.xres | (info->var.yres << 12);
-	reg.vidcfg &= ~VIDCFG_HALF_MODE;
+	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+		reg.screensize = info->var.xres | (info->var.yres << 13);
+		reg.vidcfg |= VIDCFG_HALF_MODE;
+		reg.crt[0x09] |= 0x80;
+	} else {
+		reg.screensize = info->var.xres | (info->var.yres << 12);
+		reg.vidcfg &= ~VIDCFG_HALF_MODE;
+	}
+	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+		reg.vidcfg |= VIDCFG_INTERLACE;
 	reg.miscinit0 = tdfx_inl(par, MISCINIT0);
 
 #if defined(__BIG_ENDIAN)
@@ -890,7 +907,11 @@
 
 	banshee_make_room(par, 5);
 	tdfx_outl(par,	DSTFORMAT, fmt);
-	tdfx_outl(par,	COLORFORE, rect->color);
+	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
+		tdfx_outl(par,	COLORFORE, rect->color);
+	} else { /* FB_VISUAL_TRUECOLOR */
+		tdfx_outl(par, COLORFORE, ((u32*)(info->pseudo_palette))[rect->color]);
+	}
 	tdfx_outl(par,	COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
 	tdfx_outl(par,	DSTSIZE,    rect->width | (rect->height << 16));
 	tdfx_outl(par,	LAUNCH_2D,  rect->dx | (rect->dy << 16));
@@ -1159,15 +1180,14 @@
 		return err;
 	}
 
-	size = sizeof(struct fb_info)+sizeof(struct tdfx_par)+16*sizeof(u32);
+	size = sizeof(struct tdfx_par)+16*sizeof(u32);
 
-	info = kmalloc(size, GFP_KERNEL);
+	info = framebuffer_alloc(size, &pdev->dev);
 
 	if (!info)	return -ENOMEM;
 		
-	memset(info, 0, size);
     
-	default_par = (struct tdfx_par *) (info + 1);
+	default_par = info->par;
  
 	/* Configure the default fb_fix_screeninfo first */
 	switch (pdev->device) {
@@ -1245,7 +1265,6 @@
    
 	info->fbops		= &tdfxfb_ops;
 	info->fix		= tdfx_fix; 	
-	info->par		= default_par;
 	info->pseudo_palette	= (void *)(default_par + 1); 
 	info->flags		= FBINFO_FLAG_DEFAULT;
 
@@ -1309,7 +1328,7 @@
 	release_mem_region(pci_resource_start(pdev, 0),
 			   pci_resource_len(pdev, 0));
 	pci_set_drvdata(pdev, NULL);
-	kfree(info);
+	framebuffer_release(info);
 }
 
 int __init tdfxfb_init(void)
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/tgafb.c fbdev-2.6/drivers/video/tgafb.c
--- linus-2.6/drivers/video/tgafb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/tgafb.c	Thu Oct 16 14:13:32 2003
@@ -225,30 +225,6 @@
 		BT485_WRITE(par, 0x20, BT485_CMD_2); /* cursor off, for now */
 		BT485_WRITE(par, 0xff, BT485_PIXEL_MASK);
 
-		/* Fill palette registers.  */
-		BT485_WRITE(par, 0x00, BT485_ADDR_PAL_WRITE);
-		TGA_WRITE_REG(par, BT485_DATA_PAL, TGA_RAMDAC_SETUP_REG);
-
-		for (i = 0; i < 16; i++) {
-			j = color_table[i];
-			TGA_WRITE_REG(par, default_red[j]|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, default_grn[j]|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, default_blu[j]|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-		}
-		for (i = 0; i < 240*3; i += 4) {
-			TGA_WRITE_REG(par, 0x55|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT485_DATA_PAL<<8),
-				      TGA_RAMDAC_REG);
-		}
-
 	} else { /* 24-plane or 24plusZ */
 
 		/* Init BT463 registers.  */
@@ -267,30 +243,6 @@
 		BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_2, 0x00);
 		BT463_WRITE(par, BT463_REG_ACC, BT463_BLINK_MASK_3, 0x00);
 
-		/* Fill the palette.  */
-		BT463_LOAD_ADDR(par, 0x0000);
-		TGA_WRITE_REG(par, BT463_PALETTE<<2, TGA_RAMDAC_REG);
-
-		for (i = 0; i < 16; i++) {
-			j = color_table[i];
-			TGA_WRITE_REG(par, default_red[j]|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, default_grn[j]|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, default_blu[j]|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-		}
-		for (i = 0; i < 512*3; i += 4) {
-			TGA_WRITE_REG(par, 0x55|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-			TGA_WRITE_REG(par, 0x00|(BT463_PALETTE<<10),
-				      TGA_RAMDAC_REG);
-		}
-
 		/* Fill window type table after start of vertical retrace.  */
 		while (!(TGA_READ_REG(par, TGA_INTR_STAT_REG) & 0x01))
 			continue;
@@ -314,6 +266,9 @@
 
 	}
 
+	/* Init the palette. */
+	fb_set_cmap(fb_default_cmap(16), 1, info);
+
 	/* Finally, enable video scan (and pray for the monitor... :-) */
 	TGA_WRITE_REG(par, TGA_VALID_VIDEO, TGA_VALID_REG);
 
@@ -509,16 +464,8 @@
  *  Acceleration.
  */
 
-/**
- *      tgafb_imageblit - REQUIRED function. Can use generic routines if
- *                        non acclerated hardware and packed pixel based.
- *                        Copies a image from system memory to the screen. 
- *
- *      @info: frame buffer structure that represents a single frame buffer
- *      @image: structure defining the image.
- */
 static void
-tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
 {
 	static unsigned char const bitrev[256] = {
 		0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@@ -562,6 +509,17 @@
 	const unsigned char *data;
 	void *regs_base, *fb_base;
 
+	is8bpp = info->var.bits_per_pixel == 8;
+
+	/* For copies that aren't pixel expansion, there's little we
+	   can do better than the generic code.  */
+	/* ??? There is a DMA write mode; I wonder if that could be
+	   made to pull the data from the image buffer...  */
+	if (image->depth > 1) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
 	dx = image->dx;
 	dy = image->dy;
 	width = image->width;
@@ -579,18 +537,8 @@
 	if (dy + height > vyres)
 		height = vyres - dy;
 
-	/* For copies that aren't pixel expansion, there's little we
-	   can do better than the generic code.  */
-	/* ??? There is a DMA write mode; I wonder if that could be
-	   made to pull the data from the image buffer...  */
-	if (image->depth > 1) {
-		cfb_imageblit(info, image);
-		return;
-	}
-
 	regs_base = par->tga_regs_base;
 	fb_base = par->tga_fb_base;
-	is8bpp = info->var.bits_per_pixel == 8;
 
 	/* Expand the color values to fill 32-bits.  */
 	/* ??? Would be nice to notice colour changes elsewhere, so
@@ -768,6 +716,86 @@
 		     regs_base + TGA_MODE_REG);
 }
 
+static void
+tgafb_clut_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	struct tga_par *par = (struct tga_par *) info->par;
+	u32 color, dx, dy, width, height, vxres, vyres;
+	u32 *palette = ((u32 *)info->pseudo_palette);
+	unsigned long pos, line_length;
+	unsigned long i, j;
+	const unsigned char *data;
+	void *regs_base, *fb_base;
+
+	dx = image->dx;
+	dy = image->dy;
+	width = image->width;
+	height = image->height;
+	vxres = info->var.xres_virtual;
+	vyres = info->var.yres_virtual;
+	line_length = info->fix.line_length;
+
+	/* Crop the image to the screen.  */
+	if (dx > vxres || dy > vyres)
+		return;
+	if (dx + width > vxres)
+		width = vxres - dx;
+	if (dy + height > vyres)
+		height = vyres - dy;
+
+	regs_base = par->tga_regs_base;
+	fb_base = par->tga_fb_base;
+
+	pos = dy * line_length + (dx * 4);
+	data = image->data;
+
+	/* Now copy the image, color_expanding via the palette. */
+	for (i = 0; i < height; i++) {
+		for (j = 0; j < width; j++) {
+			color = palette[*data++];
+			__raw_writel(color, fb_base + pos + j*4);
+		}
+		pos += line_length;
+	}
+}
+
+/**
+ *      tgafb_imageblit - REQUIRED function. Can use generic routines if
+ *                        non acclerated hardware and packed pixel based.
+ *                        Copies a image from system memory to the screen.
+ *
+ *      @info: frame buffer structure that represents a single frame buffer
+ *      @image: structure defining the image.
+ */
+static void
+tgafb_imageblit(struct fb_info *info, const struct fb_image *image)
+{
+	unsigned int is8bpp = info->var.bits_per_pixel == 8;
+
+	/* If a mono image, regardless of FB depth, go do it. */
+	if (image->depth == 1) {
+		tgafb_mono_imageblit(info, image);
+		return;
+	}
+
+	/* For copies that aren't pixel expansion, there's little we
+	   can do better than the generic code.  */
+	/* ??? There is a DMA write mode; I wonder if that could be
+	   made to pull the data from the image buffer...  */
+	if (image->depth == info->var.bits_per_pixel) {
+		cfb_imageblit(info, image);
+		return;
+	}
+
+	/* If 24-plane FB and the image is 8-plane with CLUT, we can do it. */
+	if (!is8bpp && image->depth == 8) {
+		tgafb_clut_imageblit(info, image);
+		return;
+	}
+
+	/* Silently return... */
+}
+
 /**
  *      tgafb_fillrect - REQUIRED function. Can use generic routines if 
  *                       non acclerated hardware and packed pixel based.
@@ -1360,6 +1388,19 @@
 	info->fix.ywrapstep = 0;
 
 	info->fix.accel = FB_ACCEL_DEC_TGA;
+
+	/*
+	 * These are needed by fb_set_logo_truepalette(), so we
+	 * set them here for 24-plane cards.
+	 */
+	if (tga_type != TGA_TYPE_8PLANE) {
+		info->var.red.length = 8;
+		info->var.green.length = 8;
+		info->var.blue.length = 8;
+		info->var.red.offset = 16;
+		info->var.green.offset = 8;
+		info->var.blue.offset = 0;
+	}
 }
 
 static __devinit int
@@ -1427,9 +1468,9 @@
 	all->info.flags = FBINFO_FLAG_DEFAULT;
 	all->info.fbops = &tgafb_ops;
 	all->info.screen_base = (char *) all->par.tga_fb_base;
-	all->info.currcon = -1;
 	all->info.par = &all->par;
 	all->info.pseudo_palette = all->pseudo_palette;
+	all->info.dev = &pdev->dev;
 
 	/* This should give a reasonable default video mode.  */
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/tridentfb.c fbdev-2.6/drivers/video/tridentfb.c
--- linus-2.6/drivers/video/tridentfb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/tridentfb.c	Thu Oct 16 14:13:32 2003
@@ -1156,6 +1156,7 @@
 		default_var.accel_flags &= ~FB_ACCELF_TEXT;
 	default_var.activate |= FB_ACTIVATE_NOW;
 	fb_info.var = default_var;
+	fb_info.class_dev.dev = &dev->dev;
 	if (register_framebuffer(&fb_info) < 0) {
 		output("Could not register Trident framebuffer\n");
 		return -EINVAL;
diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/valkyriefb.c fbdev-2.6/drivers/video/valkyriefb.c
--- linus-2.6/drivers/video/valkyriefb.c	Thu Oct 16 14:13:32 2003
+++ fbdev-2.6/drivers/video/valkyriefb.c	Thu Oct 16 14:13:32 2003
@@ -51,7 +51,6 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/fb.h>
-#include <linux/selection.h>
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/nvram.h>
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h fbdev-2.6/include/linux/fb.h
--- linus-2.6/include/linux/fb.h	Thu Oct 16 14:15:57 2003
+++ fbdev-2.6/include/linux/fb.h	Thu Oct 16 14:15:57 2003
@@ -1,10 +1,7 @@
 #ifndef _LINUX_FB_H
 #define _LINUX_FB_H
 
-#include <linux/tty.h>
-#include <linux/workqueue.h>
 #include <asm/types.h>
-#include <asm/io.h>
 
 /* Definitions of frame buffers						*/
 
@@ -326,32 +323,46 @@
 	struct fb_image	image;	/* Cursor image */
 };
 
-#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
-#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
-#define FB_PIXMAP_IO      4     /* memory is iomapped       */
-#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
-
-struct fb_pixmap {
-        __u8  *addr;                      /* pointer to memory             */  
-	__u32 size;                       /* size of buffer in bytes       */
-	__u32 offset;                     /* current offset to buffer      */
-	__u32 buf_align;                  /* byte alignment of each bitmap */
-	__u32 scan_align;                 /* alignment per scanline        */
-	__u32 flags;                      /* see FB_PIXMAP_*               */
-					  /* access methods                */
-	void (*outbuf)(u8 *dst, u8 *addr, unsigned int size); 
-	u8   (*inbuf) (u8 *addr);
-	spinlock_t lock;                  /* spinlock                      */
-	atomic_t count;
-};
 #ifdef __KERNEL__
 
 #include <linux/fs.h>
 #include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
 
 struct fb_info;
 struct vm_area_struct;
 struct file;
+struct device;
+
+/*
+ * The purpose of this structure is to translate data
+ * from the hardwre independent format of fbdev to what
+ * format the hardware needs.
+ */
+
+#define FB_PIXMAP_DEFAULT 1     /* used internally by fbcon */
+#define FB_PIXMAP_SYSTEM  2     /* memory is in system RAM  */
+#define FB_PIXMAP_IO      4     /* memory is iomapped       */
+#define FB_PIXMAP_SYNC    256   /* set if GPU can DMA       */
+
+struct fb_pixmap {
+	u8  *addr;		/* pointer to memory 			*/
+	u32 size;		/* size of buffer in bytes 		*/
+	u32 offset;		/* current offset to buffer 		*/
+	u32 buf_align;		/* byte alignment of each bitmap 	*/
+	u32 scan_align;		/* alignment per scanline 		*/
+	u32 access_align;	/* alignment per read/write		*/
+	u32 flags;		/* see FB_PIXMAP_* 			*/
+	spinlock_t lock;	/* spinlock 				*/
+	atomic_t count;
+	/* access methods */
+	void (*outbuf)(struct fb_info *info, u8 *addr, u8 *src, unsigned int size);
+	u8   (*inbuf) (u8 *addr);
+};
 
     /*
      *  Frame buffer operations
@@ -396,24 +407,26 @@
 };
 
 struct fb_info {
-   int node;
-   int flags;
-   int open;                            /* Has this been open already ? */
+	int node;
+	int flags;
 #define FBINFO_FLAG_MODULE	1	/* Low-level driver is a module */
-   struct fb_var_screeninfo var;        /* Current var */
-   struct fb_fix_screeninfo fix;        /* Current fix */
-   struct fb_monspecs monspecs;         /* Current Monitor specs */
-   struct fb_cursor cursor;		/* Current cursor */	
-   struct work_struct queue;		/* Framebuffer event queue */
-   struct fb_pixmap pixmap;	        /* Current pixmap */
-   struct fb_cmap cmap;                 /* Current cmap */
-   struct fb_ops *fbops;
-   char *screen_base;                   /* Virtual address */
-   struct vc_data *display_fg;		/* Console visible on this display */
-   int currcon;				/* Current VC. */	
-   void *pseudo_palette;                /* Fake palette of 16 colors */ 
-   /* From here on everything is device dependent */
-   void *par;	
+	struct fb_var_screeninfo var;	/* Current var */
+	struct fb_fix_screeninfo fix;	/* Current fix */
+	struct fb_monspecs monspecs;	/* Current Monitor specs */
+	struct fb_cursor cursor;	/* Current cursor */
+	struct work_struct queue;	/* Framebuffer event queue */
+	struct fb_pixmap pixmap;	/* Image HW mapper */
+	struct fb_pixmap sprite;	/* Cursor HW mapper */
+	struct fb_cmap cmap;		/* Current cmap */
+	struct fb_ops *fbops;
+	char *screen_base;		/* Virtual address */
+	struct vc_data *display_fg;	/* Console visible on this display */
+	void *pseudo_palette;		/* Fake palette of 16 colors */
+	int currcon;			/* Current VC. */
+	struct class_device class_dev;
+
+	/* From here on everything is device dependent */
+	void *par;
 };
 
 #ifdef MODULE
@@ -478,15 +491,19 @@
 
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
+extern struct fb_info *framebuffer_alloc(size_t size, struct device *dev);
 extern int unregister_framebuffer(struct fb_info *fb_info);
+extern void framebuffer_release(struct fb_info *fb_info);
 extern int fb_prepare_logo(struct fb_info *fb_info);
 extern int fb_show_logo(struct fb_info *fb_info);
-extern u32 fb_get_buffer_offset(struct fb_info *info, u32 size);
-extern void move_buf_unaligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
-			     	u32 height, u32 mask, u32 shift_high, u32 shift_low,
-				u32 mod, u32 idx);
-extern void move_buf_aligned(struct fb_info *info, u8 *dst, u8 *src, u32 d_pitch,
-			     u32 s_pitch, u32 height);
+extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
+extern void move_buf_unaligned(struct fb_info *info, struct fb_pixmap *buf,
+				u8 *dst, u32 d_pitch, u8 *src, u32 idx,
+				u32 height, u32 shift_high, u32 shift_low, u32 mod);
+extern void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+				u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+				u32 height);
+extern void load_cursor_image(struct fb_info *);
 extern struct fb_info *registered_fb[FB_MAX];
 extern int num_registered_fb;
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/fb.h.diff fbdev-2.6/include/linux/fb.h.diff
--- linus-2.6/include/linux/fb.h.diff	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/include/linux/fb.h.diff	Wed Oct 15 19:44:02 2003
@@ -0,0 +1,45 @@
+--- fb.h	Mon Sep 15 14:51:14 2003
++++ fb.h.new	Mon Sep 15 14:49:19 2003
+@@ -359,10 +354,30 @@
++struct vm_area_struct;
++struct fb_client;
++struct fb_info;
++struct device;
++struct file;
++
++struct fb_client_ops {
++	struct module *owner;
++	void 	(*state_manager)(struct fb_info *info, void *data, u32 state);
++};
++
++struct fb_client {
++	struct list_head	link;
++	struct fb_client_ops	*ops;
++	void 			*data;
++};
++
++extern int register_fb_client(struct fb_client_ops *ops, void *data);
++extern int unregister_fb_client(struct fb_client_ops *ops);
++
+     /*
+      *  Frame buffer operations
+      */
+@@ -422,7 +437,8 @@
+ 	struct vc_data *display_fg;	/* Console visible on this display */
+ 	void *pseudo_palette;		/* Fake palette of 16 colors */
+ 	struct device *dev;		/* Pointer to the device for this fb */
+	int currcon;			/* Current VC. */
++	u32 state;			/* Hardware states i.e suspend */
+ 	/* From here on everything is device dependent */
+ 	void *par;
+ };
+@@ -499,8 +515,8 @@
+ extern void move_buf_aligned(struct fb_info *info, struct fb_pixmap *buf,
+ 				u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch,
+ 				u32 height);
+ extern void load_cursor_image(struct fb_info *);
+ extern struct fb_info *registered_fb[FB_MAX];
++extern const struct fb_ops dummy_fbdev;
+ extern int num_registered_fb;
+
+ /* drivers/video/fbmon.c */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/linux_logo.h fbdev-2.6/include/linux/linux_logo.h
--- linus-2.6/include/linux/linux_logo.h	Thu Oct 16 14:16:01 2003
+++ fbdev-2.6/include/linux/linux_logo.h	Thu Oct 16 14:16:01 2003
@@ -16,13 +16,11 @@
 
 #include <linux/init.h>
 
-
 #define LINUX_LOGO_MONO		1	/* monochrome black/white */
 #define LINUX_LOGO_VGA16	2	/* 16 colors VGA text palette */
 #define LINUX_LOGO_CLUT224	3	/* 224 colors */
 #define LINUX_LOGO_GRAY256	4	/* 256 levels grayscale */
 
-
 struct linux_logo {
 	int type;			/* one of LINUX_LOGO_* */
 	unsigned int width;
@@ -32,6 +30,6 @@
 	const unsigned char *data;
 };
 
-extern const struct linux_logo *fb_find_logo(int depth);
+extern const struct linux_logo *find_logo(int depth);
 
 #endif /* _LINUX_LINUX_LOGO_H */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/linux/pci_ids.h fbdev-2.6/include/linux/pci_ids.h
--- linus-2.6/include/linux/pci_ids.h	Thu Oct 16 14:16:03 2003
+++ fbdev-2.6/include/linux/pci_ids.h	Thu Oct 16 14:16:02 2003
@@ -216,28 +216,37 @@
 /* Rage128 GL */
 #define PCI_DEVICE_ID_ATI_RAGE128_RE	0x5245
 #define PCI_DEVICE_ID_ATI_RAGE128_RF	0x5246
-#define PCI_DEVICE_ID_ATI_RAGE128_RG	0x534b
-#define PCI_DEVICE_ID_ATI_RAGE128_RH	0x534c
-#define PCI_DEVICE_ID_ATI_RAGE128_RI	0x534d
+#define PCI_DEVICE_ID_ATI_RAGE128_RG	0x5247
 /* Rage128 VR */
 #define PCI_DEVICE_ID_ATI_RAGE128_RK	0x524b
 #define PCI_DEVICE_ID_ATI_RAGE128_RL	0x524c
-#define PCI_DEVICE_ID_ATI_RAGE128_RM	0x5345
-#define PCI_DEVICE_ID_ATI_RAGE128_RN	0x5346
-#define PCI_DEVICE_ID_ATI_RAGE128_RO	0x5347
+#define PCI_DEVICE_ID_ATI_RAGE128_SE	0x5345
+#define PCI_DEVICE_ID_ATI_RAGE128_SF	0x5346
+#define PCI_DEVICE_ID_ATI_RAGE128_SG	0x5347
+#define PCI_DEVICE_ID_ATI_RAGE128_SH	0x5348
+#define PCI_DEVICE_ID_ATI_RAGE128_SK	0x534b
+#define PCI_DEVICE_ID_ATI_RAGE128_SL	0x534c
+#define PCI_DEVICE_ID_ATI_RAGE128_SM	0x534d
+#define PCI_DEVICE_ID_ATI_RAGE128_SN	0x534e
+/* Rage128 Ultra */
+#define PCI_DEVICE_ID_ATI_RAGE128_TF	0x5446
+#define PCI_DEVICE_ID_ATI_RAGE128_TL	0x544c
+#define PCI_DEVICE_ID_ATI_RAGE128_TR	0x5452
+#define PCI_DEVICE_ID_ATI_RAGE128_TS	0x5453
+#define PCI_DEVICE_ID_ATI_RAGE128_TT	0x5454
+#define PCI_DEVICE_ID_ATI_RAGE128_TU	0x5455
 /* Rage128 M3 */
 #define PCI_DEVICE_ID_ATI_RAGE128_LE	0x4c45
 #define PCI_DEVICE_ID_ATI_RAGE128_LF	0x4c46
-/* Rage128 Pro Ultra */
-#define PCI_DEVICE_ID_ATI_RAGE128_U1	0x5446
-#define PCI_DEVICE_ID_ATI_RAGE128_U2	0x544C
-#define PCI_DEVICE_ID_ATI_RAGE128_U3	0x5452
+/* Rage128 M4 */
+#define PCI_DEVICE_ID_ATI_RAGE128_MF    0x4d46
+#define PCI_DEVICE_ID_ATI_RAGE128_ML    0x4d4c
 /* Rage128 Pro GL */
-#define PCI_DEVICE_ID_ATI_Rage128_PA	0x5041
-#define PCI_DEVICE_ID_ATI_Rage128_PB	0x5042
-#define PCI_DEVICE_ID_ATI_Rage128_PC	0x5043
-#define PCI_DEVICE_ID_ATI_Rage128_PD	0x5044
-#define PCI_DEVICE_ID_ATI_Rage128_PE	0x5045
+#define PCI_DEVICE_ID_ATI_RAGE128_PA	0x5041
+#define PCI_DEVICE_ID_ATI_RAGE128_PB	0x5042
+#define PCI_DEVICE_ID_ATI_RAGE128_PC	0x5043
+#define PCI_DEVICE_ID_ATI_RAGE128_PD	0x5044
+#define PCI_DEVICE_ID_ATI_RAGE128_PE	0x5045
 #define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
 /* Rage128 Pro VR */
 #define PCI_DEVICE_ID_ATI_RAGE128_PG	0x5047
@@ -259,17 +268,23 @@
 #define PCI_DEVICE_ID_ATI_RAGE128_PV	0x5056
 #define PCI_DEVICE_ID_ATI_RAGE128_PW	0x5057
 #define PCI_DEVICE_ID_ATI_RAGE128_PX	0x5058
-/* Rage128 M4 */
-#define PCI_DEVICE_ID_ATI_RADEON_LE	0x4d45
-#define PCI_DEVICE_ID_ATI_RADEON_LF	0x4d46
 /* Radeon R100 */
 #define PCI_DEVICE_ID_ATI_RADEON_QD	0x5144
 #define PCI_DEVICE_ID_ATI_RADEON_QE	0x5145
 #define PCI_DEVICE_ID_ATI_RADEON_QF	0x5146
 #define PCI_DEVICE_ID_ATI_RADEON_QG	0x5147
+#define PCI_DEVICE_ID_ATI_RADEON_QH	0x5148
+#define PCI_DEVICE_ID_ATI_RADEON_QI	0x5149
+#define PCI_DEVICE_ID_ATI_RADEON_QJ	0x514a
+#define PCI_DEVICE_ID_ATI_RADEON_QK	0x514b
 /* Radeon RV100 (VE) */
 #define PCI_DEVICE_ID_ATI_RADEON_QY	0x5159
 #define PCI_DEVICE_ID_ATI_RADEON_QZ	0x515a
+#define PCI_DEVICE_ID_ATI_RADEON_Qh	0x5168
+#define PCI_DEVICE_ID_ATI_RADEON_Qi	0x5169
+#define PCI_DEVICE_ID_ATI_RADEON_Qj	0x516a
+#define PCI_DEVICE_ID_ATI_RADEON_Qk	0x516b
+#define PCI_DEVICE_ID_ATI_RADEON_Ql	0x516c
 /* Radeon R200 (8500) */
 #define PCI_DEVICE_ID_ATI_RADEON_QL	0x514c
 #define PCI_DEVICE_ID_ATI_RADEON_QN	0x514e
@@ -289,6 +304,7 @@
 #define PCI_DEVICE_ID_ATI_RADEON_Ie	0x4965
 #define PCI_DEVICE_ID_ATI_RADEON_If	0x4966
 #define PCI_DEVICE_ID_ATI_RADEON_Ig	0x4967
+#define PCI_DEVICE_ID_ATI_RADEON_In	0x496e
 /* Radeon RV280 (9200) */
 #define PCI_DEVICE_ID_ATI_RADEON_Y_	0x5960
 /* Radeon R300 (9500) */
@@ -298,11 +314,36 @@
 #define PCI_DEVICE_ID_ATI_RADEON_NE	0x4e45
 #define PCI_DEVICE_ID_ATI_RADEON_NF	0x4e46
 #define PCI_DEVICE_ID_ATI_RADEON_NG	0x4e47
+#define PCI_DEVICE_ID_ATI_RADEON_Nd	0x4e64
+#define PCI_DEVICE_ID_ATI_RADEON_Ne	0x4e65
+#define PCI_DEVICE_ID_ATI_RADEON_Nf	0x4e66
+#define PCI_DEVICE_ID_ATI_RADEON_Ng	0x4e67
+#define PCI_DEVICE_ID_ATI_RADEON_A6	0x4136
+#define PCI_DEVICE_ID_ATI_RADEON_A7	0x4137
+#define PCI_DEVICE_ID_ATI_RADEON_AD	0x4144
 #define PCI_DEVICE_ID_ATI_RADEON_AE	0x4145
 #define PCI_DEVICE_ID_ATI_RADEON_AF	0x4146
+#define PCI_DEVICE_ID_ATI_RADEON_AG	0x4147
+#define PCI_DEVICE_ID_ATI_RADEON_Ad	0x4164
+#define PCI_DEVICE_ID_ATI_RADEON_B7	0x4237
+#define PCI_DEVICE_ID_ATI_RADEON_BB	0x4242
+#define PCI_DEVICE_ID_ATI_RADEON_C6	0x4336
+#define PCI_DEVICE_ID_ATI_RADEON_C7	0x4337
+#define PCI_DEVICE_ID_ATI_RADEON_D7	0x4337
+/* Radeon RS300 */
+#define PCI_DEVICE_ID_ATI_RADEON_X0	0x5830
+#define PCI_DEVICE_ID_ATI_RADEON_X1	0x5831
+#define PCI_DEVICE_ID_ATI_RADEON_X2	0x5832
+#define PCI_DEVICE_ID_ATI_RADEON_X3	0x5833
+#define PCI_DEVICE_ID_ATI_RADEON_X4	0x5834
+#define PCI_DEVICE_ID_ATI_RADEON_X5	0x5835
+#define PCI_DEVICE_ID_ATI_RADEON_X6	0x5836
+#define PCI_DEVICE_ID_ATI_RADEON_X7	0x5837
 /* Radeon R350 (9800) */
 #define PCI_DEVICE_ID_ATI_RADEON_NH	0x4e48
+#define PCI_DEVICE_ID_ATI_RADEON_Nh	0x4e68
 #define PCI_DEVICE_ID_ATI_RADEON_NI	0x4e49
+#define PCI_DEVICE_ID_ATI_RADEON_Ni	0x4e69
 /* Radeon RV350 (9600) */
 #define PCI_DEVICE_ID_ATI_RADEON_AP	0x4150
 #define PCI_DEVICE_ID_ATI_RADEON_AR	0x4152
@@ -317,6 +358,7 @@
 #define PCI_DEVICE_ID_ATI_RADEON_Le	0x4c65
 #define PCI_DEVICE_ID_ATI_RADEON_Lf	0x4c66
 #define PCI_DEVICE_ID_ATI_RADEON_Lg	0x4c67
+#define PCI_DEVICE_ID_ATI_RADEON_Ln	0x4c6e
 /* Radeon */
 #define PCI_DEVICE_ID_ATI_RADEON_RA	0x5144
 #define PCI_DEVICE_ID_ATI_RADEON_RB	0x5145
@@ -326,10 +368,6 @@
 #define PCI_DEVICE_ID_ATI_RS100		0xcab0
 #define PCI_DEVICE_ID_ATI_RS200		0xcab2
 #define PCI_DEVICE_ID_ATI_RS250		0xcab3
-#define PCI_DEVICE_ID_ATI_RS300_100	0x5830
-#define PCI_DEVICE_ID_ATI_RS300_133	0x5831
-#define PCI_DEVICE_ID_ATI_RS300_166	0x5832
-#define PCI_DEVICE_ID_ATI_RS300_200	0x5833
 
 #define PCI_VENDOR_ID_VLSI		0x1004
 #define PCI_DEVICE_ID_VLSI_82C592	0x0005
@@ -519,6 +557,7 @@
 #define PCI_DEVICE_ID_CT_65550		0x00e0
 #define PCI_DEVICE_ID_CT_65554		0x00e4
 #define PCI_DEVICE_ID_CT_65555		0x00e5
+#define PCI_DEVICE_ID_CT_69000		0x00c0
 
 #define PCI_VENDOR_ID_MIRO		0x1031
 #define PCI_DEVICE_ID_MIRO_36050	0x5601
@@ -1060,6 +1099,16 @@
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL	0x0258
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL	0x0259
 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL	0x025B
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800	0x0280
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4280	0x0281
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_SE 0x0282
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO	0x0286
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_U	0x0301
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800	0x0302
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_U	0x0311
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600	0x0312
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_U	0x0321
+#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200	0x0322
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_8849		0x8849
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/aty128.h fbdev-2.6/include/video/aty128.h
--- linus-2.6/include/video/aty128.h	Thu Oct 16 14:16:22 2003
+++ fbdev-2.6/include/video/aty128.h	Thu Oct 16 14:16:22 2003
@@ -415,5 +415,8 @@
 #define PWR_MGT_SLOWDOWN_MCLK			0x00002000
 
 #define PMI_PMSCR_REG				0x60
+
+/* used by ATI bug fix for hardware ROM */
+#define RAGE128_MPP_TB_CONFIG                   0x01c0
 
 #endif				/* REG_RAGE128_H */
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/cvisionppc.h fbdev-2.6/include/video/cvisionppc.h
--- linus-2.6/include/video/cvisionppc.h	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/include/video/cvisionppc.h	Thu Oct 16 14:16:22 2003
@@ -0,0 +1,51 @@
+/*
+ * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer
+ * driver.
+ *
+ * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT)
+ * --------------------------------------------------------------------------
+ * $Id: cvisionppc.h,v 1.8 1999/01/28 13:18:07 illo Exp $
+ * --------------------------------------------------------------------------
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef CVISIONPPC_H
+#define CVISIONPPC_H
+
+#ifndef PM2FB_H
+#include "pm2fb.h"
+#endif
+
+struct cvppc_par {
+	unsigned char* pci_config;
+	unsigned char* pci_bridge;
+	u32 user_flags;
+};
+
+#define CSPPC_PCI_BRIDGE		0xfffe0000
+#define CSPPC_BRIDGE_ENDIAN		0x0000
+#define CSPPC_BRIDGE_INT		0x0010
+
+#define	CVPPC_PCI_CONFIG		0xfffc0000
+#define CVPPC_ROM_ADDRESS		0xe2000001
+#define CVPPC_REGS_REGION		0xef000000
+#define CVPPC_FB_APERTURE_ONE		0xe0000000
+#define CVPPC_FB_APERTURE_TWO		0xe1000000
+#define CVPPC_FB_SIZE			0x00800000
+#define CVPPC_MEM_CONFIG_OLD		0xed61fcaa	/* FIXME Fujitsu?? */
+#define CVPPC_MEM_CONFIG_NEW		0xed41c532	/* FIXME USA?? */
+#define CVPPC_MEMCLOCK			83000		/* in KHz */
+
+/* CVPPC_BRIDGE_ENDIAN */
+#define CSPPCF_BRIDGE_BIG_ENDIAN	0x02
+
+/* CVPPC_BRIDGE_INT */
+#define CSPPCF_BRIDGE_ACTIVE_INT2	0x01
+
+#endif	/* CVISIONPPC_H */
+
+/*****************************************************************************
+ * That's all folks!
+ *****************************************************************************/
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/epson1355.h fbdev-2.6/include/video/epson1355.h
--- linus-2.6/include/video/epson1355.h	Wed Dec 31 16:00:00 1969
+++ fbdev-2.6/include/video/epson1355.h	Thu Oct 16 14:16:22 2003
@@ -0,0 +1,64 @@
+/*
+ * include/video/epson13xx.h -- Epson 13xx frame buffer
+ *
+ * Copyright (C) Hewlett-Packard Company.  All rights reserved.
+ *
+ * Written by Christopher Hoover <ch@hpl.hp.com>
+ *
+ */
+
+#ifndef _EPSON13XX_H_
+#define _EPSON13XX_H_
+
+#define REG_REVISION_CODE              0x00
+#define REG_MEMORY_CONFIG              0x01
+#define REG_PANEL_TYPE                 0x02
+#define REG_MOD_RATE                   0x03
+#define REG_HORZ_DISP_WIDTH            0x04
+#define REG_HORZ_NONDISP_PERIOD        0x05
+#define REG_HRTC_START_POSITION        0x06
+#define REG_HRTC_PULSE_WIDTH           0x07
+#define REG_VERT_DISP_HEIGHT0          0x08
+#define REG_VERT_DISP_HEIGHT1          0x09
+#define REG_VERT_NONDISP_PERIOD        0x0A
+#define REG_VRTC_START_POSITION        0x0B
+#define REG_VRTC_PULSE_WIDTH           0x0C
+#define REG_DISPLAY_MODE               0x0D
+#define REG_SCRN1_LINE_COMPARE0        0x0E
+#define REG_SCRN1_LINE_COMPARE1        0x0F
+#define REG_SCRN1_DISP_START_ADDR0     0x10
+#define REG_SCRN1_DISP_START_ADDR1     0x11
+#define REG_SCRN1_DISP_START_ADDR2     0x12
+#define REG_SCRN2_DISP_START_ADDR0     0x13
+#define REG_SCRN2_DISP_START_ADDR1     0x14
+#define REG_SCRN2_DISP_START_ADDR2     0x15
+#define REG_MEM_ADDR_OFFSET0           0x16
+#define REG_MEM_ADDR_OFFSET1           0x17
+#define REG_PIXEL_PANNING              0x18
+#define REG_CLOCK_CONFIG               0x19
+#define REG_POWER_SAVE_CONFIG          0x1A
+#define REG_MISC                       0x1B
+#define REG_MD_CONFIG_READBACK0        0x1C
+#define REG_MD_CONFIG_READBACK1        0x1D
+#define REG_GPIO_CONFIG0               0x1E
+#define REG_GPIO_CONFIG1               0x1F
+#define REG_GPIO_CONTROL0              0x20
+#define REG_GPIO_CONTROL1              0x21
+#define REG_PERF_ENHANCEMENT0          0x22
+#define REG_PERF_ENHANCEMENT1          0x23
+#define REG_LUT_ADDR                   0x24
+#define REG_RESERVED_1                 0x25
+#define REG_LUT_DATA                   0x26
+#define REG_INK_CURSOR_CONTROL         0x27
+#define REG_CURSOR_X_POSITION0         0x28
+#define REG_CURSOR_X_POSITION1         0x29
+#define REG_CURSOR_Y_POSITION0         0x2A
+#define REG_CURSOR_Y_POSITION1         0x2B
+#define REG_INK_CURSOR_COLOR0_0        0x2C
+#define REG_INK_CURSOR_COLOR0_1        0x2D
+#define REG_INK_CURSOR_COLOR1_0        0x2E
+#define REG_INK_CURSOR_COLOR1_1        0x2F
+#define REG_INK_CURSOR_START_ADDR      0x30
+#define REG_ALTERNATE_FRM              0x31
+
+#endif
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/neomagic.h fbdev-2.6/include/video/neomagic.h
--- linus-2.6/include/video/neomagic.h	Thu Oct 16 14:16:23 2003
+++ fbdev-2.6/include/video/neomagic.h	Thu Oct 16 14:16:23 2003
@@ -55,6 +55,20 @@
 #define NEO_MODE1_X_1600        0x1c00
 #define NEO_MODE1_BLT_ON_ADDR   0x2000
 
+/* These are offseted in MMIO space by par->CursorOff */
+#define NEOREG_CURSCNTL		0x00
+#define NEOREG_CURSX		0x04
+#define NEOREG_CURSY		0x08
+#define NEOREG_CURSBGCOLOR	0x0C
+#define NEOREG_CURSFGCOLOR	0x10
+#define NEOREG_CURSMEMPOS	0x14
+
+#define NEO_CURS_DISABLE	0x00000000
+#define NEO_CURS_ENABLE		0x00000001
+#define NEO_ICON64_ENABLE	0x00000008
+#define NEO_ICON128_ENABLE	0x0000000C
+#define NEO_ICON_BLANK		0x00000010
+
 #ifdef __KERNEL__
 
 #ifdef NEOFB_DEBUG
@@ -75,45 +89,45 @@
 
 
 struct xtimings {
-  unsigned int pixclock;
-  unsigned int HDisplay;
-  unsigned int HSyncStart;
-  unsigned int HSyncEnd;
-  unsigned int HTotal;
-  unsigned int VDisplay;
-  unsigned int VSyncStart;
-  unsigned int VSyncEnd;
-  unsigned int VTotal;
-  unsigned int sync;
-  int	       dblscan;
-  int	       interlaced;
+	unsigned int pixclock;
+	unsigned int HDisplay;
+	unsigned int HSyncStart;
+	unsigned int HSyncEnd;
+	unsigned int HTotal;
+	unsigned int VDisplay;
+	unsigned int VSyncStart;
+	unsigned int VSyncEnd;
+	unsigned int VTotal;
+	unsigned int sync;
+	int dblscan;
+	int interlaced;
 };
 
 
 /* --------------------------------------------------------------------- */
 
 typedef volatile struct {
-  __u32 bltStat;
-  __u32 bltCntl;
-  __u32 xpColor;
-  __u32 fgColor;
-  __u32 bgColor;
-  __u32 pitch;
-  __u32 clipLT;
-  __u32 clipRB;
-  __u32 srcBitOffset;
-  __u32 srcStart;
-  __u32 reserved0;
-  __u32 dstStart;
-  __u32 xyExt;
-
-  __u32 reserved1[19];
-
-  __u32 pageCntl;
-  __u32 pageBase;
-  __u32 postBase;
-  __u32 postPtr;
-  __u32 dataPtr;
+	__u32 bltStat;
+	__u32 bltCntl;
+	__u32 xpColor;
+	__u32 fgColor;
+	__u32 bgColor;
+	__u32 pitch;
+	__u32 clipLT;
+	__u32 clipRB;
+	__u32 srcBitOffset;
+	__u32 srcStart;
+	__u32 reserved0;
+	__u32 dstStart;
+	__u32 xyExt;
+
+	__u32 reserved1[19];
+
+	__u32 pageCntl;
+	__u32 pageBase;
+	__u32 postBase;
+	__u32 postPtr;
+	__u32 dataPtr;
 } Neo2200;
 
 #define NR_PALETTE	256
@@ -124,142 +138,69 @@
 #define NEO_EXT_GR_MAX 0xC7
 
 struct neofb_par {
-  
-  unsigned char MiscOutReg;     /* Misc */
-  unsigned char CRTC[25];       /* Crtc Controller */
-  unsigned char Sequencer[5];   /* Video Sequencer */
-  unsigned char Graphics[9];    /* Video Graphics */
-  unsigned char Attribute[21];  /* Video Atribute */
-
-  unsigned char GeneralLockReg;
-  unsigned char ExtCRTDispAddr;
-  unsigned char ExtCRTOffset;
-  unsigned char SysIfaceCntl1;
-  unsigned char SysIfaceCntl2;
-  unsigned char ExtColorModeSelect;
-  unsigned char biosMode;
-
-  unsigned char PanelDispCntlReg1;
-  unsigned char PanelDispCntlReg2;
-  unsigned char PanelDispCntlReg3;
-  unsigned char PanelVertCenterReg1;
-  unsigned char PanelVertCenterReg2;
-  unsigned char PanelVertCenterReg3;
-  unsigned char PanelVertCenterReg4;
-  unsigned char PanelVertCenterReg5;
-  unsigned char PanelHorizCenterReg1;
-  unsigned char PanelHorizCenterReg2;
-  unsigned char PanelHorizCenterReg3;
-  unsigned char PanelHorizCenterReg4;
-  unsigned char PanelHorizCenterReg5;
-
-  int           ProgramVCLK;
-  unsigned char VCLK3NumeratorLow;
-  unsigned char VCLK3NumeratorHigh;
-  unsigned char VCLK3Denominator;
-  unsigned char VerticalExt;
+	struct vgastate state;
+	atomic_t ref_count;
+
+	unsigned char MiscOutReg;	/* Misc */
+	unsigned char CRTC[25];		/* Crtc Controller */
+	unsigned char Sequencer[5];	/* Video Sequencer */
+	unsigned char Graphics[9];	/* Video Graphics */
+	unsigned char Attribute[21];	/* Video Atribute */
+
+	unsigned char GeneralLockReg;
+	unsigned char ExtCRTDispAddr;
+	unsigned char ExtCRTOffset;
+	unsigned char SysIfaceCntl1;
+	unsigned char SysIfaceCntl2;
+	unsigned char ExtColorModeSelect;
+	unsigned char biosMode;
+
+	unsigned char PanelDispCntlReg1;
+	unsigned char PanelDispCntlReg2;
+	unsigned char PanelDispCntlReg3;
+	unsigned char PanelVertCenterReg1;
+	unsigned char PanelVertCenterReg2;
+	unsigned char PanelVertCenterReg3;
+	unsigned char PanelVertCenterReg4;
+	unsigned char PanelVertCenterReg5;
+	unsigned char PanelHorizCenterReg1;
+	unsigned char PanelHorizCenterReg2;
+	unsigned char PanelHorizCenterReg3;
+	unsigned char PanelHorizCenterReg4;
+	unsigned char PanelHorizCenterReg5;
+
+	int ProgramVCLK;
+	unsigned char VCLK3NumeratorLow;
+	unsigned char VCLK3NumeratorHigh;
+	unsigned char VCLK3Denominator;
+	unsigned char VerticalExt;
 
 #ifdef CONFIG_MTRR
-  int    mtrr;
+	int mtrr;
 #endif
-  u8    *mmio_vbase;
-
-  Neo2200 *neo2200;
-
-  /* Panels size */
-  int NeoPanelWidth;
-  int NeoPanelHeight;
-
-  int maxClock;
-
-  int pci_burst;
-  int lcd_stretch;
-  int internal_display;
-  int external_display;
-  int libretto;
+	u8 *mmio_vbase;
+	u8 cursorOff;
+	u8 *cursorPad;		/* Must die !! */
+
+	Neo2200 *neo2200;
+
+	/* Panels size */
+	int NeoPanelWidth;
+	int NeoPanelHeight;
+
+	int maxClock;
+
+	int pci_burst;
+	int lcd_stretch;
+	int internal_display;
+	int external_display;
+	int libretto;
 };
 
 typedef struct {
-    int x_res;
-    int y_res;
-    int mode;
+	int x_res;
+	int y_res;
+	int mode;
 } biosMode;
 
-/* vga IO functions */
-static inline u8 VGArCR (u8 index)
-{
-  outb (index, 0x3d4);
-  return inb (0x3d5);
-}
-
-static inline void VGAwCR (u8 index, u8 val)
-{
-  outb (index, 0x3d4);
-  outb (val, 0x3d5);
-}
-
-static inline u8 VGArGR (u8 index)
-{
-  outb (index, 0x3ce);
-  return inb (0x3cf);
-}
-
-static inline void VGAwGR (u8 index, u8 val)
-{
-  outb (index, 0x3ce);
-  outb (val, 0x3cf);
-}
-
-static inline u8 VGArSEQ (u8 index)
-{
-  outb (index, 0x3c4);
-  return inb (0x3c5);
-}
-
-static inline void VGAwSEQ (u8 index, u8 val)
-{
-  outb (index, 0x3c4);
-  outb (val, 0x3c5);
-}
-
-
-static int paletteEnabled = 0;
-
-static inline void VGAenablePalette (void)
-{
-  u8 tmp;
-
-  tmp = inb (0x3da);
-  outb (0x00, 0x3c0);
-  paletteEnabled = 1;
-}
-
-static inline void VGAdisablePalette (void)
-{
-  u8 tmp;
-
-  tmp = inb (0x3da);
-  outb (0x20, 0x3c0);
-  paletteEnabled = 0;
-}
-
-static inline void VGAwATTR (u8 index, u8 value)
-{
-  u8 tmp;
-
-  if (paletteEnabled)
-    index &= ~0x20;
-  else
-    index |= 0x20;
-
-  tmp = inb (0x3da);
-  outb (index, 0x3c0);
-  outb (value, 0x3c0);
-}
-
-static inline void VGAwMISC (u8 value)
-{
-  outb (value, 0x3c2);
-}
 #endif
-
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/radeon.h fbdev-2.6/include/video/radeon.h
--- linus-2.6/include/video/radeon.h	Thu Oct 16 14:16:23 2003
+++ fbdev-2.6/include/video/radeon.h	Wed Oct 15 17:14:12 2003
@@ -365,6 +365,8 @@
 #define DSTCACHE_CTLSTAT                       0x1714  
 #define DEFAULT_PITCH_OFFSET                   0x16E0  
 #define DEFAULT_SC_BOTTOM_RIGHT                0x16E8  
+#define SRC_PITCH_OFFSET                       0x1428
+#define DST_PITCH_OFFSET                       0x142C
 #define DP_GUI_MASTER_CNTL                     0x146C  
 #define SC_TOP_LEFT                            0x16EC  
 #define SC_BOTTOM_RIGHT                        0x16F0  
@@ -373,18 +375,23 @@
 #define RB2D_DSTCACHE_CTLSTAT		       0x342C
 #define LVDS_GEN_CNTL			       0x02d0
 #define LVDS_PLL_CNTL			       0x02d4
+#define FP2_GEN_CNTL                           0x0288
+#define TMDS_CNTL                              0x0294
 #define TMDS_CRC			       0x02a0
 #define TMDS_TRANSMITTER_CNTL		       0x02a4
+#define MPP_TB_CONFIG            	       0x01c0
 
-#define RADEON_BASE_CODE		       0x0f0b
-#define RADEON_BIOS_0_SCRATCH		       0x0010
-#define RADEON_BIOS_1_SCRATCH		       0x0014
-#define RADEON_BIOS_2_SCRATCH		       0x0018
-#define RADEON_BIOS_3_SCRATCH		       0x001c
-#define RADEON_BIOS_4_SCRATCH		       0x0020
-#define RADEON_BIOS_5_SCRATCH		       0x0024
-#define RADEON_BIOS_6_SCRATCH		       0x0028
-#define RADEON_BIOS_7_SCRATCH		       0x002c
+//#define BASE_CODE			       0x0f0b
+#define BIOS_0_SCRATCH			       0x0010
+#define BIOS_1_SCRATCH			       0x0014
+#define BIOS_2_SCRATCH			       0x0018
+#define BIOS_3_SCRATCH			       0x001c
+#define BIOS_4_SCRATCH			       0x0020
+#define BIOS_5_SCRATCH			       0x0024
+#define BIOS_6_SCRATCH			       0x0028
+#define BIOS_7_SCRATCH			       0x002c
+
+#define HDP_SOFT_RESET                         (1 << 26)
 
 #define TV_DAC_CNTL                            0x088c
 #define GPIOPAD_MASK                           0x0198
@@ -422,6 +429,7 @@
 #define P2PLL_CNTL                                 0x002a
 #define P2PLL_REF_DIV                              0x002b
 #define PIXCLKS_CNTL                               0x002d
+#define SCLK_MORE_CNTL				   0x0035
 
 /* MCLK_CNTL bit constants */
 #define FORCEON_MCLKA				   (1 << 16)
@@ -431,6 +439,13 @@
 #define FORCEON_MC            		   	   (1 << 20)
 #define FORCEON_AIC           		   	   (1 << 21)
 
+/* SCLK_CNTL bit constants */
+#define DYN_STOP_LAT_MASK			   0x00007ff8
+#define CP_MAX_DYN_STOP_LAT			   0x0008
+#define SCLK_FORCEON_MASK			   0xffff8000
+
+/* SCLK_MORE_CNTL bit constants */
+#define SCLK_MORE_FORCEON			   0x0700
 
 /* BUS_CNTL bit constants */
 #define BUS_DBL_RESYNC                             0x00000001
@@ -484,6 +499,7 @@
 #define CRTC_DBL_SCAN_EN                           0x00000001
 #define CRTC_CUR_EN                                0x00010000
 #define CRTC_INTERLACE_EN			   (1 << 1)
+#define CRTC_BYPASS_LUT_EN     			   (1 << 14)
 #define CRTC_EXT_DISP_EN      			   (1 << 24)
 #define CRTC_EN					   (1 << 25)
 #define CRTC_DISP_REQ_EN_B                         (1 << 26)
@@ -500,6 +516,22 @@
 /* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */
 #define CUR_LOCK                                   0x80000000
 
+/* GPIO bit constants */
+#define GPIO_A_0		(1 <<  0)
+#define GPIO_A_1		(1 <<  1)
+#define GPIO_Y_0		(1 <<  8)
+#define GPIO_Y_1		(1 <<  9)
+#define GPIO_EN_0		(1 << 16)
+#define GPIO_EN_1		(1 << 17)
+#define GPIO_MASK_0		(1 << 24)
+#define GPIO_MASK_1		(1 << 25)
+#define VGA_DDC_DATA_OUTPUT	GPIO_A_0
+#define VGA_DDC_CLK_OUTPUT	GPIO_A_1
+#define VGA_DDC_DATA_INPUT	GPIO_Y_0
+#define VGA_DDC_CLK_INPUT	GPIO_Y_1
+#define VGA_DDC_DATA_OUT_EN	GPIO_EN_0
+#define VGA_DDC_CLK_OUT_EN	GPIO_EN_1
+
 
 /* FP bit constants */
 #define FP_CRTC_H_TOTAL_MASK			   0x000003ff
@@ -560,7 +592,7 @@
 #define TMDS_PLL_EN				   (1 << 0)
 #define TMDS_PLLRST				   (1 << 1)
 #define TMDS_RAN_PAT_RST			   (1 << 7)
-#define ICHCSEL					   (1 << 28)
+#define TMDS_ICHCSEL				   (1 << 28)
 
 /* FP_HORZ_STRETCH bit constants */
 #define HORZ_STRETCH_RATIO_MASK			   0xffff
@@ -592,14 +624,25 @@
 #define DAC_4BPP_PIX_ORDER                         0x00000200
 #define DAC_CRC_EN                                 0x00080000
 #define DAC_MASK_ALL				   (0xff << 24)
+#define DAC_PDWN                                   (1 << 15)
 #define DAC_EXPAND_MODE				   (1 << 14)
 #define DAC_VGA_ADR_EN				   (1 << 13)
-#define DAC_RANGE_CNTL				   (3 << 0)
-#define DAC_BLANKING				   (1 << 2)
-#define DAC_CMP_EN                                 (1 << 3)
+#define DAC_RANGE_CNTL				   (3 <<  0)
+#define DAC_RANGE_CNTL_MASK    			   0x03
+#define DAC_BLANKING				   (1 <<  2)
+#define DAC_CMP_EN                                 (1 <<  3)
+#define DAC_CMP_OUTPUT                             (1 <<  7)
 
 /* DAC_CNTL2 bit constants */   
 #define DAC2_CMP_EN                                (1 << 7)
+#define DAC2_PALETTE_ACCESS_CNTL                   (1 << 5)
+
+/* DAC_EXT_CNTL bit constants */
+#define DAC_FORCE_BLANK_OFF_EN                     (1 << 4)
+#define DAC_FORCE_DATA_EN                          (1 << 5)
+#define DAC_FORCE_DATA_SEL_MASK                    (3 << 6)
+#define DAC_FORCE_DATA_MASK                        0x0003ff00
+#define DAC_FORCE_DATA_SHIFT                       8
 
 /* GEN_RESET_CNTL bit constants */
 #define SOFT_RESET_GUI                             0x00000001
@@ -871,6 +914,995 @@
 #define	PPLL_VGA_ATOMIC_UPDATE_EN	0x00020000
 
 #define GUI_ACTIVE			0x80000000
+
+
+#define MC_IND_INDEX                           0x01F8
+#define MC_IND_DATA                            0x01FC
+#define MEM_REFRESH_CNTL                       0x0178
+
+// CLK_PIN_CNTL
+#define CLK_PIN_CNTL__OSC_EN_MASK                          0x00000001L
+#define CLK_PIN_CNTL__OSC_EN                               0x00000001L
+#define CLK_PIN_CNTL__XTL_LOW_GAIN_MASK                    0x00000004L
+#define CLK_PIN_CNTL__XTL_LOW_GAIN                         0x00000004L
+#define CLK_PIN_CNTL__DONT_USE_XTALIN_MASK                 0x00000010L
+#define CLK_PIN_CNTL__DONT_USE_XTALIN                      0x00000010L
+#define CLK_PIN_CNTL__SLOW_CLOCK_SOURCE_MASK               0x00000020L
+#define CLK_PIN_CNTL__SLOW_CLOCK_SOURCE                    0x00000020L
+#define CLK_PIN_CNTL__CG_CLK_TO_OUTPIN_MASK                0x00000800L
+#define CLK_PIN_CNTL__CG_CLK_TO_OUTPIN                     0x00000800L
+#define CLK_PIN_CNTL__CG_COUNT_UP_TO_OUTPIN_MASK           0x00001000L
+#define CLK_PIN_CNTL__CG_COUNT_UP_TO_OUTPIN                0x00001000L
+#define CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND_MASK          0x00002000L
+#define CLK_PIN_CNTL__ACCESS_REGS_IN_SUSPEND               0x00002000L
+#define CLK_PIN_CNTL__CG_SPARE_MASK                        0x00004000L
+#define CLK_PIN_CNTL__CG_SPARE                             0x00004000L
+#define CLK_PIN_CNTL__SCLK_DYN_START_CNTL_MASK             0x00008000L
+#define CLK_PIN_CNTL__SCLK_DYN_START_CNTL                  0x00008000L
+#define CLK_PIN_CNTL__CP_CLK_RUNNING_MASK                  0x00010000L
+#define CLK_PIN_CNTL__CP_CLK_RUNNING                       0x00010000L
+#define CLK_PIN_CNTL__CG_SPARE_RD_MASK                     0x00060000L
+#define CLK_PIN_CNTL__XTALIN_ALWAYS_ONb_MASK               0x00080000L
+#define CLK_PIN_CNTL__XTALIN_ALWAYS_ONb                    0x00080000L
+#define CLK_PIN_CNTL__PWRSEQ_DELAY_MASK                    0xff000000L
+
+// CLK_PWRMGT_CNTL_M6
+#define	CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF__SHIFT         0x00000000
+#define	CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF__SHIFT         0x00000001
+#define	CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF__SHIFT         0x00000002
+#define	CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF__SHIFT        0x00000003
+#define	CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF__SHIFT            0x00000004
+#define	CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF__SHIFT            0x00000005
+#define	CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF__SHIFT            0x00000006
+#define	CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF__SHIFT           0x00000007
+#define	CLK_PWRMGT_CNTL_M6__MC_CH_MODE__SHIFT              0x00000008
+#define	CLK_PWRMGT_CNTL_M6__TEST_MODE__SHIFT               0x00000009
+#define	CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN__SHIFT          0x0000000a
+#define	CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE__SHIFT      0x0000000c
+#define	CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT__SHIFT         0x0000000d
+#define	CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT__SHIFT       0x0000000f
+#define	CLK_PWRMGT_CNTL_M6__MC_BUSY__SHIFT                 0x00000010
+#define	CLK_PWRMGT_CNTL_M6__MC_INT_CNTL__SHIFT             0x00000011
+#define	CLK_PWRMGT_CNTL_M6__MC_SWITCH__SHIFT               0x00000012
+#define	CLK_PWRMGT_CNTL_M6__DLL_READY__SHIFT               0x00000013
+#define	CLK_PWRMGT_CNTL_M6__DISP_PM__SHIFT                 0x00000014
+#define	CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE__SHIFT           0x00000015
+#define	CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG__SHIFT            0x00000018
+#define	CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF__SHIFT        0x0000001e
+#define	CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF__SHIFT           0x0000001f
+
+// P2PLL_CNTL
+#define P2PLL_CNTL__P2PLL_RESET_MASK                       0x00000001L
+#define P2PLL_CNTL__P2PLL_RESET                            0x00000001L
+#define P2PLL_CNTL__P2PLL_SLEEP_MASK                       0x00000002L
+#define P2PLL_CNTL__P2PLL_SLEEP                            0x00000002L
+#define P2PLL_CNTL__P2PLL_TST_EN_MASK                      0x00000004L
+#define P2PLL_CNTL__P2PLL_TST_EN                           0x00000004L
+#define P2PLL_CNTL__P2PLL_REFCLK_SEL_MASK                  0x00000010L
+#define P2PLL_CNTL__P2PLL_REFCLK_SEL                       0x00000010L
+#define P2PLL_CNTL__P2PLL_FBCLK_SEL_MASK                   0x00000020L
+#define P2PLL_CNTL__P2PLL_FBCLK_SEL                        0x00000020L
+#define P2PLL_CNTL__P2PLL_TCPOFF_MASK                      0x00000040L
+#define P2PLL_CNTL__P2PLL_TCPOFF                           0x00000040L
+#define P2PLL_CNTL__P2PLL_TVCOMAX_MASK                     0x00000080L
+#define P2PLL_CNTL__P2PLL_TVCOMAX                          0x00000080L
+#define P2PLL_CNTL__P2PLL_PCP_MASK                         0x00000700L
+#define P2PLL_CNTL__P2PLL_PVG_MASK                         0x00003800L
+#define P2PLL_CNTL__P2PLL_PDC_MASK                         0x0000c000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_EN_MASK            0x00010000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_EN                 0x00010000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_SYNC_MASK          0x00040000L
+#define P2PLL_CNTL__P2PLL_ATOMIC_UPDATE_SYNC               0x00040000L
+#define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET_MASK          0x00080000L
+#define P2PLL_CNTL__P2PLL_DISABLE_AUTO_RESET               0x00080000L
+
+// PIXCLKS_CNTL
+#define	PIXCLKS_CNTL__PIX2CLK_SRC_SEL__SHIFT               0x00000000
+#define	PIXCLKS_CNTL__PIX2CLK_INVERT__SHIFT                0x00000004
+#define	PIXCLKS_CNTL__PIX2CLK_SRC_INVERT__SHIFT            0x00000005
+#define	PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb__SHIFT            0x00000006
+#define	PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb__SHIFT        0x00000007
+#define	PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL__SHIFT             0x00000008
+#define	PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb__SHIFT       0x0000000b
+#define	PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb__SHIFT          0x0000000c
+#define	PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb__SHIFT    0x0000000d
+#define	PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb__SHIFT        0x0000000e
+#define	PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb__SHIFT        0x0000000f
+
+
+// PIXCLKS_CNTL
+#define PIXCLKS_CNTL__PIX2CLK_SRC_SEL_MASK                 0x00000003L
+#define PIXCLKS_CNTL__PIX2CLK_INVERT_MASK                  0x00000010L
+#define PIXCLKS_CNTL__PIX2CLK_INVERT                       0x00000010L
+#define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT_MASK              0x00000020L
+#define PIXCLKS_CNTL__PIX2CLK_SRC_INVERT                   0x00000020L
+#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb_MASK              0x00000040L
+#define PIXCLKS_CNTL__PIX2CLK_ALWAYS_ONb                   0x00000040L
+#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb_MASK          0x00000080L
+#define PIXCLKS_CNTL__PIX2CLK_DAC_ALWAYS_ONb               0x00000080L
+#define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL_MASK               0x00000100L
+#define PIXCLKS_CNTL__PIXCLK_TV_SRC_SEL                    0x00000100L
+#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb_MASK         0x00000800L
+#define PIXCLKS_CNTL__PIXCLK_BLEND_ALWAYS_ONb              0x00000800L
+#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb_MASK            0x00001000L
+#define PIXCLKS_CNTL__PIXCLK_GV_ALWAYS_ONb                 0x00001000L
+#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb_MASK      0x00002000L
+#define PIXCLKS_CNTL__PIXCLK_DIG_TMDS_ALWAYS_ONb           0x00002000L
+#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb_MASK          0x00004000L
+#define PIXCLKS_CNTL__PIXCLK_LVDS_ALWAYS_ONb               0x00004000L
+#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb_MASK          0x00008000L
+#define PIXCLKS_CNTL__PIXCLK_TMDS_ALWAYS_ONb               0x00008000L
+
+
+// P2PLL_DIV_0
+#define P2PLL_DIV_0__P2PLL_FB_DIV_MASK                     0x000007ffL
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W_MASK            0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_W                 0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_R_MASK            0x00008000L
+#define P2PLL_DIV_0__P2PLL_ATOMIC_UPDATE_R                 0x00008000L
+#define P2PLL_DIV_0__P2PLL_POST_DIV_MASK                   0x00070000L
+
+// SCLK_CNTL_M6
+#define SCLK_CNTL_M6__SCLK_SRC_SEL_MASK                    0x00000007L
+#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT_MASK             0x00000008L
+#define SCLK_CNTL_M6__CP_MAX_DYN_STOP_LAT                  0x00000008L
+#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT_MASK            0x00000010L
+#define SCLK_CNTL_M6__HDP_MAX_DYN_STOP_LAT                 0x00000010L
+#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT_MASK             0x00000020L
+#define SCLK_CNTL_M6__TV_MAX_DYN_STOP_LAT                  0x00000020L
+#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT_MASK             0x00000040L
+#define SCLK_CNTL_M6__E2_MAX_DYN_STOP_LAT                  0x00000040L
+#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT_MASK             0x00000080L
+#define SCLK_CNTL_M6__SE_MAX_DYN_STOP_LAT                  0x00000080L
+#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT_MASK           0x00000100L
+#define SCLK_CNTL_M6__IDCT_MAX_DYN_STOP_LAT                0x00000100L
+#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT_MASK            0x00000200L
+#define SCLK_CNTL_M6__VIP_MAX_DYN_STOP_LAT                 0x00000200L
+#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT_MASK             0x00000400L
+#define SCLK_CNTL_M6__RE_MAX_DYN_STOP_LAT                  0x00000400L
+#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT_MASK             0x00000800L
+#define SCLK_CNTL_M6__PB_MAX_DYN_STOP_LAT                  0x00000800L
+#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT_MASK            0x00001000L
+#define SCLK_CNTL_M6__TAM_MAX_DYN_STOP_LAT                 0x00001000L
+#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT_MASK            0x00002000L
+#define SCLK_CNTL_M6__TDM_MAX_DYN_STOP_LAT                 0x00002000L
+#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT_MASK             0x00004000L
+#define SCLK_CNTL_M6__RB_MAX_DYN_STOP_LAT                  0x00004000L
+#define SCLK_CNTL_M6__FORCE_DISP2_MASK                     0x00008000L
+#define SCLK_CNTL_M6__FORCE_DISP2                          0x00008000L
+#define SCLK_CNTL_M6__FORCE_CP_MASK                        0x00010000L
+#define SCLK_CNTL_M6__FORCE_CP                             0x00010000L
+#define SCLK_CNTL_M6__FORCE_HDP_MASK                       0x00020000L
+#define SCLK_CNTL_M6__FORCE_HDP                            0x00020000L
+#define SCLK_CNTL_M6__FORCE_DISP1_MASK                     0x00040000L
+#define SCLK_CNTL_M6__FORCE_DISP1                          0x00040000L
+#define SCLK_CNTL_M6__FORCE_TOP_MASK                       0x00080000L
+#define SCLK_CNTL_M6__FORCE_TOP                            0x00080000L
+#define SCLK_CNTL_M6__FORCE_E2_MASK                        0x00100000L
+#define SCLK_CNTL_M6__FORCE_E2                             0x00100000L
+#define SCLK_CNTL_M6__FORCE_SE_MASK                        0x00200000L
+#define SCLK_CNTL_M6__FORCE_SE                             0x00200000L
+#define SCLK_CNTL_M6__FORCE_IDCT_MASK                      0x00400000L
+#define SCLK_CNTL_M6__FORCE_IDCT                           0x00400000L
+#define SCLK_CNTL_M6__FORCE_VIP_MASK                       0x00800000L
+#define SCLK_CNTL_M6__FORCE_VIP                            0x00800000L
+#define SCLK_CNTL_M6__FORCE_RE_MASK                        0x01000000L
+#define SCLK_CNTL_M6__FORCE_RE                             0x01000000L
+#define SCLK_CNTL_M6__FORCE_PB_MASK                        0x02000000L
+#define SCLK_CNTL_M6__FORCE_PB                             0x02000000L
+#define SCLK_CNTL_M6__FORCE_TAM_MASK                       0x04000000L
+#define SCLK_CNTL_M6__FORCE_TAM                            0x04000000L
+#define SCLK_CNTL_M6__FORCE_TDM_MASK                       0x08000000L
+#define SCLK_CNTL_M6__FORCE_TDM                            0x08000000L
+#define SCLK_CNTL_M6__FORCE_RB_MASK                        0x10000000L
+#define SCLK_CNTL_M6__FORCE_RB                             0x10000000L
+#define SCLK_CNTL_M6__FORCE_TV_SCLK_MASK                   0x20000000L
+#define SCLK_CNTL_M6__FORCE_TV_SCLK                        0x20000000L
+#define SCLK_CNTL_M6__FORCE_SUBPIC_MASK                    0x40000000L
+#define SCLK_CNTL_M6__FORCE_SUBPIC                         0x40000000L
+#define SCLK_CNTL_M6__FORCE_OV0_MASK                       0x80000000L
+#define SCLK_CNTL_M6__FORCE_OV0                            0x80000000L
+
+// SCLK_MORE_CNTL
+#define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT_MASK     0x00000001L
+#define SCLK_MORE_CNTL__DISPREGS_MAX_DYN_STOP_LAT          0x00000001L
+#define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT_MASK       0x00000002L
+#define SCLK_MORE_CNTL__MC_GUI_MAX_DYN_STOP_LAT            0x00000002L
+#define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT_MASK      0x00000004L
+#define SCLK_MORE_CNTL__MC_HOST_MAX_DYN_STOP_LAT           0x00000004L
+#define SCLK_MORE_CNTL__FORCE_DISPREGS_MASK                0x00000100L
+#define SCLK_MORE_CNTL__FORCE_DISPREGS                     0x00000100L
+#define SCLK_MORE_CNTL__FORCE_MC_GUI_MASK                  0x00000200L
+#define SCLK_MORE_CNTL__FORCE_MC_GUI                       0x00000200L
+#define SCLK_MORE_CNTL__FORCE_MC_HOST_MASK                 0x00000400L
+#define SCLK_MORE_CNTL__FORCE_MC_HOST                      0x00000400L
+#define SCLK_MORE_CNTL__STOP_SCLK_EN_MASK                  0x00001000L
+#define SCLK_MORE_CNTL__STOP_SCLK_EN                       0x00001000L
+#define SCLK_MORE_CNTL__STOP_SCLK_A_MASK                   0x00002000L
+#define SCLK_MORE_CNTL__STOP_SCLK_A                        0x00002000L
+#define SCLK_MORE_CNTL__STOP_SCLK_B_MASK                   0x00004000L
+#define SCLK_MORE_CNTL__STOP_SCLK_B                        0x00004000L
+#define SCLK_MORE_CNTL__STOP_SCLK_C_MASK                   0x00008000L
+#define SCLK_MORE_CNTL__STOP_SCLK_C                        0x00008000L
+#define SCLK_MORE_CNTL__HALF_SPEED_SCLK_MASK               0x00010000L
+#define SCLK_MORE_CNTL__HALF_SPEED_SCLK                    0x00010000L
+#define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP_MASK            0x00020000L
+#define SCLK_MORE_CNTL__IO_CG_VOLTAGE_DROP                 0x00020000L
+#define SCLK_MORE_CNTL__TVFB_SOFT_RESET_MASK               0x00040000L
+#define SCLK_MORE_CNTL__TVFB_SOFT_RESET                    0x00040000L
+#define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC_MASK             0x00080000L
+#define SCLK_MORE_CNTL__VOLTAGE_DROP_SYNC                  0x00080000L
+#define SCLK_MORE_CNTL__VOLTAGE_DELAY_SEL_MASK             0x00300000L
+#define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK_MASK          0x00400000L
+#define SCLK_MORE_CNTL__IDLE_DELAY_HALF_SCLK               0x00400000L
+#define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK_MASK            0x00800000L
+#define SCLK_MORE_CNTL__AGP_BUSY_HALF_SCLK                 0x00800000L
+#define SCLK_MORE_CNTL__CG_SPARE_RD_C_MASK                 0xff000000L
+
+// MCLK_CNTL_M6
+#define MCLK_CNTL_M6__MCLKA_SRC_SEL_MASK                   0x00000007L
+#define MCLK_CNTL_M6__YCLKA_SRC_SEL_MASK                   0x00000070L
+#define MCLK_CNTL_M6__MCLKB_SRC_SEL_MASK                   0x00000700L
+#define MCLK_CNTL_M6__YCLKB_SRC_SEL_MASK                   0x00007000L
+#define MCLK_CNTL_M6__FORCE_MCLKA_MASK                     0x00010000L
+#define MCLK_CNTL_M6__FORCE_MCLKA                          0x00010000L
+#define MCLK_CNTL_M6__FORCE_MCLKB_MASK                     0x00020000L
+#define MCLK_CNTL_M6__FORCE_MCLKB                          0x00020000L
+#define MCLK_CNTL_M6__FORCE_YCLKA_MASK                     0x00040000L
+#define MCLK_CNTL_M6__FORCE_YCLKA                          0x00040000L
+#define MCLK_CNTL_M6__FORCE_YCLKB_MASK                     0x00080000L
+#define MCLK_CNTL_M6__FORCE_YCLKB                          0x00080000L
+#define MCLK_CNTL_M6__FORCE_MC_MASK                        0x00100000L
+#define MCLK_CNTL_M6__FORCE_MC                             0x00100000L
+#define MCLK_CNTL_M6__FORCE_AIC_MASK                       0x00200000L
+#define MCLK_CNTL_M6__FORCE_AIC                            0x00200000L
+#define MCLK_CNTL_M6__MRDCKA0_SOUTSEL_MASK                 0x03000000L
+#define MCLK_CNTL_M6__MRDCKA1_SOUTSEL_MASK                 0x0c000000L
+#define MCLK_CNTL_M6__MRDCKB0_SOUTSEL_MASK                 0x30000000L
+#define MCLK_CNTL_M6__MRDCKB1_SOUTSEL_MASK                 0xc0000000L
+
+// MCLK_MISC
+#define MCLK_MISC__SCLK_SOURCED_FROM_MPLL_SEL_MASK         0x00000003L
+#define MCLK_MISC__MCLK_FROM_SPLL_DIV_SEL_MASK             0x00000004L
+#define MCLK_MISC__MCLK_FROM_SPLL_DIV_SEL                  0x00000004L
+#define MCLK_MISC__ENABLE_SCLK_FROM_MPLL_MASK              0x00000008L
+#define MCLK_MISC__ENABLE_SCLK_FROM_MPLL                   0x00000008L
+#define MCLK_MISC__MPLL_MODEA_MODEC_HW_SEL_EN_MASK         0x00000010L
+#define MCLK_MISC__MPLL_MODEA_MODEC_HW_SEL_EN              0x00000010L
+#define MCLK_MISC__DLL_READY_LAT_MASK                      0x00000100L
+#define MCLK_MISC__DLL_READY_LAT                           0x00000100L
+#define MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT_MASK           0x00001000L
+#define MCLK_MISC__MC_MCLK_MAX_DYN_STOP_LAT                0x00001000L
+#define MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT_MASK           0x00002000L
+#define MCLK_MISC__IO_MCLK_MAX_DYN_STOP_LAT                0x00002000L
+#define MCLK_MISC__MC_MCLK_DYN_ENABLE_MASK                 0x00004000L
+#define MCLK_MISC__MC_MCLK_DYN_ENABLE                      0x00004000L
+#define MCLK_MISC__IO_MCLK_DYN_ENABLE_MASK                 0x00008000L
+#define MCLK_MISC__IO_MCLK_DYN_ENABLE                      0x00008000L
+#define MCLK_MISC__CGM_CLK_TO_OUTPIN_MASK                  0x00010000L
+#define MCLK_MISC__CGM_CLK_TO_OUTPIN                       0x00010000L
+#define MCLK_MISC__CLK_OR_COUNT_SEL_MASK                   0x00020000L
+#define MCLK_MISC__CLK_OR_COUNT_SEL                        0x00020000L
+#define MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND_MASK        0x00040000L
+#define MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND             0x00040000L
+#define MCLK_MISC__CGM_SPARE_RD_MASK                       0x00300000L
+#define MCLK_MISC__CGM_SPARE_A_RD_MASK                     0x00c00000L
+#define MCLK_MISC__TCLK_TO_YCLKB_EN_MASK                   0x01000000L
+#define MCLK_MISC__TCLK_TO_YCLKB_EN                        0x01000000L
+#define MCLK_MISC__CGM_SPARE_A_MASK                        0x0e000000L
+
+// VCLK_ECP_CNTL
+#define VCLK_ECP_CNTL__VCLK_SRC_SEL_MASK                   0x00000003L
+#define VCLK_ECP_CNTL__VCLK_INVERT_MASK                    0x00000010L
+#define VCLK_ECP_CNTL__VCLK_INVERT                         0x00000010L
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT_MASK              0x00000020L
+#define VCLK_ECP_CNTL__PIXCLK_SRC_INVERT                   0x00000020L
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb_MASK              0x00000040L
+#define VCLK_ECP_CNTL__PIXCLK_ALWAYS_ONb                   0x00000040L
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb_MASK          0x00000080L
+#define VCLK_ECP_CNTL__PIXCLK_DAC_ALWAYS_ONb               0x00000080L
+#define VCLK_ECP_CNTL__ECP_DIV_MASK                        0x00000300L
+#define VCLK_ECP_CNTL__ECP_FORCE_ON_MASK                   0x00040000L
+#define VCLK_ECP_CNTL__ECP_FORCE_ON                        0x00040000L
+#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON_MASK                0x00080000L
+#define VCLK_ECP_CNTL__SUBCLK_FORCE_ON                     0x00080000L
+
+// PLL_PWRMGT_CNTL
+#define PLL_PWRMGT_CNTL__MPLL_TURNOFF_MASK                 0x00000001L
+#define PLL_PWRMGT_CNTL__MPLL_TURNOFF                      0x00000001L
+#define PLL_PWRMGT_CNTL__SPLL_TURNOFF_MASK                 0x00000002L
+#define PLL_PWRMGT_CNTL__SPLL_TURNOFF                      0x00000002L
+#define PLL_PWRMGT_CNTL__PPLL_TURNOFF_MASK                 0x00000004L
+#define PLL_PWRMGT_CNTL__PPLL_TURNOFF                      0x00000004L
+#define PLL_PWRMGT_CNTL__P2PLL_TURNOFF_MASK                0x00000008L
+#define PLL_PWRMGT_CNTL__P2PLL_TURNOFF                     0x00000008L
+#define PLL_PWRMGT_CNTL__TVPLL_TURNOFF_MASK                0x00000010L
+#define PLL_PWRMGT_CNTL__TVPLL_TURNOFF                     0x00000010L
+#define PLL_PWRMGT_CNTL__AGPCLK_DYN_STOP_LAT_MASK          0x000001e0L
+#define PLL_PWRMGT_CNTL__APM_POWER_STATE_MASK              0x00000600L
+#define PLL_PWRMGT_CNTL__APM_PWRSTATE_RD_MASK              0x00001800L
+#define PLL_PWRMGT_CNTL__PM_MODE_SEL_MASK                  0x00002000L
+#define PLL_PWRMGT_CNTL__PM_MODE_SEL                       0x00002000L
+#define PLL_PWRMGT_CNTL__EN_PWRSEQ_DONE_COND_MASK          0x00004000L
+#define PLL_PWRMGT_CNTL__EN_PWRSEQ_DONE_COND               0x00004000L
+#define PLL_PWRMGT_CNTL__EN_DISP_PARKED_COND_MASK          0x00008000L
+#define PLL_PWRMGT_CNTL__EN_DISP_PARKED_COND               0x00008000L
+#define PLL_PWRMGT_CNTL__MOBILE_SU_MASK                    0x00010000L
+#define PLL_PWRMGT_CNTL__MOBILE_SU                         0x00010000L
+#define PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK_MASK             0x00020000L
+#define PLL_PWRMGT_CNTL__SU_SCLK_USE_BCLK                  0x00020000L
+#define PLL_PWRMGT_CNTL__SU_MCLK_USE_BCLK_MASK             0x00040000L
+#define PLL_PWRMGT_CNTL__SU_MCLK_USE_BCLK                  0x00040000L
+#define PLL_PWRMGT_CNTL__SU_SUSTAIN_DISABLE_MASK           0x00080000L
+#define PLL_PWRMGT_CNTL__SU_SUSTAIN_DISABLE                0x00080000L
+#define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE_MASK           0x00100000L
+#define PLL_PWRMGT_CNTL__TCL_BYPASS_DISABLE                0x00100000L
+#define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD_MASK          0x00200000L
+#define PLL_PWRMGT_CNTL__TCL_CLOCK_ACTIVE_RD               0x00200000L
+#define PLL_PWRMGT_CNTL__CG_NO2_DEBUG_MASK                 0xff000000L
+
+// CLK_PWRMGT_CNTL_M6
+#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF_MASK           0x00000001L
+#define CLK_PWRMGT_CNTL_M6__MPLL_PWRMGT_OFF                0x00000001L
+#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF_MASK           0x00000002L
+#define CLK_PWRMGT_CNTL_M6__SPLL_PWRMGT_OFF                0x00000002L
+#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF_MASK           0x00000004L
+#define CLK_PWRMGT_CNTL_M6__PPLL_PWRMGT_OFF                0x00000004L
+#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF_MASK          0x00000008L
+#define CLK_PWRMGT_CNTL_M6__P2PLL_PWRMGT_OFF               0x00000008L
+#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF_MASK              0x00000010L
+#define CLK_PWRMGT_CNTL_M6__MCLK_TURNOFF                   0x00000010L
+#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF_MASK              0x00000020L
+#define CLK_PWRMGT_CNTL_M6__SCLK_TURNOFF                   0x00000020L
+#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF_MASK              0x00000040L
+#define CLK_PWRMGT_CNTL_M6__PCLK_TURNOFF                   0x00000040L
+#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF_MASK             0x00000080L
+#define CLK_PWRMGT_CNTL_M6__P2CLK_TURNOFF                  0x00000080L
+#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE_MASK                0x00000100L
+#define CLK_PWRMGT_CNTL_M6__MC_CH_MODE                     0x00000100L
+#define CLK_PWRMGT_CNTL_M6__TEST_MODE_MASK                 0x00000200L
+#define CLK_PWRMGT_CNTL_M6__TEST_MODE                      0x00000200L
+#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN_MASK            0x00000400L
+#define CLK_PWRMGT_CNTL_M6__GLOBAL_PMAN_EN                 0x00000400L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE_MASK        0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ENGINE_DYNCLK_MODE             0x00001000L
+#define CLK_PWRMGT_CNTL_M6__ACTIVE_HILO_LAT_MASK           0x00006000L
+#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT_MASK         0x00008000L
+#define CLK_PWRMGT_CNTL_M6__DISP_DYN_STOP_LAT              0x00008000L
+#define CLK_PWRMGT_CNTL_M6__MC_BUSY_MASK                   0x00010000L
+#define CLK_PWRMGT_CNTL_M6__MC_BUSY                        0x00010000L
+#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL_MASK               0x00020000L
+#define CLK_PWRMGT_CNTL_M6__MC_INT_CNTL                    0x00020000L
+#define CLK_PWRMGT_CNTL_M6__MC_SWITCH_MASK                 0x00040000L
+#define CLK_PWRMGT_CNTL_M6__MC_SWITCH                      0x00040000L
+#define CLK_PWRMGT_CNTL_M6__DLL_READY_MASK                 0x00080000L
+#define CLK_PWRMGT_CNTL_M6__DLL_READY                      0x00080000L
+#define CLK_PWRMGT_CNTL_M6__DISP_PM_MASK                   0x00100000L
+#define CLK_PWRMGT_CNTL_M6__DISP_PM                        0x00100000L
+#define CLK_PWRMGT_CNTL_M6__DYN_STOP_MODE_MASK             0x00e00000L
+#define CLK_PWRMGT_CNTL_M6__CG_NO1_DEBUG_MASK              0x3f000000L
+#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF_MASK          0x40000000L
+#define CLK_PWRMGT_CNTL_M6__TVPLL_PWRMGT_OFF               0x40000000L
+#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF_MASK             0x80000000L
+#define CLK_PWRMGT_CNTL_M6__TVCLK_TURNOFF                  0x80000000L
+
+// BUS_CNTL1
+#define BUS_CNTL1__PMI_IO_DISABLE_MASK                     0x00000001L
+#define BUS_CNTL1__PMI_IO_DISABLE                          0x00000001L
+#define BUS_CNTL1__PMI_MEM_DISABLE_MASK                    0x00000002L
+#define BUS_CNTL1__PMI_MEM_DISABLE                         0x00000002L
+#define BUS_CNTL1__PMI_BM_DISABLE_MASK                     0x00000004L
+#define BUS_CNTL1__PMI_BM_DISABLE                          0x00000004L
+#define BUS_CNTL1__PMI_INT_DISABLE_MASK                    0x00000008L
+#define BUS_CNTL1__PMI_INT_DISABLE                         0x00000008L
+#define BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE_MASK         0x00000020L
+#define BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE              0x00000020L
+#define BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS_MASK         0x00000100L
+#define BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS              0x00000100L
+#define BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS_MASK         0x00000200L
+#define BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS              0x00000200L
+#define BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS_MASK         0x00000400L
+#define BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS              0x00000400L
+#define BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS_MASK   0x00000800L
+#define BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS        0x00000800L
+#define BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK                0x0c000000L
+#define BUS_CNTL1__SEND_SBA_LATENCY_MASK                   0x70000000L
+#define BUS_CNTL1__AGPCLK_VALID_MASK                       0x80000000L
+#define BUS_CNTL1__AGPCLK_VALID                            0x80000000L
+
+// BUS_CNTL1
+#define	BUS_CNTL1__PMI_IO_DISABLE__SHIFT                   0x00000000
+#define	BUS_CNTL1__PMI_MEM_DISABLE__SHIFT                  0x00000001
+#define	BUS_CNTL1__PMI_BM_DISABLE__SHIFT                   0x00000002
+#define	BUS_CNTL1__PMI_INT_DISABLE__SHIFT                  0x00000003
+#define	BUS_CNTL1__BUS2_IMMEDIATE_PMI_DISABLE__SHIFT       0x00000005
+#define	BUS_CNTL1__BUS2_VGA_REG_COHERENCY_DIS__SHIFT       0x00000008
+#define	BUS_CNTL1__BUS2_VGA_MEM_COHERENCY_DIS__SHIFT       0x00000009
+#define	BUS_CNTL1__BUS2_HDP_REG_COHERENCY_DIS__SHIFT       0x0000000a
+#define	BUS_CNTL1__BUS2_GUI_INITIATOR_COHERENCY_DIS__SHIFT 0x0000000b
+#define	BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT              0x0000001a
+#define	BUS_CNTL1__SEND_SBA_LATENCY__SHIFT                 0x0000001c
+#define	BUS_CNTL1__AGPCLK_VALID__SHIFT                     0x0000001f
+
+// CRTC_OFFSET_CNTL
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_MASK              0x0000000fL
+#define CRTC_OFFSET_CNTL__CRTC_TILE_LINE_RIGHT_MASK        0x000000f0L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT_MASK          0x00004000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_RIGHT               0x00004000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN_MASK                0x00008000L
+#define CRTC_OFFSET_CNTL__CRTC_TILE_EN                     0x00008000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL_MASK       0x00010000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_FLIP_CNTL            0x00010000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN_MASK       0x00020000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_OFFSET_EN            0x00020000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_EN_MASK         0x000c0000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN_MASK     0x00100000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN          0x00100000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_MASK            0x00200000L
+#define CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC                 0x00200000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN_MASK 0x10000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_LEFT_EN     0x10000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN_MASK 0x20000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_RIGHT_EN    0x20000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET_MASK        0x40000000L
+#define CRTC_OFFSET_CNTL__CRTC_GUI_TRIG_OFFSET             0x40000000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK_MASK            0x80000000L
+#define CRTC_OFFSET_CNTL__CRTC_OFFSET_LOCK                 0x80000000L
+
+// CRTC_GEN_CNTL
+#define CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN_MASK               0x00000001L
+#define CRTC_GEN_CNTL__CRTC_DBL_SCAN_EN                    0x00000001L
+#define CRTC_GEN_CNTL__CRTC_INTERLACE_EN_MASK              0x00000002L
+#define CRTC_GEN_CNTL__CRTC_INTERLACE_EN                   0x00000002L
+#define CRTC_GEN_CNTL__CRTC_C_SYNC_EN_MASK                 0x00000010L
+#define CRTC_GEN_CNTL__CRTC_C_SYNC_EN                      0x00000010L
+#define CRTC_GEN_CNTL__CRTC_PIX_WIDTH_MASK                 0x00000f00L
+#define CRTC_GEN_CNTL__CRTC_ICON_EN_MASK                   0x00008000L
+#define CRTC_GEN_CNTL__CRTC_ICON_EN                        0x00008000L
+#define CRTC_GEN_CNTL__CRTC_CUR_EN_MASK                    0x00010000L
+#define CRTC_GEN_CNTL__CRTC_CUR_EN                         0x00010000L
+#define CRTC_GEN_CNTL__CRTC_VSTAT_MODE_MASK                0x00060000L
+#define CRTC_GEN_CNTL__CRTC_CUR_MODE_MASK                  0x00700000L
+#define CRTC_GEN_CNTL__CRTC_EXT_DISP_EN_MASK               0x01000000L
+#define CRTC_GEN_CNTL__CRTC_EXT_DISP_EN                    0x01000000L
+#define CRTC_GEN_CNTL__CRTC_EN_MASK                        0x02000000L
+#define CRTC_GEN_CNTL__CRTC_EN                             0x02000000L
+#define CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B_MASK             0x04000000L
+#define CRTC_GEN_CNTL__CRTC_DISP_REQ_EN_B                  0x04000000L
+
+// CRTC2_GEN_CNTL
+#define CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN_MASK             0x00000001L
+#define CRTC2_GEN_CNTL__CRTC2_DBL_SCAN_EN                  0x00000001L
+#define CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN_MASK            0x00000002L
+#define CRTC2_GEN_CNTL__CRTC2_INTERLACE_EN                 0x00000002L
+#define CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE_MASK           0x00000010L
+#define CRTC2_GEN_CNTL__CRTC2_SYNC_TRISTATE                0x00000010L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE_MASK          0x00000020L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_TRISTATE               0x00000020L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE_MASK          0x00000040L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_TRISTATE               0x00000040L
+#define CRTC2_GEN_CNTL__CRT2_ON_MASK                       0x00000080L
+#define CRTC2_GEN_CNTL__CRT2_ON                            0x00000080L
+#define CRTC2_GEN_CNTL__CRTC2_PIX_WIDTH_MASK               0x00000f00L
+#define CRTC2_GEN_CNTL__CRTC2_ICON_EN_MASK                 0x00008000L
+#define CRTC2_GEN_CNTL__CRTC2_ICON_EN                      0x00008000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_EN_MASK                  0x00010000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_EN                       0x00010000L
+#define CRTC2_GEN_CNTL__CRTC2_CUR_MODE_MASK                0x00700000L
+#define CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS_MASK             0x00800000L
+#define CRTC2_GEN_CNTL__CRTC2_DISPLAY_DIS                  0x00800000L
+#define CRTC2_GEN_CNTL__CRTC2_EN_MASK                      0x02000000L
+#define CRTC2_GEN_CNTL__CRTC2_EN                           0x02000000L
+#define CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B_MASK           0x04000000L
+#define CRTC2_GEN_CNTL__CRTC2_DISP_REQ_EN_B                0x04000000L
+#define CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN_MASK               0x08000000L
+#define CRTC2_GEN_CNTL__CRTC2_C_SYNC_EN                    0x08000000L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS_MASK               0x10000000L
+#define CRTC2_GEN_CNTL__CRTC2_HSYNC_DIS                    0x10000000L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS_MASK               0x20000000L
+#define CRTC2_GEN_CNTL__CRTC2_VSYNC_DIS                    0x20000000L
+
+// AGP_CNTL
+#define AGP_CNTL__MAX_IDLE_CLK_MASK                        0x000000ffL
+#define AGP_CNTL__HOLD_RD_FIFO_MASK                        0x00000100L
+#define AGP_CNTL__HOLD_RD_FIFO                             0x00000100L
+#define AGP_CNTL__HOLD_RQ_FIFO_MASK                        0x00000200L
+#define AGP_CNTL__HOLD_RQ_FIFO                             0x00000200L
+#define AGP_CNTL__EN_2X_STBB_MASK                          0x00000400L
+#define AGP_CNTL__EN_2X_STBB                               0x00000400L
+#define AGP_CNTL__FORCE_FULL_SBA_MASK                      0x00000800L
+#define AGP_CNTL__FORCE_FULL_SBA                           0x00000800L
+#define AGP_CNTL__SBA_DIS_MASK                             0x00001000L
+#define AGP_CNTL__SBA_DIS                                  0x00001000L
+#define AGP_CNTL__AGP_REV_ID_MASK                          0x00002000L
+#define AGP_CNTL__AGP_REV_ID                               0x00002000L
+#define AGP_CNTL__REG_CRIPPLE_AGP4X_MASK                   0x00004000L
+#define AGP_CNTL__REG_CRIPPLE_AGP4X                        0x00004000L
+#define AGP_CNTL__REG_CRIPPLE_AGP2X4X_MASK                 0x00008000L
+#define AGP_CNTL__REG_CRIPPLE_AGP2X4X                      0x00008000L
+#define AGP_CNTL__FORCE_INT_VREF_MASK                      0x00010000L
+#define AGP_CNTL__FORCE_INT_VREF                           0x00010000L
+#define AGP_CNTL__PENDING_SLOTS_VAL_MASK                   0x00060000L
+#define AGP_CNTL__PENDING_SLOTS_SEL_MASK                   0x00080000L
+#define AGP_CNTL__PENDING_SLOTS_SEL                        0x00080000L
+#define AGP_CNTL__EN_EXTENDED_AD_STB_2X_MASK               0x00100000L
+#define AGP_CNTL__EN_EXTENDED_AD_STB_2X                    0x00100000L
+#define AGP_CNTL__DIS_QUEUED_GNT_FIX_MASK                  0x00200000L
+#define AGP_CNTL__DIS_QUEUED_GNT_FIX                       0x00200000L
+#define AGP_CNTL__EN_RDATA2X4X_MULTIRESET_MASK             0x00400000L
+#define AGP_CNTL__EN_RDATA2X4X_MULTIRESET                  0x00400000L
+#define AGP_CNTL__EN_RBFCALM_MASK                          0x00800000L
+#define AGP_CNTL__EN_RBFCALM                               0x00800000L
+#define AGP_CNTL__FORCE_EXT_VREF_MASK                      0x01000000L
+#define AGP_CNTL__FORCE_EXT_VREF                           0x01000000L
+#define AGP_CNTL__DIS_RBF_MASK                             0x02000000L
+#define AGP_CNTL__DIS_RBF                                  0x02000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_EN_MASK                  0x04000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_EN                       0x04000000L
+#define AGP_CNTL__DELAY_FIRST_SBA_VAL_MASK                 0x38000000L
+#define AGP_CNTL__AGP_MISC_MASK                            0xc0000000L
+
+// AGP_CNTL
+#define	AGP_CNTL__MAX_IDLE_CLK__SHIFT                      0x00000000
+#define	AGP_CNTL__HOLD_RD_FIFO__SHIFT                      0x00000008
+#define	AGP_CNTL__HOLD_RQ_FIFO__SHIFT                      0x00000009
+#define	AGP_CNTL__EN_2X_STBB__SHIFT                        0x0000000a
+#define	AGP_CNTL__FORCE_FULL_SBA__SHIFT                    0x0000000b
+#define	AGP_CNTL__SBA_DIS__SHIFT                           0x0000000c
+#define	AGP_CNTL__AGP_REV_ID__SHIFT                        0x0000000d
+#define	AGP_CNTL__REG_CRIPPLE_AGP4X__SHIFT                 0x0000000e
+#define	AGP_CNTL__REG_CRIPPLE_AGP2X4X__SHIFT               0x0000000f
+#define	AGP_CNTL__FORCE_INT_VREF__SHIFT                    0x00000010
+#define	AGP_CNTL__PENDING_SLOTS_VAL__SHIFT                 0x00000011
+#define	AGP_CNTL__PENDING_SLOTS_SEL__SHIFT                 0x00000013
+#define	AGP_CNTL__EN_EXTENDED_AD_STB_2X__SHIFT             0x00000014
+#define	AGP_CNTL__DIS_QUEUED_GNT_FIX__SHIFT                0x00000015
+#define	AGP_CNTL__EN_RDATA2X4X_MULTIRESET__SHIFT           0x00000016
+#define	AGP_CNTL__EN_RBFCALM__SHIFT                        0x00000017
+#define	AGP_CNTL__FORCE_EXT_VREF__SHIFT                    0x00000018
+#define	AGP_CNTL__DIS_RBF__SHIFT                           0x00000019
+#define	AGP_CNTL__DELAY_FIRST_SBA_EN__SHIFT                0x0000001a
+#define	AGP_CNTL__DELAY_FIRST_SBA_VAL__SHIFT               0x0000001b
+#define	AGP_CNTL__AGP_MISC__SHIFT                          0x0000001e
+
+// DISP_MISC_CNTL
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_PP_MASK            0x00000001L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_PP                 0x00000001L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP_MASK          0x00000002L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_PP               0x00000002L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_PP_MASK             0x00000004L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_PP                  0x00000004L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK_MASK          0x00000010L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH_SCLK               0x00000010L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK_MASK        0x00000020L
+#define DISP_MISC_CNTL__SOFT_RESET_SUBPIC_SCLK             0x00000020L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK_MASK           0x00000040L
+#define DISP_MISC_CNTL__SOFT_RESET_OV0_SCLK                0x00000040L
+#define DISP_MISC_CNTL__SYNC_STRENGTH_MASK                 0x00000300L
+#define DISP_MISC_CNTL__SYNC_PAD_FLOP_EN_MASK              0x00000400L
+#define DISP_MISC_CNTL__SYNC_PAD_FLOP_EN                   0x00000400L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP_MASK           0x00001000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_PP                0x00001000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK_MASK         0x00008000L
+#define DISP_MISC_CNTL__SOFT_RESET_GRPH2_SCLK              0x00008000L
+#define DISP_MISC_CNTL__SOFT_RESET_LVDS_MASK               0x00010000L
+#define DISP_MISC_CNTL__SOFT_RESET_LVDS                    0x00010000L
+#define DISP_MISC_CNTL__SOFT_RESET_TMDS_MASK               0x00020000L
+#define DISP_MISC_CNTL__SOFT_RESET_TMDS                    0x00020000L
+#define DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS_MASK           0x00040000L
+#define DISP_MISC_CNTL__SOFT_RESET_DIG_TMDS                0x00040000L
+#define DISP_MISC_CNTL__SOFT_RESET_TV_MASK                 0x00080000L
+#define DISP_MISC_CNTL__SOFT_RESET_TV                      0x00080000L
+#define DISP_MISC_CNTL__PALETTE2_MEM_RD_MARGIN_MASK        0x00f00000L
+#define DISP_MISC_CNTL__PALETTE_MEM_RD_MARGIN_MASK         0x0f000000L
+#define DISP_MISC_CNTL__RMX_BUF_MEM_RD_MARGIN_MASK         0xf0000000L
+
+// DISP_PWR_MAN
+#define DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN_MASK         0x00000001L
+#define DISP_PWR_MAN__DISP_PWR_MAN_D3_CRTC_EN              0x00000001L
+#define DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN_MASK       0x00000010L
+#define DISP_PWR_MAN__DISP2_PWR_MAN_D3_CRTC2_EN            0x00000010L
+#define DISP_PWR_MAN__DISP_PWR_MAN_DPMS_MASK               0x00000300L
+#define DISP_PWR_MAN__DISP_D3_RST_MASK                     0x00010000L
+#define DISP_PWR_MAN__DISP_D3_RST                          0x00010000L
+#define DISP_PWR_MAN__DISP_D3_REG_RST_MASK                 0x00020000L
+#define DISP_PWR_MAN__DISP_D3_REG_RST                      0x00020000L
+#define DISP_PWR_MAN__DISP_D3_GRPH_RST_MASK                0x00040000L
+#define DISP_PWR_MAN__DISP_D3_GRPH_RST                     0x00040000L
+#define DISP_PWR_MAN__DISP_D3_SUBPIC_RST_MASK              0x00080000L
+#define DISP_PWR_MAN__DISP_D3_SUBPIC_RST                   0x00080000L
+#define DISP_PWR_MAN__DISP_D3_OV0_RST_MASK                 0x00100000L
+#define DISP_PWR_MAN__DISP_D3_OV0_RST                      0x00100000L
+#define DISP_PWR_MAN__DISP_D1D2_GRPH_RST_MASK              0x00200000L
+#define DISP_PWR_MAN__DISP_D1D2_GRPH_RST                   0x00200000L
+#define DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST_MASK            0x00400000L
+#define DISP_PWR_MAN__DISP_D1D2_SUBPIC_RST                 0x00400000L
+#define DISP_PWR_MAN__DISP_D1D2_OV0_RST_MASK               0x00800000L
+#define DISP_PWR_MAN__DISP_D1D2_OV0_RST                    0x00800000L
+#define DISP_PWR_MAN__DIG_TMDS_ENABLE_RST_MASK             0x01000000L
+#define DISP_PWR_MAN__DIG_TMDS_ENABLE_RST                  0x01000000L
+#define DISP_PWR_MAN__TV_ENABLE_RST_MASK                   0x02000000L
+#define DISP_PWR_MAN__TV_ENABLE_RST                        0x02000000L
+#define DISP_PWR_MAN__AUTO_PWRUP_EN_MASK                   0x04000000L
+#define DISP_PWR_MAN__AUTO_PWRUP_EN                        0x04000000L
+
+// MC_IND_INDEX
+#define MC_IND_INDEX__MC_IND_ADDR_MASK                     0x0000001fL
+#define MC_IND_INDEX__MC_IND_WR_EN_MASK                    0x00000100L
+#define MC_IND_INDEX__MC_IND_WR_EN                         0x00000100L
+
+// MC_IND_DATA
+#define MC_IND_DATA__MC_IND_DATA_MASK                      0xffffffffL
+
+// MC_CHP_IO_CNTL_A1
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA__SHIFT            0x00000000
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA__SHIFT             0x00000001
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA__SHIFT           0x00000002
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA__SHIFT           0x00000003
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA__SHIFT            0x00000004
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA__SHIFT             0x00000005
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA__SHIFT           0x00000006
+#define	MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA__SHIFT           0x00000007
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA__SHIFT            0x00000008
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA__SHIFT          0x00000009
+#define	MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA__SHIFT          0x0000000a
+#define	MC_CHP_IO_CNTL_A1__MEM_IO_MODEA__SHIFT             0x0000000c
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_CKA__SHIFT              0x0000000e
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_AA__SHIFT               0x00000010
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_DQMA__SHIFT             0x00000012
+#define	MC_CHP_IO_CNTL_A1__MEM_REC_DQSA__SHIFT             0x00000014
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA__SHIFT          0x00000016
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA__SHIFT         0x00000017
+#define	MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA__SHIFT             0x00000018
+#define	MC_CHP_IO_CNTL_A1__MEM_CLK_SELA__SHIFT             0x0000001a
+#define	MC_CHP_IO_CNTL_A1__MEM_CLK_INVA__SHIFT             0x0000001c
+#define	MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A__SHIFT         0x0000001e
+#define	MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A__SHIFT         0x0000001f
+
+// MC_CHP_IO_CNTL_B1
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB__SHIFT            0x00000000
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB__SHIFT             0x00000001
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB__SHIFT           0x00000002
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB__SHIFT           0x00000003
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB__SHIFT            0x00000004
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB__SHIFT             0x00000005
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB__SHIFT           0x00000006
+#define	MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB__SHIFT           0x00000007
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB__SHIFT            0x00000008
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB__SHIFT          0x00000009
+#define	MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB__SHIFT          0x0000000a
+#define	MC_CHP_IO_CNTL_B1__MEM_IO_MODEB__SHIFT             0x0000000c
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_CKB__SHIFT              0x0000000e
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_AB__SHIFT               0x00000010
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_DQMB__SHIFT             0x00000012
+#define	MC_CHP_IO_CNTL_B1__MEM_REC_DQSB__SHIFT             0x00000014
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB__SHIFT          0x00000016
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB__SHIFT         0x00000017
+#define	MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB__SHIFT             0x00000018
+#define	MC_CHP_IO_CNTL_B1__MEM_CLK_SELB__SHIFT             0x0000001a
+#define	MC_CHP_IO_CNTL_B1__MEM_CLK_INVB__SHIFT             0x0000001c
+#define	MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B__SHIFT         0x0000001e
+#define	MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B__SHIFT         0x0000001f
+
+// MC_CHP_IO_CNTL_A1
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA_MASK              0x00000001L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_CKA                   0x00000001L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA_MASK               0x00000002L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_AA                    0x00000002L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA_MASK             0x00000004L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQMA                  0x00000004L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA_MASK             0x00000008L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWN_DQSA                  0x00000008L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA_MASK              0x00000010L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_CKA                   0x00000010L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA_MASK               0x00000020L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_AA                    0x00000020L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA_MASK             0x00000040L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQMA                  0x00000040L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA_MASK             0x00000080L
+#define MC_CHP_IO_CNTL_A1__MEM_SLEWP_DQSA                  0x00000080L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA_MASK              0x00000100L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_AA                   0x00000100L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA_MASK            0x00000200L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQMA                 0x00000200L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA_MASK            0x00000400L
+#define MC_CHP_IO_CNTL_A1__MEM_PREAMP_DQSA                 0x00000400L
+#define MC_CHP_IO_CNTL_A1__MEM_IO_MODEA_MASK               0x00003000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_CKA_MASK                0x0000c000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_AA_MASK                 0x00030000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_DQMA_MASK               0x000c0000L
+#define MC_CHP_IO_CNTL_A1__MEM_REC_DQSA_MASK               0x00300000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA_MASK            0x00400000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_PHASEA                 0x00400000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA_MASK           0x00800000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_CENTERA                0x00800000L
+#define MC_CHP_IO_CNTL_A1__MEM_SYNC_ENA_MASK               0x03000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_SELA_MASK               0x0c000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_INVA_MASK               0x10000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CLK_INVA                    0x10000000L
+#define MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A_MASK           0x40000000L
+#define MC_CHP_IO_CNTL_A1__MEM_DATA_ENIMP_A                0x40000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A_MASK           0x80000000L
+#define MC_CHP_IO_CNTL_A1__MEM_CNTL_ENIMP_A                0x80000000L
+
+// MC_CHP_IO_CNTL_B1
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB_MASK              0x00000001L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_CKB                   0x00000001L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB_MASK               0x00000002L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_AB                    0x00000002L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB_MASK             0x00000004L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQMB                  0x00000004L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB_MASK             0x00000008L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWN_DQSB                  0x00000008L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB_MASK              0x00000010L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_CKB                   0x00000010L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB_MASK               0x00000020L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_AB                    0x00000020L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB_MASK             0x00000040L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQMB                  0x00000040L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB_MASK             0x00000080L
+#define MC_CHP_IO_CNTL_B1__MEM_SLEWP_DQSB                  0x00000080L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB_MASK              0x00000100L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_AB                   0x00000100L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB_MASK            0x00000200L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQMB                 0x00000200L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB_MASK            0x00000400L
+#define MC_CHP_IO_CNTL_B1__MEM_PREAMP_DQSB                 0x00000400L
+#define MC_CHP_IO_CNTL_B1__MEM_IO_MODEB_MASK               0x00003000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_CKB_MASK                0x0000c000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_AB_MASK                 0x00030000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_DQMB_MASK               0x000c0000L
+#define MC_CHP_IO_CNTL_B1__MEM_REC_DQSB_MASK               0x00300000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB_MASK            0x00400000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_PHASEB                 0x00400000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB_MASK           0x00800000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_CENTERB                0x00800000L
+#define MC_CHP_IO_CNTL_B1__MEM_SYNC_ENB_MASK               0x03000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_SELB_MASK               0x0c000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_INVB_MASK               0x10000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CLK_INVB                    0x10000000L
+#define MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B_MASK           0x40000000L
+#define MC_CHP_IO_CNTL_B1__MEM_DATA_ENIMP_B                0x40000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B_MASK           0x80000000L
+#define MC_CHP_IO_CNTL_B1__MEM_CNTL_ENIMP_B                0x80000000L
+
+// MEM_SDRAM_MODE_REG
+#define MEM_SDRAM_MODE_REG__MEM_MODE_REG_MASK              0x00007fffL
+#define MEM_SDRAM_MODE_REG__MEM_WR_LATENCY_MASK            0x000f0000L
+#define MEM_SDRAM_MODE_REG__MEM_CAS_LATENCY_MASK           0x00700000L
+#define MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY_MASK           0x00800000L
+#define MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY                0x00800000L
+#define MEM_SDRAM_MODE_REG__MEM_STR_LATENCY_MASK           0x01000000L
+#define MEM_SDRAM_MODE_REG__MEM_STR_LATENCY                0x01000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD_MASK          0x02000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD               0x02000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA_MASK         0x04000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA              0x04000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR_MASK          0x08000000L
+#define MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR               0x08000000L
+#define MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE_MASK          0x10000000L
+#define MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE               0x10000000L
+#define MEM_SDRAM_MODE_REG__MEM_DDR_DLL_MASK               0x20000000L
+#define MEM_SDRAM_MODE_REG__MEM_DDR_DLL                    0x20000000L
+#define MEM_SDRAM_MODE_REG__MEM_CFG_TYPE_MASK              0x40000000L
+#define MEM_SDRAM_MODE_REG__MEM_CFG_TYPE                   0x40000000L
+#define MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET_MASK           0x80000000L
+#define MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET                0x80000000L
+
+// MEM_SDRAM_MODE_REG
+#define	MEM_SDRAM_MODE_REG__MEM_MODE_REG__SHIFT            0x00000000
+#define	MEM_SDRAM_MODE_REG__MEM_WR_LATENCY__SHIFT          0x00000010
+#define	MEM_SDRAM_MODE_REG__MEM_CAS_LATENCY__SHIFT         0x00000014
+#define	MEM_SDRAM_MODE_REG__MEM_CMD_LATENCY__SHIFT         0x00000017
+#define	MEM_SDRAM_MODE_REG__MEM_STR_LATENCY__SHIFT         0x00000018
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_CMD__SHIFT        0x00000019
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_DATA__SHIFT       0x0000001a
+#define	MEM_SDRAM_MODE_REG__MEM_FALL_OUT_STR__SHIFT        0x0000001b
+#define	MEM_SDRAM_MODE_REG__MC_INIT_COMPLETE__SHIFT        0x0000001c
+#define	MEM_SDRAM_MODE_REG__MEM_DDR_DLL__SHIFT             0x0000001d
+#define	MEM_SDRAM_MODE_REG__MEM_CFG_TYPE__SHIFT            0x0000001e
+#define	MEM_SDRAM_MODE_REG__MEM_SDRAM_RESET__SHIFT         0x0000001f
+
+// MEM_REFRESH_CNTL
+#define MEM_REFRESH_CNTL__MEM_REFRESH_RATE_MASK            0x000000ffL
+#define MEM_REFRESH_CNTL__MEM_REFRESH_DIS_MASK             0x00000100L
+#define MEM_REFRESH_CNTL__MEM_REFRESH_DIS                  0x00000100L
+#define MEM_REFRESH_CNTL__MEM_DYNAMIC_CKE_MASK             0x00000200L
+#define MEM_REFRESH_CNTL__MEM_DYNAMIC_CKE                  0x00000200L
+#define MEM_REFRESH_CNTL__MEM_TRFC_MASK                    0x0000f000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0_ENABLE_MASK            0x00010000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0_ENABLE                 0x00010000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0b_ENABLE_MASK           0x00020000L
+#define MEM_REFRESH_CNTL__MEM_CLKA0b_ENABLE                0x00020000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1_ENABLE_MASK            0x00040000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1_ENABLE                 0x00040000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1b_ENABLE_MASK           0x00080000L
+#define MEM_REFRESH_CNTL__MEM_CLKA1b_ENABLE                0x00080000L
+#define MEM_REFRESH_CNTL__MEM_CLKAFB_ENABLE_MASK           0x00100000L
+#define MEM_REFRESH_CNTL__MEM_CLKAFB_ENABLE                0x00100000L
+#define MEM_REFRESH_CNTL__DLL_FB_SLCT_CKA_MASK             0x00c00000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0_ENABLE_MASK            0x01000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0_ENABLE                 0x01000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0b_ENABLE_MASK           0x02000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB0b_ENABLE                0x02000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1_ENABLE_MASK            0x04000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1_ENABLE                 0x04000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1b_ENABLE_MASK           0x08000000L
+#define MEM_REFRESH_CNTL__MEM_CLKB1b_ENABLE                0x08000000L
+#define MEM_REFRESH_CNTL__MEM_CLKBFB_ENABLE_MASK           0x10000000L
+#define MEM_REFRESH_CNTL__MEM_CLKBFB_ENABLE                0x10000000L
+#define MEM_REFRESH_CNTL__DLL_FB_SLCT_CKB_MASK             0xc0000000L
+
+// MC_STATUS
+#define MC_STATUS__MEM_PWRUP_COMPL_A_MASK                  0x00000001L
+#define MC_STATUS__MEM_PWRUP_COMPL_A                       0x00000001L
+#define MC_STATUS__MEM_PWRUP_COMPL_B_MASK                  0x00000002L
+#define MC_STATUS__MEM_PWRUP_COMPL_B                       0x00000002L
+#define MC_STATUS__MC_IDLE_MASK                            0x00000004L
+#define MC_STATUS__MC_IDLE                                 0x00000004L
+#define MC_STATUS__IMP_N_VALUE_R_BACK_MASK                 0x00000078L
+#define MC_STATUS__IMP_P_VALUE_R_BACK_MASK                 0x00000780L
+#define MC_STATUS__TEST_OUT_R_BACK_MASK                    0x00000800L
+#define MC_STATUS__TEST_OUT_R_BACK                         0x00000800L
+#define MC_STATUS__DUMMY_OUT_R_BACK_MASK                   0x00001000L
+#define MC_STATUS__DUMMY_OUT_R_BACK                        0x00001000L
+#define MC_STATUS__IMP_N_VALUE_A_R_BACK_MASK               0x0001e000L
+#define MC_STATUS__IMP_P_VALUE_A_R_BACK_MASK               0x001e0000L
+#define MC_STATUS__IMP_N_VALUE_CK_R_BACK_MASK              0x01e00000L
+#define MC_STATUS__IMP_P_VALUE_CK_R_BACK_MASK              0x1e000000L
+
+// MDLL_CKO
+#define MDLL_CKO__MCKOA_SLEEP_MASK                         0x00000001L
+#define MDLL_CKO__MCKOA_SLEEP                              0x00000001L
+#define MDLL_CKO__MCKOA_RESET_MASK                         0x00000002L
+#define MDLL_CKO__MCKOA_RESET                              0x00000002L
+#define MDLL_CKO__MCKOA_RANGE_MASK                         0x0000000cL
+#define MDLL_CKO__ERSTA_SOUTSEL_MASK                       0x00000030L
+#define MDLL_CKO__MCKOA_FB_SEL_MASK                        0x000000c0L
+#define MDLL_CKO__MCKOA_REF_SKEW_MASK                      0x00000700L
+#define MDLL_CKO__MCKOA_FB_SKEW_MASK                       0x00007000L
+#define MDLL_CKO__MCKOA_BP_SEL_MASK                        0x00008000L
+#define MDLL_CKO__MCKOA_BP_SEL                             0x00008000L
+#define MDLL_CKO__MCKOB_SLEEP_MASK                         0x00010000L
+#define MDLL_CKO__MCKOB_SLEEP                              0x00010000L
+#define MDLL_CKO__MCKOB_RESET_MASK                         0x00020000L
+#define MDLL_CKO__MCKOB_RESET                              0x00020000L
+#define MDLL_CKO__MCKOB_RANGE_MASK                         0x000c0000L
+#define MDLL_CKO__ERSTB_SOUTSEL_MASK                       0x00300000L
+#define MDLL_CKO__MCKOB_FB_SEL_MASK                        0x00c00000L
+#define MDLL_CKO__MCKOB_REF_SKEW_MASK                      0x07000000L
+#define MDLL_CKO__MCKOB_FB_SKEW_MASK                       0x70000000L
+#define MDLL_CKO__MCKOB_BP_SEL_MASK                        0x80000000L
+#define MDLL_CKO__MCKOB_BP_SEL                             0x80000000L
+
+// MDLL_RDCKA
+#define MDLL_RDCKA__MRDCKA0_SLEEP_MASK                     0x00000001L
+#define MDLL_RDCKA__MRDCKA0_SLEEP                          0x00000001L
+#define MDLL_RDCKA__MRDCKA0_RESET_MASK                     0x00000002L
+#define MDLL_RDCKA__MRDCKA0_RESET                          0x00000002L
+#define MDLL_RDCKA__MRDCKA0_RANGE_MASK                     0x0000000cL
+#define MDLL_RDCKA__MRDCKA0_REF_SEL_MASK                   0x00000030L
+#define MDLL_RDCKA__MRDCKA0_FB_SEL_MASK                    0x000000c0L
+#define MDLL_RDCKA__MRDCKA0_REF_SKEW_MASK                  0x00000700L
+#define MDLL_RDCKA__MRDCKA0_SINSEL_MASK                    0x00000800L
+#define MDLL_RDCKA__MRDCKA0_SINSEL                         0x00000800L
+#define MDLL_RDCKA__MRDCKA0_FB_SKEW_MASK                   0x00007000L
+#define MDLL_RDCKA__MRDCKA0_BP_SEL_MASK                    0x00008000L
+#define MDLL_RDCKA__MRDCKA0_BP_SEL                         0x00008000L
+#define MDLL_RDCKA__MRDCKA1_SLEEP_MASK                     0x00010000L
+#define MDLL_RDCKA__MRDCKA1_SLEEP                          0x00010000L
+#define MDLL_RDCKA__MRDCKA1_RESET_MASK                     0x00020000L
+#define MDLL_RDCKA__MRDCKA1_RESET                          0x00020000L
+#define MDLL_RDCKA__MRDCKA1_RANGE_MASK                     0x000c0000L
+#define MDLL_RDCKA__MRDCKA1_REF_SEL_MASK                   0x00300000L
+#define MDLL_RDCKA__MRDCKA1_FB_SEL_MASK                    0x00c00000L
+#define MDLL_RDCKA__MRDCKA1_REF_SKEW_MASK                  0x07000000L
+#define MDLL_RDCKA__MRDCKA1_SINSEL_MASK                    0x08000000L
+#define MDLL_RDCKA__MRDCKA1_SINSEL                         0x08000000L
+#define MDLL_RDCKA__MRDCKA1_FB_SKEW_MASK                   0x70000000L
+#define MDLL_RDCKA__MRDCKA1_BP_SEL_MASK                    0x80000000L
+#define MDLL_RDCKA__MRDCKA1_BP_SEL                         0x80000000L
+
+// MDLL_RDCKB
+#define MDLL_RDCKB__MRDCKB0_SLEEP_MASK                     0x00000001L
+#define MDLL_RDCKB__MRDCKB0_SLEEP                          0x00000001L
+#define MDLL_RDCKB__MRDCKB0_RESET_MASK                     0x00000002L
+#define MDLL_RDCKB__MRDCKB0_RESET                          0x00000002L
+#define MDLL_RDCKB__MRDCKB0_RANGE_MASK                     0x0000000cL
+#define MDLL_RDCKB__MRDCKB0_REF_SEL_MASK                   0x00000030L
+#define MDLL_RDCKB__MRDCKB0_FB_SEL_MASK                    0x000000c0L
+#define MDLL_RDCKB__MRDCKB0_REF_SKEW_MASK                  0x00000700L
+#define MDLL_RDCKB__MRDCKB0_SINSEL_MASK                    0x00000800L
+#define MDLL_RDCKB__MRDCKB0_SINSEL                         0x00000800L
+#define MDLL_RDCKB__MRDCKB0_FB_SKEW_MASK                   0x00007000L
+#define MDLL_RDCKB__MRDCKB0_BP_SEL_MASK                    0x00008000L
+#define MDLL_RDCKB__MRDCKB0_BP_SEL                         0x00008000L
+#define MDLL_RDCKB__MRDCKB1_SLEEP_MASK                     0x00010000L
+#define MDLL_RDCKB__MRDCKB1_SLEEP                          0x00010000L
+#define MDLL_RDCKB__MRDCKB1_RESET_MASK                     0x00020000L
+#define MDLL_RDCKB__MRDCKB1_RESET                          0x00020000L
+#define MDLL_RDCKB__MRDCKB1_RANGE_MASK                     0x000c0000L
+#define MDLL_RDCKB__MRDCKB1_REF_SEL_MASK                   0x00300000L
+#define MDLL_RDCKB__MRDCKB1_FB_SEL_MASK                    0x00c00000L
+#define MDLL_RDCKB__MRDCKB1_REF_SKEW_MASK                  0x07000000L
+#define MDLL_RDCKB__MRDCKB1_SINSEL_MASK                    0x08000000L
+#define MDLL_RDCKB__MRDCKB1_SINSEL                         0x08000000L
+#define MDLL_RDCKB__MRDCKB1_FB_SKEW_MASK                   0x70000000L
+#define MDLL_RDCKB__MRDCKB1_BP_SEL_MASK                    0x80000000L
+#define MDLL_RDCKB__MRDCKB1_BP_SEL                         0x80000000L
+
+#define pllVCLK_ECP_CNTL                            0x0008
+#define pllDISP_TEST_MACRO_RW_WRITE                 0x001A
+#define pllDISP_TEST_MACRO_RW_READ                  0x001B
+#define pllDISP_TEST_MACRO_RW_DATA                  0x001C
+#define pllDISP_TEST_MACRO_RW_CNTL                  0x001D
+#define pllPIXCLKS_CNTL                             0x002D
+#define pllPPLL_DIV_0                               0x0004
+#define pllPPLL_DIV_1                               0x0005
+#define pllPPLL_DIV_2                               0x0006
+#define pllPPLL_DIV_3                               0x0007
+#define pllHTOTAL_CNTL                              0x0009
+#define pllPLL_TEST_CNTL_M6                         0x0013
+#define pllP2PLL_DIV_0                              0x002C
+#define pllHTOTAL2_CNTL                             0x002E
+#define pllCLK_PIN_CNTL                             0x0001
+#define pllPPLL_CNTL                                0x0002
+#define pllPPLL_REF_DIV                             0x0003
+#define pllSPLL_CNTL                                0x000C
+#define pllSPLL_AUX_CNTL                            0x0024
+#define pllSCLK_CNTL_M6                             0x000D
+#define pllAGP_PLL_CNTL                             0x000B
+#define pllTV_PLL_FINE_CNTL                         0x0020
+#define pllTV_PLL_CNTL                              0x0021
+#define pllTV_PLL_CNTL1                             0x0022
+#define pllTV_DTO_INCREMENTS                        0x0023
+#define pllP2PLL_CNTL                               0x002A
+#define pllP2PLL_REF_DIV                            0x002B
+#define pllSSPLL_CNTL                               0x0030
+#define pllSSPLL_REF_DIV                            0x0031
+#define pllSSPLL_DIV_0                              0x0032
+#define pllSS_INT_CNTL                              0x0033
+#define pllSS_TST_CNTL                              0x0034
+#define pllSCLK_MORE_CNTL                           0x0035
+#define pllCLK_PWRMGT_CNTL_M6                       0x0014
+#define pllPLL_PWRMGT_CNTL                          0x0015
+#define pllM_SPLL_REF_FB_DIV                        0x000A
+#define pllMPLL_CNTL                                0x000E
+#define pllMPLL_AUX_CNTL                            0x0025
+#define pllMDLL_CKO                                 0x000F
+#define pllMDLL_RDCKA                               0x0010
+#define pllMDLL_RDCKB                               0x0011
+#define pllMCLK_CNTL_M6                             0x0012
+#define pllMCLK_MISC                                0x001F
+#define pllCG_TEST_MACRO_RW_WRITE                   0x0016
+#define pllCG_TEST_MACRO_RW_READ                    0x0017
+#define pllCG_TEST_MACRO_RW_DATA                    0x0018
+#define pllCG_TEST_MACRO_RW_CNTL                    0x0019
+
+#define ixMC_PERF_CNTL                             0x0000
+#define ixMC_PERF_SEL                              0x0001
+#define ixMC_PERF_REGION_0                         0x0002
+#define ixMC_PERF_REGION_1                         0x0003
+#define ixMC_PERF_COUNT_0                          0x0004
+#define ixMC_PERF_COUNT_1                          0x0005
+#define ixMC_PERF_COUNT_2                          0x0006
+#define ixMC_PERF_COUNT_3                          0x0007
+#define ixMC_PERF_COUNT_MEMCH_A                    0x0008
+#define ixMC_PERF_COUNT_MEMCH_B                    0x0009
+#define ixMC_IMP_CNTL                              0x000A
+#define ixMC_CHP_IO_CNTL_A0                        0x000B
+#define ixMC_CHP_IO_CNTL_A1                        0x000C
+#define ixMC_CHP_IO_CNTL_B0                        0x000D
+#define ixMC_CHP_IO_CNTL_B1                        0x000E
+#define ixMC_IMP_CNTL_0                            0x000F
+#define ixTC_MISMATCH_1                            0x0010
+#define ixTC_MISMATCH_2                            0x0011
+#define ixMC_BIST_CTRL                             0x0012
+#define ixREG_COLLAR_WRITE                         0x0013
+#define ixREG_COLLAR_READ                          0x0014
+
+
+
 
 #endif	/* _RADEON_H */
 
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/sisfb.h fbdev-2.6/include/video/sisfb.h
--- linus-2.6/include/video/sisfb.h	Thu Oct 16 14:16:23 2003
+++ fbdev-2.6/include/video/sisfb.h	Thu Oct 16 14:16:23 2003
@@ -6,6 +6,53 @@
 #include <asm/ioctl.h>
 #include <asm/types.h>
 
+/* TW: vbflags */
+#define CRT2_DEFAULT            0x00000001
+#define CRT2_LCD                0x00000002  /* TW: Never change the order of the CRT2_XXX entries */
+#define CRT2_TV                 0x00000004  /*     (see SISCycleCRT2Type())                       */
+#define CRT2_VGA                0x00000008
+#define CRT2_ENABLE		(CRT2_LCD | CRT2_TV | CRT2_VGA)
+#define VB_DISPTYPE_DISP2	CRT2_ENABLE
+#define VB_DISPTYPE_CRT2	CRT2_ENABLE
+#define TV_NTSC                 0x00000010
+#define TV_PAL                  0x00000020
+#define TV_HIVISION             0x00000040
+#define TV_HIVISION_LV          0x00000080
+#define TV_TYPE                 (TV_NTSC | TV_PAL | TV_HIVISION | TV_HIVISION_LV)
+#define TV_AVIDEO               0x00000100
+#define TV_SVIDEO               0x00000200
+#define TV_SCART                0x00000400
+#define TV_INTERFACE            (TV_AVIDEO | TV_SVIDEO | TV_SCART | TV_CHSCART | TV_CHHDTV)
+#define VB_USELCDA		0x00000800
+#define TV_PALM                 0x00001000
+#define TV_PALN                 0x00002000
+#define TV_CHSCART              0x00008000
+#define TV_CHHDTV               0x00010000
+#define VGA2_CONNECTED          0x00040000
+#define VB_DISPTYPE_CRT1	0x00080000  	/* CRT1 connected and used */
+#define VBDISPTYPE_DISP1	VB_DISPTYPE_CRT1
+#define VB_301                  0x00100000	/* Video bridge type */
+#define VB_301B                 0x00200000
+#define VB_302B                 0x00400000
+#define VB_30xBDH		0x00800000      /* 30xB DH version (w/o LCD support) */
+#define VB_LVDS                 0x01000000
+#define VB_CHRONTEL             0x02000000
+#define VB_301LV                0x04000000
+#define VB_302LV                0x08000000
+#define VB_301C			0x10000000
+#define VB_VIDEOBRIDGE		(VB_301|VB_301B|VB_301C|VB_302B|VB_301LV|VB_302LV| \
+				 VB_LVDS|VB_CHRONTEL)
+#define VB_SISBRIDGE            (VB_301|VB_301B|VB_302B|VB_301LV|VB_302LV)
+#define VB_SINGLE_MODE          0x20000000   	 /* CRT1 or CRT2; determined by VB_DISPTYPE_CRTx */
+#define VB_DISPMODE_SINGLE	VB_SINGLE_MODE
+#define VB_MIRROR_MODE		0x40000000   	 /* CRT1 + CRT2 identical (mirror mode) */
+#define VB_DISPMODE_MIRROR	VB_MIRROR_MODE
+#define VB_DUALVIEW_MODE	0x80000000   	 /* CRT1 + CRT2 independent (dual head mode) */
+#define VB_DISPMODE_DUAL	VB_DUALVIEW_MODE
+#define VB_DISPLAY_MODE         (VB_SINGLE_MODE | VB_MIRROR_MODE | VB_DUALVIEW_MODE)
+
+
+/* entries for disp_state - deprecated as of 1.6.02 */
 #define DISPTYPE_CRT1       0x00000008L
 #define DISPTYPE_CRT2       0x00000004L
 #define DISPTYPE_LCD        0x00000002L
@@ -16,6 +63,7 @@
 #define DISPMODE_MIRROR	    0x00000010L
 #define DISPMODE_DUALVIEW   0x00000040L
 
+/* Deprecated as of 1.6.02 - use vbflags instead */
 #define HASVB_NONE      	0x00
 #define HASVB_301       	0x01
 #define HASVB_LVDS      	0x02
@@ -39,6 +87,8 @@
 	SIS_650,
 	SIS_740,
 	SIS_330,
+	SIS_660,
+	SIS_760,
 	MAX_SIS_CHIP
 } SIS_CHIP_TYPE;
 
@@ -83,13 +133,15 @@
 	struct mode_info minfo;
 	unsigned long iobase;
 	unsigned int  mem_size;
-	unsigned long disp_state;    	
+	unsigned long disp_state;  /* deprecated */
 	SIS_CHIP_TYPE chip;
 	unsigned char hasVB;
-	SIS_TV_TYPE TV_type;
-	SIS_TV_PLUG TV_plug;
+	SIS_TV_TYPE TV_type;	   /* deprecated */
+	SIS_TV_PLUG TV_plug;	   /* deprecated */
 	unsigned long version;
-	char reserved[256];
+	unsigned long vbflags;	   /* replaces deprecated entries above */
+	unsigned long currentvbflags;
+	char reserved[248];
 };
 
 struct video_info {
@@ -114,10 +166,10 @@
 	int    video_linelength;
 	unsigned int refresh_rate;
 
-	unsigned long disp_state;
-	unsigned char hasVB;
-	unsigned char TV_type;
-	unsigned char TV_plug;
+	unsigned long disp_state;		/* DEPRECATED */
+	unsigned char hasVB;			/* DEPRECATED */
+	unsigned char TV_type;			/* DEPRECATED */
+	unsigned char TV_plug;			/* DEPRECATED */
 
 	SIS_CHIP_TYPE chip;
 	unsigned char revision_id;
@@ -136,8 +188,19 @@
 
 	unsigned short subsysvendor;
 	unsigned short subsysdevice;
+
+	unsigned long  vbflags;			/* Replacing deprecated stuff from above */
+	unsigned long  currentvbflags;
+
+	int    current_bpp;
+	int    current_width;
+	int    current_height;
+	int    current_htotal;
+	int    current_vtotal;
+	__u32  current_pixclock;
+	int    current_refresh_rate;
 
-	char reserved[236];
+	char reserved[200];
 };
 
 
@@ -145,14 +208,6 @@
 /*     If changing this, vgatypes.h must also be changed (for X driver)    */
 
 /* TW: ioctl for identifying and giving some info (esp. memory heap start) */
-
-/*
- * NOTE! The ioctl types used to be "size_t" by mistake, but were
- * really meant to be __u32. Changed to "__u32" even though that
- * changes the value on 64-bit architectures, because the value
- * (with a 4-byte size) is also hardwired in vgatypes.h for user
- * space exports. So "__u32" is actually more compatible, duh!
- */
 #define SISFB_GET_INFO	  	_IOR('n',0xF8,__u32)
 #define SISFB_GET_VBRSTATUS  	_IOR('n',0xF9,__u32)
 
@@ -184,8 +239,14 @@
 	unsigned char sisfb_lcdpdc;	/* PanelDelayCompensation */
 	
 	unsigned char sisfb_lcda;	/* Detected status of LCDA for low res/text modes */
+
+	unsigned long sisfb_vbflags;
+	unsigned long sisfb_currentvbflags;
+
+	int sisfb_scalelcd;
+	unsigned long sisfb_specialtiming;
 
-	char reserved[235]; 		/* for future use */
+	char reserved[219]; 		/* for future use */
 };
 
 #ifdef __KERNEL__
diff -urN -X /home/jsimmons/dontdiff linus-2.6/include/video/tdfx.h fbdev-2.6/include/video/tdfx.h
--- linus-2.6/include/video/tdfx.h	Thu Oct 16 14:16:23 2003
+++ fbdev-2.6/include/video/tdfx.h	Thu Oct 16 14:16:23 2003
@@ -114,6 +114,7 @@
 #define VGAINIT1_MASK                   0x1fffff
 #define VIDCFG_VIDPROC_ENABLE           BIT(0)
 #define VIDCFG_CURS_X11                 BIT(1)
+#define VIDCFG_INTERLACE                BIT(3)
 #define VIDCFG_HALF_MODE                BIT(4)
 #define VIDCFG_DESK_ENABLE              BIT(7)
 #define VIDCFG_CLUT_BYPASS              BIT(10)